Renamed MeasureCharacterRanges to MeasureText.
Sped up MeasureText. Added MeasureText overloads. Obsoleted MeasureString function.
This commit is contained in:
parent
26645b1cee
commit
f2ac359999
1 changed files with 89 additions and 33 deletions
|
@ -33,15 +33,17 @@ namespace OpenTK.Graphics
|
||||||
static int texture;
|
static int texture;
|
||||||
static TexturePacker<Glyph> pack;
|
static TexturePacker<Glyph> pack;
|
||||||
static int texture_width, texture_height;
|
static int texture_width, texture_height;
|
||||||
|
static StringFormat default_string_format = StringFormat.GenericTypographic;
|
||||||
|
static SizeF maximum_graphics_size;
|
||||||
|
|
||||||
int[] data = new int[256]; // Used to upload glyph buffer to the OpenGL texture.
|
int[] data = new int[256]; // Used to upload the glyph buffer to the OpenGL texture.
|
||||||
|
|
||||||
object upload_lock = new object();
|
object upload_lock = new object();
|
||||||
|
|
||||||
#region --- Constructor ---
|
#region --- Constructor ---
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Constructs a new TextureFont object, using the specified System.Drawing.Font.
|
/// Constructs a new TextureFont, using the specified System.Drawing.Font.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="font">The System.Drawing.Font to use.</param>
|
/// <param name="font">The System.Drawing.Font to use.</param>
|
||||||
public TextureFont(Font font)
|
public TextureFont(Font font)
|
||||||
|
@ -53,6 +55,7 @@ namespace OpenTK.Graphics
|
||||||
|
|
||||||
bmp = new Bitmap(font.Height * 2, font.Height * 2);
|
bmp = new Bitmap(font.Height * 2, font.Height * 2);
|
||||||
gfx = Graphics.FromImage(bmp);
|
gfx = Graphics.FromImage(bmp);
|
||||||
|
maximum_graphics_size = gfx.ClipBounds.Size;
|
||||||
|
|
||||||
// Adjust font rendering mode. Small sizes look blurry without gridfitting, so turn
|
// Adjust font rendering mode. Small sizes look blurry without gridfitting, so turn
|
||||||
// that on. Increasing contrast also seems to help.
|
// that on. Increasing contrast also seems to help.
|
||||||
|
@ -68,6 +71,25 @@ namespace OpenTK.Graphics
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Constructs a new TextureFont, using the specified parameters.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="font">The System.Drawing.FontFamily to use for the typeface.</param>
|
||||||
|
/// <param name="emSize">The em size to use for the typeface.</param>
|
||||||
|
public TextureFont(FontFamily family, float emSize)
|
||||||
|
: this(new Font(family, emSize))
|
||||||
|
{ }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Constructs a new TextureFont, using the specified parameters.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="font">The System.Drawing.FontFamily to use for the typeface.</param>
|
||||||
|
/// <param name="emSize">The em size to use for the typeface.</param>
|
||||||
|
/// <param name="family">The style to use for the typeface.</param>
|
||||||
|
public TextureFont(FontFamily family, float emSize, FontStyle style)
|
||||||
|
: this(new Font(family, emSize, style))
|
||||||
|
{ }
|
||||||
|
|
||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
#region --- Public Methods ---
|
#region --- Public Methods ---
|
||||||
|
@ -82,10 +104,18 @@ namespace OpenTK.Graphics
|
||||||
{
|
{
|
||||||
RectangleF rect = new RectangleF();
|
RectangleF rect = new RectangleF();
|
||||||
foreach (char c in glyphs)
|
foreach (char c in glyphs)
|
||||||
|
{
|
||||||
|
try
|
||||||
{
|
{
|
||||||
if (!loaded_glyphs.ContainsKey(c))
|
if (!loaded_glyphs.ContainsKey(c))
|
||||||
LoadGlyph(c, out rect);
|
LoadGlyph(c, out rect);
|
||||||
}
|
}
|
||||||
|
catch (Exception e)
|
||||||
|
{
|
||||||
|
Debug.Print(e.ToString());
|
||||||
|
throw;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#endregion
|
#endregion
|
||||||
|
@ -165,6 +195,7 @@ namespace OpenTK.Graphics
|
||||||
/// <param name="width">The measured width.</param>
|
/// <param name="width">The measured width.</param>
|
||||||
/// <param name="height">The measured height.</param>
|
/// <param name="height">The measured height.</param>
|
||||||
/// <param name="accountForOverhangs">If true, adds space to account for glyph overhangs. Set to true if you wish to measure a complete string. Set to false if you wish to perform layout on adjacent strings.</param>
|
/// <param name="accountForOverhangs">If true, adds space to account for glyph overhangs. Set to true if you wish to measure a complete string. Set to false if you wish to perform layout on adjacent strings.</param>
|
||||||
|
[Obsolete("Returns invalid results - use MeasureText() instead")]
|
||||||
public void MeasureString(string str, out float width, out float height, bool accountForOverhangs)
|
public void MeasureString(string str, out float width, out float height, bool accountForOverhangs)
|
||||||
{
|
{
|
||||||
System.Drawing.StringFormat format = accountForOverhangs ? System.Drawing.StringFormat.GenericDefault : System.Drawing.StringFormat.GenericTypographic;
|
System.Drawing.StringFormat format = accountForOverhangs ? System.Drawing.StringFormat.GenericDefault : System.Drawing.StringFormat.GenericTypographic;
|
||||||
|
@ -212,6 +243,7 @@ namespace OpenTK.Graphics
|
||||||
/// <param name="width">The measured width.</param>
|
/// <param name="width">The measured width.</param>
|
||||||
/// <param name="height">The measured height.</param>
|
/// <param name="height">The measured height.</param>
|
||||||
/// <seealso cref="public void MeasureString(string str, out float width, out float height, bool accountForOverhangs)"/>
|
/// <seealso cref="public void MeasureString(string str, out float width, out float height, bool accountForOverhangs)"/>
|
||||||
|
[Obsolete("Returns invalid results - use MeasureText() instead")]
|
||||||
public void MeasureString(string str, out float width, out float height)
|
public void MeasureString(string str, out float width, out float height)
|
||||||
{
|
{
|
||||||
MeasureString(str, out width, out height, true);
|
MeasureString(str, out width, out height, true);
|
||||||
|
@ -219,56 +251,75 @@ namespace OpenTK.Graphics
|
||||||
|
|
||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
#region public void MeasureCharacterRanges(string text, ref ICollection<RectangleF> ranges)
|
#region public RectangleF MeasureText(string text)
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Measures the individual character positions for the specified string.
|
/// Calculates size information for the specified text.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="text">The string to measure.</param>
|
/// <param name="text">The string to measure.</param>
|
||||||
/// <param name="ranges">An ICollection of RectangleF structures, containing the positions of individual characters.</param>
|
/// <returns>A RectangleF containing the bounding box for the specified text.</returns>
|
||||||
public void MeasureCharacterRanges(string text, ref ICollection<RectangleF> ranges)
|
public RectangleF MeasureText(string text)
|
||||||
{
|
{
|
||||||
MeasureCharacterRanges(text, false, ref ranges);
|
return MeasureText(text, SizeF.Empty, default_string_format, null);
|
||||||
}
|
}
|
||||||
|
|
||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
#region public void MeasureCharacterRanges(string text, bool accountForOverhangs, ref ICollection<RectangleF> ranges)
|
#region public RectangleF MeasureText(string text, SizeF bounds)
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Measures the individual character positions for the specified string.
|
/// Calculates size information for the specified text.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="text">The string to measure.</param>
|
/// <param name="text">The string to measure.</param>
|
||||||
/// <param name="accountForOverhangs">If true, adds space to account for glyph overhangs. Set to true if you wish to measure a complete string. Set to false if you wish to perform layout on adjacent strings.</param>
|
/// <param name="bounds">A SizeF structure containing the maximum desired width and height of the text. Default is SizeF.Empty.</param>
|
||||||
/// <param name="ranges">An ICollection of RectangleF structures, containing the positions of individual characters.</param>
|
/// <returns>A RectangleF containing the bounding box for the specified text.</returns>
|
||||||
public void MeasureCharacterRanges(string text, bool accountForOverhangs, ref ICollection<RectangleF> ranges)
|
public RectangleF MeasureText(string text, SizeF bounds)
|
||||||
{
|
{
|
||||||
System.Drawing.StringFormat format = accountForOverhangs ? System.Drawing.StringFormat.GenericDefault : System.Drawing.StringFormat.GenericTypographic;
|
return MeasureText(text, bounds, default_string_format, null);
|
||||||
RectangleF rect = new RectangleF(0, 0, gfx.ClipBounds.Width, gfx.ClipBounds.Height);
|
|
||||||
MeasureCharacterRanges(text, ref rect, format, ref ranges);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
|
#region public RectangleF MeasureText(string text, SizeF bounds, StringFormat format)
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Calculates size information for the specified text.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="text">The string to measure.</param>
|
||||||
|
/// <param name="bounds">A SizeF structure containing the maximum desired width and height of the text. Pass SizeF.Empty to disable wrapping calculations. A width or height of 0 disables the relevant calculation.</param>
|
||||||
|
/// <param name="format">A StringFormat object which specifies the measurement format of the string. Pass null to use the default StringFormat (StringFormat.GenericTypographic).</param>
|
||||||
|
/// <returns>A RectangleF containing the bounding box for the specified text.</returns>
|
||||||
|
public RectangleF MeasureText(string text, SizeF bounds, StringFormat format)
|
||||||
|
{
|
||||||
|
return MeasureText(text, bounds, format, null);
|
||||||
|
}
|
||||||
|
|
||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
#region --- Private Methods ---
|
#region public RectangleF MeasureText(string text, SizeF bounds, StringFormat format, IList<RectangleF> ranges)
|
||||||
|
|
||||||
#region void MeasureCharacterRanges(string text, ref RectangleF layoutRect, StringFormat format, ref ICollection<RectangleF> ranges)
|
/// <summary>
|
||||||
|
/// Calculates size information for the specified text.
|
||||||
void MeasureCharacterRanges(string text, ref RectangleF layoutRect, StringFormat format, ref ICollection<RectangleF> ranges)
|
/// </summary>
|
||||||
|
/// <param name="text">The string to measure.</param>
|
||||||
|
/// <param name="bounds">A SizeF structure containing the maximum desired width and height of the text. Pass SizeF.Empty to disable wrapping calculations. A width or height of 0 disables the relevant calculation.</param>
|
||||||
|
/// <param name="format">A StringFormat object which specifies the measurement format of the string. Pass null to use the default StringFormat (StringFormat.GenericTypographic).</param>
|
||||||
|
/// <param name="ranges">Fills the specified IList of RectangleF structures with position information for individual characters. If this argument is null, these calculations are skipped.</param>
|
||||||
|
/// <returns>A RectangleF containing the bounding box for the specified text.</returns>
|
||||||
|
public RectangleF MeasureText(string text, SizeF bounds, StringFormat format, IList<RectangleF> ranges)
|
||||||
{
|
{
|
||||||
ranges.Clear(); // Hopefully this doesn't trim the collection.
|
|
||||||
|
|
||||||
//GPRECTF rect = new GPRECTF(layoutRect);
|
|
||||||
//rect = new GPRECTF(0, 0, 256, 256);
|
|
||||||
int status = 0;
|
int status = 0;
|
||||||
|
|
||||||
if (String.IsNullOrEmpty(text))
|
RectangleF bounding_box = new RectangleF();
|
||||||
return;
|
|
||||||
|
|
||||||
if (font == null) throw new ArgumentNullException("font");
|
if (String.IsNullOrEmpty(text))
|
||||||
if (format == null) throw new ArgumentNullException("format");
|
return RectangleF.Empty;
|
||||||
|
|
||||||
|
if (bounds == SizeF.Empty)
|
||||||
|
bounds = maximum_graphics_size;
|
||||||
|
|
||||||
|
if (format == null)
|
||||||
|
format = default_string_format;
|
||||||
|
|
||||||
IntPtr[] regions = new IntPtr[GdiPlus.MaxMeasurableCharacterRanges];
|
IntPtr[] regions = new IntPtr[GdiPlus.MaxMeasurableCharacterRanges];
|
||||||
CharacterRange[] characterRanges = new CharacterRange[GdiPlus.MaxMeasurableCharacterRanges];
|
CharacterRange[] characterRanges = new CharacterRange[GdiPlus.MaxMeasurableCharacterRanges];
|
||||||
|
@ -295,6 +346,7 @@ namespace OpenTK.Graphics
|
||||||
IntPtr native_graphics = GdiPlus.GetNativeGraphics(gfx);
|
IntPtr native_graphics = GdiPlus.GetNativeGraphics(gfx);
|
||||||
IntPtr native_font = GdiPlus.GetNativeFont(font);
|
IntPtr native_font = GdiPlus.GetNativeFont(font);
|
||||||
IntPtr native_string_format = GdiPlus.GetNativeStringFormat(format);
|
IntPtr native_string_format = GdiPlus.GetNativeStringFormat(format);
|
||||||
|
RectangleF layoutRect = new RectangleF(PointF.Empty, bounds);
|
||||||
|
|
||||||
status = GdiPlus.MeasureCharacterRanges(new HandleRef(gfx, native_graphics), text, text.Length,
|
status = GdiPlus.MeasureCharacterRanges(new HandleRef(gfx, native_graphics), text, text.Length,
|
||||||
new HandleRef(font, native_font), ref layoutRect,
|
new HandleRef(font, native_font), ref layoutRect,
|
||||||
|
@ -303,15 +355,19 @@ namespace OpenTK.Graphics
|
||||||
|
|
||||||
for (int j = 0; j < num_characters; j++)
|
for (int j = 0; j < num_characters; j++)
|
||||||
{
|
{
|
||||||
RectangleF rect = new RectangleF();
|
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);
|
|
||||||
|
|
||||||
ranges.Add(rect);
|
if (ranges != null)
|
||||||
|
ranges.Add(bounding_box);
|
||||||
|
|
||||||
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.Location = PointF.Empty;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return bounding_box;
|
||||||
}
|
}
|
||||||
|
|
||||||
#endregion
|
#endregion
|
||||||
|
|
Loading…
Reference in a new issue