mirror of
https://github.com/Ryujinx/Opentk.git
synced 2024-12-26 04:45:38 +00:00
Remove exceptions from the typical path (significant speed increase).
This commit is contained in:
parent
a26b75f3af
commit
a868c4b4e8
|
@ -37,7 +37,7 @@ namespace OpenTK.Graphics.Text
|
||||||
|
|
||||||
IGlyphRasterizer rasterizer;
|
IGlyphRasterizer rasterizer;
|
||||||
List<GlyphSheet> sheets = new List<GlyphSheet>();
|
List<GlyphSheet> sheets = new List<GlyphSheet>();
|
||||||
Bitmap bmp = new Bitmap(256, 256);
|
Bitmap bmp = new Bitmap(32, 32);
|
||||||
|
|
||||||
Dictionary<Glyph, CachedGlyphInfo> cached_glyphs = new Dictionary<Glyph, CachedGlyphInfo>();
|
Dictionary<Glyph, CachedGlyphInfo> cached_glyphs = new Dictionary<Glyph, CachedGlyphInfo>();
|
||||||
|
|
||||||
|
@ -64,24 +64,19 @@ namespace OpenTK.Graphics.Text
|
||||||
|
|
||||||
using (Bitmap bmp = rasterizer.Rasterize(glyph))
|
using (Bitmap bmp = rasterizer.Rasterize(glyph))
|
||||||
{
|
{
|
||||||
|
Rectangle rect = new Rectangle(0, 0, bmp.Width, bmp.Height);
|
||||||
foreach (GlyphSheet sheet in sheets)
|
foreach (GlyphSheet sheet in sheets)
|
||||||
{
|
{
|
||||||
try
|
inserted = InsertGlyph(glyph, bmp, rect, sheet);
|
||||||
{
|
if (inserted)
|
||||||
InsertGlyph(glyph, bmp, sheet);
|
break;
|
||||||
inserted = true;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
catch (TexturePackerFullException)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!inserted)
|
if (!inserted)
|
||||||
{
|
{
|
||||||
GlyphSheet sheet = new GlyphSheet();
|
GlyphSheet sheet = new GlyphSheet();
|
||||||
sheets.Add(sheet);
|
sheets.Add(sheet);
|
||||||
InsertGlyph(glyph, bmp, sheet);
|
InsertGlyph(glyph, bmp, rect, sheet);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -103,14 +98,17 @@ namespace OpenTK.Graphics.Text
|
||||||
|
|
||||||
#region Private Members
|
#region Private Members
|
||||||
|
|
||||||
void InsertGlyph(Glyph glyph, Bitmap bmp, GlyphSheet sheet)
|
// Asks the packer for an empty space and writes the glyph there.
|
||||||
|
bool InsertGlyph(Glyph glyph, Bitmap bmp, Rectangle source, GlyphSheet sheet)
|
||||||
{
|
{
|
||||||
Rectangle source = new Rectangle(0, 0, bmp.Width, bmp.Height);
|
Rectangle target = new Rectangle();
|
||||||
Rectangle target = sheet.Packer.Add(source);
|
if (!sheet.Packer.TryAdd(source, out target))
|
||||||
|
return false;
|
||||||
|
|
||||||
sheet.Texture.WriteRegion(source, target, 0, bmp);
|
sheet.Texture.WriteRegion(source, target, 0, bmp);
|
||||||
|
|
||||||
cached_glyphs.Add(glyph, new CachedGlyphInfo(sheet.Texture, target));
|
cached_glyphs.Add(glyph, new CachedGlyphInfo(sheet.Texture, target));
|
||||||
|
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
#endregion
|
#endregion
|
||||||
|
|
|
@ -53,6 +53,64 @@ namespace OpenTK.Graphics.Text
|
||||||
|
|
||||||
#region --- Public Methods ---
|
#region --- Public Methods ---
|
||||||
|
|
||||||
|
#region public bool TryAdd(Rectangle boundingBox)
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Adds boundingBox to the GlyphPacker.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="boundingBox">The bounding box of the item to pack.</param>
|
||||||
|
/// <param name="packedRectangle">The System.Drawing.Rectangle that contains the position of the packed item.</param>
|
||||||
|
/// <returns>True, if the item was successfully packed; false if the item is too big for this packer..</returns>
|
||||||
|
/// <exception cref="InvalidOperationException">Occurs if the item is larger than the available TexturePacker area</exception>
|
||||||
|
/// <exception cref="TexturePackerFullException">Occurs if the item cannot fit in the remaining packer space.</exception>
|
||||||
|
public bool TryAdd(Rectangle boundingBox, out Rectangle packedRectangle)
|
||||||
|
{
|
||||||
|
if (!root.Rectangle.Contains(boundingBox))
|
||||||
|
{
|
||||||
|
packedRectangle = new Rectangle();
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Increase size so that the glyphs do not touch each other (to avoid rendering artifacts).
|
||||||
|
boundingBox.Width += 2;
|
||||||
|
boundingBox.Height += 2;
|
||||||
|
|
||||||
|
Node node = root.Insert(boundingBox);
|
||||||
|
|
||||||
|
// Tree is full and insertion failed:
|
||||||
|
if (node == null)
|
||||||
|
{
|
||||||
|
packedRectangle = new Rectangle();
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
packedRectangle = new Rectangle(node.Rectangle.X, node.Rectangle.Y, node.Rectangle.Width - 2, node.Rectangle.Height - 2);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
#region public Rectangle TryAdd(RectangleF boundingBox)
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Adds boundingBox to the GlyphPacker.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="boundingBox">The bounding box of the item to pack.</param>
|
||||||
|
/// <param name="packedRectangle">The System.Drawing.RectangleF that contains the position of the packed item.</param>
|
||||||
|
/// <returns>True, if the item was successfully packed; false if the item is too big for this packer..</returns>
|
||||||
|
/// <exception cref="InvalidOperationException">Occurs if the item is larger than the available TexturePacker area</exception>
|
||||||
|
/// <exception cref="TexturePackerFullException">Occurs if the item cannot fit in the remaining packer space.</exception>
|
||||||
|
public bool TryAdd(RectangleF boundingBox, out RectangleF packedRectangle)
|
||||||
|
{
|
||||||
|
Rectangle bbox = new Rectangle(
|
||||||
|
(int)boundingBox.X, (int)boundingBox.Y,
|
||||||
|
(int)(boundingBox.Width + 0.5f), (int)(boundingBox.Height + 0.5f));
|
||||||
|
|
||||||
|
return TryAdd(bbox, out packedRectangle);
|
||||||
|
}
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
|
||||||
#region public Rectangle Add(Rectangle boundingBox)
|
#region public Rectangle Add(Rectangle boundingBox)
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
@ -61,24 +119,13 @@ namespace OpenTK.Graphics.Text
|
||||||
/// <param name="boundingBox">The bounding box of the item to pack.</param>
|
/// <param name="boundingBox">The bounding box of the item to pack.</param>
|
||||||
/// <returns>A System.Drawing.Rectangle containing the coordinates of the packed item.</returns>
|
/// <returns>A System.Drawing.Rectangle containing the coordinates of the packed item.</returns>
|
||||||
/// <exception cref="InvalidOperationException">Occurs if the item is larger than the available TexturePacker area</exception>
|
/// <exception cref="InvalidOperationException">Occurs if the item is larger than the available TexturePacker area</exception>
|
||||||
/// <exception cref="ArgumentException">Occurs if the item already exists in the TexturePacker.</exception>
|
/// <exception cref="TexturePackerFullException">Occurs if the item cannot fit in the remaining packer space.</exception>
|
||||||
public Rectangle Add(Rectangle boundingBox)
|
public Rectangle Add(Rectangle boundingBox)
|
||||||
{
|
{
|
||||||
if (!root.Rectangle.Contains(boundingBox))
|
if (!TryAdd(boundingBox, out boundingBox))
|
||||||
throw new InvalidOperationException("The item is too large for this TexturePacker");
|
|
||||||
|
|
||||||
Node node;
|
|
||||||
// Increase size so that the glyphs do not touch each other (to avoid rendering artifacts).
|
|
||||||
boundingBox.Width += 2;
|
|
||||||
boundingBox.Height += 2;
|
|
||||||
node = root.Insert(boundingBox);
|
|
||||||
|
|
||||||
// Tree is full and insertion failed:
|
|
||||||
if (node == null)
|
|
||||||
throw new TexturePackerFullException();
|
throw new TexturePackerFullException();
|
||||||
|
|
||||||
return new Rectangle(node.Rectangle.X, node.Rectangle.Y, node.Rectangle.Width - 2, node.Rectangle.Height - 2);
|
return boundingBox;
|
||||||
//return node.Rectangle;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#endregion
|
#endregion
|
||||||
|
@ -115,22 +162,6 @@ namespace OpenTK.Graphics.Text
|
||||||
|
|
||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
#region public void ChangeSize(int new_width, int new_height)
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Changes the dimensions of the TexturePacker surface.
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="new_width">The new width of the TexturePacker surface.</param>
|
|
||||||
/// <param name="new_height">The new height of the TexturePacker surface.</param>
|
|
||||||
/// <remarks>Changing the size of the TexturePacker surface will implicitly call TexturePacker.Clear().</remarks>
|
|
||||||
/// <seealso cref="Clear"/>
|
|
||||||
public void ChangeSize(int new_width, int new_height)
|
|
||||||
{
|
|
||||||
throw new NotImplementedException();
|
|
||||||
}
|
|
||||||
|
|
||||||
#endregion
|
|
||||||
|
|
||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
#region Node
|
#region Node
|
||||||
|
|
Loading…
Reference in a new issue