diff --git a/src/UglyToad.PdfPig/Core/TransformationMatrix.cs b/src/UglyToad.PdfPig/Core/TransformationMatrix.cs index 8deb6f21..471324bf 100644 --- a/src/UglyToad.PdfPig/Core/TransformationMatrix.cs +++ b/src/UglyToad.PdfPig/Core/TransformationMatrix.cs @@ -106,10 +106,10 @@ public PdfRectangle Transform(PdfRectangle original) { return new PdfRectangle( + Transform(original.TopLeft.ToVector()), + Transform(original.TopRight.ToVector()), Transform(original.BottomLeft.ToVector()), - Transform(original.BottomLeft.ToVector()), - Transform(original.BottomLeft.ToVector()), - Transform(original.BottomLeft.ToVector()) + Transform(original.BottomRight.ToVector()) ); } diff --git a/src/UglyToad.PdfPig/Fonts/Composite/Type0Font.cs b/src/UglyToad.PdfPig/Fonts/Composite/Type0Font.cs index 7b907e40..f8d4c38a 100644 --- a/src/UglyToad.PdfPig/Fonts/Composite/Type0Font.cs +++ b/src/UglyToad.PdfPig/Fonts/Composite/Type0Font.cs @@ -71,12 +71,12 @@ return ToUnicode.TryGet(characterCode, out value); } - public PdfRectangle GetDisplacement(int characterCode) + public PdfRectangle GetBoundingBox(int characterCode) { - return fontMatrix.Transform(GetRectangle(characterCode)); + return fontMatrix.Transform(GetBoundingBoxInGlyphSpace(characterCode)); } - public PdfRectangle GetRectangle(int characterCode) + private PdfRectangle GetBoundingBoxInGlyphSpace(int characterCode) { var cid = CMap.ConvertToCid(characterCode); @@ -85,11 +85,6 @@ return new PdfRectangle(0, 0, fromFont, 0); } - public PdfRectangle GetBoundingBox(int characterCode) - { - throw new NotImplementedException(); - } - public TransformationMatrix GetFontMatrix() { return CidFont.FontMatrix; diff --git a/src/UglyToad.PdfPig/Fonts/IFont.cs b/src/UglyToad.PdfPig/Fonts/IFont.cs index aed6f0c2..42d35195 100644 --- a/src/UglyToad.PdfPig/Fonts/IFont.cs +++ b/src/UglyToad.PdfPig/Fonts/IFont.cs @@ -15,8 +15,6 @@ bool TryGetUnicode(int characterCode, out string value); - PdfRectangle GetDisplacement(int characterCode); - PdfRectangle GetBoundingBox(int characterCode); TransformationMatrix GetFontMatrix(); diff --git a/src/UglyToad.PdfPig/Fonts/Parser/Handlers/TrueTypeFontHandler.cs b/src/UglyToad.PdfPig/Fonts/Parser/Handlers/TrueTypeFontHandler.cs index ec16712a..be3a0adb 100644 --- a/src/UglyToad.PdfPig/Fonts/Parser/Handlers/TrueTypeFontHandler.cs +++ b/src/UglyToad.PdfPig/Fonts/Parser/Handlers/TrueTypeFontHandler.cs @@ -42,12 +42,6 @@ public IFont Generate(DictionaryToken dictionary, bool isLenientParsing) { - var firstCharacter = FontDictionaryAccessHelper.GetFirstCharacter(dictionary); - - var lastCharacter = FontDictionaryAccessHelper.GetLastCharacter(dictionary); - - var widths = FontDictionaryAccessHelper.GetWidths(pdfScanner, dictionary, isLenientParsing); - var descriptor = FontDictionaryAccessHelper.GetFontDescriptor(pdfScanner, fontDescriptorFactory, dictionary, isLenientParsing); // TODO: use the parsed font fully. @@ -70,7 +64,7 @@ Encoding encoding = encodingReader.Read(dictionary, isLenientParsing, descriptor); - return new TrueTypeSimpleFont(name, firstCharacter, lastCharacter, widths, descriptor, toUnicodeCMap, encoding, font); + return new TrueTypeSimpleFont(name, descriptor, toUnicodeCMap, encoding, font); } private TrueTypeFont ParseTrueTypeFont(FontDescriptor descriptor) diff --git a/src/UglyToad.PdfPig/Fonts/Simple/TrueTypeSimpleFont.cs b/src/UglyToad.PdfPig/Fonts/Simple/TrueTypeSimpleFont.cs index 56eb2861..44779c4d 100644 --- a/src/UglyToad.PdfPig/Fonts/Simple/TrueTypeSimpleFont.cs +++ b/src/UglyToad.PdfPig/Fonts/Simple/TrueTypeSimpleFont.cs @@ -12,16 +12,11 @@ internal class TrueTypeSimpleFont : IFont { - private readonly int firstCharacterCode; - - private readonly int lastCharacterCode; - - private readonly decimal[] widths; - private readonly FontDescriptor descriptor; [CanBeNull] private readonly Encoding encoding; + [CanBeNull] private readonly TrueTypeFont font; @@ -34,15 +29,12 @@ private readonly TransformationMatrix fontMatrix = TransformationMatrix.FromValues(0.001m, 0, 0, 0.001m, 0, 0); - public TrueTypeSimpleFont(NameToken name, int firstCharacterCode, int lastCharacterCode, decimal[] widths, + public TrueTypeSimpleFont(NameToken name, FontDescriptor descriptor, [CanBeNull] CMap toUnicodeCMap, [CanBeNull] Encoding encoding, - [CanBeNull]TrueTypeFont font) + [CanBeNull] TrueTypeFont font) { - this.firstCharacterCode = firstCharacterCode; - this.lastCharacterCode = lastCharacterCode; - this.widths = widths; this.descriptor = descriptor; this.encoding = encoding; this.font = font; @@ -88,24 +80,12 @@ return true; } - public PdfRectangle GetDisplacement(int characterCode) - { - return fontMatrix.Transform(GetRectangle(characterCode)); - } - - public PdfRectangle GetRectangle(int characterCode) - { - var index = characterCode - firstCharacterCode; - - if (index < 0 || index >= widths.Length) - { - return new PdfRectangle(0, 0, descriptor.MissingWidth, 0); - } - - return new PdfRectangle(0, 0, widths[index], 0); - } - public PdfRectangle GetBoundingBox(int characterCode) + { + return fontMatrix.Transform(GetBoundingBoxInGlyphSpace(characterCode)); + } + + private PdfRectangle GetBoundingBoxInGlyphSpace(int characterCode) { if (font?.CMapTable == null) { diff --git a/src/UglyToad.PdfPig/Fonts/Simple/Type1FontSimple.cs b/src/UglyToad.PdfPig/Fonts/Simple/Type1FontSimple.cs index 9b636e60..b30c5ef4 100644 --- a/src/UglyToad.PdfPig/Fonts/Simple/Type1FontSimple.cs +++ b/src/UglyToad.PdfPig/Fonts/Simple/Type1FontSimple.cs @@ -14,10 +14,15 @@ internal class Type1FontSimple : IFont { private readonly int firstChar; + private readonly int lastChar; + private readonly decimal[] widths; + private readonly FontDescriptor fontDescriptor; + private readonly Encoding encoding; + private readonly ToUnicodeCMap toUnicodeCMap; private readonly TransformationMatrix fontMatrix = TransformationMatrix.FromValues(0.001m, 0, 0, 0.001m, 0, 0); @@ -81,12 +86,12 @@ return true; } - public PdfRectangle GetDisplacement(int characterCode) + public PdfRectangle GetBoundingBox(int characterCode) { - return fontMatrix.Transform(GetRectangle(characterCode)); + return fontMatrix.Transform(GetBoundingBoxInGlyphSpace(characterCode)); } - public PdfRectangle GetRectangle(int characterCode) + private PdfRectangle GetBoundingBoxInGlyphSpace(int characterCode) { if (characterCode < firstChar || characterCode > lastChar) { @@ -96,11 +101,6 @@ return new PdfRectangle(0, 0, widths[characterCode - firstChar], 0); } - public PdfRectangle GetBoundingBox(int characterCode) - { - throw new System.NotImplementedException(); - } - public TransformationMatrix GetFontMatrix() { return fontMatrix; diff --git a/src/UglyToad.PdfPig/Fonts/Simple/Type1Standard14Font.cs b/src/UglyToad.PdfPig/Fonts/Simple/Type1Standard14Font.cs index 38637902..581404bf 100644 --- a/src/UglyToad.PdfPig/Fonts/Simple/Type1Standard14Font.cs +++ b/src/UglyToad.PdfPig/Fonts/Simple/Type1Standard14Font.cs @@ -44,12 +44,12 @@ return true; } - public PdfRectangle GetDisplacement(int characterCode) + public PdfRectangle GetBoundingBox(int characterCode) { - return fontMatrix.Transform(GetRectangle(characterCode)); + return fontMatrix.Transform(GetBoundingBoxInGlyphSpace(characterCode)); } - public PdfRectangle GetRectangle(int characterCode) + private PdfRectangle GetBoundingBoxInGlyphSpace(int characterCode) { var name = encoding.GetName(characterCode); @@ -61,11 +61,6 @@ return new PdfRectangle(0, 0, metrics.WidthX, 0); } - public PdfRectangle GetBoundingBox(int characterCode) - { - throw new NotImplementedException(); - } - public TransformationMatrix GetFontMatrix() { return fontMatrix; diff --git a/src/UglyToad.PdfPig/Fonts/Simple/Type3Font.cs b/src/UglyToad.PdfPig/Fonts/Simple/Type3Font.cs index ec180cf4..98ddc981 100644 --- a/src/UglyToad.PdfPig/Fonts/Simple/Type3Font.cs +++ b/src/UglyToad.PdfPig/Fonts/Simple/Type3Font.cs @@ -63,12 +63,12 @@ return true; } - public PdfRectangle GetDisplacement(int characterCode) + public PdfRectangle GetBoundingBox(int characterCode) { - return fontMatrix.Transform(GetRectangle(characterCode)); + return fontMatrix.Transform(GetBoundingBoxInGlyphSpace(characterCode)); } - public PdfRectangle GetRectangle(int characterCode) + private PdfRectangle GetBoundingBoxInGlyphSpace(int characterCode) { if (characterCode < firstChar || characterCode > lastChar) { @@ -78,11 +78,6 @@ return new PdfRectangle(0, 0, widths[characterCode - firstChar], 0); ; } - public PdfRectangle GetBoundingBox(int characterCode) - { - throw new System.NotImplementedException(); - } - public TransformationMatrix GetFontMatrix() { return fontMatrix; diff --git a/src/UglyToad.PdfPig/Graphics/ContentStreamProcessor.cs b/src/UglyToad.PdfPig/Graphics/ContentStreamProcessor.cs index e21a379b..dc081bd5 100644 --- a/src/UglyToad.PdfPig/Graphics/ContentStreamProcessor.cs +++ b/src/UglyToad.PdfPig/Graphics/ContentStreamProcessor.cs @@ -93,9 +93,13 @@ var fontSize = currentState.FontState.FontSize; var horizontalScaling = currentState.FontState.HorizontalScaling / 100m; var characterSpacing = currentState.FontState.CharacterSpacing; + var rise = currentState.FontState.Rise; var transformationMatrix = currentState.CurrentTransformationMatrix; + var renderingMatrix = + TransformationMatrix.FromValues(fontSize * horizontalScaling, 0, 0, fontSize, 0, rise); + // TODO: this does not seem correct, produces the correct result for now but we need to revisit. // see: https://stackoverflow.com/questions/48010235/pdf-specification-get-font-size-in-points var pointSize = decimal.Round(fontSize * transformationMatrix.A, 2); @@ -119,17 +123,15 @@ if (font.IsVertical) { - throw new NotImplementedException("Vertical fonts are# currently unsupported, please submit a pull request or issue with an example file."); + throw new NotImplementedException("Vertical fonts are currently unsupported, please submit a pull request or issue with an example file."); } - var displacement = font.GetDisplacement(code); - - var fontScaling = TransformationMatrix.Identity.Multiply(fontSize); + var boundingBox = font.GetBoundingBox(code); var transformedDisplacement = transformationMatrix .Transform(TextMatrices.TextMatrix - .Transform(fontScaling - .Transform(displacement))); + .Transform(renderingMatrix + .Transform(boundingBox))); ShowGlyph(font, transformedDisplacement, unicode, fontSize, pointSize); @@ -137,11 +139,11 @@ if (font.IsVertical) { tx = 0; - ty = displacement.Height * fontSize + characterSpacing + wordSpacing; + ty = boundingBox.Height * fontSize + characterSpacing + wordSpacing; } else { - tx = (displacement.Width * fontSize + characterSpacing + wordSpacing) * horizontalScaling; + tx = (boundingBox.Width * fontSize + characterSpacing + wordSpacing) * horizontalScaling; ty = 0; } diff --git a/src/UglyToad.PdfPig/Graphics/TextMatrices.cs b/src/UglyToad.PdfPig/Graphics/TextMatrices.cs index 348441ed..fa838c34 100644 --- a/src/UglyToad.PdfPig/Graphics/TextMatrices.cs +++ b/src/UglyToad.PdfPig/Graphics/TextMatrices.cs @@ -10,39 +10,5 @@ public TransformationMatrix TextMatrix { get; set; } public TransformationMatrix TextLineMatrix { get; set; } - - /// - /// Gets the Text Rendering Matrix (Trm) which maps from text space to device space. - /// - /// - /// The rendering matrix is temporary and is calculated for each glyph in a text showing operation. - /// - /// The rendering matrix is calculated as follows:
- /// | (Tfs * Th) 0 0 |
- /// | 0 Tfs 0 | * Tm * CTM
- /// | 0 Trise 1 |
- /// Where Tfs is the font size, Th is the horizontal scaling, Trise is the text rise, Tm is the current and CTM is the - /// . - ///
- ///
- public TransformationMatrix GetRenderingMatrix(CurrentGraphicsState currentGraphicsState) - { - var fontSize = currentGraphicsState.FontState.FontSize; - var horizontalScaling = currentGraphicsState.FontState.HorizontalScaling; - var rise = currentGraphicsState.FontState.Rise; - - var initialMatrix = TransformationMatrix.FromArray(new[] - { - (fontSize * horizontalScaling), 0, 0, - 0, fontSize, 0, - 0, rise, 1 - }); - - var multipledByTextMatrix = initialMatrix.Multiply(TextMatrix); - - var result = multipledByTextMatrix.Multiply(currentGraphicsState.CurrentTransformationMatrix); - - return result; - } } } \ No newline at end of file