Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[POC] Start refactoring to render pdf pages as images #656

Closed
wants to merge 5 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
37 changes: 23 additions & 14 deletions src/UglyToad.PdfPig.Core/TransformationMatrix.cs
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
namespace UglyToad.PdfPig.Core
{
using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics.Contracts;
using System.Linq;
Expand All @@ -10,22 +9,22 @@
/// <summary>
/// Specifies the conversion from the transformed coordinate space to the original untransformed coordinate space.
/// </summary>
public struct TransformationMatrix
public readonly struct TransformationMatrix
{
/// <summary>
/// The default <see cref="TransformationMatrix"/>.
/// </summary>
public static TransformationMatrix Identity = new TransformationMatrix(1,0,0,
0,1,0,
0,0,1);
public static TransformationMatrix Identity = new TransformationMatrix(1, 0, 0,
0, 1, 0,
0, 0, 1);

/// <summary>
/// Create a new <see cref="TransformationMatrix"/> with the X and Y translation values set.
/// </summary>
public static TransformationMatrix GetTranslationMatrix(double x, double y) => new TransformationMatrix(1, 0, 0,
0, 1, 0,
x, y, 1);

/// <summary>
/// Create a new <see cref="TransformationMatrix"/> with the X and Y scaling values set.
/// </summary>
Expand Down Expand Up @@ -105,7 +104,7 @@ public static TransformationMatrix GetRotationMatrix(double degreesCounterclockw
/// The value at (2, 1) - translation in Y.
/// </summary>
public readonly double F;

/// <summary>
/// Get the value at the specific row and column.
/// </summary>
Expand Down Expand Up @@ -224,10 +223,20 @@ public TransformationMatrix(double a, double b, double r1, double c, double d, d
[Pure]
public PdfPoint Transform(PdfPoint original)
{
var x = A * original.X + C * original.Y + E;
var y = B * original.X + D * original.Y + F;
(double x, double y) xy = Transform(original.X, original.Y);
return new PdfPoint(xy.x, xy.y);
}

return new PdfPoint(x, y);
/// <summary>
/// Transform a point using this transformation matrix.
/// </summary>
/// <param name="x">The original point X coordinate.</param>
/// <param name="y">The original point Y coordinate.</param>
/// <returns>A new point which is the result of applying this transformation matrix.</returns>
[Pure]
public (double x, double y) Transform(double x, double y)
{
return new(A * x + C * y + E, B * x + D * y + F);
}

/// <summary>
Expand Down Expand Up @@ -353,7 +362,7 @@ public static TransformationMatrix FromValues(double a, double b, double c, doub
/// <param name="values">Either all 9 values of the matrix, 6 values in the default PDF order or the 4 values of the top left square.</param>
/// <returns></returns>
public static TransformationMatrix FromArray(decimal[] values)
=> FromArray(values.Select(x => (double) x).ToArray());
=> FromArray(values.Select(x => (double)x).ToArray());

/// <summary>
/// Create a new <see cref="TransformationMatrix"/> from the values.
Expand Down Expand Up @@ -404,8 +413,8 @@ public TransformationMatrix Multiply(TransformationMatrix matrix)
var f = (E * matrix.B) + (F * matrix.D) + (row3 * matrix.F);
var r3 = (E * matrix.row1) + (F * matrix.row2) + (row3 * matrix.row3);

return new TransformationMatrix(a, b, r1,
c, d, r2,
return new TransformationMatrix(a, b, r1,
c, d, r2,
e, f, r3);
}

Expand Down
1 change: 1 addition & 0 deletions src/UglyToad.PdfPig.Core/UglyToad.PdfPig.Core.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
<GenerateDocumentationFile>true</GenerateDocumentationFile>
<SignAssembly>true</SignAssembly>
<AssemblyOriginatorKeyFile>..\pdfpig.snk</AssemblyOriginatorKeyFile>
<Nullable>annotations</Nullable>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(TargetFramework)|$(Platform)'=='Debug|netstandard2.0|AnyCPU'">
<TreatWarningsAsErrors>true</TreatWarningsAsErrors>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
<GenerateDocumentationFile>true</GenerateDocumentationFile>
<SignAssembly>true</SignAssembly>
<AssemblyOriginatorKeyFile>..\pdfpig.snk</AssemblyOriginatorKeyFile>
<Nullable>annotations</Nullable>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(TargetFramework)|$(Platform)'=='Debug|netstandard2.0|AnyCPU'">
<TreatWarningsAsErrors>true</TreatWarningsAsErrors>
Expand Down
1 change: 1 addition & 0 deletions src/UglyToad.PdfPig.Fonts/UglyToad.PdfPig.Fonts.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
<GenerateDocumentationFile>true</GenerateDocumentationFile>
<SignAssembly>true</SignAssembly>
<AssemblyOriginatorKeyFile>..\pdfpig.snk</AssemblyOriginatorKeyFile>
<Nullable>annotations</Nullable>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(TargetFramework)|$(Platform)'=='Debug|netstandard2.0|AnyCPU'">
<TreatWarningsAsErrors>true</TreatWarningsAsErrors>
Expand Down
22 changes: 22 additions & 0 deletions src/UglyToad.PdfPig.Rendering.Skia.Tests/Helpers.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
namespace UglyToad.PdfPig.Rendering.Skia.Tests
{
internal static class Helpers
{
private static readonly string basePath = Path.GetFullPath("..\\..\\..\\..\\UglyToad.PdfPig.Tests\\Integration\\Documents");

public static string GetDocumentPath(string fileName)
{
if (!fileName.EndsWith(".pdf"))
{
fileName += ".pdf";
}

return Path.Combine(basePath, fileName);
}

public static string[] GetAllDocuments()
{
return Directory.GetFiles(basePath, "*.pdf");
}
}
}
97 changes: 97 additions & 0 deletions src/UglyToad.PdfPig.Rendering.Skia.Tests/RenderTests.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,97 @@
using SkiaSharp;
using UglyToad.PdfPig.Rendering.Skia.Parser;

namespace UglyToad.PdfPig.Rendering.Skia.Tests
{
public class RenderTests
{
// Image rotated bug

const float scale = 1.5f;

public RenderTests()
{
Directory.CreateDirectory("renders");
}

[Fact]
public void PigProductionHandbook()
{
RenderDocument("Pig Production Handbook");
}

[Fact]
public void d_68_1990_01_A()
{
RenderDocument("68-1990-01_A");
}

[Fact]
public void d_22060_A1_01_Plans_1()
{
RenderDocument("22060_A1_01_Plans-1");
}

[Fact]
public void cat_genetics_bobld()
{
RenderDocument("cat-genetics_bobld");
}

[Fact(Skip = "For debugging purpose")]
public void RenderAllDocuments()
{
foreach (string doc in Helpers.GetAllDocuments())
{
string fileName = Path.GetFileNameWithoutExtension(doc);

using (var document = PdfDocument.Open(doc))
{
document.AddPageFactory<SKPicture, SkiaPageFactory>();

for (int p = 1; p <= document.NumberOfPages; p++)
{
var page = document.GetPage(p);

using (var picture = document.GetPage<SKPicture>(p))
{
Assert.NotNull(picture);

using (var fs = new FileStream($"renders\\{fileName}_{p}.png", FileMode.Create))
using (var image = SKImage.FromPicture(picture, new SKSizeI((int)(page.Width * scale), (int)(page.Height * scale)), SKMatrix.CreateScale(scale, scale)))
using (SKData d = image.Encode(SKEncodedImageFormat.Png, 100))
{
d.SaveTo(fs);
}
}
}
}
}
}

private static void RenderDocument(string path)
{
using (var document = PdfDocument.Open(Helpers.GetDocumentPath(path)))
{
document.AddPageFactory<SKPicture, SkiaPageFactory>();

for (int p = 1; p <= document.NumberOfPages; p++)
{
var page = document.GetPage(p);

using (var picture = document.GetPage<SKPicture>(p))
{
Assert.NotNull(picture);

using (var fs = new FileStream($"renders\\{path}_{p}.png", FileMode.Create))
using (var image = SKImage.FromPicture(picture, new SKSizeI((int)(page.Width * scale), (int)(page.Height * scale)), SKMatrix.CreateScale(scale, scale)))
using (SKData d = image.Encode(SKEncodedImageFormat.Png, 100))
{
d.SaveTo(fs);
}
}
}
}
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
<Project Sdk="Microsoft.NET.Sdk">

<PropertyGroup>
<TargetFramework>net6.0</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>

<IsPackable>false</IsPackable>
<IsTestProject>true</IsTestProject>
</PropertyGroup>

<ItemGroup>
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="17.5.0" />
<PackageReference Include="xunit" Version="2.4.2" />
<PackageReference Include="xunit.runner.visualstudio" Version="2.4.5">
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
<PrivateAssets>all</PrivateAssets>
</PackageReference>
<PackageReference Include="coverlet.collector" Version="3.2.0">
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
<PrivateAssets>all</PrivateAssets>
</PackageReference>
</ItemGroup>

<ItemGroup>
<ProjectReference Include="..\UglyToad.PdfPig.Rendering.Skia\UglyToad.PdfPig.Rendering.Skia.csproj" />
</ItemGroup>

</Project>
1 change: 1 addition & 0 deletions src/UglyToad.PdfPig.Rendering.Skia.Tests/Usings.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
global using Xunit;
Loading
Loading