예제 #1
0
 //Baseline calculation to match http://bobpowell.net/formattingtext.aspx
 public float Ascent(ISvgRenderer renderer)
 {
     var ff = _font.FontFamily;
     float ascent = ff.GetCellAscent(_font.Style);
     float baselineOffset = _font.SizeInPoints / ff.GetEmHeight(_font.Style) * ascent;
     return renderer.DpiY / 72f * baselineOffset;
 }
예제 #2
0
파일: SvgPolyline.cs 프로젝트: durlandd/SVG
        public override GraphicsPath Path(ISvgRenderer renderer)
        {
            if (_Path == null || this.IsPathDirty)
            {
                _Path = new GraphicsPath();

                try
                {
                    for (int i = 0; (i + 1) < Points.Count; i += 2)
                    {
                        PointF endPoint = new PointF(Points[i].ToDeviceValue(renderer, UnitRenderingType.Horizontal, this),
                                                     Points[i + 1].ToDeviceValue(renderer, UnitRenderingType.Vertical, this));

                        // TODO: Remove unrequired first line
                        if (_Path.PointCount == 0)
                        {
                            _Path.AddLine(endPoint, endPoint);
                        }
                        else
                        {
                            _Path.AddLine(_Path.GetLastPoint(), endPoint);
                        }
                    }
                }
                catch (Exception exc)
                {
                    Trace.TraceError("Error rendering points: " + exc.Message);
                }
                this.IsPathDirty = false;
            }
            return _Path;
        }
예제 #3
0
 public System.Drawing.SizeF MeasureString(ISvgRenderer renderer, string text)
 {
     var result = new List<RectangleF>();
     using (var path = GetPath(renderer, text, result, true)) { }
     var nonEmpty = result.Where(r => r != RectangleF.Empty);
     if (!nonEmpty.Any()) return SizeF.Empty;
     return new SizeF(nonEmpty.Last().Right - nonEmpty.First().Left, Ascent(renderer));
 }
        public SvgPictureBoxWindow(SvgPictureBox control, ISvgRenderer renderer)
            : base(control.Width, control.Height, renderer)
        {
            if (control == null)
            {
                throw new NullReferenceException("control cannot be null");
            }

            _svgPictureBox = control;
        }
        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);
                }
            //}
        }
예제 #6
0
        public SizeF MeasureString(ISvgRenderer renderer, string text)
        {
		    var g = GetGraphics(renderer);
		    StringFormat format = StringFormat.GenericTypographic.Clone() as StringFormat;
		    format.SetMeasurableCharacterRanges(new CharacterRange[] {new CharacterRange(0, text.Length)});
		    format.FormatFlags |= StringFormatFlags.MeasureTrailingSpaces;
			Region[] r = g.MeasureCharacterRanges(text, _font, new Rectangle(0, 0, 1000, 1000), format);
			RectangleF rect = r[0].GetBounds(g);

			return new SizeF(rect.Width, Ascent(renderer));
		}
예제 #7
0
        protected SvgWindow(long innerWidth, long innerHeight, ISvgRenderer renderer)
        {
            this.renderer = renderer;
            if (this.renderer != null)
            {
                this.renderer.Window = this;
            }

            this.innerWidth  = innerWidth;
            this.innerHeight = innerHeight;
        }
        public override void BeforeRender(ISvgRenderer renderer)
        {
            if (_uniqueColor.IsEmpty)
                  _uniqueColor = ((GdiRenderer)renderer)._getNextColor(this);

            GraphicsWrapper graphics = ((GdiRenderer) renderer).GraphicsWrapper;

            graphicsContainer = graphics.BeginContainer();
            SetQuality(graphics);
            Transform(graphics);
        }
예제 #9
0
 public void AddStringToPath(ISvgRenderer renderer, GraphicsPath path, string text, PointF location)
 {
     var textPath = GetPath(renderer, text, null, false);
     if (textPath.PointCount > 0)
     {
         using (var translate = new Matrix())
         {
             translate.Translate(location.X, location.Y);
             textPath.Transform(translate);
             path.AddPath(textPath, false);
         }
     }
 }
예제 #10
0
        private GraphicsPath GetPath(ISvgRenderer renderer, string text, IList<RectangleF> ranges, bool measureSpaces)
        {
            EnsureDictionaries();

            RectangleF bounds;
            SvgGlyph glyph;
            SvgKern kern;
            GraphicsPath path;
            SvgGlyph prevGlyph = null;
            Matrix scaleMatrix;
            float xPos = 0;

            var ascent = Ascent(renderer);

            var result = new GraphicsPath();
            if (string.IsNullOrEmpty(text)) return result;

            for (int i = 0; i < text.Length; i++)
            {
                if (!_glyphs.TryGetValue(text.Substring(i, 1), out glyph)) glyph = _font.Descendants().OfType<SvgMissingGlyph>().First();
                if (prevGlyph != null && _kerning.TryGetValue(prevGlyph.GlyphName + "|" + glyph.GlyphName, out kern))
                {
                    xPos -= kern.Kerning * _emScale;
                }
                path = (GraphicsPath)glyph.Path(renderer).Clone();
                scaleMatrix = new Matrix();
                scaleMatrix.Scale(_emScale, -1 * _emScale, MatrixOrder.Append);
                scaleMatrix.Translate(xPos, ascent, MatrixOrder.Append);
                path.Transform(scaleMatrix);
                scaleMatrix.Dispose();

                bounds = path.GetBounds();
                if (ranges != null)
                {
                    if (measureSpaces && bounds == RectangleF.Empty)
                    {
                        ranges.Add(new RectangleF(xPos, 0, glyph.HorizAdvX * _emScale, ascent));
                    }
                    else
                    {
                        ranges.Add(bounds);
                    }
                }
                if (path.PointCount > 0) result.AddPath(path, false);

                xPos += glyph.HorizAdvX * _emScale;
                prevGlyph = glyph;
            }

            return result;
        }
예제 #11
0
        public virtual bool NeedRender(ISvgRenderer renderer)
        {
            // We make this assumption so that the first pass is still fast
              // That way we don't have to calculate the screen regions
              // Before a full rerender
              if (screenRegion == RectangleF.Empty)
            return true;
              if (renderer.InvalidRect == RectangleF.Empty)
            return true;
              if (renderer.InvalidRect.IntersectsWith(screenRegion))
            // TODO: Eventually add a full path check here?
            return true;

              return false;
        }
예제 #12
0
 public IList<RectangleF> MeasureCharacters(ISvgRenderer renderer, string text)
 {
     var g = GetGraphics(renderer);
     var regions = new List<RectangleF>();
     StringFormat format;
     for (int s = 0; s <= (text.Length - 1) / 32; s++)
     {
         format = StringFormat.GenericTypographic;
         format.FormatFlags |= StringFormatFlags.MeasureTrailingSpaces;
         format.SetMeasurableCharacterRanges((from r in Enumerable.Range(32 * s, Math.Min(32, text.Length - 32 * s))
                                              select new CharacterRange(r, 1)).ToArray());
         regions.AddRange(from r in g.MeasureCharacterRanges(text, _font, new Rectangle(0, 0, 1000, 1000), format)
                          select r.GetBounds(g));
     }
     return regions;
 }
예제 #13
0
        public override void RenderChildren(ISvgRenderer renderer)
        {
            // search through all child elements and find one that passes all tests
            foreach ( XmlNode node in ChildNodes )
            {
                SvgElement element = node as SvgElement;
                ISvgTests testsElement = node as ISvgTests;
                if ( element != null && testsElement != null && passesAllTest(testsElement))
                {
                    element.Render(renderer);

                    // make sure we only render the first element that passes
                    break;
                }
            }
        }
        public override void CacheRenderingRegion(ISvgRenderer renderer)
        {
            base.CacheRenderingRegion(renderer);

              if (renderingNode != null)
              {
            if (renderingNode.ScreenRegion != RectangleF.Empty)
              return;

            //TODO this is still fairly experimental, a margin of 20 gives us some overlap for leeway
            //TODO in general, overlap is necessary to handle strokes, which are not covered in bbox, but are
            //TODO for rendering purposes (same with markers)
            string strokeWidth = this.GetPropertyValue("stroke-width");
            if(strokeWidth.Length == 0) strokeWidth = "1px";
            SvgLength strokeWidthLength = new SvgLength(this, "stroke-width", SvgLengthDirection.Viewport, strokeWidth);
            renderingNode.ScreenRegion = GetBRect((float)strokeWidthLength.Value);
              }
        }
