From 39786ac00a0fcbc49465760b61d25a6a17f65892 Mon Sep 17 00:00:00 2001 From: Eliot Jones Date: Fri, 14 Dec 2018 18:33:01 +0000 Subject: [PATCH] #21 add a test for accented characters and fill in more writing methods for content stream operators the output is currently incorrect for accented characters --- .../Writer/PdfDocumentBuilderTests.cs | 17 +++++++++++++++++ src/UglyToad.PdfPig/Filters/FlateFilter.cs | 2 +- .../ModifyCurrentTransformationMatrix.cs | 3 +++ .../Operations/SpecialGraphicsState/Pop.cs | 7 ++++++- .../Operations/SpecialGraphicsState/Push.cs | 16 ++++++++++------ .../Operations/TextObjects/BeginText.cs | 3 +++ .../Graphics/Operations/TextObjects/EndText.cs | 3 +++ .../TextPositioning/MoveToNextLine.cs | 3 ++- .../MoveToNextLineWithOffsetSetLeading.cs | 11 ++++++++++- .../TextPositioning/SetTextMatrix.cs | 18 +++++++++++++++++- .../TextState/SetCharacterSpacing.cs | 9 ++++++++- .../Writer/TrueTypeWritingFont.cs | 2 +- 12 files changed, 81 insertions(+), 13 deletions(-) diff --git a/src/UglyToad.PdfPig.Tests/Writer/PdfDocumentBuilderTests.cs b/src/UglyToad.PdfPig.Tests/Writer/PdfDocumentBuilderTests.cs index 3e3471f8..500239f7 100644 --- a/src/UglyToad.PdfPig.Tests/Writer/PdfDocumentBuilderTests.cs +++ b/src/UglyToad.PdfPig.Tests/Writer/PdfDocumentBuilderTests.cs @@ -207,6 +207,23 @@ } } + [Fact] + public void CanWriteSinglePageWithAccentedCharacters() + { + var builder = new PdfDocumentBuilder(); + var page = builder.AddPage(PageSize.A4); + + var path = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "Fonts", "TrueType"); + var file = Path.Combine(path, "Roboto-Regular.ttf"); + + var font = builder.AddTrueTypeFont(File.ReadAllBytes(file)); + + page.AddText("é (lower case, upper case É).", 9, + new PdfPoint(30, page.PageSize.Height - 50), font); + + WriteFile(nameof(CanWriteSinglePageWithAccentedCharacters), builder.Build()); + } + private static void WriteFile(string name, byte[] bytes) { try diff --git a/src/UglyToad.PdfPig/Filters/FlateFilter.cs b/src/UglyToad.PdfPig/Filters/FlateFilter.cs index 9c3cbc1a..f303d842 100644 --- a/src/UglyToad.PdfPig/Filters/FlateFilter.cs +++ b/src/UglyToad.PdfPig/Filters/FlateFilter.cs @@ -77,7 +77,7 @@ { using (var memoryStream = new MemoryStream(input)) { - // The first 2 bytes are the header which DelfateStream does not support. + // The first 2 bytes are the header which DeflateStream does not support. memoryStream.ReadByte(); memoryStream.ReadByte(); diff --git a/src/UglyToad.PdfPig/Graphics/Operations/SpecialGraphicsState/ModifyCurrentTransformationMatrix.cs b/src/UglyToad.PdfPig/Graphics/Operations/SpecialGraphicsState/ModifyCurrentTransformationMatrix.cs index 3ab91225..b7bf4c3f 100644 --- a/src/UglyToad.PdfPig/Graphics/Operations/SpecialGraphicsState/ModifyCurrentTransformationMatrix.cs +++ b/src/UglyToad.PdfPig/Graphics/Operations/SpecialGraphicsState/ModifyCurrentTransformationMatrix.cs @@ -5,6 +5,9 @@ using Content; using PdfPig.Core; + /// + /// Modify the current transformation matrix by concatenating the specified matrix. + /// internal class ModifyCurrentTransformationMatrix : IGraphicsStateOperation { public const string Symbol = "cm"; diff --git a/src/UglyToad.PdfPig/Graphics/Operations/SpecialGraphicsState/Pop.cs b/src/UglyToad.PdfPig/Graphics/Operations/SpecialGraphicsState/Pop.cs index 1a5eb3bf..f22cbd77 100644 --- a/src/UglyToad.PdfPig/Graphics/Operations/SpecialGraphicsState/Pop.cs +++ b/src/UglyToad.PdfPig/Graphics/Operations/SpecialGraphicsState/Pop.cs @@ -4,9 +4,13 @@ using System.IO; using Content; + /// + /// Restore the graphics state by removing the most recently saved state from the stack and making it the current state. + /// internal class Pop : IGraphicsStateOperation { public const string Symbol = "Q"; + public static readonly Pop Value = new Pop(); public string Operator => Symbol; @@ -30,7 +34,8 @@ public void Write(Stream stream) { - throw new NotImplementedException(); + stream.WriteText(Symbol); + stream.WriteNewLine(); } public override string ToString() diff --git a/src/UglyToad.PdfPig/Graphics/Operations/SpecialGraphicsState/Push.cs b/src/UglyToad.PdfPig/Graphics/Operations/SpecialGraphicsState/Push.cs index 52f44f9c..a363d2a3 100644 --- a/src/UglyToad.PdfPig/Graphics/Operations/SpecialGraphicsState/Push.cs +++ b/src/UglyToad.PdfPig/Graphics/Operations/SpecialGraphicsState/Push.cs @@ -3,6 +3,9 @@ using System.IO; using Content; + /// + /// Save the current graphics state on the graphics state stack. + /// internal class Push : IGraphicsStateOperation { public const string Symbol = "q"; @@ -14,11 +17,6 @@ { } - public override string ToString() - { - return Symbol; - } - public void Run(IOperationContext context, IResourceStore resourceStore) { context.PushState(); @@ -26,7 +24,13 @@ public void Write(Stream stream) { - throw new System.NotImplementedException(); + stream.WriteText(Symbol); + stream.WriteNewLine(); + } + + public override string ToString() + { + return Symbol; } } } diff --git a/src/UglyToad.PdfPig/Graphics/Operations/TextObjects/BeginText.cs b/src/UglyToad.PdfPig/Graphics/Operations/TextObjects/BeginText.cs index 48b5e428..86e3fab0 100644 --- a/src/UglyToad.PdfPig/Graphics/Operations/TextObjects/BeginText.cs +++ b/src/UglyToad.PdfPig/Graphics/Operations/TextObjects/BeginText.cs @@ -4,6 +4,9 @@ using Content; using PdfPig.Core; + /// + /// Begin a text object, initializing the text matrix and the text line matrix to the identity matrix. Text objects cannot be nested. + /// internal class BeginText : IGraphicsStateOperation { public const string Symbol = "BT"; diff --git a/src/UglyToad.PdfPig/Graphics/Operations/TextObjects/EndText.cs b/src/UglyToad.PdfPig/Graphics/Operations/TextObjects/EndText.cs index c8d2c88f..10f9b917 100644 --- a/src/UglyToad.PdfPig/Graphics/Operations/TextObjects/EndText.cs +++ b/src/UglyToad.PdfPig/Graphics/Operations/TextObjects/EndText.cs @@ -4,6 +4,9 @@ using Content; using PdfPig.Core; + /// + /// End a text object, discarding the text matrix. + /// internal class EndText : IGraphicsStateOperation { public const string Symbol = "ET"; diff --git a/src/UglyToad.PdfPig/Graphics/Operations/TextPositioning/MoveToNextLine.cs b/src/UglyToad.PdfPig/Graphics/Operations/TextPositioning/MoveToNextLine.cs index 06162fd6..4d737c3a 100644 --- a/src/UglyToad.PdfPig/Graphics/Operations/TextPositioning/MoveToNextLine.cs +++ b/src/UglyToad.PdfPig/Graphics/Operations/TextPositioning/MoveToNextLine.cs @@ -30,7 +30,8 @@ public void Write(Stream stream) { - throw new System.NotImplementedException(); + stream.WriteText(Symbol); + stream.WriteNewLine(); } public override string ToString() diff --git a/src/UglyToad.PdfPig/Graphics/Operations/TextPositioning/MoveToNextLineWithOffsetSetLeading.cs b/src/UglyToad.PdfPig/Graphics/Operations/TextPositioning/MoveToNextLineWithOffsetSetLeading.cs index c7d53f4a..440b360d 100644 --- a/src/UglyToad.PdfPig/Graphics/Operations/TextPositioning/MoveToNextLineWithOffsetSetLeading.cs +++ b/src/UglyToad.PdfPig/Graphics/Operations/TextPositioning/MoveToNextLineWithOffsetSetLeading.cs @@ -4,6 +4,10 @@ using Content; using TextState; + /// + /// Move to the start of the next line, offset from the start of the current line by (tx, ty). + /// This operator also sets the leading parameter in the text state. + /// internal class MoveToNextLineWithOffsetSetLeading : IGraphicsStateOperation { public const string Symbol = "TD"; @@ -33,7 +37,12 @@ public void Write(Stream stream) { - throw new System.NotImplementedException(); + stream.WriteDecimal(Tx); + stream.WriteWhiteSpace(); + stream.WriteDecimal(Ty); + stream.WriteWhiteSpace(); + stream.WriteText(Symbol); + stream.WriteNewLine(); } public override string ToString() diff --git a/src/UglyToad.PdfPig/Graphics/Operations/TextPositioning/SetTextMatrix.cs b/src/UglyToad.PdfPig/Graphics/Operations/TextPositioning/SetTextMatrix.cs index 0f102ef3..53718c8a 100644 --- a/src/UglyToad.PdfPig/Graphics/Operations/TextPositioning/SetTextMatrix.cs +++ b/src/UglyToad.PdfPig/Graphics/Operations/TextPositioning/SetTextMatrix.cs @@ -5,6 +5,9 @@ using Content; using PdfPig.Core; + /// + /// Set the text matrix and the text line matrix. + /// internal class SetTextMatrix : IGraphicsStateOperation { public const string Symbol = "Tm"; @@ -33,7 +36,20 @@ public void Write(Stream stream) { - throw new NotImplementedException(); + stream.WriteDecimal(Value[0]); + stream.WriteWhiteSpace(); + stream.WriteDecimal(Value[1]); + stream.WriteWhiteSpace(); + stream.WriteDecimal(Value[2]); + stream.WriteWhiteSpace(); + stream.WriteDecimal(Value[3]); + stream.WriteWhiteSpace(); + stream.WriteDecimal(Value[4]); + stream.WriteWhiteSpace(); + stream.WriteDecimal(Value[5]); + stream.WriteWhiteSpace(); + stream.WriteText(Symbol); + stream.WriteNewLine(); } public override string ToString() diff --git a/src/UglyToad.PdfPig/Graphics/Operations/TextState/SetCharacterSpacing.cs b/src/UglyToad.PdfPig/Graphics/Operations/TextState/SetCharacterSpacing.cs index 72f8dd80..c5e739a9 100644 --- a/src/UglyToad.PdfPig/Graphics/Operations/TextState/SetCharacterSpacing.cs +++ b/src/UglyToad.PdfPig/Graphics/Operations/TextState/SetCharacterSpacing.cs @@ -3,6 +3,10 @@ using System.IO; using Content; + /// + /// Set the character spacing to a number expressed in unscaled text space units. + /// Initial value: 0. + /// internal class SetCharacterSpacing : IGraphicsStateOperation { public const string Symbol = "Tc"; @@ -25,7 +29,10 @@ public void Write(Stream stream) { - throw new System.NotImplementedException(); + stream.WriteDecimal(Spacing); + stream.WriteWhiteSpace(); + stream.WriteText(Symbol); + stream.WriteNewLine(); } public override string ToString() diff --git a/src/UglyToad.PdfPig/Writer/TrueTypeWritingFont.cs b/src/UglyToad.PdfPig/Writer/TrueTypeWritingFont.cs index f1a7ebec..5523cff2 100644 --- a/src/UglyToad.PdfPig/Writer/TrueTypeWritingFont.cs +++ b/src/UglyToad.PdfPig/Writer/TrueTypeWritingFont.cs @@ -165,7 +165,7 @@ if (!font.TryGetBoundingAdvancedWidth(characterCode, out var width)) { - throw new InvalidFontFormatException($"Could not find advanced with for character named '{pair.Value}' with character code: {characterCode}."); + width = font.TableRegister.HorizontalMetricsTable.AdvancedWidths[0]; } widths[pair.Key - firstCharacter] = new NumericToken(width * scaling);