#20 support retrieval of named system fonts for truetype on windows

This commit is contained in:
Eliot Jones
2018-12-22 18:28:49 +00:00
parent d8b5f00fa0
commit ed3792c950
4 changed files with 47 additions and 12 deletions

View File

@@ -1,6 +1,7 @@
namespace UglyToad.PdfPig.Fonts.Parser.Handlers
{
using System;
using SystemFonts;
using Cmap;
using Encodings;
using Exceptions;
@@ -18,18 +19,20 @@
internal class TrueTypeFontHandler : IFontHandler
{
private readonly ILog log;
private readonly IPdfTokenScanner pdfScanner;
private readonly IFilterProvider filterProvider;
private readonly CMapCache cMapCache;
private readonly FontDescriptorFactory fontDescriptorFactory;
private readonly TrueTypeFontParser trueTypeFontParser;
private readonly IEncodingReader encodingReader;
private readonly IPdfTokenScanner pdfScanner;
private readonly ISystemFontFinder systemFontFinder;
public TrueTypeFontHandler(ILog log, IPdfTokenScanner pdfScanner, IFilterProvider filterProvider,
CMapCache cMapCache,
FontDescriptorFactory fontDescriptorFactory,
TrueTypeFontParser trueTypeFontParser,
IEncodingReader encodingReader)
IEncodingReader encodingReader,
ISystemFontFinder systemFontFinder)
{
this.log = log;
this.filterProvider = filterProvider;
@@ -37,6 +40,7 @@
this.fontDescriptorFactory = fontDescriptorFactory;
this.trueTypeFontParser = trueTypeFontParser;
this.encodingReader = encodingReader;
this.systemFontFinder = systemFontFinder;
this.pdfScanner = pdfScanner;
}
@@ -73,8 +77,16 @@
private TrueTypeFontProgram ParseTrueTypeFont(FontDescriptor descriptor)
{
if (descriptor?.FontFile == null)
if (descriptor.FontFile == null)
{
try
{
return systemFontFinder.GetTrueTypeFont(descriptor.FontName.Data);
}
catch (Exception ex)
{
log.Error($"Failed finding system font by name: {descriptor.FontName}.", ex);
}
// TODO: check if this font is present on the host OS. See: FileSystemFontProvider.java
return null;
}

View File

@@ -0,0 +1,9 @@
using UglyToad.PdfPig.Fonts.TrueType;
namespace UglyToad.PdfPig.Fonts.SystemFonts
{
internal interface ISystemFontFinder
{
TrueTypeFontProgram GetTrueTypeFont(string name);
}
}

View File

@@ -9,12 +9,12 @@
using TrueType;
using TrueType.Parser;
internal class SystemFontFinder
internal class SystemFontFinder : ISystemFontFinder
{
private readonly TrueTypeFontParser trueTypeFontParser;
private readonly Lazy<IReadOnlyList<SystemFontRecord>> availableFonts;
private readonly Dictionary<string, IFont> cache = new Dictionary<string, IFont>();
private readonly Dictionary<string, TrueTypeFontProgram> cache = new Dictionary<string, TrueTypeFontProgram>(StringComparer.OrdinalIgnoreCase);
public SystemFontFinder(TrueTypeFontParser trueTypeFontParser)
{
@@ -42,6 +42,11 @@
public TrueTypeFontProgram GetTrueTypeFont(string name)
{
if (cache.TryGetValue(name, out var result))
{
return result;
}
foreach (var record in availableFonts.Value)
{
if (record.Type == SystemFontType.TrueType)
@@ -50,13 +55,21 @@
{
var input = new StreamInputBytes(fileStream);
var trueType = trueTypeFontParser.Parse(new TrueTypeDataBytes(input));
//TODO: cache.
var psName = trueType.TableRegister.NameTable?.GetPostscriptName() ?? trueType.Name;
if (!cache.ContainsKey(psName))
{
cache[psName] = trueType;
}
if (string.Equals(psName, name, StringComparison.OrdinalIgnoreCase))
{
return trueType;
}
}
}
else if (record.Type == SystemFontType.OpenType)
{
throw new NotImplementedException($"TODO: OpenType fonts. Found system font: {record.Path}.");
}
// TODO: OTF
}
return null;

View File

@@ -12,6 +12,7 @@
using Fonts.Parser;
using Fonts.Parser.Handlers;
using Fonts.Parser.Parts;
using Fonts.SystemFonts;
using Fonts.TrueType.Parser;
using Fonts.Type1.Parser;
using Graphics;
@@ -107,7 +108,7 @@
var fontFactory = new FontFactory(log, new Type0FontHandler(cidFontFactory,
cMapCache,
filterProvider, pdfScanner),
new TrueTypeFontHandler(log, pdfScanner, filterProvider, cMapCache, fontDescriptorFactory, trueTypeFontParser, encodingReader),
new TrueTypeFontHandler(log, pdfScanner, filterProvider, cMapCache, fontDescriptorFactory, trueTypeFontParser, encodingReader, new SystemFontFinder(new TrueTypeFontParser())),
new Type1FontHandler(pdfScanner, cMapCache, filterProvider, fontDescriptorFactory, encodingReader,
new Type1FontParser(new Type1EncryptedPortionParser()),
new CompactFontFormatParser(new CompactFontFormatIndividualFontParser(compactFontFormatIndexReader, new CompactFontFormatTopLevelDictionaryReader(),