예제 #15
0
        protected override GraphicsPath GetBaselinePath(ISvgRenderer renderer)
        {
            var path = this.OwnerDocument.IdManager.GetElementById(this.ReferencedPath) as SvgVisualElement;
            if (path == null) return null;
            var pathData = (GraphicsPath)path.Path(renderer).Clone();
            if (path.Transforms.Count > 0)
            {
                Matrix transformMatrix = new Matrix(1, 0, 0, 1, 0, 0);

                foreach (var transformation in path.Transforms)
                {
                    transformMatrix.Multiply(transformation.Matrix);
                }

                pathData.Transform(transformMatrix);
            }
            return pathData;
        }
예제 #16
0
        public override void Render(ISvgRenderer renderer)
        {
            GraphicsWrapper graphics = ((GdiRenderer) renderer).GraphicsWrapper;

            SvgSvgElement svgElm = (SvgSvgElement) element;

            float x = (float)svgElm.X.AnimVal.Value;
            float y = (float)svgElm.Y.AnimVal.Value;
            float width = (float)svgElm.Width.AnimVal.Value;
            float height = (float)svgElm.Height.AnimVal.Value;

            RectangleF elmRect = new RectangleF(x, y, width, height);

            if ( element.ParentNode is SvgElement )
            {
                // TODO: should it be moved with x and y?
            }

            fitToViewbox(graphics, elmRect);
        }
예제 #17
0
파일: SvgPolyline.cs 프로젝트: hh10k/SVG
        public override GraphicsPath Path(ISvgRenderer renderer)
        {
            if ((_Path == null || this.IsPathDirty) && base.StrokeWidth > 0)
            {
                _Path = new GraphicsPath();

                try
                {
                    for (int i = 0; (i + 1) < Points.Count; i += 2)
                    {
                        PointF endPoint = new PointF(Points[i].ToDeviceValue(renderer, UnitRenderingType.Horizontal, this),
                                                     Points[i + 1].ToDeviceValue(renderer, UnitRenderingType.Vertical, this));

                        if (renderer == null)
                        {
                          var radius = base.StrokeWidth / 2;
                          _Path.AddEllipse(endPoint.X - radius, endPoint.Y - radius, 2 * radius, 2 * radius);
                          continue;
                        }

                        // TODO: Remove unrequired first line
                        if (_Path.PointCount == 0)
                        {
                            _Path.AddLine(endPoint, endPoint);
                        }
                        else
                        {
                            _Path.AddLine(_Path.GetLastPoint(), endPoint);
                        }
                    }
                }
                catch (Exception exc)
                {
                    Trace.TraceError("Error rendering points: " + exc.Message);
                }
                if (renderer != null)
                  this.IsPathDirty = false;
            }
            return _Path;
        }
예제 #18
0
파일: SvgUnit.cs 프로젝트: vvvv/SVG
 private IFontDefn GetFont(ISvgRenderer renderer, SvgElement owner)
 {
     if (owner == null) return null;
     var visual = owner.Parents.OfType<SvgVisualElement>().FirstOrDefault();
     return visual?.GetFont(renderer);
 }
예제 #19
0
 protected internal override void RenderFillAndStroke(ISvgRenderer renderer)
 {
     base.RenderFillAndStroke(renderer);
     RenderChildren(renderer);
 }
예제 #20
0
        private IFontDefn GetFont(ISvgRenderer renderer, SvgElement owner, SvgFontManager fontManager)
        {
            var visual = owner?.Parents.OfType <SvgVisualElement>().FirstOrDefault();

            return(visual?.GetFont(renderer, fontManager));
        }
예제 #21
0
 /// <summary>
 /// Renders the <see cref="SvgElement"/> and contents to the specified <see cref="ISvgRenderer"/> object.
 /// </summary>
 /// <param name="renderer">The <see cref="ISvgRenderer"/> object to render to.</param>
 void ISvgElement.Render(ISvgRenderer renderer)
 {
     this.Render(renderer);
 }
예제 #22
0
 /// <summary>
 /// Renders this element to the <see cref="ISvgRenderer"/>.
 /// </summary>
 /// <param name="renderer">The <see cref="ISvgRenderer"/> that the element should use to render itself.</param>
 public void RenderElement(ISvgRenderer renderer)
 {
     this.Render(renderer);
 }
예제 #23
0
        /// <summary>
        /// Gets a <see cref="Brush"/> representing the current paint server.
        /// </summary>
        /// <param name="renderingElement">The owner <see cref="SvgVisualElement"/>.</param>
        /// <param name="renderer">The renderer object.</param>
        /// <param name="opacity">The opacity of the brush.</param>
        /// <param name="forStroke">Not used.</param>
        public override Brush GetBrush(SvgVisualElement renderingElement, ISvgRenderer renderer, float opacity, bool forStroke = false)
        {
            var chain = new List <SvgPatternServer>();
            var curr  = this;

            while (curr != null)
            {
                chain.Add(curr);
                curr = SvgDeferredPaintServer.TryGet <SvgPatternServer>(curr.InheritGradient, renderingElement);
            }

            var childElem = chain.Where((p) => p.Children != null && p.Children.Count > 0).FirstOrDefault();

            if (childElem == null)
            {
                return(null);
            }
            var widthElem  = chain.Where((p) => p.Width != null && p.Width != SvgUnit.None).FirstOrDefault();
            var heightElem = chain.Where((p) => p.Height != null && p.Height != SvgUnit.None).FirstOrDefault();

            if (widthElem == null && heightElem == null)
            {
                return(null);
            }

            var viewBoxElem = chain.Where((p) => p.ViewBox != null && p.ViewBox != SvgViewBox.Empty).FirstOrDefault();
            var viewBox     = viewBoxElem == null ? SvgViewBox.Empty : viewBoxElem.ViewBox;
            var xElem       = chain.Where((p) => p.X != null && p.X != SvgUnit.None).FirstOrDefault();
            var yElem       = chain.Where((p) => p.Y != null && p.Y != SvgUnit.None).FirstOrDefault();
            var xUnit       = xElem == null ? SvgUnit.Empty : xElem.X;
            var yUnit       = yElem == null ? SvgUnit.Empty : yElem.Y;

            var patternUnitElem        = chain.Where((p) => p.PatternUnits != SvgCoordinateUnits.Inherit).FirstOrDefault();
            var patternUnits           = (patternUnitElem == null ? SvgCoordinateUnits.ObjectBoundingBox : patternUnitElem.PatternUnits);
            var patternContentUnitElem = chain.Where((p) => p.PatternContentUnits != SvgCoordinateUnits.Inherit).FirstOrDefault();
            var patternContentUnits    = (patternContentUnitElem == null ? SvgCoordinateUnits.UserSpaceOnUse : patternContentUnitElem.PatternContentUnits);

            try
            {
                if (patternUnits == SvgCoordinateUnits.ObjectBoundingBox)
                {
                    renderer.SetBoundable(renderingElement);
                }

                using (var patternMatrix = new Matrix())
                {
                    var bounds = renderer.GetBoundable().Bounds;
                    var xScale = (patternUnits == SvgCoordinateUnits.ObjectBoundingBox ? bounds.Width : 1);
                    var yScale = (patternUnits == SvgCoordinateUnits.ObjectBoundingBox ? bounds.Height : 1);

                    float x = xScale * NormalizeUnit(xUnit).ToDeviceValue(renderer, UnitRenderingType.Horizontal, this);
                    float y = yScale * NormalizeUnit(yUnit).ToDeviceValue(renderer, UnitRenderingType.Vertical, this);

                    float width  = xScale * NormalizeUnit(widthElem.Width).ToDeviceValue(renderer, UnitRenderingType.Horizontal, this);
                    float height = yScale * NormalizeUnit(heightElem.Height).ToDeviceValue(renderer, UnitRenderingType.Vertical, this);

                    // Apply a scale if needed
                    patternMatrix.Scale((patternContentUnits == SvgCoordinateUnits.ObjectBoundingBox ? bounds.Width : 1) *
                                        (viewBox.Width > 0 ? width / viewBox.Width : 1),
                                        (patternContentUnits == SvgCoordinateUnits.ObjectBoundingBox ? bounds.Height : 1) *
                                        (viewBox.Height > 0 ? height / viewBox.Height : 1), MatrixOrder.Prepend);

                    Bitmap image = new Bitmap((int)width, (int)height);
                    using (var iRenderer = SvgRenderer.FromImage(image))
                    {
                        iRenderer.SetBoundable((_patternContentUnits == SvgCoordinateUnits.ObjectBoundingBox) ? new GenericBoundable(0, 0, width, height) : renderer.GetBoundable());
                        iRenderer.Transform     = patternMatrix;
                        iRenderer.SmoothingMode = SmoothingMode.AntiAlias;
                        iRenderer.SetClip(new Region(new RectangleF(0, 0,
                                                                    viewBox.Width > 0 ? viewBox.Width : width,
                                                                    viewBox.Height > 0 ? viewBox.Height : height)));

                        foreach (SvgElement child in childElem.Children)
                        {
                            child.RenderElement(iRenderer);
                        }
                    }

                    TextureBrush textureBrush   = new TextureBrush(image);
                    var          brushTransform = EffectivePatternTransform.Clone();
                    brushTransform.Translate(x, y, MatrixOrder.Append);
                    textureBrush.Transform = brushTransform;
                    return(textureBrush);
                }
            }
            finally
            {
                if (this.PatternUnits == SvgCoordinateUnits.ObjectBoundingBox)
                {
                    renderer.PopBoundable();
                }
            }
        }
