update readme and document public api for document creation

This commit is contained in:
Eliot Jones
2018-12-28 16:55:46 +00:00
parent 9f4f42660e
commit d9052e1388
10 changed files with 202 additions and 35 deletions

View File

@@ -28,6 +28,23 @@ The simplest usage at this stage is to open a document, reading the words from e
}
}
New in v0.0.5 - To create documents use the class ```PdfDocumentBuilder```. Though they are deprecated within the PDF specification the Standard 14 fonts provide a quick way to get started:
PdfDocumentBuilder builder = new PdfDocumentBuilder();
PdfPageBuilder page = builder.AddPage(PageSize.A4);
// Fonts must be registered with the document builder prior to use to prevent duplication.
PdfDocumentBuilder.AddedFont font = builder.AddStandard14Font(Standard14Font.Helvetica);
page.AddText("Hello World!", 12, new PdfPoint(25, 520), font);
byte[] documentBytes = builder.Build();
File.WriteAllBytes(@"C:\\git\newPdf.pdf");
Each font must be registered with the PdfDocumentBuilder prior to use enable pages to share the font resources. Currently only Standard 14 fonts and TrueType fonts (.ttf) are supported.
## Installation ##
The package is available via the releases tab or from Nuget:
@@ -71,6 +88,47 @@ The document contains the version of the PDF specification it complies with, acc
decimal version = document.Version;
### Document Creation ###
New in v0.0.5 - The ```PdfDocumentBuilder``` creates a new document with no pages or content. First, for text content, a font must be registered with the builder. Currently this supports Standard 14 fonts provided by Adobe by default and TrueType format fonts.
To add a Standard 14 font use:
public AddedFont AddStandard14Font(Standard14Font type)
Or for a TrueType font use:
AddedFont AddTrueTypeFont(IReadOnlyList<byte> fontFileBytes)
Passing in the bytes of a TrueType file (.ttf). You can check the suitability of a TrueType file for embedding in a PDF document using:
bool CanUseTrueTypeFont(IReadOnlyList<byte> fontFileBytes, out IReadOnlyList<string> reasons)
Which provides a list of reasons why the font cannot be used if the check fails. You should check the license for a TrueType font prior to use, since the compressed font file is embedded in, and distributed with, the resultant document.
The ```AddedFont``` class represents a key to the font stored on the document builder. This must be provided when adding text content to pages. To add a page to a document use:
PdfPageBuilder AddPage(PageSize size, bool isPortrait = true)
This creates a new ```PdfPageBuilder``` with the specified size. The first added page is page number 1, then 2, then 3, etc. The page builder supports adding text, drawing lines and rectangles and measuring the size of text prior to drawing.
To draw lines and rectangles in black (different colors are not currently supported) use the methods:
void DrawLine(PdfPoint from, PdfPoint to, decimal lineWidth = 1)
void DrawRectangle(PdfPoint position, decimal width, decimal height, decimal lineWidth = 1)
The line width can be varied and defaults to 1.
To write text to the page you must have a reference to an ```AddedFont``` from the methods on ```PdfDocumentBuilder``` as described above. You can then draw the text to the page using:
IReadOnlyList<Letter> AddText(string text, decimal fontSize, PdfPoint position, PdfDocumentBuilder.AddedFont font)
Where ```position``` is the baseline of the text to draw. Currently **only ASCII text is supported** and the text will be drawn in black and the color cannot be varied. You can also measure the resulting size of text prior to drawing using the method:
IReadOnlyList<Letter> MeasureText(string text, decimal fontSize, PdfPoint position, PdfDocumentBuilder.AddedFont font)
Which does not change the state of the page, unlike ```AddText```.
### Document Information ###
The ```PdfDocument``` provides access to the document metadata as ```DocumentInformation``` defined in the PDF file. These tend not to be provided therefore most of these entries will be ```null```:

View File

@@ -50,6 +50,7 @@
"UglyToad.PdfPig.Fonts.FontDescriptor",
"UglyToad.PdfPig.Fonts.FontDescriptorFlags",
"UglyToad.PdfPig.Fonts.FontStretch",
"UglyToad.PdfPig.Fonts.Standard14Font",
"UglyToad.PdfPig.Tokens.ArrayToken",
"UglyToad.PdfPig.Tokens.BooleanToken",
"UglyToad.PdfPig.Tokens.CommentToken",
@@ -65,6 +66,9 @@
"UglyToad.PdfPig.Tokens.StreamToken",
"UglyToad.PdfPig.Tokens.StringToken",
"UglyToad.PdfPig.Util.IWordExtractor",
"UglyToad.PdfPig.Writer.PdfDocumentBuilder",
"UglyToad.PdfPig.Writer.PdfPageBuilder",
"UglyToad.PdfPig.Writer.TokenWriter",
"UglyToad.PdfPig.XObjects.XObjectImage"
};

