diff --git a/src/UglyToad.PdfPig.Tests/Integration/Documents/Publication_of_award_of_Bids_for_Transport_Sector__August_2016.pdf b/src/UglyToad.PdfPig.Tests/Integration/Documents/Publication_of_award_of_Bids_for_Transport_Sector__August_2016.pdf new file mode 100644 index 00000000..64cf98bd Binary files /dev/null and b/src/UglyToad.PdfPig.Tests/Integration/Documents/Publication_of_award_of_Bids_for_Transport_Sector__August_2016.pdf differ diff --git a/src/UglyToad.PdfPig.Tests/Integration/WrongPathCountClippingTests.cs b/src/UglyToad.PdfPig.Tests/Integration/WrongPathCountClippingTests.cs new file mode 100644 index 00000000..2ec66288 --- /dev/null +++ b/src/UglyToad.PdfPig.Tests/Integration/WrongPathCountClippingTests.cs @@ -0,0 +1,22 @@ +namespace UglyToad.PdfPig.Tests.Integration +{ + using Xunit; + + public class WrongPathCountClippingTests + { + [Fact] + public void WrongPathCount() + { + using (var document = PdfDocument.Open(IntegrationHelpers.GetDocumentPath("Publication_of_award_of_Bids_for_Transport_Sector__August_2016.pdf"), + new ParsingOptions() + { + ClipPaths = true + })) + { + var page = document.GetPage(1); + Assert.Equal(612, page.Height); + Assert.Equal(224, page.ExperimentalAccess.Paths.Count); + } + } + } +} diff --git a/src/UglyToad.PdfPig/Graphics/ContentStreamProcessor.cs b/src/UglyToad.PdfPig/Graphics/ContentStreamProcessor.cs index 7412b769..dcc9be2d 100644 --- a/src/UglyToad.PdfPig/Graphics/ContentStreamProcessor.cs +++ b/src/UglyToad.PdfPig/Graphics/ContentStreamProcessor.cs @@ -103,20 +103,35 @@ this.filterProvider = filterProvider ?? throw new ArgumentNullException(nameof(filterProvider)); this.parsingOptions = parsingOptions; - // initiate CurrentClippingPath to cropBox - var clippingSubpath = new PdfSubpath(); - clippingSubpath.Rectangle(cropBox.Bounds.BottomLeft.X, cropBox.Bounds.BottomLeft.Y, cropBox.Bounds.Width, cropBox.Bounds.Height); - var clippingPath = new PdfPath() { clippingSubpath }; - clippingPath.SetClipping(FillingRule.EvenOdd); + TransformationMatrix initialMatrix = GetInitialMatrix(userSpaceUnit, mediaBox, cropBox, rotation, parsingOptions.Logger); graphicsStack.Push(new CurrentGraphicsState() { - CurrentTransformationMatrix = GetInitialMatrix(userSpaceUnit, mediaBox, cropBox, rotation, parsingOptions.Logger), - CurrentClippingPath = clippingPath, + CurrentTransformationMatrix = initialMatrix, + CurrentClippingPath = GetInitialClipping(cropBox, initialMatrix), ColorSpaceContext = new ColorSpaceContext(GetCurrentState, resourceStore) }); } + /// + /// Get the initial clipping path using the crop box and the initial transformation matrix. + /// + private static PdfPath GetInitialClipping(CropBox cropBox, TransformationMatrix initialMatrix) + { + var transformedCropBox = initialMatrix.Transform(cropBox.Bounds); + + // We re-compute width and height to get possible negative values. + double width = transformedCropBox.TopRight.X - transformedCropBox.BottomLeft.X; + double height = transformedCropBox.TopRight.Y - transformedCropBox.BottomLeft.Y; + + // initiate CurrentClippingPath to cropBox + var clippingSubpath = new PdfSubpath(); + clippingSubpath.Rectangle(transformedCropBox.BottomLeft.X, transformedCropBox.BottomLeft.Y, width, height); + var clippingPath = new PdfPath() { clippingSubpath }; + clippingPath.SetClipping(FillingRule.EvenOdd); + return clippingPath; + } + [System.Diagnostics.Contracts.Pure] internal static TransformationMatrix GetInitialMatrix(UserSpaceUnit userSpaceUnit, MediaBox mediaBox, @@ -129,7 +144,7 @@ var viewBox = mediaBox.Bounds.Intersect(cropBox.Bounds) ?? cropBox.Bounds; if (rotation.Value == 0 - && viewBox.Left == 0 + && viewBox.Left == 0 && viewBox.Bottom == 0 && userSpaceUnit.PointMultiples == 1) {