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

@@ -25,7 +25,7 @@
private readonly Lazy<IReadOnlyList<IGlyphDescription>> glyphs;
public IReadOnlyList<IGlyphDescription> Glyphs => glyphs.Value;
public GlyphDataTable(TrueTypeHeaderTable directoryTable, IReadOnlyList<uint> glyphOffsets,
PdfRectangle maxGlyphBounds,
TrueTypeDataBytes tableBytes)
@@ -52,6 +52,39 @@
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)
{
data.Seek(table.Offset);
@@ -81,7 +114,7 @@
for (var i = 0; i < glyphCount; i++)
{
if (offsets[i] == offsets[i + 1])
if (offsets[i + 1] <= offsets[i])
{
// empty glyph
result[i] = emptyGlyph;

View File

@@ -112,22 +112,16 @@
{
return false;
}
var glyph = TableRegister.GlyphTable.Glyphs[index];
if (glyph?.Bounds == null)
if (!TableRegister.GlyphTable.TryGetGlyphBounds(index, out boundingBox))
{
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);
}
else
{
boundingBox = glyph.Bounds;
}
return true;
}