private void InsertSquare(SvgGroupElement group, int xIndex, int yIndex)
		{
			bool isBlack = ((xIndex + yIndex) % 2 == 0);
			if (!isBlack)
			{
				// nothing to draw in case of a white square
				return;
			}

			float x = m_UpperLeft.X + xIndex * m_SquareLength;
			float y = m_UpperLeft.Y + yIndex * m_SquareLength;

			SvgRectElement rectangle = new SvgRectElement(
				x, y,
				m_SquareLength, m_SquareLength
				);
			rectangle.Style = s_FilledBlack;

			group.AddChild(rectangle);
		}
Пример #2
0
        public SvgGraphics()
        {
            _root = new SvgSvgElement();
            _root.Id = "SvgGdi_output";

            _bg = new SvgRectElement(0, 0, "100%", "100%");
            _bg.Style.Set("fill", new SvgColor(Color.FromName("Control")));
            _bg.Id = "background";
            _root.AddChild(_bg);

            _topgroup = new SvgGroupElement("root_group");
            _topgroup.Style.Set("shape-rendering", "crispEdges");
            _cur = _topgroup;
            _root.AddChild(_topgroup);

            _defs = new SvgDefsElement("clips_hatches_and_gradients");
            _root.AddChild(_defs);

            _transforms = new MatrixStack();
        }
		public void AddSquares(float yOffset, float xOffset, float sideLength, int xCount, int yCount)
		{
			SvgGroupElement squaresGroup = new SvgGroupElement("Squares");
			squaresGroup.Style = s_NormalLineStyle;

			float xStart = this.Origin.X + xOffset - xCount / 2.0F * sideLength;
			float yStart = this.Origin.Y + yOffset;

			for (int i = 0; i < xCount; i++)
			{
				for (int j = 0; j < yCount; j++)
				{
					SvgRectElement rectElement = new SvgRectElement(
						GetSvgLength(xStart + i * sideLength), GetSvgLength(yStart + j * sideLength),
						GetSvgLength(sideLength), GetSvgLength(sideLength));
					
					squaresGroup.AddChild(rectElement);
				}
			}

			this.Root.AddChild(squaresGroup);
		}
Пример #4
0
 /// <summary>
 /// Implemented
 /// </summary>
 public void DrawRectangle(Pen pen, Single x, Single y, Single width, Single height)
 {
     SvgRectElement rc= new SvgRectElement(x,y,width,height);
     rc.Style = new SvgStyle(pen);
     if (!_transforms.Result.IsIdentity)
         rc.Transform = new SvgTransformList(_transforms.Result.Clone());
     _cur.AddChild(rc);
 }
