Example #1
0
        /// <summary>
        /// AfterRender - Dispose of Graphics object created for rendering.
        /// </summary>
        private void OnAfterRender()
        {
            if (_ownsGraphics)
            {
                if (_graphics != null)
                {
                    if (_hitTestHelper != null)
                    {
                        if (_hitTestHelper != _graphics.HitTestHelper)
                        {
                            _hitTestHelper.Dispose();
                            _hitTestHelper = _graphics.HitTestHelper;
                        }
                    }

                    _graphics.HitTestHelper = GdiHitTestHelper.NoHit; // Prevent disposal actual height test
                    _graphics.Dispose();
                    _graphics = null;
                }
            }

            if (_hitTestHelper == null)
            {
                _hitTestHelper = GdiHitTestHelper.NoHit;
            }
        }
Example #2
0
        /// <summary>
        /// BeforeRender - Make sure we have a Graphics object to render to.
        /// If we don't have one, then create one to match the SvgWindow's
        /// physical dimensions.
        /// </summary>
        private void RendererBeforeRender()
        {
            // Testing for null here allows "advanced" developers to create their own Graphics object for rendering
            if (_graphics == null)
            {
                // Get the current SVGWindow's width and height
                int innerWidth  = (int)_svgWindow.InnerWidth;
                int innerHeight = (int)_svgWindow.InnerHeight;

                // Make sure we have an actual area to render to
                if (innerWidth > 0 && innerHeight > 0)
                {
                    // See if we already have a rasterImage that matches the current SVGWindow dimensions
                    if (_rasterImage == null || _rasterImage.Width != innerWidth || _rasterImage.Height != innerHeight)
                    {
                        // Nope, so create one
                        if (_rasterImage != null)
                        {
                            _rasterImage.Dispose();
                            _rasterImage = null;
                        }
                        _rasterImage = new Bitmap(innerWidth, innerHeight);
                    }

                    // Make a GraphicsWrapper object from the rasterImage and clear it to the background color
//                    _graphics = GdiGraphicsWrapper.FromImage(_rasterImage, _isStatic);
                    _graphics = GdiGraphicsImpl.FromImage(_rasterImage, _isStatic);
                    _graphics.Clear(_backColor);

                    _hitTestHelper = _graphics.HitTestHelper;
                }
            }
        }
