improve caching for system font finder and fix issue with composite glyphs in truetype fonts

This commit is contained in:
Eliot Jones
2019-01-09 20:42:49 +00:00
parent b6a528a97d
commit d86c79da45
3 changed files with 73 additions and 18 deletions

View File

@@ -1,5 +1,8 @@
namespace UglyToad.PdfPig.Tests.Integration
{
//using System;
//using System.Diagnostics;
//using System.IO;
using Xunit;
/// <summary>
@@ -10,6 +13,27 @@
[Fact]
public void Tests()
{
//var files = Directory.GetFiles("C:\\git\\testdocs", "*.pdf");
//foreach (var file in files)
//{
// try
// {
// using (var document = PdfDocument.Open(file, new ParsingOptions{ UseLenientParsing = false}))
// {
// for (var i = 1; i <= document.NumberOfPages; i++)
// {
// var page = document.GetPage(i);
// var text = page.Text;
// Trace.WriteLine(text);
// }
// }
// }
// catch (Exception ex)
// {
// throw new InvalidOperationException($"Error parsing: {Path.GetFileName(file)}.", ex);
// }
//}
}
}
}

View File

@@ -13,8 +13,9 @@
{
private readonly TrueTypeFontParser trueTypeFontParser;
private readonly Lazy<IReadOnlyList<SystemFontRecord>> availableFonts;
private readonly Dictionary<string, TrueTypeFontProgram> cache = new Dictionary<string, TrueTypeFontProgram>(StringComparer.OrdinalIgnoreCase);
private readonly HashSet<string> readFiles = new HashSet<string>();
public SystemFontFinder(TrueTypeFontParser trueTypeFontParser)
{
@@ -52,26 +53,21 @@
return result;
}
var nameCandidates = availableFonts.Value.Where(x => Path.GetFileName(x.Path)?.StartsWith(name[0].ToString(), StringComparison.OrdinalIgnoreCase) == true);
foreach (var systemFontRecord in nameCandidates)
{
if (TryGetTrueTypeFont(name, systemFontRecord, out var font))
{
return font;
}
}
foreach (var record in availableFonts.Value)
{
if (record.Type == SystemFontType.TrueType)
if (TryGetTrueTypeFont(name, record, out var font))
{
using (var fileStream = File.OpenRead(record.Path))
{
var input = new StreamInputBytes(fileStream);
var trueType = trueTypeFontParser.Parse(new TrueTypeDataBytes(input));
var psName = trueType.TableRegister.NameTable?.GetPostscriptName() ?? trueType.Name;
if (!cache.ContainsKey(psName))
{
cache[psName] = trueType;
}
if (string.Equals(psName, name, StringComparison.OrdinalIgnoreCase))
{
return trueType;
}
}
return font;
}
// TODO: OTF
@@ -79,5 +75,38 @@
return null;
}
private bool TryGetTrueTypeFont(string name, SystemFontRecord record, out TrueTypeFontProgram font)
{
font = null;
if (record.Type == SystemFontType.TrueType)
{
if (readFiles.Contains(record.Path))
{
return false;
}
using (var fileStream = File.OpenRead(record.Path))
{
readFiles.Add(record.Path);
var input = new StreamInputBytes(fileStream);
var trueType = trueTypeFontParser.Parse(new TrueTypeDataBytes(input));
var psName = trueType.TableRegister.NameTable?.GetPostscriptName() ?? trueType.Name;
if (!cache.ContainsKey(psName))
{
cache[psName] = trueType;
}
if (string.Equals(psName, name, StringComparison.OrdinalIgnoreCase))
{
font = trueType;
return true;
}
}
}
return false;
}
}
}

View File

@@ -144,7 +144,9 @@
throw new InvalidOperationException($"The composite glyph required a contour at index {glyphIndex} but there was no simple or composite glyph at this location.");
}
var position = data.Position;
childGlyph = ReadCompositeGlyph(data, missingComposite, compositeLocations, glyphs, emptyGlyph);
data.Seek(position);
glyphs[glyphIndex] = childGlyph;
}