Пример #5
0
        /// <summary>
        /// When a GDI instruction with a brush parameter is called, there can be a lot we have to do to emulate the brush.  The aim is to return a 
        /// style that represents the brush.
        /// <para>
        /// Solid brush is very easy.
        /// </para>
        /// <para>
        /// Linear grad brush:  we ignore the blend curve and the transformation (and therefore the rotation parameter if any)
        /// Hatch brush: 
        /// </para>
        /// <para>
        /// Other types of brushes are too hard to emulate and are rendered pink.
        /// </para>
        /// </summary>
        /// <param name="br"></param>
        /// <returns></returns>
        private SvgStyle HandleBrush(Brush br)
        {
            if (br.GetType() == typeof(SolidBrush))
            {
                return new SvgStyle((SolidBrush)br);
            }

            if (br.GetType() == typeof(LinearGradientBrush))
            {
                LinearGradientBrush grbr = (LinearGradientBrush)br;
                RectangleF rc = grbr.Rectangle;

                SvgLinearGradient grad = new SvgLinearGradient(rc.Left, rc.Top, rc.Right, rc.Bottom);

                switch(grbr.WrapMode)
                {
                        //I have not been able to test Clamp because using a clamped gradient appears to crash the process
                        //under XP (?!?!)
                    case WrapMode.Clamp:
                        grad.SpreadMethod = "pad"; grad.GradientUnits = "objectBoundingBox"; break;
                    case WrapMode.Tile:
                        grad.SpreadMethod = "repeat"; grad.GradientUnits = "userSpaceOnUse"; break;
                    default:
                        grad.SpreadMethod = "reflect"; grad.GradientUnits = "userSpaceOnUse"; break;
                }

                ColorBlend cb = null;

                //GDI dll tends to crash when you try and access some members of gradient brushes that haven't been specified.
                try
                {
                    cb = grbr.InterpolationColors;
                }
                catch(Exception){}

                if(cb != null)
                {
                    for(int i = 0; i < grbr.InterpolationColors.Colors.Length; ++i)
                    {
                        grad.AddChild(new SvgStopElement(grbr.InterpolationColors.Positions[i], grbr.InterpolationColors.Colors[i]));
                    }
                }
                else
                {
                    grad.AddChild(new SvgStopElement("0%", grbr.LinearColors[0]));
                    grad.AddChild(new SvgStopElement("100%", grbr.LinearColors[1]));
                }

                grad.Id += "_LinearGradientBrush";

                _defs.AddChild(grad);

                SvgStyle s = new SvgStyle();
                s.Set("fill", new SvgUriReference(grad));
                return s;
            }

            if (br.GetType() == typeof(HatchBrush))
            {
                HatchBrush habr = (HatchBrush)br;

                SvgPatternElement patty = new SvgPatternElement(0,0,8,8, new SvgNumList("4 4 12 12"));
                patty.Style.Set("shape-rendering", "crispEdges");
                patty.Style.Set("stroke-linecap", "butt");

                SvgRectElement rc = new SvgRectElement(0,0,8,8);
                rc.Style.Set("fill", new SvgColor(habr.BackgroundColor));
                patty.AddChild(rc);

                AddHatchBrushDetails(patty, new SvgColor(habr.ForegroundColor), habr.HatchStyle);

                patty.Id += "_HatchBrush";
                patty.PatternUnits = "userSpaceOnUse";
                patty.PatternContentUnits = "userSpaceOnUse";
                _defs.AddChild(patty);

                SvgStyle s = new SvgStyle();
                s.Set("fill", new SvgUriReference(patty));
                return s;
            }

            //most types of brush we can't emulate, but luckily they are quite unusual
            return new SvgStyle(new SolidBrush(Color.Salmon));
        }
Пример #6
0
        private void DrawText(String s, Font font, Brush brush, RectangleF rect, StringFormat fmt, bool ignoreRect)
        {
            SvgTextElement txt = new SvgTextElement(s, rect.X, rect.Y);

            //GDI takes x and y as the upper left corner; svg takes them as the lower left.
            //We must therefore move the text one line down, but SVG does not understand about lines,
            //so we do as best we can, applying a downward translation before the current GDI translation.

            txt.Transform = new SvgTransformList(_transforms.Result.Clone());

            txt.Style = HandleBrush(brush);
            txt.Style += new SvgStyle(font);

            if (fmt.Alignment == StringAlignment.Center)
            {
                txt.Style.Set("text-anchor", "middle");
                txt.X = rect.X + rect.Width/2;
            }

            if (fmt.Alignment == StringAlignment.Far)
            {
                txt.Style.Set("text-anchor", "end");
                txt.X = rect.Right;
            }

            txt.Style.Set("baseline-shift", "-86%");//a guess.

            if(!ignoreRect && (fmt.FormatFlags != StringFormatFlags.NoClip))
            {
                SvgClipPathElement clipper = new SvgClipPathElement();
                clipper.Id += "_text_clipper";
                SvgRectElement rc = new SvgRectElement(rect.X, rect.Y, rect.Width, rect.Height);
                clipper.AddChild(rc);
                _defs.AddChild(clipper);

                txt.Style.Set("clip-path", new SvgUriReference(clipper));
            }

            _cur.AddChild(txt);
        }