Example #3
0
 public GdiGraphicsRenderer(GdiGraphics graphics, SvgWindow svgWindow)
     : this(graphics)
 {
     _svgWindow = svgWindow;
     if (_svgWindow != null)
     {
         _svgWindow.Renderer = this;
     }
 }
        protected void FitToViewbox(GdiGraphics graphics, RectangleF elmRect)
        {
            ISvgFitToViewBox fitToVBElm = _svgElement as ISvgFitToViewBox;

            if (fitToVBElm != null)
            {
                SvgPreserveAspectRatio spar = (SvgPreserveAspectRatio)fitToVBElm.PreserveAspectRatio.AnimVal;

                double[] translateAndScale = spar.FitToViewBox((SvgRect)fitToVBElm.ViewBox.AnimVal,
                                                               new SvgRect(elmRect.X, elmRect.Y, elmRect.Width, elmRect.Height));
                graphics.TranslateTransform((float)translateAndScale[0], (float)translateAndScale[1]);
                graphics.ScaleTransform((float)translateAndScale[2], (float)translateAndScale[3]);
            }
        }
        protected void SetTransform(GdiGraphics gr)
        {
            if (_svgElement is ISvgTransformable)
            {
                if (_transformMatrix == null)
                {
                    ISvgTransformable transElm  = (ISvgTransformable)_svgElement;
                    SvgTransformList  svgTList  = (SvgTransformList)transElm.Transform.AnimVal;
                    SvgMatrix         svgMatrix = ((SvgTransformList)transElm.Transform.AnimVal).TotalMatrix;

                    _transformMatrix = new Matrix((float)svgMatrix.A, (float)svgMatrix.B, (float)svgMatrix.C,
                                                  (float)svgMatrix.D, (float)svgMatrix.E, (float)svgMatrix.F);
                }
                gr.Transform = _transformMatrix;
            }
        }
        private SvgWindow GetSvgWindow(GdiGraphics graphics)
        {
            SvgImageElement iElm = this.Element as SvgImageElement;
            SvgWindow       wnd  = iElm.SvgWindow;

            if (_embeddedRenderer == null)
            {
                _embeddedRenderer = new GdiGraphicsRenderer(graphics, wnd);
            }
            else
            {
                wnd.Renderer             = _embeddedRenderer;
                _embeddedRenderer.Window = wnd;
            }

            return(wnd);
        }
        protected static void PaintMarkers(GdiGraphicsRenderer renderer,
                                           SvgStyleableElement styleElm, GdiGraphics gr)
        {
            // OPTIMIZE

            if (styleElm is ISharpMarkerHost)
            {
                string markerStartUrl  = ExtractMarkerUrl(styleElm.GetPropertyValue("marker-start", "marker"));
                string markerMiddleUrl = ExtractMarkerUrl(styleElm.GetPropertyValue("marker-mid", "marker"));
                string markerEndUrl    = ExtractMarkerUrl(styleElm.GetPropertyValue("marker-end", "marker"));

                if (markerStartUrl.Length > 0)
                {
                    GdiMarkerRendering grNode = CreateByUri(styleElm.OwnerDocument,
                                                            styleElm.BaseURI, markerStartUrl) as GdiMarkerRendering;
                    if (grNode != null)
                    {
                        grNode.PaintMarker(renderer, gr, SvgMarkerPosition.Start, styleElm);
                    }
                }

                if (markerMiddleUrl.Length > 0)
                {
                    // TODO markerMiddleUrl != markerStartUrl
                    GdiMarkerRendering grNode = CreateByUri(styleElm.OwnerDocument,
                                                            styleElm.BaseURI, markerMiddleUrl) as GdiMarkerRendering;
                    if (grNode != null)
                    {
                        grNode.PaintMarker(renderer, gr, SvgMarkerPosition.Mid, styleElm);
                    }
                }

                if (markerEndUrl.Length > 0)
                {
                    // TODO: markerEndUrl != markerMiddleUrl
                    GdiMarkerRendering grNode = CreateByUri(styleElm.OwnerDocument,
                                                            styleElm.BaseURI, markerEndUrl) as GdiMarkerRendering;
                    if (grNode != null)
                    {
                        grNode.PaintMarker(renderer, gr, SvgMarkerPosition.End, styleElm);
                    }
                }
            }
        }
Example #8
0
        private void Dispose(bool disposing)
        {
            if (_hitTestHelper != null)
            {
                _hitTestHelper.Dispose();
            }
            if (_disposeRaster && _rasterImage != null)
            {
                _rasterImage.Dispose();
            }
            if (_graphics != null)
            {
                _graphics.Dispose();
            }

            _graphics      = null;
            _rasterImage   = null;
            _hitTestHelper = null;
        }
