예제 #1
0
        /// <summary>
        /// Parse an SVG given as XElement root
        /// </summary>
        public GraphicVisual ParseRoot(XElement root)
        {
            var        nameSpaceAttributes       = root.Attributes().Where(a => a.IsNamespaceDeclaration);
            var        defaultNamespaceAttribute = root.Attributes().Where(a => a.IsNamespaceDeclaration && a.Name.Namespace == XNamespace.None).FirstOrDefault();
            XNamespace defaultNamespace          = defaultNamespaceAttribute.Value;

            Matrix currentTransformationMatrix = Matrix.Identity;

            cssStyleCascade = new CssStyleCascade(root);

            var svgViewBox = new SvgViewBox
            {
                ViewBox = new Rect(0, 0, 100, 100),
                Align   = "none",
                Slice   = "meet"
            };

            cssStyleCascade.PushViewBox(svgViewBox);

            doubleParser = new DoubleParser(cssStyleCascade);
            ReadGlobalDefinitions(root);

            var brushParser    = new BrushParser(defaultNamespace, cssStyleCascade, globalDefinitions, doubleParser);
            var geometryParser = new GeometryParser(doubleParser);

            var geometryTextParser = new GeometryTextParser(cssStyleCascade, doubleParser);

            clipping    = new Clipping(cssStyleCascade, globalDefinitions, geometryParser, geometryTextParser);
            shapeParser = new ShapeParser(cssStyleCascade, brushParser, geometryParser, clipping);
            textParser  = new TextParser(cssStyleCascade, doubleParser, brushParser, clipping);

            GraphicVisual visual = ParseSVG(root, currentTransformationMatrix, true);

            visual = OptimizeVisual.Optimize(visual);

            return(visual);
        }
예제 #2
0
        /// <summary>
        /// Get the viewbox transformation matrix
        /// </summary>
        private (bool, Matrix) GetViewBoxMatrix(XElement element, bool isTopLevel)
        {
            var viewPort = GetViewPort(element, isTopLevel);
            var viewBox  = GetViewBox(element);

            if (viewPort.IsEmpty && viewBox.IsEmpty)
            {
                return(false, Matrix.Identity);
            }

            Matrix matrix;
            bool   newViewBoxPushOnStack = false;
            string align;
            string slice;

            if (viewPort.IsEmpty)
            {
                var svgViewBox = cssStyleCascade.GetCurrentViewBox();
                viewPort = new Rect(0, 0, svgViewBox.ViewBox.Width, svgViewBox.ViewBox.Height);
            }

            if (viewBox.IsEmpty)
            {
                var svgViewBox = cssStyleCascade.GetCurrentViewBox();
                viewBox = svgViewBox.ViewBox;
                align   = svgViewBox.Align;
                slice   = svgViewBox.Slice;
            }
            else
            {
                (align, slice) = GetAlignSlice(element);

                var svgViewBox = new SvgViewBox
                {
                    ViewBox = viewBox,
                    Align   = align,
                    Slice   = slice
                };
                cssStyleCascade.PushViewBox(svgViewBox);

                newViewBoxPushOnStack = true;
            }

            var scaleX = viewPort.Width / viewBox.Width;
            var scaleY = viewPort.Height / viewBox.Height;

            matrix = Matrix.Identity;

            if (align == "none")
            {
                matrix.Translate(-viewBox.X, -viewBox.Y);
                matrix.Scale(scaleX, scaleY);
                matrix.Translate(viewPort.X, viewPort.Y);
            }
            else
            {
                switch (slice)
                {
                case "meet":
                    if (scaleX < scaleY)
                    {
                        scaleY = scaleX;
                    }
                    else
                    {
                        scaleX = scaleY;
                    }
                    break;

                case "slice":
                    if (scaleX > scaleY)
                    {
                        scaleY = scaleX;
                    }
                    else
                    {
                        scaleX = scaleY;
                    }
                    break;

                default:
                    throw new ArgumentException("invalid argument");
                }

                var xOperation = align.Substring(0, 4);
                var yOperation = align.Substring(4, 4);

                double translateX;
                double translateY;

                switch (xOperation)
                {
                case "xmid":
                    translateX = viewBox.Width / 2;
                    break;

                case "xmax":
                    translateX = viewBox.Width;
                    break;

                default:
                    throw new ArgumentException("invalid argument");
                }

                switch (yOperation)
                {
                case "ymid":
                    translateY = viewBox.Height / 2;
                    break;

                case "ymax":
                    translateY = viewBox.Height;
                    break;

                default:
                    throw new ArgumentException("invalid argument");
                }

                matrix.Translate(-viewBox.X - translateX, -viewBox.Y - translateY);
                matrix.Scale(scaleX, scaleY);
                matrix.Translate(viewPort.X + viewPort.Width / 2, viewPort.Y + viewPort.Height / 2);
            }

            return(newViewBoxPushOnStack, matrix);
        }
예제 #3
0
 /// <summary>
 /// Push a new view box on the stack
 /// </summary>
 public void PushViewBox(SvgViewBox svgViewBox)
 {
     svgViewBoxStack.Push(svgViewBox);
 }