Пример #7
0
        private void DrawEndAnchor(LineCap lc, CustomLineCap clc, Color col, float w, PointF pt, float angle)
        {
            SvgStyledTransformedElement anchor=null;
            PointF[] points = null;

            switch(lc)
            {
                case LineCap.ArrowAnchor:
                    points = new PointF[3];
                    points[0] = new PointF(0, -w/2f);
                    points[1] = new PointF(-w, w);
                    points[2] = new PointF(w, w);
                    anchor = new SvgPolygonElement(points);
                    break;
                case LineCap.DiamondAnchor:
                    points = new PointF[4];
                    points[0] = new PointF(0, -w);
                    points[1] = new PointF(w, 0);
                    points[2] = new PointF(0, w);
                    points[3] = new PointF(-w, 0);
                    anchor = new SvgPolygonElement(points);
                    break;
                case LineCap.RoundAnchor:
                    anchor = new SvgEllipseElement(0, 0, w, w);
                    break;
                case LineCap.SquareAnchor:
                    float ww = (w/3)*2;
                    anchor = new SvgRectElement(0 - ww, 0 - ww, ww*2, ww*2);
                    break;
                case LineCap.Custom:
                    //not implemented!
                    return;

                default:
                    return;
            }

            anchor.Id += "_line_anchor";
            anchor.Style.Set("fill", new SvgColor(col));
            anchor.Style.Set("stroke", "none");

            Matrix rotation = new Matrix();
            rotation.Rotate((angle/(float)Math.PI)*180);
            Matrix translation = new Matrix();
            translation.Translate(pt.X, pt.Y);

            anchor.Transform  = new SvgTransformList(_transforms.Result.Clone());
            anchor.Transform.Add(translation);
            anchor.Transform.Add(rotation);
            _cur.AddChild(anchor);
        }
