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); }
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); }