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.True(Math.Abs(theirX - myX) < 2);
Assert.Equal(theirX, myX, new DecimalComparer(3m));
index++;
}

View File

@@ -60,7 +60,7 @@
Assert.Equal(709.2m, page.Letters[5].Rectangle.BottomLeft.Y, 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);

View File

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

View File

@@ -8,5 +8,7 @@
internal interface ICidFontProgram
{
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)
{
var firstCharacter = FontDictionaryAccessHelper.GetFirstCharacter(dictionary);
var widths = FontDictionaryAccessHelper.GetWidths(pdfScanner, dictionary, isLenientParsing);
var descriptor = FontDictionaryAccessHelper.GetFontDescriptor(pdfScanner, fontDescriptorFactory, dictionary, isLenientParsing);
// TODO: use the parsed font fully.
@@ -64,7 +68,7 @@
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)

View File

@@ -1,4 +1,6 @@
namespace UglyToad.PdfPig.Fonts.Simple
using System;
namespace UglyToad.PdfPig.Fonts.Simple
{
using Cmap;
using Composite;
@@ -20,6 +22,10 @@
[CanBeNull]
private readonly TrueTypeFont font;
private readonly int firstCharacter;
private readonly decimal[] widths;
public NameToken Name { get; }
public bool IsVertical { get; }
@@ -31,11 +37,15 @@
FontDescriptor descriptor,
[CanBeNull] CMap toUnicodeCMap,
[CanBeNull] Encoding encoding,
[CanBeNull] TrueTypeFont font)
[CanBeNull] TrueTypeFont font,
int firstCharacter,
decimal[] widths)
{
this.descriptor = descriptor;
this.encoding = encoding;
this.font = font;
this.firstCharacter = firstCharacter;
this.widths = widths;
Name = name;
IsVertical = false;
@@ -95,7 +105,24 @@
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()

View File

@@ -58,5 +58,24 @@
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;
}
}
}