Example #1
0
        public void TestCalcAngleBiSector()
        {
            Assert.AreEqual(135, SvgNumber.CalcAngleBisection(180, 90));

            Assert.AreEqual(315, SvgNumber.CalcAngleBisection(90, 180));
            Assert.AreEqual(185, SvgNumber.CalcAngleBisection(280, 90));
            Assert.AreEqual(185, SvgNumber.CalcAngleBisection(0, 370));
        }
        private GradientStopCollection GetGradientStops(XmlNodeList stops)
        {
            int itemCount = stops.Count;
            GradientStopCollection gradientStops = new GradientStopCollection(itemCount);

            double lastOffset = 0;

            for (int i = 0; i < itemCount; i++)
            {
                SvgStopElement stop  = (SvgStopElement)stops.Item(i);
                string         prop  = stop.GetAttribute("stop-color");
                string         style = stop.GetAttribute("style");
                Color          color = Colors.Transparent; // no auto-inherited...
                if (!String.IsNullOrEmpty(prop) || !String.IsNullOrEmpty(style))
                {
                    WpfSvgColor svgColor = new WpfSvgColor(stop, "stop-color");
                    color = svgColor.Color;
                }
                else
                {
                    color = Colors.Black; // the default color...
                    double alpha = 255;
                    string opacity;

                    opacity = stop.GetAttribute("stop-opacity"); // no auto-inherit
                    if (opacity == "inherit")                    // if explicitly defined...
                    {
                        opacity = stop.GetPropertyValue("stop-opacity");
                    }
                    if (opacity != null && opacity.Length > 0)
                    {
                        alpha *= SvgNumber.ParseNumber(opacity);
                    }

                    alpha = Math.Min(alpha, 255);
                    alpha = Math.Max(alpha, 0);

                    color = Color.FromArgb((byte)Convert.ToInt32(alpha),
                                           color.R, color.G, color.B);
                }

                double offset = stop.Offset.AnimVal;

                offset /= 100;
                offset  = Math.Max(lastOffset, offset);

                gradientStops.Add(new GradientStop(color, offset));
                lastOffset = offset;
            }

            if (itemCount == 0)
            {
                gradientStops.Add(new GradientStop(Colors.Black, 0));
                gradientStops.Add(new GradientStop(Colors.Black, 1));
            }

            return(gradientStops);
        }
Example #3
0
        private Tuple <string, ICssValue> ParseValue(string name, string value, string priority, bool presentation)
        {
            var important = priority == "important";

            if (!presentation)
            {
                name = name.ToLower();
            }

            ICssValue parsedValue = null;

            switch (name)
            {
            case "fill":
            case "stroke":
                parsedValue = new SvgPaint(value);
                break;

            case "stroke-width":
                parsedValue = SvgLength.Parse(value, presentation);
                break;

            case "stop-color":
                parsedValue = new SvgColor(value);
                break;

            case "fill-opacity":
            case "stroke-opacity":
            case "stop-opacity":
            case "opacity":
                parsedValue = SvgNumber.Parse(value, 0.0F, 1.0F);
                break;

            case "clip-path":
                parsedValue = new SvgIri(value);
                break;

            case "fill-rule":
            case "clip-rule":
                parsedValue = new SvgFillRule(presentation ? value : value.ToLower());
                break;
            }

            if (!this._cache.ContainsKey(name))
            {
                var result = Tuple.Create(value, parsedValue);
                this._cache.Add(name, result);
                return(result);
            }
            else if (important)
            {
                var result = Tuple.Create(value, parsedValue);
                this._cache[name] = result;
                return(result);
            }

            return(null);
        }
        public override void Render(ISvgRenderer renderer)
        {
            GraphicsWrapper graphics = ((GdiRenderer)renderer).GraphicsWrapper;
            SvgImageElement iElement = (SvgImageElement)element;
            //HttpResource resource = iElement.ReferencedResource;

            /*if (resource != null )
             * {*/
            ImageAttributes imageAttributes = new ImageAttributes();

            string sOpacity = iElement.GetPropertyValue("opacity");

            if (sOpacity.Length > 0)
            {
                double      opacity       = SvgNumber.ParseToFloat(sOpacity);
                ColorMatrix myColorMatrix = new ColorMatrix();
                myColorMatrix.Matrix00 = 1.00f;                         // Red
                myColorMatrix.Matrix11 = 1.00f;                         // Green
                myColorMatrix.Matrix22 = 1.00f;                         // Blue
                myColorMatrix.Matrix33 = (float)opacity;                // alpha
                myColorMatrix.Matrix44 = 1.00f;                         // w

                imageAttributes.SetColorMatrix(myColorMatrix, ColorMatrixFlag.Default, ColorAdjustType.Bitmap);
            }

            float width  = (float)iElement.Width.AnimVal.Value;
            float height = (float)iElement.Height.AnimVal.Value;

            Rectangle destRect = new Rectangle();

            destRect.X      = Convert.ToInt32(iElement.X.AnimVal.Value);
            destRect.Y      = Convert.ToInt32(iElement.Y.AnimVal.Value);
            destRect.Width  = Convert.ToInt32(width);
            destRect.Height = Convert.ToInt32(height);

            Image image;

            if (iElement.IsSvgImage)
            {
                SvgWindow wnd = getSvgWindow();
                gdiRenderer.BackColor = Color.Empty;
                gdiRenderer.Render(wnd.Document as SvgDocument);

                //wnd.Render();
                image = gdiRenderer.RasterImage;
                image.Save(@"c:\inlinesvg.png", ImageFormat.Png);
            }
            else
            {
                image = iElement.Bitmap;
            }

            if (image != null)
            {
                graphics.DrawImage(this, image, destRect, 0f, 0f, image.Width, image.Height, GraphicsUnit.Pixel, imageAttributes);
            }
            //}
        }
Example #5
0
        public static GradientStopCollection ToGradientStops(System.Xml.XmlNodeList stops)
        {
            int itemCount = stops.Count;
            GradientStopCollection gradientStops = new GradientStopCollection(itemCount);

            double lastOffset = 0;

            for (int i = 0; i < itemCount; i++)
            {
                SvgStopElement stop  = (SvgStopElement)stops.Item(i);
                string         prop  = stop.GetAttribute("stop-color");
                string         style = stop.GetAttribute("style");
                Color          color = Colors.Transparent; // no auto-inherited...
                if (!string.IsNullOrWhiteSpace(prop) || !string.IsNullOrWhiteSpace(style))
                {
                    SvgColor svgColor = new SvgColor(stop.GetComputedStyle(string.Empty).GetPropertyValue("stop-color"));
                    if (svgColor.ColorType == SvgColorType.CurrentColor)
                    {
                        string sCurColor = stop.GetComputedStyle(string.Empty).GetPropertyValue(CssConstants.PropColor);
                        svgColor = new SvgColor(sCurColor);
                    }
                    TryConvertColor(svgColor.RgbColor, out color);
                }
                else
                {
                    color = Colors.Black; // the default color...
                }

                double alpha = 255;
                string opacity;

                opacity = stop.GetAttribute("stop-opacity"); // no auto-inherit
                if (opacity == "inherit")                    // if explicitly defined...
                {
                    opacity = stop.GetPropertyValue("stop-opacity");
                }
                if (!string.IsNullOrWhiteSpace(opacity))
                {
                    alpha *= SvgNumber.ParseNumber(opacity);
                }

                alpha = Math.Min(alpha, 255);
                alpha = Math.Max(alpha, 0);

                color = Color.FromArgb((byte)Convert.ToInt32(alpha),
                                       color.R, color.G, color.B);

                double offset = stop.Offset.AnimVal;

                offset /= 100;
                offset  = Math.Max(lastOffset, offset);

                gradientStops.Add(new GradientStop(color, offset));
                lastOffset = offset;
            }

            return(gradientStops);
        }
Example #6
0
        private void RenderTSpanPath(SvgTSpanElement element, WpfPathTextBuilder pathBuilder, ref Point ctp)
        {
            WpfTextPlacement placement = WpfTextPlacement.Create(element, ctp, true);

            ctp = placement.Location;
            double rotate = placement.Rotation;

            if (!placement.HasPositions)
            {
                placement = null; // Render it useless.
            }

            string sBaselineShift = element.GetPropertyValue("baseline-shift").Trim();
            double shiftBy        = 0;

            var comparer = StringComparison.OrdinalIgnoreCase;

            if (sBaselineShift.Length > 0)
            {
                SvgTextBaseElement textElement = (SvgTextBaseElement)element.SelectSingleNode("ancestor::svg:text",
                                                                                              element.OwnerDocument.NamespaceManager);

                double textFontSize = GetComputedFontSize(textElement);
                if (sBaselineShift.EndsWith("%", comparer))
                {
                    shiftBy = SvgNumber.ParseNumber(sBaselineShift.Substring(0,
                                                                             sBaselineShift.Length - 1)) / 100f * textFontSize;
                }
                else if (string.Equals(sBaselineShift, "sub", comparer))
                {
                    shiftBy = -0.6F * textFontSize;
                }
                else if (string.Equals(sBaselineShift, "super", comparer))
                {
                    shiftBy = 0.6F * textFontSize;
                }
                else if (string.Equals(sBaselineShift, "baseline", comparer))
                {
                    shiftBy = 0;
                }
                else
                {
                    shiftBy = SvgNumber.ParseNumber(sBaselineShift);
                }
            }

            foreach (XmlNode child in element.ChildNodes)
            {
                if (child.NodeType == XmlNodeType.Text)
                {
                    ctp.Y -= shiftBy;
                    RenderTextPath(element, pathBuilder, GetText(element, child),
                                   new Point(ctp.X, ctp.Y), rotate, placement);
                    ctp.Y += shiftBy;
                }
            }
        }
