mirror of
https://github.com/UglyToad/PdfPig.git
synced 2025-08-20 09:00:07 +08:00
back-calculate first char if last char and widths present (#1081)
* back-calculate first char if last char and widths present when a truetype font has a last char and widths array in its font dictionary the first char can be calculated #644 * fix off by 1 in last char calculation
This commit is contained in:
parent
de3b6ac6f4
commit
016b754c5b
@ -49,13 +49,18 @@
|
|||||||
|
|
||||||
public IFont Generate(DictionaryToken dictionary)
|
public IFont Generate(DictionaryToken dictionary)
|
||||||
{
|
{
|
||||||
if (!dictionary.TryGetOptionalTokenDirect(NameToken.FirstChar, pdfScanner, out NumericToken? firstCharacterToken)
|
int? firstChar = null;
|
||||||
|
if (!dictionary.TryGetOptionalTokenDirect(NameToken.FirstChar,
|
||||||
|
pdfScanner,
|
||||||
|
out NumericToken? firstCharacterToken)
|
||||||
|| !dictionary.TryGet<IToken>(NameToken.FontDescriptor, pdfScanner, out _)
|
|| !dictionary.TryGet<IToken>(NameToken.FontDescriptor, pdfScanner, out _)
|
||||||
|| !dictionary.TryGet(NameToken.Widths, out IToken _))
|
|| !dictionary.TryGet(NameToken.Widths, out _))
|
||||||
{
|
{
|
||||||
|
var isStandard14 = true;
|
||||||
if (!dictionary.TryGetOptionalTokenDirect(NameToken.BaseFont, pdfScanner, out NameToken? baseFont))
|
if (!dictionary.TryGetOptionalTokenDirect(NameToken.BaseFont, pdfScanner, out NameToken? baseFont))
|
||||||
{
|
{
|
||||||
throw new InvalidFontFormatException($"The provided TrueType font dictionary did not contain a /FirstChar or a /BaseFont entry: {dictionary}.");
|
throw new InvalidFontFormatException(
|
||||||
|
$"The provided TrueType font dictionary did not contain a /FirstChar or a /BaseFont entry: {dictionary}.");
|
||||||
}
|
}
|
||||||
|
|
||||||
// Can use the AFM descriptor despite not being Type 1!
|
// Can use the AFM descriptor despite not being Type 1!
|
||||||
@ -63,37 +68,53 @@
|
|||||||
|
|
||||||
if (standard14Font is null)
|
if (standard14Font is null)
|
||||||
{
|
{
|
||||||
throw new InvalidFontFormatException($"The provided TrueType font dictionary did not have a /FirstChar and did not match a Standard 14 font: {dictionary}.");
|
if (dictionary.TryGet(NameToken.LastChar, pdfScanner, out NumericToken? lastCharToken)
|
||||||
|
&& dictionary.TryGet(NameToken.Widths, pdfScanner, out ArrayToken? widthsArrayLoc))
|
||||||
|
{
|
||||||
|
// If the widths array contains widths for characters 0 - 3 it will contain 4 entries but last char is 3.
|
||||||
|
firstChar = (lastCharToken.Int - widthsArrayLoc.Length) + 1;
|
||||||
|
isStandard14 = false;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
throw new InvalidFontFormatException(
|
||||||
|
$"The provided TrueType font dictionary did not have a /FirstChar and did not match a Standard 14 font: {dictionary}.");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
var fileSystemFont = systemFontFinder.GetTrueTypeFont(baseFont.Data);
|
if (isStandard14)
|
||||||
|
|
||||||
var thisEncoding = encodingReader.Read(dictionary);
|
|
||||||
|
|
||||||
if (thisEncoding is null)
|
|
||||||
{
|
{
|
||||||
thisEncoding = new AdobeFontMetricsEncoding(standard14Font);
|
var fileSystemFont = systemFontFinder.GetTrueTypeFont(baseFont.Data);
|
||||||
|
|
||||||
|
var thisEncoding = encodingReader.Read(dictionary);
|
||||||
|
|
||||||
|
if (thisEncoding is null)
|
||||||
|
{
|
||||||
|
thisEncoding = new AdobeFontMetricsEncoding(standard14Font);
|
||||||
|
}
|
||||||
|
|
||||||
|
double[]? widthsOverride = null;
|
||||||
|
|
||||||
|
if (dictionary.TryGet(NameToken.FirstChar, pdfScanner, out firstCharacterToken))
|
||||||
|
{
|
||||||
|
firstChar = firstCharacterToken.Int;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (dictionary.TryGet(NameToken.Widths, pdfScanner, out ArrayToken? widthsArray))
|
||||||
|
{
|
||||||
|
widthsOverride = widthsArray.Data.OfType<NumericToken>()
|
||||||
|
.Select(x => x.Double).ToArray();
|
||||||
|
}
|
||||||
|
|
||||||
|
return new TrueTypeStandard14FallbackSimpleFont(baseFont,
|
||||||
|
standard14Font!,
|
||||||
|
thisEncoding,
|
||||||
|
fileSystemFont,
|
||||||
|
new TrueTypeStandard14FallbackSimpleFont.MetricOverrides(firstChar, widthsOverride));
|
||||||
}
|
}
|
||||||
|
|
||||||
int? firstChar = null;
|
|
||||||
double[]? widthsOverride = null;
|
|
||||||
|
|
||||||
if (dictionary.TryGet(NameToken.FirstChar, pdfScanner, out firstCharacterToken))
|
|
||||||
{
|
|
||||||
firstChar = firstCharacterToken.Int;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (dictionary.TryGet(NameToken.Widths, pdfScanner, out ArrayToken? widthsArray))
|
|
||||||
{
|
|
||||||
widthsOverride = widthsArray.Data.OfType<NumericToken>()
|
|
||||||
.Select(x => x.Double).ToArray();
|
|
||||||
}
|
|
||||||
|
|
||||||
return new TrueTypeStandard14FallbackSimpleFont(baseFont, standard14Font, thisEncoding, fileSystemFont,
|
|
||||||
new TrueTypeStandard14FallbackSimpleFont.MetricOverrides(firstChar, widthsOverride));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
var firstCharacter = firstCharacterToken.Int;
|
var firstCharacter = firstChar ?? firstCharacterToken!.Int;
|
||||||
|
|
||||||
var widths = FontDictionaryAccessHelper.GetWidths(pdfScanner, dictionary);
|
var widths = FontDictionaryAccessHelper.GetWidths(pdfScanner, dictionary);
|
||||||
|
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user