예제 #24
0
 /// <summary>
 /// Renders the <see cref="SvgElement"/> and contents to the specified <see cref="ISvgRenderer"/> object.
 /// </summary>
 /// <param name="renderer">The <see cref="ISvgRenderer"/> object to render to.</param>
 protected override void Render(ISvgRenderer renderer)
 {
     // Never render paint servers or their children
 }
예제 #25
0
        public void AddViewBoxTransform(SvgAspectRatio aspectRatio, ISvgRenderer renderer, SvgFragment frag)
        {
            var x = (frag == null ? 0 : frag.X.ToDeviceValue(renderer, UnitRenderingType.Horizontal, frag));
            var y = (frag == null ? 0 : frag.Y.ToDeviceValue(renderer, UnitRenderingType.Vertical, frag));

            if (this.Equals(SvgViewBox.Empty))
            {
                renderer.TranslateTransform(x, y, MatrixOrder.Prepend);
                return;
            }

            var width  = (frag == null ? this.Width : frag.Width.ToDeviceValue(renderer, UnitRenderingType.Horizontal, frag));
            var height = (frag == null ? this.Height : frag.Height.ToDeviceValue(renderer, UnitRenderingType.Vertical, frag));

            var fScaleX = width / this.Width;
            var fScaleY = height / this.Height; //(this.MinY < 0 ? -1 : 1) *
            var fMinX   = -this.MinX * fScaleX;
            var fMinY   = -this.MinY * fScaleY;

            if (aspectRatio == null)
            {
                aspectRatio = new SvgAspectRatio(SvgPreserveAspectRatio.xMidYMid, false);
            }
            if (aspectRatio.Align != SvgPreserveAspectRatio.none)
            {
                if (aspectRatio.Slice)
                {
                    fScaleX = Math.Max(fScaleX, fScaleY);
                    fScaleY = Math.Max(fScaleX, fScaleY);
                }
                else
                {
                    fScaleX = Math.Min(fScaleX, fScaleY);
                    fScaleY = Math.Min(fScaleX, fScaleY);
                }
                float fViewMidX = (this.Width / 2) * fScaleX;
                float fViewMidY = (this.Height / 2) * fScaleY;
                float fMidX     = width / 2;
                float fMidY     = height / 2;
                fMinX = -this.MinX * fScaleX;
                fMinY = -this.MinY * fScaleY;

                switch (aspectRatio.Align)
                {
                case SvgPreserveAspectRatio.xMinYMin:
                    break;

                case SvgPreserveAspectRatio.xMidYMin:
                    fMinX += fMidX - fViewMidX;
                    break;

                case SvgPreserveAspectRatio.xMaxYMin:
                    fMinX += width - this.Width * fScaleX;
                    break;

                case SvgPreserveAspectRatio.xMinYMid:
                    fMinY += fMidY - fViewMidY;
                    break;

                case SvgPreserveAspectRatio.xMidYMid:
                    fMinX += fMidX - fViewMidX;
                    fMinY += fMidY - fViewMidY;
                    break;

                case SvgPreserveAspectRatio.xMaxYMid:
                    fMinX += width - this.Width * fScaleX;
                    fMinY += fMidY - fViewMidY;
                    break;

                case SvgPreserveAspectRatio.xMinYMax:
                    fMinY += height - this.Height * fScaleY;
                    break;

                case SvgPreserveAspectRatio.xMidYMax:
                    fMinX += fMidX - fViewMidX;
                    fMinY += height - this.Height * fScaleY;
                    break;

                case SvgPreserveAspectRatio.xMaxYMax:
                    fMinX += width - this.Width * fScaleX;
                    fMinY += height - this.Height * fScaleY;
                    break;

                default:
                    break;
                }
            }

            renderer.TranslateTransform(x, y, MatrixOrder.Prepend);
            renderer.TranslateTransform(fMinX, fMinY, MatrixOrder.Prepend);
            renderer.ScaleTransform(fScaleX, fScaleY, MatrixOrder.Prepend);
        }
예제 #26
0
 /// <summary>
 /// Renders the <see cref="SvgElement"/> and contents to the specified <see cref="ISvgRenderer"/> object.
 /// </summary>
 /// <param name="renderer">The <see cref="ISvgRenderer"/> object to render to.</param>
 protected override void Render(ISvgRenderer renderer)
 {
     // Do nothing. Children should NOT be rendered.
 }
예제 #27
0
 /// <summary>
 /// Gets the <see cref="System.Drawing.Drawing2D.GraphicsPath"/> for this element.
 /// </summary>
 /// <value></value>
 public override System.Drawing.Drawing2D.GraphicsPath Path(ISvgRenderer renderer)
 {
     return(GetPaths(this, renderer));
 }
예제 #28
0
 /// <summary>
 /// Resets the clipping region of the specified <see cref="ISvgRenderer"/> back to where it was before the <see cref="SetClip"/> method was called.
 /// </summary>
 /// <param name="renderer">The <see cref="ISvgRenderer"/> to have its clipping region reset.</param>
 void ISvgClipable.ResetClip(ISvgRenderer renderer)
 {
     this.ResetClip(renderer);
 }
예제 #29
0
        /// <summary>
        /// Renders the stroke of the <see cref="SvgVisualElement"/> to the specified <see cref="ISvgRenderer"/>
        /// </summary>
        /// <param name="renderer">The <see cref="ISvgRenderer"/> object to render to.</param>
        protected internal virtual bool RenderStroke(ISvgRenderer renderer)
        {
            if (this.Stroke != null && this.Stroke != SvgColourServer.None && this.StrokeWidth > 0)
            {
                float strokeWidth = this.StrokeWidth.ToDeviceValue(renderer, UnitRenderingType.Other, this);
                using (var brush = this.Stroke.GetBrush(this, renderer, Math.Min(Math.Max(this.StrokeOpacity * this.Opacity, 0), 1), true))
                {
                    if (brush != null)
                    {
                        var path   = this.Path(renderer);
                        var bounds = path.GetBounds();
                        if (path.PointCount < 1)
                        {
                            return(false);
                        }
                        if (bounds.Width <= 0 && bounds.Height <= 0)
                        {
                            switch (this.StrokeLineCap)
                            {
                            case SvgStrokeLineCap.Round:
                                using (var capPath = new GraphicsPath())
                                {
                                    capPath.AddEllipse(path.PathPoints[0].X - strokeWidth / 2, path.PathPoints[0].Y - strokeWidth / 2, strokeWidth, strokeWidth);
                                    renderer.FillPath(brush, capPath);
                                }
                                break;

                            case SvgStrokeLineCap.Square:
                                using (var capPath = new GraphicsPath())
                                {
                                    capPath.AddRectangle(new RectangleF(path.PathPoints[0].X - strokeWidth / 2, path.PathPoints[0].Y - strokeWidth / 2, strokeWidth, strokeWidth));
                                    renderer.FillPath(brush, capPath);
                                }
                                break;
                            }
                        }
                        else
                        {
                            using (var pen = new Pen(brush, strokeWidth))
                            {
                                if (this.StrokeDashArray != null && this.StrokeDashArray.Count > 0)
                                {
                                    if (this.StrokeDashArray.Count % 2 != 0)
                                    {
                                        // handle odd dash arrays by repeating them once
                                        this.StrokeDashArray.AddRange(this.StrokeDashArray);
                                    }
                                    /* divide by stroke width - GDI behaviour that I don't quite understand yet.*/
                                    pen.DashPattern = this.StrokeDashArray.ConvertAll(u => ((u.ToDeviceValue(renderer, UnitRenderingType.Other, this) <= 0) ? 1 : u.ToDeviceValue(renderer, UnitRenderingType.Other, this)) /
                                                                                      ((strokeWidth <= 0) ? 1 : strokeWidth)).ToArray();

                                    if (this.StrokeDashOffset != null && this.StrokeDashOffset.Value != 0)
                                    {
                                        pen.DashOffset = ((this.StrokeDashOffset.ToDeviceValue(renderer, UnitRenderingType.Other, this) <= 0) ? 1 : this.StrokeDashOffset.ToDeviceValue(renderer, UnitRenderingType.Other, this)) /
                                                         ((strokeWidth <= 0) ? 1 : strokeWidth);
                                    }
                                }
                                switch (this.StrokeLineJoin)
                                {
                                case SvgStrokeLineJoin.Bevel:
                                    pen.LineJoin = LineJoin.Bevel;
                                    break;

                                case SvgStrokeLineJoin.Round:
                                    pen.LineJoin = LineJoin.Round;
                                    break;

                                default:
                                    pen.LineJoin = LineJoin.Miter;
                                    break;
                                }
                                pen.MiterLimit = this.StrokeMiterLimit;
                                switch (this.StrokeLineCap)
                                {
                                case SvgStrokeLineCap.Round:
                                    pen.StartCap = LineCap.Round;
                                    pen.EndCap   = LineCap.Round;
                                    break;

                                case SvgStrokeLineCap.Square:
                                    pen.StartCap = LineCap.Square;
                                    pen.EndCap   = LineCap.Square;
                                    break;
                                }

                                renderer.DrawPath(pen, path);

                                return(true);
                            }
                        }
                    }
                }
            }

            return(false);
        }