Пример #8
0
        private void AddHatchBrushDetails(SvgPatternElement patty, SvgColor col, HatchStyle hs)
        {
            SvgStyledTransformedElement l1=null;
            SvgStyledTransformedElement l2 = null;
            SvgStyledTransformedElement l3 = null;
            SvgStyledTransformedElement l4 = null;

            switch(hs)
            {
                case HatchStyle.Cross:
                    l1 = new SvgLineElement(4,0,4,8);
                    l2 = new SvgLineElement(0,4,8,4);
                    break;

                case HatchStyle.BackwardDiagonal:
                    l1 = new SvgLineElement(8,0,0,8);
                    break;

                case HatchStyle.LightDownwardDiagonal:
                case HatchStyle.DarkDownwardDiagonal:
                    l1 = new SvgLineElement(4,0,8,4);
                    l2 = new SvgLineElement(0,4,4,8);
                    l3 = new SvgLineElement(0,0,8,8);
                    break;
                case HatchStyle.LightHorizontal:
                case HatchStyle.DarkHorizontal:
                    l1 = new SvgLineElement(0,2,8,2);
                    l2 = new SvgLineElement(0,6,8,6);
                    break;
                case HatchStyle.LightUpwardDiagonal:
                case HatchStyle.DarkUpwardDiagonal:
                    l1 = new SvgLineElement(0,4,4,0);
                    l2 = new SvgLineElement(4,8,8,4);
                    l3 = new SvgLineElement(0,8,8,0);
                    break;
                case HatchStyle.LightVertical:
                case HatchStyle.DarkVertical:
                    l1 = new SvgLineElement(2,0,2,8);
                    l2 = new SvgLineElement(6,0,6,8);
                    break;
                case HatchStyle.DashedDownwardDiagonal:
                    l1 = new SvgLineElement(0,0,4,4);
                    l2 = new SvgLineElement(4,0,8,4);
                    break;
                case HatchStyle.DashedHorizontal:
                    l1 = new SvgLineElement(0,2,4,2);
                    l2 = new SvgLineElement(4,6,8,6);
                    break;
                case HatchStyle.DashedUpwardDiagonal:
                    l1 = new SvgLineElement(4,0,0,4);
                    l2 = new SvgLineElement(8,0,4,4);
                    break;
                case HatchStyle.DashedVertical:
                    l1 = new SvgLineElement(2,0,2,4);
                    l2 = new SvgLineElement(6,4,6,8);
                    break;
                case HatchStyle.DiagonalBrick:
                    l1 = new SvgLineElement(0,8,8,0);
                    l2 = new SvgLineElement(0,0,4,4);
                    break;
                case HatchStyle.DiagonalCross:
                    l1 = new SvgLineElement(0,0,8,8);
                    l2 = new SvgLineElement(8,0,0,8);
                    break;
                case HatchStyle.Divot:
                    l1 = new SvgLineElement(2,2,4,4);
                    l2 = new SvgLineElement(4,4,2,6);
                    break;
                case HatchStyle.DottedDiamond:
                    l1 = new SvgLineElement(0,0,8,8);
                    l2 = new SvgLineElement(0,8,8,0);
                    break;
                case HatchStyle.DottedGrid:
                    l1 = new SvgLineElement(4,0,4,8);
                    l2 = new SvgLineElement(0,4,8,4);
                    break;
                case HatchStyle.ForwardDiagonal:
                    l1 = new SvgLineElement(0,0,8,8);
                    break;
                case HatchStyle.Horizontal:
                    l1 = new SvgLineElement(0,4,8,4);
                    break;
                case HatchStyle.HorizontalBrick:
                    l1 = new SvgLineElement(0,3,8,3);
                    l2 = new SvgLineElement(3,0,3,3);
                    l3 = new SvgLineElement(0,3,0,7);
                    l4 = new SvgLineElement(0,7,7,7);
                    break;
                case HatchStyle.LargeCheckerBoard:
                    l1 = new SvgRectElement(0,0,3f,3f);
                    l2 = new SvgRectElement(4,4,4,4f);
                    break;
                case HatchStyle.LargeConfetti:
                    l1 = new SvgRectElement(0,0,1,1);
                    l2 = new SvgRectElement(2,3,1,1);
                    l3 = new SvgRectElement(5,2,1,1);
                    l4 = new SvgRectElement(6,6,1,1);
                    break;
                case HatchStyle.NarrowHorizontal:
                    l1 = new SvgLineElement(0,1,8,1);
                    l2 = new SvgLineElement(0,3,8,3);
                    l3 = new SvgLineElement(0,5,8,5);
                    l4 = new SvgLineElement(0,7,8,7);
                    break;
                case HatchStyle.NarrowVertical:
                    l1 = new SvgLineElement(1,0,1,8);
                    l2 = new SvgLineElement(3,0,3,8);
                    l3 = new SvgLineElement(5,0,5,8);
                    l4 = new SvgLineElement(7,0,7,8);
                    break;
                case HatchStyle.OutlinedDiamond:
                    l1 = new SvgLineElement(0,0,8,8);
                    l2 = new SvgLineElement(8,0,0,8);
                    break;
                case HatchStyle.Plaid:
                    l1 = new SvgLineElement(0,0,8,0);
                    l2 = new SvgLineElement(0,3,8,3);
                    l3 = new SvgRectElement(0,4,3,3);
                    break;
                case HatchStyle.Shingle:
                    l1 = new SvgLineElement(0,2,2,0);
                    l2 = new SvgLineElement(2,0,7,5);
                    l3 = new SvgLineElement(0,3,3,7);
                    break;
                case HatchStyle.SmallCheckerBoard:
                    l1 = new SvgRectElement(0,0,1,1);
                    l2 = new SvgRectElement(4,4,1,1);
                    l3 = new SvgRectElement(4,0,1,1);
                    l4 = new SvgRectElement(0,4,1,1);
                    break;
                case HatchStyle.SmallConfetti:
                    l1 = new SvgLineElement(0,0,2,2);
                    l2 = new SvgLineElement(7,3,5,5);
                    l3 = new SvgLineElement(2,6,4,4);
                    break;
                case HatchStyle.SmallGrid:
                    l1 = new SvgLineElement(0,2,8,2);
                    l2 = new SvgLineElement(0,6,8,6);
                    l3 = new SvgLineElement(2,0,2,8);
                    l4 = new SvgLineElement(6,0,6,8);
                    break;
                case HatchStyle.SolidDiamond:
                    l1 = new SvgPolygonElement("3 0 6 3 3 6 0 3");
                    break;
                case HatchStyle.Sphere:
                    l1 = new SvgEllipseElement(3,3,2,2);
                    break;
                case HatchStyle.Trellis:
                    l1 = new SvgLineElement(0,1,8,1);
                    l2 = new SvgLineElement(0,3,8,3);
                    l3 = new SvgLineElement(0,5,8,5);
                    l4 = new SvgLineElement(0,7,8,7);
                    break;
                case HatchStyle.Vertical:
                    l4 = new SvgLineElement(0,0,0,8);
                    break;
                case HatchStyle.Wave:
                    l3 = new SvgLineElement(0,4,3,2);
                    l4 = new SvgLineElement(3,2,8,4);
                    break;
                case HatchStyle.Weave:
                    l1 = new SvgLineElement(0,4,4,0);
                    l2 = new SvgLineElement(8,4,4,8);
                    l3 = new SvgLineElement(0,0,0,4);
                    l4 = new SvgLineElement(0,4,4,8);
                    break;
                case HatchStyle.WideDownwardDiagonal:
                    l1 = new SvgLineElement(0,0,8,8);
                    l2 = new SvgLineElement(0,1,8,9);
                    l3 = new SvgLineElement(7,0,8,1);
                    break;
                case HatchStyle.WideUpwardDiagonal:
                    l1 = new SvgLineElement(8,0,0,8);
                    l2 = new SvgLineElement(8,1,0,9);
                    l3 = new SvgLineElement(0,1,-1,0);
                    break;
                case HatchStyle.ZigZag:
                    l1 = new SvgLineElement(0,4,4,0);
                    l2 = new SvgLineElement(4,0,8,4);
                    break;

                case HatchStyle.Percent05:
                    l1 = new SvgLineElement(0,0,1,0);
                    l2 = new SvgLineElement(4,4,5,4);
                    break;
                case HatchStyle.Percent10:
                    l1 = new SvgLineElement(0,0,1,0);
                    l2 = new SvgLineElement(4,2,5,2);
                    l3 = new SvgLineElement(2,4,3,4);
                    l4 = new SvgLineElement(6,6,7,6);
                    break;
                case HatchStyle.Percent20:
                    l1 = new SvgLineElement(0,0,2,0);
                    l2 = new SvgLineElement(4,2,6,2);
                    l3 = new SvgLineElement(2,4,4,4);
                    l4 = new SvgLineElement(5,6,7,6);
                    break;
                case HatchStyle.Percent25:
                    l1 = new SvgLineElement(0,0,3,0);
                    l2 = new SvgLineElement(4,2,6,2);
                    l3 = new SvgLineElement(2,4,5,4);
                    l4 = new SvgLineElement(5,6,7,6);
                    break;
                case HatchStyle.Percent30:
                    l1 = new SvgRectElement(0,0,3,1);
                    l2 = new SvgLineElement(4,2,6,2);
                    l3 = new SvgRectElement(2,4,3,1);
                    l4 = new SvgLineElement(5,6,7,6);
                    break;
                case HatchStyle.Percent40:
                    l1 = new SvgRectElement(0,0,3,1);
                    l2 = new SvgRectElement(4,2,3,1);
                    l3 = new SvgRectElement(2,4,3,1);
                    l4 = new SvgRectElement(5,6,3,1);
                    break;
                case HatchStyle.Percent50:
                    l1 = new SvgRectElement(0,0,3,3);
                    l2 = new SvgRectElement(4,4,4,4f);
                    break;
                case HatchStyle.Percent60:
                    l1 = new SvgRectElement(0,0,4,3);
                    l2 = new SvgRectElement(4,4,4,4f);
                    break;
                case HatchStyle.Percent70:
                    l1 = new SvgRectElement(0,0,4,5);
                    l2 = new SvgRectElement(4,4,4,4f);
                    break;
                case HatchStyle.Percent75:
                    l1 = new SvgRectElement(0,0,7,3);
                    l2 = new SvgRectElement(0,2,3,7);
                    break;
                case HatchStyle.Percent80:
                    l1 = new SvgRectElement(0,0,7,4);
                    l2 = new SvgRectElement(0,2,4,7);
                    break;
                case HatchStyle.Percent90:
                    l1 = new SvgRectElement(0,0,7,5);
                    l2 = new SvgRectElement(0,2,5,7);
                    break;

                default:

                    break;
            }

            if (l1 != null)
            {
                l1.Style.Set("stroke", col);
                l1.Style.Set("fill", col);
                patty.AddChild(l1);
            }
            if (l2 != null)
            {
                l2.Style.Set("stroke", col);
                l2.Style.Set("fill", col);
                patty.AddChild(l2);
            }
            if (l3 != null)
            {
                l3.Style.Set("stroke", col);
                l3.Style.Set("fill", col);
                patty.AddChild(l3);
            }
            if (l4 != null)
            {
                l4.Style.Set("stroke", col);
                l4.Style.Set("fill", col);
                patty.AddChild(l4);
            }
        }
