add method to retrieve single glyph bounds from truetype

this improves performance since we only need to load a single rectangle rather than the entire glyphs array including all points.
This commit is contained in:
Eliot Jones
2020-01-06 14:43:51 +00:00
parent 09c72a2fb2
commit fc9c1b6ff5
2 changed files with 38 additions and 11 deletions

View File

@@ -52,6 +52,39 @@
glyphs = new Lazy<IReadOnlyList<IGlyphDescription>>(ReadGlyphs); glyphs = new Lazy<IReadOnlyList<IGlyphDescription>>(ReadGlyphs);
} }
public bool TryGetGlyphBounds(int glyphIndex, out PdfRectangle bounds)
{
bounds = default(PdfRectangle);
if (glyphIndex < 0 || glyphIndex >= glyphOffsets.Count - 1)
{
return false;
}
var offset = glyphOffsets[glyphIndex];
var nextOffset = glyphOffsets[glyphIndex + 1];
if (nextOffset <= offset)
{
bounds = new PdfRectangle(0, 0, 0, 0);
return true;
}
tableBytes.Seek(offset);
// ReSharper disable once UnusedVariable
var contourCount = tableBytes.ReadSignedShort();
var minX = tableBytes.ReadSignedShort();
var minY = tableBytes.ReadSignedShort();
var maxX = tableBytes.ReadSignedShort();
var maxY = tableBytes.ReadSignedShort();
bounds = new PdfRectangle(minX, minY, maxX, maxY);
return true;
}
public static GlyphDataTable Load(TrueTypeDataBytes data, TrueTypeHeaderTable table, TableRegister.Builder tableRegister) public static GlyphDataTable Load(TrueTypeDataBytes data, TrueTypeHeaderTable table, TableRegister.Builder tableRegister)
{ {
data.Seek(table.Offset); data.Seek(table.Offset);
@@ -81,7 +114,7 @@
for (var i = 0; i < glyphCount; i++) for (var i = 0; i < glyphCount; i++)
{ {
if (offsets[i] == offsets[i + 1]) if (offsets[i + 1] <= offsets[i])
{ {
// empty glyph // empty glyph
result[i] = emptyGlyph; result[i] = emptyGlyph;

View File

@@ -113,21 +113,15 @@
return false; return false;
} }
var glyph = TableRegister.GlyphTable.Glyphs[index]; if (!TableRegister.GlyphTable.TryGetGlyphBounds(index, out boundingBox))
if (glyph?.Bounds == null)
{ {
return false; return false;
} }
if (glyph.IsEmpty && TryGetBoundingAdvancedWidthByIndex(index, out var advanceWidth)) if (boundingBox.Width.Equals(0) && TryGetBoundingAdvancedWidthByIndex(index, out var advanceWidth))
{ {
boundingBox = new PdfRectangle(0, 0, advanceWidth, 0); boundingBox = new PdfRectangle(0, 0, advanceWidth, 0);
} }
else
{
boundingBox = glyph.Bounds;
}
return true; return true;
} }