static void BuildTextSpan(GeometryGroup gp, TextStyle textStyle, TextShape.TSpan.Element tspan, ref double x, ref double y) { foreach (TextShape.TSpan.Element child in tspan.Children) { if (child.ElementType == TextShape.TSpan.Element.eElementType.Text) { string txt = child.Text; double totalwidth = 0; double baseline = y; if (child.TextStyle.BaseLineShift == "sub") { baseline += child.TextStyle.FontSize * 0.5; } /* * cap height ? fontSize*/ ; if (child.TextStyle.BaseLineShift == "super") { baseline -= tspan.TextStyle.FontSize + (child.TextStyle.FontSize * 0.25) /*font.CapsHeight * fontSize*/; } Geometry gm = BuildGlyphRun(child.TextStyle, txt, x, baseline, ref totalwidth); TextRender.SetElement(gm, child); gp.Children.Add(gm); x += totalwidth; continue; } if (child.ElementType == TextShape.TSpan.Element.eElementType.Tag) { BuildTextSpan(gp, textStyle, child, ref x, ref y); } } }
DrawingGroup LoadGroup(IList <Shape> elements) { List <ControlLine> debugPoints = new List <ControlLine>(); DrawingGroup grp = new DrawingGroup(); foreach (Shape shape in elements) { shape.GetFill().FillBrush = m_brush; if (shape is UseShape) { UseShape useshape = shape as UseShape; Group group = SVG.GetShape(useshape.hRef) as Group; if (group != null) { Shape oldparent = group.Parent; group.Parent = useshape; // this to get proper style propagated DrawingGroup subgroup = LoadGroup(group.Elements); subgroup.Transform = new TranslateTransform(useshape.X, useshape.Y); grp.Children.Add(subgroup); group.Parent = oldparent; } continue; } if (shape is Group) { DrawingGroup subgroup = LoadGroup((shape as Group).Elements); if (shape.Transform != null) { subgroup.Transform = shape.Transform; } grp.Children.Add(subgroup); continue; } if (shape is RectangleShape) { RectangleShape r = shape as RectangleShape; RectangleGeometry rect = new RectangleGeometry(new Rect(r.X, r.Y, r.Width, r.Height)); rect.RadiusX = r.RX; rect.RadiusY = r.RY; if (rect.RadiusX == 0 && rect.RadiusY > 0) { rect.RadiusX = rect.RadiusY; } grp.Children.Add(NewDrawingItem(shape, rect)); } if (shape is LineShape) { LineShape r = shape as LineShape; LineGeometry line = new LineGeometry(r.P1, r.P2); grp.Children.Add(NewDrawingItem(shape, line)); } if (shape is PolylineShape) { PolylineShape r = shape as PolylineShape; PathGeometry path = new PathGeometry(); PathFigure p = new PathFigure(); path.Figures.Add(p); p.IsClosed = false; p.StartPoint = r.Points[0]; for (int index = 1; index < r.Points.Length; index++) { p.Segments.Add(new LineSegment(r.Points[index], true)); } grp.Children.Add(NewDrawingItem(shape, path)); } if (shape is PolygonShape) { PolygonShape r = shape as PolygonShape; PathGeometry path = new PathGeometry(); PathFigure p = new PathFigure(); path.Figures.Add(p); p.IsClosed = true; p.StartPoint = r.Points[0]; for (int index = 1; index < r.Points.Length; index++) { p.Segments.Add(new LineSegment(r.Points[index], true)); } grp.Children.Add(NewDrawingItem(shape, path)); } if (shape is CircleShape) { CircleShape r = shape as CircleShape; EllipseGeometry c = new EllipseGeometry(new Point(r.CX, r.CY), r.R, r.R); grp.Children.Add(NewDrawingItem(shape, c)); } if (shape is EllipseShape) { EllipseShape r = shape as EllipseShape; EllipseGeometry c = new EllipseGeometry(new Point(r.CX, r.CY), r.RX, r.RY); grp.Children.Add(NewDrawingItem(shape, c)); } if (shape is ImageShape) { ImageShape image = shape as ImageShape; ImageDrawing i = new ImageDrawing(image.ImageSource, new Rect(image.X, image.Y, image.Width, image.Height)); grp.Children.Add(i); } if (shape is TextShape) { GeometryGroup gp = TextRender.BuildTextGeometry(shape as TextShape); if (gp != null) { foreach (Geometry gm in gp.Children) { TextShape.TSpan.Element tspan = TextRender.GetElement(gm); if (tspan != null) { grp.Children.Add(NewDrawingItem(tspan, gm)); } else { grp.Children.Add(NewDrawingItem(shape, gm)); } } } } if (shape is PathShape) { PathShape r = shape as PathShape; PathFigure p = null; Point lastPoint = new Point(0, 0); PathShape.CurveTo lastc = null; Point lastcirPoint = new Point(0, 0); PathGeometry path = new PathGeometry(); foreach (PathShape.PathElement element in r.Elements) { bool isRelative = element.IsRelative; if (element is PathShape.MoveTo) { p = new PathFigure(); p.IsClosed = r.ClosePath; if (isRelative) { p.StartPoint = lastPoint + (Vector)((PathShape.MoveTo)element).Point; } else { p.StartPoint = ((PathShape.MoveTo)element).Point; } lastPoint = p.StartPoint; path.Figures.Add(p); continue; } if (element is PathShape.LineTo) { PathShape.LineTo lineto = element as PathShape.LineTo; foreach (Point point in lineto.Points) { if (isRelative) { Point newpoint = lastPoint + (Vector)point; lastPoint = newpoint; p.Segments.Add(new LineSegment(newpoint, true)); } else { if (lineto.PositionType == PathShape.LineTo.eType.Point) { lastPoint = point; } if (lineto.PositionType == PathShape.LineTo.eType.Horizontal) { lastPoint = new Point(point.X, lastPoint.Y); } if (lineto.PositionType == PathShape.LineTo.eType.Vertical) { lastPoint = new Point(lastPoint.X, point.Y); } p.Segments.Add(new LineSegment(lastPoint, true)); } } continue; } if (element is PathShape.CurveTo) { PathShape.CurveTo c = element as PathShape.CurveTo; Point startPoint = lastPoint; BezierSegment s = new BezierSegment(); if (isRelative) { s.Point1 = lastPoint + (Vector)c.CtrlPoint1; if (c.Command == 's') { // first control point is a mirrored point of last end control point //s.Point1 = lastPoint + new Vector(lastc.Point.X - dx, lastc.Point.Y - dy); //s.Point1 = new Point(lastctrlpoint.X+2, lastctrlpoint.Y+2); double dx = lastc.CtrlPoint2.X - lastc.Point.X; double dy = lastc.CtrlPoint2.Y - lastc.Point.Y; s.Point1 = new Point(lastcirPoint.X - dx, lastcirPoint.Y - dy); //s.Point1 = lastctrlpoint; } s.Point2 = lastPoint + (Vector)c.CtrlPoint2; s.Point3 = lastPoint + (Vector)c.Point; } else { s.Point1 = c.CtrlPoint1; s.Point2 = c.CtrlPoint2; s.Point3 = c.Point; } lastPoint = s.Point3; p.Segments.Add(s); lastc = c; lastcirPoint = s.Point3; //debugPoints.Add(new ControlLine(startPoint, s.Point1)); //debugPoints.Add(new ControlLine(s.Point3, s.Point2)); continue; } if (element is PathShape.EllipticalArcTo) { PathShape.EllipticalArcTo c = element as PathShape.EllipticalArcTo; ArcSegment s = new ArcSegment(); if (isRelative) { s.Point = lastPoint + new Vector(c.X, c.Y); } else { s.Point = new Point(c.X, c.Y); } s.Size = new Size(c.RX, c.RY); s.RotationAngle = c.AxisRotation; s.SweepDirection = SweepDirection.Counterclockwise; if (c.Clockwise) { s.SweepDirection = SweepDirection.Clockwise; } s.IsLargeArc = c.LargeArc; lastPoint = s.Point; p.Segments.Add(s); continue; } } /* * if (r.Transform != null) * path.Transform = r.Transform; */ grp.Children.Add(NewDrawingItem(shape, path)); //} } } if (debugPoints != null) { foreach (ControlLine line in debugPoints) { grp.Children.Add(line.Draw()); } } return(grp); }