Пример #9
0
        /// <summary>
        /// Implemented.
        /// </summary>
        public void SetClip(RectangleF rect)
        {
            SvgClipPathElement clipper = new SvgClipPathElement();
            clipper.Id += "_SetClip";
            SvgRectElement rc = new SvgRectElement(rect.X, rect.Y, rect.Width, rect.Height);
            clipper.AddChild(rc);
            _defs.AddChild(clipper);

            _cur.Style.Set("clip-path", new SvgUriReference(clipper));
        }
Пример #10
0
 /// <summary>
 /// Implemented
 /// </summary>
 public void FillRectangle(Brush brush, Single x, Single y, Single width, Single height)
 {
     SvgRectElement rc = new SvgRectElement(x, y, width, height);
     rc.Style = HandleBrush(brush);
     if (!_transforms.Result.IsIdentity)
         rc.Transform = _transforms.Result.Clone();
     _cur.AddChild(rc);
 }
Пример #11
0
        private void DrawImagePixel(SvgElement container, Color c, float x, float y, float w, float h)
        {
            if (c.A == 0)
                return;

            SvgRectElement rc = new SvgRectElement(x, y, w, h);
            rc.Id="";
            rc.Style.Set("fill", "rgb("+c.R+","+c.G+","+c.B+")");
            if (c.A < 255)
                rc.Style.Set("opacity", c.A/255f);

            container.AddChild(rc);
        }