Example #7
0
        private void RenderTSpanPath(SvgTSpanElement element, WpfTextOnPathDrawing pathDrawing,
                                     ref Point ctp)
        {
            WpfTextPlacement placement = GetCurrentTextPosition(element, ctp);

            ctp = placement.Location;
            double rotate = placement.Rotation;

            if (!placement.HasPositions)
            {
                placement = null; // Render it useless.
            }

            string sBaselineShift = element.GetPropertyValue("baseline-shift").Trim();
            double shiftBy        = 0;

            if (sBaselineShift.Length > 0)
            {
                SvgTextElement textElement = (SvgTextElement)element.SelectSingleNode("ancestor::svg:text",
                                                                                      element.OwnerDocument.NamespaceManager);

                double textFontSize = GetComputedFontSize(textElement);
                if (sBaselineShift.EndsWith("%"))
                {
                    shiftBy = SvgNumber.ParseNumber(sBaselineShift.Substring(0,
                                                                             sBaselineShift.Length - 1)) / 100f * textFontSize;
                }
                else if (sBaselineShift == "sub")
                {
                    shiftBy = -0.6F * textFontSize;
                }
                else if (sBaselineShift == "super")
                {
                    shiftBy = 0.6F * textFontSize;
                }
                else if (sBaselineShift == "baseline")
                {
                    shiftBy = 0;
                }
                else
                {
                    shiftBy = SvgNumber.ParseNumber(sBaselineShift);
                }
            }

            foreach (XmlNode child in element.ChildNodes)
            {
                if (child.NodeType == XmlNodeType.Text)
                {
                    ctp.Y -= shiftBy;
                    RenderTextPath(element, pathDrawing, GetText(element, child),
                                   new Point(ctp.X, ctp.Y), rotate, placement);
                    ctp.Y += shiftBy;
                }
            }
        }
Example #8
0
        private void diffAndBisectTest(SvgPathSegList list, int startSeg, float expectedDiff, float expectedBisect)
        {
            float diff   = SvgNumber.CalcAngleDiff(((SvgPathSeg)list[startSeg]).EndAngle, ((SvgPathSeg)list[startSeg + 1]).StartAngle);
            float bisect = SvgNumber.CalcAngleBisection(((SvgPathSeg)list[startSeg]).EndAngle, ((SvgPathSeg)list[startSeg + 1]).StartAngle);

            string label = startSeg + "-" + (startSeg + 1);

            floatsTest(label + " diff", expectedDiff, diff);
            floatsTest(label + " bisect", expectedBisect, bisect);
        }
Example #9
0
        private Color?GetNodeColor(ISvgElement targetNode, string property)
        {
            //StyleColor fillColor = new StyleColor();
            //fillColor.FillType = ColorFillType.Solid;
            string szRGB         = null;
            string szOpacity     = null;
            string szNodeopacity = null;


            if (targetNode.RenderingHint == SvgRenderingHint.Text || targetNode.RenderingHint == SvgRenderingHint.Shape)
            {
                szRGB         = (targetNode as SvgElement).GetComputedStyle("").GetPropertyValue(property);
                szOpacity     = (targetNode as SvgElement).GetComputedStyle("").GetPropertyValue(property + @"-opacity");
                szNodeopacity = (targetNode as SvgElement).GetComputedStyle("").GetPropertyValue("opacity");

                if (string.IsNullOrEmpty(szRGB))
                {
                    return(null);
                }
            }

            //Get RGB Color
            SvgPaint paint = new SvgPaint(szRGB);

            if (paint.RgbColor == null)
            {
                return(null);
            }
            Color?solidColor = WpfConvert.ToColor(paint.RgbColor);

            if (solidColor == null)
            {
                return(null);
            }

            //Get Aplha
            Color result = solidColor.Value;

            if (szNodeopacity != null || szOpacity != null)
            {
                double opacityValue = 1;
                if (szNodeopacity != null && szNodeopacity.Length > 0)
                {
                    opacityValue *= SvgNumber.ParseNumber(szNodeopacity);
                }
                else if (szOpacity != null && szOpacity.Length > 0)
                {
                    opacityValue *= SvgNumber.ParseNumber(szOpacity);
                }
                opacityValue = Math.Min(opacityValue, 1);
                opacityValue = Math.Max(opacityValue, 0);
                result.A     = Convert.ToByte(opacityValue * 255);
            }
            return(result);
        }
Example #10
0
 public void TestCalcAngleDiff()
 {
     Assert.AreEqual(107, SvgNumber.CalcAngleDiff(197, 90));
     Assert.AreEqual(287, SvgNumber.CalcAngleDiff(197, -90));
     Assert.AreEqual(287, SvgNumber.CalcAngleDiff(197, 270));
     Assert.AreEqual(186, SvgNumber.CalcAngleDiff(23, 197));
     Assert.AreEqual(230, SvgNumber.CalcAngleDiff(230, 0));
     Assert.AreEqual(0, SvgNumber.CalcAngleDiff(360, 0));
     Assert.AreEqual(15, SvgNumber.CalcAngleDiff(375, 0));
     Assert.AreEqual(345, SvgNumber.CalcAngleDiff(0, 375));
 }
        public override void Render(WpfDrawingRenderer renderer)
        {
            if (_drawGroup != null)
            {
                Geometry clipGeom = this.ClipGeometry;
                if (clipGeom != null)
                {
                    _drawGroup.ClipGeometry = clipGeom;
                }

                Transform transform = this.Transform;
                if (transform != null)
                {
                    _drawGroup.Transform = transform;
                }

                float opacityValue = -1;

                SvgGElement element = (SvgGElement)_svgElement;
                string      opacity = element.GetAttribute("opacity");
                if (string.IsNullOrWhiteSpace(opacity))
                {
                    opacity = element.GetPropertyValue("opacity");
                }
                if (!string.IsNullOrWhiteSpace(opacity))
                {
                    opacityValue = (float)SvgNumber.ParseNumber(opacity);
                    opacityValue = Math.Min(opacityValue, 1);
                    opacityValue = Math.Max(opacityValue, 0);
                }

                if (opacityValue >= 0 && opacityValue < 1)
                {
                    _drawGroup.Opacity = opacityValue;
                }

                string sVisibility = element.GetPropertyValue("visibility");
                string sDisplay    = element.GetPropertyValue("display");
                if (string.Equals(sVisibility, "hidden") || string.Equals(sDisplay, "none"))
                {
                    _drawGroup.Opacity = 0;
                }
            }

            // Register this drawing with the Drawing-Document...
            this.Rendered(_drawGroup);

            base.Render(renderer);
        }
Example #12
0
        private double GetMiterLimit(double strokeWidth)
        {
            // Use this to prevent the default value of "4" being used...
            string miterLimitAttr = _element.GetAttribute("stroke-miterlimit");

            if (String.IsNullOrEmpty(miterLimitAttr))
            {
                string strokeLinecap = _element.GetAttribute("stroke-linecap");
                if (String.Equals(strokeLinecap, "round", StringComparison.OrdinalIgnoreCase))
                {
                    return(1.0d);
                }
                return(-1.0d);
            }

            string miterLimitStr = _element.GetPropertyValue("stroke-miterlimit");

            if (String.IsNullOrEmpty(miterLimitStr) || (float)(strokeWidth) <= 0)
            {
                return(-1.0d);
            }

            double miterLimit = SvgNumber.ParseNumber(miterLimitStr);

            if (miterLimit < 1)
            {
                throw new SvgException(SvgExceptionType.SvgInvalidValueErr,
                                       "stroke-miterlimit can not be less then 1");
            }

            //if (miterLimit < 1.0d)
            //{
            //    return -1.0d;
            //}

            double ratioLimit = miterLimit / strokeWidth;

            if (ratioLimit >= 1.8d)
            {
                return(miterLimit);
            }
            else
            {
                return(1.0d);
            }
        }
        private void AddTSpanElementPath(SvgTSpanElement element, ref PointF ctp)
        {
            ctp = GetCurrentTextPosition(element, ctp);
            string sBaselineShift = element.GetPropertyValue("baseline-shift").Trim();
            double shiftBy        = 0;

            if (sBaselineShift.Length > 0)
            {
                SvgTextBaseElement textElement = (SvgTextBaseElement)element.SelectSingleNode("ancestor::svg:text",
                                                                                              element.OwnerDocument.NamespaceManager);

                float textFontSize = GetComputedFontSize(textElement);
                if (sBaselineShift.EndsWith("%", StringComparison.OrdinalIgnoreCase))
                {
                    shiftBy = SvgNumber.ParseNumber(sBaselineShift.Substring(0,
                                                                             sBaselineShift.Length - 1)) / 100 * textFontSize;
                }
                else if (sBaselineShift == "sub")
                {
                    shiftBy = -0.6F * textFontSize;
                }
                else if (sBaselineShift == "super")
                {
                    shiftBy = 0.6F * textFontSize;
                }
                else if (sBaselineShift == "baseline")
                {
                    shiftBy = 0;
                }
                else
                {
                    shiftBy = SvgNumber.ParseNumber(sBaselineShift);
                }
            }

            foreach (XmlNode child in element.ChildNodes)
            {
                if (child.NodeType == XmlNodeType.Text)
                {
                    ctp.Y -= (float)shiftBy;
                    AddGraphicsPath(element, ref ctp, GetText(element, child));
                    ctp.Y += (float)shiftBy;
                }
            }
        }
        private float GetMiterLimit()
        {
            string miterLimitStr = _element.GetPropertyValue("stroke-miterlimit");

            if (miterLimitStr.Length == 0)
            {
                miterLimitStr = "4";
            }

            float miterLimit = (float)SvgNumber.ParseNumber(miterLimitStr);

            if (miterLimit < 1)
            {
                throw new SvgException(SvgExceptionType.SvgInvalidValueErr, "stroke-miterlimit can not be less then 1");
            }

            return(miterLimit);
        }
Example #15
0
        public static double GetOpacity(SvgStyleableElement element, string fillOrStroke)
        {
            double opacityValue = 1;

            string opacity = element.GetPropertyValue(fillOrStroke + "-opacity");

            if (opacity != null && opacity.Length > 0)
            {
                opacityValue *= SvgNumber.ParseNumber(opacity);
            }

            opacity = element.GetPropertyValue("opacity");
            if (opacity != null && opacity.Length > 0)
            {
                opacityValue *= SvgNumber.ParseNumber(opacity);
            }

            opacityValue = Math.Min(opacityValue, 1);
            opacityValue = Math.Max(opacityValue, 0);

            return(opacityValue);
        }
Example #16
0
        private double GetOpacity(string fillOrStroke)
        {
            double opacityValue = 1;

            string opacity = _element.GetPropertyValue(fillOrStroke + "-opacity");

            if (opacity != null && opacity.Length > 0)
            {
                opacityValue *= SvgNumber.ParseNumber(opacity);
            }

            opacity = _element.GetPropertyValue("opacity");
            if (opacity != null && opacity.Length > 0)
            {
                opacityValue *= SvgNumber.ParseNumber(opacity);
            }

            opacityValue = Math.Min(opacityValue, 1);
            opacityValue = Math.Max(opacityValue, 0);

            return(opacityValue);
        }
