From a20b8407a2aff4d17aeff99e4ffd3d4263d12298 Mon Sep 17 00:00:00 2001 From: the_fiddler Date: Tue, 24 Jun 2008 20:35:37 +0000 Subject: [PATCH] Fixed clipping issues with font layout. Improved glyph loading speed. Fixed text measurement. --- Source/Utilities/Fonts/Glyph.cs | 26 +++++++------------ Source/Utilities/Fonts/TextPrinter.cs | 2 +- Source/Utilities/Fonts/TextureFont.cs | 37 ++++++++++++++++----------- 3 files changed, 32 insertions(+), 33 deletions(-) diff --git a/Source/Utilities/Fonts/Glyph.cs b/Source/Utilities/Fonts/Glyph.cs index ee516228..c386d739 100644 --- a/Source/Utilities/Fonts/Glyph.cs +++ b/Source/Utilities/Fonts/Glyph.cs @@ -20,8 +20,8 @@ namespace OpenTK.Graphics { char character; Font font; - int width; - static Bitmap bmp = new Bitmap(1, 1); + SizeF size; + //static Bitmap bmp = new Bitmap(1, 1); object obj = new object(); #region --- Constructors --- @@ -31,12 +31,13 @@ namespace OpenTK.Graphics /// /// The character to represent. /// The Font of the character. - public Glyph(char c, Font f) + public Glyph(char c, Font f, SizeF s) { if (f == null) throw new ArgumentNullException("f", "You must specify a valid font"); character = c; font = f; + size = s; } #endregion @@ -82,17 +83,7 @@ namespace OpenTK.Graphics { get { - if (width == 0) - { - lock (obj) - using (Graphics gfx = Graphics.FromImage(bmp)) - { - float w = gfx.MeasureString(Character.ToString(), font).Width; - width = (int)System.Math.Ceiling(w); - } - } - - return width; + return (int)System.Math.Ceiling(size.Width); } } @@ -103,7 +94,7 @@ namespace OpenTK.Graphics { get { - return font.Height; + return (int)System.Math.Ceiling(size.Height); } } @@ -118,12 +109,13 @@ namespace OpenTK.Graphics public override string ToString() { - return String.Format("'{0}', {1} {2}, {3} {4}", Character, Font.Name, font.Style, font.Size, font.Unit); + return String.Format("'{0}', {1} {2}, {3} {4}, ({5}, {6})", Character, Font.Name, font.Style, font.Size, font.Unit, Width, Height); } public override int GetHashCode() { - return character.GetHashCode() ^ font.Style.GetHashCode() ^ font.Size.GetHashCode() ^ font.Unit.GetHashCode(); + //return character.GetHashCode() ^ font.Style.GetHashCode() ^ font.Size.GetHashCode() ^ font.Unit.GetHashCode(); + return character.GetHashCode() ^ font.GetHashCode() ^ size.GetHashCode(); } #region IEquatable Members diff --git a/Source/Utilities/Fonts/TextPrinter.cs b/Source/Utilities/Fonts/TextPrinter.cs index 22964c74..804511ff 100644 --- a/Source/Utilities/Fonts/TextPrinter.cs +++ b/Source/Utilities/Fonts/TextPrinter.cs @@ -211,7 +211,7 @@ namespace OpenTK.Graphics font.MeasureText(text, SizeF.Empty, null, ranges); int current = 0; - //foreach (char c in text) + foreach (RectangleF range in ranges) { char c = text[current++]; diff --git a/Source/Utilities/Fonts/TextureFont.cs b/Source/Utilities/Fonts/TextureFont.cs index e561d629..99cba1ba 100644 --- a/Source/Utilities/Fonts/TextureFont.cs +++ b/Source/Utilities/Fonts/TextureFont.cs @@ -177,7 +177,7 @@ namespace OpenTK.Graphics #region public float Width /// - /// Gets a float indicating the default line spacing of this font. + /// Gets a float indicating the default size of this font, in points. /// public float Width { @@ -321,9 +321,15 @@ namespace OpenTK.Graphics if (format == null) format = default_string_format; + if (ranges != null) + ranges.Clear(); + IntPtr[] regions = new IntPtr[GdiPlus.MaxMeasurableCharacterRanges]; CharacterRange[] characterRanges = new CharacterRange[GdiPlus.MaxMeasurableCharacterRanges]; + PointF origin = PointF.Empty; + SizeF size = SizeF.Empty; + RectangleF rect = new RectangleF(); for (int i = 0; i < text.Length; i += GdiPlus.MaxMeasurableCharacterRanges) { int num_characters = text.Length - i > GdiPlus.MaxMeasurableCharacterRanges ? GdiPlus.MaxMeasurableCharacterRanges : text.Length - i; @@ -355,19 +361,21 @@ namespace OpenTK.Graphics for (int j = 0; j < num_characters; j++) { - status = GdiPlus.GetRegionBounds(regions[j], new HandleRef(gfx, GdiPlus.GetNativeGraphics(gfx)), ref bounding_box); + status = GdiPlus.GetRegionBounds(regions[j], new HandleRef(gfx, GdiPlus.GetNativeGraphics(gfx)), ref rect); + + if (i == 0 && j == 0) + origin = rect.Location; if (ranges != null) - ranges.Add(bounding_box); + ranges.Add(rect); status = GdiPlus.DeleteRegion(regions[j]); } - bounding_box.Size = new SizeF(bounding_box.X + bounding_box.Width, bounding_box.Y + bounding_box.Height); - bounding_box.Location = PointF.Empty; + bounding_box = RectangleF.Union(bounding_box, rect); } - - return bounding_box; + + return new RectangleF(origin.X, origin.Y, bounding_box.Width, bounding_box.Height); } #endregion @@ -403,20 +411,18 @@ namespace OpenTK.Graphics #endregion - #region private void LoadGlyph(char c, out Box2 rectangle) + #region private void LoadGlyph(char c, out RectangleF rectangle) - /// - /// Adds a glyph to the texture packer. - /// - /// The character of the glyph. - /// An OpenTK.Math.Box2 that will hold the buffer for this glyph. + // Adds the specified caharacter to the texture packer. private void LoadGlyph(char c, out RectangleF rectangle) { if (pack == null) PrepareTexturePacker(); - Glyph g = new Glyph(c, font); - Rectangle rect = new Rectangle(); + RectangleF glyph_rect = MeasureText(c.ToString(), SizeF.Empty, StringFormat.GenericDefault); + SizeF glyph_size = new SizeF(glyph_rect.Right, glyph_rect.Bottom); // We need to do this, since the origin might not be (0, 0) + Glyph g = new Glyph(c, font, glyph_size); + Rectangle rect; try { @@ -431,6 +437,7 @@ namespace OpenTK.Graphics GL.BindTexture(TextureTarget.Texture2D, texture); + //gfx.TextRenderingHint = TextRenderingHint.AntiAlias; gfx.Clear(System.Drawing.Color.Transparent); gfx.DrawString(g.Character.ToString(), g.Font, System.Drawing.Brushes.White, 0.0f, 0.0f);