private void Init(Group group, Transform transform, StringDictionary style) { if (transform is Transform.Matrix) { var matrix = (Transform.Matrix)transform; group.ScaleX = (matrix.A >= 0 ? 1 : -1) * Math.Sqrt(matrix.A * matrix.A + matrix.C * matrix.C); group.ScaleY = (matrix.D >= 0 ? 1 : -1) * Math.Sqrt(matrix.B * matrix.B + matrix.D * matrix.D); group.Rotation = Math.Atan(matrix.B / matrix.D) * 180 / Math.PI; group.TranslateX = matrix.E; group.TranslateY = matrix.F; } if (transform is Transform.Translate) { var translate = (Transform.Translate)transform; group.TranslateX = translate.Tx; group.TranslateY = translate.Ty; } if (transform is Transform.Scale) { var scale = (Transform.Scale)transform; group.ScaleX = scale.Sx; group.ScaleY = scale.Sy; } if (transform is Transform.Rotate) { var rotate = (Transform.Rotate)transform; group.Rotation = rotate.Angle; group.PivotX = rotate.Cx; group.PivotY = rotate.Cy; } var clipPath = style["clip-path"]; if (!string.IsNullOrEmpty(clipPath) && clipPath != "none") { var match = Regex.Match(clipPath, @"^url\(#(?<key>.+)\)$"); if (!match.Success) { throw new UnsupportedFormatException("Wrong clip-path attribute value."); } var key = match.Groups["key"].Value; foreach (var x in ClipPathHelper.ExtractPaths((SvgClipPath)_map[key])) { var vdClipPath = group.Children.Append <VdClipPath>(); vdClipPath.PathData = x.Path.D; SetFillType(vdClipPath, x.Style["clip-rule"]); vdClipPath.PathData = PathDataFixer.Fix(vdClipPath.PathData); } } }
private void Init(Group group, SvgPath svgPath, StringDictionary parentStyle) { var style = StyleHelper.MergeStyles(parentStyle, svgPath.Style); Init(group, svgPath.Transform, style); var vdPath = group.Children.Append <VdPath>(); vdPath.PathData = PathDataFixer.Fix(svgPath.D); foreach (string key in style.Keys) { var value = style[key]; switch (key) { case "fill": if (value.StartsWith("#")) { vdPath.FillColor = value; } break; case "stroke": if (value.StartsWith("#")) { vdPath.StrokeColor = value; } break; case "stroke-width": vdPath.StrokeWidth = float.Parse(value, CultureInfo.InvariantCulture); break; case "stroke-opacity": vdPath.StrokeAlpha = float.Parse(value, CultureInfo.InvariantCulture); break; case "fill-opacity": vdPath.FillAlpha = float.Parse(value, CultureInfo.InvariantCulture); break; case "stroke-linecap": vdPath.StrokeLineCap = value; break; case "stroke-linejoin": vdPath.StrokeLineJoin = value; break; case "stroke-miterlimit": vdPath.StrokeMiterLimit = value; break; case "fill-rule": SetFillType(vdPath, value); break; case "stroke-dasharray": _isStrokeDasharrayUsed |= value != "none"; break; } } }
private void Init(Group outerGroup, Group innerGroup, Transform transform, StringDictionary style) { if (transform is Transform.Matrix matrix) { if (matrix.A == 0 && matrix.D == 0) { innerGroup.Rotation = 90; innerGroup.ScaleX = matrix.B; innerGroup.ScaleY = -matrix.C; innerGroup.TranslateX = matrix.E; innerGroup.TranslateY = matrix.F; } else if (matrix.A * matrix.C == -matrix.B * matrix.D) { innerGroup.Rotation = MathHelper.ToDegrees(Math.Atan(matrix.B / matrix.A)); innerGroup.ScaleX = Math.Sign(matrix.A) * Math.Sqrt(MathHelper.Square(matrix.A) + MathHelper.Square(matrix.B)); innerGroup.ScaleY = Math.Sign(matrix.D) * Math.Sqrt(MathHelper.Square(matrix.C) + MathHelper.Square(matrix.D)); innerGroup.TranslateX = matrix.E; innerGroup.TranslateY = matrix.F; } else { var svd = DenseMatrix.OfArray(new[, ] { { matrix.A, matrix.C }, { matrix.B, matrix.D } }).Svd(); outerGroup.Rotation = MathHelper.ToDegrees(Math.Atan2(svd.U[1, 0], svd.U[0, 0])); innerGroup.Rotation = MathHelper.ToDegrees(Math.Atan2(svd.VT[1, 0], svd.VT[0, 0])); outerGroup.ScaleX = svd.S[0]; outerGroup.ScaleY = svd.S[1] * svd.U.Determinant(); innerGroup.ScaleY = svd.VT.Determinant(); outerGroup.TranslateX = matrix.E; outerGroup.TranslateY = matrix.F; } } if (transform is Transform.Translate translate) { innerGroup.TranslateX = translate.Tx; innerGroup.TranslateY = translate.Ty; } if (transform is Transform.Scale scale) { innerGroup.ScaleX = scale.Sx; innerGroup.ScaleY = scale.Sy; } if (transform is Transform.Rotate rotate) { innerGroup.Rotation = rotate.Angle; innerGroup.PivotX = rotate.Cx; innerGroup.PivotY = rotate.Cy; } var clipPath = style["clip-path"]; if (!string.IsNullOrEmpty(clipPath) && clipPath != "none") { var match = Regex.Match(clipPath, @"^url\(#(?<key>.+)\)$"); if (!match.Success) { throw new UnsupportedFormatException("Wrong clip-path attribute value."); } var key = match.Groups["key"].Value; foreach (var x in ClipPathHelper.ExtractPaths((G)_map[key])) { var vdClipPath = innerGroup.Children.Append <VdClipPath>(); vdClipPath.PathData = x.Path.D; SetFillType(vdClipPath, x.Style["clip-rule"]); vdClipPath.PathData = PathDataFixer.Fix(vdClipPath.PathData); } } }
private void Init(Group outerGroup, Group innerGroup, SvgPath svgPath, StringDictionary parentStyle) { var style = StyleHelper.MergeStyles(parentStyle, svgPath.Style); Init(outerGroup, innerGroup, svgPath.Transform, style); var fillPath = innerGroup.Children.Append <VdPath>(); var strokePath = fillPath; fillPath.PathData = svgPath.D; if (style.ContainsKey("fill") && SetFillType(fillPath, style["fill-rule"])) { strokePath = innerGroup.Children.Append <VdPath>(); strokePath.PathData = PathDataFixer.Fix(svgPath.D); } fillPath.PathData = PathDataFixer.Fix(fillPath.PathData); foreach (string key in style.Keys) { var value = style[key]; switch (key) { case "fill": if (value.StartsWith("#")) { fillPath.FillColor = value; } break; case "stroke": if (value.StartsWith("#")) { strokePath.StrokeColor = value; } break; case "stroke-width": strokePath.StrokeWidth = (float)UnitConverter.ConvertToPx(value, 0); break; case "stroke-opacity": strokePath.StrokeAlpha *= float.Parse(value, CultureInfo.InvariantCulture); break; case "fill-opacity": fillPath.FillAlpha *= float.Parse(value, CultureInfo.InvariantCulture); break; case "opacity": strokePath.StrokeAlpha *= float.Parse(value, CultureInfo.InvariantCulture); fillPath.FillAlpha *= float.Parse(value, CultureInfo.InvariantCulture); break; case "stroke-linecap": strokePath.StrokeLineCap = value; break; case "stroke-linejoin": strokePath.StrokeLineJoin = value; break; case "stroke-miterlimit": strokePath.StrokeMiterLimit = value; break; case "stroke-dasharray": _isStrokeDasharrayUsed |= value != "none"; break; } } }