fallbacks to true type font bounding boxes

This commit is contained in:
modest-as
2018-04-14 12:39:53 +01:00
parent fe3f627f9c
commit fcc0e06bef
7 changed files with 60 additions and 8 deletions

View File

@@ -83,7 +83,7 @@
Assert.Equal(theirLetter, myLetter); Assert.Equal(theirLetter, myLetter);
Assert.True(Math.Abs(theirX - myX) < 2); Assert.Equal(theirX, myX, new DecimalComparer(3m));
index++; index++;
} }

View File

@@ -60,7 +60,7 @@
Assert.Equal(709.2m, page.Letters[5].Rectangle.BottomLeft.Y, comparer); Assert.Equal(709.2m, page.Letters[5].Rectangle.BottomLeft.Y, comparer);
Assert.Equal(119.82m, page.Letters[5].Rectangle.TopRight.X, comparer); Assert.Equal(119.82m, page.Letters[5].Rectangle.TopRight.X, comparer);
Assert.Equal(719.89m, page.Letters[5].Rectangle.TopRight.Y, comparer); Assert.Equal(714.89m, page.Letters[5].Rectangle.TopRight.Y, comparer);
Assert.Equal("f", page.Letters[16].Value); Assert.Equal("f", page.Letters[16].Value);

View File

@@ -57,8 +57,8 @@ namespace UglyToad.PdfPig.Tests.Integration
{ {
var page = document.GetPage(1); var page = document.GetPage(1);
Assert.False((bool) page.Letters.Any(x => x.Rectangle.Width == 0)); Assert.True((bool) page.Letters.Any(x => x.Rectangle.Width != 0));
Assert.False((bool) page.Letters.Any(x => x.Rectangle.Height == 0)); Assert.True((bool) page.Letters.Any(x => x.Rectangle.Height != 0));
} }
} }
} }

View File

@@ -8,5 +8,7 @@
internal interface ICidFontProgram internal interface ICidFontProgram
{ {
bool TryGetBoundingBox(int characterCode, out PdfRectangle boundingBox); bool TryGetBoundingBox(int characterCode, out PdfRectangle boundingBox);
bool TryGetBoundingAdvancedWidth(int characterCode, out decimal width);
} }
} }

View File

@@ -42,6 +42,10 @@
public IFont Generate(DictionaryToken dictionary, bool isLenientParsing) public IFont Generate(DictionaryToken dictionary, bool isLenientParsing)
{ {
var firstCharacter = FontDictionaryAccessHelper.GetFirstCharacter(dictionary);
var widths = FontDictionaryAccessHelper.GetWidths(pdfScanner, dictionary, isLenientParsing);
var descriptor = FontDictionaryAccessHelper.GetFontDescriptor(pdfScanner, fontDescriptorFactory, dictionary, isLenientParsing); var descriptor = FontDictionaryAccessHelper.GetFontDescriptor(pdfScanner, fontDescriptorFactory, dictionary, isLenientParsing);
// TODO: use the parsed font fully. // TODO: use the parsed font fully.
@@ -64,7 +68,7 @@
Encoding encoding = encodingReader.Read(dictionary, isLenientParsing, descriptor); Encoding encoding = encodingReader.Read(dictionary, isLenientParsing, descriptor);
return new TrueTypeSimpleFont(name, descriptor, toUnicodeCMap, encoding, font); return new TrueTypeSimpleFont(name, descriptor, toUnicodeCMap, encoding, font, firstCharacter, widths);
} }
private TrueTypeFont ParseTrueTypeFont(FontDescriptor descriptor) private TrueTypeFont ParseTrueTypeFont(FontDescriptor descriptor)

View File

@@ -1,4 +1,6 @@
namespace UglyToad.PdfPig.Fonts.Simple using System;
namespace UglyToad.PdfPig.Fonts.Simple
{ {
using Cmap; using Cmap;
using Composite; using Composite;
@@ -20,6 +22,10 @@
[CanBeNull] [CanBeNull]
private readonly TrueTypeFont font; private readonly TrueTypeFont font;
private readonly int firstCharacter;
private readonly decimal[] widths;
public NameToken Name { get; } public NameToken Name { get; }
public bool IsVertical { get; } public bool IsVertical { get; }
@@ -31,11 +37,15 @@
FontDescriptor descriptor, FontDescriptor descriptor,
[CanBeNull] CMap toUnicodeCMap, [CanBeNull] CMap toUnicodeCMap,
[CanBeNull] Encoding encoding, [CanBeNull] Encoding encoding,
[CanBeNull] TrueTypeFont font) [CanBeNull] TrueTypeFont font,
int firstCharacter,
decimal[] widths)
{ {
this.descriptor = descriptor; this.descriptor = descriptor;
this.encoding = encoding; this.encoding = encoding;
this.font = font; this.font = font;
this.firstCharacter = firstCharacter;
this.widths = widths;
Name = name; Name = name;
IsVertical = false; IsVertical = false;
@@ -95,7 +105,24 @@
return bounds; return bounds;
} }
return descriptor.BoundingBox; if (font.TryGetBoundingAdvancedWidth(characterCode, out var width))
{
return new PdfRectangle(0, 0, width, 0);
}
return new PdfRectangle(0, 0, GetWidth(characterCode), 0);
}
private decimal GetWidth(int characterCode)
{
var index = characterCode - firstCharacter;
if (index < 0 || index >= widths.Length)
{
return descriptor.MissingWidth;
}
return widths[index];
} }
public TransformationMatrix GetFontMatrix() public TransformationMatrix GetFontMatrix()

View File

@@ -58,5 +58,24 @@
return true; return true;
} }
public bool TryGetBoundingAdvancedWidth(int characterCode, out decimal width)
{
width = 0m;
if (CMapTable == null)
{
return false;
}
if (!CMapTable.TryGetGlyphIndex(characterCode, out var index))
{
return false;
}
width = TableRegister.HorizontalMetricsTable.GetAdvanceWidth(index);
return true;
}
} }
} }