Пример #12
0
        private void DrawText(String s, Font font, Brush brush, RectangleF rect, StringFormat fmt, bool ignoreRect)
        {
            if (s != null && s.Contains("\n"))
                throw new SvgGdiNotImpl("DrawText multiline text");

            SvgTextElement txt = new SvgTextElement(s, rect.X, rect.Y);

            //GDI takes x and y as the upper left corner; svg takes them as the lower left.
            //We must therefore move the text one line down, but SVG does not understand about lines,
            //so we do as best we can, applying a downward translation before the current GDI translation.

            txt.Transform = new SvgTransformList(_transforms.Result.Clone());

            txt.Style = HandleBrush(brush);
            txt.Style += new SvgStyle(font);

            switch (fmt.Alignment)
            {
                case StringAlignment.Near:
                    break;

                case StringAlignment.Center:
                    {
                        if (ignoreRect)
                            throw new SvgGdiNotImpl("DrawText automatic rect");

                        txt.Style.Set("text-anchor", "middle");
                        txt.X = rect.X + rect.Width / 2;
                    }
                    break;

                case StringAlignment.Far:
                    {
                        if (ignoreRect)
                            throw new SvgGdiNotImpl("DrawText automatic rect");

                        txt.Style.Set("text-anchor", "end");
                        txt.X = rect.Right;
                    }
                    break;

                default:
                    throw new SvgGdiNotImpl("DrawText horizontal alignment");
            }

            if (!ignoreRect && ((fmt.FormatFlags & StringFormatFlags.NoClip) != StringFormatFlags.NoClip))
            {
                SvgClipPathElement clipper = new SvgClipPathElement();
                clipper.Id += "_text_clipper";
                SvgRectElement rc = new SvgRectElement(rect.X, rect.Y, rect.Width, rect.Height);
                clipper.AddChild(rc);
                _defs.AddChild(clipper);

                txt.Style.Set("clip-path", new SvgUriReference(clipper));
            }

            switch (fmt.LineAlignment)
            {
                case StringAlignment.Near:
                    {
                        // TODO: ??
                        // txt.Style.Set("baseline-shift", "-86%");//a guess.
                        var span = new SvgTspanElement(s);
                        span.DY = new SvgLength(txt.Style.Get("font-size").ToString());
                        txt.Text = null;
                        txt.AddChild(span);
                    }
                    break;

                case StringAlignment.Center:
                    {
                        if (ignoreRect)
                            throw new SvgGdiNotImpl("DrawText automatic rect");

                        txt.Y.Value = txt.Y.Value + (rect.Height / 2);
                        var span = new SvgTspanElement(s);
                        span.DY = new SvgLength(txt.Style.Get("font-size").ToString());
                        span.DY.Value = span.DY.Value * ((1 - GetFontDescentPercentage(font)) - 0.5f);
                        txt.Text = null;
                        txt.AddChild(span);
                    }
                    break;

                case StringAlignment.Far:
                    {
                        if (ignoreRect)
                            throw new SvgGdiNotImpl("DrawText automatic rect");

                        txt.Y.Value = txt.Y.Value + rect.Height;
                        // This would solve the alignment as well, but it's not supported by Internet Explorer
                        //
                        // txt.Attributes["dominant-baseline"] = "text-after-edge";
                        var span = new SvgTspanElement(s);
                        span.DY = new SvgLength(txt.Style.Get("font-size").ToString());
                        span.DY.Value = span.DY.Value * ((1 - GetFontDescentPercentage(font)) - 1);
                        txt.Text = null;
                        txt.AddChild(span);
                    }
                    break;

                default:
                    throw new SvgGdiNotImpl("DrawText vertical alignment");
            }

            _cur.AddChild(txt);
        }