예제 #30
0
 /// <summary>
 /// Gets the <see cref="GraphicsPath"/> for this element.
 /// </summary>
 public abstract GraphicsPath Path(ISvgRenderer renderer);
예제 #31
0
 /// <summary>
 /// Renders the <see cref="SvgElement"/> and contents to the specified <see cref="Graphics"/> object.
 /// </summary>
 /// <param name="renderer">The <see cref="ISvgRenderer"/> object to render to.</param>
 protected override void Render(ISvgRenderer renderer)
 {
     this.Render(renderer, true);
 }
예제 #32
0
 public override void AfterRender(ISvgRenderer renderer)
 {
 }
예제 #33
0
파일: SvgPolyline.cs 프로젝트: hh10k/SVG
        /// <summary>
        /// Renders the stroke of the <see cref="SvgVisualElement"/> to the specified <see cref="ISvgRenderer"/>
        /// </summary>
        /// <param name="renderer">The <see cref="ISvgRenderer"/> object to render to.</param>
        protected internal override bool RenderStroke(ISvgRenderer renderer)
        {
            var result = base.RenderStroke(renderer);
            var path = this.Path(renderer);

            if (this.MarkerStart != null)
            {
                SvgMarker marker = this.OwnerDocument.GetElementById<SvgMarker>(this.MarkerStart.ToString());
                marker.RenderMarker(renderer, this, path.PathPoints[0], path.PathPoints[0], path.PathPoints[1]);
            }

            if (this.MarkerMid != null)
            {
                SvgMarker marker = this.OwnerDocument.GetElementById<SvgMarker>(this.MarkerMid.ToString());
                for (int i = 1; i <= path.PathPoints.Length - 2; i++)
                    marker.RenderMarker(renderer, this, path.PathPoints[i], path.PathPoints[i - 1], path.PathPoints[i], path.PathPoints[i + 1]);
            }

            if (this.MarkerEnd != null)
            {
                SvgMarker marker = this.OwnerDocument.GetElementById<SvgMarker>(this.MarkerEnd.ToString());
                marker.RenderMarker(renderer, this, path.PathPoints[path.PathPoints.Length - 1], path.PathPoints[path.PathPoints.Length - 2], path.PathPoints[path.PathPoints.Length - 1]);
            }

            return result;
        }
예제 #34
0
        /// <summary>
        /// Gets a <see cref="Brush"/> representing the current paint server.
        /// </summary>
        /// <param name="renderingElement">The owner <see cref="SvgVisualElement"/>.</param>
        /// <param name="renderer">The renderer object.</param>
        /// <param name="opacity">The opacity of the brush.</param>
        /// <param name="forStroke">Not used.</param>
        public override Brush GetBrush(SvgVisualElement renderingElement, ISvgRenderer renderer, float opacity, bool forStroke = false)
        {
            var chain = new List <SvgPatternServer>();

            var curr = this;

            do
            {
                chain.Add(curr);
                curr = SvgDeferredPaintServer.TryGet <SvgPatternServer>(curr.InheritGradient, renderingElement);
            } while (curr != null);

            var firstChildren = chain.Where(p => p.Children.Count > 0).FirstOrDefault();

            if (firstChildren == null)
            {
                return(null);
            }
            var firstX      = chain.Where(p => p.X != null && p.X != SvgUnit.None).FirstOrDefault();
            var firstY      = chain.Where(p => p.Y != null && p.Y != SvgUnit.None).FirstOrDefault();
            var firstWidth  = chain.Where(p => p.Width != null && p.Width != SvgUnit.None).FirstOrDefault();
            var firstHeight = chain.Where(p => p.Height != null && p.Height != SvgUnit.None).FirstOrDefault();

            if (firstWidth == null || firstHeight == null)
            {
                return(null);
            }
            var firstPatternUnit        = chain.Where(p => p._patternUnits.HasValue).FirstOrDefault();
            var firstPatternContentUnit = chain.Where(p => p._patternContentUnits.HasValue).FirstOrDefault();
            var firstViewBox            = chain.Where(p => p.ViewBox != null && p.ViewBox != SvgViewBox.Empty).FirstOrDefault();

            var xUnit      = firstX == null ? new SvgUnit(0f) : firstX.X;
            var yUnit      = firstY == null ? new SvgUnit(0f) : firstY.Y;
            var widthUnit  = firstWidth.Width;
            var heightUnit = firstHeight.Height;

            var patternUnits        = firstPatternUnit == null ? SvgCoordinateUnits.ObjectBoundingBox : firstPatternUnit.PatternUnits;
            var patternContentUnits = firstPatternContentUnit == null ? SvgCoordinateUnits.UserSpaceOnUse : firstPatternContentUnit.PatternContentUnits;
            var viewBox             = firstViewBox == null ? SvgViewBox.Empty : firstViewBox.ViewBox;

            var isPatternObjectBoundingBox = patternUnits == SvgCoordinateUnits.ObjectBoundingBox;

            try
            {
                if (isPatternObjectBoundingBox)
                {
                    renderer.SetBoundable(renderingElement);
                }

                var x      = xUnit.ToDeviceValue(renderer, UnitRenderingType.Horizontal, this);
                var y      = yUnit.ToDeviceValue(renderer, UnitRenderingType.Vertical, this);
                var width  = widthUnit.ToDeviceValue(renderer, UnitRenderingType.Horizontal, this);
                var height = heightUnit.ToDeviceValue(renderer, UnitRenderingType.Vertical, this);

                if (isPatternObjectBoundingBox)
                {
                    var bounds = renderer.GetBoundable().Bounds;    // Boundary without stroke is expect...

                    if (xUnit.Type != SvgUnitType.Percentage)
                    {
                        x *= bounds.Width;
                    }
                    if (yUnit.Type != SvgUnitType.Percentage)
                    {
                        y *= bounds.Height;
                    }
                    if (widthUnit.Type != SvgUnitType.Percentage)
                    {
                        width *= bounds.Width;
                    }
                    if (heightUnit.Type != SvgUnitType.Percentage)
                    {
                        height *= bounds.Height;
                    }
                    x += bounds.X;
                    y += bounds.Y;
                }

                var tile = new Bitmap((int)Math.Ceiling(width), (int)Math.Ceiling(height));
                using (var tileRenderer = SvgRenderer.FromImage(tile))
                {
                    tileRenderer.SetBoundable(renderingElement);
                    if (viewBox != SvgViewBox.Empty)
                    {
                        var bounds = tileRenderer.GetBoundable().Bounds;
                        tileRenderer.ScaleTransform(width / viewBox.Width, height / viewBox.Height);
                    }
                    else if (patternContentUnits == SvgCoordinateUnits.ObjectBoundingBox)
                    {
                        var bounds = tileRenderer.GetBoundable().Bounds;
                        tileRenderer.ScaleTransform(bounds.Width, bounds.Height);
                    }

                    foreach (var child in firstChildren.Children)
                    {
                        child.RenderElement(tileRenderer);
                    }
                }

                using (var transform = EffectivePatternTransform)
                {
                    var textureBrush = new TextureBrush(tile, new RectangleF(0f, 0f, width, height))
                    {
                        Transform = transform
                    };
                    textureBrush.TranslateTransform(x, y);
                    return(textureBrush);
                }
            }
            finally
            {
                if (isPatternObjectBoundingBox)
                {
                    renderer.PopBoundable();
                }
            }
        }
