Skip to content

Commit 9ace674

Browse files
authored
Merge pull request #36 from synercoder/features/refactor
Complete rewrite with better low-level support
2 parents 8f65e79 + 99dcd45 commit 9ace674

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

53 files changed

+2109
-1345
lines changed

Directory.Build.props

Lines changed: 0 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -48,16 +48,6 @@
4848
</PropertyGroup>
4949

5050
<Choose>
51-
<When Condition="'$(TargetFramework)' == 'net472'">
52-
<PropertyGroup>
53-
<DefineConstants>$(DefineConstants);SUPPORTS_CODECOVERAGE</DefineConstants>
54-
</PropertyGroup>
55-
</When>
56-
<When Condition="'$(TargetFramework)' == 'netstandard2.0'">
57-
<PropertyGroup>
58-
<DefineConstants>$(DefineConstants);SUPPORTS_CODECOVERAGE</DefineConstants>
59-
</PropertyGroup>
60-
</When>
6151
<When Condition="'$(TargetFramework)' == 'netstandard2.1'">
6252
<PropertyGroup>
6353
<DefineConstants>$(DefineConstants);SUPPORTS_MATHF</DefineConstants>
@@ -66,19 +56,6 @@
6656
<DefineConstants>$(DefineConstants);SUPPORTS_NULLABLEREFATTRIBUTES</DefineConstants>
6757
</PropertyGroup>
6858
</When>
69-
<When Condition="'$(TargetFramework)' == 'netcoreapp2.0'">
70-
<PropertyGroup>
71-
<DefineConstants>$(DefineConstants);SUPPORTS_MATHF</DefineConstants>
72-
<DefineConstants>$(DefineConstants);SUPPORTS_CODECOVERAGE</DefineConstants>
73-
</PropertyGroup>
74-
</When>
75-
<When Condition="'$(TargetFramework)' == 'netcoreapp2.1'">
76-
<PropertyGroup>
77-
<DefineConstants>$(DefineConstants);SUPPORTS_MATHF</DefineConstants>
78-
<DefineConstants>$(DefineConstants);SUPPORTS_HASHCODE</DefineConstants>
79-
<DefineConstants>$(DefineConstants);SUPPORTS_CODECOVERAGE</DefineConstants>
80-
</PropertyGroup>
81-
</When>
8259
<When Condition="'$(TargetFramework)' == 'netcoreapp3.1'">
8360
<PropertyGroup>
8461
<DefineConstants>$(DefineConstants);SUPPORTS_MATHF</DefineConstants>

samples/Synercoding.FileFormats.Pdf.ConsoleTester/Program.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
using Synercoding.FileFormats.Pdf.Primitives;
1+
using Synercoding.FileFormats.Pdf.Extensions;
22
using Synercoding.Primitives;
33
using Synercoding.Primitives.Extensions;
44
using System.IO;

src/Directory.Build.props

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
<Project>
33

44
<PropertyGroup>
5-
<TargetFrameworks>net5.0;netcoreapp3.1;netcoreapp2.1;netstandard2.1;netstandard2.0;netstandard1.6</TargetFrameworks>
5+
<TargetFrameworks>net5.0;netcoreapp3.1;netstandard2.1</TargetFrameworks>
66
<MSBuildAllProjects>$(MSBuildAllProjects);$(MSBuildThisFileDirectory)..\Directory.Build.props</MSBuildAllProjects>
77
<SynercodingProjectCategory>src</SynercodingProjectCategory>
88
</PropertyGroup>

src/Synercoding.FileFormats.Pdf/DocumentInformation.cs

Lines changed: 92 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,21 @@
1+
using Synercoding.FileFormats.Pdf.LowLevel;
2+
using Synercoding.FileFormats.Pdf.LowLevel.Extensions;
13
using System;
24

