public static UseDrawable Create(SvgUse svgUse, SKRect skViewport, DrawableBase?parent, IAssetLoader assetLoader, HashSet <Uri>?references, DrawAttributes ignoreAttributes = DrawAttributes.None) { var drawable = new UseDrawable(assetLoader, references) { Element = svgUse, Parent = parent, IgnoreAttributes = ignoreAttributes }; drawable.IsDrawable = drawable.CanDraw(svgUse, drawable.IgnoreAttributes) && drawable.HasFeatures(svgUse, drawable.IgnoreAttributes); if (!drawable.IsDrawable) { return(drawable); } if (SvgExtensions.HasRecursiveReference(svgUse, (e) => e.ReferencedElement, new HashSet <Uri>())) { drawable.IsDrawable = false; return(drawable); } var svgReferencedElement = SvgExtensions.GetReference <SvgElement>(svgUse, svgUse.ReferencedElement); if (svgReferencedElement is null) { drawable.IsDrawable = false; return(drawable); } var x = svgUse.X.ToDeviceValue(UnitRenderingType.Horizontal, svgUse, skViewport); var y = svgUse.Y.ToDeviceValue(UnitRenderingType.Vertical, svgUse, skViewport); var width = svgUse.Width.ToDeviceValue(UnitRenderingType.Horizontal, svgUse, skViewport); var height = svgUse.Height.ToDeviceValue(UnitRenderingType.Vertical, svgUse, skViewport); if (width <= 0f) { width = new SvgUnit(SvgUnitType.Percentage, 100f).ToDeviceValue(UnitRenderingType.Horizontal, svgUse, skViewport); } if (height <= 0f) { height = new SvgUnit(SvgUnitType.Percentage, 100f).ToDeviceValue(UnitRenderingType.Vertical, svgUse, skViewport); } var originalReferencedElementParent = svgReferencedElement.Parent; try { if (s_referencedElementParent is { }) { s_referencedElementParent.SetValue(svgReferencedElement, svgUse); } }
protected virtual SvgElement GetSvgElement(int x, int y, Color color) { var use = new SvgUse { X = x * scale, Y = y * scale, ReferencedElement = new Uri("#element", UriKind.Relative), Fill = new SvgColourServer(color) }; return(use); }
public static DrawableBase?Create(SvgElement svgElement, Rect skOwnerBounds, DrawableBase?parent, IAssetLoader assetLoader, Attributes ignoreAttributes = Attributes.None) { return(svgElement switch { SvgAnchor svgAnchor => AnchorDrawable.Create(svgAnchor, skOwnerBounds, parent, assetLoader, ignoreAttributes), SvgFragment svgFragment => FragmentDrawable.Create(svgFragment, skOwnerBounds, parent, assetLoader, ignoreAttributes), SvgImage svgImage => ImageDrawable.Create(svgImage, skOwnerBounds, parent, assetLoader, ignoreAttributes), SvgSwitch svgSwitch => SwitchDrawable.Create(svgSwitch, skOwnerBounds, parent, assetLoader, ignoreAttributes), SvgUse svgUse => UseDrawable.Create(svgUse, skOwnerBounds, parent, assetLoader, ignoreAttributes), SvgCircle svgCircle => CircleDrawable.Create(svgCircle, skOwnerBounds, parent, assetLoader, ignoreAttributes), SvgEllipse svgEllipse => EllipseDrawable.Create(svgEllipse, skOwnerBounds, parent, assetLoader, ignoreAttributes), SvgRectangle svgRectangle => RectangleDrawable.Create(svgRectangle, skOwnerBounds, parent, assetLoader, ignoreAttributes), SvgGroup svgGroup => GroupDrawable.Create(svgGroup, skOwnerBounds, parent, assetLoader, ignoreAttributes), SvgLine svgLine => LineDrawable.Create(svgLine, skOwnerBounds, parent, assetLoader, ignoreAttributes), SvgPath svgPath => PathDrawable.Create(svgPath, skOwnerBounds, parent, assetLoader, ignoreAttributes), SvgPolyline svgPolyline => PolylineDrawable.Create(svgPolyline, skOwnerBounds, parent, assetLoader, ignoreAttributes), SvgPolygon svgPolygon => PolygonDrawable.Create(svgPolygon, skOwnerBounds, parent, assetLoader, ignoreAttributes), SvgText svgText => TextDrawable.Create(svgText, skOwnerBounds, parent, assetLoader, ignoreAttributes), _ => null, });
public static Drawable?Create(SvgElement svgElement, SKRect skOwnerBounds, Drawable?root, Drawable?parent, Attributes ignoreAttributes = Attributes.None) { return(svgElement switch { SvgAnchor svgAnchor => new AnchorDrawable(svgAnchor, skOwnerBounds, root, parent, ignoreAttributes), SvgFragment svgFragment => new FragmentDrawable(svgFragment, skOwnerBounds, root, parent, ignoreAttributes), SvgImage svgImage => new ImageDrawable(svgImage, skOwnerBounds, root, parent, ignoreAttributes), SvgSwitch svgSwitch => new SwitchDrawable(svgSwitch, skOwnerBounds, root, parent, ignoreAttributes), SvgUse svgUse => new UseDrawable(svgUse, skOwnerBounds, root, parent, ignoreAttributes), SvgCircle svgCircle => new CircleDrawable(svgCircle, skOwnerBounds, root, parent, ignoreAttributes), SvgEllipse svgEllipse => new EllipseDrawable(svgEllipse, skOwnerBounds, root, parent, ignoreAttributes), SvgRectangle svgRectangle => new RectangleDrawable(svgRectangle, skOwnerBounds, root, parent, ignoreAttributes), SvgGroup svgGroup => new GroupDrawable(svgGroup, skOwnerBounds, root, parent, ignoreAttributes), SvgLine svgLine => new LineDrawable(svgLine, skOwnerBounds, root, parent, ignoreAttributes), SvgPath svgPath => new PathDrawable(svgPath, skOwnerBounds, root, parent, ignoreAttributes), SvgPolyline svgPolyline => new PolylineDrawable(svgPolyline, skOwnerBounds, root, parent, ignoreAttributes), SvgPolygon svgPolygon => new PolygonDrawable(svgPolygon, skOwnerBounds, root, parent, ignoreAttributes), SvgText svgText => new TextDrawable(svgText, skOwnerBounds, root, parent, ignoreAttributes), _ => null, });
public Use(SvgUse svgUse, SvgVisualElement svgVisualElement) { matrix = SvgHelper.GetSKMatrix(svgUse.Transforms); float x = svgUse.X.ToDeviceValue(null, UnitRenderingType.Horizontal, svgUse); float y = svgUse.Y.ToDeviceValue(null, UnitRenderingType.Vertical, svgUse); var skMatrixTranslateXY = SKMatrix.MakeTranslation(x, y); SKMatrix.Concat(ref matrix, ref matrix, ref skMatrixTranslateXY); var ew = svgUse.Width.ToDeviceValue(null, UnitRenderingType.Horizontal, svgUse); var eh = svgUse.Height.ToDeviceValue(null, UnitRenderingType.Vertical, svgUse); if (ew > 0 && eh > 0) { var _attributes = svgVisualElement.GetType().GetField("_attributes", BindingFlags.NonPublic | BindingFlags.Instance); if (_attributes != null) { var attributes = _attributes.GetValue(svgVisualElement) as SvgAttributeCollection; if (attributes != null) { var viewBox = attributes.GetAttribute <SvgViewBox>("viewBox"); //var viewBox = svgVisualElement.Attributes.GetAttribute<SvgViewBox>("viewBox"); if (viewBox != SvgViewBox.Empty && Math.Abs(ew - viewBox.Width) > float.Epsilon && Math.Abs(eh - viewBox.Height) > float.Epsilon) { var sw = ew / viewBox.Width; var sh = eh / viewBox.Height; var skMatrixTranslateSWSH = SKMatrix.MakeTranslation(sw, sh); SKMatrix.Concat(ref matrix, ref matrix, ref skMatrixTranslateSWSH); } } } //else //{ // throw new Exception("Can not get 'use' referenced element transform."); //} } }
public UseDrawable(SvgUse svgUse, SKRect skOwnerBounds, Drawable?root, Drawable?parent, Attributes ignoreAttributes = Attributes.None) : base(svgUse, root, parent) { IgnoreAttributes = ignoreAttributes; IsDrawable = CanDraw(svgUse, IgnoreAttributes) && HasFeatures(svgUse, IgnoreAttributes); if (!IsDrawable) { return; } if (SvgExtensions.HasRecursiveReference(svgUse, (e) => e.ReferencedElement, new HashSet <Uri>())) { IsDrawable = false; return; } var svgReferencedElement = SvgExtensions.GetReference <SvgElement>(svgUse, svgUse.ReferencedElement); if (svgReferencedElement == null) { IsDrawable = false; return; } float x = svgUse.X.ToDeviceValue(UnitRenderingType.Horizontal, svgUse, skOwnerBounds); float y = svgUse.Y.ToDeviceValue(UnitRenderingType.Vertical, svgUse, skOwnerBounds); float width = svgUse.Width.ToDeviceValue(UnitRenderingType.Horizontal, svgUse, skOwnerBounds); float height = svgUse.Height.ToDeviceValue(UnitRenderingType.Vertical, svgUse, skOwnerBounds); if (width <= 0f) { width = new SvgUnit(SvgUnitType.Percentage, 100f).ToDeviceValue(UnitRenderingType.Horizontal, svgUse, skOwnerBounds); } if (height <= 0f) { height = new SvgUnit(SvgUnitType.Percentage, 100f).ToDeviceValue(UnitRenderingType.Vertical, svgUse, skOwnerBounds); } var originalReferencedElementParent = svgReferencedElement.Parent; var referencedElementParent = default(FieldInfo); try { referencedElementParent = svgReferencedElement.GetType().GetField("_parent", BindingFlags.NonPublic | BindingFlags.Instance); if (referencedElementParent != null) { referencedElementParent.SetValue(svgReferencedElement, svgUse); } } catch (Exception ex) { Debug.WriteLine(ex.Message); Debug.WriteLine(ex.StackTrace); } svgReferencedElement.InvalidateChildPaths(); if (svgReferencedElement is SvgSymbol svgSymbol) { ReferencedDrawable = new SymbolDrawable(svgSymbol, x, y, width, height, skOwnerBounds, root, this, ignoreAttributes); _disposable.Add(ReferencedDrawable); } else { var drawable = DrawableFactory.Create(svgReferencedElement, skOwnerBounds, root, this, ignoreAttributes); if (drawable != null) { ReferencedDrawable = drawable; _disposable.Add(ReferencedDrawable); } else { IsDrawable = false; return; } } IsAntialias = SvgPaintingExtensions.IsAntialias(svgUse); TransformedBounds = ReferencedDrawable.TransformedBounds; Transform = SvgTransformsExtensions.ToSKMatrix(svgUse.Transforms); if (!(svgReferencedElement is SvgSymbol)) { var skMatrixTranslateXY = SKMatrix.MakeTranslation(x, y); Transform = Transform.PreConcat(skMatrixTranslateXY); } Fill = null; Stroke = null; // TODO: Transform _skBounds using _skMatrix. TransformedBounds = Transform.MapRect(TransformedBounds); try { if (referencedElementParent != null) { referencedElementParent.SetValue(svgReferencedElement, originalReferencedElementParent); } } catch (Exception ex) { Debug.WriteLine(ex.Message); Debug.WriteLine(ex.StackTrace); } }
private void button1_Click(object sender, EventArgs e) { /* * L 最低 * M 低 * Q 中等 * H 高 */ FolderBrowserDialog fileDialog = new FolderBrowserDialog { Description = @"请选择保存输出图件的文件夹", ShowNewFolderButton = true, SelectedPath = Environment.CurrentDirectory, }; if (fileDialog.ShowDialog() == DialogResult.OK) { List <QRCodeUrlInfo> qRCodeUrlInfos = new List <QRCodeUrlInfo>(); try { qRCodeUrlInfos = JsonConvert.DeserializeObject <List <QRCodeUrlInfo> >(textBox1.Text); } catch (Exception ex) { MessageBox.Show(ex.Message); } try { string elStr = comboBox1.SelectedItem.ToString().Split(' ')[0]; foreach (QRCodeUrlInfo qRCodeUrlInfo in qRCodeUrlInfos) { WebClient wc = new WebClient(); string xxx = System.Web.HttpUtility.UrlEncode(qRCodeUrlInfo.Url, Encoding.UTF8); string url = "http://www.liantu.com/savevector.php?text=" + xxx + "&el=" + elStr + "&m=15&vt=svg"; string svgFileFullName = fileDialog.SelectedPath + "\\" + qRCodeUrlInfo.Name + ".svg"; string svgTempFileFullName = fileDialog.SelectedPath + "\\" + qRCodeUrlInfo.Name + ".Temp.svg"; wc.DownloadFile(url, svgTempFileFullName); SvgDocument svgDoc = SvgDocument.Open(svgTempFileFullName); SvgUnit minX = SvgUnit.None; SvgUnit minY = SvgUnit.None; SvgUnit maxX = SvgUnit.None; SvgUnit maxY = SvgUnit.None; SvgUnit recWidth = SvgUnit.None; #region 获取真实边框大小 foreach (SvgElement element in svgDoc.Children) { if (element is SvgDefinitionList) { if (element.Children.Count > 0) { if (element.Children[0] is SvgRectangle) { SvgRectangle svgRectangle = element.Children[0] as SvgRectangle; recWidth = svgRectangle.Width; } } SvgDefinitionList svgDefinitionList = element as SvgDefinitionList; } if (element is SvgGroup) { if (element.Children.Count > 0) { if (element.Children[0] is SvgUse) { SvgUse svgUse = element.Children[0] as SvgUse; if (minX.IsNone || minY.IsNone) { minX = svgUse.X; minY = svgUse.Y; } else if (minX.Value > svgUse.X) { minX = svgUse.X; } else if (minY.Value > svgUse.Y) { minY = svgUse.Y; } } if (element.Children[element.Children.Count - 1] is SvgUse) { SvgUse svgUse = element.Children[element.Children.Count - 1] as SvgUse; if (maxX.IsNone || maxY.IsNone) { maxX = svgUse.X; maxY = svgUse.Y; } else if (maxX.Value < svgUse.X) { maxX = svgUse.X; } else if (maxY.Value < svgUse.Y) { maxY = svgUse.Y; } } } } } maxX.Value = maxX.Value - minX.Value + recWidth.Value; maxY.Value = maxY.Value - minY.Value + recWidth.Value; SvgUnitType svgUnitType = minX.Type; #endregion int rowNum = Convert.ToInt32(Math.Floor(maxX.Value / recWidth.Value)); #region 进行位置计算 foreach (SvgElement element in svgDoc.Children) { if (element is SvgRectangle) { SvgRectangle svgRectangle = element as SvgRectangle; svgRectangle.Width = maxX; svgRectangle.Height = maxY; } if (element is SvgGroup) { foreach (SvgElement element2 in element.Children) { SvgUse svgUse = element2 as SvgUse; if (svgUse != null) { svgUse.X = new SvgUnit(svgUnitType, svgUse.X.Value - minX.Value); svgUse.Y = new SvgUnit(svgUnitType, svgUse.Y.Value - minY.Value); } } } } #endregion for (int i = 0; i < svgDoc.Children.Count; i++) { if (svgDoc.Children[i] is SvgRectangle) { SvgRectangle svgRectangle = svgDoc.Children[i] as SvgRectangle; svgRectangle.Width = new SvgUnit(svgUnitType, maxX.Value - recWidth.Value - recWidth.Value); svgRectangle.Height = new SvgUnit(svgUnitType, maxY.Value - recWidth.Value - recWidth.Value); } if (svgDoc.Children[i] is SvgGroup) { SvgElement element = svgDoc.Children[i] as SvgElement; string attribute = string.Empty; element.TryGetAttribute("fill", out attribute); for (int j = element.Children.Count; j > 0; j--) { SvgUse svgUse = element.Children[j - 1] as SvgUse; if (((int)svgUse.Y.Value) + ((int)recWidth.Value) == ((int)maxY.Value) ||// 最后一行 ((int)svgUse.Y.Value) == 0 || // 第一行 ((int)svgUse.X.Value) + ((int)recWidth.Value) == ((int)maxX.Value) || // 最后一列 ((int)svgUse.X.Value) == 0) // 第一列 { // 最后一行 element.Children.RemoveAt(j - 1); } else { if (svgUse != null) { svgUse.X = new SvgUnit(svgUnitType, svgUse.X.Value - recWidth.Value); svgUse.Y = new SvgUnit(svgUnitType, svgUse.Y.Value - recWidth.Value); } } } } } svgDoc.Width = new SvgUnit(svgUnitType, maxX.Value - recWidth.Value - recWidth.Value); svgDoc.Height = new SvgUnit(svgUnitType, maxY.Value - recWidth.Value - recWidth.Value); svgDoc.ViewBox = new SvgViewBox(0, 0, svgDoc.Width.Value, svgDoc.Height.Value); var svgXml = svgDoc.GetXML(); File.WriteAllText(svgFileFullName, svgXml); File.Delete(svgTempFileFullName); } MessageBox.Show(@"导出完成"); } catch (Exception ex) { MessageBox.Show(ex.Message); } } }
public void DrawUse(SvgUse svgUse, bool ignoreDisplay) { if (!CanDraw(svgUse, ignoreDisplay)) { return; } var svgVisualElement = SkiaUtil.GetReference <SvgVisualElement>(svgUse, svgUse.ReferencedElement); if (svgVisualElement == null || SkiaUtil.HasRecursiveReference(svgUse)) { return; } float x = svgUse.X.ToDeviceValue(null, UnitRenderingType.Horizontal, svgUse); float y = svgUse.Y.ToDeviceValue(null, UnitRenderingType.Vertical, svgUse); var skMatrixTranslateXY = SKMatrix.MakeTranslation(x, y); var skMatrix = SkiaUtil.GetSKMatrix(svgUse.Transforms); SKMatrix.PreConcat(ref skMatrix, ref skMatrixTranslateXY); var ew = svgUse.Width.ToDeviceValue(null, UnitRenderingType.Horizontal, svgUse); var eh = svgUse.Height.ToDeviceValue(null, UnitRenderingType.Vertical, svgUse); if (ew > 0 && eh > 0) { var _attributes = svgVisualElement.GetType().GetField("_attributes", BindingFlags.NonPublic | BindingFlags.Instance); if (_attributes != null) { var attributes = _attributes.GetValue(svgVisualElement) as SvgAttributeCollection; if (attributes != null) { var viewBox = attributes.GetAttribute <SvgViewBox>("viewBox"); if (viewBox != SvgViewBox.Empty && Math.Abs(ew - viewBox.Width) > float.Epsilon && Math.Abs(eh - viewBox.Height) > float.Epsilon) { var sw = ew / viewBox.Width; var sh = eh / viewBox.Height; var skMatrixTranslateSWSH = SKMatrix.MakeTranslation(sw, sh); SKMatrix.PreConcat(ref skMatrix, ref skMatrixTranslateSWSH); } } } } var originalParent = svgUse.Parent; var useParent = svgUse.GetType().GetField("_parent", BindingFlags.NonPublic | BindingFlags.Instance); if (useParent != null) { useParent.SetValue(svgVisualElement, svgUse); } svgVisualElement.InvalidateChildPaths(); _skCanvas.Save(); SetTransform(skMatrix); SetClipPath(svgUse, _disposable); var skPaintOpacity = SetOpacity(svgUse, _disposable); var skPaintFilter = SetFilter(svgUse, _disposable); if (svgVisualElement is SvgSymbol svgSymbol) { DrawSymbol(svgSymbol, ignoreDisplay); } else { Draw(svgVisualElement, ignoreDisplay); } if (skPaintFilter != null) { _skCanvas.Restore(); } if (skPaintOpacity != null) { _skCanvas.Restore(); } _skCanvas.Restore(); if (useParent != null) { useParent.SetValue(svgVisualElement, originalParent); } }