Skip to content

Commit 1139de6

Browse files
committed
Added first cut of a new SkiaSharp render target based on the PDFSharp target.
1 parent b2b5d2e commit 1139de6

22 files changed

+1996
-2
lines changed

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -109,3 +109,4 @@ UpgradeLog*.XML
109109

110110
*.DotSettings
111111
/Source/.vs/
112+
/Source/Demo/Console/HtmlRenderer.Demo.Console/Output
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
<Project Sdk="Microsoft.NET.Sdk">
2+
3+
<PropertyGroup>
4+
<OutputType>Exe</OutputType>
5+
<TargetFramework>net7.0</TargetFramework>
6+
<ImplicitUsings>enable</ImplicitUsings>
7+
<Nullable>enable</Nullable>
8+
</PropertyGroup>
9+
10+
<ItemGroup>
11+
<ProjectReference Include="..\..\..\HtmlRenderer.Core\HtmlRenderer.Core.csproj" />
12+
<ProjectReference Include="..\..\..\HtmlRenderer.PdfSharp.Core\HtmlRenderer.PdfSharp.Core.csproj" />
13+
<ProjectReference Include="..\..\..\HtmlRenderer.SkiaSharp\HtmlRenderer.SkiaSharp.csproj" />
14+
<ProjectReference Include="..\..\Common\HtmlRenderer.Demo.Common.csproj" />
15+
</ItemGroup>
16+
17+
</Project>
Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
using System;
2+
using System.Collections.Generic;
3+
using System.Linq;
4+
using System.Text;
5+
using System.Threading.Tasks;
6+
using TheArtOfDev.HtmlRenderer.Demo.Common;
7+
using TheArtOfDev.HtmlRenderer.PdfSharp;
8+
9+
namespace HtmlRenderer.Demo.Console
10+
{
11+
public class PdfSharpCoreConverter : SampleConverterBase
12+
{
13+
public PdfSharpCoreConverter(string sampleRunIdentifier, string basePath) : base(sampleRunIdentifier, basePath)
14+
{
15+
}
16+
17+
public void GenerateSample(HtmlSample sample)
18+
{
19+
var config = new PdfGenerateConfig();
20+
21+
config.PageSize = PdfSharpCore.PageSize.A4;
22+
config.MarginLeft = 0;
23+
config.MarginRight = 0;
24+
config.MarginTop = 0;
25+
config.MarginBottom = 0;
26+
27+
var pdf = PdfGenerator.GeneratePdf(sample.Html, config, base.CssData, base.StylesheetLoad, base.ImageLoad);
28+
pdf.Save(GetSamplePath(sample));
29+
}
30+
}
31+
}
Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
using HtmlRenderer.Demo.Console;
2+
using System.Diagnostics;
3+
using TheArtOfDev.HtmlRenderer.Demo.Common;
4+
5+
//By default, write to a sub folder 'output'
6+
string basePath= @".\Ouput";
7+
if (args.Length > 0)
8+
{
9+
//And if there's an output path given, use that.
10+
basePath = args[0];
11+
}
12+
13+
//Probably won't be running a suite of tests more than once a second, so this will do.
14+
string runIdentifier = DateTime.Now.ToString("ddMMyyyy-hhMMss");
15+
16+
var skia = new SkiaConverter(runIdentifier, basePath);
17+
var pdfSharp = new PdfSharpCoreConverter(runIdentifier, basePath);
18+
19+
SamplesLoader.Init("Console", typeof(Program).Assembly.GetName().Version.ToString());
20+
21+
var samples = SamplesLoader.TestSamples;
22+
23+
foreach (var htmlSample in samples)
24+
{
25+
skia.GenerateSample(htmlSample);
26+
pdfSharp.GenerateSample(htmlSample);
27+
}
28+
29+
30+
//At this point.. there should be something!!
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
{
2+
"profiles": {
3+
"HtmlRenderer.Demo.Console": {
4+
"commandName": "Project",
5+
"commandLineArgs": "..\\..\\..\\Output"
6+
}
7+
}
8+
}
Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
using System;
2+
using System.Collections.Generic;
3+
using System.Linq;
4+
using System.Runtime.CompilerServices;
5+
using System.Text;
6+
using System.Threading.Tasks;
7+
using TheArtOfDev.HtmlRenderer.Demo.Common;
8+
9+
namespace HtmlRenderer.Demo.Console
10+
{
11+
public class SampleConverterBase
12+
{
13+
private string _sampleRunIdentifier;
14+
private string _thisTypeName;
15+
private string _basePath;
16+
17+
public SampleConverterBase(string sampleRunIdentifier, string basePath)
18+
{
19+
_sampleRunIdentifier = sampleRunIdentifier;
20+
_basePath = basePath;
21+
_thisTypeName = this.GetType().Name;
22+
}
23+
24+
protected string GetSamplePath(HtmlSample sample)
25+
{
26+
var path = Path.Combine(_basePath, _sampleRunIdentifier);
27+
Directory.CreateDirectory(path);
28+
return Path.Combine(path, sample.FullName + _thisTypeName + "_" + ".pdf");
29+
}
30+
}
31+
}
Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
using System;
2+
using System.Collections.Generic;
3+
using System.Linq;
4+
using System.Text;
5+
using System.Threading.Tasks;
6+
using TheArtOfDev.HtmlRenderer.Demo.Common;
7+
using TheArtOfDev.HtmlRenderer.SkiaSharp;
8+
9+
namespace HtmlRenderer.Demo.Console
10+
{
11+
public class SkiaConverter : SampleConverterBase
12+
{
13+
public SkiaConverter(string sampleRunIdentifier, string basePath) : base(sampleRunIdentifier, basePath)
14+
{
15+
}
16+
17+
public void GenerateSample(HtmlSample sample)
18+
{
19+
var config = new PdfGenerateConfig();
20+
21+
config.PageSize = PageSizeType.A4;
22+
//TODO: 'Units' on config, rather than this c/p 🤮
23+
config.MarginLeft = PdfGenerateConfig.MilimitersToPixels(0);
24+
config.MarginRight = PdfGenerateConfig.MilimitersToPixels(0);
25+
config.MarginTop = PdfGenerateConfig.MilimitersToPixels(0);
26+
config.MarginBottom = PdfGenerateConfig.MilimitersToPixels(0);
27+
28+
var pdf = PdfGenerator.GeneratePdf(sample.Html, config, base.CssData, base.StylesheetLoad, base.ImageLoad);
29+
using (var fileStream = File.Open(GetSamplePath(sample), FileMode.CreateNew))
30+
{
31+
pdf.CopyTo(fileStream);
32+
fileStream.Flush();
33+
}
34+
}
35+
}
36+
}
Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
// "Therefore those skilled at the unorthodox
2+
// are infinite as heaven and earth,
3+
// inexhaustible as the great rivers.
4+
// When they come to an end,
5+
// they begin again,
6+
// like the days and months;
7+
// they die and are reborn,
8+
// like the four seasons."
9+
//
10+
// - Sun Tsu,
11+
// "The Art of War"
12+
13+
using System;
14+
using TheArtOfDev.HtmlRenderer.Adapters;
15+
using SkiaSharp;
16+
17+
namespace TheArtOfDev.HtmlRenderer.SkiaSharp.Adapters
18+
{
19+
/// <summary>
20+
/// Adapter for WinForms brushes objects for core.
21+
/// </summary>
22+
internal sealed class BrushAdapter : RBrush
23+
{
24+
/// <summary>
25+
/// The actual PdfSharp brush instance.<br/>
26+
/// Should be <see cref="XBrush"/> but there is some fucking issue inheriting from it =/
27+
/// </summary>
28+
private readonly object _brush;
29+
30+
/// <summary>
31+
/// Init.
32+
/// </summary>
33+
public BrushAdapter(object brush)
34+
{
35+
_brush = brush;
36+
}
37+
38+
/// <summary>
39+
/// The actual WinForms brush instance.
40+
/// </summary>
41+
public object Brush
42+
{
43+
get { return _brush; }
44+
}
45+
46+
public override void Dispose()
47+
{ }
48+
}
49+
}
Lines changed: 105 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,105 @@
1+
// "Therefore those skilled at the unorthodox
2+
// are infinite as heaven and earth,
3+
// inexhaustible as the great rivers.
4+
// When they come to an end,
5+
// they begin again,
6+
// like the days and months;
7+
// they die and are reborn,
8+
// like the four seasons."
9+
//
10+
// - Sun Tsu,
11+
// "The Art of War"
12+
13+
using TheArtOfDev.HtmlRenderer.Adapters;
14+
using SkiaSharp;
15+
16+
namespace TheArtOfDev.HtmlRenderer.SkiaSharp.Adapters
17+
{
18+
/// <summary>
19+
/// Adapter for WinForms Font object for core.
20+
/// </summary>
21+
internal sealed class FontAdapter : RFont
22+
{
23+
#region Fields and Consts
24+
25+
/// <summary>
26+
/// the underline win-forms font.
27+
/// </summary>
28+
private readonly SKFont _font;
29+
30+
/// <summary>
31+
/// the vertical offset of the font underline location from the top of the font.
32+
/// </summary>
33+
private double _underlineOffset = -1;
34+
35+
/// <summary>
36+
/// Cached font height.
37+
/// </summary>
38+
private double _height = -1;
39+
40+
/// <summary>
41+
/// Cached font whitespace width.
42+
/// </summary>
43+
private double _whitespaceWidth = -1;
44+
45+
#endregion
46+
47+
48+
/// <summary>
49+
/// Init.
50+
/// </summary>
51+
public FontAdapter(SKFont font)
52+
{
53+
_font = font;
54+
}
55+
56+
/// <summary>
57+
/// the underline win-forms font.
58+
/// </summary>
59+
public SKFont Font
60+
{
61+
get { return _font; }
62+
}
63+
64+
public override double Size
65+
{
66+
get { return _font.Size; }
67+
}
68+
69+
public override double UnderlineOffset
70+
{
71+
get { return _underlineOffset; }
72+
}
73+
74+
public override double Height
75+
{
76+
get { return _height; }
77+
}
78+
79+
public override double LeftPadding
80+
{
81+
get { return _height / 6f; }
82+
}
83+
84+
85+
public override double GetWhitespaceWidth(RGraphics graphics)
86+
{
87+
if (_whitespaceWidth < 0)
88+
{
89+
_whitespaceWidth = graphics.MeasureString(" ", this).Width;
90+
}
91+
return _whitespaceWidth;
92+
}
93+
94+
/// <summary>
95+
/// Set font metrics to be cached for the font for future use.
96+
/// </summary>
97+
/// <param name="height">the full height of the font</param>
98+
/// <param name="underlineOffset">the vertical offset of the font underline location from the top of the font.</param>
99+
internal void SetMetrics(int height, int underlineOffset)
100+
{
101+
_height = height;
102+
_underlineOffset = underlineOffset;
103+
}
104+
}
105+
}
Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
// "Therefore those skilled at the unorthodox
2+
// are infinite as heaven and earth,
3+
// inexhaustible as the great rivers.
4+
// When they come to an end,
5+
// they begin again,
6+
// like the days and months;
7+
// they die and are reborn,
8+
// like the four seasons."
9+
//
10+
// - Sun Tsu,
11+
// "The Art of War"
12+
13+
using SkiaSharp;
14+
using TheArtOfDev.HtmlRenderer.Adapters;
15+
16+
namespace TheArtOfDev.HtmlRenderer.SkiaSharp.Adapters
17+
{
18+
/// <summary>
19+
/// Adapter for WinForms Font object for core.
20+
/// </summary>
21+
internal sealed class FontFamilyAdapter : RFontFamily
22+
{
23+
/// <summary>
24+
/// the underline win-forms font.
25+
/// </summary>
26+
private readonly SKTypeface _fontFamily;
27+
28+
/// <summary>
29+
/// Init.
30+
/// </summary>
31+
public FontFamilyAdapter(SKTypeface fontFamily)
32+
{
33+
_fontFamily = fontFamily;
34+
}
35+
36+
/// <summary>
37+
/// the underline win-forms font family.
38+
/// </summary>
39+
public SKTypeface FontFamily
40+
{
41+
get { return _fontFamily; }
42+
}
43+
44+
public override string Name
45+
{
46+
get { return _fontFamily.FamilyName; }
47+
}
48+
}
49+
}

0 commit comments

Comments
 (0)