예제 #35
0
 /// <summary>
 /// Gets a <see cref="Color"/> representing the current paint server.
 /// </summary>
 /// <param name="renderingElement">The owner <see cref="SvgVisualElement"/>.</param>
 /// <param name="renderer">The renderer object.</param>
 /// <param name="opacity">The opacity of the brush.</param>
 /// <param name="forStroke">Not used.</param>
 public override Color GetColor(SvgVisualElement renderingElement, ISvgRenderer renderer, float opacity, bool forStroke = false)
 {
     return(System.Drawing.Color.Black);
 }
예제 #36
0
 protected virtual GraphicsPath GetBaselinePath(ISvgRenderer renderer)
 {
     return(null);
 }
예제 #37
0
 /// <summary>
 /// Removes any previously applied transforms from the specified <see cref="ISvgRenderer"/>.
 /// </summary>
 /// <param name="renderer">The <see cref="ISvgRenderer"/> that should have transforms removed.</param>
 void ISvgTransformable.PopTransforms(ISvgRenderer renderer)
 {
     this.PopTransforms(renderer);
 }
예제 #38
0
        /// <summary>
        /// Get the font information based on data stored with the text object or inherited from the parent.
        /// </summary>
        /// <returns></returns>
        internal IFontDefn GetFont(ISvgRenderer renderer)
        {
            // Get the font-size
            float fontSize;
            var   fontSizeUnit = this.FontSize;

            if (fontSizeUnit == SvgUnit.None || fontSizeUnit == SvgUnit.Empty)
            {
                fontSize = 1.0f;
            }
            else
            {
                fontSize = fontSizeUnit.ToDeviceValue(renderer, UnitRenderingType.Vertical, this);
            }

            var family = ValidateFontFamily(this.FontFamily, this.OwnerDocument);
            var sFaces = family as IEnumerable <SvgFontFace>;

            if (sFaces == null)
            {
                var fontStyle = System.Drawing.FontStyle.Regular;

                // Get the font-weight
                switch (this.FontWeight)
                {
                //Note: Bold is not listed because it is = W700.
                case SvgFontWeight.Bolder:
                case SvgFontWeight.W600:
                case SvgFontWeight.W700:
                case SvgFontWeight.W800:
                case SvgFontWeight.W900:
                    fontStyle |= System.Drawing.FontStyle.Bold;
                    break;
                }

                // Get the font-style
                switch (this.FontStyle)
                {
                case SvgFontStyle.Italic:
                case SvgFontStyle.Oblique:
                    fontStyle |= System.Drawing.FontStyle.Italic;
                    break;
                }

                // Get the text-decoration
                switch (this.TextDecoration)
                {
                case SvgTextDecoration.LineThrough:
                    fontStyle |= System.Drawing.FontStyle.Strikeout;
                    break;

                case SvgTextDecoration.Underline:
                    fontStyle |= System.Drawing.FontStyle.Underline;
                    break;
                }

                var ff = family as FontFamily;
                if (!ff.IsStyleAvailable(fontStyle))
                {
                    // Do Something
                }

                // Get the font-family
                return(new GdiFontDefn(new System.Drawing.Font(ff, fontSize, fontStyle, System.Drawing.GraphicsUnit.Pixel)));
            }
            else
            {
                var font = sFaces.First().Parent as SvgFont;
                if (font == null)
                {
                    var uri = sFaces.First().Descendants().OfType <SvgFontFaceUri>().First().ReferencedElement;
                    font = OwnerDocument.IdManager.GetElementById(uri) as SvgFont;
                }
                return(new SvgFontDefn(font, fontSize, OwnerDocument.Ppi));
            }
        }
예제 #39
0
 /// <summary>
 /// Renders the <see cref="SvgElement"/> and contents to the specified <see cref="ISvgRenderer"/> object.
 /// </summary>
 /// <param name="renderer">The <see cref="ISvgRenderer"/> object to render to.</param>
 protected virtual void Render(ISvgRenderer renderer)
 {
     this.PushTransforms(renderer);
     this.RenderChildren(renderer);
     this.PopTransforms(renderer);
 }
예제 #40
0
        public WpfSvgWindow(long innerWidth, long innerHeight, ISvgRenderer renderer)
            : base(innerWidth, innerHeight, renderer)
        {
//            _preferUserSize = true;
        }
예제 #41
0
        /// <summary>
        /// Renders the <see cref="SvgElement"/> and contents to the specified <see cref="Graphics"/> object.
        /// </summary>
        protected override void Render(ISvgRenderer renderer)
        {
            if (!Visible || !Displayable)
            {
                return;
            }

            if (Width.Value > 0.0f && Height.Value > 0.0f && this.Href != null)
            {
                var img = GetImage();
                if (img != null)
                {
                    RectangleF srcRect;
                    var        bmp = img as Image;
                    var        svg = img as SvgFragment;
                    if (bmp != null)
                    {
                        srcRect = new RectangleF(0, 0, bmp.Width, bmp.Height);
                    }
                    else if (svg != null)
                    {
                        srcRect = new RectangleF(new PointF(0, 0), svg.GetDimensions());
                    }
                    else
                    {
                        return;
                    }

                    var destClip = new RectangleF(this.Location.ToDeviceValue(renderer, this),
                                                  new SizeF(Width.ToDeviceValue(renderer, UnitRenderingType.Horizontal, this),
                                                            Height.ToDeviceValue(renderer, UnitRenderingType.Vertical, this)));
                    RectangleF destRect = destClip;

                    this.PushTransforms(renderer);
                    renderer.SetClip(new Region(destClip), CombineMode.Intersect);
                    this.SetClip(renderer);

                    SvgAspectRatio aspectRatio = AspectRatio ?? new SvgAspectRatio(SvgPreserveAspectRatio.xMidYMid);
                    if (aspectRatio.Align != SvgPreserveAspectRatio.none)
                    {
                        var fScaleX = destClip.Width / srcRect.Width;
                        var fScaleY = destClip.Height / srcRect.Height;
                        var xOffset = 0.0f;
                        var yOffset = 0.0f;

                        if (aspectRatio.Slice)
                        {
                            fScaleX = Math.Max(fScaleX, fScaleY);
                            fScaleY = Math.Max(fScaleX, fScaleY);
                        }
                        else
                        {
                            fScaleX = Math.Min(fScaleX, fScaleY);
                            fScaleY = Math.Min(fScaleX, fScaleY);
                        }

                        switch (aspectRatio.Align)
                        {
                        case SvgPreserveAspectRatio.xMinYMin:
                            break;

                        case SvgPreserveAspectRatio.xMidYMin:
                            xOffset = (destClip.Width - srcRect.Width * fScaleX) / 2;
                            break;

                        case SvgPreserveAspectRatio.xMaxYMin:
                            xOffset = (destClip.Width - srcRect.Width * fScaleX);
                            break;

                        case SvgPreserveAspectRatio.xMinYMid:
                            yOffset = (destClip.Height - srcRect.Height * fScaleY) / 2;
                            break;

                        case SvgPreserveAspectRatio.xMidYMid:
                            xOffset = (destClip.Width - srcRect.Width * fScaleX) / 2;
                            yOffset = (destClip.Height - srcRect.Height * fScaleY) / 2;
                            break;

                        case SvgPreserveAspectRatio.xMaxYMid:
                            xOffset = (destClip.Width - srcRect.Width * fScaleX);
                            yOffset = (destClip.Height - srcRect.Height * fScaleY) / 2;
                            break;

                        case SvgPreserveAspectRatio.xMinYMax:
                            yOffset = (destClip.Height - srcRect.Height * fScaleY);
                            break;

                        case SvgPreserveAspectRatio.xMidYMax:
                            xOffset = (destClip.Width - srcRect.Width * fScaleX) / 2;
                            yOffset = (destClip.Height - srcRect.Height * fScaleY);
                            break;

                        case SvgPreserveAspectRatio.xMaxYMax:
                            xOffset = (destClip.Width - srcRect.Width * fScaleX);
                            yOffset = (destClip.Height - srcRect.Height * fScaleY);
                            break;
                        }

                        destRect = new RectangleF(destClip.X + xOffset, destClip.Y + yOffset,
                                                  srcRect.Width * fScaleX, srcRect.Height * fScaleY);
                    }

                    if (bmp != null)
                    {
                        if (Opacity == 1F)
                        {
                            renderer.DrawImage(bmp, destRect, srcRect, GraphicsUnit.Pixel);
                        }
                        else
                        {
                            renderer.DrawImage(bmp, destRect, srcRect, GraphicsUnit.Pixel, Opacity);
                        }
                        bmp.Dispose();
                    }
                    else if (svg != null)
                    {
                        var currOffset = new PointF(renderer.Transform.OffsetX, renderer.Transform.OffsetY);
                        renderer.TranslateTransform(-currOffset.X, -currOffset.Y);
                        renderer.ScaleTransform(destRect.Width / srcRect.Width, destRect.Height / srcRect.Height);
                        renderer.TranslateTransform(currOffset.X + destRect.X, currOffset.Y + destRect.Y);
                        renderer.SetBoundable(new GenericBoundable(srcRect));
                        svg.RenderElement(renderer);
                        renderer.PopBoundable();
                    }


                    this.ResetClip(renderer);
                    this.PopTransforms(renderer);
                }
                // TODO: cache images... will need a shared context for this
            }
        }
