Fixed clipping issues with font layout.

Improved glyph loading speed.
Fixed text measurement.
This commit is contained in:
the_fiddler 2008-06-24 20:35:37 +00:00
parent 922d9ae3ff
commit 856551e212
3 changed files with 32 additions and 33 deletions

View file

@ -20,8 +20,8 @@ namespace OpenTK.Graphics
{ {
char character; char character;
Font font; Font font;
int width; SizeF size;
static Bitmap bmp = new Bitmap(1, 1); //static Bitmap bmp = new Bitmap(1, 1);
object obj = new object(); object obj = new object();
#region --- Constructors --- #region --- Constructors ---
@ -31,12 +31,13 @@ namespace OpenTK.Graphics
/// </summary> /// </summary>
/// <param name="c">The character to represent.</param> /// <param name="c">The character to represent.</param>
/// <param name="f">The Font of the character.</param> /// <param name="f">The Font of the character.</param>
public Glyph(char c, Font f) public Glyph(char c, Font f, SizeF s)
{ {
if (f == null) if (f == null)
throw new ArgumentNullException("f", "You must specify a valid font"); throw new ArgumentNullException("f", "You must specify a valid font");
character = c; character = c;
font = f; font = f;
size = s;
} }
#endregion #endregion
@ -82,17 +83,7 @@ namespace OpenTK.Graphics
{ {
get get
{ {
if (width == 0) return (int)System.Math.Ceiling(size.Width);
{
lock (obj)
using (Graphics gfx = Graphics.FromImage(bmp))
{
float w = gfx.MeasureString(Character.ToString(), font).Width;
width = (int)System.Math.Ceiling(w);
}
}
return width;
} }
} }
@ -103,7 +94,7 @@ namespace OpenTK.Graphics
{ {
get get
{ {
return font.Height; return (int)System.Math.Ceiling(size.Height);
} }
} }
@ -118,12 +109,13 @@ namespace OpenTK.Graphics
public override string ToString() 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() 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<Glyph> Members #region IEquatable<Glyph> Members

View file

@ -211,7 +211,7 @@ namespace OpenTK.Graphics
font.MeasureText(text, SizeF.Empty, null, ranges); font.MeasureText(text, SizeF.Empty, null, ranges);
int current = 0; int current = 0;
//foreach (char c in text)
foreach (RectangleF range in ranges) foreach (RectangleF range in ranges)
{ {
char c = text[current++]; char c = text[current++];

View file

@ -177,7 +177,7 @@ namespace OpenTK.Graphics
#region public float Width #region public float Width
/// <summary> /// <summary>
/// Gets a float indicating the default line spacing of this font. /// Gets a float indicating the default size of this font, in points.
/// </summary> /// </summary>
public float Width public float Width
{ {
@ -321,9 +321,15 @@ namespace OpenTK.Graphics
if (format == null) if (format == null)
format = default_string_format; format = default_string_format;
if (ranges != null)
ranges.Clear();
IntPtr[] regions = new IntPtr[GdiPlus.MaxMeasurableCharacterRanges]; IntPtr[] regions = new IntPtr[GdiPlus.MaxMeasurableCharacterRanges];
CharacterRange[] characterRanges = new CharacterRange[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) for (int i = 0; i < text.Length; i += GdiPlus.MaxMeasurableCharacterRanges)
{ {
int num_characters = text.Length - i > GdiPlus.MaxMeasurableCharacterRanges ? GdiPlus.MaxMeasurableCharacterRanges : text.Length - i; 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++) 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) if (ranges != null)
ranges.Add(bounding_box); ranges.Add(rect);
status = GdiPlus.DeleteRegion(regions[j]); status = GdiPlus.DeleteRegion(regions[j]);
} }
bounding_box.Size = new SizeF(bounding_box.X + bounding_box.Width, bounding_box.Y + bounding_box.Height); bounding_box = RectangleF.Union(bounding_box, rect);
bounding_box.Location = PointF.Empty;
} }
return bounding_box; return new RectangleF(origin.X, origin.Y, bounding_box.Width, bounding_box.Height);
} }
#endregion #endregion
@ -403,20 +411,18 @@ namespace OpenTK.Graphics
#endregion #endregion
#region private void LoadGlyph(char c, out Box2 rectangle) #region private void LoadGlyph(char c, out RectangleF rectangle)
/// <summary> // Adds the specified caharacter to the texture packer.
/// Adds a glyph to the texture packer.
/// </summary>
/// <param name="c">The character of the glyph.</param>
/// <param name="rectangle">An OpenTK.Math.Box2 that will hold the buffer for this glyph.</param>
private void LoadGlyph(char c, out RectangleF rectangle) private void LoadGlyph(char c, out RectangleF rectangle)
{ {
if (pack == null) if (pack == null)
PrepareTexturePacker(); PrepareTexturePacker();
Glyph g = new Glyph(c, font); RectangleF glyph_rect = MeasureText(c.ToString(), SizeF.Empty, StringFormat.GenericDefault);
Rectangle rect = new Rectangle(); 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 try
{ {
@ -431,6 +437,7 @@ namespace OpenTK.Graphics
GL.BindTexture(TextureTarget.Texture2D, texture); GL.BindTexture(TextureTarget.Texture2D, texture);
//gfx.TextRenderingHint = TextRenderingHint.AntiAlias;
gfx.Clear(System.Drawing.Color.Transparent); gfx.Clear(System.Drawing.Color.Transparent);
gfx.DrawString(g.Character.ToString(), g.Font, System.Drawing.Brushes.White, 0.0f, 0.0f); gfx.DrawString(g.Character.ToString(), g.Font, System.Drawing.Brushes.White, 0.0f, 0.0f);