View File

@@ -68,9 +68,9 @@
{
var builder = new PdfDocumentBuilder();
var page = builder.AddPage(PageSize.A4);
PdfPageBuilder page = builder.AddPage(PageSize.A4);
var font = builder.AddStandard14Font(Standard14Font.Helvetica);
PdfDocumentBuilder.AddedFont font = builder.AddStandard14Font(Standard14Font.Helvetica);
page.AddText("Hello World!", 12, new PdfPoint(25, 520), font);

View File

@@ -38,7 +38,7 @@
public string Keywords { get; }
/// <summary>
/// The name of the application which created the original document before it was converted to PDF. if applicable.
/// The name of the application which created the original document before it was converted to PDF if applicable.
/// </summary>
[CanBeNull]
public string Creator { get; }

View File

@@ -167,22 +167,4 @@
return mappedName;
}
}
internal enum Standard14Font
{
TimesRoman = 0,
TimesBold = 1,
TimesItalic=2,
TimesBoldItalic = 3,
Helvetica = 4,
HelveticaBold = 5,
HelveticaOblique = 6,
HelveticaBoldOblique = 7,
Courier = 8,
CourierBold = 9,
CourierOblique = 10,
CourierBoldOblique = 11,
Symbol = 12,
ZapfDingbats = 13
}
}

View File

@@ -0,0 +1,65 @@
namespace UglyToad.PdfPig.Fonts
{
/// <summary>
/// The Standard 14 fonts included by default in PDF readers.
/// </summary>
public enum Standard14Font
{
/// <summary>
/// Times New Roman.
/// </summary>
TimesRoman = 0,
/// <summary>
/// Times New Roman Bold.
/// </summary>
TimesBold = 1,
/// <summary>
/// Times New Roman Italic.
/// </summary>
TimesItalic = 2,
/// <summary>
/// Times New Roman Bold and Italic.
/// </summary>
TimesBoldItalic = 3,
/// <summary>
/// Helvetica.
/// </summary>
Helvetica = 4,
/// <summary>
/// Helvetica Bold.
/// </summary>
HelveticaBold = 5,
/// <summary>
/// Helvetica Oblique (Italic without different font shapes).
/// </summary>
HelveticaOblique = 6,
/// <summary>
/// Helvetica Bold and Oblique.
/// </summary>
HelveticaBoldOblique = 7,
/// <summary>
/// Courier.
/// </summary>
Courier = 8,
/// <summary>
/// Courier Bold.
/// </summary>
CourierBold = 9,
/// <summary>
/// Courier Oblique.
/// </summary>
CourierOblique = 10,
/// <summary>
/// Courier Bold and Oblique.
/// </summary>
CourierBoldOblique = 11,
/// <summary>
/// Symbol.
/// </summary>
Symbol = 12,
/// <summary>
/// Zapf Dingbats.
/// </summary>
ZapfDingbats = 13
}
}

View File

@@ -87,6 +87,7 @@
// TODO: Implement and test this;
return null;
#pragma warning disable 162
var rowWidth = data.ReadUnsignedShort();
var leftClassTableOffset = data.ReadUnsignedShort();
@@ -135,6 +136,7 @@
}
return new KerningSubTable(version, coverage, pairs);
#pragma warning restore 162
}
}
}

View File