예제 #42
0
        /// <summary>
        /// Common code for rendering a marker once the orientation angle has been calculated
        /// </summary>
        /// <param name="fAngle"></param>
        /// <param name="pRenderer"></param>
        /// <param name="pOwner"></param>
        /// <param name="pMarkerPoint"></param>
        private void RenderPart2(float fAngle, ISvgRenderer pRenderer, SvgVisualElement pOwner, PointF pMarkerPoint)
        {
            using (var pRenderPen = CreatePen(pOwner, pRenderer))
            {
                using (var markerPath = GetClone(pOwner, pRenderer))
                {
                    using (var transMatrix = new Matrix())
                    {
                        transMatrix.Translate(pMarkerPoint.X, pMarkerPoint.Y);
                        if (Orient.IsAuto)
                        {
                            transMatrix.Rotate(fAngle);
                        }
                        else
                        {
                            transMatrix.Rotate(Orient.Angle);
                        }
                        switch (MarkerUnits)
                        {
                        case SvgMarkerUnits.StrokeWidth:
                            if (ViewBox.Width > 0 && ViewBox.Height > 0)
                            {
                                transMatrix.Scale(MarkerWidth, MarkerHeight);
                                var strokeWidth = pOwner.StrokeWidth.ToDeviceValue(pRenderer, UnitRenderingType.Other, this);
                                transMatrix.Translate(AdjustForViewBoxWidth(-RefX.ToDeviceValue(pRenderer, UnitRenderingType.Horizontal, this) *
                                                                            strokeWidth),
                                                      AdjustForViewBoxHeight(-RefY.ToDeviceValue(pRenderer, UnitRenderingType.Vertical, this) *
                                                                             strokeWidth));
                            }
                            else
                            {
                                // SvgMarkerUnits.UserSpaceOnUse
                                // TODO: We know this isn't correct.
                                //        But use this until the TODOs from AdjustForViewBoxWidth and AdjustForViewBoxHeight are done.
                                //  MORE see Unit Test "MakerEndTest.TestArrowCodeCreation()"
                                transMatrix.Translate(-RefX.ToDeviceValue(pRenderer, UnitRenderingType.Horizontal, this),
                                                      -RefY.ToDeviceValue(pRenderer, UnitRenderingType.Vertical, this));
                            }
                            break;

                        case SvgMarkerUnits.UserSpaceOnUse:
                            transMatrix.Translate(-RefX.ToDeviceValue(pRenderer, UnitRenderingType.Horizontal, this),
                                                  -RefY.ToDeviceValue(pRenderer, UnitRenderingType.Vertical, this));
                            break;
                        }

                        if (MarkerElement != null && MarkerElement.Transforms != null)
                        {
                            using (var matrix = MarkerElement.Transforms.GetMatrix())
                                transMatrix.Multiply(matrix);
                        }
                        markerPath.Transform(transMatrix);
                        if (pRenderPen != null)
                        {
                            pRenderer.DrawPath(pRenderPen, markerPath);
                        }

                        SvgPaintServer pFill     = this.Children.First().Fill;
                        SvgFillRule    pFillRule = FillRule; // TODO: What do we use the fill rule for?

                        if (pFill != null)
                        {
                            using (var pBrush = pFill.GetBrush(this, pRenderer, FixOpacityValue(FillOpacity)))
                            {
                                pRenderer.FillPath(pBrush, markerPath);
                            }
                        }
                    }
                }
            }
        }
예제 #43
0
 public static System.Drawing.PointF GetDevicePointOffset(SvgUnit x, SvgUnit y, ISvgRenderer renderer, SvgElement owner)
 {
     return(new System.Drawing.PointF(x.ToDeviceValue(renderer, UnitRenderingType.HorizontalOffset, owner),
                                      y.ToDeviceValue(renderer, UnitRenderingType.VerticalOffset, owner)));
 }
예제 #44
0
파일: SvgTextBase.cs 프로젝트: zdrlik/SVG
        /// <summary>
        /// Renders the <see cref="SvgElement"/> and contents to the specified <see cref="Graphics"/> object.
        /// </summary>
        /// <param name="renderer">The <see cref="ISvgRenderer"/> object to render to.</param>
        /// <remarks>Necessary to make sure that any internal tspan elements get rendered as well</remarks>
        protected override void Render(ISvgRenderer renderer)
        {
            if ((this.Path(renderer) != null) && this.Visible && this.Displayable)
            {
                this.PushTransforms(renderer);
                this.SetClip(renderer);

                // If this element needs smoothing enabled turn anti-aliasing on
                if (this.RequiresSmoothRendering)
                {
                    renderer.SmoothingMode = SmoothingMode.AntiAlias;
                }

                this.RenderFill(renderer);
                this.RenderStroke(renderer);
                this.RenderChildren(renderer);

                // Reset the smoothing mode
                if (this.RequiresSmoothRendering && renderer.SmoothingMode == SmoothingMode.AntiAlias)
                {
                    renderer.SmoothingMode = SmoothingMode.Default;
                }

                this.ResetClip(renderer);
                this.PopTransforms(renderer);
            }
        }
예제 #45
0
파일: SvgUnit.cs 프로젝트: vvvv/SVG
        /// <summary>
        /// Converts the current unit to one that can be used at render time.
        /// </summary>
        /// <param name="boundable">The container element used as the basis for calculations</param>
        /// <returns>The representation of the current unit in a device value (usually pixels).</returns>
        public float ToDeviceValue(ISvgRenderer renderer, UnitRenderingType renderType, SvgElement owner)
        {
            // If it's already been calculated
            if (this._deviceValue.HasValue)
            {
                return this._deviceValue.Value;
            }

            if (this._value == 0.0f)
            {
                this._deviceValue = 0.0f;
                return this._deviceValue.Value;
            }

            // http://www.w3.org/TR/CSS21/syndata.html#values
            // http://www.w3.org/TR/SVG11/coords.html#Units

            const float cmInInch = 2.54f;
            int ppi = SvgDocument.PointsPerInch;

            var type = this.Type;
            var value = this.Value;

            float points;

            switch (type)
            {
                case SvgUnitType.Em:
                    using (var currFont = GetFont(renderer, owner))
                    {
                        if (currFont == null)
                        {
                            points = (float)(value * 9);
                            _deviceValue = (points / 72.0f) * ppi;
                        }
                        else
                        {
                            _deviceValue = value * (currFont.SizeInPoints / 72.0f) * ppi;
                        }
                    }
                    break;
                case SvgUnitType.Ex:
                    using (var currFont = GetFont(renderer, owner))
                    {
                        if (currFont == null)
                        {
                            points = (float)(value * 9);
                            _deviceValue = (points * 0.5f / 72.0f) * ppi;
                        }
                        else
                        {
                            _deviceValue = value * 0.5f * (currFont.SizeInPoints / 72.0f) * ppi;
                        }
                        break;
                    }
                case SvgUnitType.Centimeter:
                    _deviceValue = (float)((value / cmInInch) * ppi);
                    break;
                case SvgUnitType.Inch:
                    _deviceValue = value * ppi;
                    break;
                case SvgUnitType.Millimeter:
                    _deviceValue = (float)((value / 10) / cmInInch) * ppi;
                    break;
                case SvgUnitType.Pica:
                    _deviceValue = ((value * 12) / 72) * ppi;
                    break;
                case SvgUnitType.Point:
                    _deviceValue = (value / 72) * ppi;
                    break;
                case SvgUnitType.Pixel:
                    _deviceValue = value;
                    break;
                case SvgUnitType.User:
                    _deviceValue = value;
                    break;
                case SvgUnitType.Percentage:
                    // Can't calculate if there is no style owner
                    var boundable = (renderer == null ? (owner == null ? null : owner.OwnerDocument) : renderer.GetBoundable());
                    if (boundable == null)
                    {
                        _deviceValue = value;
                        break;
                    }

                    System.Drawing.SizeF size = boundable.Bounds.Size;

                    switch (renderType)
                    {
                        case UnitRenderingType.Horizontal:
                            _deviceValue = (size.Width / 100) * value;
                            break;
                        case UnitRenderingType.HorizontalOffset:
                            _deviceValue = (size.Width / 100) * value + boundable.Location.X;
                            break;
                        case UnitRenderingType.Vertical:
                            _deviceValue = (size.Height / 100) * value;
                            break;
                        case UnitRenderingType.VerticalOffset:
                            _deviceValue = (size.Height / 100) * value + boundable.Location.Y;
                            break;
                        default:
                            _deviceValue = (float)(Math.Sqrt(Math.Pow(size.Width, 2) + Math.Pow(size.Height, 2)) / Math.Sqrt(2) * value / 100.0);
                            break;
                    }
                    break;
                default:
                    _deviceValue = value;
                    break;
            }
            return this._deviceValue.Value;
        }
