mirror of
https://github.com/UglyToad/PdfPig.git
synced 2025-09-20 20:07:57 +08:00
Added "Paths" collection to Page object.
Added matrix transformation to path operators.
This commit is contained in:
@@ -9,6 +9,7 @@
|
||||
using Util;
|
||||
using Util.JetBrains.Annotations;
|
||||
using XObjects;
|
||||
using UglyToad.PdfPig.Geometry;
|
||||
|
||||
/// <summary>
|
||||
/// Contains the content and provides access to methods of a single page in the <see cref="PdfDocument"/>.
|
||||
@@ -41,6 +42,11 @@
|
||||
/// </summary>
|
||||
public IReadOnlyList<Letter> Letters => Content?.Letters ?? new Letter[0];
|
||||
|
||||
/// <summary>
|
||||
/// The set of <see cref="PdfPath"/>s drawn by the PDF content.
|
||||
/// </summary>
|
||||
public List<PdfPath> Paths => Content?.Paths ?? new List<PdfPath>();
|
||||
|
||||
/// <summary>
|
||||
/// The full text of all characters on the page in the order they are presented in the PDF content.
|
||||
/// </summary>
|
||||
|
@@ -5,6 +5,7 @@
|
||||
using Graphics.Operations;
|
||||
using Tokenization.Scanner;
|
||||
using XObjects;
|
||||
using UglyToad.PdfPig.Geometry;
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
@@ -23,8 +24,9 @@
|
||||
internal IReadOnlyList<IGraphicsStateOperation> GraphicsStateOperations { get; }
|
||||
|
||||
public IReadOnlyList<Letter> Letters { get; }
|
||||
public List<PdfPath> Paths { get; }
|
||||
|
||||
internal PageContent(IReadOnlyList<IGraphicsStateOperation> graphicsStateOperations, IReadOnlyList<Letter> letters,
|
||||
internal PageContent(IReadOnlyList<IGraphicsStateOperation> graphicsStateOperations, IReadOnlyList<Letter> letters, List<PdfPath> paths,
|
||||
IReadOnlyDictionary<XObjectType, List<XObjectContentRecord>> xObjects,
|
||||
IPdfTokenScanner pdfScanner,
|
||||
XObjectFactory xObjectFactory,
|
||||
@@ -32,6 +34,7 @@
|
||||
{
|
||||
GraphicsStateOperations = graphicsStateOperations;
|
||||
Letters = letters;
|
||||
Paths = paths;
|
||||
this.xObjects = xObjects;
|
||||
this.pdfScanner = pdfScanner;
|
||||
this.xObjectFactory = xObjectFactory;
|
||||
|
@@ -5,27 +5,29 @@ namespace UglyToad.PdfPig.Geometry
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using UglyToad.PdfPig.Core;
|
||||
|
||||
/// <summary>
|
||||
/// A path in a PDF document, used by glyphs and page content.
|
||||
/// </summary>
|
||||
public class PdfPath
|
||||
{
|
||||
private readonly List<IPathCommand> commands = new List<IPathCommand>();
|
||||
public readonly List<IPathCommand> Commands = new List<IPathCommand>();
|
||||
private PdfPoint? currentPosition;
|
||||
internal TransformationMatrix CurrentTransformationMatrix;
|
||||
|
||||
internal void MoveTo(decimal x, decimal y)
|
||||
{
|
||||
currentPosition = new PdfPoint(x, y);
|
||||
commands.Add(new Move(currentPosition.Value));
|
||||
currentPosition = CurrentTransformationMatrix.Transform(new PdfPoint(x, y));
|
||||
Commands.Add(new Move(currentPosition.Value));
|
||||
}
|
||||
|
||||
internal void LineTo(decimal x, decimal y)
|
||||
{
|
||||
if (currentPosition.HasValue)
|
||||
{
|
||||
var to = new PdfPoint(x, y);
|
||||
commands.Add(new Line(currentPosition.Value, to));
|
||||
var to = CurrentTransformationMatrix.Transform(new PdfPoint(x, y));
|
||||
Commands.Add(new Line(currentPosition.Value, to));
|
||||
currentPosition = to;
|
||||
}
|
||||
else
|
||||
@@ -40,9 +42,9 @@ namespace UglyToad.PdfPig.Geometry
|
||||
{
|
||||
if (currentPosition.HasValue)
|
||||
{
|
||||
var to = new PdfPoint(x3, y3);
|
||||
commands.Add(new BezierCurve(currentPosition.Value,
|
||||
new PdfPoint(x1, y1), new PdfPoint(x2, y2), to));
|
||||
var to = CurrentTransformationMatrix.Transform(new PdfPoint(x3, y3));
|
||||
Commands.Add(new BezierCurve(currentPosition.Value,
|
||||
CurrentTransformationMatrix.Transform(new PdfPoint(x1, y1)), CurrentTransformationMatrix.Transform(new PdfPoint(x2, y2)), to));
|
||||
currentPosition = to;
|
||||
}
|
||||
else
|
||||
@@ -55,12 +57,12 @@ namespace UglyToad.PdfPig.Geometry
|
||||
|
||||
internal void ClosePath()
|
||||
{
|
||||
commands.Add(new Close());
|
||||
Commands.Add(new Close());
|
||||
}
|
||||
|
||||
internal PdfRectangle? GetBoundingRectangle()
|
||||
{
|
||||
if (commands.Count == 0)
|
||||
if (Commands.Count == 0)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
@@ -71,7 +73,7 @@ namespace UglyToad.PdfPig.Geometry
|
||||
var minY = decimal.MaxValue;
|
||||
var maxY = decimal.MinValue;
|
||||
|
||||
foreach (var command in commands)
|
||||
foreach (var command in Commands)
|
||||
{
|
||||
var rect = command.GetBoundingRectangle();
|
||||
if (rect == null)
|
||||
@@ -106,7 +108,7 @@ namespace UglyToad.PdfPig.Geometry
|
||||
internal string ToSvg()
|
||||
{
|
||||
var builder = new StringBuilder();
|
||||
foreach (var pathCommand in commands)
|
||||
foreach (var pathCommand in Commands)
|
||||
{
|
||||
pathCommand.WriteSvg(builder);
|
||||
}
|
||||
@@ -136,7 +138,7 @@ namespace UglyToad.PdfPig.Geometry
|
||||
var bbox = GetBoundingRectangle();
|
||||
var bboxes = new List<PdfRectangle>();
|
||||
|
||||
foreach (var command in commands)
|
||||
foreach (var command in Commands)
|
||||
{
|
||||
var segBbox = command.GetBoundingRectangle();
|
||||
if (segBbox.HasValue)
|
||||
@@ -153,7 +155,7 @@ namespace UglyToad.PdfPig.Geometry
|
||||
return result;
|
||||
}
|
||||
|
||||
internal interface IPathCommand
|
||||
public interface IPathCommand
|
||||
{
|
||||
PdfRectangle? GetBoundingRectangle();
|
||||
|
||||
@@ -173,7 +175,7 @@ namespace UglyToad.PdfPig.Geometry
|
||||
}
|
||||
}
|
||||
|
||||
private class Move : IPathCommand
|
||||
public class Move : IPathCommand
|
||||
{
|
||||
public PdfPoint Location { get; }
|
||||
|
||||
@@ -193,7 +195,7 @@ namespace UglyToad.PdfPig.Geometry
|
||||
}
|
||||
}
|
||||
|
||||
private class Line : IPathCommand
|
||||
public class Line : IPathCommand
|
||||
{
|
||||
public PdfPoint From { get; }
|
||||
|
||||
@@ -216,7 +218,7 @@ namespace UglyToad.PdfPig.Geometry
|
||||
}
|
||||
}
|
||||
|
||||
internal class BezierCurve : IPathCommand
|
||||
public class BezierCurve : IPathCommand
|
||||
{
|
||||
public PdfPoint StartPoint { get; }
|
||||
|
||||
@@ -379,6 +381,11 @@ namespace UglyToad.PdfPig.Geometry
|
||||
|
||||
internal void Rectangle(decimal x, decimal y, decimal width, decimal height)
|
||||
{
|
||||
currentPosition = CurrentTransformationMatrix.Transform(new PdfPoint(x, y));
|
||||
LineTo(x + width, y);
|
||||
LineTo(x + width, y + height);
|
||||
LineTo(x, y + height);
|
||||
LineTo(x, y);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@@ -48,7 +48,6 @@
|
||||
};
|
||||
|
||||
public List<Letter> Letters = new List<Letter>();
|
||||
|
||||
public ContentStreamProcessor(PdfRectangle cropBox, IResourceStore resourceStore, UserSpaceUnit userSpaceUnit, PageRotationDegrees rotation, bool isLenientParsing,
|
||||
IPdfTokenScanner pdfScanner,
|
||||
XObjectFactory xObjectFactory,
|
||||
@@ -70,7 +69,7 @@
|
||||
|
||||
ProcessOperations(operations);
|
||||
|
||||
return new PageContent(operations, Letters, xObjects, pdfScanner, xObjectFactory, isLenientParsing);
|
||||
return new PageContent(operations, Letters, paths, xObjects, pdfScanner, xObjectFactory, isLenientParsing);
|
||||
}
|
||||
|
||||
private void ProcessOperations(IReadOnlyList<IGraphicsStateOperation> operations)
|
||||
@@ -267,6 +266,7 @@
|
||||
public void BeginSubpath()
|
||||
{
|
||||
CurrentPath = new PdfPath();
|
||||
CurrentPath.CurrentTransformationMatrix = GetCurrentState().CurrentTransformationMatrix;
|
||||
}
|
||||
|
||||
public void StrokePath(bool close)
|
||||
@@ -275,12 +275,21 @@
|
||||
{
|
||||
ClosePath();
|
||||
}
|
||||
paths.Add(CurrentPath);
|
||||
}
|
||||
|
||||
public void FillPath(bool close)
|
||||
{
|
||||
if (close)
|
||||
{
|
||||
ClosePath();
|
||||
}
|
||||
paths.Add(CurrentPath);
|
||||
}
|
||||
|
||||
public void ClosePath()
|
||||
{
|
||||
CurrentPath.ClosePath();
|
||||
paths.Add(CurrentPath);
|
||||
CurrentPath = null;
|
||||
}
|
||||
|
||||
|
@@ -82,6 +82,12 @@
|
||||
/// <param name="close">Whether to also close the path.</param>
|
||||
void StrokePath(bool close);
|
||||
|
||||
/// <summary>
|
||||
/// Fill the current path.
|
||||
/// </summary>
|
||||
/// <param name="close">Whether to also close the path.</param>
|
||||
void FillPath(bool close);
|
||||
|
||||
/// <summary>
|
||||
/// Close the current path.
|
||||
/// </summary>
|
||||
|
@@ -28,6 +28,7 @@
|
||||
/// <inheritdoc />
|
||||
public void Run(IOperationContext operationContext)
|
||||
{
|
||||
operationContext.FillPath(true);
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
|
@@ -28,6 +28,7 @@
|
||||
/// <inheritdoc />
|
||||
public void Run(IOperationContext operationContext)
|
||||
{
|
||||
operationContext.FillPath(true);
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
|
@@ -28,6 +28,7 @@
|
||||
/// <inheritdoc />
|
||||
public void Run(IOperationContext operationContext)
|
||||
{
|
||||
operationContext.FillPath(false);
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
|
@@ -28,6 +28,7 @@
|
||||
/// <inheritdoc />
|
||||
public void Run(IOperationContext operationContext)
|
||||
{
|
||||
operationContext.FillPath(false);
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
|
@@ -29,6 +29,7 @@
|
||||
/// <inheritdoc />
|
||||
public void Run(IOperationContext operationContext)
|
||||
{
|
||||
operationContext.FillPath(false);
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
|
@@ -28,6 +28,7 @@
|
||||
/// <inheritdoc />
|
||||
public void Run(IOperationContext operationContext)
|
||||
{
|
||||
operationContext.FillPath(false);
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
|
@@ -29,6 +29,7 @@
|
||||
/// <inheritdoc />
|
||||
public void Run(IOperationContext operationContext)
|
||||
{
|
||||
operationContext.FillPath(false);
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
|
@@ -52,7 +52,7 @@
|
||||
{
|
||||
operationContext.BeginSubpath();
|
||||
operationContext.CurrentPath.Rectangle(LowerLeft.X, LowerLeft.Y, Width, Height);
|
||||
operationContext.CurrentPath.ClosePath();
|
||||
//operationContext.CurrentPath.ClosePath();
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
|
@@ -37,6 +37,7 @@
|
||||
{
|
||||
operationContext.BeginSubpath();
|
||||
operationContext.CurrentPosition = Point;
|
||||
operationContext.CurrentPath.LineTo(Point.X, Point.Y);
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
|
Reference in New Issue
Block a user