Implement EndPath

Make path clipping optional
This commit is contained in:
BobLd
2020-04-02 17:51:43 +01:00
committed by Eliot Jones
parent a7fe39fc32
commit 51165dc11a
9 changed files with 45 additions and 30 deletions

View File

@@ -65,6 +65,7 @@
public void BeginSubpath() public void BeginSubpath()
{ {
} }
public PdfPoint CloseSubpath() public PdfPoint CloseSubpath()
{ {
return new PdfPoint(); return new PdfPoint();
@@ -87,6 +88,10 @@
} }
public void EndPath()
{
}
public void ClosePath() public void ClosePath()
{ {
} }

View File

@@ -4,6 +4,6 @@
internal interface IPageFactory internal interface IPageFactory
{ {
Page Create(int number, DictionaryToken dictionary, PageTreeMembers pageTreeMembers); Page Create(int number, DictionaryToken dictionary, PageTreeMembers pageTreeMembers, bool clipPaths);
} }
} }

View File

@@ -23,7 +23,7 @@
Count = catalog.PagesDictionary.GetIntOrDefault(NameToken.Count); Count = catalog.PagesDictionary.GetIntOrDefault(NameToken.Count);
} }
public Page GetPage(int pageNumber) public Page GetPage(int pageNumber, bool clipPaths)
{ {
if (pageNumber <= 0 || pageNumber > Count) if (pageNumber <= 0 || pageNumber > Count)
{ {
@@ -63,7 +63,7 @@
} }
} }
var page = pageFactory.Create(pageNumber, pageNode.NodeDictionary, pageTreeMembers); var page = pageFactory.Create(pageNumber, pageNode.NodeDictionary, pageTreeMembers, clipPaths);
return page; return page;
} }

View File

@@ -48,6 +48,7 @@
private readonly IPageContentParser pageContentParser; private readonly IPageContentParser pageContentParser;
private readonly IFilterProvider filterProvider; private readonly IFilterProvider filterProvider;
private readonly ILog log; private readonly ILog log;
private readonly bool clipPaths;
private readonly MarkedContentStack markedContentStack = new MarkedContentStack(); private readonly MarkedContentStack markedContentStack = new MarkedContentStack();
private Stack<CurrentGraphicsState> graphicsStack = new Stack<CurrentGraphicsState>(); private Stack<CurrentGraphicsState> graphicsStack = new Stack<CurrentGraphicsState>();
@@ -86,7 +87,8 @@
IPdfTokenScanner pdfScanner, IPdfTokenScanner pdfScanner,
IPageContentParser pageContentParser, IPageContentParser pageContentParser,
IFilterProvider filterProvider, IFilterProvider filterProvider,
ILog log) ILog log,
bool clipPaths)
{ {
this.resourceStore = resourceStore; this.resourceStore = resourceStore;
this.userSpaceUnit = userSpaceUnit; this.userSpaceUnit = userSpaceUnit;
@@ -95,6 +97,7 @@
this.pageContentParser = pageContentParser ?? throw new ArgumentNullException(nameof(pageContentParser)); this.pageContentParser = pageContentParser ?? throw new ArgumentNullException(nameof(pageContentParser));
this.filterProvider = filterProvider ?? throw new ArgumentNullException(nameof(filterProvider)); this.filterProvider = filterProvider ?? throw new ArgumentNullException(nameof(filterProvider));
this.log = log; this.log = log;
this.clipPaths = clipPaths;
// initiate CurrentClippingPath to cropBox // initiate CurrentClippingPath to cropBox
var clippingSubpath = new PdfSubpath(); var clippingSubpath = new PdfSubpath();
@@ -509,12 +512,12 @@
if (CurrentPath.IsClipping) if (CurrentPath.IsClipping)
{ {
/*if (!clipPaths) if (!clipPaths)
{ {
// if we don't clip paths, add clipping paths // if we don't clip paths, add clipping paths
paths.Add(CurrentPath); paths.Add(CurrentPath);
markedContentStack.AddPath(CurrentPath); markedContentStack.AddPath(CurrentPath);
}*/ }
CurrentPath = null; CurrentPath = null;
return; return;
} }
@@ -549,20 +552,20 @@
CurrentPath.FillColor = currentState.CurrentNonStrokingColor; CurrentPath.FillColor = currentState.CurrentNonStrokingColor;
} }
//if (clipPaths) if (clipPaths)
//{ {
var clippedPath = currentState.CurrentClippingPath.Clip(CurrentPath); var clippedPath = currentState.CurrentClippingPath.Clip(CurrentPath);
if (clippedPath != null) if (clippedPath != null)
{ {
paths.Add(clippedPath); paths.Add(clippedPath);
markedContentStack.AddPath(clippedPath); markedContentStack.AddPath(clippedPath);
} }
/*} }
else else
{ {
paths.Add(CurrentPath); paths.Add(CurrentPath);
markedContentStack.AddPath(CurrentPath); markedContentStack.AddPath(CurrentPath);
}*/ }
CurrentPath = null; CurrentPath = null;
} }

View File