예제 #46
0
 protected virtual GraphicsPath GetBaselinePath(ISvgRenderer renderer)
 {
     return null;
 }
예제 #47
0
 public override void Render(ISvgRenderer renderer)
 {
 }
예제 #48
0
 public TextDrawingState(ISvgRenderer renderer, SvgTextBase element)
 {
     this.Element = element;
     this.Renderer = renderer;
     this.Current = PointF.Empty;
     _xAnchor = 0;
     this.BaselinePath = element.GetBaselinePath(renderer);
     _authorPathLength = element.GetAuthorPathLength();
 }
예제 #49
0
 // disable default rendering
 public override void BeforeRender(ISvgRenderer renderer)
 {
 }
예제 #50
0
 public WpfSvgWindow(long innerWidth, long innerHeight, ISvgRenderer renderer)
     : base(innerWidth, innerHeight, renderer)
 {
 }
예제 #51
0
파일: SvgUse.cs 프로젝트: nt0tsky/SVG
        public override System.Drawing.Drawing2D.GraphicsPath Path(ISvgRenderer renderer)
        {
            SvgVisualElement element = (SvgVisualElement)this.OwnerDocument.IdManager.GetElementById(this.ReferencedElement);

            return((element != null && !this.HasRecursiveReference()) ? element.Path(renderer) : null);
        }
예제 #52
0
 /// <summary>
 /// Gets a <see cref="Brush"/> representing the current paint server.
 /// </summary>
 /// <param name="styleOwner">The owner <see cref="SvgVisualElement"/>.</param>
 /// <param name="renderer">The renderer object.</param>
 /// <param name="opacity">The opacity of the brush.</param>
 /// <param name="forStroke">Not used.</param>
 public abstract Brush GetBrush(SvgVisualElement styleOwner, ISvgRenderer renderer, float opacity, bool forStroke = false);
예제 #53
0
        /// <summary>
        /// Renders the <see cref="SvgElement"/> and contents to the specified <see cref="Graphics"/> object.
        /// </summary>
        /// <param name="renderer">The <see cref="ISvgRenderer"/> object to render to.</param>
        /// <remarks>Necessary to make sure that any internal tspan elements get rendered as well</remarks>
        protected override void Render(ISvgRenderer renderer)
        {
            if ((this.Path(renderer) != null) && this.Visible && this.Displayable)
            {
                this.PushTransforms(renderer);
                this.SetClip(renderer);

                // If this element needs smoothing enabled turn anti-aliasing on
                if (this.RequiresSmoothRendering)
                {
                    renderer.SmoothingMode = SmoothingMode.AntiAlias;
                }

                // If text color blends with background color, text will be rendered blurry
                // To avoid it, we set SourceCopy which overwrite background color
                var compositingMode = renderer.CompositingMode;
                renderer.CompositingMode = CompositingMode.SourceCopy;

                this.RenderFill(renderer);
                this.RenderStroke(renderer);
                this.RenderChildren(renderer);

                // Reset the smoothing mode
                if (this.RequiresSmoothRendering && renderer.SmoothingMode == SmoothingMode.AntiAlias)
                {
                    renderer.SmoothingMode = SmoothingMode.Default;
                }

                renderer.CompositingMode = compositingMode;

                this.ResetClip(renderer);
                this.PopTransforms(renderer);
            }
        }
예제 #54
0
파일: GdiFontDefn.cs 프로젝트: xprl-gjf/SVG
 public void AddStringToPath(ISvgRenderer renderer, GraphicsPath path, string text, PointF location)
 {
     path.AddString(text, _font.FontFamily, (int)_font.Style, _font.Size, location, StringFormat.GenericTypographic);
 }
예제 #55
0
        /// <summary>
        /// Gets the <see cref="GraphicsPath"/> for this element.
        /// </summary>
        /// <value></value>
        public override GraphicsPath Path(ISvgRenderer renderer)
        {
            //if there is a TSpan inside of this text element then path should not be null (even if this text is empty!)
            var nodes = GetContentNodes().Where(x => x is SvgContentNode &&
                                                     string.IsNullOrEmpty(x.Content.Trim(new[] { '\r', '\n', '\t' })));

            if (_path == null || IsPathDirty || nodes.Count() == 1)
            {
                renderer = (renderer ?? SvgRenderer.FromNull());
                SetPath(new TextDrawingState(renderer, this));
            }
            return _path;
        }
예제 #56
0
        protected override Brush CreateBrush(SvgVisualElement renderingElement, ISvgRenderer renderer, float opacity, bool forStroke)
        {
            try
            {
                if (this.GradientUnits == SvgCoordinateUnits.ObjectBoundingBox)
                {
                    renderer.SetBoundable(renderingElement);
                }

                var points = new PointF[] {
                    SvgUnit.GetDevicePoint(NormalizeUnit(this.X1), NormalizeUnit(this.Y1), renderer, this),
                    SvgUnit.GetDevicePoint(NormalizeUnit(this.X2), NormalizeUnit(this.Y2), renderer, this)
                };

                var bounds = renderer.GetBoundable().Bounds;
                if (bounds.Width <= 0 || bounds.Height <= 0 || ((points[0].X == points[1].X) && (points[0].Y == points[1].Y)))
                {
                    if (this.GetCallback != null)
                    {
                        return(GetCallback().GetBrush(renderingElement, renderer, opacity, forStroke));
                    }
                    return(null);
                }

                using (var transform = EffectiveGradientTransform)
                {
                    transform.Translate(bounds.X, bounds.Y, MatrixOrder.Prepend);
                    if (this.GradientUnits == SvgCoordinateUnits.ObjectBoundingBox)
                    {
                        // Transform a normal (i.e. perpendicular line) according to the transform
                        transform.Scale(bounds.Width, bounds.Height, MatrixOrder.Prepend);
                    }
                    transform.TransformPoints(points);
                }

                points[0].X = (float)Math.Round(points[0].X, 4);
                points[0].Y = (float)Math.Round(points[0].Y, 4);
                points[1].X = (float)Math.Round(points[1].X, 4);
                points[1].Y = (float)Math.Round(points[1].Y, 4);

                if (this.GradientUnits == SvgCoordinateUnits.ObjectBoundingBox)
                {
                    // Transform the normal line back to a line such that the gradient still starts in the correct corners, but
                    // has the proper normal vector based on the transforms.  If you work out the geometry, these formulas should work.
                    var midPoint = new PointF((points[0].X + points[1].X) / 2, (points[0].Y + points[1].Y) / 2);
                    var dy       = points[1].Y - points[0].Y;
                    var dx       = points[1].X - points[0].X;
                    var x1       = points[0].X;
                    var y2       = points[1].Y;

                    if (dx != 0f && dy != 0f)
                    {
                        var startX = (float)((dy * dx * (midPoint.Y - y2) + Math.Pow(dx, 2) * midPoint.X + Math.Pow(dy, 2) * x1) /
                                             (Math.Pow(dx, 2) + Math.Pow(dy, 2)));
                        var endY = dy * (startX - x1) / dx + y2;
                        points[0] = new PointF(startX, midPoint.Y + (midPoint.Y - endY));
                        points[1] = new PointF(midPoint.X + (midPoint.X - startX), endY);
                    }
                }

                var effectiveStart = points[0];
                var effectiveEnd   = points[1];

                if (PointsToMove(renderingElement, points[0], points[1]) > LinePoints.None)
                {
                    var expansion = ExpandGradient(renderingElement, points[0], points[1]);
                    effectiveStart = expansion.StartPoint;
                    effectiveEnd   = expansion.EndPoint;
                }

                var result = new LinearGradientBrush(effectiveStart, effectiveEnd, System.Drawing.Color.Transparent, System.Drawing.Color.Transparent)
                {
                    InterpolationColors = CalculateColorBlend(renderer, opacity, points[0], effectiveStart, points[1], effectiveEnd),
                    WrapMode            = WrapMode.TileFlipX
                };
                return(result);
            }
            finally
            {
                if (this.GradientUnits == SvgCoordinateUnits.ObjectBoundingBox)
                {
                    renderer.PopBoundable();
                }
            }
        }