Пример #13
0
        private void DrawEndAnchor(LineCap lc, CustomLineCap clc, Color col, float w, PointF pt, float angle, bool ignoreUnsupportedLineCaps)
        {
            SvgStyledTransformedElement anchor = null;
            PointF[] points = null;

            switch (lc) {
                case LineCap.NoAnchor:
                    break;

                case LineCap.Flat:
                    // TODO: what is the correct look?
                    break;

                case LineCap.ArrowAnchor:
                    points = new PointF[3];
                    points[0] = new PointF(0, -w / 2f);
                    points[1] = new PointF(-w, w);
                    points[2] = new PointF(w, w);
                    anchor = new SvgPolygonElement(points);
                    break;

                case LineCap.DiamondAnchor:
                    points = new PointF[4];
                    points[0] = new PointF(0, -w);
                    points[1] = new PointF(w, 0);
                    points[2] = new PointF(0, w);
                    points[3] = new PointF(-w, 0);
                    anchor = new SvgPolygonElement(points);
                    break;

                case LineCap.RoundAnchor:
                    anchor = new SvgEllipseElement(0, 0, w, w);
                    break;

                case LineCap.SquareAnchor:
                    float ww = (w / 3) * 2;
                    anchor = new SvgRectElement(0 - ww, 0 - ww, ww * 2, ww * 2);
                    break;

                case LineCap.Custom:
                    if (clc != null)
                    {
                        if (!ignoreUnsupportedLineCaps)
                            throw new SvgGdiNotImpl("DrawEndAnchor custom");
                    }
                    break;

                default:
                    if (!ignoreUnsupportedLineCaps)
                        throw new SvgGdiNotImpl("DrawEndAnchor " + lc.ToString());
                    break;
            }

            if (anchor == null)
                return;

            anchor.Id += "_line_anchor";
            anchor.Style.Set("fill", new SvgColor(col));
            anchor.Style.Set("stroke", "none");

            Matrix rotation = new Matrix();
            rotation.Rotate((angle / (float)Math.PI) * 180);
            Matrix translation = new Matrix();
            translation.Translate(pt.X, pt.Y);

            anchor.Transform = new SvgTransformList(_transforms.Result.Clone());
            anchor.Transform.Add(translation);
            anchor.Transform.Add(rotation);
            _cur.AddChild(anchor);
        }