From b044459fc1d1a370eb48e38c2e45dca714955db0 Mon Sep 17 00:00:00 2001 From: Tebjan Halm Date: Sat, 24 Dec 2011 04:53:56 +0100 Subject: [PATCH] * correct text alignment on base line * added precise MeasureString method --- Source/SvgRenderer.cs | 15 +++++++++++++++ Source/Text/SvgText.cs | 12 ++++++------ Source/Text/SvgTextAnchor.cs | 2 ++ 3 files changed, 23 insertions(+), 6 deletions(-) diff --git a/Source/SvgRenderer.cs b/Source/SvgRenderer.cs index 7af50e5..efe4187 100644 --- a/Source/SvgRenderer.cs +++ b/Source/SvgRenderer.cs @@ -132,5 +132,20 @@ namespace Svg { this._innerGraphics.Dispose(); } + + public SizeF MeasureString(string text, Font font) + { + var ff = font.FontFamily; + float lineSpace = ff.GetLineSpacing(font.Style); + float ascent = ff.GetCellAscent(font.Style); + float baseline = font.GetHeight(this._innerGraphics) * ascent / lineSpace; + + StringFormat format = StringFormat.GenericTypographic; + format.SetMeasurableCharacterRanges(new CharacterRange[]{new CharacterRange(0, text.Length)}); + Region[] r = this._innerGraphics.MeasureCharacterRanges(text, font, new Rectangle(0, 0, 1000, 1000), format); + RectangleF rect = r[0].GetBounds(this._innerGraphics); + + return new SizeF(rect.Width, baseline); + } } } \ No newline at end of file diff --git a/Source/Text/SvgText.cs b/Source/Text/SvgText.cs index e0be0c1..c860cf7 100644 --- a/Source/Text/SvgText.cs +++ b/Source/Text/SvgText.cs @@ -191,6 +191,7 @@ namespace Svg { GraphicsPath p = new GraphicsPath(); p.AddString(text, font.FontFamily, 0, font.Size, new PointF(0.0f, 0.0f), StringFormat.GenericTypographic); + p.Transform(renderer.Transform); return p.GetBounds(); } @@ -211,23 +212,22 @@ namespace Svg { fontSize = 1.0f; } - RectangleF stringBounds; + PointF location = PointF.Empty; Font font = new Font(this._fontFamily, fontSize, FontStyle.Regular, GraphicsUnit.Pixel); + SizeF stringBounds = _stringMeasure.MeasureString(this.Text, font); // Minus FontSize because the x/y coords mark the bottom left, not bottom top. switch (this.TextAnchor) { case SvgTextAnchor.Start: - location = new PointF(this.X.ToDeviceValue(this), this.Y.ToDeviceValue(this, true) - this._fontSize); + location = new PointF(this.X.ToDeviceValue(this), this.Y.ToDeviceValue(this, true) - stringBounds.Height); break; case SvgTextAnchor.Middle: - stringBounds = SvgText.MeasureString(_stringMeasure, this.Text, font); - location = new PointF(this.X.ToDeviceValue(this) - (stringBounds.Width / 2), this.Y.ToDeviceValue(this, true) - this._fontSize); + location = new PointF(this.X.ToDeviceValue(this) - (stringBounds.Width / 2), this.Y.ToDeviceValue(this, true) - stringBounds.Height); break; case SvgTextAnchor.End: - stringBounds = SvgText.MeasureString(_stringMeasure, this.Text, font); - location = new PointF(this.X.ToDeviceValue(this) - stringBounds.Width, this.Y.ToDeviceValue(this, true) - this._fontSize); + location = new PointF(this.X.ToDeviceValue(this) - stringBounds.Width, this.Y.ToDeviceValue(this, true) - stringBounds.Height); break; } diff --git a/Source/Text/SvgTextAnchor.cs b/Source/Text/SvgTextAnchor.cs index 55f7236..207bf95 100644 --- a/Source/Text/SvgTextAnchor.cs +++ b/Source/Text/SvgTextAnchor.cs @@ -2,12 +2,14 @@ using System.Collections.Generic; using System.Linq; using System.Text; +using System.ComponentModel; namespace Svg { /// /// Text anchor is used to align (start-, middle- or end-alignment) a string of text relative to a given point. /// + [TypeConverter(typeof(SvgTextAnchorConverter))] public enum SvgTextAnchor { /// -- GitLab