public RenderedSvg RenderHeader() { RenderedSvg result = new RenderedSvg(); SvgPaintServer blackPaint = new SvgColourServer(System.Drawing.Color.Black); string[] spans = vm.Heading.Split(new char[] { '\n' }, StringSplitOptions.RemoveEmptyEntries).Select(s => s.Trim()).ToArray(); SvgText text = new SvgText(); float fontSize = 10.0f; foreach (var span in spans) { SvgTextSpan tspan = new SvgTextSpan(); tspan.Text = span; tspan.FontSize = new SvgUnit(fontSize); tspan.Dy.Add(Helpers.dtos(fontSize * 1.2)); tspan.X.Add(0); tspan.Fill = blackPaint; text.Children.Add(tspan); } //text.Transforms.Add(new Svg.Transforms.SvgTranslate(0, (float)(- (fontSize * 1.2) * spans.Length * 0.5))); result.RenderedSize = headerView.RenderSize; result.SVG = text; return(result); }
public void DrawTextSpan(SvgTextSpan svgTextSpan, bool ignoreDisplay) { if (!CanDraw(svgTextSpan, ignoreDisplay)) { return; } _skCanvas.Save(); var skMatrix = SkiaUtil.GetSKMatrix(svgTextSpan.Transforms); SetTransform(skMatrix); SetClipPath(svgTextSpan, _disposable); var skPaintOpacity = SetOpacity(svgTextSpan, _disposable); var skPaintFilter = SetFilter(svgTextSpan, _disposable); // TODO: if (skPaintFilter != null) { _skCanvas.Restore(); } if (skPaintOpacity != null) { _skCanvas.Restore(); } _skCanvas.Restore(); }
private void setDynValue(ResponseValue responseValue, DynValue dynValueConfig, ref SvgTextSpan svgElement) { string newValue = string.Empty; int iValue; double doubleValue; //svg.Children.Remove(element); if (responseValue.value is double) { doubleValue = (double)responseValue.value; double dValue = (doubleValue + dynValueConfig.offset) * dynValueConfig.ratio; newValue = dValue + dynValueConfig.unit; } else { if (int.TryParse(responseValue.value.ToString(), out iValue) == true) { double dValue = (iValue + dynValueConfig.offset) * dynValueConfig.ratio; newValue = dValue + dynValueConfig.unit; } if (newValue == string.Empty) { newValue = responseValue.value.ToString(); } } svgElement.Text = newValue; //svg.Nodes.Add(element); }
private void setTextlist(SvgDocument svg, ResponseValue responseVar, Textlist textlist, ref SvgRectangle rectangle, ref SvgTextSpan svgText) { int textId = int.Parse(responseVar.value.ToString()); SvgColourServer rectColor = new SvgColourServer(Color.FromName(textlist.items[textId].bgColor)); rectangle.Fill = rectColor; svgText.Text = textlist.items[textId].value; SvgColourServer textColor = new SvgColourServer(Color.FromName(textlist.items[textId].textColor)); svgText.Fill = textColor; }
public SvgElement Paint(LayerVM vm, double availableWidth, double availableHeight) { if (vm is ClassificationLayerTextPresentingVM) { ClassificationLayerTextPresentingVM cltpVM = (ClassificationLayerTextPresentingVM)vm; if (cltpVM.Text != null) { string[] spans = cltpVM.Text.Split(new char[] { ',' }, StringSplitOptions.RemoveEmptyEntries).Select(s => s.Trim()).ToArray(); SvgText text = new SvgText(); text.Transforms.Add(new Svg.Transforms.SvgTranslate((float)textXoffset, (float)(availableHeight * 0.5 + textYoffset))); foreach (var span in spans) { SvgTextSpan tspan = new SvgTextSpan(); tspan.Text = span; tspan.FontSize = Helpers.dtos(fontSize); tspan.Dy.Add(Helpers.dtos(fontSize * 1.2)); tspan.X.Add(0); tspan.Fill = blackPaint; text.Children.Add(tspan); } return(text); } else { return(new SvgGroup()); } } else if (vm is LengthLayerVM) { LengthLayerVM lrlcVM = (LengthLayerVM)vm; SvgText text = new SvgText(string.Format("{0:0.##} м", lrlcVM.RealLength)); text.FontSize = Helpers.dtos(fontSize); text.Fill = blackPaint; text.Transforms.Add(new Svg.Transforms.SvgTranslate((float)textXoffset, (float)(availableHeight * 0.5 + textYoffset))); return(text); } else if (vm is MultiClassificationLayerIconPresentingVM) { MultiClassificationLayerIconPresentingVM mclipVM = (MultiClassificationLayerIconPresentingVM)vm; SvgGroup group = new SvgGroup(); float iconWidth = 32.0f; if (mclipVM.IconsSVG != null) { SvgFragment[] fragments = mclipVM.IconsSVG.Where(f => f != null).ToArray(); if (fragments.Length == 0) { return(group); } float maxHeight = fragments.Select(f => f.Bounds.Height).Max(); float offset = (float)((availableWidth - fragments.Length * iconWidth) * 0.5); foreach (var item in fragments) { SvgFragment copy = (SvgFragment)item.DeepCopy(); float aspectRatio = copy.Bounds.Width / copy.Bounds.Height; copy.ViewBox = copy.Bounds; copy.X += offset; copy.Y = (float)(availableHeight - maxHeight) * 0.5f; //copy.Transforms.Add(new Svg.Transforms.SvgScale(ratio)); copy.Width = iconWidth; copy.Height = iconWidth / aspectRatio; group.Children.Add(copy); offset += iconWidth; } } return(group); } else { return(new SvgGroup()); } }
private float DrawNextStringToken( float yOffset, string cardToken, SvgElement container, Graphics graphics, FontFamily fontFamily, float textFontSize, Color textColor) { if (cardToken.Contains(PromptBlankLine.PromptBlankPlaceholder)) { var textRectangle = new RectangleF( LeftBorderPadding, yOffset, CardWidthInPixels - (LeftBorderPadding + RightBorderPadding), CardHeightInPixels - (yOffset + BottomBorderPadding)); var sizeForText = new SizeF(textRectangle.Width, textRectangle.Height); var font = new Font(fontFamily, textFontSize, FontStyle.Regular, GraphicsUnit.Pixel); var textToDraw = PadTextWithSpaces(graphics, cardToken, font, sizeForText); var height = graphics.MeasureString(textToDraw, font, sizeForText, StringFormat.GenericDefault).Height; yOffset += height; var textElement = new SvgText(textToDraw) { Fill = new SvgColourServer(textColor), FontFamily = fontFamily.Name, FontSize = new SvgUnit(textFontSize), FontStyle = SvgFontStyle.Normal, X = new SvgUnitCollection { new SvgUnit(textRectangle.X + Origin.X) }, Y = new SvgUnitCollection { new SvgUnit(textRectangle.Y + Origin.Y + height) }, }; container.Children.Add(textElement); return(yOffset); } else { var textElement = new SvgText { Fill = new SvgColourServer(textColor), FontFamily = fontFamily.Name, FontSize = new SvgUnit(textFontSize), FontStyle = SvgFontStyle.Normal }; container.Children.Add(textElement); var textRectangle = new RectangleF( LeftBorderPadding, yOffset, CardWidthInPixels - (LeftBorderPadding + RightBorderPadding), CardHeightInPixels - (yOffset + BottomBorderPadding)); var sizeForText = new SizeF(textRectangle.Width, textRectangle.Height); var font = new Font(fontFamily, textFontSize, FontStyle.Regular, GraphicsUnit.Pixel); foreach (var lineToken in GetLineTokens(cardToken, graphics, font, sizeForText)) { textRectangle = new RectangleF( LeftBorderPadding, yOffset, CardWidthInPixels - (LeftBorderPadding + RightBorderPadding), CardHeightInPixels - (yOffset + BottomBorderPadding)); sizeForText = new SizeF(textRectangle.Width, textRectangle.Height); font = new Font(fontFamily, textFontSize, FontStyle.Regular, GraphicsUnit.Pixel); var height = graphics.MeasureString(lineToken, font, sizeForText, StringFormat.GenericDefault).Height; yOffset += height; var textSpanElement = new SvgTextSpan { X = new SvgUnitCollection { new SvgUnit(textRectangle.X + Origin.X) }, Y = new SvgUnitCollection { new SvgUnit(textRectangle.Y + Origin.Y + height) }, Text = lineToken }; textElement.Children.Add(textSpanElement); } return(yOffset); } }
public TextSpan(SvgTextSpan svgTextSpan) { matrix = SvgHelper.GetSKMatrix(svgTextSpan.Transforms); }
public static void MakeSVG(List <CapturePacket> packets, string fileName) { const int baselinestep = 250; // distance between vertical lines const int horizontalBase = 130; // upper range for the vertical lines const int unitBoxWidth = 120; // width of device box const int unitBoxHeight = 40; // height of device box const int firstarrowdistance = 50; // vertical distance before the first sequence arrow const int maxboxwidth = 1000; // maximum width of description textboxes var font = new Font("Calibri", 9); // SVG and C# have different ideas of what a fontsize is apparently, so we set this lower and hope for the best int baselinegen = -100; // iterator for making the vertical lines, the first line does one step from this value int arrowgen = horizontalBase + firstarrowdistance; // iterator for making sequence arrows // iterate through the data and gather what we need into a little struct for convenience List <Sequence> list = GetSequences(packets, baselinestep, out var devices, ref baselinegen); // after all vertical lines have been placed, make one for the description boxes int descriptionBaseline = baselinegen + 50; var svg = new SvgDocument(); var groupDevices = new SvgGroup { FontFamily = "Calibri", FontSize = 16 }; var groupArrows = new SvgGroup { ID = "arrows", Stroke = new SvgColourServer(Color.Black), StrokeWidth = 2 }; var groupArrowTexts = new SvgGroup { ID = "arrowtexts", FontFamily = "Calibri", FontSize = 11 }; var groupBaselines = new SvgGroup { ID = "baselines", Stroke = new SvgColourServer(Color.Black), StrokeWidth = 2, StrokeDashArray = new SvgUnitCollection { 10, 10 } }; var groupDescriptionBoxes = new SvgGroup { ID = "descriptionboxes", Fill = new SvgColourServer(Color.Transparent), Stroke = new SvgColourServer(Color.Black), StrokeWidth = 2 }; var groupDescriptionTexts = new SvgGroup { ID = "descriptiontexts", FontFamily = "Calibri", FontSize = 12 }; svg.Children.Add(groupDevices); svg.Children.Add(groupArrows); svg.Children.Add(groupArrowTexts); svg.Children.Add(groupBaselines); svg.Children.Add(groupDescriptionBoxes); svg.Children.Add(groupDescriptionTexts); var svgDefinitionList = new SvgDefinitionList(); var svgMarker = new SvgMarker { ID = "arrow", MarkerWidth = 10, MarkerHeight = 10, RefX = 9, RefY = 3, Orient = new SvgOrient { IsAuto = true }, MarkerUnits = SvgMarkerUnits.StrokeWidth }; var svgPath = new SvgPath { PathData = new SvgPathSegmentList { new SvgMoveToSegment(new PointF(0, 0)), new SvgLineSegment(new PointF(0, 0), new PointF(0, 6)), new SvgLineSegment(new PointF(0, 0), new PointF(9, 3)), new SvgClosePathSegment() }, Fill = new SvgColourServer(Color.Black) }; svgMarker.Children.Add(svgPath); svgDefinitionList.Children.Add(svgMarker); svg.Children.Add(svgDefinitionList); // make the device boxes foreach (KeyValuePair <IPAddress, int> device in devices) { groupDevices.Children.Add(new SvgRectangle { Fill = new SvgColourServer(Color.White), Stroke = new SvgColourServer(Color.Black), StrokeWidth = 2, X = device.Value - unitBoxWidth / 2, Y = horizontalBase - unitBoxHeight, Width = unitBoxWidth, Height = unitBoxHeight }); groupDevices.Children.Add(new SvgText { Text = device.Key.ToString(), Stroke = new SvgColourServer(Color.Black), X = new SvgUnitCollection { new SvgUnit(device.Value) }, Y = new SvgUnitCollection { new SvgUnit(horizontalBase - unitBoxHeight / 2) }, TextAnchor = SvgTextAnchor.Middle }); } foreach (Sequence sequence in list) { // get the x axis of the two devices we are relating int one = devices[sequence.From]; int two = devices[sequence.To]; groupArrows.Children.Add(new SvgLine { StartX = one, StartY = arrowgen, EndX = two, EndY = arrowgen, MarkerEnd = new Uri("url(#arrow)", UriKind.Relative) }); // get middle of arrow int right = Math.Max(one, two); int left = Math.Min(one, two); int middle = (right - left) / 2; middle = left + middle; groupArrowTexts.Children.Add(new SvgText { Text = sequence.Name, X = new SvgUnitCollection { new SvgUnit(middle) }, Y = new SvgUnitCollection { new SvgUnit(arrowgen - 2) }, TextAnchor = SvgTextAnchor.Middle }); var svgBoxText = new SvgText { X = new SvgUnitCollection { new SvgUnit(descriptionBaseline + 5) }, Y = new SvgUnitCollection { new SvgUnit(arrowgen - 12) } }; svgBoxText.Children.Add(new SvgTextSpan { Text = sequence.Time, TextDecoration = SvgTextDecoration.Underline, X = new SvgUnitCollection { new SvgUnit(descriptionBaseline + 5) }, Dy = new SvgUnitCollection { new SvgUnit(SvgUnitType.Em, 1.2f) } }); int maxstrlen = TextRenderer.MeasureText(sequence.Time, font).Width; var lines = 1; foreach (KeyValuePair <string, string> pair in sequence.Dic) { var both = new SvgTextSpan { X = new SvgUnitCollection { new SvgUnit(descriptionBaseline + 5) }, Dy = new SvgUnitCollection { new SvgUnit(SvgUnitType.Em, 1.2f) } }; string textKey = pair.Key + ": "; string textValue = Functions.RemoveInvalidXMLChars(pair.Value); int strlen = TextRenderer.MeasureText(textKey + textValue, font).Width; if (strlen > maxboxwidth) { // ooof string tv1 = textValue; var tv2 = ""; while (TextRenderer.MeasureText(textKey + tv1, font).Width > maxboxwidth) { tv2 = tv1[tv1.Length - 1] + tv2; tv1 = tv1.Substring(0, tv1.Length - 1); } var keySpan = new SvgTextSpan { Text = textKey, FontWeight = SvgFontWeight.Bold }; var valueSpan1 = new SvgTextSpan { Text = tv1 }; var valueSpan2 = new SvgTextSpan { Text = tv2, X = new SvgUnitCollection { new SvgUnit(descriptionBaseline + 5) }, Dy = new SvgUnitCollection { new SvgUnit(SvgUnitType.Em, 1.2f) } }; both.Children.Add(keySpan); both.Children.Add(valueSpan1); svgBoxText.Children.Add(both); svgBoxText.Children.Add(valueSpan2); lines += 2; } else { var keySpan = new SvgTextSpan { Text = textKey, FontWeight = SvgFontWeight.Bold }; var valueSpan = new SvgTextSpan { Text = textValue }; both.Children.Add(keySpan); both.Children.Add(valueSpan); svgBoxText.Children.Add(both); lines++; } if (strlen > maxstrlen) { maxstrlen = strlen; } } // box height calc, 30 margin + 14 per line. Then have 20 between box bottom and next arrow (at least) var boxheight = (int)(lines * font.Height * 1.02); // draw the box groupDescriptionBoxes.Children.Add(new SvgRectangle { X = descriptionBaseline, Y = arrowgen - 10, Width = maxstrlen, Height = boxheight }); // add text after box groupDescriptionTexts.Children.Add(svgBoxText); // setup next arrow arrowgen += boxheight + 30; } // finally, draw the baselines foreach (KeyValuePair <IPAddress, int> device in devices) { groupBaselines.Children.Add(new SvgLine { StartX = device.Value, StartY = horizontalBase, EndX = device.Value, EndY = arrowgen }); } // now lets make SVG!!! svg.Width = descriptionBaseline + maxboxwidth + 5; svg.Height = arrowgen + 5; svg.ViewBox = new SvgViewBox(0, 0, descriptionBaseline + maxboxwidth + 5, arrowgen + 5); using (FileStream fileStream = File.Create(fileName)) { svg.Write(fileStream); } }