@@ -18,7 +18,7 @@
/// <summary>
/// Provides methods to construct new PDF documents.
/// </summary>
internal class PdfDocumentBuilder
public class PdfDocumentBuilder
{
private static readonly TrueTypeFontParser Parser = new TrueTypeFontParser();
@@ -29,6 +29,7 @@
/// Whether to include the document information dictionary in the produced document.
/// </summary>
public bool IncludeDocumentInformation { get; set; } = true;
/// <summary>
/// The values of the fields to include in the document information dictionary.
/// </summary>
@@ -42,7 +43,7 @@
/// <summary>
/// The fonts currently available in the document builder added via <see cref="AddTrueTypeFont"/> or <see cref="AddStandard14Font"/>. Keyed by id for internal purposes.
/// </summary>
public IReadOnlyDictionary<Guid, IWritingFont> Fonts => fonts.ToDictionary(x => x.Key, x => x.Value.FontProgram);
internal IReadOnlyDictionary<Guid, IWritingFont> Fonts => fonts.ToDictionary(x => x.Key, x => x.Value.FontProgram);
/// <summary>
/// Determines whether the bytes of the TrueType font file provided can be used in a PDF document.
@@ -340,12 +341,25 @@
}
}
/// <summary>
/// A key representing a font available to use on the current document builder. Create by adding a font to a document using either
/// <see cref="AddStandard14Font"/> or <see cref="AddTrueTypeFont"/>.
/// </summary>
public class AddedFont
{
public Guid Id { get; }
/// <summary>
/// The Id uniquely identifying this font on the builder.
/// </summary>
internal Guid Id { get; }
/// <summary>
/// The name of this font.
/// </summary>
public NameToken Name { get; }
/// <summary>
/// Create a new <see cref="AddedFont"/>.
/// </summary>
internal AddedFont(Guid id, NameToken name)
{
Id = id;
@@ -353,13 +367,40 @@
}
}
internal class DocumentInformationBuilder
/// <summary>
/// Sets the values of the <see cref="DocumentInformation"/> dictionary for the document being created.
/// Control inclusion of the document information dictionary on the output with <see cref="IncludeDocumentInformation"/>.
/// </summary>
public class DocumentInformationBuilder
{
/// <summary>
/// <see cref="DocumentInformation.Title"/>.
/// </summary>
public string Title { get; set; }
/// <summary>
/// <see cref="DocumentInformation.Author"/>.
/// </summary>
public string Author { get; set; }
/// <summary>
/// <see cref="DocumentInformation.Subject"/>.
/// </summary>
public string Subject { get; set; }
/// <summary>
/// <see cref="DocumentInformation.Keywords"/>.
/// </summary>
public string Keywords { get; set; }
/// <summary>
/// <see cref="DocumentInformation.Creator"/>.
/// </summary>
public string Creator { get; set; }
/// <summary>
/// <see cref="DocumentInformation.Producer"/>.
/// </summary>
public string Producer { get; set; } = "PdfPig";
internal Dictionary<NameToken, IToken> ToDictionary()

View File

@@ -16,7 +16,7 @@
/// <summary>
/// A builder used to add construct a page in a PDF document.
/// </summary>
internal class PdfPageBuilder
public class PdfPageBuilder
{
private readonly PdfDocumentBuilder documentBuilder;
private readonly List<IGraphicsStateOperation> operations = new List<IGraphicsStateOperation>();

View File

@@ -8,7 +8,10 @@
using Tokens;
using Util;
internal class TokenWriter
/// <summary>
/// Writes any type of <see cref="IToken"/> to the corresponding PDF document format output.
/// </summary>
public class TokenWriter
{
private static readonly byte ArrayStart = GetByte("[");
private static readonly byte ArrayEnd = GetByte("]");
@@ -52,6 +55,11 @@
private static readonly byte[] Xref = OtherEncodings.StringAsLatin1Bytes("xref");
/// <summary>
/// Writes the given input token to the output stream with the correct PDF format and encoding including whitespace and line breaks as applicable.
/// </summary>
/// <param name="token">The token to write to the stream.</param>
/// <param name="outputStream">The stream to write the token to.</param>
public static void WriteToken(IToken token, Stream outputStream)
{
switch (token)
@@ -96,14 +104,14 @@
}
}
private static void WriteHex(HexToken hex, Stream stream)
{
stream.WriteByte(HexStart);
stream.WriteText(hex.GetHexString());
stream.WriteByte(HexEnd);
}
public static void WriteCrossReferenceTable(IReadOnlyDictionary<IndirectReference, long> objectOffsets,
/// <summary>
/// Writes a valid single section cross-reference (xref) table plus trailer dictionary to the output for the set of object offsets.
/// </summary>
/// <param name="objectOffsets">The byte offset from the start of the document for each object in the document.</param>
/// <param name="catalogToken">The object representing the catalog dictionary which is referenced from the trailer dictionary.</param>
/// <param name="outputStream">The output stream to write to.</param>
/// <param name="documentInformationReference">The object reference for the document information dictionary if present.</param>
internal static void WriteCrossReferenceTable(IReadOnlyDictionary<IndirectReference, long> objectOffsets,
ObjectToken catalogToken,
Stream outputStream,
IndirectReference? documentInformationReference)
@@ -198,6 +206,13 @@
outputStream.Write(Eof, 0, Eof.Length);
}
private static void WriteHex(HexToken hex, Stream stream)
{
stream.WriteByte(HexStart);
stream.WriteText(hex.GetHexString());
stream.WriteByte(HexEnd);
}
private static void WriteArray(ArrayToken array, Stream outputStream)
{
outputStream.WriteByte(ArrayStart);