Example #9
0
 public void ClearAll()
 {
     if (_graphics != null)
     {
         _graphics.Dispose();
         _graphics = null;
     }
     if (_rasterImage != null)
     {
         _rasterImage.Dispose();
         _rasterImage = null;
     }
     if (_hitTestHelper != null)
     {
         _hitTestHelper.Dispose();
         _hitTestHelper = null;
     }
     _hitTestHelper = GdiHitTestHelper.NoHit;
 }
        protected void SetQuality(GdiGraphics gr)
        {
            Graphics graphics = gr.Graphics;

            string colorRendering = _svgElement.GetComputedStringValue("color-rendering", string.Empty);

            switch (colorRendering)
            {
            case "optimizeSpeed":
                graphics.CompositingQuality = CompositingQuality.HighSpeed;
                break;

            case "optimizeQuality":
                graphics.CompositingQuality = CompositingQuality.HighQuality;
                break;

            default:
                // "auto"
                // todo: could use AssumeLinear for slightly better
                graphics.CompositingQuality = CompositingQuality.Default;
                break;
            }

            if (_svgElement is SvgTextContentElement)
            {
                // Unfortunately the text rendering hints are not applied because the
                // text path is recorded and painted to the Graphics object as a path
                // not as text.
                string textRendering = _svgElement.GetComputedStringValue("text-rendering", string.Empty);
                switch (textRendering)
                {
                case "optimizeSpeed":
                    graphics.SmoothingMode     = SmoothingMode.HighSpeed;
                    graphics.TextRenderingHint = System.Drawing.Text.TextRenderingHint.SingleBitPerPixel;
                    break;

                case "optimizeLegibility":
                    graphics.SmoothingMode     = SmoothingMode.HighQuality;
                    graphics.TextRenderingHint = System.Drawing.Text.TextRenderingHint.ClearTypeGridFit;
                    break;

                case "geometricPrecision":
                    graphics.SmoothingMode     = SmoothingMode.AntiAlias;
                    graphics.TextRenderingHint = System.Drawing.Text.TextRenderingHint.AntiAlias;
                    break;

                default:
                    // "auto"
                    graphics.SmoothingMode     = SmoothingMode.AntiAlias;
                    graphics.TextRenderingHint = System.Drawing.Text.TextRenderingHint.SystemDefault;
                    break;
                }
            }
            else
            {
                string shapeRendering = _svgElement.GetComputedStringValue("shape-rendering", string.Empty);
                switch (shapeRendering)
                {
                case "optimizeSpeed":
                    graphics.SmoothingMode = SmoothingMode.HighSpeed;
                    break;

                case "crispEdges":
                    graphics.SmoothingMode = SmoothingMode.None;
                    break;

                case "geometricPrecision":
                    graphics.SmoothingMode = SmoothingMode.HighQuality;
                    break;

                default:
                    // "auto"
                    graphics.SmoothingMode = SmoothingMode.AntiAlias;
                    break;
                }
            }
        }
        protected void SetClip(GdiGraphics graphics)
        {
            if (_svgElement == null)
            {
                return;
            }

            SvgRenderingHint hint = _svgElement.RenderingHint;

            // todo: should we correct the clipping to adjust to the off-one-pixel drawing?
            graphics.TranslateClip(1, 1);

            #region Clip with clip
            // see http://www.w3.org/TR/SVG/masking.html#OverflowAndClipProperties
            if (_svgElement is ISvgSvgElement || _svgElement is ISvgMarkerElement ||
                _svgElement is ISvgSymbolElement || _svgElement is ISvgPatternElement)
            {
                // check overflow property
                CssValue overflow = _svgElement.GetComputedCssValue("overflow", string.Empty) as CssValue;
                // TODO: clip can have "rect(10 10 auto 10)"
                CssPrimitiveValue clip = _svgElement.GetComputedCssValue("clip", string.Empty) as CssPrimitiveValue;

                string sOverflow = null;

                if (overflow != null || overflow.CssText == "")
                {
                    sOverflow = overflow.CssText;
                }
                else
                {
                    if (this is ISvgSvgElement)
                    {
                        sOverflow = "hidden";
                    }
                }

                if (sOverflow != null)
                {
                    // "If the 'overflow' property has a value other than hidden or scroll, the property has no effect (i.e., a clipping rectangle is not created)."
                    if (sOverflow == "hidden" || sOverflow == "scroll")
                    {
                        RectangleF clipRect = RectangleF.Empty;
                        if (clip != null && clip.PrimitiveType == CssPrimitiveType.Rect)
                        {
                            if (_svgElement is ISvgSvgElement)
                            {
                                ISvgSvgElement svgElement = (ISvgSvgElement)_svgElement;
                                SvgRect        viewPort   = svgElement.Viewport as SvgRect;
                                clipRect = GdiConverter.ToRectangle(viewPort);
                                ICssRect clipShape = (CssRect)clip.GetRectValue();
                                if (clipShape.Top.PrimitiveType != CssPrimitiveType.Ident)
                                {
                                    clipRect.Y += (float)clipShape.Top.GetFloatValue(CssPrimitiveType.Number);
                                }
                                if (clipShape.Left.PrimitiveType != CssPrimitiveType.Ident)
                                {
                                    clipRect.X += (float)clipShape.Left.GetFloatValue(CssPrimitiveType.Number);
                                }
                                if (clipShape.Right.PrimitiveType != CssPrimitiveType.Ident)
                                {
                                    clipRect.Width = (clipRect.Right - clipRect.X) - (float)clipShape.Right.GetFloatValue(CssPrimitiveType.Number);
                                }
                                if (clipShape.Bottom.PrimitiveType != CssPrimitiveType.Ident)
                                {
                                    clipRect.Height = (clipRect.Bottom - clipRect.Y) - (float)clipShape.Bottom.GetFloatValue(CssPrimitiveType.Number);
                                }
                            }
                        }
                        else if (clip == null || (clip.PrimitiveType == CssPrimitiveType.Ident && clip.GetStringValue() == "auto"))
                        {
                            if (_svgElement is ISvgSvgElement)
                            {
                                ISvgSvgElement svgElement = (ISvgSvgElement)_svgElement;
                                SvgRect        viewPort   = svgElement.Viewport as SvgRect;
                                clipRect = GdiConverter.ToRectangle(viewPort);
                            }
                            else if (_svgElement is ISvgMarkerElement || _svgElement is ISvgSymbolElement ||
                                     _svgElement is ISvgPatternElement)
                            {
                                // TODO: what to do here?
                            }
                        }
                        if (clipRect != RectangleF.Empty)
                        {
                            graphics.SetClip(clipRect);
                        }
                    }
                }
            }
            #endregion

            #region Clip with clip-path

            // see: http://www.w3.org/TR/SVG/masking.html#EstablishingANewClippingPath

            if (hint == SvgRenderingHint.Shape || hint == SvgRenderingHint.Text ||
                hint == SvgRenderingHint.Clipping || hint == SvgRenderingHint.Masking ||
                hint == SvgRenderingHint.Containment || hint == SvgRenderingHint.Image)
            {
                CssPrimitiveValue clipPath = _svgElement.GetComputedCssValue("clip-path", string.Empty) as CssPrimitiveValue;

                if (clipPath != null && clipPath.PrimitiveType == CssPrimitiveType.Uri)
                {
                    string absoluteUri = _svgElement.ResolveUri(clipPath.GetStringValue());

                    SvgClipPathElement eClipPath = _svgElement.OwnerDocument.GetNodeByUri(absoluteUri) as SvgClipPathElement;

                    if (eClipPath != null)
                    {
                        GraphicsPath gpClip = CreateClippingRegion(graphics, eClipPath);

                        RectangleF clipBounds = gpClip != null?gpClip.GetBounds() : RectangleF.Empty;

                        if (clipBounds.Width.Equals(0) || clipBounds.Height.Equals(0))
                        {
                            return;
                        }

                        SvgUnitType pathUnits = (SvgUnitType)eClipPath.ClipPathUnits.AnimVal;

                        if (pathUnits == SvgUnitType.ObjectBoundingBox)
                        {
                            SvgTransformableElement transElement = _svgElement as SvgTransformableElement;

                            if (transElement != null)
                            {
                                ISvgRect bbox = transElement.GetBBox();

                                // scale clipping path
                                Matrix matrix = new Matrix();
                                matrix.Scale((float)bbox.Width, (float)bbox.Height);
                                gpClip.Transform(matrix);
                                graphics.SetClip(gpClip);

                                // offset clip
                                graphics.TranslateClip((float)bbox.X, (float)bbox.Y);
                            }
                            else
                            {
                                throw new NotImplementedException("clip-path with SvgUnitType.ObjectBoundingBox "
                                                                  + "not supported for this type of element: " + _svgElement.GetType());
                            }
                        }
                        else
                        {
                            graphics.SetClip(gpClip);
                        }

                        gpClip.Dispose();
                        gpClip = null;
                    }
                }
            }
            #endregion
        }