예제 #57
0
        /// <summary>
        /// Get the font information based on data stored with the text object or inherited from the parent.
        /// </summary>
        /// <returns></returns>
        internal IFontDefn GetFont(ISvgRenderer renderer)
        {
            // Get the font-size
            float fontSize;
            var fontSizeUnit = this.FontSize;
            if (fontSizeUnit == SvgUnit.None || fontSizeUnit == SvgUnit.Empty)
            {
                fontSize = 1.0f;
            }
            else
            {
                fontSize = fontSizeUnit.ToDeviceValue(renderer, UnitRenderingType.Vertical, this);
            }

            var family = ValidateFontFamily(this.FontFamily, this.OwnerDocument);
            var sFaces = family as IEnumerable<SvgFontFace>;

            if (sFaces == null)
            {
                var fontStyle = System.Drawing.FontStyle.Regular;

                // Get the font-weight
                switch (this.FontWeight)
                {
                    case SvgFontWeight.bold:
                    case SvgFontWeight.bolder:
                    case SvgFontWeight.w600:
                    case SvgFontWeight.w700:
                    case SvgFontWeight.w800:
                    case SvgFontWeight.w900:
                        fontStyle |= System.Drawing.FontStyle.Bold;
                        break;
                }

                // Get the font-style
                switch (this.FontStyle)
                {
                    case SvgFontStyle.italic:
                    case SvgFontStyle.oblique:
                        fontStyle |= System.Drawing.FontStyle.Italic;
                        break;
                }

                // Get the text-decoration
                switch (this.TextDecoration)
                {
                    case SvgTextDecoration.lineThrough:
                        fontStyle |= System.Drawing.FontStyle.Strikeout;
                        break;
                    case SvgTextDecoration.underline:
                        fontStyle |= System.Drawing.FontStyle.Underline;
                        break;
                }

                var ff = family as FontFamily;
                if (!ff.IsStyleAvailable(fontStyle))
                {
                    // Do Something
                }

                // Get the font-family
                return new GdiFontDefn(new System.Drawing.Font(ff, fontSize, fontStyle, System.Drawing.GraphicsUnit.Pixel));
            }
            else
            {
                var font = sFaces.First().Parent as SvgFont;
                if (font == null)
                {
                    var uri = sFaces.First().Descendants().OfType<SvgFontFaceUri>().First().ReferencedElement;
                    font = OwnerDocument.IdManager.GetElementById(uri) as SvgFont;
                }
                return new SvgFontDefn(font, fontSize, OwnerDocument.Ppi);
            }
        }
예제 #58
0
        private ColorBlend CalculateColorBlend(ISvgRenderer renderer, float opacity, PointF specifiedStart, PointF effectiveStart, PointF specifiedEnd, PointF effectiveEnd)
        {
            float        startExtend;
            float        endExtend;
            List <Color> colors;
            List <float> positions;

            var colorBlend = GetColorBlend(renderer, opacity, false);

            var startDelta = CalculateDistance(specifiedStart, effectiveStart);
            var endDelta   = CalculateDistance(specifiedEnd, effectiveEnd);

            if (!(startDelta > 0) && !(endDelta > 0))
            {
                return(colorBlend);
            }

            var specifiedLength     = CalculateDistance(specifiedStart, specifiedEnd);
            var specifiedUnitVector = new PointF((specifiedEnd.X - specifiedStart.X) / (float)specifiedLength, (specifiedEnd.Y - specifiedStart.Y) / (float)specifiedLength);

            var effectiveLength = CalculateDistance(effectiveStart, effectiveEnd);

            switch (SpreadMethod)
            {
            case SvgGradientSpreadMethod.Reflect:
                startExtend = (float)(Math.Ceiling(CalculateDistance(effectiveStart, specifiedStart) / specifiedLength));
                endExtend   = (float)(Math.Ceiling(CalculateDistance(effectiveEnd, specifiedEnd) / specifiedLength));
                colors      = colorBlend.Colors.ToList();
                positions   = (from p in colorBlend.Positions select p + startExtend).ToList();

                for (var i = 0; i < startExtend; i++)
                {
                    if (i % 2 == 0)
                    {
                        for (var j = 1; j < colorBlend.Positions.Length; j++)
                        {
                            positions.Insert(0, (float)((startExtend - 1 - i) + 1 - colorBlend.Positions[j]));
                            colors.Insert(0, colorBlend.Colors[j]);
                        }
                    }
                    else
                    {
                        for (var j = 0; j < colorBlend.Positions.Length - 1; j++)
                        {
                            positions.Insert(j, (float)((startExtend - 1 - i) + colorBlend.Positions[j]));
                            colors.Insert(j, colorBlend.Colors[j]);
                        }
                    }
                }

                int insertPos;
                for (var i = 0; i < endExtend; i++)
                {
                    if (i % 2 == 0)
                    {
                        insertPos = positions.Count;
                        for (var j = 0; j < colorBlend.Positions.Length - 1; j++)
                        {
                            positions.Insert(insertPos, (float)((startExtend + 1 + i) + 1 - colorBlend.Positions[j]));
                            colors.Insert(insertPos, colorBlend.Colors[j]);
                        }
                    }
                    else
                    {
                        for (var j = 1; j < colorBlend.Positions.Length; j++)
                        {
                            positions.Add((float)((startExtend + 1 + i) + colorBlend.Positions[j]));
                            colors.Add(colorBlend.Colors[j]);
                        }
                    }
                }

                colorBlend.Colors    = colors.ToArray();
                colorBlend.Positions = (from p in positions select p / (startExtend + 1 + endExtend)).ToArray();
                break;

            case SvgGradientSpreadMethod.Repeat:
                startExtend = (float)(Math.Ceiling(CalculateDistance(effectiveStart, specifiedStart) / specifiedLength));
                endExtend   = (float)(Math.Ceiling(CalculateDistance(effectiveEnd, specifiedEnd) / specifiedLength));
                colors      = new List <Color>();
                positions   = new List <float>();

                for (int i = 0; i < startExtend + endExtend + 1; i++)
                {
                    for (int j = 0; j < colorBlend.Positions.Length; j++)
                    {
                        positions.Add((i + colorBlend.Positions[j] * 0.9999f) / (startExtend + endExtend + 1));
                        colors.Add(colorBlend.Colors[j]);
                    }
                }
                positions[positions.Count - 1] = 1.0f;

                colorBlend.Colors    = colors.ToArray();
                colorBlend.Positions = positions.ToArray();

                break;

            default:
                for (var i = 0; i < colorBlend.Positions.Length; i++)
                {
                    var originalPoint = MovePointAlongVector(specifiedStart, specifiedUnitVector, (float)specifiedLength * colorBlend.Positions[i]);

                    var distanceFromEffectiveStart = CalculateDistance(effectiveStart, originalPoint);

                    colorBlend.Positions[i] = (float)Math.Round(Math.Max(0F, Math.Min((distanceFromEffectiveStart / effectiveLength), 1.0F)), 5);
                }

                if (startDelta > 0)
                {
                    colorBlend.Positions = new[] { 0F }.Concat(colorBlend.Positions).ToArray();
                    colorBlend.Colors    = new[] { colorBlend.Colors.First() }.Concat(colorBlend.Colors).ToArray();
                }

                if (endDelta > 0)
                {
                    colorBlend.Positions = colorBlend.Positions.Concat(new[] { 1F }).ToArray();
                    colorBlend.Colors    = colorBlend.Colors.Concat(new[] { colorBlend.Colors.Last() }).ToArray();
                }
                break;
            }

            return(colorBlend);
        }
예제 #59
0
 /// <summary>
 /// Gets the <see cref="GraphicsPath"/> for this element.
 /// </summary>
 /// <value></value>
 public override GraphicsPath Path(ISvgRenderer renderer)
 {
     return(GetPaths(this, renderer));
 }
예제 #60
0
 private void Draw(ISvgRenderer renderer, ISvgBoundable boundable)
 {
     renderer.SetBoundable(boundable);
     this.Render(renderer);
 }