35
namespace Synercoding.FileFormats.Pdf
46
{
57
/// <summary>
68
/// This class contains information about the document
79
/// </summary>
8-
public class DocumentInformation
10+
public class DocumentInformation : IPdfObject
911
{
12+
private bool _isWritten;
13+
14+
internal DocumentInformation(PdfReference id)
15+
{
16+
Reference = id;
17+
}
18+
1019
/// <summary>
1120
/// The document's title
1221
/// </summary>
@@ -46,5 +55,87 @@ public class DocumentInformation
4655
/// The date and time the document was most recently modified, in human-readable form.
4756
/// </summary>
4857
public DateTime? ModDate { get; set; }
58+
59+
/// <inheritdoc />
60+
public PdfReference Reference { get; }
61+
62+
internal uint WriteToStream(PdfStream stream)
63+
{
64+
if (_isWritten)
65+
throw new InvalidOperationException("Object is already written to stream.");
66+
67+
var position = (uint)stream.Position;
68+
69+
stream.IndirectDictionary(this, static (did, dictionary) =>
70+
{
71+
if (!string.IsNullOrWhiteSpace(did.Title))
72+
dictionary.Write(PdfName.Get("Title"), _toPdfHexadecimalString(did.Title!));
73+
if (!string.IsNullOrWhiteSpace(did.Author))
74+
dictionary.Write(PdfName.Get("Author"), _toPdfHexadecimalString(did.Author!));
75+
if (!string.IsNullOrWhiteSpace(did.Subject))
76+
dictionary.Write(PdfName.Get("Subject"), _toPdfHexadecimalString(did.Subject!));
77+
if (!string.IsNullOrWhiteSpace(did.Keywords))
78+
dictionary.Write(PdfName.Get("Keywords"), _toPdfHexadecimalString(did.Keywords!));
79+
if (!string.IsNullOrWhiteSpace(did.Creator))
80+
dictionary.Write(PdfName.Get("Creator"), _toPdfHexadecimalString(did.Creator!));
81+
if (!string.IsNullOrWhiteSpace(did.Producer))
82+
dictionary.Write(PdfName.Get("Producer"), _toPdfHexadecimalString(did.Producer!));
83+
if (did.CreationDate != null)
84+
dictionary.Write(PdfName.Get("CreationDate"), _toPdfDate(did.CreationDate.Value));
85+
if (did.ModDate != null)
86+
dictionary.Write(PdfName.Get("ModDate"), _toPdfDate(did.ModDate.Value));
87+
});
88+
89+
_isWritten = true;
90+
91+
return position;
92+
}
93+
94+
private static string _toPdfHexadecimalString(string input)
95+
{
96+
var bytes = System.Text.Encoding.ASCII.GetBytes(input);
97+
var builder = new System.Text.StringBuilder((bytes.Length * 2) + 2);
98+
builder.Append('<');
99+
foreach (var b in bytes)
100+
{
101+
builder.Append(b.ToString("X2"));
102+
}
103+
builder.Append('>');
104+
return builder.ToString();
105+
}
106+
107+
private static string _toPdfDate(DateTimeOffset input)
108+
{
109+
var datePart = input.ToString("yyyyMMddHHmmss");
110+
111+
var builder = new System.Text.StringBuilder(22);
112+
builder.Append("(D:");
113+
builder.Append(datePart);
114+
115+
var hours = input.Offset.Hours;
116+
var minutes = input.Offset.Minutes;
117+
118+
if (hours == 0 && minutes == 0)
119+
{
120+
builder.Append("Z00'00");
121+
}
122+
else
123+
{
124+
if (hours > 0 || (hours == 0 && minutes > 0))
125+
{
126+
builder.Append('+');
127+
}
128+
else
129+
{
130+
builder.Append('-');
131+
}
132+
builder.Append(Math.Abs(hours).ToString().PadLeft(2, '0'));
133+
builder.Append('\'');
134+
builder.Append(minutes.ToString().PadLeft(2, '0'));
135+
}
136+
builder.Append(')');
137+
138+
return builder.ToString();
139+
}
49140
}
50141
}

src/Synercoding.FileFormats.Pdf/Extensions/MatrixExtensions.cs

