diff --git a/src/UglyToad.PdfPig/Content/PageRotationDegrees.cs b/src/UglyToad.PdfPig/Content/PageRotationDegrees.cs
index 261e9b8f..38bd219e 100644
--- a/src/UglyToad.PdfPig/Content/PageRotationDegrees.cs
+++ b/src/UglyToad.PdfPig/Content/PageRotationDegrees.cs
@@ -44,7 +44,7 @@
///
/// Create a .
///
- /// Rotation in degrees clockwise.
+ /// Rotation in degrees clockwise, must be a multiple of 90.
public PageRotationDegrees(int rotation)
{
if (rotation < 0)
diff --git a/src/UglyToad.PdfPig/Writer/PdfDocumentBuilder.cs b/src/UglyToad.PdfPig/Writer/PdfDocumentBuilder.cs
index 039223bf..26c110e3 100644
--- a/src/UglyToad.PdfPig/Writer/PdfDocumentBuilder.cs
+++ b/src/UglyToad.PdfPig/Writer/PdfDocumentBuilder.cs
@@ -3,7 +3,6 @@ namespace UglyToad.PdfPig.Writer
{
using System;
using System.Collections.Generic;
- using System.Diagnostics;
using System.IO;
using System.Linq;
using Content;
@@ -559,6 +558,11 @@ namespace UglyToad.PdfPig.Writer
pageDictionary[NameToken.MediaBox] = RectangleToArray(page.Value.PageSize);
}
+ if (page.Value.rotation.HasValue)
+ {
+ pageDictionary[NameToken.Rotate] = new NumericToken(page.Value.rotation.Value);
+ }
+
// Adobe Acrobat errors if content streams ref'd by multiple pages, turn off
// dedup if on to avoid issues
var prev = context.AttemptDeduplication;
diff --git a/src/UglyToad.PdfPig/Writer/PdfPageBuilder.cs b/src/UglyToad.PdfPig/Writer/PdfPageBuilder.cs
index 872ccb4a..7c6f4cd3 100644
--- a/src/UglyToad.PdfPig/Writer/PdfPageBuilder.cs
+++ b/src/UglyToad.PdfPig/Writer/PdfPageBuilder.cs
@@ -46,6 +46,8 @@
private int imageKey = 1;
+ internal int? rotation;
+
internal IReadOnlyDictionary Resources => pageDictionary.GetOrCreateDict(NameToken.Resources);
///
@@ -131,7 +133,7 @@
/// The first point on the line.
/// The last point on the line.
/// The width of the line in user space units.
- public void DrawLine(PdfPoint from, PdfPoint to, decimal lineWidth = 1)
+ public PdfPageBuilder DrawLine(PdfPoint from, PdfPoint to, decimal lineWidth = 1)
{
if (lineWidth != 1)
{
@@ -146,6 +148,8 @@
{
currentStream.Add(new SetLineWidth(1));
}
+
+ return this;
}
///
@@ -156,7 +160,7 @@
/// The height of the rectangle.
/// The width of the line border of the rectangle.
/// Whether to fill with the color set by .
- public void DrawRectangle(PdfPoint position, decimal width, decimal height, decimal lineWidth = 1, bool fill = false)
+ public PdfPageBuilder DrawRectangle(PdfPoint position, decimal width, decimal height, decimal lineWidth = 1, bool fill = false)
{
if (lineWidth != 1)
{
@@ -178,6 +182,17 @@
{
currentStream.Add(new SetLineWidth(lineWidth));
}
+
+ return this;
+ }
+
+ ///
+ /// Set the number of degrees by which the page is rotated clockwise when displayed or printed.
+ ///
+ public PdfPageBuilder SetRotation(PageRotationDegrees degrees)
+ {
+ rotation = degrees.Value;
+ return this;
}
///
@@ -188,7 +203,7 @@
/// Position of the third corner of the triangle.
/// The width of the line border of the triangle.
/// Whether to fill with the color set by .
- public void DrawTriangle(PdfPoint point1, PdfPoint point2, PdfPoint point3, decimal lineWidth = 1, bool fill = false)
+ public PdfPageBuilder DrawTriangle(PdfPoint point1, PdfPoint point2, PdfPoint point3, decimal lineWidth = 1, bool fill = false)
{
if (lineWidth != 1)
{
@@ -213,6 +228,8 @@
{
currentStream.Add(new SetLineWidth(lineWidth));
}
+
+ return this;
}
///
@@ -222,9 +239,11 @@
/// The diameter of the circle.
/// The width of the line border of the circle.
/// Whether to fill with the color set by .
- public void DrawCircle(PdfPoint center, decimal diameter, decimal lineWidth = 1, bool fill = false)
+ public PdfPageBuilder DrawCircle(PdfPoint center, decimal diameter, decimal lineWidth = 1, bool fill = false)
{
DrawEllipsis(center, diameter, diameter, lineWidth, fill);
+
+ return this;
}
///
@@ -235,7 +254,7 @@
/// The height of the ellipsis.
/// The width of the line border of the ellipsis.
/// Whether to fill with the color set by .
- public void DrawEllipsis(PdfPoint center, decimal width, decimal height, decimal lineWidth = 1, bool fill = false)
+ public PdfPageBuilder DrawEllipsis(PdfPoint center, decimal width, decimal height, decimal lineWidth = 1, bool fill = false)
{
width /= 2;
height /= 2;
@@ -283,6 +302,8 @@
{
currentStream.Add(new SetLineWidth(lineWidth));
}
+
+ return this;
}
///
@@ -291,10 +312,12 @@
/// Red - 0 to 255
/// Green - 0 to 255
/// Blue - 0 to 255
- public void SetStrokeColor(byte r, byte g, byte b)
+ public PdfPageBuilder SetStrokeColor(byte r, byte g, byte b)
{
currentStream.Add(Push.Value);
currentStream.Add(new SetStrokeColorDeviceRgb(RgbToDecimal(r), RgbToDecimal(g), RgbToDecimal(b)));
+
+ return this;
}
///
@@ -303,11 +326,13 @@
/// Red - 0 to 1
/// Green - 0 to 1
/// Blue - 0 to 1
- internal void SetStrokeColorExact(decimal r, decimal g, decimal b)
+ internal PdfPageBuilder SetStrokeColorExact(decimal r, decimal g, decimal b)
{
currentStream.Add(Push.Value);
currentStream.Add(new SetStrokeColorDeviceRgb(CheckRgbDecimal(r, nameof(r)),
CheckRgbDecimal(g, nameof(g)), CheckRgbDecimal(b, nameof(b))));
+
+ return this;
}
///
@@ -316,18 +341,22 @@
/// Red - 0 to 255
/// Green - 0 to 255
/// Blue - 0 to 255
- public void SetTextAndFillColor(byte r, byte g, byte b)
+ public PdfPageBuilder SetTextAndFillColor(byte r, byte g, byte b)
{
currentStream.Add(Push.Value);
currentStream.Add(new SetNonStrokeColorDeviceRgb(RgbToDecimal(r), RgbToDecimal(g), RgbToDecimal(b)));
+
+ return this;
}
///
/// Restores the stroke, text and fill color to default (black).
///
- public void ResetColor()
+ public PdfPageBuilder ResetColor()
{
currentStream.Add(Pop.Value);
+
+ return this;
}
///
@@ -451,9 +480,11 @@
/// To insert invisible text, for example output of OCR, use TextRenderingMode.Neither.
///
/// Text rendering mode to set.
- public void SetTextRenderingMode(TextRenderingMode mode)
+ public PdfPageBuilder SetTextRenderingMode(TextRenderingMode mode)
{
currentStream.Add(new SetTextRenderingMode(mode));
+
+ return this;
}
private NameToken GetAddedFont(PdfDocumentBuilder.AddedFont font)
@@ -690,7 +721,7 @@
/// Copy a page from unknown source to this page
///
/// Page to be copied
- public void CopyFrom(Page srcPage)
+ public PdfPageBuilder CopyFrom(Page srcPage)
{
if (currentStream.Operations.Count > 0)
{
@@ -704,7 +735,7 @@
// If the page doesn't have resources, then we copy the entire content stream, since not operation would collide
// with the ones already written
destinationStream.Operations.AddRange(srcPage.Operations);
- return;
+ return this;
}
// TODO: How should we handle any other token in the page dictionary (Eg. LastModified, MediaBox, CropBox, BleedBox, TrimBox, ArtBox,
@@ -828,6 +859,8 @@
}
destinationStream.Operations.AddRange(operations);
+
+ return this;
}
private List DrawLetters(NameToken name, string text, IWritingFont font, TransformationMatrix fontMatrix, decimal fontSize, TransformationMatrix textMatrix)