Example #17
0
        private double GetOpacity(string fillOrStroke)
        {
            double opacityValue = 1;

            string opacity = _element.GetPropertyValue(fillOrStroke + "-opacity");

            if (!string.IsNullOrWhiteSpace(opacity))
            {
                opacityValue *= SvgNumber.ParseNumber(opacity);
            }

            opacity = _element.GetPropertyValue("opacity");
            if (!string.IsNullOrWhiteSpace(opacity))
            {
                opacityValue *= SvgNumber.ParseNumber(opacity);
            }

            opacityValue = Math.Min(opacityValue, 1);
            opacityValue = Math.Max(opacityValue, 0);

            return(opacityValue);
        }
        private int GetOpacity(string fillOrStroke)
        {
            double alpha = 255;
            string opacity;

            opacity = _element.GetPropertyValue(fillOrStroke + "-opacity");
            if (opacity.Length > 0)
            {
                alpha *= SvgNumber.ParseNumber(opacity);
            }

            opacity = _element.GetPropertyValue("opacity");
            if (opacity.Length > 0)
            {
                alpha *= SvgNumber.ParseNumber(opacity);
            }

            alpha = Math.Min(alpha, 255);
            alpha = Math.Max(alpha, 0);

            return(Convert.ToInt32(alpha));
        }
Example #19
0
        public static bool TryGetMiterLimit(SvgStyleableElement element, double strokeWidth, out double miterLimit)
        {
            string miterLimitAttr = element.GetAttribute("stroke-miterlimit");

            if (string.IsNullOrWhiteSpace(miterLimitAttr))
            {
                string strokeLinecap = element.GetAttribute("stroke-linecap");
                if (string.Equals(strokeLinecap, "round", StringComparison.OrdinalIgnoreCase))
                {
                    miterLimit = 1.0d;
                    return(true);
                }
                miterLimit = -1.0d;
                return(false);
            }

            string miterLimitStr = element.GetPropertyValue("stroke-miterlimit");

            if (string.IsNullOrWhiteSpace(miterLimitStr) || strokeWidth <= 0)
            {
                miterLimit = -1.0d;
                return(false);
            }

            miterLimit = SvgNumber.ParseNumber(miterLimitStr);
            if (miterLimit < 1)
            {
                return(false);
            }

            double ratioLimit = miterLimit / strokeWidth;

            if (ratioLimit < 1.8d)
            {
                miterLimit = 1.0d;
            }
            return(true);
        }