Lines changed: 0 additions & 35 deletions
This file was deleted.
Lines changed: 127 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,127 @@
1+
using Synercoding.Primitives;
2+
using System.IO;
3+
4+
namespace Synercoding.FileFormats.Pdf.Extensions
5+
{
6+
/// <summary>
7+
/// Extension class for <see cref="PdfPage"/>
8+
/// </summary>
9+
public static class PdfPageExtensions
10+
{
11+
/// <summary>
12+
/// Add an image to the pdf page
13+
/// </summary>
14+
/// <param name="page">The page to add the image to</param>
15+
/// <param name="image">The image to add</param>
16+
/// <param name="matrix">The placement matrix</param>
17+
/// <returns>The same <see cref="PdfPage"/> to chain other calls.</returns>
18+
public static PdfPage AddImage(this PdfPage page, Image image, Matrix matrix)
19+
{
20+
page.ContentStream
21+
.SaveState()
22+
.CTM(matrix)
23+
.Paint(page.AddImageToResources(image))
24+
.RestoreState();
25+
26+
return page;
27+
}
28+
29+
/// <summary>
30+
/// Add an image to the pdf page
31+
/// </summary>
32+
/// <param name="page">The page to add the image to</param>
33+
/// <param name="image">The image to add</param>
34+
/// <param name="rectangle">The placement rectangle</param>
35+
/// <returns>The same <see cref="PdfPage"/> to chain other calls.</returns>
36+
public static PdfPage AddImage(this PdfPage page, Image image, Rectangle rectangle)
37+
=> page.AddImage(image, rectangle.AsPlacementMatrix());
38+
39+
/// <summary>
40+
/// Add an image to the pdf page
41+
/// </summary>
42+
/// <param name="page">The page to add the image to</param>
43+
/// <param name="image">The image to add</param>
44+
/// <param name="matrix">The placement matrix</param>
45+
/// <returns>The same <see cref="PdfPage"/> to chain other calls.</returns>
46+
public static PdfPage AddImage(this PdfPage page, SixLabors.ImageSharp.Image image, Matrix matrix)
47+
{
48+
page.ContentStream
49+
.SaveState()
50+
.CTM(matrix)
51+
.Paint(page.AddImageToResources(image))
52+
.RestoreState();
53+
54+
return page;
55+
}
56+
57+
/// <summary>
58+
/// Add an image to the pdf page
59+
/// </summary>
60+
/// <param name="page">The page to add the image to</param>
61+
/// <param name="image">The image to add</param>
62+
/// <param name="rectangle">The placement rectangle</param>
63+
/// <returns>The same <see cref="PdfPage"/> to chain other calls.</returns>
64+
public static PdfPage AddImage(this PdfPage page, SixLabors.ImageSharp.Image image, Rectangle rectangle)
65+
=> page.AddImage(image, rectangle.AsPlacementMatrix());
66+
67+
/// <summary>
68+
/// Add an image to the pdf page
69+
/// </summary>
70+
/// <param name="page">The page to add the image to</param>
71+
/// <param name="imageStream">The image to add</param>
72+
/// <param name="matrix">The placement matrix</param>
73+
/// <returns>The same <see cref="PdfPage"/> to chain other calls.</returns>
74+
public static PdfPage AddImage(this PdfPage page, Stream imageStream, Matrix matrix)
75+
{
76+
page.ContentStream
77+
.SaveState()
78+
.CTM(matrix)
79+
.Paint(page.AddImageToResources(imageStream))
80+
.RestoreState();
81+
82+
return page;
83+
}
84+
85+
/// <summary>
86+
/// Add an image to the pdf page
87+
/// </summary>
88+
/// <param name="page">The page to add the image to</param>
89+
/// <param name="imageStream">The image to add</param>
90+
/// <param name="rectangle">The placement rectangle</param>
91+
/// <returns>The same <see cref="PdfPage"/> to chain other calls.</returns>
92+
public static PdfPage AddImage(this PdfPage page, Stream imageStream, Rectangle rectangle)
93+
=> page.AddImage(imageStream, rectangle.AsPlacementMatrix());
94+
95+
/// <summary>
96+
/// Add an image to the pdf page
97+
/// </summary>
98+
/// <param name="page">The page to add the image to</param>
99+
/// <param name="jpgStream">The image to add</param>
100+
/// <param name="originalWidth">The original width of the image</param>
101+
/// <param name="originalHeight">The original height of the image</param>
102+
/// <param name="matrix">The placement matrix</param>
103+
/// <returns>The same <see cref="PdfPage"/> to chain other calls.</returns>
104+
public static PdfPage AddImage(this PdfPage page, Stream jpgStream, int originalWidth, int originalHeight, Matrix matrix)
105+
{
106+
page.ContentStream
107+
.SaveState()
108+
.CTM(matrix)
109+
.Paint(page.AddImageToResources(jpgStream, originalWidth, originalHeight))
110+
.RestoreState();
111+
112+
return page;
113+
}
114+
115+
/// <summary>
116+
/// Add an image to the pdf page
117+
/// </summary>
118+
/// <param name="page">The page to add the image to</param>
119+
/// <param name="jpgStream">The image to add</param>
120+
/// <param name="originalWidth">The original width of the image</param>
121+
/// <param name="originalHeight">The original height of the image</param>
122+
/// <param name="rectangle">The placement rectangle</param>
123+
/// <returns>The same <see cref="PdfPage"/> to chain other calls.</returns>
124+
public static PdfPage AddImage(this PdfPage page, Stream jpgStream, int originalWidth, int originalHeight, Rectangle rectangle)
125+
=> page.AddImage(jpgStream, originalWidth, originalHeight, rectangle.AsPlacementMatrix());
126+
}
127+
}
Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
using Synercoding.Primitives;
2+
3+
namespace Synercoding.FileFormats.Pdf.Extensions
4+
{
5+
public static class PrimitiveExtensions
6+
{
7+
public static Matrix AsPlacementMatrix(this Rectangle rectangle)
8+
{
9+
rectangle = rectangle.ConvertTo(Unit.Points);
10+
return new Matrix(
11+
rectangle.URX.Raw - rectangle.LLX.Raw, 0,
12+
0, rectangle.URY.Raw - rectangle.LLY.Raw,
13+
rectangle.LLX.Raw, rectangle.LLY.Raw);
14+
}
15+
}
16+
}

0 commit comments

Comments
 (0)