private void AddGraphicsPath(SvgTextContentElement element, ref PointF ctp, string text)
        {
            if (text.Length == 0)
            {
                return;
            }

            float        emSize = GetComputedFontSize(element);
            FontFamily   family = GetFontFamily(element);
            int          style  = GetFontStyle(element);
            StringFormat sf     = GetStringFormat(element);

            GraphicsPath textGeometry = new GraphicsPath();

            float xCorrection = 0;

            if (sf.Alignment == StringAlignment.Near)
            {
                xCorrection = emSize * 1 / 6;
            }
            else if (sf.Alignment == StringAlignment.Far)
            {
                xCorrection = -emSize * 1 / 6;
            }

            float yCorrection = (float)(family.GetCellAscent(FontStyle.Regular)) / (float)(family.GetEmHeight(FontStyle.Regular)) * emSize;

            // TODO: font property
            PointF p = new PointF(ctp.X - xCorrection, ctp.Y - yCorrection);

            textGeometry.AddString(text, family, style, emSize, p, sf);
            if (!textGeometry.GetBounds().IsEmpty)
            {
                float bboxWidth = textGeometry.GetBounds().Width;
                if (sf.Alignment == StringAlignment.Center)
                {
                    bboxWidth /= 2;
                }
                else if (sf.Alignment == StringAlignment.Far)
                {
                    bboxWidth = 0;
                }

                ctp.X += bboxWidth + emSize / 4;
            }

            if (_textMode == GdiTextMode.Outlining)
            {
                _graphicsPath.AddPath(textGeometry, false);
                return;
            }

            GdiSvgPaint fillPaint = new GdiSvgPaint(element, "fill");
            Brush       brush     = fillPaint.GetBrush(textGeometry);

            GdiSvgPaint strokePaint = new GdiSvgPaint(element, "stroke");
            Pen         pen         = strokePaint.GetPen(textGeometry);

            if (brush != null)
            {
                if (brush is PathGradientBrush)
                {
                    var gps = fillPaint.PaintFill as GdiRadialGradientFill;

                    _graphics.SetClip(gps.GetRadialRegion(textGeometry.GetBounds()), CombineMode.Exclude);

                    SolidBrush tempBrush = new SolidBrush(((PathGradientBrush)brush).InterpolationColors.Colors[0]);
                    _graphics.FillPath(this, tempBrush, textGeometry);
                    tempBrush.Dispose();
                    _graphics.ResetClip();
                }

                _graphics.FillPath(this, brush, textGeometry);
                brush.Dispose();
            }

            if (pen != null)
            {
                if (pen.Brush is PathGradientBrush)
                {
                    var gps = strokePaint.PaintFill as GdiRadialGradientFill;
                    GdiGraphicsContainer container = _graphics.BeginContainer();

                    _graphics.SetClip(gps.GetRadialRegion(textGeometry.GetBounds()), CombineMode.Exclude);

                    SolidBrush tempBrush = new SolidBrush(((PathGradientBrush)pen.Brush).InterpolationColors.Colors[0]);
                    Pen        tempPen   = new Pen(tempBrush, pen.Width);
                    _graphics.DrawPath(this, tempPen, textGeometry);
                    tempPen.Dispose();
                    tempBrush.Dispose();

                    _graphics.EndContainer(container);
                }

                _graphics.DrawPath(this, pen, textGeometry);
                pen.Dispose();
            }

            textGeometry.Dispose();
        }
Beispiel #2
0
        public void PaintMarker(GdiGraphicsRenderer renderer, GdiGraphics gr,
                                SvgMarkerPosition markerPos, SvgStyleableElement refElement)
        {
            ISharpMarkerHost markerHostElm = (ISharpMarkerHost)refElement;
            SvgMarkerElement markerElm     = (SvgMarkerElement)_svgElement;

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

            bool mayHaveCurves = markerHostElm.MayHaveCurves;
            int  start;
            int  len;

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

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

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

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

                GdiGraphicsContainer gc = gr.BeginContainer();

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

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

                    switch (markerPos)
                    {
                    case SvgMarkerPosition.Start:
                        angle = markerHostElm.GetStartAngle(i);
                        //angle = markerHostElm.GetStartAngle(i + 1);
                        if (vertexPositions.Length >= 2)
                        {
                            SvgPointF pMarkerPoint1 = vertexPositions[start];
                            SvgPointF pMarkerPoint2 = vertexPositions[end];
                            float     xDiff         = pMarkerPoint2.X - pMarkerPoint1.X;
                            float     yDiff         = pMarkerPoint2.Y - pMarkerPoint1.Y;
                            double    angleMarker   = (float)(Math.Atan2(yDiff, xDiff) * 180.0 / Math.PI);
                            if (!angleMarker.Equals(angle))
                            {
                                angle = angleMarker;
                            }
                        }
                        break;

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

                    default:
                        angle = markerHostElm.GetEndAngle(i - 1);
                        //double angle2 = markerHostElm.GetEndAngle(i);
                        if (vertexPositions.Length >= 2)
                        {
                            SvgPointF pMarkerPoint1 = vertexPositions[start - 1];
                            SvgPointF pMarkerPoint2 = vertexPositions[start];
                            float     xDiff         = pMarkerPoint2.X - pMarkerPoint1.X;
                            float     yDiff         = pMarkerPoint2.Y - pMarkerPoint1.Y;
                            double    angleMarker   = (float)(Math.Atan2(yDiff, xDiff) * 180.0 / Math.PI);
                            if (!angleMarker.Equals(angle))
                            {
                                angle = angleMarker;
                            }
                        }
                        //if (mayHaveCurves)
                        //{
                        //	angle = this.GetAngleAt(start - 1, angle, markerPos, markerHostElm);
                        //}
                        break;
                    }
                    gr.RotateTransform((float)angle);
                }

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

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

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

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

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

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

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

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

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

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

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

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

                RectangleF rectClip = RectangleF.Empty;

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

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

                renderer.RenderChildren(markerElm);

                gr.EndContainer(gc);
            }
        }
Beispiel #3
0
        public void PaintMarker(GdiGraphicsRenderer renderer, GdiGraphics gr,
                                SvgMarkerPosition markerPos, SvgStyleableElement refElement)
        {
            ISharpMarkerHost markerHostElm = (ISharpMarkerHost)refElement;
            SvgMarkerElement markerElm     = (SvgMarkerElement)_svgElement;

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

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

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

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

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

                GdiGraphicsContainer gc = gr.BeginContainer();

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

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

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

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

                    default:
                        angle = markerHostElm.GetEndAngle(i);
                        break;
                    }
                    gr.RotateTransform((float)angle);
                }

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

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


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

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

                Clip(gr);

                renderer.RenderChildren(markerElm);

                gr.EndContainer(gc);
            }
        }