Example #20
0
        public void RenderMarker(WpfDrawingRenderer renderer, WpfDrawingContext gr,
                                 SvgMarkerPosition markerPos, SvgStyleableElement refElement)
        {
            ISharpMarkerHost markerHostElm = (ISharpMarkerHost)refElement;

            SvgPointF[] vertexPositions = markerHostElm.MarkerPositions;
            int         start           = 0;
            int         len             = 0;

            // Choose which part of the position array to use
            switch (markerPos)
            {
            case SvgMarkerPosition.Start:
                start = 0;
                len   = 1;
                break;

            case SvgMarkerPosition.Mid:
                start = 1;
                len   = vertexPositions.Length - 2;
                break;

            default:
                // == MarkerPosition.End
                start = vertexPositions.Length - 1;
                len   = 1;
                break;
            }
            int end = start + len;

            TransformGroup transform = new TransformGroup();

            for (int i = start; i < end; i++)
            {
                SvgPointF point = vertexPositions[i];

                //GdiGraphicsContainer gc = gr.BeginContainer();

                this.BeforeRender(renderer);

                //Matrix matrix = Matrix.Identity;

                Matrix matrix = GetTransformMatrix(_svgElement, transform);

                ISvgAnimatedEnumeration orientType = _markerElement.OrientType;

                if (orientType.AnimVal.Equals((ushort)SvgMarkerOrient.Angle))
                {
                    double scaleValue = _markerElement.OrientAngle.AnimVal.Value;
                    if (!scaleValue.Equals(0))
                    {
                        matrix.Rotate(scaleValue);
                        transform.Children.Add(new RotateTransform(scaleValue));
                    }
                }
                else
                {
                    bool isAutoReverse = orientType.AnimVal.Equals((ushort)SvgMarkerOrient.AutoStartReverse);

                    double angle = 0;
                    switch (markerPos)
                    {
                    case SvgMarkerPosition.Start:
                        angle = markerHostElm.GetStartAngle(i);
                        //angle = markerHostElm.GetStartAngle(i + 1);
                        if (vertexPositions.Length >= 2)
                        {
                            SvgPointF pMarkerPoint1 = vertexPositions[start];
                            SvgPointF pMarkerPoint2 = vertexPositions[end];
                            float     xDiff         = pMarkerPoint2.X - pMarkerPoint1.X;
                            float     yDiff         = pMarkerPoint2.Y - pMarkerPoint1.Y;
                            double    angleMarker   = (float)(Math.Atan2(yDiff, xDiff) * 180.0 / Math.PI);
                            if (!angleMarker.Equals(angle))
                            {
                                angle = angleMarker;
                            }
                        }
                        // A value of 'auto-start-reverse' means the same as 'auto' except that for a
                        // marker placed by 'marker-start', the orientation is 180° different from
                        // the orientation as determined by 'auto'.
                        if (isAutoReverse)
                        {
                            angle += 180;
                        }
                        break;

                    case SvgMarkerPosition.Mid:
                        //angle = (markerHostElm.GetEndAngle(i) + markerHostElm.GetStartAngle(i + 1)) / 2;
                        angle = SvgNumber.CalcAngleBisection(markerHostElm.GetEndAngle(i), markerHostElm.GetStartAngle(i + 1));
                        break;

                    default:
                        angle = markerHostElm.GetEndAngle(i - 1);
                        //angle = markerHostElm.GetEndAngle(i);
                        if (vertexPositions.Length >= 2)
                        {
                            SvgPointF pMarkerPoint1 = vertexPositions[start - 1];
                            SvgPointF pMarkerPoint2 = vertexPositions[start];
                            float     xDiff         = pMarkerPoint2.X - pMarkerPoint1.X;
                            float     yDiff         = pMarkerPoint2.Y - pMarkerPoint1.Y;
                            double    angleMarker   = (float)(Math.Atan2(yDiff, xDiff) * 180.0 / Math.PI);
                            if (!angleMarker.Equals(angle))
                            {
                                angle = angleMarker;
                            }
                        }
                        break;
                    }
                    matrix.Rotate(angle);
                    transform.Children.Add(new RotateTransform(angle));
                }

                // 'viewBox' and 'preserveAspectRatio' attributes
                // viewBox -> viewport(0, 0, markerWidth, markerHeight)
                SvgPreserveAspectRatio spar = (SvgPreserveAspectRatio)_markerElement.PreserveAspectRatio.AnimVal;
                double[] translateAndScale  = spar.FitToViewBox((SvgRect)_markerElement.ViewBox.AnimVal,
                                                                new SvgRect(0, 0, _markerElement.MarkerWidth.AnimVal.Value, _markerElement.MarkerHeight.AnimVal.Value));

                // Warning at this time, refX and refY are relative to the painted element's coordinate system.
                // We need to move the reference point to the marker's coordinate system
                double refX = _markerElement.RefX.AnimVal.Value;
                double refY = _markerElement.RefY.AnimVal.Value;

                if (!(refX.Equals(0) && refY.Equals(0)))
                {
                    var ptRef = matrix.Transform(new Point(refX, refY));

                    refX = ptRef.X;
                    refY = ptRef.Y;

                    matrix.Translate(-refX, -refY);
                    transform.Children.Add(new TranslateTransform(-refX, -refY));
                }

                //matrix.Translate(-markerElm.RefX.AnimVal.Value * translateAndScale[2],
                //    -markerElm.RefY.AnimVal.Value * translateAndScale[3]);
                //transform.Children.Add(new TranslateTransform(-markerElm.RefX.AnimVal.Value * translateAndScale[2],
                //    -markerElm.RefY.AnimVal.Value * translateAndScale[3]));

                // compute an additional transform for 'strokeWidth' coordinate system
                ISvgAnimatedEnumeration markerUnits = _markerElement.MarkerUnits;
                if (markerUnits.AnimVal.Equals((ushort)SvgMarkerUnit.StrokeWidth))
                {
                    SvgLength strokeWidthLength = new SvgLength(refElement,
                                                                "stroke-width", SvgLengthSource.Css, SvgLengthDirection.Viewport, "1");
                    double strokeWidth = strokeWidthLength.Value;
                    if (!strokeWidth.Equals(1))
                    {
                        matrix.Scale(strokeWidth, strokeWidth);
                        transform.Children.Add(new ScaleTransform(strokeWidth, strokeWidth));
                    }
                }

                if (!(translateAndScale[2].Equals(1) && translateAndScale[3].Equals(1)))
                {
                    matrix.Scale(translateAndScale[2], translateAndScale[3]);
                    transform.Children.Add(new ScaleTransform(translateAndScale[2], translateAndScale[3]));
                }

                matrix.Translate(point.X, point.Y);
                transform.Children.Add(new TranslateTransform(point.X, point.Y));

                _matrix = matrix;

                this.Transform = transform;

                this.Render(renderer);

                //Clip(gr);

                renderer.RenderChildren(_markerElement);

                //gr.EndContainer(gc);

                this.AfterRender(renderer);
            }
        }
        public override void Render(WpfDrawingRenderer renderer)
        {
            Geometry  clipGeom  = this.ClipGeometry;
            Transform transform = this.Transform;

            WpfDrawingContext context = renderer.Context;

            SvgSwitchElement switchElement = (SvgSwitchElement)_svgElement;

            string elementId = this.GetElementName();

            float opacityValue = -1;

            string opacity = switchElement.GetAttribute("opacity");

            if (string.IsNullOrWhiteSpace(opacity))
            {
                opacity = switchElement.GetPropertyValue("opacity");
            }
            if (!string.IsNullOrWhiteSpace(opacity))
            {
                opacityValue = (float)SvgNumber.ParseNumber(opacity);
                opacityValue = Math.Min(opacityValue, 1);
                opacityValue = Math.Max(opacityValue, 0);
            }

            if (clipGeom != null || transform != null || (opacityValue >= 0 && opacityValue < 1) ||
                (!string.IsNullOrWhiteSpace(elementId) && !context.IsRegisteredId(elementId)))
            {
                _drawGroup = new DrawingGroup();

                DrawingGroup currentGroup = context.Peek();

                if (currentGroup == null)
                {
                    throw new InvalidOperationException("An existing group is expected.");
                }

                currentGroup.Children.Add(_drawGroup);
                context.Push(_drawGroup);

                if (clipGeom != null)
                {
                    _drawGroup.ClipGeometry = clipGeom;
                }

                if (transform != null)
                {
                    _drawGroup.Transform = transform;
                }

                if (opacityValue >= 0 && opacityValue < 1)
                {
                    _drawGroup.Opacity = opacityValue;
                }

                if (!string.IsNullOrWhiteSpace(elementId) && !context.IsRegisteredId(elementId))
                {
                    SvgObject.SetName(_drawGroup, elementId);

                    context.RegisterId(elementId);

                    if (context.IncludeRuntime)
                    {
                        SvgObject.SetId(_drawGroup, elementId);
                    }
                }
            }

            base.Render(renderer);
        }
        private double[] FitToViewBox(SvgPreserveAspectRatioType alignment, SvgRect viewBox, SvgRect rectToFit)
        {
            double translateX = 0;
            double translateY = 0;
            double scaleX     = 1;
            double scaleY     = 1;

            if (!viewBox.IsEmpty)
            {
                // calculate scale values for non-uniform scaling
                scaleX = rectToFit.Width / viewBox.Width;
                scaleY = rectToFit.Height / viewBox.Height;

                if (alignment != SvgPreserveAspectRatioType.None)
                {
                    // uniform scaling
                    scaleX = Math.Max(scaleX, scaleY);

                    scaleY = scaleX;

                    if (alignment == SvgPreserveAspectRatioType.XMidYMax ||
                        alignment == SvgPreserveAspectRatioType.XMidYMid ||
                        alignment == SvgPreserveAspectRatioType.XMidYMin)
                    {
                        // align to the Middle X
                        translateX = (rectToFit.X + rectToFit.Width / 2) - scaleX * (viewBox.X + viewBox.Width / 2);
                    }
                    else if (alignment == SvgPreserveAspectRatioType.XMaxYMax ||
                             alignment == SvgPreserveAspectRatioType.XMaxYMid ||
                             alignment == SvgPreserveAspectRatioType.XMaxYMin)
                    {
                        // align to the right X
                        translateX = (rectToFit.Width - viewBox.Width * scaleX);
                    }

                    if (alignment == SvgPreserveAspectRatioType.XMaxYMid ||
                        alignment == SvgPreserveAspectRatioType.XMidYMid ||
                        alignment == SvgPreserveAspectRatioType.XMinYMid)
                    {
                        // align to the Middle Y
                        translateY = (rectToFit.Y + rectToFit.Height / 2) - scaleY * (viewBox.Y + viewBox.Height / 2);
                    }
                    else if (alignment == SvgPreserveAspectRatioType.XMaxYMax ||
                             alignment == SvgPreserveAspectRatioType.XMidYMax ||
                             alignment == SvgPreserveAspectRatioType.XMinYMax)
                    {
                        // align to the bottom Y
                        translateY = (rectToFit.Height - viewBox.Height * scaleY);
                    }
                }
                else
                {
                    translateX = -viewBox.X * scaleX;
                    translateY = -viewBox.Y * scaleY;
                }
            }

            if (!SvgNumber.IsValid(translateX))
            {
                translateX = 0;
            }
            if (!SvgNumber.IsValid(translateY))
            {
                translateY = 0;
            }
            if (!SvgNumber.IsValid(scaleX))
            {
                scaleX = 1;
            }
            if (!SvgNumber.IsValid(scaleY))
            {
                scaleY = 1;
            }

            return(new double[] { translateX, translateY, scaleX, scaleY });
        }
        private void AddTSpanElementRun(SvgTSpanElement element, ref Point ctp,
                                        bool isVertical, bool isSingleLine)
        {
            WpfTextPlacement placement = WpfTextRenderer.GetCurrentTextPosition(element, ctp);

            ctp = placement.Location;
            double rotate = placement.Rotation;

            if (!placement.HasPositions)
            {
                placement = null; // render it useless
            }

            string sBaselineShift = element.GetPropertyValue("baseline-shift").Trim();
            double shiftBy        = 0;

            if (sBaselineShift.Length > 0)
            {
                double textFontSize = WpfTextRenderer.GetComputedFontSize(_textElement);
                if (sBaselineShift.EndsWith("%", StringComparison.OrdinalIgnoreCase))
                {
                    shiftBy = SvgNumber.ParseNumber(sBaselineShift.Substring(0,
                                                                             sBaselineShift.Length - 1)) / 100f * textFontSize;
                }
                else if (sBaselineShift == "sub")
                {
                    shiftBy = -0.6F * textFontSize;
                }
                else if (sBaselineShift == "super")
                {
                    shiftBy = 0.6F * textFontSize;
                }
                else if (sBaselineShift == "baseline")
                {
                    shiftBy = 0;
                }
                else
                {
                    shiftBy = SvgNumber.ParseNumber(sBaselineShift);
                }
            }

            foreach (XmlNode child in element.ChildNodes)
            {
                if (child.NodeType == XmlNodeType.Text)
                {
                    if (isVertical)
                    {
                        ctp.X += shiftBy;
                        if (isSingleLine)
                        {
                            RenderSingleLineTextV(element, ref ctp,
                                                  WpfTextRenderer.GetText(element, child), rotate, placement);
                        }
                        else
                        {
                            RenderTextRunV(element, ref ctp,
                                           WpfTextRenderer.GetText(element, child), rotate, placement);
                        }
                        ctp.X -= shiftBy;
                    }
                    else
                    {
                        ctp.Y -= shiftBy;
                        if (isSingleLine)
                        {
                            RenderSingleLineTextH(element, ref ctp,
                                                  WpfTextRenderer.GetText(element, child), rotate, placement);
                        }
                        else
                        {
                            RenderTextRunH(element, ref ctp,
                                           WpfTextRenderer.GetText(element, child), rotate, placement);
                        }
                        ctp.Y += shiftBy;
                    }
                }
            }
        }
        public override void Render(WpfDrawingRenderer renderer)
        {
            if (_drawGroup == null || _drawContext == null)
            {
                return;
            }

            Point ctp = new Point(0, 0); // current text position

            WpfTextPlacement placement = WpfTextRenderer.GetCurrentTextPosition(_textElement, ctp);

            ctp = placement.Location;
            double rotate = placement.Rotation;

            if (!placement.HasPositions)
            {
                placement = null; // render it useless
            }
            string sBaselineShift = _textElement.GetPropertyValue("baseline-shift").Trim();
            double shiftBy        = 0;

            if (sBaselineShift.Length > 0)
            {
                double textFontSize = WpfTextRenderer.GetComputedFontSize(_textElement);
                if (sBaselineShift.EndsWith("%", StringComparison.OrdinalIgnoreCase))
                {
                    shiftBy = SvgNumber.ParseNumber(sBaselineShift.Substring(0,
                                                                             sBaselineShift.Length - 1)) / 100 * textFontSize;
                }
                else if (sBaselineShift == "sub")
                {
                    shiftBy = -0.6F * textFontSize;
                }
                else if (sBaselineShift == "super")
                {
                    shiftBy = 0.6F * textFontSize;
                }
                else if (sBaselineShift == "baseline")
                {
                    shiftBy = 0;
                }
                else
                {
                    shiftBy = SvgNumber.ParseNumber(sBaselineShift);
                }
            }

            XmlNodeType nodeType = XmlNodeType.None;

            bool   isVertical  = false;
            string writingMode = _textElement.GetPropertyValue("writing-mode");

            if (!string.IsNullOrWhiteSpace(writingMode) &&
                string.Equals(writingMode, "tb", StringComparison.OrdinalIgnoreCase))
            {
                isVertical = true;
            }

            if (_svgElement.ChildNodes.Count == 1)
            {
                XmlNode child = _svgElement.ChildNodes[0];
                nodeType = child.NodeType;
                if (nodeType == XmlNodeType.Text || nodeType == XmlNodeType.CDATA)
                {
                    if (isVertical)
                    {
                        ctp.X -= shiftBy;
                        RenderSingleLineTextV(_textElement, ref ctp,
                                              WpfTextRenderer.GetText(_textElement, child), rotate, placement);
                        ctp.X += shiftBy;
                    }
                    else
                    {
                        ctp.Y -= shiftBy;
                        RenderSingleLineTextH(_textElement, ref ctp,
                                              WpfTextRenderer.GetText(_textElement, child), rotate, placement);
                        ctp.Y += shiftBy;
                    }
                }
                else if (nodeType == XmlNodeType.Element)
                {
                    string nodeName = child.Name;
                    if (string.Equals(nodeName, "tref"))
                    {
                        AddTRefElementRun((SvgTRefElement)child, ref ctp, isVertical, true);
                    }
                    else if (string.Equals(nodeName, "tspan"))
                    {
                        AddTSpanElementRun((SvgTSpanElement)child, ref ctp, isVertical, true);
                    }
                    else if (string.Equals(nodeName, "textPath"))
                    {
                        RenderTextPath((SvgTextPathElement)child, ref ctp, rotate, placement);
                    }
                }
                else if (nodeType == XmlNodeType.Whitespace)
                {
                    if (isVertical)
                    {
                        ctp.X -= shiftBy;
                        RenderSingleLineTextV(_textElement, ref ctp,
                                              WpfTextRenderer.GetText(_textElement, child), rotate, placement);
                        ctp.X += shiftBy;
                    }
                    else
                    {
                        ctp.Y -= shiftBy;
                        RenderSingleLineTextH(_textElement, ref ctp,
                                              WpfTextRenderer.GetText(_textElement, child), rotate, placement);
                        ctp.Y += shiftBy;
                    }
                }
            }
            else
            {
                string textAnchor = _textElement.GetPropertyValue("text-anchor");

                WpfTextAnchor anchor = WpfTextAnchor.None;

                if (textAnchor == "middle")
                {
                    anchor = WpfTextAnchor.Middle;
                }
                else if (textAnchor == "end")
                {
                    anchor = WpfTextAnchor.End;
                }

                XmlNodeList nodeList = _svgElement.ChildNodes;
                // This is a very simply hack to change centered text to left align, since for
                // text containing spans, different font weights may be applied to the spans...
                if (anchor == WpfTextAnchor.Middle)
                {
                    // Suspend the rendering...
                    _isMeasuring = true;

                    foreach (XmlNode child in nodeList)
                    {
                        nodeType = child.NodeType;
                        if (nodeType == XmlNodeType.Text)
                        {
                            if (isVertical)
                            {
                                ctp.X -= shiftBy;
                                RenderTextRunV(_textElement, ref ctp,
                                               WpfTextRenderer.GetText(_textElement, child), rotate, placement);
                                ctp.X += shiftBy;
                            }
                            else
                            {
                                ctp.Y -= shiftBy;
                                RenderTextRunH(_textElement, ref ctp,
                                               WpfTextRenderer.GetText(_textElement, child), rotate, placement);
                                ctp.Y += shiftBy;
                            }
                        }
                        else if (nodeType == XmlNodeType.Element)
                        {
                            string nodeName = child.Name;
                            if (string.Equals(nodeName, "tref"))
                            {
                                AddTRefElementRun((SvgTRefElement)child, ref ctp, isVertical, false);
                            }
                            else if (string.Equals(nodeName, "tspan"))
                            {
                                AddTSpanElementRun((SvgTSpanElement)child, ref ctp, isVertical, false);
                            }
                            else if (string.Equals(nodeName, "textPath"))
                            {
                                RenderTextPath((SvgTextPathElement)child, ref ctp, rotate, placement);
                            }
                        }
                        else if (nodeType == XmlNodeType.Whitespace)
                        {
                            if (isVertical)
                            {
                                ctp.X -= shiftBy;
                                //RenderTextRunV(_textElement, ref ctp, GetText(_textElement, child));
                                RenderTextRunV(_textElement, ref ctp, Whitespace, rotate, placement);
                                ctp.X += shiftBy;
                            }
                            else
                            {
                                ctp.Y -= shiftBy;
                                //RenderTextRunH(_textElement, ref ctp, GetText(_textElement, child));
                                RenderTextRunH(_textElement, ref ctp, Whitespace, rotate, placement);
                                ctp.Y += shiftBy;
                            }
                        }
                    }

                    ctp.X -= (_textWidth / 2d);

                    // Resume the rendering...
                    _isMeasuring = false;
                }

                bool textRendered = false;

                for (int i = 0; i < nodeList.Count; i++)
                {
                    XmlNode child = nodeList[i];
                    nodeType = child.NodeType;
                    if (nodeType == XmlNodeType.Text)
                    {
                        if (isVertical)
                        {
                            ctp.X -= shiftBy;
                            RenderTextRunV(_textElement, ref ctp,
                                           WpfTextRenderer.GetText(_textElement, child), rotate, placement);
                            ctp.X += shiftBy;
                        }
                        else
                        {
                            ctp.Y -= shiftBy;
                            RenderTextRunH(_textElement, ref ctp,
                                           WpfTextRenderer.GetText(_textElement, child), rotate, placement);
                            ctp.Y += shiftBy;
                        }

                        textRendered = true;
                    }
                    else if (nodeType == XmlNodeType.Element)
                    {
                        string nodeName = child.Name;
                        if (string.Equals(nodeName, "tref"))
                        {
                            AddTRefElementRun((SvgTRefElement)child, ref ctp, isVertical, false);

                            textRendered = true;
                        }
                        else if (string.Equals(nodeName, "tspan"))
                        {
                            AddTSpanElementRun((SvgTSpanElement)child, ref ctp, isVertical, false);

                            textRendered = true;
                        }
                        else if (string.Equals(nodeName, "textPath"))
                        {
                            RenderTextPath((SvgTextPathElement)child, ref ctp, rotate, placement);

                            textRendered = false;
                        }
                    }
                    else if (nodeType == XmlNodeType.Whitespace)
                    {
                        if (textRendered)
                        {
                            if (isVertical)
                            {
                                ctp.X -= shiftBy;
                                //RenderTextRunV(_textElement, ref ctp, GetText(_textElement, child));
                                RenderTextRunV(_textElement, ref ctp, Whitespace, rotate, placement);
                                ctp.X += shiftBy;
                            }
                            else
                            {
                                ctp.Y -= shiftBy;
                                //RenderTextRunH(_textElement, ref ctp, GetText(_textElement, child));
                                RenderTextRunH(_textElement, ref ctp, Whitespace, rotate, placement);
                                ctp.Y += shiftBy;
                            }

                            textRendered = false;
                        }
                    }
                }
            }
        }
