Esempio n. 1
0
        public override IEnumerable <SvgAttribute> GetAttributes()
        {
            var baseAttributes = base.GetAttributes();

            if (baseAttributes != null)
            {
                foreach (var attr in baseAttributes)
                {
                    yield return(attr);
                }
            }

            var ci = CultureInfo.InvariantCulture;

            yield return(new SvgAttribute("x1", "0",
                                          () => X1.ToString(ci),
                                          v => X1 = SvgAttribute.ParseFloatAttribute(v)
                                          ));

            yield return(new SvgAttribute("y1", "0",
                                          () => Y1.ToString(ci),
                                          v => Y1 = SvgAttribute.ParseFloatAttribute(v)
                                          ));

            yield return(new SvgAttribute("x2", "0",
                                          () => X2.ToString(ci),
                                          v => X2 = SvgAttribute.ParseFloatAttribute(v)
                                          ));

            yield return(new SvgAttribute("y2", "0",
                                          () => Y2.ToString(ci),
                                          v => Y2 = SvgAttribute.ParseFloatAttribute(v)
                                          ));

            yield return(new SvgAttribute("stroke-width",
                                          () => StrokeWidth.ToString(ci),
                                          v => StrokeWidth = SvgAttribute.ParseFloatAttribute(v)
                                          ));

            yield return(new SvgAttribute("stroke",
                                          () => Stroke == Color.Empty ? "none" : ColorTranslator.ToSvg(Stroke),
                                          v => Stroke = SvgAttribute.ParseColorAttribute(v, Stroke.A)
                                          ));

            yield return(new SvgAttribute("stroke-opacity", "1",
                                          () => ((double)Stroke.A / 255).ToString(ci),
                                          v => Stroke = SvgAttribute.ParseOpacityAttribute(v, Stroke)
                                          ));

            yield return(new SvgAttribute("stroke-dashoffset",
                                          () => StrokeDashOffset.ToString(ci),
                                          v => StrokeDashOffset = SvgAttribute.ParseFloatAttribute(v)
                                          ));

            yield return(new SvgAttribute("stroke-dasharray",
                                          () => DashArrayToString(),
                                          v => StrokeDashArray = SvgAttribute.ParseFloatArray(v)
                                          ));
        }
Esempio n. 2
0
        public override IEnumerable <SvgAttribute> GetAttributes()
        {
            var baseAttributes = base.GetAttributes();

            if (baseAttributes != null)
            {
                foreach (var attr in baseAttributes)
                {
                    yield return(attr);
                }
            }

            var ci = CultureInfo.InvariantCulture;

            yield return(new SvgAttribute("cx", "0",
                                          () => Cx.ToString(ci),
                                          v => Cx = SvgAttribute.ParseFloatAttribute(v)
                                          ));

            yield return(new SvgAttribute("cy", "0",
                                          () => Cy.ToString(ci),
                                          v => Cy = SvgAttribute.ParseFloatAttribute(v)
                                          ));

            yield return(new SvgAttribute("rx", "0",
                                          () => Rx.ToString(ci),
                                          v => Rx = SvgAttribute.ParseFloatAttribute(v)
                                          ));

            yield return(new SvgAttribute("ry", "0",
                                          () => Ry.ToString(ci),
                                          v => Ry = SvgAttribute.ParseFloatAttribute(v)
                                          ));

            yield return(new SvgAttribute("stroke-width",
                                          () => StrokeWidth.ToString(ci),
                                          v => StrokeWidth = SvgAttribute.ParseFloatAttribute(v)
                                          ));

            yield return(new SvgAttribute("stroke",
                                          () => ColorTranslator.ToSvg(Stroke),
                                          v => Stroke = SvgAttribute.ParseColorAttribute(v, Stroke.A)
                                          ));

            yield return(new SvgAttribute("stroke-opacity", "1",
                                          () => ((double)Stroke.A / 255).ToString(ci),
                                          v => Stroke = SvgAttribute.ParseOpacityAttribute(v, Stroke)
                                          ));

            yield return(new SvgAttribute("fill",
                                          () => Fill.A == 0 ? "none" : ColorTranslator.ToSvg(Fill),
                                          v => Fill = SvgAttribute.ParseColorAttribute(v, Fill.A)
                                          ));

            yield return(new SvgAttribute("fill-opacity", "1",
                                          () => ((double)Fill.A / 255).ToString(ci),
                                          v => Fill = SvgAttribute.ParseOpacityAttribute(v, Fill)
                                          ));
        }
 public override int GetHashCode()
 {
     return(string.Concat(FillColor.ToString(), StrokeColor.ToString(), StrokeWidth.GetHashCode()).GetHashCode());
     //return ComputeStringHash(FillColor, StrokeColor, StrokeWidth);
     //unchecked
     //{
     //	int hash = FillColor.ToString().GetHashCode();
     //	// Maybe nullity checks, if these are objects not primitives!
     //	hash = hash * 29 + StrokeColor.ToString().GetHashCode();
     //	hash = hash * 29 + StrokeWidth.ToString().GetHashCode();
     //	return hash;
     //}
 }
