diff --git a/src/UglyToad.PdfPig.Tests/Fonts/CharacterPathTests.cs b/src/UglyToad.PdfPig.Tests/Fonts/CharacterPathTests.cs
index 7f504d7c..033a2b95 100644
--- a/src/UglyToad.PdfPig.Tests/Fonts/CharacterPathTests.cs
+++ b/src/UglyToad.PdfPig.Tests/Fonts/CharacterPathTests.cs
@@ -10,7 +10,7 @@
[Fact]
public void BezierCurveGeneratesCorrectBoundingBox()
{
- var curve = new CharacterPath.BezierCurve(new PdfPoint(60, 105),
+ var curve = new PdfPath.BezierCurve(new PdfPoint(60, 105),
new PdfPoint(75, 30),
new PdfPoint(215, 115),
new PdfPoint(140, 160));
@@ -28,7 +28,7 @@
[Fact]
public void LoopBezierCurveGeneratesCorrectBoundingBox()
{
- var curve = new CharacterPath.BezierCurve(new PdfPoint(166, 142),
+ var curve = new PdfPath.BezierCurve(new PdfPoint(166, 142),
new PdfPoint(75, 30),
new PdfPoint(215, 115),
new PdfPoint(140, 160));
@@ -47,7 +47,7 @@
[Fact]
public void BezierCurveAddsCorrectSvgCommand()
{
- var curve = new CharacterPath.BezierCurve(new PdfPoint(60, 105),
+ var curve = new PdfPath.BezierCurve(new PdfPoint(60, 105),
new PdfPoint(75, 30),
new PdfPoint(215, 115),
new PdfPoint(140, 160));
diff --git a/src/UglyToad.PdfPig.Tests/Graphics/TestOperationContext.cs b/src/UglyToad.PdfPig.Tests/Graphics/TestOperationContext.cs
index 7cc9d35e..3008f97f 100644
--- a/src/UglyToad.PdfPig.Tests/Graphics/TestOperationContext.cs
+++ b/src/UglyToad.PdfPig.Tests/Graphics/TestOperationContext.cs
@@ -3,6 +3,7 @@
using System.Collections.Generic;
using Content;
using PdfPig.Fonts;
+ using PdfPig.Geometry;
using PdfPig.Graphics;
using PdfPig.IO;
using PdfPig.Tokens;
@@ -17,9 +18,14 @@
public TextMatrices TextMatrices { get; set; }
= new TextMatrices();
+ public PdfPath CurrentPath { get; set; }
+
+ public PdfPoint CurrentPosition { get; set; }
+
public TestOperationContext()
{
StateStack.Push(new CurrentGraphicsState());
+ CurrentPath = new PdfPath();
}
public CurrentGraphicsState GetCurrentState()
@@ -48,6 +54,18 @@
public void ApplyXObject(StreamToken xObjectStream)
{
}
+
+ public void BeginSubpath()
+ {
+ }
+
+ public void StrokePath(bool close)
+ {
+ }
+
+ public void ClosePath()
+ {
+ }
}
internal class TestResourceStore : IResourceStore
diff --git a/src/UglyToad.PdfPig.Tests/Writer/PdfDocumentBuilderTests.cs b/src/UglyToad.PdfPig.Tests/Writer/PdfDocumentBuilderTests.cs
index 0a0cf329..3e3471f8 100644
--- a/src/UglyToad.PdfPig.Tests/Writer/PdfDocumentBuilderTests.cs
+++ b/src/UglyToad.PdfPig.Tests/Writer/PdfDocumentBuilderTests.cs
@@ -93,6 +93,14 @@
var page = builder.AddPage(PageSize.A4);
+ page.DrawLine(new PdfPoint(30, 520), new PdfPoint(360, 520));
+ page.DrawLine(new PdfPoint(360, 520), new PdfPoint(360, 250));
+
+ page.DrawLine(new PdfPoint(25, 70), new PdfPoint(100, 70), 3);
+
+ page.DrawRectangle(new PdfPoint(30, 100), 250, 100, 0.5m);
+ page.DrawRectangle(new PdfPoint(30, 200), 250, 100, 0.5m);
+
var path = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "Fonts", "TrueType");
var file = Path.Combine(path, "Andada-Regular.ttf");
@@ -139,6 +147,8 @@
{
var builder = new PdfDocumentBuilder();
+ builder.DocumentInformation.Title = "Hello Windows!";
+
var page = builder.AddPage(PageSize.A4);
var file = @"C:\Windows\Fonts\BASKVILL.TTF";
diff --git a/src/UglyToad.PdfPig/Fonts/CompactFontFormat/CharStrings/Type2BuildCharContext.cs b/src/UglyToad.PdfPig/Fonts/CompactFontFormat/CharStrings/Type2BuildCharContext.cs
index 864d82cd..c62e4553 100644
--- a/src/UglyToad.PdfPig/Fonts/CompactFontFormat/CharStrings/Type2BuildCharContext.cs
+++ b/src/UglyToad.PdfPig/Fonts/CompactFontFormat/CharStrings/Type2BuildCharContext.cs
@@ -18,7 +18,7 @@
///
/// The current path.
///
- public CharacterPath Path { get; } = new CharacterPath();
+ public PdfPath Path { get; } = new PdfPath();
///
/// The current location of the active point.
diff --git a/src/UglyToad.PdfPig/Fonts/CompactFontFormat/CharStrings/Type2CharStrings.cs b/src/UglyToad.PdfPig/Fonts/CompactFontFormat/CharStrings/Type2CharStrings.cs
index 2adba0bd..87a0c3dd 100644
--- a/src/UglyToad.PdfPig/Fonts/CompactFontFormat/CharStrings/Type2CharStrings.cs
+++ b/src/UglyToad.PdfPig/Fonts/CompactFontFormat/CharStrings/Type2CharStrings.cs
@@ -46,7 +46,7 @@
/// Evaluate the CharString for the character with a given name returning the path constructed for the glyph.
///
/// The name of the character to retrieve the CharString for.
- /// A for the glyph.
+ /// A for the glyph.
public Type2Glyph Generate(string name)
{
Type2Glyph glyph;
@@ -171,7 +171,7 @@
/// The path of the glyph.
///
[NotNull]
- public CharacterPath Path { get; }
+ public PdfPath Path { get; }
///
/// The width of the glyph as a difference from the nominal width X for the font. Optional.
@@ -181,7 +181,7 @@
///
/// Create a new .
///
- public Type2Glyph(CharacterPath path, decimal? widthDifferenceFromNominal)
+ public Type2Glyph(PdfPath path, decimal? widthDifferenceFromNominal)
{
Path = path ?? throw new ArgumentNullException(nameof(path));
WidthDifferenceFromNominal = widthDifferenceFromNominal;
diff --git a/src/UglyToad.PdfPig/Fonts/CharacterPath.cs b/src/UglyToad.PdfPig/Fonts/PdfPath.cs
similarity index 96%
rename from src/UglyToad.PdfPig/Fonts/CharacterPath.cs
rename to src/UglyToad.PdfPig/Fonts/PdfPath.cs
index 17a501c1..81652ebd 100644
--- a/src/UglyToad.PdfPig/Fonts/CharacterPath.cs
+++ b/src/UglyToad.PdfPig/Fonts/PdfPath.cs
@@ -7,7 +7,7 @@ namespace UglyToad.PdfPig.Fonts
using System.Text;
using Geometry;
- internal class CharacterPath
+ internal class PdfPath
{
private readonly List commands = new List();
private PdfPoint? currentPosition;
@@ -239,8 +239,8 @@ namespace UglyToad.PdfPig.Fonts
double maxX;
if (StartPoint.X <= EndPoint.X)
{
- minX = (double) StartPoint.X;
- maxX = (double) EndPoint.X;
+ minX = (double)StartPoint.X;
+ maxX = (double)EndPoint.X;
}
else
{
@@ -254,9 +254,9 @@ namespace UglyToad.PdfPig.Fonts
{
minY = (double)StartPoint.Y;
maxY = (double)EndPoint.Y;
- }
- else
- {
+ }
+ else
+ {
minY = (double)EndPoint.Y;
maxY = (double)StartPoint.Y;
}
@@ -294,7 +294,7 @@ namespace UglyToad.PdfPig.Fonts
// P' = 3da(1-t)^2 + 6db(1-t)t + 3dct^2
// P' = 3da - 3dat - 3dat + 3dat^2 + 6dbt - 6dbt^2 + 3dct^2
// P' = (3da - 6db + 3dc)t^2 + (6db - 3da - 3da)t + 3da
- var p1 = (double)( isX ? StartPoint.X : StartPoint.Y);
+ var p1 = (double)(isX ? StartPoint.X : StartPoint.Y);
var p2 = (double)(isX ? FirstControlPoint.X : FirstControlPoint.Y);
var p3 = (double)(isX ? SecondControlPoint.X : SecondControlPoint.Y);
var p4 = (double)(isX ? EndPoint.X : EndPoint.Y);
@@ -361,8 +361,8 @@ namespace UglyToad.PdfPig.Fonts
// P = (1−t)^3*P_1 + 3(1−t)^2*t*P_2 + 3(1−t)*t^2*P_3 + t^3*P_4
var oneMinusT = 1 - t;
var p = ((oneMinusT * oneMinusT * oneMinusT) * p1)
- + (3 * (oneMinusT * oneMinusT) * t * p2)
- + (3 * oneMinusT * (t * t) * p3)
+ + (3 * (oneMinusT * oneMinusT) * t * p2)
+ + (3 * oneMinusT * (t * t) * p3)
+ ((t * t * t) * p4);
return p;
@@ -374,5 +374,9 @@ namespace UglyToad.PdfPig.Fonts
EndPoint.X, EndPoint.Y);
}
}
+
+ public void Rectangle(decimal x, decimal y, decimal width, decimal height)
+ {
+ }
}
}
diff --git a/src/UglyToad.PdfPig/Fonts/Type1/CharStrings/Commands/Type1BuildCharContext.cs b/src/UglyToad.PdfPig/Fonts/Type1/CharStrings/Commands/Type1BuildCharContext.cs
index 2a0af378..29939308 100644
--- a/src/UglyToad.PdfPig/Fonts/Type1/CharStrings/Commands/Type1BuildCharContext.cs
+++ b/src/UglyToad.PdfPig/Fonts/Type1/CharStrings/Commands/Type1BuildCharContext.cs
@@ -7,7 +7,7 @@
internal class Type1BuildCharContext
{
- private readonly Func characterByIndexFactory;
+ private readonly Func characterByIndexFactory;
public IReadOnlyDictionary Subroutines { get; }
public decimal WidthX { get; set; }
@@ -21,7 +21,7 @@
public bool IsFlexing { get; set; }
[NotNull]
- public CharacterPath Path { get; private set; } = new CharacterPath();
+ public PdfPath Path { get; private set; } = new PdfPath();
public PdfPoint CurrentPosition { get; set; }
@@ -32,7 +32,7 @@
public IReadOnlyList FlexPoints { get; }
public Type1BuildCharContext(IReadOnlyDictionary subroutines,
- Func characterByIndexFactory)
+ Func characterByIndexFactory)
{
this.characterByIndexFactory = characterByIndexFactory ?? throw new ArgumentNullException(nameof(characterByIndexFactory));
Subroutines = subroutines ?? throw new ArgumentNullException(nameof(subroutines));
@@ -43,12 +43,12 @@
}
- public CharacterPath GetCharacter(int characterCode)
+ public PdfPath GetCharacter(int characterCode)
{
return characterByIndexFactory(characterCode);
}
- public void SetPath(CharacterPath path)
+ public void SetPath(PdfPath path)
{
Path = path ?? throw new ArgumentNullException(nameof(path));
}
diff --git a/src/UglyToad.PdfPig/Fonts/Type1/CharStrings/Type1CharStrings.cs b/src/UglyToad.PdfPig/Fonts/Type1/CharStrings/Type1CharStrings.cs
index 886393bb..ee8e641c 100644
--- a/src/UglyToad.PdfPig/Fonts/Type1/CharStrings/Type1CharStrings.cs
+++ b/src/UglyToad.PdfPig/Fonts/Type1/CharStrings/Type1CharStrings.cs
@@ -10,7 +10,7 @@
{
private readonly IReadOnlyDictionary charStringIndexToName;
private readonly object locker = new object();
- private readonly Dictionary glyphs = new Dictionary();
+ private readonly Dictionary glyphs = new Dictionary();
public IReadOnlyDictionary CharStrings { get; }
@@ -24,9 +24,9 @@
Subroutines = subroutines ?? throw new ArgumentNullException(nameof(subroutines));
}
- public CharacterPath Generate(string name)
+ public PdfPath Generate(string name)
{
- CharacterPath glyph;
+ PdfPath glyph;
lock (locker)
{
if (glyphs.TryGetValue(name, out var result))
@@ -47,7 +47,7 @@
return glyph;
}
- private CharacterPath Run(CommandSequence sequence)
+ private PdfPath Run(CommandSequence sequence)
{
var context = new Type1BuildCharContext(Subroutines, i =>
{
diff --git a/src/UglyToad.PdfPig/Graphics/ContentStreamProcessor.cs b/src/UglyToad.PdfPig/Graphics/ContentStreamProcessor.cs
index 98e63c1f..4db29d77 100644
--- a/src/UglyToad.PdfPig/Graphics/ContentStreamProcessor.cs
+++ b/src/UglyToad.PdfPig/Graphics/ContentStreamProcessor.cs
@@ -16,6 +16,7 @@
internal class ContentStreamProcessor : IOperationContext
{
+ private readonly List paths = new List();
private readonly IResourceStore resourceStore;
private readonly UserSpaceUnit userSpaceUnit;
private readonly bool isLenientParsing;
@@ -26,6 +27,9 @@
public TextMatrices TextMatrices { get; } = new TextMatrices();
+ public PdfPath CurrentPath { get; private set; }
+ public PdfPoint CurrentPosition { get; set; }
+
public int StackSize => graphicsStack.Count;
private readonly Dictionary> xObjects = new Dictionary>
@@ -73,7 +77,7 @@
graphicsStack.Push(saved.Peek().DeepClone());
return saved;
}
-
+
[DebuggerStepThrough]
public CurrentGraphicsState GetCurrentState()
{
@@ -245,6 +249,26 @@
}
}
+ public void BeginSubpath()
+ {
+ CurrentPath = new PdfPath();
+ }
+
+ public void StrokePath(bool close)
+ {
+ if (close)
+ {
+ ClosePath();
+ }
+ }
+
+ public void ClosePath()
+ {
+ CurrentPath.ClosePath();
+ paths.Add(CurrentPath);
+ CurrentPath = null;
+ }
+
private void AdjustTextMatrix(decimal tx, decimal ty)
{
var matrix = TransformationMatrix.GetTranslationMatrix(tx, ty);
diff --git a/src/UglyToad.PdfPig/Graphics/IOperationContext.cs b/src/UglyToad.PdfPig/Graphics/IOperationContext.cs
index fd10f469..1f15aef9 100644
--- a/src/UglyToad.PdfPig/Graphics/IOperationContext.cs
+++ b/src/UglyToad.PdfPig/Graphics/IOperationContext.cs
@@ -1,11 +1,19 @@
namespace UglyToad.PdfPig.Graphics
{
using System.Collections.Generic;
+ using Fonts;
+ using Geometry;
using IO;
using Tokens;
+ using Util.JetBrains.Annotations;
internal interface IOperationContext
{
+ [CanBeNull]
+ PdfPath CurrentPath { get; }
+
+ PdfPoint CurrentPosition { get; set; }
+
CurrentGraphicsState GetCurrentState();
TextMatrices TextMatrices { get; }
@@ -21,5 +29,11 @@
void ShowPositionedText(IReadOnlyList tokens);
void ApplyXObject(StreamToken xObjectStream);
+
+ void BeginSubpath();
+
+ void StrokePath(bool close);
+
+ void ClosePath();
}
}
\ No newline at end of file
diff --git a/src/UglyToad.PdfPig/Graphics/Operations/CloseAndStrokePath.cs b/src/UglyToad.PdfPig/Graphics/Operations/CloseAndStrokePath.cs
index ef46da5a..6c440852 100644
--- a/src/UglyToad.PdfPig/Graphics/Operations/CloseAndStrokePath.cs
+++ b/src/UglyToad.PdfPig/Graphics/Operations/CloseAndStrokePath.cs
@@ -17,11 +17,13 @@
public void Run(IOperationContext operationContext, IResourceStore resourceStore)
{
+ operationContext.StrokePath(true);
}
public void Write(Stream stream)
{
- throw new System.NotImplementedException();
+ stream.WriteText(Symbol);
+ stream.WriteNewLine();
}
public override string ToString()
diff --git a/src/UglyToad.PdfPig/Graphics/Operations/General/SetLineWidth.cs b/src/UglyToad.PdfPig/Graphics/Operations/General/SetLineWidth.cs
index d57534ef..64b43465 100644
--- a/src/UglyToad.PdfPig/Graphics/Operations/General/SetLineWidth.cs
+++ b/src/UglyToad.PdfPig/Graphics/Operations/General/SetLineWidth.cs
@@ -25,7 +25,10 @@
public void Write(Stream stream)
{
- throw new System.NotImplementedException();
+ stream.WriteDecimal(Width);
+ stream.WriteWhiteSpace();
+ stream.WriteText(Symbol);
+ stream.WriteNewLine();
}
public override string ToString()
diff --git a/src/UglyToad.PdfPig/Graphics/Operations/PathConstruction/AppendDualControlPointBezierCurve.cs b/src/UglyToad.PdfPig/Graphics/Operations/PathConstruction/AppendDualControlPointBezierCurve.cs
index c81fa97f..e25d8e84 100644
--- a/src/UglyToad.PdfPig/Graphics/Operations/PathConstruction/AppendDualControlPointBezierCurve.cs
+++ b/src/UglyToad.PdfPig/Graphics/Operations/PathConstruction/AppendDualControlPointBezierCurve.cs
@@ -25,11 +25,28 @@
public void Run(IOperationContext operationContext, IResourceStore resourceStore)
{
+ operationContext.CurrentPath.BezierCurveTo(ControlPoint1.X, ControlPoint1.Y,
+ ControlPoint2.X, ControlPoint2.Y,
+ End.X, End.Y);
+ operationContext.CurrentPosition = End;
}
public void Write(Stream stream)
{
- throw new System.NotImplementedException();
+ stream.WriteDecimal(ControlPoint1.X);
+ stream.WriteWhiteSpace();
+ stream.WriteDecimal(ControlPoint1.Y);
+ stream.WriteWhiteSpace();
+ stream.WriteDecimal(ControlPoint2.X);
+ stream.WriteWhiteSpace();
+ stream.WriteDecimal(ControlPoint2.Y);
+ stream.WriteWhiteSpace();
+ stream.WriteDecimal(End.X);
+ stream.WriteWhiteSpace();
+ stream.WriteDecimal(End.Y);
+ stream.WriteWhiteSpace();
+ stream.WriteText(Symbol);
+ stream.WriteNewLine();
}
public override string ToString()
diff --git a/src/UglyToad.PdfPig/Graphics/Operations/PathConstruction/AppendEndControlPointBezierCurve.cs b/src/UglyToad.PdfPig/Graphics/Operations/PathConstruction/AppendEndControlPointBezierCurve.cs
index 59c23f80..2972118b 100644
--- a/src/UglyToad.PdfPig/Graphics/Operations/PathConstruction/AppendEndControlPointBezierCurve.cs
+++ b/src/UglyToad.PdfPig/Graphics/Operations/PathConstruction/AppendEndControlPointBezierCurve.cs
@@ -22,11 +22,26 @@
public void Run(IOperationContext operationContext, IResourceStore resourceStore)
{
+ operationContext.CurrentPath.BezierCurveTo(ControlPoint1.X, ControlPoint1.Y,
+ End.X,
+ End.Y,
+ End.X,
+ End.Y);
+ operationContext.CurrentPosition = End;
}
public void Write(Stream stream)
{
- throw new System.NotImplementedException();
+ stream.WriteDecimal(ControlPoint1.X);
+ stream.WriteWhiteSpace();
+ stream.WriteDecimal(ControlPoint1.Y);
+ stream.WriteWhiteSpace();
+ stream.WriteDecimal(End.X);
+ stream.WriteWhiteSpace();
+ stream.WriteDecimal(End.Y);
+ stream.WriteWhiteSpace();
+ stream.WriteText(Symbol);
+ stream.WriteNewLine();
}
public override string ToString()
diff --git a/src/UglyToad.PdfPig/Graphics/Operations/PathConstruction/AppendRectangle.cs b/src/UglyToad.PdfPig/Graphics/Operations/PathConstruction/AppendRectangle.cs
index fb8fbcc0..94e159dc 100644
--- a/src/UglyToad.PdfPig/Graphics/Operations/PathConstruction/AppendRectangle.cs
+++ b/src/UglyToad.PdfPig/Graphics/Operations/PathConstruction/AppendRectangle.cs
@@ -26,11 +26,23 @@
public void Run(IOperationContext operationContext, IResourceStore resourceStore)
{
+ operationContext.BeginSubpath();
+ operationContext.CurrentPath.Rectangle(LowerLeft.X, LowerLeft.Y, Width, Height);
+ operationContext.CurrentPath.ClosePath();
}
public void Write(Stream stream)
{
- throw new System.NotImplementedException();
+ stream.WriteDecimal(LowerLeft.X);
+ stream.WriteWhiteSpace();
+ stream.WriteDecimal(LowerLeft.Y);
+ stream.WriteWhiteSpace();
+ stream.WriteDecimal(Width);
+ stream.WriteWhiteSpace();
+ stream.WriteDecimal(Height);
+ stream.WriteWhiteSpace();
+ stream.WriteText(Symbol);
+ stream.WriteNewLine();
}
public override string ToString()
diff --git a/src/UglyToad.PdfPig/Graphics/Operations/PathConstruction/AppendStartControlPointBezierCurve.cs b/src/UglyToad.PdfPig/Graphics/Operations/PathConstruction/AppendStartControlPointBezierCurve.cs
index 5bcdc54f..bc85f3cf 100644
--- a/src/UglyToad.PdfPig/Graphics/Operations/PathConstruction/AppendStartControlPointBezierCurve.cs
+++ b/src/UglyToad.PdfPig/Graphics/Operations/PathConstruction/AppendStartControlPointBezierCurve.cs
@@ -22,11 +22,27 @@
public void Run(IOperationContext operationContext, IResourceStore resourceStore)
{
+ operationContext.CurrentPath.BezierCurveTo(operationContext.CurrentPosition.X,
+ operationContext.CurrentPosition.Y,
+ ControlPoint2.X,
+ ControlPoint2.Y,
+ End.X,
+ End.Y);
+ operationContext.CurrentPosition = End;
}
public void Write(Stream stream)
{
- throw new System.NotImplementedException();
+ stream.WriteDecimal(ControlPoint2.X);
+ stream.WriteWhiteSpace();
+ stream.WriteDecimal(ControlPoint2.Y);
+ stream.WriteWhiteSpace();
+ stream.WriteDecimal(End.X);
+ stream.WriteWhiteSpace();
+ stream.WriteDecimal(End.Y);
+ stream.WriteWhiteSpace();
+ stream.WriteText(Symbol);
+ stream.WriteNewLine();
}
public override string ToString()
diff --git a/src/UglyToad.PdfPig/Graphics/Operations/PathConstruction/AppendStraightLineSegment.cs b/src/UglyToad.PdfPig/Graphics/Operations/PathConstruction/AppendStraightLineSegment.cs
index 99d94a0c..33d485a8 100644
--- a/src/UglyToad.PdfPig/Graphics/Operations/PathConstruction/AppendStraightLineSegment.cs
+++ b/src/UglyToad.PdfPig/Graphics/Operations/PathConstruction/AppendStraightLineSegment.cs
@@ -19,11 +19,18 @@
public void Run(IOperationContext operationContext, IResourceStore resourceStore)
{
+ operationContext.CurrentPath.LineTo(End.X, End.Y);
+ operationContext.CurrentPosition = End;
}
public void Write(Stream stream)
{
- throw new System.NotImplementedException();
+ stream.WriteDecimal(End.X);
+ stream.WriteWhiteSpace();
+ stream.WriteDecimal(End.Y);
+ stream.WriteWhiteSpace();
+ stream.WriteText(Symbol);
+ stream.WriteWhiteSpace();
}
public override string ToString()
diff --git a/src/UglyToad.PdfPig/Graphics/Operations/PathConstruction/BeginNewSubpath.cs b/src/UglyToad.PdfPig/Graphics/Operations/PathConstruction/BeginNewSubpath.cs
index 3cc10131..ea0d3067 100644
--- a/src/UglyToad.PdfPig/Graphics/Operations/PathConstruction/BeginNewSubpath.cs
+++ b/src/UglyToad.PdfPig/Graphics/Operations/PathConstruction/BeginNewSubpath.cs
@@ -19,11 +19,18 @@
public void Run(IOperationContext operationContext, IResourceStore resourceStore)
{
+ operationContext.BeginSubpath();
+ operationContext.CurrentPosition = Point;
}
public void Write(Stream stream)
{
- throw new System.NotImplementedException();
+ stream.WriteDecimal(Point.X);
+ stream.WriteWhiteSpace();
+ stream.WriteDecimal(Point.Y);
+ stream.WriteWhiteSpace();
+ stream.WriteText(Symbol);
+ stream.WriteNewLine();
}
public override string ToString()
diff --git a/src/UglyToad.PdfPig/Graphics/Operations/PathConstruction/CloseSubpath.cs b/src/UglyToad.PdfPig/Graphics/Operations/PathConstruction/CloseSubpath.cs
index 3fee623b..2185c7f8 100644
--- a/src/UglyToad.PdfPig/Graphics/Operations/PathConstruction/CloseSubpath.cs
+++ b/src/UglyToad.PdfPig/Graphics/Operations/PathConstruction/CloseSubpath.cs
@@ -17,11 +17,13 @@
public void Run(IOperationContext operationContext, IResourceStore resourceStore)
{
+ operationContext.CurrentPath.ClosePath();
}
public void Write(Stream stream)
{
- throw new System.NotImplementedException();
+ stream.WriteText(Symbol);
+ stream.WriteNewLine();
}
public override string ToString()
diff --git a/src/UglyToad.PdfPig/Graphics/Operations/StrokePath.cs b/src/UglyToad.PdfPig/Graphics/Operations/StrokePath.cs
index 68ec1bc1..cfe54048 100644
--- a/src/UglyToad.PdfPig/Graphics/Operations/StrokePath.cs
+++ b/src/UglyToad.PdfPig/Graphics/Operations/StrokePath.cs
@@ -17,11 +17,13 @@
public void Run(IOperationContext operationContext, IResourceStore resourceStore)
{
+ operationContext.StrokePath(false);
}
public void Write(Stream stream)
{
- throw new System.NotImplementedException();
+ stream.WriteText(Symbol);
+ stream.WriteNewLine();
}
public override string ToString()
diff --git a/src/UglyToad.PdfPig/Writer/PdfDocumentBuilder.cs b/src/UglyToad.PdfPig/Writer/PdfDocumentBuilder.cs
index 24c0c65c..41c1a185 100644
--- a/src/UglyToad.PdfPig/Writer/PdfDocumentBuilder.cs
+++ b/src/UglyToad.PdfPig/Writer/PdfDocumentBuilder.cs
@@ -17,12 +17,15 @@
internal class PdfDocumentBuilder
{
- private const byte Break = (byte) '\n';
+ private const byte Break = (byte)'\n';
private static readonly TrueTypeFontParser Parser = new TrueTypeFontParser();
private readonly Dictionary pages = new Dictionary();
private readonly Dictionary fonts = new Dictionary();
+ public bool IncludeDocumentInformation { get; set; } = true;
+ public DocumentInformationBuilder DocumentInformation { get; } = new DocumentInformationBuilder();
+
public IReadOnlyDictionary Pages => pages;
public IReadOnlyDictionary Fonts => fonts.ToDictionary(x => x.Key, x => x.Value.FontProgram);
@@ -219,7 +222,18 @@
var catalogRef = context.WriteObject(memory, catalog);
- TokenWriter.WriteCrossReferenceTable(context.ObjectOffsets, catalogRef, memory);
+ var informationReference = default(IndirectReference?);
+ if (IncludeDocumentInformation)
+ {
+ var informationDictionary = DocumentInformation.ToDictionary();
+ if (informationDictionary.Count > 0)
+ {
+ var dictionary = new DictionaryToken(informationDictionary);
+ informationReference = context.WriteObject(memory, dictionary).Number;
+ }
+ }
+
+ TokenWriter.WriteCrossReferenceTable(context.ObjectOffsets, catalogRef, memory, informationReference);
return memory.ToArray();
}
@@ -257,7 +271,7 @@
new NumericToken(rectangle.TopRight.Y)
});
}
-
+
private static void WriteString(string text, MemoryStream stream, bool appendBreak = true)
{
var bytes = OtherEncodings.StringAsLatin1Bytes(text);
@@ -295,5 +309,52 @@
Name = name ?? throw new ArgumentNullException(nameof(name));
}
}
+
+ internal class DocumentInformationBuilder
+ {
+ public string Title { get; set; }
+ public string Author { get; set; }
+ public string Subject { get; set; }
+ public string Keywords { get; set; }
+ public string Creator { get; set; }
+ public string Producer { get; set; } = "PdfPig";
+
+ internal Dictionary ToDictionary()
+ {
+ var result = new Dictionary();
+
+ if (Title != null)
+ {
+ result[NameToken.Title] = new StringToken(Title);
+ }
+
+ if (Author != null)
+ {
+ result[NameToken.Author] = new StringToken(Author);
+ }
+
+ if (Subject != null)
+ {
+ result[NameToken.Subject] = new StringToken(Subject);
+ }
+
+ if (Keywords != null)
+ {
+ result[NameToken.Keywords] = new StringToken(Keywords);
+ }
+
+ if (Creator != null)
+ {
+ result[NameToken.Creator] = new StringToken(Creator);
+ }
+
+ if (Producer != null)
+ {
+ result[NameToken.Producer] = new StringToken(Producer);
+ }
+
+ return result;
+ }
+ }
}
}
diff --git a/src/UglyToad.PdfPig/Writer/PdfPageBuilder.cs b/src/UglyToad.PdfPig/Writer/PdfPageBuilder.cs
index f25adbc0..584ea3e9 100644
--- a/src/UglyToad.PdfPig/Writer/PdfPageBuilder.cs
+++ b/src/UglyToad.PdfPig/Writer/PdfPageBuilder.cs
@@ -6,6 +6,8 @@
using Core;
using Geometry;
using Graphics.Operations;
+ using Graphics.Operations.General;
+ using Graphics.Operations.PathConstruction;
using Graphics.Operations.TextObjects;
using Graphics.Operations.TextPositioning;
using Graphics.Operations.TextShowing;
@@ -28,6 +30,39 @@
PageNumber = number;
}
+ public void DrawLine(PdfPoint from, PdfPoint to, decimal lineWidth = 1)
+ {
+ if (lineWidth != 1)
+ {
+ operations.Add(new SetLineWidth(lineWidth));
+ }
+
+ operations.Add(new BeginNewSubpath(from.X, from.Y));
+ operations.Add(new AppendStraightLineSegment(to.X, to.Y));
+ operations.Add(StrokePath.Value);
+
+ if (lineWidth != 1)
+ {
+ operations.Add(new SetLineWidth(1));
+ }
+ }
+
+ public void DrawRectangle(PdfPoint position, decimal width, decimal height, decimal lineWidth = 1)
+ {
+ if (lineWidth != 1)
+ {
+ operations.Add(new SetLineWidth(lineWidth));
+ }
+
+ operations.Add(new AppendRectangle(position.X, position.Y, width, height));
+ operations.Add(StrokePath.Value);
+
+ if (lineWidth != 1)
+ {
+ operations.Add(new SetLineWidth(lineWidth));
+ }
+ }
+
public List AddText(string text, decimal fontSize, PdfPoint position, PdfDocumentBuilder.AddedFont font)
{
if (font == null)
diff --git a/src/UglyToad.PdfPig/Writer/TokenWriter.cs b/src/UglyToad.PdfPig/Writer/TokenWriter.cs
index 82c5eb75..9b623080 100644
--- a/src/UglyToad.PdfPig/Writer/TokenWriter.cs
+++ b/src/UglyToad.PdfPig/Writer/TokenWriter.cs
@@ -2,6 +2,7 @@
{
using System;
using System.Collections.Generic;
+ using System.Collections.ObjectModel;
using System.IO;
using System.Linq;
using Tokens;
@@ -95,7 +96,8 @@
public static void WriteCrossReferenceTable(IReadOnlyDictionary objectOffsets,
ObjectToken catalogToken,
- Stream outputStream)
+ Stream outputStream,
+ IndirectReference? documentInformationReference)
{
if (objectOffsets.Count == 0)
{
@@ -150,11 +152,18 @@
outputStream.Write(Trailer, 0, Trailer.Length);
WriteLineBreak(outputStream);
- var trailerDictionary = new DictionaryToken(new Dictionary
+ var trailerDictionaryData = new Dictionary
{
- {NameToken.Size, new NumericToken(objectOffsets.Count) },
- {NameToken.Root, new IndirectReferenceToken(catalogToken.Number) }
- });
+ {NameToken.Size, new NumericToken(objectOffsets.Count)},
+ {NameToken.Root, new IndirectReferenceToken(catalogToken.Number)}
+ };
+
+ if (documentInformationReference.HasValue)
+ {
+ trailerDictionaryData[NameToken.Info] = new IndirectReferenceToken(documentInformationReference.Value);
+ }
+
+ var trailerDictionary = new DictionaryToken(trailerDictionaryData);
WriteDictionary(trailerDictionary, outputStream);
WriteLineBreak(outputStream);