@@ -117,6 +117,12 @@
/// <param name="close">Whether to also close the path.</param> /// <param name="close">Whether to also close the path.</param>
void FillStrokePath(FillingRule fillingRule, bool close); void FillStrokePath(FillingRule fillingRule, bool close);
/// <summary>
/// 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").
/// </summary>
void EndPath();
/// <summary> /// <summary>
/// Close the current path. /// Close the current path.
/// </summary> /// </summary>

View File

@@ -56,17 +56,15 @@
/// <inheritdoc /> /// <inheritdoc />
public void Run(IOperationContext operationContext) public void Run(IOperationContext operationContext)
{ {
var controlPoint2 = new PdfPoint(X2, Y2); var controlPoint2 = operationContext.CurrentTransformationMatrix.Transform(new PdfPoint(X2, Y2));
var end = new PdfPoint(X3, Y3); var end = operationContext.CurrentTransformationMatrix.Transform(new PdfPoint(X3, Y3));
var controlPoint2Transform = operationContext.CurrentTransformationMatrix.Transform(controlPoint2);
var endTransform = operationContext.CurrentTransformationMatrix.Transform(end);
operationContext.CurrentSubpath.BezierCurveTo(operationContext.CurrentPosition.X, operationContext.CurrentSubpath.BezierCurveTo(operationContext.CurrentPosition.X,
operationContext.CurrentPosition.Y, operationContext.CurrentPosition.Y,
controlPoint2Transform.X, controlPoint2.X,
controlPoint2Transform.Y, controlPoint2.Y,
endTransform.X, end.X,
endTransform.Y); end.Y);
operationContext.CurrentPosition = endTransform; operationContext.CurrentPosition = end;
} }
/// <inheritdoc /> /// <inheritdoc />

View File

@@ -28,6 +28,7 @@
/// <inheritdoc /> /// <inheritdoc />
public void Run(IOperationContext operationContext) public void Run(IOperationContext operationContext)
{ {
operationContext.EndPath();
} }
/// <inheritdoc /> /// <inheritdoc />

View File

@@ -33,7 +33,7 @@
this.pdfScanner = pdfScanner; this.pdfScanner = pdfScanner;
} }
public Page Create(int number, DictionaryToken dictionary, PageTreeMembers pageTreeMembers) public Page Create(int number, DictionaryToken dictionary, PageTreeMembers pageTreeMembers, bool clipPaths)
{ {
if (dictionary == null) if (dictionary == null)
{ {
@@ -108,7 +108,7 @@
} }
} }
content = GetContent(number, bytes, cropBox, userSpaceUnit, rotation); content = GetContent(number, bytes, cropBox, userSpaceUnit, rotation, clipPaths);
} }
else else
{ {
@@ -121,7 +121,7 @@
var bytes = contentStream.Decode(filterProvider); var bytes = contentStream.Decode(filterProvider);
content = GetContent(number, bytes, cropBox, userSpaceUnit, rotation); content = GetContent(number, bytes, cropBox, userSpaceUnit, rotation, clipPaths);
} }
var page = new Page(number, dictionary, mediaBox, cropBox, rotation, content, var page = new Page(number, dictionary, mediaBox, cropBox, rotation, content,
@@ -137,7 +137,7 @@
} }
private PageContent GetContent(int pageNumber, IReadOnlyList<byte> contentBytes, CropBox cropBox, UserSpaceUnit userSpaceUnit, private PageContent GetContent(int pageNumber, IReadOnlyList<byte> contentBytes, CropBox cropBox, UserSpaceUnit userSpaceUnit,
PageRotationDegrees rotation) PageRotationDegrees rotation, bool clipPaths)
{ {
var operations = pageContentParser.Parse(pageNumber, new ByteArrayInputBytes(contentBytes), var operations = pageContentParser.Parse(pageNumber, new ByteArrayInputBytes(contentBytes),
log); log);
@@ -145,7 +145,8 @@
var context = new ContentStreamProcessor(cropBox.Bounds, resourceStore, userSpaceUnit, rotation, pdfScanner, var context = new ContentStreamProcessor(cropBox.Bounds, resourceStore, userSpaceUnit, rotation, pdfScanner,
pageContentParser, pageContentParser,
filterProvider, filterProvider,
log); log,
clipPaths);
return context.Process(pageNumber, operations); return context.Process(pageNumber, operations);
} }

View File

@@ -141,8 +141,9 @@
/// Get the page with the specified page number (1 indexed). /// Get the page with the specified page number (1 indexed).
/// </summary> /// </summary>
/// <param name="pageNumber">The number of the page to return, this starts from 1.</param> /// <param name="pageNumber">The number of the page to return, this starts from 1.</param>
/// <param name="clipPaths">Paths will be clipped if set to true. Default is false.</param>
/// <returns>The page.</returns> /// <returns>The page.</returns>
public Page GetPage(int pageNumber) public Page GetPage(int pageNumber, bool clipPaths = false)
{ {
if (isDisposed) if (isDisposed)
{ {
@@ -153,7 +154,7 @@
try try
{ {
return pages.GetPage(pageNumber); return pages.GetPage(pageNumber, clipPaths);
} }
catch (Exception ex) catch (Exception ex)
{ {