Esempio n. 4
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>
        /// <param name="stroke"></param>
        protected internal virtual bool RenderStroke(ISvgRenderer renderer, SvgPaintServer stroke = null)
        {
            stroke = stroke ?? Stroke;

            if (stroke != null && stroke != SvgPaintServer.None)
            {
                var strokeWidth = StrokeWidth.ToDeviceValue(renderer, UnitRenderingType.Other, this);

                renderer.DrawPath(Path(renderer), stroke.GetColor(this, renderer, FixOpacityValue(StrokeOpacity), true), strokeWidth);
                return(true);
            }

            return(false);
        }
Esempio n. 5
0
        /// <summary>
        /// Create a pen that can be used to render this marker
        /// </summary>
        /// <param name="pStroke"></param>
        /// <returns></returns>
        private Pen CreatePen(SvgPath pPath, SvgRenderer renderer)
        {
            Brush pBrush = pPath.Stroke.GetBrush(this, renderer, Opacity);

            switch (MarkerUnits)
            {
            case SvgMarkerUnits.strokeWidth:
                return(new Pen(pBrush, StrokeWidth.ToDeviceValue(renderer, UnitRenderingType.Other, this) *
                               pPath.StrokeWidth.ToDeviceValue(renderer, UnitRenderingType.Other, this)));

            case SvgMarkerUnits.userSpaceOnUse:
                return(new Pen(pBrush, StrokeWidth.ToDeviceValue(renderer, UnitRenderingType.Other, this)));
            }
            return(new Pen(pBrush, StrokeWidth.ToDeviceValue(renderer, UnitRenderingType.Other, this)));
        }
Esempio n. 6
0
        /// <summary>
        /// Create a pen that can be used to render this marker
        /// </summary>
        /// <returns></returns>
        private Pen CreatePen(SvgVisualElement pPath, ISvgRenderer renderer)
        {
            if (pPath.Stroke == null)
            {
                return(null);
            }
            Brush pBrush = pPath.Stroke.GetBrush(this, renderer, Opacity);

            switch (MarkerUnits)
            {
            case SvgMarkerUnits.StrokeWidth:
                return(new Pen(pBrush, StrokeWidth.ToDeviceValue(renderer, UnitRenderingType.Other, this) *
                               pPath.StrokeWidth.ToDeviceValue(renderer, UnitRenderingType.Other, this)));

            case SvgMarkerUnits.UserSpaceOnUse:
                return(new Pen(pBrush, StrokeWidth.ToDeviceValue(renderer, UnitRenderingType.Other, this)));
            }
            return(new Pen(pBrush, StrokeWidth.ToDeviceValue(renderer, UnitRenderingType.Other, this)));
        }
Esempio n. 7
0
        /// <summary>
        /// Create a pen that can be used to render this marker
        /// </summary>
        /// <returns></returns>
        private Pen CreatePen(SvgVisualElement pPath, ISvgRenderer renderer)
        {
            if (this.Stroke == null)
            {
                return(null);
            }
            Brush pBrush = this.Stroke.GetBrush(this, renderer, FixOpacityValue(Opacity));

            switch (MarkerUnits)
            {
            case SvgMarkerUnits.StrokeWidth:
                // TODO: have to multiply with marker stroke width if it is not inherted from the
                // same ancestor as owner path stroke width
                return(new Pen(pBrush, pPath.StrokeWidth.ToDeviceValue(renderer, UnitRenderingType.Other, this)));

            case SvgMarkerUnits.UserSpaceOnUse:
                return(new Pen(pBrush, StrokeWidth.ToDeviceValue(renderer, UnitRenderingType.Other, this)));
            }
            return(new Pen(pBrush, StrokeWidth.ToDeviceValue(renderer, UnitRenderingType.Other, this)));
        }