Example #25
0
        private void AddTSpanElementRun(SvgTSpanElement element, ref Point ctp,
                                        bool isVertical, bool isSingleLine, XmlNode spaceNode = null)
        {
            var nodeList  = element.ChildNodes;
            int nodeCount = nodeList.Count;

            if (nodeCount == 0)
            {
                return;
            }

            _textContext.PositioningElement = element;
            _textContext.PositioningStart   = new Point(ctp.X, ctp.Y);

            WpfTextPlacement placement = WpfTextPlacement.Create(element, ctp);

            ctp = placement.Location;
            double rotate = placement.Rotation;

            if (!placement.HasPositions)
            {
                placement = null; // render it useless
            }

            _textContext.PositioningEnd = new Point(ctp.X, ctp.Y);

            var comparer = StringComparison.OrdinalIgnoreCase;

            string sBaselineShift = element.GetPropertyValue("baseline-shift").Trim();
            double shiftBy        = 0;

            if (sBaselineShift.Length > 0)
            {
                double textFontSize = WpfTextRenderer.GetComputedFontSize(_textElement);
                if (sBaselineShift.EndsWith("%", comparer))
                {
                    shiftBy = SvgNumber.ParseNumber(sBaselineShift.Substring(0,
                                                                             sBaselineShift.Length - 1)) / 100f * textFontSize;
                }
                else if (string.Equals(sBaselineShift, "sub", comparer))
                {
                    shiftBy = -0.6F * textFontSize;
                }
                else if (string.Equals(sBaselineShift, "super", comparer))
                {
                    shiftBy = 0.6F * textFontSize;
                }
                else if (string.Equals(sBaselineShift, "baseline", comparer))
                {
                    shiftBy = 0;
                }
                else
                {
                    shiftBy = SvgNumber.ParseNumber(sBaselineShift);
                }
            }

            for (int i = 0; i < nodeCount; i++)
            {
                XmlNode child = nodeList[i];
                if (child.NodeType == XmlNodeType.Text)
                {
                    if (isVertical)
                    {
                        ctp.X += shiftBy;
                        if (isSingleLine)
                        {
                            if (i == (nodeCount - 1) && spaceNode != null)
                            {
                                RenderSingleLineTextV(element, ref ctp,
                                                      WpfTextRenderer.GetText(element, child, spaceNode), rotate, placement);
                            }
                            else
                            {
                                RenderSingleLineTextV(element, ref ctp,
                                                      WpfTextRenderer.GetText(element, child), rotate, placement);
                            }
                        }
                        else
                        {
                            if (i == (nodeCount - 1) && spaceNode != null)
                            {
                                RenderTextRunV(element, ref ctp,
                                               WpfTextRenderer.GetText(element, child, spaceNode), rotate, placement);
                            }
                            else
                            {
                                RenderTextRunV(element, ref ctp,
                                               WpfTextRenderer.GetText(element, child), rotate, placement);
                            }
                        }
                        ctp.X -= shiftBy;
                    }
                    else
                    {
                        ctp.Y -= shiftBy;
                        if (isSingleLine)
                        {
                            if (i == (nodeCount - 1) && spaceNode != null)
                            {
                                RenderSingleLineTextH(element, ref ctp,
                                                      WpfTextRenderer.GetText(element, child, spaceNode), rotate, placement);
                            }
                            else
                            {
                                RenderSingleLineTextH(element, ref ctp,
                                                      WpfTextRenderer.GetText(element, child), rotate, placement);
                            }
                        }
                        else
                        {
                            if (i == (nodeCount - 1) && spaceNode != null)
                            {
                                RenderTextRunH(element, ref ctp,
                                               WpfTextRenderer.GetText(element, child, spaceNode), rotate, placement);
                            }
                            else
                            {
                                RenderTextRunH(element, ref ctp,
                                               WpfTextRenderer.GetText(element, child), rotate, placement);
                            }
                        }
                        ctp.Y += shiftBy;
                    }
                }
            }
        }