Example #12
0
        protected static void PaintMarkers(GdiGraphicsRenderer renderer,
                                           SvgStyleableElement styleElm, GdiGraphics gr)
        {
            // OPTIMIZE

            if (styleElm is ISharpMarkerHost)
            {
                string markerStartUrl  = ExtractMarkerUrl(styleElm.GetPropertyValue("marker-start", "marker"));
                string markerMiddleUrl = ExtractMarkerUrl(styleElm.GetPropertyValue("marker-mid", "marker"));
                string markerEndUrl    = ExtractMarkerUrl(styleElm.GetPropertyValue("marker-end", "marker"));
                string markerAll       = ExtractMarkerUrl(styleElm.GetPropertyValue("marker", "marker"));

                //  The SVG specification defines three properties to reference markers: marker-start,
                // marker -mid, marker-end. It also provides a shorthand property, marker. Using the marker
                // property from a style sheet is equivalent to using all three (start, mid, end).
                // However, shorthand properties cannot be used as presentation attributes.
                if (!string.IsNullOrWhiteSpace(markerAll) && !IsPresentationMarker(styleElm))
                {
                    if (string.IsNullOrWhiteSpace(markerStartUrl))
                    {
                        markerStartUrl = markerAll;
                    }
                    if (string.IsNullOrWhiteSpace(markerMiddleUrl))
                    {
                        markerMiddleUrl = markerAll;
                    }
                    if (string.IsNullOrWhiteSpace(markerEndUrl))
                    {
                        markerEndUrl = markerAll;
                    }
                }

                if (markerStartUrl.Length > 0)
                {
                    GdiMarkerRendering grNode = CreateByUri(styleElm.OwnerDocument,
                                                            styleElm.BaseURI, markerStartUrl) as GdiMarkerRendering;
                    if (grNode != null)
                    {
                        grNode.PaintMarker(renderer, gr, SvgMarkerPosition.Start, styleElm);
                    }
                }

                if (markerMiddleUrl.Length > 0)
                {
                    // TODO markerMiddleUrl != markerStartUrl
                    GdiMarkerRendering grNode = CreateByUri(styleElm.OwnerDocument,
                                                            styleElm.BaseURI, markerMiddleUrl) as GdiMarkerRendering;
                    if (grNode != null)
                    {
                        grNode.PaintMarker(renderer, gr, SvgMarkerPosition.Mid, styleElm);
                    }
                }

                if (markerEndUrl.Length > 0)
                {
                    // TODO: markerEndUrl != markerMiddleUrl
                    GdiMarkerRendering grNode = CreateByUri(styleElm.OwnerDocument,
                                                            styleElm.BaseURI, markerEndUrl) as GdiMarkerRendering;
                    if (grNode != null)
                    {
                        grNode.PaintMarker(renderer, gr, SvgMarkerPosition.End, styleElm);
                    }
                }
            }
        }
