diff --git a/src/UglyToad.PdfPig.Tests/Graphics/TestOperationContext.cs b/src/UglyToad.PdfPig.Tests/Graphics/TestOperationContext.cs
index 003e9a47..5885ebf4 100644
--- a/src/UglyToad.PdfPig.Tests/Graphics/TestOperationContext.cs
+++ b/src/UglyToad.PdfPig.Tests/Graphics/TestOperationContext.cs
@@ -69,8 +69,13 @@
public void StrokePath(bool close)
{
}
- public void FillPath(bool close)
+
+ public void FillPath(FillingRule fillingRule, bool close)
{
+ }
+ public void FillStrokePath(FillingRule fillingRule, bool close)
+ {
+
}
public void ClosePath()
diff --git a/src/UglyToad.PdfPig/Graphics/ContentStreamProcessor.cs b/src/UglyToad.PdfPig/Graphics/ContentStreamProcessor.cs
index 7bb3df6f..0b480f3f 100644
--- a/src/UglyToad.PdfPig/Graphics/ContentStreamProcessor.cs
+++ b/src/UglyToad.PdfPig/Graphics/ContentStreamProcessor.cs
@@ -17,6 +17,7 @@
using Tokenization.Scanner;
using Tokens;
using XObjects;
+ using static UglyToad.PdfPig.Core.PdfSubpath;
internal class ContentStreamProcessor : IOperationContext
{
@@ -94,7 +95,14 @@
this.pageContentParser = pageContentParser ?? throw new ArgumentNullException(nameof(pageContentParser));
this.filterProvider = filterProvider ?? throw new ArgumentNullException(nameof(filterProvider));
this.log = log;
- graphicsStack.Push(new CurrentGraphicsState());
+
+ // initiate CurrentClippingPath to cropBox
+ var clippingSubpath = new PdfSubpath();
+ clippingSubpath.Rectangle(cropBox.BottomLeft.X, cropBox.BottomLeft.Y, cropBox.Width, cropBox.Height);
+ var clippingPath = new PdfPath() { clippingSubpath };
+ clippingPath.SetClipping(FillingRule.NonZeroWinding);
+
+ graphicsStack.Push(new CurrentGraphicsState() { CurrentClippingPath = clippingPath });
ColorSpaceContext = new ColorSpaceContext(GetCurrentState, resourceStore);
}
@@ -399,7 +407,41 @@
public void BeginSubpath()
{
-
+ if (CurrentPath == null)
+ {
+ CurrentPath = new PdfPath();
+ }
+
+ AddSubpath();
+ CurrentSubpath = new PdfSubpath();
+ }
+
+ public PdfPoint CloseSubpath()
+ {
+ PdfPoint point;
+ if (CurrentSubpath.Commands[0] is Move move)
+ {
+ point = move.Location;
+ }
+ else
+ {
+ throw new ArgumentException("CloseSubpath(): first command not Move.");
+ }
+
+ CurrentSubpath.ClosePath();
+ AddSubpath();
+ return point;
+ }
+
+ public void AddSubpath()
+ {
+ if (CurrentSubpath == null)
+ {
+ return;
+ }
+
+ CurrentPath.Add(CurrentSubpath);
+ CurrentSubpath = null;
}
public void StrokePath(bool close)
@@ -407,11 +449,16 @@
}
- public void FillPath(bool close)
+ public void FillPath(FillingRule fillingRule, bool close)
{
}
+ public void FillStrokePath(FillingRule fillingRule, bool close)
+ {
+
+ }
+
public void ClosePath()
{
diff --git a/src/UglyToad.PdfPig/Graphics/IOperationContext.cs b/src/UglyToad.PdfPig/Graphics/IOperationContext.cs
index 64eb1744..6482d343 100644
--- a/src/UglyToad.PdfPig/Graphics/IOperationContext.cs
+++ b/src/UglyToad.PdfPig/Graphics/IOperationContext.cs
@@ -95,8 +95,16 @@
///
/// Fill the current path.
///
+ /// The filling rule to use.
/// Whether to also close the path.
- void FillPath(bool close);
+ void FillPath(FillingRule fillingRule, bool close);
+
+ ///
+ /// Fill and stroke the current path.
+ ///
+ /// The filling rule to use.
+ /// Whether to also close the path.
+ void FillStrokePath(FillingRule fillingRule, bool close);
///
/// Close the current path.
diff --git a/src/UglyToad.PdfPig/Graphics/Operations/PathPainting/CloseFillPathEvenOddRuleAndStroke.cs b/src/UglyToad.PdfPig/Graphics/Operations/PathPainting/CloseFillPathEvenOddRuleAndStroke.cs
index 77e3fe57..b4927b4a 100644
--- a/src/UglyToad.PdfPig/Graphics/Operations/PathPainting/CloseFillPathEvenOddRuleAndStroke.cs
+++ b/src/UglyToad.PdfPig/Graphics/Operations/PathPainting/CloseFillPathEvenOddRuleAndStroke.cs
@@ -28,7 +28,7 @@
///
public void Run(IOperationContext operationContext)
{
- operationContext.FillPath(true);
+ operationContext.FillStrokePath(PdfPig.Core.FillingRule.EvenOdd, true);
}
///
diff --git a/src/UglyToad.PdfPig/Graphics/Operations/PathPainting/CloseFillPathNonZeroWindingAndStroke.cs b/src/UglyToad.PdfPig/Graphics/Operations/PathPainting/CloseFillPathNonZeroWindingAndStroke.cs
index d9fa07b7..52e30f33 100644
--- a/src/UglyToad.PdfPig/Graphics/Operations/PathPainting/CloseFillPathNonZeroWindingAndStroke.cs
+++ b/src/UglyToad.PdfPig/Graphics/Operations/PathPainting/CloseFillPathNonZeroWindingAndStroke.cs
@@ -28,7 +28,7 @@
///
public void Run(IOperationContext operationContext)
{
- operationContext.FillPath(true);
+ operationContext.FillStrokePath(PdfPig.Core.FillingRule.NonZeroWinding, true);
}
///
diff --git a/src/UglyToad.PdfPig/Graphics/Operations/PathPainting/FillPathEvenOddRule.cs b/src/UglyToad.PdfPig/Graphics/Operations/PathPainting/FillPathEvenOddRule.cs
index d475cff5..fa3614d7 100644
--- a/src/UglyToad.PdfPig/Graphics/Operations/PathPainting/FillPathEvenOddRule.cs
+++ b/src/UglyToad.PdfPig/Graphics/Operations/PathPainting/FillPathEvenOddRule.cs
@@ -28,7 +28,7 @@
///
public void Run(IOperationContext operationContext)
{
- operationContext.FillPath(false);
+ operationContext.FillPath(PdfPig.Core.FillingRule.EvenOdd, false);
}
///
diff --git a/src/UglyToad.PdfPig/Graphics/Operations/PathPainting/FillPathEvenOddRuleAndStroke.cs b/src/UglyToad.PdfPig/Graphics/Operations/PathPainting/FillPathEvenOddRuleAndStroke.cs
index 0f590bfb..92d80bd7 100644
--- a/src/UglyToad.PdfPig/Graphics/Operations/PathPainting/FillPathEvenOddRuleAndStroke.cs
+++ b/src/UglyToad.PdfPig/Graphics/Operations/PathPainting/FillPathEvenOddRuleAndStroke.cs
@@ -28,7 +28,7 @@
///
public void Run(IOperationContext operationContext)
{
- operationContext.FillPath(false);
+ operationContext.FillStrokePath(PdfPig.Core.FillingRule.EvenOdd, false);
}
///
diff --git a/src/UglyToad.PdfPig/Graphics/Operations/PathPainting/FillPathNonZeroWinding.cs b/src/UglyToad.PdfPig/Graphics/Operations/PathPainting/FillPathNonZeroWinding.cs
index 1fb1a93d..bd0efdc0 100644
--- a/src/UglyToad.PdfPig/Graphics/Operations/PathPainting/FillPathNonZeroWinding.cs
+++ b/src/UglyToad.PdfPig/Graphics/Operations/PathPainting/FillPathNonZeroWinding.cs
@@ -29,7 +29,7 @@
///
public void Run(IOperationContext operationContext)
{
- operationContext.FillPath(false);
+ operationContext.FillPath(PdfPig.Core.FillingRule.NonZeroWinding, false);
}
///
diff --git a/src/UglyToad.PdfPig/Graphics/Operations/PathPainting/FillPathNonZeroWindingAndStroke.cs b/src/UglyToad.PdfPig/Graphics/Operations/PathPainting/FillPathNonZeroWindingAndStroke.cs
index 26f1a2f0..1b254580 100644
--- a/src/UglyToad.PdfPig/Graphics/Operations/PathPainting/FillPathNonZeroWindingAndStroke.cs
+++ b/src/UglyToad.PdfPig/Graphics/Operations/PathPainting/FillPathNonZeroWindingAndStroke.cs
@@ -28,7 +28,7 @@
///
public void Run(IOperationContext operationContext)
{
- operationContext.FillPath(false);
+ operationContext.FillStrokePath(PdfPig.Core.FillingRule.NonZeroWinding, false);
}
///
diff --git a/src/UglyToad.PdfPig/Graphics/Operations/PathPainting/FillPathNonZeroWindingCompatibility.cs b/src/UglyToad.PdfPig/Graphics/Operations/PathPainting/FillPathNonZeroWindingCompatibility.cs
index e655ae55..b148ae24 100644
--- a/src/UglyToad.PdfPig/Graphics/Operations/PathPainting/FillPathNonZeroWindingCompatibility.cs
+++ b/src/UglyToad.PdfPig/Graphics/Operations/PathPainting/FillPathNonZeroWindingCompatibility.cs
@@ -15,7 +15,7 @@
public const string Symbol = "F";
///
- /// The instance of the operation.
+ /// The instance of the operation.
///
public static readonly FillPathNonZeroWindingCompatibility Value = new FillPathNonZeroWindingCompatibility();
@@ -29,13 +29,14 @@
///
public void Run(IOperationContext operationContext)
{
- operationContext.FillPath(false);
+ operationContext.FillPath(PdfPig.Core.FillingRule.NonZeroWinding, false);
}
///
public void Write(Stream stream)
{
- stream.WriteText(Symbol);
+ // Although PDF reader applications shall be able to accept this operator, PDF writer applications should use f instead.
+ stream.WriteText(FillPathNonZeroWinding.Symbol);
stream.WriteNewLine();
}