Example #26
0
        public void RenderMarker2(WpfDrawingRenderer renderer, WpfDrawingContext gr,
                                  SvgMarkerPosition markerPos, SvgStyleableElement refElement)
        {
            ISharpMarkerHost markerHostElm = (ISharpMarkerHost)refElement;
            SvgMarkerElement markerElm     = (SvgMarkerElement)_svgElement;

            SvgPointF[] vertexPositions = markerHostElm.MarkerPositions;
            int         start;
            int         len;

            // Choose which part of the position array to use
            switch (markerPos)
            {
            case SvgMarkerPosition.Start:
                start = 0;
                len   = 1;
                break;

            case SvgMarkerPosition.Mid:
                start = 1;
                len   = vertexPositions.Length - 2;
                break;

            default:
                // == MarkerPosition.End
                start = vertexPositions.Length - 1;
                len   = 1;
                break;
            }

            for (int i = start; i < start + len; i++)
            {
                SvgPointF point = vertexPositions[i];

                //GdiGraphicsContainer gc = gr.BeginContainer();

                this.BeforeRender(renderer);

                //Matrix matrix = Matrix.Identity;

                Matrix matrix = GetTransformMatrix(_svgElement);

                if (markerElm.OrientType.AnimVal.Equals((ushort)SvgMarkerOrient.Angle))
                {
                    matrix.Rotate(markerElm.OrientAngle.AnimVal.Value);
                }
                else
                {
                    double angle = 0;

                    switch (markerPos)
                    {
                    case SvgMarkerPosition.Start:
                        angle = markerHostElm.GetStartAngle(i + 1);
                        break;

                    case SvgMarkerPosition.Mid:
                        //angle = (markerHostElm.GetEndAngle(i) + markerHostElm.GetStartAngle(i + 1)) / 2;
                        angle = SvgNumber.CalcAngleBisection(markerHostElm.GetEndAngle(i), markerHostElm.GetStartAngle(i + 1));
                        break;

                    default:
                        angle = markerHostElm.GetEndAngle(i);
                        break;
                    }
                    matrix.Rotate(angle);
                }

                if (markerElm.MarkerUnits.AnimVal.Equals((ushort)SvgMarkerUnit.StrokeWidth))
                {
                    SvgLength strokeWidthLength = new SvgLength(refElement,
                                                                "stroke-width", SvgLengthSource.Css, SvgLengthDirection.Viewport, "1");
                    double strokeWidth = strokeWidthLength.Value;
                    matrix.Scale(strokeWidth, strokeWidth);
                }

                SvgPreserveAspectRatio spar =
                    (SvgPreserveAspectRatio)markerElm.PreserveAspectRatio.AnimVal;
                double[] translateAndScale = spar.FitToViewBox((SvgRect)markerElm.ViewBox.AnimVal,
                                                               new SvgRect(0, 0, markerElm.MarkerWidth.AnimVal.Value,
                                                                           markerElm.MarkerHeight.AnimVal.Value));


                matrix.Translate(-markerElm.RefX.AnimVal.Value * translateAndScale[2],
                                 -markerElm.RefY.AnimVal.Value * translateAndScale[3]);

                matrix.Scale(translateAndScale[2], translateAndScale[3]);

                matrix.Translate(point.X, point.Y);

                _matrix = matrix;
                this.Render(renderer);

                //Clip(gr);

                renderer.RenderChildren(markerElm);

                //gr.EndContainer(gc);

                this.AfterRender(renderer);
            }
        }
        public override void Render(WpfDrawingRenderer renderer)
        {
            WpfDrawingContext context      = renderer.Context;
            SvgImageElement   imageElement = (SvgImageElement)_svgElement;

            double x      = imageElement.X.AnimVal.Value;
            double y      = imageElement.Y.AnimVal.Value;
            double width  = imageElement.Width.AnimVal.Value;
            double height = imageElement.Height.AnimVal.Value;

            Rect destRect = new Rect(x, y, width, height);
            Rect clipRect = new Rect(x, y, width, height);

            ImageSource imageSource = null;

            if (imageElement.IsSvgImage)
            {
                if (imageElement.IsRootReferenced(imageElement.OwnerDocument.BaseURI))
                {
                    return;
                }

                SvgWindow wnd = GetSvgWindow();
                if (wnd == null)
                {
                    return;
                }
                //_embeddedRenderer.BackColor = Color.Empty;
                _embeddedRenderer.Render(wnd.Document);

                DrawingGroup imageGroup = _embeddedRenderer.Drawing as DrawingGroup;
                if (imageGroup != null &&
                    (imageGroup.Children != null && imageGroup.Children.Count == 1))
                {
                    DrawingGroup imageDrawing = imageGroup.Children[0] as DrawingGroup;
                    if (imageDrawing != null)
                    {
                        imageDrawing.ClipGeometry = null;

                        imageSource = new DrawingImage(imageDrawing);
                    }
                    else
                    {
                        imageGroup.ClipGeometry = null;

                        imageSource = new DrawingImage(imageGroup);
                    }
                }
                else
                {
                    imageSource = new DrawingImage(_embeddedRenderer.Drawing);
                }

                if (_embeddedRenderer != null)
                {
                    _embeddedRenderer.Dispose();
                    _embeddedRenderer = null;
                }
            }
            else
            {
                imageSource = GetBitmapSource(imageElement, context);
            }

            if (imageSource == null)
            {
                return;
            }

            //TODO--PAUL: Set the DecodePixelWidth/DecodePixelHeight?

            // Freeze the DrawingImage for performance benefits.
            //imageSource.Freeze();

            DrawingGroup drawGroup = null;

            ISvgAnimatedPreserveAspectRatio animatedAspectRatio = imageElement.PreserveAspectRatio;

            if (animatedAspectRatio != null && animatedAspectRatio.AnimVal != null)
            {
                SvgPreserveAspectRatio     aspectRatio     = animatedAspectRatio.AnimVal as SvgPreserveAspectRatio;
                SvgPreserveAspectRatioType aspectRatioType =
                    (aspectRatio != null) ? aspectRatio.Align : SvgPreserveAspectRatioType.Unknown;
                if (aspectRatio != null && aspectRatioType != SvgPreserveAspectRatioType.None &&
                    aspectRatioType != SvgPreserveAspectRatioType.Unknown)
                {
                    double imageWidth  = imageSource.Width;
                    double imageHeight = imageSource.Height;

                    double viewWidth  = destRect.Width;
                    double viewHeight = destRect.Height;

                    SvgMeetOrSlice meetOrSlice = aspectRatio.MeetOrSlice;
                    if (meetOrSlice == SvgMeetOrSlice.Meet)
                    {
                        if (imageWidth <= viewWidth && imageHeight <= viewHeight)
                        {
                            if (this.Transform == null)
                            {
                                if (!aspectRatio.IsDefaultAlign) // Cacxa
                                {
                                    destRect = this.GetBounds(destRect, new Size(imageWidth, imageHeight), aspectRatioType);
                                }
                                else
                                {
                                    Transform viewTransform = this.GetAspectRatioTransform(aspectRatio,
                                                                                           new SvgRect(0, 0, imageWidth, imageHeight),
                                                                                           new SvgRect(destRect.X, destRect.Y, destRect.Width, destRect.Height));

                                    if (viewTransform != null)
                                    {
                                        drawGroup           = new DrawingGroup();
                                        drawGroup.Transform = viewTransform;

                                        DrawingGroup lastGroup = context.Peek();
                                        Debug.Assert(lastGroup != null);

                                        if (lastGroup != null)
                                        {
                                            lastGroup.Children.Add(drawGroup);
                                        }

                                        destRect = this.GetBounds(destRect,
                                                                  new Size(imageWidth, imageHeight), aspectRatioType);

                                        // The origin is already handled by the view transform...
                                        destRect.X = 0;
                                        destRect.Y = 0;
                                    }
                                }
                            }
                            else
                            {
                                destRect = new Rect(0, 0, viewWidth, viewHeight);
                            }
                        }
                        else
                        {
                            if (this.Transform == null)
                            {
                                Transform viewTransform = this.GetAspectRatioTransform(aspectRatio,
                                                                                       new SvgRect(0, 0, imageWidth, imageHeight),
                                                                                       new SvgRect(destRect.X, destRect.Y, destRect.Width, destRect.Height));

                                if (viewTransform != null)
                                {
                                    drawGroup           = new DrawingGroup();
                                    drawGroup.Transform = viewTransform;

                                    DrawingGroup lastGroup = context.Peek();
                                    Debug.Assert(lastGroup != null);

                                    if (lastGroup != null)
                                    {
                                        lastGroup.Children.Add(drawGroup);
                                    }

                                    destRect = this.GetBounds(destRect,
                                                              new Size(imageWidth, imageHeight), aspectRatioType);

                                    // The origin is already handled by the view transform...
                                    destRect.X = 0;
                                    destRect.Y = 0;
                                }
                            }
                        }
                    }
                    else if (meetOrSlice == SvgMeetOrSlice.Slice)
                    {
                        var       fScaleX       = viewWidth / imageWidth;
                        var       fScaleY       = viewHeight / imageHeight;
                        Transform viewTransform = this.GetAspectRatioTransform(aspectRatio,
                                                                               new SvgRect(0, 0, imageWidth, imageHeight),
                                                                               new SvgRect(destRect.X, destRect.Y, destRect.Width, destRect.Height));

                        DrawingGroup sliceGroup = new DrawingGroup();
                        sliceGroup.ClipGeometry = new RectangleGeometry(clipRect);

                        DrawingGroup lastGroup = context.Peek();
                        Debug.Assert(lastGroup != null);

                        if (lastGroup != null)
                        {
                            lastGroup.Children.Add(sliceGroup);
                        }

                        if (viewTransform != null)
                        {
                            drawGroup           = new DrawingGroup();
                            drawGroup.Transform = viewTransform;

                            sliceGroup.Children.Add(drawGroup);

                            destRect = this.GetBounds(destRect,
                                                      new Size(imageWidth, imageHeight), aspectRatioType);

                            // The origin is already handled by the view transform...
                            destRect.X = 0;
                            destRect.Y = 0;
                        }
                        else
                        {
                            drawGroup = sliceGroup;
                        }
                    }
                }
            }

            ImageDrawing drawing = new ImageDrawing(imageSource, destRect);

            float opacityValue = -1;

            string opacity = imageElement.GetAttribute("opacity");

            if (string.IsNullOrWhiteSpace(opacity))
            {
                opacity = imageElement.GetPropertyValue("opacity");
            }
            if (!string.IsNullOrWhiteSpace(opacity))
            {
                opacityValue = (float)SvgNumber.ParseNumber(opacity);
                opacityValue = Math.Min(opacityValue, 1);
                opacityValue = Math.Max(opacityValue, 0);
            }

            Geometry  clipGeom  = this.ClipGeometry;
            Transform transform = this.Transform;

            bool ownedGroup = true;

            if (drawGroup == null)
            {
                drawGroup  = context.Peek();
                ownedGroup = false;
            }

            Debug.Assert(drawGroup != null);
            if (drawGroup != null)
            {
                if ((opacityValue >= 0 && opacityValue < 1) || (clipGeom != null && !clipGeom.IsEmpty()) ||
                    (transform != null && !transform.Value.IsIdentity))
                {
                    DrawingGroup clipGroup = ownedGroup ? drawGroup : new DrawingGroup();
                    if (opacityValue >= 0 && opacityValue < 1)
                    {
                        clipGroup.Opacity = opacityValue;
                    }
                    if (clipGeom != null)
                    {
                        SvgUnitType clipUnits = this.ClipUnits;
                        if (clipUnits == SvgUnitType.ObjectBoundingBox)
                        {
                            Rect drawingBounds = drawing.Bounds;

                            TransformGroup transformGroup = new TransformGroup();

                            // Scale the clip region (at (0, 0)) and translate to the top-left corner of the target.
                            transformGroup.Children.Add(
                                new ScaleTransform(drawingBounds.Width, drawingBounds.Height));
                            transformGroup.Children.Add(
                                new TranslateTransform(drawingBounds.X, drawingBounds.Y));

                            clipGeom.Transform = transformGroup;
                        }

                        clipGroup.ClipGeometry = clipGeom;
                    }
                    if (transform != null)
                    {
                        Transform curTransform = clipGroup.Transform;
                        if (curTransform != null && curTransform.Value.IsIdentity == false)
                        {
                            TransformGroup transformGroup = new TransformGroup();
                            transformGroup.Children.Add(curTransform);
                            transformGroup.Children.Add(transform);
                            clipGroup.Transform = transformGroup;
                        }
                        else
                        {
                            clipGroup.Transform = transform;
                        }
                    }

                    clipGroup.Children.Add(drawing);
                    if (!ownedGroup)
                    {
                        drawGroup.Children.Add(clipGroup);
                    }
                }
                else
                {
                    drawGroup.Children.Add(drawing);
                }

                string elementId = this.GetElementName();
                if (ownedGroup)
                {
                    string sVisibility = imageElement.GetPropertyValue("visibility");
                    string sDisplay    = imageElement.GetPropertyValue("display");
                    if (string.Equals(sVisibility, "hidden") || string.Equals(sDisplay, "none"))
                    {
                        drawGroup.Opacity = 0;
                    }

                    if (!_idAssigned && !string.IsNullOrWhiteSpace(elementId) && !context.IsRegisteredId(elementId))
                    {
                        context.RegisterId(elementId);

                        if (context.IncludeRuntime)
                        {
                            SvgObject.SetName(drawGroup, elementId);

                            SvgObject.SetId(drawGroup, elementId);
                        }
                    }

                    // Register this drawing with the Drawing-Document...
                    this.Rendered(drawGroup);
                }
                else if (!_idAssigned)
                {
                    if (!_idAssigned && !string.IsNullOrWhiteSpace(elementId) && !context.IsRegisteredId(elementId))
                    {
                        context.RegisterId(elementId);

                        if (context.IncludeRuntime)
                        {
                            SvgObject.SetName(imageSource, elementId);

                            SvgObject.SetId(imageSource, elementId);
                        }
                    }

                    // Register this drawing with the Drawing-Document...
                    this.Rendered(drawing);
                }
            }
        }
        public override void Render(WpfDrawingRenderer renderer)
        {
            if (_drawGroup == null || _drawContext == null)
            {
                return;
            }

            var comparer = StringComparison.OrdinalIgnoreCase;

            Point ctp = new Point(0, 0); // current text position

            WpfTextPlacement placement = WpfTextPlacement.Create(_textElement, ctp, _textContext.IsTextPath);

            ctp = placement.Location;
            double rotate = placement.Rotation;

            if (!placement.HasPositions)
            {
                placement = null; // render it useless
            }
            string sBaselineShift = _textElement.GetPropertyValue("baseline-shift").Trim();
            double shiftBy        = 0;

            if (sBaselineShift.Length > 0)
            {
                double textFontSize = WpfTextRenderer.GetComputedFontSize(_textElement);
                if (sBaselineShift.EndsWith("%", comparer))
                {
                    shiftBy = SvgNumber.ParseNumber(sBaselineShift.Substring(0,
                                                                             sBaselineShift.Length - 1)) / 100 * textFontSize;
                }
                else if (string.Equals(sBaselineShift, "sub", comparer))
                {
                    shiftBy = -0.6F * textFontSize;
                }
                else if (string.Equals(sBaselineShift, "super", comparer))
                {
                    shiftBy = 0.6F * textFontSize;
                }
                else if (string.Equals(sBaselineShift, "baseline", comparer))
                {
                    shiftBy = 0;
                }
                else
                {
                    shiftBy = SvgNumber.ParseNumber(sBaselineShift);
                }
            }

            // For for fonts loading in the background...
            var svgDoc = _svgElement.OwnerDocument;

            if (svgDoc.IsFontsLoaded == false)
            {
                //TODO: Use of SpinUntil is known to CPU heavy, but will work for now...
                //SpinWait.SpinUntil(() => svgDoc.IsFontsLoaded == true);

                var svgWnd = svgDoc.Window as SvgWindow;
                if (svgWnd != null)
                {
                    svgWnd.AwaitTasks("SvgDocument");
                }
            }

            XmlNodeType nodeType = XmlNodeType.None;

            bool   isVertical  = false;
            string writingMode = _textElement.GetPropertyValue("writing-mode");

            if (!string.IsNullOrWhiteSpace(writingMode) && string.Equals(writingMode, "tb", comparer))
            {
                isVertical = true;
            }

            if (_svgElement.ChildNodes.Count == 1)
            {
                XmlNode child = _svgElement.ChildNodes[0];
                nodeType = child.NodeType;
                if (nodeType == XmlNodeType.Text || nodeType == XmlNodeType.CDATA)
                {
                    if (isVertical)
                    {
                        ctp.X -= shiftBy;
                        RenderVertText(_textElement, ref ctp,
                                       WpfTextRenderer.GetText(_textElement, child), rotate, placement);
                        ctp.X += shiftBy;
                    }
                    else
                    {
                        ctp.Y -= shiftBy;
                        RenderHorzText(_textElement, ref ctp,
                                       WpfTextRenderer.GetText(_textElement, child), rotate, placement);
                        ctp.Y += shiftBy;
                    }
                }
                else if (nodeType == XmlNodeType.Element)
                {
                    string nodeName = child.Name;
                    if (string.Equals(nodeName, "tref", comparer))
                    {
                        AddTRefElementRun((SvgTRefElement)child, ref ctp, isVertical, true);
                    }
                    else if (string.Equals(nodeName, "tspan", comparer))
                    {
                        AddTSpanElementRun((SvgTSpanElement)child, ref ctp, isVertical, true);
                    }
                    else if (string.Equals(nodeName, "textPath", comparer))
                    {
                        RenderTextPath((SvgTextPathElement)child, ref ctp, rotate, placement);
                    }
                    else if (string.Equals(nodeName, "altGlyph", comparer))
                    {
                        AddAltGlyphElementRun((SvgAltGlyphElement)child, ref ctp, isVertical, true);
                    }
                }
                else if (nodeType == XmlNodeType.Whitespace)
                {
                    if (isVertical)
                    {
                        ctp.X -= shiftBy;
                        RenderVertText(_textElement, ref ctp,
                                       WpfTextRenderer.GetText(_textElement, child), rotate, placement);
                        ctp.X += shiftBy;
                    }
                    else
                    {
                        ctp.Y -= shiftBy;
                        RenderHorzText(_textElement, ref ctp,
                                       WpfTextRenderer.GetText(_textElement, child), rotate, placement);
                        ctp.Y += shiftBy;
                    }
                }
            }
            else
            {
                string textAnchor = _textElement.GetPropertyValue("text-anchor");

                WpfTextAnchor anchor = WpfTextAnchor.None;

                if (string.Equals(textAnchor, "middle", comparer))
                {
                    anchor = WpfTextAnchor.Middle;
                }
                else if (string.Equals(textAnchor, "end", comparer))
                {
                    anchor = WpfTextAnchor.End;
                }

                XmlNodeList nodeList  = _svgElement.ChildNodes;
                int         nodeCount = nodeList.Count;
                // This is a very simply hack to change centered text to left align, since for
                // text containing spans, different font weights may be applied to the spans...
                if (anchor == WpfTextAnchor.Middle)
                {
                    // Suspend the rendering...
                    _isMeasuring = true;
                    Point savedPt = new Point(ctp.X, ctp.Y);

                    _textContext.BeginMeasure(nodeCount);

                    for (int i = 0; i < nodeCount; i++)
                    {
                        XmlNode child = nodeList[i];
                        nodeType = child.NodeType;
                        //if (i == 0 && nodeType == XmlNodeType.Whitespace)
                        //{
                        //    continue;
                        //}
                        if (nodeType == XmlNodeType.Text)
                        {
                            var nodeText = WpfTextRenderer.GetText(_textElement, child);
                            if (i == (nodeCount - 1))
                            {
                                // No need to render the last white space...
                                nodeText = nodeText.TrimEnd();
                            }
                            else if (i == 0)
                            {
                                nodeText = nodeText.Trim();
                            }

                            if (isVertical)
                            {
                                ctp.X -= shiftBy;
                                RenderVertTextRun(_textElement, ref ctp, nodeText, rotate, placement);
                                ctp.X += shiftBy;
                            }
                            else
                            {
                                ctp.Y -= shiftBy;
                                RenderHorzTextRun(_textElement, ref ctp, nodeText, rotate, placement);
                                ctp.Y += shiftBy;
                            }
                        }
                        else if (nodeType == XmlNodeType.Element)
                        {
                            string nodeName = child.Name;
                            if (string.Equals(nodeName, "tref", comparer))
                            {
                                AddTRefElementRun((SvgTRefElement)child, ref ctp, isVertical, false);
                            }
                            else if (string.Equals(nodeName, "tspan", comparer))
                            {
                                bool isAdded = false;
                                if ((i + 1) < nodeCount - 1)
                                {
                                    XmlNode nextChild = nodeList[i + 1];
                                    if (nextChild.NodeType == XmlNodeType.Whitespace)
                                    {
                                        isAdded = true;
                                        AddTSpanElementRun((SvgTSpanElement)child, ref ctp, isVertical, false, nextChild);
                                        i++;
                                    }
                                }
                                if (!isAdded)
                                {
                                    AddTSpanElementRun((SvgTSpanElement)child, ref ctp, isVertical, false);
                                }
                            }
                            else if (string.Equals(nodeName, "textPath", comparer))
                            {
                                RenderTextPath((SvgTextPathElement)child, ref ctp, rotate, placement);
                            }
                            else if (string.Equals(nodeName, "altGlyph", comparer))
                            {
                                AddAltGlyphElementRun((SvgAltGlyphElement)child, ref ctp, isVertical, false);
                            }
                        }
                        else if (nodeType == XmlNodeType.Whitespace)
                        {
                            if (isVertical)
                            {
                                ctp.X -= shiftBy;
                                RenderVertTextRun(_textElement, ref ctp, Whitespace, rotate, placement, true);
                                ctp.X += shiftBy;
                            }
                            else
                            {
                                ctp.Y -= shiftBy;
                                RenderHorzTextRun(_textElement, ref ctp, Whitespace, rotate, placement, true);
                                ctp.Y += shiftBy;
                            }
                        }
                    }

                    _textContext.EndMeasure();

                    ctp = savedPt;

                    ctp.X -= (_textWidth / 2d);

                    // Resume the rendering...
                    _isMeasuring = false;
                }

                bool textRendered = false;

                for (int i = 0; i < nodeCount; i++)
                {
                    XmlNode child = nodeList[i];
                    nodeType = child.NodeType;
                    //if (i == 0 && nodeType == XmlNodeType.Whitespace)
                    //{
                    //    continue;
                    //}

                    if (nodeType == XmlNodeType.Text)
                    {
                        var nodeText = WpfTextRenderer.GetText(_textElement, child);
                        if (i == (nodeCount - 1))
                        {
                            // No need to render the last white space...
                            nodeText = nodeText.TrimEnd();
                        }
                        else if (i == 0)
                        {
                            nodeText = nodeText.Trim();
                        }

                        if (isVertical)
                        {
                            ctp.X -= shiftBy;
                            RenderVertTextRun(_textElement, ref ctp, nodeText, rotate, placement);
                            ctp.X += shiftBy;
                        }
                        else
                        {
                            ctp.Y -= shiftBy;
                            RenderHorzTextRun(_textElement, ref ctp, nodeText, rotate, placement);
                            ctp.Y += shiftBy;
                        }

                        textRendered = true;
                    }
                    else if (nodeType == XmlNodeType.Element)
                    {
                        string nodeName = child.Name;
                        if (string.Equals(nodeName, "tref", comparer))
                        {
                            AddTRefElementRun((SvgTRefElement)child, ref ctp, isVertical, false);

                            textRendered = true;
                        }
                        else if (string.Equals(nodeName, "tspan", comparer))
                        {
                            bool isAdded = false;
                            if ((i + 1) < nodeCount - 1)
                            {
                                XmlNode nextChild = nodeList[i + 1];
                                if (nextChild.NodeType == XmlNodeType.Whitespace)
                                {
                                    isAdded = true;
                                    AddTSpanElementRun((SvgTSpanElement)child, ref ctp, isVertical, false, nextChild);
                                    i++;
                                }
                            }
                            if (!isAdded)
                            {
                                AddTSpanElementRun((SvgTSpanElement)child, ref ctp, isVertical, false);
                            }

                            textRendered = true;
                        }
                        else if (string.Equals(nodeName, "textPath", comparer))
                        {
                            RenderTextPath((SvgTextPathElement)child, ref ctp, rotate, placement);

                            textRendered = false;
                        }
                        else if (string.Equals(nodeName, "altGlyph", comparer))
                        {
                            AddAltGlyphElementRun((SvgAltGlyphElement)child, ref ctp, isVertical, false);
                        }
                    }
                    else if (nodeType == XmlNodeType.Whitespace)
                    {
                        if (textRendered)
                        {
                            if (isVertical)
                            {
                                ctp.X -= shiftBy;
                                RenderVertTextRun(_textElement, ref ctp, Whitespace, rotate, placement, true);
                                ctp.X += shiftBy;
                            }
                            else
                            {
                                ctp.Y -= shiftBy;
                                RenderHorzTextRun(_textElement, ref ctp, Whitespace, rotate, placement, true);
                                ctp.Y += shiftBy;
                            }

                            textRendered = false;
                        }
                    }
                }
            }

            // Register this drawing with the Drawing-Document...
            if (_drawGroup != null)
            {
                this.Rendered(_drawGroup);
            }
        }
