diff --git a/src/UglyToad.PdfPig.Tests/Graphics/TestOperationContext.cs b/src/UglyToad.PdfPig.Tests/Graphics/TestOperationContext.cs index 5f2faa17..f56ed6dd 100644 --- a/src/UglyToad.PdfPig.Tests/Graphics/TestOperationContext.cs +++ b/src/UglyToad.PdfPig.Tests/Graphics/TestOperationContext.cs @@ -7,6 +7,8 @@ using PdfPig.Tokens; using PdfPig.Core; using Tokens; + using UglyToad.PdfPig.Graphics.Core; + using UglyToad.PdfPig.Graphics.Operations.TextPositioning; internal class TestOperationContext : IOperationContext { @@ -184,6 +186,91 @@ { } + private void AdjustTextMatrix(double tx, double ty) + { + var matrix = TransformationMatrix.GetTranslationMatrix(tx, ty); + TextMatrices.TextMatrix = matrix.Multiply(TextMatrices.TextMatrix); + } + + public void SetFlatnessTolerance(decimal tolerance) + { + GetCurrentState().Flatness = tolerance; + } + + public void SetLineCap(LineCapStyle cap) + { + GetCurrentState().CapStyle = cap; + } + + public void SetLineDashPattern(LineDashPattern pattern) + { + GetCurrentState().LineDashPattern = pattern; + } + + public void SetLineJoin(LineJoinStyle join) + { + GetCurrentState().JoinStyle = join; + } + + public void SetLineWidth(decimal width) + { + GetCurrentState().LineWidth = width; + } + + public void SetMiterLimit(decimal limit) + { + GetCurrentState().MiterLimit = limit; + } + + public void MoveToNextLineWithOffset() + { + var tdOperation = new MoveToNextLineWithOffset(0, -1 * (decimal)GetCurrentState().FontState.Leading); + tdOperation.Run(this); + } + + public void SetFontAndSize(NameToken font, double size) + { + var currentState = GetCurrentState(); + currentState.FontState.FontSize = size; + currentState.FontState.FontName = font; + } + + public void SetHorizontalScaling(double scale) + { + GetCurrentState().FontState.HorizontalScaling = scale; + } + + public void SetTextLeading(double leading) + { + GetCurrentState().FontState.Leading = leading; + } + + public void SetTextRenderingMode(TextRenderingMode mode) + { + GetCurrentState().FontState.TextRenderingMode = mode; + } + + public void SetTextRise(double rise) + { + GetCurrentState().FontState.Rise = rise; + } + + public void SetWordSpacing(double spacing) + { + GetCurrentState().FontState.WordSpacing = spacing; + } + + public void ModifyCurrentTransformationMatrix(double[] value) + { + var ctm = GetCurrentState().CurrentTransformationMatrix; + GetCurrentState().CurrentTransformationMatrix = TransformationMatrix.FromArray(value).Multiply(ctm); + } + + public void SetCharacterSpacing(double spacing) + { + GetCurrentState().FontState.CharacterSpacing = spacing; + } + private class TestFontFactory : IFontFactory { public IFont Get(DictionaryToken dictionary) diff --git a/src/UglyToad.PdfPig/Graphics/ContentStreamProcessor.cs b/src/UglyToad.PdfPig/Graphics/ContentStreamProcessor.cs index 03f290ba..482e2249 100644 --- a/src/UglyToad.PdfPig/Graphics/ContentStreamProcessor.cs +++ b/src/UglyToad.PdfPig/Graphics/ContentStreamProcessor.cs @@ -1,9 +1,5 @@ namespace UglyToad.PdfPig.Graphics { - using System; - using System.Collections.Generic; - using System.Diagnostics; - using System.Linq; using Colors; using Content; using Core; @@ -14,8 +10,13 @@ using Parser; using PdfFonts; using PdfPig.Core; + using System; + using System.Collections.Generic; + using System.Diagnostics; + using System.Linq; using Tokenization.Scanner; using Tokens; + using UglyToad.PdfPig.Graphics.Operations.TextPositioning; using XObjects; using static PdfPig.Core.PdfSubpath; @@ -815,9 +816,86 @@ { var matrix = TransformationMatrix.GetTranslationMatrix(tx, ty); - var newMatrix = matrix.Multiply(TextMatrices.TextMatrix); + TextMatrices.TextMatrix = matrix.Multiply(TextMatrices.TextMatrix); + } - TextMatrices.TextMatrix = newMatrix; + public void SetFlatnessTolerance(decimal tolerance) + { + GetCurrentState().Flatness = tolerance; + } + + public void SetLineCap(LineCapStyle cap) + { + GetCurrentState().CapStyle = cap; + } + + public void SetLineDashPattern(LineDashPattern pattern) + { + GetCurrentState().LineDashPattern = pattern; + } + + public void SetLineJoin(LineJoinStyle join) + { + GetCurrentState().JoinStyle = join; + } + + public void SetLineWidth(decimal width) + { + GetCurrentState().LineWidth = width; + } + + public void SetMiterLimit(decimal limit) + { + GetCurrentState().MiterLimit = limit; + } + + public void MoveToNextLineWithOffset() + { + var tdOperation = new MoveToNextLineWithOffset(0, -1 * (decimal)GetCurrentState().FontState.Leading); + tdOperation.Run(this); + } + + public void SetFontAndSize(NameToken font, double size) + { + var currentState = GetCurrentState(); + currentState.FontState.FontSize = size; + currentState.FontState.FontName = font; + } + + public void SetHorizontalScaling(double scale) + { + GetCurrentState().FontState.HorizontalScaling = scale; + } + + public void SetTextLeading(double leading) + { + GetCurrentState().FontState.Leading = leading; + } + + public void SetTextRenderingMode(TextRenderingMode mode) + { + GetCurrentState().FontState.TextRenderingMode = mode; + } + + public void SetTextRise(double rise) + { + GetCurrentState().FontState.Rise = rise; + } + + public void SetWordSpacing(double spacing) + { + GetCurrentState().FontState.WordSpacing = spacing; + } + + public void ModifyCurrentTransformationMatrix(double[] value) + { + var ctm = GetCurrentState().CurrentTransformationMatrix; + GetCurrentState().CurrentTransformationMatrix = TransformationMatrix.FromArray(value).Multiply(ctm); + } + + public void SetCharacterSpacing(double spacing) + { + GetCurrentState().FontState.CharacterSpacing = spacing; } } } \ No newline at end of file diff --git a/src/UglyToad.PdfPig/Graphics/IOperationContext.cs b/src/UglyToad.PdfPig/Graphics/IOperationContext.cs index 155186e5..41555c65 100644 --- a/src/UglyToad.PdfPig/Graphics/IOperationContext.cs +++ b/src/UglyToad.PdfPig/Graphics/IOperationContext.cs @@ -3,6 +3,7 @@ using PdfPig.Core; using System.Collections.Generic; using Tokens; + using UglyToad.PdfPig.Graphics.Core; /// /// The current graphics state context when running a PDF content stream. @@ -19,12 +20,6 @@ /// PdfPoint CurrentPosition { get; set; } - /// - /// Get the currently active . States are stored on a stack structure. - /// - /// The currently active graphics state. - CurrentGraphicsState GetCurrentState(); - /// /// The matrices for the current text state. /// @@ -189,5 +184,90 @@ /// Modify the clipping rule of the current path. /// void ModifyClippingIntersect(FillingRule clippingRule); + + /// + /// Set the flatness tolerance in the graphics state. + /// Flatness is a number in the range 0 to 100; a value of 0 specifies the output device’s default flatness tolerance. + /// + /// + void SetFlatnessTolerance(decimal tolerance); + + /// + /// Set the line cap style in the graphics state. + /// + void SetLineCap(LineCapStyle cap); + + /// + /// Set the line dash pattern in the graphics state. + /// + void SetLineDashPattern(LineDashPattern pattern); + + /// + /// Set the line join style in the graphics state. + /// + void SetLineJoin(LineJoinStyle join); + + /// + /// Set the line width in the graphics state. + /// + void SetLineWidth(decimal width); + + /// + /// Set the miter limit in the graphics state. + /// + void SetMiterLimit(decimal limit); + + /// + /// Move to the start of the next line. + /// + /// + /// This performs this operation: 0 -Tl Td + /// The offset is negative leading text (Tl) value, this is incorrect in the specification. + /// + void MoveToNextLineWithOffset(); + + /// + /// Set the font and the font size. + /// Font is the name of a font resource in the Font subdictionary of the current resource dictionary. + /// Size is a number representing a scale factor. + /// + void SetFontAndSize(NameToken font, double size); + + /// + /// Set the horizontal scaling. + /// + /// + void SetHorizontalScaling(double scale); + + /// + /// Set the text leading. + /// + void SetTextLeading(double leading); + + /// + /// Set the text rendering mode. + /// + void SetTextRenderingMode(TextRenderingMode mode); + + /// + /// Set text rise. + /// + void SetTextRise(double rise); + + /// + /// Sets the word spacing. + /// + void SetWordSpacing(double spacing); + + /// + /// Modify the current transformation matrix by concatenating the specified matrix. + /// + void ModifyCurrentTransformationMatrix(double[] value); + + /// + /// Set the character spacing to a number expressed in unscaled text space units. + /// Initial value: 0. + /// + void SetCharacterSpacing(double spacing); } } \ No newline at end of file diff --git a/src/UglyToad.PdfPig/Graphics/Operations/General/SetFlatnessTolerance.cs b/src/UglyToad.PdfPig/Graphics/Operations/General/SetFlatnessTolerance.cs index ac9299ea..d51159b8 100644 --- a/src/UglyToad.PdfPig/Graphics/Operations/General/SetFlatnessTolerance.cs +++ b/src/UglyToad.PdfPig/Graphics/Operations/General/SetFlatnessTolerance.cs @@ -35,7 +35,7 @@ /// public void Run(IOperationContext operationContext) { - operationContext.GetCurrentState().Flatness = Tolerance; + operationContext.SetFlatnessTolerance(Tolerance); } /// diff --git a/src/UglyToad.PdfPig/Graphics/Operations/General/SetLineCap.cs b/src/UglyToad.PdfPig/Graphics/Operations/General/SetLineCap.cs index 1e06ec59..42cda784 100644 --- a/src/UglyToad.PdfPig/Graphics/Operations/General/SetLineCap.cs +++ b/src/UglyToad.PdfPig/Graphics/Operations/General/SetLineCap.cs @@ -45,7 +45,7 @@ /// public void Run(IOperationContext operationContext) { - operationContext.GetCurrentState().CapStyle = Cap; + operationContext.SetLineCap(Cap); } /// diff --git a/src/UglyToad.PdfPig/Graphics/Operations/General/SetLineDashPattern.cs b/src/UglyToad.PdfPig/Graphics/Operations/General/SetLineDashPattern.cs index 3dcad6cf..32f994f9 100644 --- a/src/UglyToad.PdfPig/Graphics/Operations/General/SetLineDashPattern.cs +++ b/src/UglyToad.PdfPig/Graphics/Operations/General/SetLineDashPattern.cs @@ -33,7 +33,7 @@ /// public void Run(IOperationContext operationContext) { - operationContext.GetCurrentState().LineDashPattern = Pattern; + operationContext.SetLineDashPattern(Pattern); } /// diff --git a/src/UglyToad.PdfPig/Graphics/Operations/General/SetLineJoin.cs b/src/UglyToad.PdfPig/Graphics/Operations/General/SetLineJoin.cs index 95398ff7..991d2b71 100644 --- a/src/UglyToad.PdfPig/Graphics/Operations/General/SetLineJoin.cs +++ b/src/UglyToad.PdfPig/Graphics/Operations/General/SetLineJoin.cs @@ -40,7 +40,7 @@ /// public void Run(IOperationContext operationContext) { - operationContext.GetCurrentState().JoinStyle = Join; + operationContext.SetLineJoin(Join); } /// diff --git a/src/UglyToad.PdfPig/Graphics/Operations/General/SetLineWidth.cs b/src/UglyToad.PdfPig/Graphics/Operations/General/SetLineWidth.cs index 949bc2cc..2add7aab 100644 --- a/src/UglyToad.PdfPig/Graphics/Operations/General/SetLineWidth.cs +++ b/src/UglyToad.PdfPig/Graphics/Operations/General/SetLineWidth.cs @@ -33,9 +33,7 @@ /// public void Run(IOperationContext operationContext) { - var currentState = operationContext.GetCurrentState(); - - currentState.LineWidth = Width; + operationContext.SetLineWidth(Width); } /// diff --git a/src/UglyToad.PdfPig/Graphics/Operations/General/SetMiterLimit.cs b/src/UglyToad.PdfPig/Graphics/Operations/General/SetMiterLimit.cs index 54ac37f1..7145a16b 100644 --- a/src/UglyToad.PdfPig/Graphics/Operations/General/SetMiterLimit.cs +++ b/src/UglyToad.PdfPig/Graphics/Operations/General/SetMiterLimit.cs @@ -33,9 +33,7 @@ /// public void Run(IOperationContext operationContext) { - var currentState = operationContext.GetCurrentState(); - - currentState.MiterLimit = Limit; + operationContext.SetMiterLimit(Limit); } /// diff --git a/src/UglyToad.PdfPig/Graphics/Operations/SpecialGraphicsState/ModifyCurrentTransformationMatrix.cs b/src/UglyToad.PdfPig/Graphics/Operations/SpecialGraphicsState/ModifyCurrentTransformationMatrix.cs index f6a33234..10c0680d 100644 --- a/src/UglyToad.PdfPig/Graphics/Operations/SpecialGraphicsState/ModifyCurrentTransformationMatrix.cs +++ b/src/UglyToad.PdfPig/Graphics/Operations/SpecialGraphicsState/ModifyCurrentTransformationMatrix.cs @@ -44,13 +44,7 @@ /// public void Run(IOperationContext operationContext) { - var newMatrix = TransformationMatrix.FromArray(Value); - - var ctm = operationContext.GetCurrentState().CurrentTransformationMatrix; - - var newCtm = newMatrix.Multiply(ctm); - - operationContext.GetCurrentState().CurrentTransformationMatrix = newCtm; + operationContext.ModifyCurrentTransformationMatrix(Array.ConvertAll(Value, x => (double)x)); } /// diff --git a/src/UglyToad.PdfPig/Graphics/Operations/TextPositioning/MoveToNextLine.cs b/src/UglyToad.PdfPig/Graphics/Operations/TextPositioning/MoveToNextLine.cs index 3f38891c..f3ea321f 100644 --- a/src/UglyToad.PdfPig/Graphics/Operations/TextPositioning/MoveToNextLine.cs +++ b/src/UglyToad.PdfPig/Graphics/Operations/TextPositioning/MoveToNextLine.cs @@ -32,9 +32,7 @@ /// public void Run(IOperationContext operationContext) { - var tdOperation = new MoveToNextLineWithOffset(0, -1 * (decimal)operationContext.GetCurrentState().FontState.Leading); - - tdOperation.Run(operationContext); + operationContext.MoveToNextLineWithOffset(); } /// diff --git a/src/UglyToad.PdfPig/Graphics/Operations/TextState/SetCharacterSpacing.cs b/src/UglyToad.PdfPig/Graphics/Operations/TextState/SetCharacterSpacing.cs index 85f3679f..7c63d747 100644 --- a/src/UglyToad.PdfPig/Graphics/Operations/TextState/SetCharacterSpacing.cs +++ b/src/UglyToad.PdfPig/Graphics/Operations/TextState/SetCharacterSpacing.cs @@ -34,9 +34,7 @@ /// public void Run(IOperationContext operationContext) { - var currentState = operationContext.GetCurrentState(); - - currentState.FontState.CharacterSpacing = (double)Spacing; + operationContext.SetCharacterSpacing((double)Spacing); } /// diff --git a/src/UglyToad.PdfPig/Graphics/Operations/TextState/SetFontAndSize.cs b/src/UglyToad.PdfPig/Graphics/Operations/TextState/SetFontAndSize.cs index 6b1efc08..77b93d34 100644 --- a/src/UglyToad.PdfPig/Graphics/Operations/TextState/SetFontAndSize.cs +++ b/src/UglyToad.PdfPig/Graphics/Operations/TextState/SetFontAndSize.cs @@ -48,10 +48,7 @@ /// public void Run(IOperationContext operationContext) { - var currentState = operationContext.GetCurrentState(); - - currentState.FontState.FontSize = (double)Size; - currentState.FontState.FontName = Font; + operationContext.SetFontAndSize(Font, (double)Size); } /// diff --git a/src/UglyToad.PdfPig/Graphics/Operations/TextState/SetHorizontalScaling.cs b/src/UglyToad.PdfPig/Graphics/Operations/TextState/SetHorizontalScaling.cs index 86712d6c..cd6f9ec0 100644 --- a/src/UglyToad.PdfPig/Graphics/Operations/TextState/SetHorizontalScaling.cs +++ b/src/UglyToad.PdfPig/Graphics/Operations/TextState/SetHorizontalScaling.cs @@ -30,9 +30,7 @@ /// public void Run(IOperationContext operationContext) { - var currentState = operationContext.GetCurrentState(); - - currentState.FontState.HorizontalScaling = (double)Scale; + operationContext.SetHorizontalScaling((double)Scale); } /// diff --git a/src/UglyToad.PdfPig/Graphics/Operations/TextState/SetTextLeading.cs b/src/UglyToad.PdfPig/Graphics/Operations/TextState/SetTextLeading.cs index 4cdafd14..e0b6ee1a 100644 --- a/src/UglyToad.PdfPig/Graphics/Operations/TextState/SetTextLeading.cs +++ b/src/UglyToad.PdfPig/Graphics/Operations/TextState/SetTextLeading.cs @@ -33,9 +33,7 @@ /// public void Run(IOperationContext operationContext) { - var currentState = operationContext.GetCurrentState(); - - currentState.FontState.Leading = (double)Leading; + operationContext.SetTextLeading((double)Leading); } /// diff --git a/src/UglyToad.PdfPig/Graphics/Operations/TextState/SetTextRenderingMode.cs b/src/UglyToad.PdfPig/Graphics/Operations/TextState/SetTextRenderingMode.cs index 091d2261..8e4119cb 100644 --- a/src/UglyToad.PdfPig/Graphics/Operations/TextState/SetTextRenderingMode.cs +++ b/src/UglyToad.PdfPig/Graphics/Operations/TextState/SetTextRenderingMode.cs @@ -33,9 +33,7 @@ /// public void Run(IOperationContext operationContext) { - var currentState = operationContext.GetCurrentState(); - - currentState.FontState.TextRenderingMode = Mode; + operationContext.SetTextRenderingMode(Mode); } /// diff --git a/src/UglyToad.PdfPig/Graphics/Operations/TextState/SetTextRise.cs b/src/UglyToad.PdfPig/Graphics/Operations/TextState/SetTextRise.cs index 80aa78c1..4d3566da 100644 --- a/src/UglyToad.PdfPig/Graphics/Operations/TextState/SetTextRise.cs +++ b/src/UglyToad.PdfPig/Graphics/Operations/TextState/SetTextRise.cs @@ -33,9 +33,7 @@ /// public void Run(IOperationContext operationContext) { - var currentState = operationContext.GetCurrentState(); - - currentState.FontState.Rise = (double)Rise; + operationContext.SetTextRise((double)Rise); } /// diff --git a/src/UglyToad.PdfPig/Graphics/Operations/TextState/SetWordSpacing.cs b/src/UglyToad.PdfPig/Graphics/Operations/TextState/SetWordSpacing.cs index e2cfd69b..92a5af66 100644 --- a/src/UglyToad.PdfPig/Graphics/Operations/TextState/SetWordSpacing.cs +++ b/src/UglyToad.PdfPig/Graphics/Operations/TextState/SetWordSpacing.cs @@ -34,9 +34,7 @@ /// public void Run(IOperationContext operationContext) { - var currentState = operationContext.GetCurrentState(); - - currentState.FontState.WordSpacing = (double)Spacing; + operationContext.SetWordSpacing((double)Spacing); } ///