Esempio n. 8
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 (Stroke != null && Stroke != SvgPaintServer.None && StrokeWidth > 0f)
            {
                var strokeWidth = StrokeWidth.ToDeviceValue(renderer, UnitRenderingType.Other, this);
                using (var brush = Stroke.GetBrush(this, renderer, Math.Min(Math.Max(StrokeOpacity, 0f), 1f), true))
                {
                    if (brush != null)
                    {
                        var path   = Path(renderer);
                        var bounds = path.GetBounds();
                        if (path.PointCount < 1)
                        {
                            return(false);
                        }
                        if (bounds.Width <= 0f && bounds.Height <= 0f)
                        {
                            switch (StrokeLineCap)
                            {
                            case SvgStrokeLineCap.Round:
                                using (var capPath = new GraphicsPath())
                                {
                                    capPath.AddEllipse(path.PathPoints[0].X - strokeWidth / 2f, path.PathPoints[0].Y - strokeWidth / 2f, strokeWidth, strokeWidth);
                                    renderer.FillPath(brush, capPath);
                                }
                                break;

                            case SvgStrokeLineCap.Square:
                                using (var capPath = new GraphicsPath())
                                {
                                    capPath.AddRectangle(new RectangleF(path.PathPoints[0].X - strokeWidth / 2f, path.PathPoints[0].Y - strokeWidth / 2f, strokeWidth, strokeWidth));
                                    renderer.FillPath(brush, capPath);
                                }
                                break;
                            }
                        }
                        else
                        {
                            using (var pen = new Pen(brush, strokeWidth))
                            {
                                if (StrokeDashArray != null && StrokeDashArray.Count > 0)
                                {
                                    strokeWidth = strokeWidth <= 0 ? 1f : strokeWidth;
                                    if (StrokeDashArray.Count % 2 != 0)
                                    {
                                        // handle odd dash arrays by repeating them once
                                        StrokeDashArray.AddRange(StrokeDashArray);
                                    }

                                    var dashOffset = StrokeDashOffset;

                                    /* divide by stroke width - GDI uses stroke width as unit.*/
                                    var dashPattern = StrokeDashArray.Select(u => ((u.ToDeviceValue(renderer, UnitRenderingType.Other, this) <= 0f) ? 1f :
                                                                                   u.ToDeviceValue(renderer, UnitRenderingType.Other, this)) / strokeWidth).ToArray();
                                    var length = dashPattern.Length;

                                    if (StrokeLineCap == SvgStrokeLineCap.Round)
                                    {
                                        // to handle round caps, we have to adapt the dash pattern
                                        // by increasing the dash length by the stroke width - GDI draws the rounded
                                        // edge inside the dash line, SVG draws it outside the line
                                        var pattern = new float[length];
                                        var offset  = 1; // the values are already normalized to dash width
                                        for (var i = 0; i < length; i++)
                                        {
                                            pattern[i] = dashPattern[i] + offset;
                                            if (pattern[i] <= 0f)
                                            {
                                                // overlapping caps - remove the gap for simplicity, see #508
                                                if (i < length - 1)
                                                {
                                                    // add the next dash segment to the current one
                                                    dashPattern[i - 1] += dashPattern[i] + dashPattern[i + 1];
                                                    length             -= 2;
                                                    for (var k = i; k < length; k++)
                                                    {
                                                        dashPattern[k] = dashPattern[k + 2];
                                                    }

                                                    // and handle the combined segment again
                                                    i -= 2;
                                                }
                                                else if (i > 2)
                                                {
                                                    // add the last dash segment to the first one
                                                    // this will change the start point, so adapt the offset
                                                    var dashLength = dashPattern[i - 1] + dashPattern[i];
                                                    pattern[0] += dashLength;
                                                    length     -= 2;
                                                    dashOffset += dashLength * strokeWidth;
                                                }
                                                else
                                                {
                                                    // we have only one dash with the gap too small -
                                                    // do not use dash at all
                                                    length = 0;
                                                    break;
                                                }
                                            }
                                            offset *= -1; // increase dash length, decrease spaces
                                        }
                                        if (length > 0)
                                        {
                                            if (length < dashPattern.Length)
                                            {
                                                Array.Resize(ref pattern, length);
                                            }
                                            dashPattern = pattern;
                                            pen.DashCap = DashCap.Round;
                                        }
                                    }

                                    if (length > 0)
                                    {
                                        pen.DashPattern = dashPattern;

                                        if (dashOffset != 0f)
                                        {
                                            pen.DashOffset = ((dashOffset.ToDeviceValue(renderer, UnitRenderingType.Other, this) <= 0f) ? 1f :
                                                              dashOffset.ToDeviceValue(renderer, UnitRenderingType.Other, this)) / strokeWidth;
                                        }
                                    }
                                }
                                switch (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 = StrokeMiterLimit;
                                switch (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);
        }
Esempio n. 9
0
 public override int GetHashCode()
 {
     return(StrokeWidth.GetHashCode() ^
            Color.GetHashCode());
 }