Example #29
0
        public static Brush CreateViewportBrush(SvgStyleableElement svgElm)
        {
            string prop    = svgElm.GetAttribute("viewport-fill");
            string opacity = svgElm.GetAttribute("viewport-fill-opacity");          // no auto-inherit

            if (string.Equals(prop, "inherit", StringComparison.OrdinalIgnoreCase)) // if explicitly defined...
            {
                prop = svgElm.GetPropertyValue("viewport-fill");
            }
            if (string.Equals(opacity, "inherit", StringComparison.OrdinalIgnoreCase)) // if explicitly defined...
            {
                opacity = svgElm.GetPropertyValue("viewport-fill-opacity");
            }
            if (!string.IsNullOrWhiteSpace(prop))
            {
                if (string.Equals(prop, "currentColor", StringComparison.OrdinalIgnoreCase))
                {
                    var svgParent = svgElm.ParentNode as SvgStyleableElement;
                    if (svgParent != null)
                    {
                        prop = svgParent.GetPropertyValue(CssConstants.PropColor, "viewport-fill");
                    }
                }

                Color       color    = Colors.Transparent; // no auto-inherited...
                WpfSvgColor svgColor = new WpfSvgColor(svgElm, "viewport-fill");
                color = svgColor.Color;

                if (color.A == 255)
                {
                    double alpha = 255;

                    if (!string.IsNullOrWhiteSpace(opacity))
                    {
                        alpha *= SvgNumber.ParseNumber(opacity);
                    }

                    alpha = Math.Min(alpha, 255);
                    alpha = Math.Max(alpha, 0);

                    color = Color.FromArgb((byte)Convert.ToInt32(alpha), color.R, color.G, color.B);
                }

                var    brush        = new SolidColorBrush(color);
                double opacityValue = 1;
                if (!string.IsNullOrWhiteSpace(opacity) && double.TryParse(opacity, out opacityValue))
                {
                    brush.Opacity = opacityValue;
                }

                return(brush);
            }
            else
            {
                Color  color = Colors.Black; // the default color...
                double alpha = 255;

                if (!string.IsNullOrWhiteSpace(opacity))
                {
                    alpha *= SvgNumber.ParseNumber(opacity);
                }

                alpha = Math.Min(alpha, 255);
                alpha = Math.Max(alpha, 0);

                color = Color.FromArgb((byte)Convert.ToInt32(alpha), color.R, color.G, color.B);

                return(new SolidColorBrush(color));
            }
        }