Example #13
0
        public void PaintMarker(GdiGraphicsRenderer renderer, GdiGraphics gr,
                                SvgMarkerPosition markerPos, SvgStyleableElement refElement)
        {
            ISharpMarkerHost markerHostElm = (ISharpMarkerHost)refElement;
            SvgMarkerElement markerElm     = (SvgMarkerElement)_svgElement;

            SvgPointF[] vertexPositions = markerHostElm.MarkerPositions;
            if (vertexPositions == null)
            {
                return;
            }
            var comparer = StringComparison.OrdinalIgnoreCase;

            bool mayHaveCurves = markerHostElm.MayHaveCurves;
            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;
            }
            int end = start + len;

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

                GdiGraphicsContainer gc = gr.BeginContainer();

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

                if (markerElm.OrientType.AnimVal.Equals((ushort)SvgMarkerOrient.Angle))
                {
                    double scaleValue = markerElm.OrientAngle.AnimVal.Value;
                    if (!scaleValue.Equals(0))
                    {
                        gr.RotateTransform((float)scaleValue);
                    }
                }
                else
                {
                    double angle;

                    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;
                            }
                        }
                        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);
                        //double angle2 = 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;
                            }
                        }
                        //if (mayHaveCurves)
                        //{
                        //	angle = this.GetAngleAt(start - 1, angle, markerPos, markerHostElm);
                        //}
                        break;
                    }
                    gr.RotateTransform((float)angle);
                }

                // 'viewBox' and 'preserveAspectRatio' attributes
                // viewBox -> viewport(0, 0, markerWidth, markerHeight)
                var      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));

                //// 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
                //float refX = (float)markerElm.RefX.AnimVal.Value;
                //float refY = (float)markerElm.RefY.AnimVal.Value;

                ////if (!(refX.Equals(0) && refY.Equals(0)))
                ////{
                ////	var points = new PointF[] { new PointF(refX, refY) };
                ////	gr.Transform.TransformPoints(points);

                ////	refX = points[0].X;
                ////	refY = points[0].Y;

                ////	gr.TranslateTransform(-refX, -refY);
                ////}

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

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

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

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

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

                if (!(translateAndScale[2].Equals(1) && translateAndScale[3].Equals(1)))
                {
                    gr.ScaleTransform((float)translateAndScale[2], (float)translateAndScale[3]);
                }

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

                RectangleF rectClip = RectangleF.Empty;

                if (markerUnits.AnimVal.Equals((ushort)SvgMarkerUnit.StrokeWidth))
                {
                    string overflowAttr = markerElm.GetAttribute("overflow");
                    if (string.IsNullOrWhiteSpace(overflowAttr) ||
                        overflowAttr.Equals("scroll", comparer) || overflowAttr.Equals(CssConstants.ValHidden, comparer))
                    {
                        var     markerClip = RectangleF.Empty;
                        SvgRect clipRect   = (SvgRect)markerElm.ViewBox.AnimVal;
                        if (clipRect != null && !clipRect.IsEmpty)
                        {
                            rectClip = new RectangleF((float)clipRect.X, (float)clipRect.Y,
                                                      (float)clipRect.Width, (float)clipRect.Height);
                        }
                        else if (markerElm.IsSizeDefined)
                        {
                            rectClip = new RectangleF(0, 0,
                                                      (float)markerElm.MarkerWidth.AnimVal.Value, (float)markerElm.MarkerHeight.AnimVal.Value);
                        }
                    }
                }

                if (rectClip.IsEmpty)
                {
                    SetClip(gr);
                }
                else
                {
                    gr.SetClip(rectClip);
                }

                renderer.RenderChildren(markerElm);

                gr.EndContainer(gc);
            }
        }
        public override void Render(GdiGraphicsRenderer renderer)
        {
            _graphics = renderer.GdiGraphics;

            SvgRenderingHint hint = _svgElement.RenderingHint;

            if (hint == SvgRenderingHint.Clipping)
            {
                return;
            }
            if (_svgElement.ParentNode is SvgClipPathElement)
            {
                return;
            }

            SvgTextElement textElement = _svgElement as SvgTextElement;

            if (textElement == null)
            {
                return;
            }

            string sVisibility = textElement.GetPropertyValue("visibility");
            string sDisplay    = textElement.GetPropertyValue("display");

            if (string.Equals(sVisibility, "hidden") || string.Equals(sDisplay, "none"))
            {
                return;
            }

            Clip(_graphics);

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

            ctp = GetCurrentTextPosition(textElement, ctp);
            string sBaselineShift = textElement.GetPropertyValue("baseline-shift").Trim();
            double shiftBy        = 0;

            if (sBaselineShift.Length > 0)
            {
                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);
                }
            }

            XmlNodeType nodeType = XmlNodeType.None;

            foreach (XmlNode child in _svgElement.ChildNodes)
            {
                SvgStyleableElement stylable = child as SvgStyleableElement;
                if (stylable != null)
                {
                    sVisibility = stylable.GetPropertyValue("visibility");
                    sDisplay    = stylable.GetPropertyValue("display");
                    if (string.Equals(sVisibility, "hidden") || string.Equals(sDisplay, "none"))
                    {
                        continue;
                    }
                }

                nodeType = child.NodeType;
                if (nodeType == XmlNodeType.Text)
                {
                    ctp.Y -= (float)shiftBy;
                    AddGraphicsPath(textElement, ref ctp, GetText(textElement, child));
                    ctp.Y += (float)shiftBy;
                }
                else if (nodeType == XmlNodeType.Element)
                {
                    string nodeName = child.Name;
                    if (string.Equals(nodeName, "tref"))
                    {
                        AddTRefElementPath((SvgTRefElement)child, ref ctp);
                    }
                    else if (string.Equals(nodeName, "tspan"))
                    {
                        AddTSpanElementPath((SvgTSpanElement)child, ref ctp);
                    }
                }
            }

            PaintMarkers(renderer, textElement, _graphics);

            _graphics = null;
        }
