fix glyph boxes for an offset glyph index range in true type fornt format 4 cmap table

This commit is contained in:
Eliot Jones
2018-04-29 19:27:34 +01:00
parent f4db97a998
commit c8c32eab24
3 changed files with 63 additions and 6 deletions

View File

@@ -12,6 +12,9 @@
internal class TrueTypeSimpleFont : IFont
{
private static readonly TransformationMatrix DefaultTransformation =
TransformationMatrix.FromValues(1m / 1000m, 0, 0, 1m / 1000m, 0, 0);
private readonly FontDescriptor descriptor;
[CanBeNull]
@@ -90,32 +93,51 @@
{
var fontMatrix = GetFontMatrix();
var boundingBox = GetBoundingBoxInGlyphSpace(characterCode);
var boundingBox = GetBoundingBoxInGlyphSpace(characterCode, out var fromFont);
boundingBox = fontMatrix.Transform(boundingBox);
var boundingBoxPreTransform = boundingBox.Width;
if (fromFont)
{
boundingBox = fontMatrix.Transform(boundingBox);
}
else
{
boundingBox = DefaultTransformation.Transform(boundingBox);
}
decimal width;
if (font == null)
{
fromFont = false;
width = widths[characterCode];
}
else
{
if (!font.TryGetBoundingAdvancedWidth(characterCode, out width))
{
width = boundingBox.Width;
width = boundingBoxPreTransform;
}
}
var advancedRectangle = new PdfRectangle(0, 0, width, 0);
advancedRectangle = fontMatrix.Transform(advancedRectangle);
if (fromFont)
{
advancedRectangle = fontMatrix.Transform(advancedRectangle);
}
else
{
advancedRectangle = DefaultTransformation.Transform(advancedRectangle);
}
return new CharacterBoundingBox(boundingBox, advancedRectangle);
}
private PdfRectangle GetBoundingBoxInGlyphSpace(int characterCode)
private PdfRectangle GetBoundingBoxInGlyphSpace(int characterCode, out bool fromFont)
{
fromFont = true;
if (font == null)
{
return descriptor.BoundingBox;
@@ -131,6 +153,8 @@
return new PdfRectangle(0, 0, width, 0);
}
fromFont = false;
return new PdfRectangle(0, 0, GetWidth(characterCode), 0);
}

View File

@@ -45,7 +45,7 @@ namespace UglyToad.PdfPig.Fonts.TrueType.Tables.CMapSubTables
if (segment.IdRangeOffset == 0)
{
return (characterCode + segment.IdDelta) % ushort.MaxValue;
return (characterCode + segment.IdDelta) & 0xFFFF;
}
var offset = segment.IdRangeOffset / 2 + (characterCode - segment.StartCode);

View File

@@ -30,6 +30,8 @@
return false;
}
var windowsMapping = default(ICMapSubTable);
foreach (var subTable in subTables)
{
glyphIndex = subTable.CharacterCodeToGlyphIndex(characterCode);
@@ -38,6 +40,37 @@
{
return true;
}
if (subTable.EncodingId == 0 && subTable.PlatformId == 3)
{
windowsMapping = subTable;
}
}
if (windowsMapping != null && characterCode >= 0 && characterCode <= 255)
{
// the CMap may use one of the following code ranges, so that we have to add the high byte to get the
// mapped value
glyphIndex = windowsMapping.CharacterCodeToGlyphIndex(characterCode + 0xF000);
if (glyphIndex != 0)
{
return true;
}
glyphIndex = windowsMapping.CharacterCodeToGlyphIndex(characterCode + 0xF100);
if (glyphIndex != 0)
{
return true;
}
glyphIndex = windowsMapping.CharacterCodeToGlyphIndex(characterCode + 0xF200);
if (glyphIndex != 0)
{
return true;
}
}
return false;