Example #30
0
        public void RenderMarker0(WpfDrawingRenderer renderer, WpfDrawingContext gr,
                                  SvgMarkerPosition markerPos, SvgStyleableElement refElement)
        {
            //PathGeometry g;
            //g.GetPointAtFractionLength(

            ISharpMarkerHost markerHostElm = (ISharpMarkerHost)refElement;
            SvgMarkerElement markerElm     = (SvgMarkerElement)_svgElement;

            SvgPointF[] vertexPositions = markerHostElm.MarkerPositions;
            int         start;
            int         len;

            // Choose which part of the position array to use
            switch (markerPos)
            {
            case SvgMarkerPosition.Start:
                start = 0;
                len   = 1;
                break;

            case SvgMarkerPosition.Mid:
                start = 1;
                len   = vertexPositions.Length - 2;
                break;

            default:
                // == MarkerPosition.End
                start = vertexPositions.Length - 1;
                len   = 1;
                break;
            }

            for (int i = start; i < start + len; i++)
            {
                SvgPointF point = vertexPositions[i];

                Matrix m = GetTransformMatrix(_svgElement);

                //GraphicsContainer gc = gr.BeginContainer();

                this.BeforeRender(renderer);

                //gr.TranslateTransform(point.X, point.Y);

                //PAUL:
                //m.Translate(point.X, point.Y);

                if (markerElm.OrientType.AnimVal.Equals((ushort)SvgMarkerOrient.Angle))
                {
                    m.Rotate(markerElm.OrientAngle.AnimVal.Value);
                    //gr.RotateTransform((double)markerElm.OrientAngle.AnimVal.Value);
                }
                else
                {
                    double angle;

                    switch (markerPos)
                    {
                    case SvgMarkerPosition.Start:
                        angle = markerHostElm.GetStartAngle(i + 1);
                        break;

                    case SvgMarkerPosition.Mid:
                        //angle = (markerHostElm.GetEndAngle(i) + markerHostElm.GetStartAngle(i + 1)) / 2;
                        angle = SvgNumber.CalcAngleBisection(markerHostElm.GetEndAngle(i), markerHostElm.GetStartAngle(i + 1));
                        break;

                    default:
                        angle = markerHostElm.GetEndAngle(i);
                        break;
                    }
                    //gr.RotateTransform(angle);
                    m.Rotate(angle);
                }

                if (markerElm.MarkerUnits.AnimVal.Equals((ushort)SvgMarkerUnit.StrokeWidth))
                {
                    string propValue = refElement.GetPropertyValue("stroke-width");
                    if (propValue.Length == 0)
                    {
                        propValue = "1";
                    }

                    SvgLength strokeWidthLength = new SvgLength("stroke-width", propValue, refElement, SvgLengthDirection.Viewport);
                    double    strokeWidth       = strokeWidthLength.Value;
                    //gr.ScaleTransform(strokeWidth, strokeWidth);
                    m.Scale(strokeWidth, strokeWidth);
                }

                SvgPreserveAspectRatio spar = (SvgPreserveAspectRatio)markerElm.PreserveAspectRatio.AnimVal;
                double[] translateAndScale  = spar.FitToViewBox(
                    (SvgRect)markerElm.ViewBox.AnimVal, new SvgRect(0, 0,
                                                                    markerElm.MarkerWidth.AnimVal.Value, markerElm.MarkerHeight.AnimVal.Value));


                //PAUL:
                //m.Translate(-(double)markerElm.RefX.AnimVal.Value * translateAndScale[2], -(double)markerElm.RefY.AnimVal.Value * translateAndScale[3]);

                //PAUL:
                m.Scale(translateAndScale[2], translateAndScale[3]);
                m.Translate(point.X, point.Y);

                //Matrix oldTransform = TransformMatrix;
                //TransformMatrix = m;
                //try
                //{
                //newTransform.Append(m);
                //TransformGroup tg = new TransformGroup();

                //renderer.Canvas.re

                //gr.TranslateTransform(
                //    -(double)markerElm.RefX.AnimVal.Value * translateAndScale[2],
                //    -(double)markerElm.RefY.AnimVal.Value * translateAndScale[3]
                //    );

                //gr.ScaleTransform(translateAndScale[2], translateAndScale[3]);

                renderer.RenderChildren(markerElm);
                //                markerElm.RenderChildren(renderer);
                //}
                //finally
                //{
                //    TransformMatrix = oldTransform;
                //}
                //    //gr.EndContainer(gc);

                _matrix = m;
                this.Render(renderer);

                //gr.EndContainer(gc);

                this.AfterRender(renderer);
            }
        }