Example #15
0
 public GdiGraphicsRenderer(GdiGraphics graphics)
     : this(true, false)
 {
     _graphics     = graphics;
     _ownsGraphics = (graphics == null);
 }
        private GraphicsPath CreateClippingRegion(GdiGraphics graphics, SvgClipPathElement clipPath)
        {
            GraphicsPath path = new GraphicsPath();

            foreach (XmlNode node in clipPath.ChildNodes)
            {
                if (node.NodeType != XmlNodeType.Element)
                {
                    continue;
                }

                // Handle a case where the clip element has "use" element as a child...
                if (string.Equals(node.LocalName, "use"))
                {
                    SvgUseElement useElement = (SvgUseElement)node;

                    XmlElement refEl = useElement.ReferencedElement;
                    if (refEl != null)
                    {
                        XmlElement refElParent = (XmlElement)refEl.ParentNode;
                        useElement.OwnerDocument.Static = true;
                        useElement.CopyToReferencedElement(refEl);
                        refElParent.RemoveChild(refEl);
                        useElement.AppendChild(refEl);

                        foreach (XmlNode useChild in useElement.ChildNodes)
                        {
                            if (useChild.NodeType != XmlNodeType.Element)
                            {
                                continue;
                            }

                            SvgStyleableElement element = useChild as SvgStyleableElement;
                            if (element != null && element.RenderingHint == SvgRenderingHint.Shape)
                            {
                                GraphicsPath childPath = CreatePath(element);

                                if (childPath != null)
                                {
                                    string clipRule = element.GetPropertyValue("clip-rule");
                                    path.FillMode = (clipRule == "evenodd") ? FillMode.Alternate : FillMode.Winding;

                                    path.AddPath(childPath, true);
                                }
                            }
                        }

                        useElement.RemoveChild(refEl);
                        useElement.RestoreReferencedElement(refEl);
                        refElParent.AppendChild(refEl);
                        useElement.OwnerDocument.Static = false;
                    }
                }
                else
                {
                    SvgStyleableElement element = node as SvgStyleableElement;
                    if (element != null)
                    {
                        if (element.RenderingHint == SvgRenderingHint.Shape)
                        {
                            GraphicsPath childPath = CreatePath(element);

                            if (childPath != null)
                            {
                                string clipRule = element.GetPropertyValue("clip-rule");
                                path.FillMode = (clipRule == "evenodd") ? FillMode.Alternate : FillMode.Winding;

                                path.AddPath(childPath, true);
                            }
                        }
                        else if (element.RenderingHint == SvgRenderingHint.Text)
                        {
                            GdiTextRendering textRendering = new GdiTextRendering(element);
                            textRendering.TextMode = GdiTextMode.Outlining;

                            GdiGraphicsRenderer renderer = new GdiGraphicsRenderer(graphics);

                            textRendering.BeforeRender(renderer);
                            textRendering.Render(renderer);
                            textRendering.AfterRender(renderer);

                            GraphicsPath childPath = textRendering.Path;
                            if (childPath != null)
                            {
                                string clipRule = element.GetPropertyValue("clip-rule");
                                path.FillMode = (clipRule == "evenodd") ? FillMode.Alternate : FillMode.Winding;

                                path.AddPath(childPath, true);
                            }
                        }
                    }
                }
            }

            return(path);
        }
        public override void Render(GdiGraphicsRenderer renderer)
        {
            _graphics = renderer.GdiGraphics;

            //SvgRenderingHint hint = _svgElement.RenderingHint;
            //if (hint == SvgRenderingHint.Clipping)
            //{
            //    return;
            //}
            //if (_svgElement.ParentNode is SvgClipPathElement)
            //{
            //    return;
            //}

            SvgTextBaseElement textElement = _svgElement as SvgTextBaseElement;

            if (textElement == null)
            {
                return;
            }

            string sVisibility = textElement.GetPropertyValue("visibility");
            string sDisplay    = textElement.GetPropertyValue("display");

            if (string.Equals(sVisibility, "hidden") || string.Equals(sDisplay, "none"))
            {
                return;
            }

            if (_textMode != GdiTextMode.Outlining)
            {
                SetClip(_graphics);
            }

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

            ctp = GetCurrentTextPosition(textElement, ctp);
            string sBaselineShift = textElement.GetPropertyValue("baseline-shift").Trim();
            double shiftBy        = 0;

            if (sBaselineShift.Length > 0)
            {
                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);
                }
            }

            // 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);
            }

            XmlNodeType nodeType = XmlNodeType.None;

            foreach (XmlNode child in _svgElement.ChildNodes)
            {
                SvgStyleableElement stylable = child as SvgStyleableElement;
                if (stylable != null)
                {
                    sVisibility = stylable.GetPropertyValue("visibility");
                    sDisplay    = stylable.GetPropertyValue("display");
                    if (string.Equals(sVisibility, "hidden") || string.Equals(sDisplay, "none"))
                    {
                        continue;
                    }
                }

                nodeType = child.NodeType;
                if (nodeType == XmlNodeType.Text)
                {
                    ctp.Y -= (float)shiftBy;
                    AddGraphicsPath(textElement, ref ctp, GetText(textElement, child));
                    ctp.Y += (float)shiftBy;
                }
                else if (nodeType == XmlNodeType.Element)
                {
                    string nodeName = child.Name;
                    if (string.Equals(nodeName, "tref"))
                    {
                        AddTRefElementPath((SvgTRefElement)child, ref ctp);
                    }
                    else if (string.Equals(nodeName, "tspan"))
                    {
                        AddTSpanElementPath((SvgTSpanElement)child, ref ctp);
                    }
                }
            }

            PaintMarkers(renderer, textElement, _graphics);

            _graphics = null;
        }
Example #18
0
        public void PaintMarker(GdiGraphicsRenderer renderer, GdiGraphics 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();

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

                if (markerElm.OrientType.AnimVal.Equals((ushort)SvgMarkerOrient.Angle))
                {
                    gr.RotateTransform((float)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((float)angle);
                }

                if (markerElm.MarkerUnits.AnimVal.Equals((ushort)SvgMarkerUnit.StrokeWidth))
                {
                    SvgLength strokeWidthLength = new SvgLength(refElement,
                                                                "stroke-width", SvgLengthSource.Css, SvgLengthDirection.Viewport, "1");
                    float strokeWidth = (float)strokeWidthLength.Value;
                    gr.ScaleTransform(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));


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

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

                Clip(gr);

                renderer.RenderChildren(markerElm);

                gr.EndContainer(gc);
            }
        }