diff --git a/src/UglyToad.PdfPig.Core/PdfSubpath.cs b/src/UglyToad.PdfPig.Core/PdfSubpath.cs
index 82fbe5b8..4ed5b413 100644
--- a/src/UglyToad.PdfPig.Core/PdfSubpath.cs
+++ b/src/UglyToad.PdfPig.Core/PdfSubpath.cs
@@ -160,9 +160,9 @@
throw new ArgumentNullException("LineTo(): currentPosition is null.");
}
}
-
+
///
- /// Adds 4 s forming a rectangle to the path.
+ /// Add a rectangle following the pdf specification (m, l, l, l, c) path. A new subpath is created.
///
public void Rectangle(double x, double y, double width, double height)
{
@@ -174,8 +174,6 @@
CloseSubpath(); // h
IsDrawnAsRectangle = true;
}
-
- internal void QuadraticCurveTo(double x1, double y1, double x2, double y2) { }
///
/// Add a to the path.
diff --git a/src/UglyToad.PdfPig.Tests/Graphics/TestOperationContext.cs b/src/UglyToad.PdfPig.Tests/Graphics/TestOperationContext.cs
index d1d718c4..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
{
@@ -88,6 +90,66 @@
}
+ public void MoveTo(double x, double y)
+ {
+ BeginSubpath();
+ var point = CurrentTransformationMatrix.Transform(new PdfPoint(x, y));
+ CurrentPosition = point;
+ CurrentSubpath.MoveTo(point.X, point.Y);
+ }
+
+ public void BezierCurveTo(double x2, double y2, double x3, double y3)
+ {
+ if (CurrentSubpath == null)
+ {
+ return;
+ }
+
+ var controlPoint2 = CurrentTransformationMatrix.Transform(new PdfPoint(x2, y2));
+ var end = CurrentTransformationMatrix.Transform(new PdfPoint(x3, y3));
+
+ CurrentSubpath.BezierCurveTo(CurrentPosition.X, CurrentPosition.Y, controlPoint2.X, controlPoint2.Y, end.X, end.Y);
+ CurrentPosition = end;
+ }
+
+ public void BezierCurveTo(double x1, double y1, double x2, double y2, double x3, double y3)
+ {
+ if (CurrentSubpath == null)
+ {
+ return;
+ }
+
+ var controlPoint1 = CurrentTransformationMatrix.Transform(new PdfPoint(x1, y1));
+ var controlPoint2 = CurrentTransformationMatrix.Transform(new PdfPoint(x2, y2));
+ var end = CurrentTransformationMatrix.Transform(new PdfPoint(x3, y3));
+
+ CurrentSubpath.BezierCurveTo(controlPoint1.X, controlPoint1.Y, controlPoint2.X, controlPoint2.Y, end.X, end.Y);
+ CurrentPosition = end;
+ }
+
+ public void LineTo(double x, double y)
+ {
+ if (CurrentSubpath == null)
+ {
+ return;
+ }
+
+ var endPoint = CurrentTransformationMatrix.Transform(new PdfPoint(x, y));
+
+ CurrentSubpath.LineTo(endPoint.X, endPoint.Y);
+ CurrentPosition = endPoint;
+ }
+
+ public void Rectangle(double x, double y, double width, double height)
+ {
+ BeginSubpath();
+ var lowerLeft = CurrentTransformationMatrix.Transform(new PdfPoint(x, y));
+ var upperRight = CurrentTransformationMatrix.Transform(new PdfPoint(x + width, y + height));
+
+ CurrentSubpath.Rectangle(lowerLeft.X, lowerLeft.Y, upperRight.X - lowerLeft.X, upperRight.Y - lowerLeft.Y);
+ AddCurrentSubpath();
+ }
+
public void EndPath()
{
}
@@ -124,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.Tests/PublicApiScannerTests.cs b/src/UglyToad.PdfPig.Tests/PublicApiScannerTests.cs
index 11c8da14..8d50073e 100644
--- a/src/UglyToad.PdfPig.Tests/PublicApiScannerTests.cs
+++ b/src/UglyToad.PdfPig.Tests/PublicApiScannerTests.cs
@@ -74,6 +74,7 @@
"UglyToad.PdfPig.Content.IPdfImage",
"UglyToad.PdfPig.Content.Letter",
"UglyToad.PdfPig.Content.MarkedContentElement",
+ "UglyToad.PdfPig.Content.MediaBox",
"UglyToad.PdfPig.Content.Page",
"UglyToad.PdfPig.Content.PageRotationDegrees",
"UglyToad.PdfPig.Content.PageSize",
@@ -197,6 +198,8 @@
"UglyToad.PdfPig.ParsingOptions",
"UglyToad.PdfPig.PdfDocument",
"UglyToad.PdfPig.PdfExtensions",
+ "UglyToad.PdfPig.Rendering.IPageImageRenderer",
+ "UglyToad.PdfPig.Rendering.PdfRendererImageFormat",
"UglyToad.PdfPig.Structure",
"UglyToad.PdfPig.Util.Adler32Checksum",
"UglyToad.PdfPig.Util.IWordExtractor",
diff --git a/src/UglyToad.PdfPig.Tokens/NameToken.Constants.cs b/src/UglyToad.PdfPig.Tokens/NameToken.Constants.cs
index 5af9c9fc..08af7bbb 100644
--- a/src/UglyToad.PdfPig.Tokens/NameToken.Constants.cs
+++ b/src/UglyToad.PdfPig.Tokens/NameToken.Constants.cs
@@ -338,6 +338,7 @@
public static readonly NameToken MarkInfo = new NameToken("MarkInfo");
public static readonly NameToken Mask = new NameToken("Mask");
public static readonly NameToken Matrix = new NameToken("Matrix");
+ public static readonly NameToken Matte = new NameToken("Matte");
public static readonly NameToken MaxLen = new NameToken("MaxLen");
public static readonly NameToken MaxWidth = new NameToken("MaxWidth");
public static readonly NameToken Mcid = new NameToken("MCID");
diff --git a/src/UglyToad.PdfPig/Content/MediaBox.cs b/src/UglyToad.PdfPig/Content/MediaBox.cs
index e72687c0..21ea25cb 100644
--- a/src/UglyToad.PdfPig/Content/MediaBox.cs
+++ b/src/UglyToad.PdfPig/Content/MediaBox.cs
@@ -9,7 +9,7 @@
///
/// See table 3.27 from the PDF specification version 1.7.
///
- internal class MediaBox
+ public class MediaBox
{
///
/// User space units per inch.
@@ -66,8 +66,14 @@
///
public static readonly MediaBox A6 = new MediaBox(new PdfRectangle(0, 0, 105 * PointsPerMm, 148 * PointsPerMm));
+ ///
+ /// A rectangle, expressed in default user space units, that defines the boundaries of the physical medium on which the page shall be displayed or printed.
+ ///
public PdfRectangle Bounds { get; }
+ ///
+ /// Create a new .
+ ///
public MediaBox(PdfRectangle? bounds)
{
Bounds = bounds ?? throw new ArgumentNullException(nameof(bounds));
diff --git a/src/UglyToad.PdfPig/Content/Page.cs b/src/UglyToad.PdfPig/Content/Page.cs
index f611bd1e..9268147e 100644
--- a/src/UglyToad.PdfPig/Content/Page.cs
+++ b/src/UglyToad.PdfPig/Content/Page.cs
@@ -35,7 +35,10 @@
///
public CropBox CropBox { get; }
- internal MediaBox MediaBox { get; }
+ ///
+ /// Defines the boundaries of the physical medium on which the page shall be displayed or printed.
+ ///
+ public MediaBox MediaBox { get; }
internal PageContent Content { get; }
diff --git a/src/UglyToad.PdfPig/Graphics/ContentStreamProcessor.cs b/src/UglyToad.PdfPig/Graphics/ContentStreamProcessor.cs
index 15597ccc..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;
@@ -560,7 +561,67 @@
ClosePath();
}
-
+
+ public void MoveTo(double x, double y)
+ {
+ BeginSubpath();
+ var point = CurrentTransformationMatrix.Transform(new PdfPoint(x, y));
+ CurrentPosition = point;
+ CurrentSubpath.MoveTo(point.X, point.Y);
+ }
+
+ public void BezierCurveTo(double x2, double y2, double x3, double y3)
+ {
+ if (CurrentSubpath == null)
+ {
+ return;
+ }
+
+ var controlPoint2 = CurrentTransformationMatrix.Transform(new PdfPoint(x2, y2));
+ var end = CurrentTransformationMatrix.Transform(new PdfPoint(x3, y3));
+
+ CurrentSubpath.BezierCurveTo(CurrentPosition.X, CurrentPosition.Y, controlPoint2.X, controlPoint2.Y, end.X, end.Y);
+ CurrentPosition = end;
+ }
+
+ public void BezierCurveTo(double x1, double y1, double x2, double y2, double x3, double y3)
+ {
+ if (CurrentSubpath == null)
+ {
+ return;
+ }
+
+ var controlPoint1 = CurrentTransformationMatrix.Transform(new PdfPoint(x1, y1));
+ var controlPoint2 = CurrentTransformationMatrix.Transform(new PdfPoint(x2, y2));
+ var end = CurrentTransformationMatrix.Transform(new PdfPoint(x3, y3));
+
+ CurrentSubpath.BezierCurveTo(controlPoint1.X, controlPoint1.Y, controlPoint2.X, controlPoint2.Y, end.X, end.Y);
+ CurrentPosition = end;
+ }
+
+ public void LineTo(double x, double y)
+ {
+ if (CurrentSubpath == null)
+ {
+ return;
+ }
+
+ var endPoint = CurrentTransformationMatrix.Transform(new PdfPoint(x, y));
+
+ CurrentSubpath.LineTo(endPoint.X, endPoint.Y);
+ CurrentPosition = endPoint;
+ }
+
+ public void Rectangle(double x, double y, double width, double height)
+ {
+ BeginSubpath();
+ var lowerLeft = CurrentTransformationMatrix.Transform(new PdfPoint(x, y));
+ var upperRight = CurrentTransformationMatrix.Transform(new PdfPoint(x + width, y + height));
+
+ CurrentSubpath.Rectangle(lowerLeft.X, lowerLeft.Y, upperRight.X - lowerLeft.X, upperRight.Y - lowerLeft.Y);
+ AddCurrentSubpath();
+ }
+
public void EndPath()
{
if (CurrentPath == null)
@@ -744,7 +805,10 @@
if (markedContentStack.CanPop)
{
var mc = markedContentStack.Pop(pdfScanner);
- if (mc != null) markedContents.Add(mc);
+ if (mc != null)
+ {
+ markedContents.Add(mc);
+ }
}
}
@@ -752,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 f08e16f3..8d5fd62f 100644
--- a/src/UglyToad.PdfPig/Graphics/IOperationContext.cs
+++ b/src/UglyToad.PdfPig/Graphics/IOperationContext.cs
@@ -3,25 +3,13 @@
using PdfPig.Core;
using System.Collections.Generic;
using Tokens;
- using Util.JetBrains.Annotations;
+ using UglyToad.PdfPig.Graphics.Core;
///
/// The current graphics state context when running a PDF content stream.
///
public interface IOperationContext
{
- ///
- /// The current subpath being drawn if applicable.
- ///
- [CanBeNull]
- PdfSubpath CurrentSubpath { get; }
-
- ///
- /// The current path being drawn if applicable.
- ///
- [CanBeNull]
- PdfPath CurrentPath { get; }
-
///
/// The active colorspaces for this content stream.
///
@@ -32,22 +20,11 @@
///
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.
///
TextMatrices TextMatrices { get; }
- ///
- /// The current transformation matrix
- ///
- TransformationMatrix CurrentTransformationMatrix { get; }
-
///
/// The number of graphics states on the stack.
///
@@ -59,7 +36,7 @@
void PopState();
///
- /// Saves a copy of the current graphics state on the stack.
+ /// Saves a copy of the current graphics state on the stack.
///
void PushState();
@@ -85,7 +62,7 @@
/// Start a new sub-path.
///
void BeginSubpath();
-
+
///
/// Close the current subpath.
///
@@ -116,6 +93,36 @@
/// Whether to also close the path.
void FillStrokePath(FillingRule fillingRule, bool close);
+ ///
+ /// Add a move command to the path.
+ /// Should implement matrix transformations.
+ ///
+ void MoveTo(double x, double y);
+
+ ///
+ /// Add a bezier curve to the current subpath.
+ /// Should implement matrix transformations.
+ ///
+ void BezierCurveTo(double x1, double y1, double x2, double y2, double x3, double y3);
+
+ ///
+ /// Add a bezier curve to the current subpath.
+ /// Should implement matrix transformations.
+ ///
+ void BezierCurveTo(double x2, double y2, double x3, double y3);
+
+ ///
+ /// Add a line command to the subpath.
+ /// Should implement matrix transformations.
+ ///
+ void LineTo(double x, double y);
+
+ ///
+ /// Add a rectangle following the pdf specification (m, l, l, l, c) path. A new subpath will be created.
+ /// Should implement matrix transformations.
+ ///
+ void Rectangle(double x, double y, double width, double height);
+
///
/// End the path object without filling or stroking it. This operator shall be a path-painting no-op,
/// used primarily for the side effect of changing the current clipping path (see 8.5.4, "Clipping Path Operators").
@@ -162,5 +169,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/IGraphicsStateOperation.cs b/src/UglyToad.PdfPig/Graphics/Operations/IGraphicsStateOperation.cs
index d08c54e8..80dbcbe2 100644
--- a/src/UglyToad.PdfPig/Graphics/Operations/IGraphicsStateOperation.cs
+++ b/src/UglyToad.PdfPig/Graphics/Operations/IGraphicsStateOperation.cs
@@ -20,6 +20,7 @@
///
/// Applies the operation to the current context with the provided resources.
+ /// Matrix transformations should be implemented in .
///
///
void Run(IOperationContext operationContext);
diff --git a/src/UglyToad.PdfPig/Graphics/Operations/PathConstruction/AppendDualControlPointBezierCurve.cs b/src/UglyToad.PdfPig/Graphics/Operations/PathConstruction/AppendDualControlPointBezierCurve.cs
index 0c2a6b72..0b308a6b 100644
--- a/src/UglyToad.PdfPig/Graphics/Operations/PathConstruction/AppendDualControlPointBezierCurve.cs
+++ b/src/UglyToad.PdfPig/Graphics/Operations/PathConstruction/AppendDualControlPointBezierCurve.cs
@@ -71,14 +71,7 @@
///
public void Run(IOperationContext operationContext)
{
- if (operationContext.CurrentSubpath == null) return;
-
- var controlPoint1 = operationContext.CurrentTransformationMatrix.Transform(new PdfPoint(X1, Y1));
- var controlPoint2 = operationContext.CurrentTransformationMatrix.Transform(new PdfPoint(X2, Y2));
- var end = operationContext.CurrentTransformationMatrix.Transform(new PdfPoint(X3, Y3));
- operationContext.CurrentSubpath.BezierCurveTo(controlPoint1.X, controlPoint1.Y,
- controlPoint2.X, controlPoint2.Y, end.X, end.Y);
- operationContext.CurrentPosition = end;
+ operationContext.BezierCurveTo((double)X1, (double)Y1, (double)X2, (double)Y2, (double)X3, (double)Y3);
}
///
diff --git a/src/UglyToad.PdfPig/Graphics/Operations/PathConstruction/AppendEndControlPointBezierCurve.cs b/src/UglyToad.PdfPig/Graphics/Operations/PathConstruction/AppendEndControlPointBezierCurve.cs
index e1a2622a..ef7a7640 100644
--- a/src/UglyToad.PdfPig/Graphics/Operations/PathConstruction/AppendEndControlPointBezierCurve.cs
+++ b/src/UglyToad.PdfPig/Graphics/Operations/PathConstruction/AppendEndControlPointBezierCurve.cs
@@ -56,12 +56,7 @@
///
public void Run(IOperationContext operationContext)
{
- if (operationContext.CurrentSubpath == null) return;
-
- var controlPoint1 = operationContext.CurrentTransformationMatrix.Transform(new PdfPoint(X1, Y1));
- var end = operationContext.CurrentTransformationMatrix.Transform(new PdfPoint(X3, Y3));
- operationContext.CurrentSubpath.BezierCurveTo(controlPoint1.X, controlPoint1.Y, end.X, end.Y, end.X, end.Y);
- operationContext.CurrentPosition = end;
+ operationContext.BezierCurveTo((double)X1, (double)Y1, (double)X3, (double)Y3, (double)X3, (double)Y3);
}
///
diff --git a/src/UglyToad.PdfPig/Graphics/Operations/PathConstruction/AppendRectangle.cs b/src/UglyToad.PdfPig/Graphics/Operations/PathConstruction/AppendRectangle.cs
index 1d730502..674f83cf 100644
--- a/src/UglyToad.PdfPig/Graphics/Operations/PathConstruction/AppendRectangle.cs
+++ b/src/UglyToad.PdfPig/Graphics/Operations/PathConstruction/AppendRectangle.cs
@@ -56,12 +56,7 @@
///
public void Run(IOperationContext operationContext)
{
- operationContext.BeginSubpath();
- var lowerLeft = operationContext.CurrentTransformationMatrix.Transform(new PdfPoint(LowerLeftX, LowerLeftY));
- var upperRight = operationContext.CurrentTransformationMatrix.Transform(new PdfPoint(LowerLeftX + Width, LowerLeftY + Height));
-
- operationContext.CurrentSubpath.Rectangle(lowerLeft.X, lowerLeft.Y, upperRight.X - lowerLeft.X, upperRight.Y - lowerLeft.Y);
- operationContext.AddCurrentSubpath();
+ operationContext.Rectangle((double)LowerLeftX, (double)LowerLeftY, (double)Width, (double)Height);
}
///
diff --git a/src/UglyToad.PdfPig/Graphics/Operations/PathConstruction/AppendStartControlPointBezierCurve.cs b/src/UglyToad.PdfPig/Graphics/Operations/PathConstruction/AppendStartControlPointBezierCurve.cs
index 22c03bb4..6c59c113 100644
--- a/src/UglyToad.PdfPig/Graphics/Operations/PathConstruction/AppendStartControlPointBezierCurve.cs
+++ b/src/UglyToad.PdfPig/Graphics/Operations/PathConstruction/AppendStartControlPointBezierCurve.cs
@@ -56,17 +56,7 @@
///
public void Run(IOperationContext operationContext)
{
- if (operationContext.CurrentSubpath == null) return;
-
- var controlPoint2 = operationContext.CurrentTransformationMatrix.Transform(new PdfPoint(X2, Y2));
- var end = operationContext.CurrentTransformationMatrix.Transform(new PdfPoint(X3, Y3));
- operationContext.CurrentSubpath.BezierCurveTo(operationContext.CurrentPosition.X,
- operationContext.CurrentPosition.Y,
- controlPoint2.X,
- controlPoint2.Y,
- end.X,
- end.Y);
- operationContext.CurrentPosition = end;
+ operationContext.BezierCurveTo((double)X2, (double)Y2, (double)X3, (double)Y3);
}
///
diff --git a/src/UglyToad.PdfPig/Graphics/Operations/PathConstruction/AppendStraightLineSegment.cs b/src/UglyToad.PdfPig/Graphics/Operations/PathConstruction/AppendStraightLineSegment.cs
index efb33483..51365770 100644
--- a/src/UglyToad.PdfPig/Graphics/Operations/PathConstruction/AppendStraightLineSegment.cs
+++ b/src/UglyToad.PdfPig/Graphics/Operations/PathConstruction/AppendStraightLineSegment.cs
@@ -41,11 +41,7 @@
///
public void Run(IOperationContext operationContext)
{
- if (operationContext.CurrentSubpath == null) return;
-
- var endPoint = operationContext.CurrentTransformationMatrix.Transform(new PdfPoint(X, Y));
- operationContext.CurrentSubpath.LineTo(endPoint.X, endPoint.Y);
- operationContext.CurrentPosition = endPoint;
+ operationContext.LineTo((double)X, (double)Y);
}
///
diff --git a/src/UglyToad.PdfPig/Graphics/Operations/PathConstruction/BeginNewSubpath.cs b/src/UglyToad.PdfPig/Graphics/Operations/PathConstruction/BeginNewSubpath.cs
index d1dc1bac..88b05374 100644
--- a/src/UglyToad.PdfPig/Graphics/Operations/PathConstruction/BeginNewSubpath.cs
+++ b/src/UglyToad.PdfPig/Graphics/Operations/PathConstruction/BeginNewSubpath.cs
@@ -41,10 +41,7 @@
///
public void Run(IOperationContext operationContext)
{
- operationContext.BeginSubpath();
- var point = operationContext.CurrentTransformationMatrix.Transform(new PdfPoint(X, Y));
- operationContext.CurrentPosition = point;
- operationContext.CurrentSubpath.MoveTo(point.X, point.Y);
+ operationContext.MoveTo((double)X, (double)Y);
}
///
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);
}
///
diff --git a/src/UglyToad.PdfPig/Rendering/IPageImageRenderer.cs b/src/UglyToad.PdfPig/Rendering/IPageImageRenderer.cs
new file mode 100644
index 00000000..a5509811
--- /dev/null
+++ b/src/UglyToad.PdfPig/Rendering/IPageImageRenderer.cs
@@ -0,0 +1,19 @@
+using UglyToad.PdfPig.Content;
+
+namespace UglyToad.PdfPig.Rendering
+{
+ ///
+ /// Render page as an image.
+ ///
+ public interface IPageImageRenderer
+ {
+ ///
+ /// Render page as an image.
+ ///
+ /// The pdf page.
+ /// The scale to apply to the page (i.e. zoom level).
+ /// The output image format, if supported.
+ /// The image as a memory stream.
+ byte[] Render(Page page, double scale, PdfRendererImageFormat imageFormat);
+ }
+}
diff --git a/src/UglyToad.PdfPig/Rendering/PdfRendererImageFormat.cs b/src/UglyToad.PdfPig/Rendering/PdfRendererImageFormat.cs
new file mode 100644
index 00000000..84cd8b29
--- /dev/null
+++ b/src/UglyToad.PdfPig/Rendering/PdfRendererImageFormat.cs
@@ -0,0 +1,33 @@
+namespace UglyToad.PdfPig.Rendering
+{
+ ///
+ /// The output image format of the .
+ ///
+ public enum PdfRendererImageFormat : byte
+ {
+ ///
+ /// Bitmap image format.
+ ///
+ Bmp,
+
+ ///
+ /// Jpeg/Jpg image format.
+ ///
+ Jpeg,
+
+ ///
+ /// Png image format.
+ ///
+ Png,
+
+ ///
+ /// Tiff image format.
+ ///
+ Tiff,
+
+ ///
+ /// Gif image format.
+ ///
+ Gif
+ }
+}