From cd84edbdc8cf4e5956b0e3d040b0fdcc9e2c308a Mon Sep 17 00:00:00 2001 From: Eliot Jones Date: Fri, 4 Jan 2019 19:54:55 +0000 Subject: [PATCH] #26 add missing operation and expose the content stream directly to the user through the page --- .../Parser/PageContentParserTests.cs | 60 +++++++++++++++++++ .../PublicApiScannerTests.cs | 1 + src/UglyToad.PdfPig/Content/Page.cs | 6 ++ ...SetGraphicsStateOperatorsFromDictionary.cs | 54 +++++++++++++++++ 4 files changed, 121 insertions(+) create mode 100644 src/UglyToad.PdfPig/Graphics/Operations/SpecialGraphicsState/SetGraphicsStateOperatorsFromDictionary.cs diff --git a/src/UglyToad.PdfPig.Tests/Parser/PageContentParserTests.cs b/src/UglyToad.PdfPig.Tests/Parser/PageContentParserTests.cs index 5cd05ebb..f6cef877 100644 --- a/src/UglyToad.PdfPig.Tests/Parser/PageContentParserTests.cs +++ b/src/UglyToad.PdfPig.Tests/Parser/PageContentParserTests.cs @@ -2,6 +2,7 @@ { using System; using System.IO; + using System.Text.RegularExpressions; using PdfPig.Graphics; using PdfPig.Graphics.Core; using PdfPig.Graphics.Operations.General; @@ -11,6 +12,7 @@ using PdfPig.Graphics.Operations.TextState; using PdfPig.Parser; using PdfPig.Tokens; + using PdfPig.Util; using Xunit; public class PageContentParserTests @@ -29,6 +31,64 @@ Assert.NotEmpty(result); } + [Fact] + public void CorrectlyWritesOperations() + { + var path = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "Parser", "SimpleGoogleDocPageContent.txt"); + var content = File.ReadAllText(path); + var input = StringBytesTestConverter.Convert(content, false); + + var result = parser.Parse(input.Bytes); + + var replacementRegex = new Regex(@"\s(\.\d+)\b"); + + using (var stream = new MemoryStream()) + { + foreach (var operation in result) + { + operation.Write(stream); + } + + var text = OtherEncodings.BytesAsLatin1String(stream.ToArray()); + + text = text.Replace("\n", " "); + content = content.Replace("\r\n", " "); + content = replacementRegex.Replace(content, " 0$1"); + + Assert.Equal(content, text); + } + } + + [Fact] + public void CorrectlyWritesSmallTextContent() + { + const string s = @"BT +/F13 48 Tf +20 38 Td +1 Tr +2 w +(ABC) Tj +ET"; + var input = StringBytesTestConverter.Convert(s, false); + + var result = parser.Parse(input.Bytes); + + using (var stream = new MemoryStream()) + { + foreach (var operation in result) + { + operation.Write(stream); + } + + var text = OtherEncodings.BytesAsLatin1String(stream.ToArray()); + + text = text.Replace("\n", " ").Trim(); + var expected = s.Replace("\r\n", " "); + + Assert.Equal(expected, text); + } + } + [Fact] public void CorrectlyExtractsOptionsInTextContext() { diff --git a/src/UglyToad.PdfPig.Tests/PublicApiScannerTests.cs b/src/UglyToad.PdfPig.Tests/PublicApiScannerTests.cs index 3b0e1884..8b3f2167 100644 --- a/src/UglyToad.PdfPig.Tests/PublicApiScannerTests.cs +++ b/src/UglyToad.PdfPig.Tests/PublicApiScannerTests.cs @@ -92,6 +92,7 @@ "UglyToad.PdfPig.Graphics.Operations.SpecialGraphicsState.ModifyCurrentTransformationMatrix", "UglyToad.PdfPig.Graphics.Operations.SpecialGraphicsState.Pop", "UglyToad.PdfPig.Graphics.Operations.SpecialGraphicsState.Push", + "UglyToad.PdfPig.Graphics.Operations.SpecialGraphicsState.SetGraphicsStateParametersFromDictionary", "UglyToad.PdfPig.Graphics.Operations.StrokePath", "UglyToad.PdfPig.Graphics.Operations.TextObjects.BeginText", "UglyToad.PdfPig.Graphics.Operations.TextObjects.EndText", diff --git a/src/UglyToad.PdfPig/Content/Page.cs b/src/UglyToad.PdfPig/Content/Page.cs index 3fdbddaa..c668bf7e 100644 --- a/src/UglyToad.PdfPig/Content/Page.cs +++ b/src/UglyToad.PdfPig/Content/Page.cs @@ -4,6 +4,7 @@ using System.Collections.Generic; using System.Linq; using Annotations; + using Graphics.Operations; using Tokens; using Util; using Util.JetBrains.Annotations; @@ -52,6 +53,11 @@ /// public PageSize Size { get; } + /// + /// The parsed graphics state operations in the content stream for this page. + /// + public IReadOnlyList Operations => Content.GraphicsStateOperations; + /// /// Access to members whose future locations within the API will change without warning. /// diff --git a/src/UglyToad.PdfPig/Graphics/Operations/SpecialGraphicsState/SetGraphicsStateOperatorsFromDictionary.cs b/src/UglyToad.PdfPig/Graphics/Operations/SpecialGraphicsState/SetGraphicsStateOperatorsFromDictionary.cs new file mode 100644 index 00000000..40aaf41c --- /dev/null +++ b/src/UglyToad.PdfPig/Graphics/Operations/SpecialGraphicsState/SetGraphicsStateOperatorsFromDictionary.cs @@ -0,0 +1,54 @@ +namespace UglyToad.PdfPig.Graphics.Operations.SpecialGraphicsState +{ + using System.IO; + using Tokens; + + /// + /// + /// Set the specified parameters in the graphics state using the ExtGState subdictionary with the given name. + /// + public class SetGraphicsStateParametersFromDictionary : IGraphicsStateOperation + { + /// + /// The symbol for this operation in a stream. + /// + public const string Symbol = "gs"; + + /// + public string Operator => Symbol; + + /// + /// The name of a graphics state parameter dictionary in the ExtGState subdictionary of the current resource dictionary. + /// + public NameToken Name { get; } + + /// + /// Create a new . + /// + /// The name of the ExtGState dictionary. + public SetGraphicsStateParametersFromDictionary(NameToken name) + { + Name = name; + } + + /// + public void Run(IOperationContext operationContext) + { + } + + /// + public void Write(Stream stream) + { + stream.WriteText($"/{Name.Data}"); + stream.WriteWhiteSpace(); + stream.WriteText(Symbol); + stream.WriteNewLine(); + } + + /// + public override string ToString() + { + return $"{Name} {Symbol}"; + } + } +}