Skip to content
Merged
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
13 changes: 10 additions & 3 deletions .github/workflows/release-package.yml
Original file line number Diff line number Diff line change
Expand Up @@ -19,14 +19,21 @@ jobs:
with:
dotnet-version: 10.0.x

# The release tag drives the published version; _build/Version.props is the fallback default.
- name: Resolve version from release tag
id: version
run: echo "version=${TAG#v}" >> "$GITHUB_OUTPUT"
env:
TAG: ${{ github.event.release.tag_name }}

- name: Restore dependencies
run: dotnet restore
- name: Build
run: dotnet build --no-restore
run: dotnet build --no-restore -c Release -p:Version=${{ steps.version.outputs.version }}
- name: Test
run: dotnet test --no-build --verbosity normal
run: dotnet test --no-build -c Release --verbosity normal
- name: pack
run: dotnet pack -c Release PdfSharpDslCore/PdfSharpDslCore.csproj
run: dotnet pack --no-build -c Release PdfSharpDslCore/PdfSharpDslCore.csproj -p:Version=${{ steps.version.outputs.version }}
# - name: add publish
# run: dotnet nuget add source --username pgourlain --password ${{ secrets.GITHUB_TOKEN }} --store-password-in-clear-text --name github "https://nuget.pkg.github.com/pgourlain/index.json"
# - name: publish package
Expand Down
13 changes: 11 additions & 2 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,12 +1,21 @@

# Change log

## Version 1.0.6 (September 20, 2024)
## Version 2.0.0 (unreleased)
* Migrated PDF generation from PdfSharpCore and its image/font/archive dependencies to TerraPDF 2.2.0.
* Added engine-independent drawing primitives and `PdfSharpDsl.Language` for the netstandard2.0 source generator.
* Added `PublishPdf(Stream)`, `PublishPdf(string)` and `PublishPdf()` to `PdfDocumentDrawer`.
* **Breaking:** `PdfSharpDslCore` now multi-targets `net8.0` and `net10.0` (was `netstandard2.0`).
* Centralized the build in a `_build/` folder: `Version.props` holds the single product version, `Common.props` the shared package metadata, licence and target-framework aliases, and `Packages.props` every NuGet version (central package management). `Directory.Build.props`, `Directory.Build.targets` and `Directory.Packages.props` at the repository root are thin stubs that import them.
* All assemblies now ship the same version. `PdfSharpDslCore.Generator` moves from `1.0.2` to `2.0.0` and `PdfSharpDslConsole` no longer carries its own `0.1.0`.
* The release workflow now derives the published package version from the GitHub release tag, and builds, tests and packs in `Release` so the tested binaries are the ones packed.
* Updated `Microsoft.Extensions.Logging.Abstractions` and `Microsoft.Extensions.Logging.Console` to 10.0.12.

## Version 1.0.6 (September 20, 2026)
* Migrated console and test projects to .NET 10 while retaining reusable projects on .NET Standard 2.0.
* Added reproducible core-only coverage enforcement at 90% line coverage.
* Added Roslyn source-generator compilation and clean NuGet consumer validation.


## Version 1.0.5 (March 3, 2024)
* Update nugets packages and upgrade to .Net 8

Expand Down
11 changes: 11 additions & 0 deletions Directory.Build.props
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
<Project>

<!--
MSBuild only auto-discovers Directory.Build.props by walking up from each project
directory, so this stub exists purely to pull in the real files from _build/.
Edit _build/Version.props and _build/Common.props, not this file.
-->
<Import Project="_build\Version.props" />
<Import Project="_build\Common.props" />

</Project>
6 changes: 6 additions & 0 deletions Directory.Build.targets
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
<Project>

<!-- Stub: see Directory.Build.props. Edit _build/Common.targets, not this file. -->
<Import Project="_build\Common.targets" />

</Project>
6 changes: 6 additions & 0 deletions Directory.Packages.props
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
<Project>

<!-- Stub: see Directory.Build.props. Edit _build/Packages.props, not this file. -->
<Import Project="_build\Packages.props" />

</Project>
316 changes: 316 additions & 0 deletions PdfSharpDsl.Language/Drawing/DrawingPrimitives.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,316 @@
using System;
using System.Collections.Generic;
using System.Linq;

namespace PdfSharpDslCore.Drawing
{
public readonly struct PdfPoint
{
public PdfPoint(double x, double y)
{
X = x;
Y = y;
}

public double X { get; }
public double Y { get; }

public PdfPoint OffsetY(double offsetY) => new(X, Y + offsetY);
}

public readonly struct PdfSize
{
public PdfSize(double width, double height)
{
Width = width;
Height = height;
}

public double Width { get; }
public double Height { get; }
}

public struct PdfRect
{
public PdfRect(double x, double y, double width, double height)
{
X = x;
Y = y;
Width = width;
Height = height;
}

public double X { readonly get; private set; }
public double Y { readonly get; private set; }
public double Width { readonly get; private set; }
public double Height { readonly get; private set; }

public static PdfRect Empty => new(0, 0, -1, -1);

public PdfRect(PdfPoint first, PdfPoint second)
: this(Math.Min(first.X, second.X), Math.Min(first.Y, second.Y),
Math.Abs(second.X - first.X), Math.Abs(second.Y - first.Y))
{
}

public PdfRect(PdfPoint location, PdfSize size)
: this(location.X, location.Y, size.Width, size.Height)
{
}

public readonly bool IsEmpty => Width < 0 || Height < 0;
public readonly double Left => X;
public readonly double Top => Y;
public readonly double Right => X + Width;
public readonly double Bottom => Y + Height;
public readonly PdfPoint TopLeft => new(X, Y);

public void Offset(double offsetX, double offsetY)
{
X += offsetX;
Y += offsetY;
}

public readonly PdfRect OffsetY(double offsetY) => new(X, Y + offsetY, Width, Height);

public void Union(PdfPoint point)
{
Union(new PdfRect(point.X, point.Y, 0, 0));
}

public void Union(PdfRect rect)
{
if (rect.IsEmpty)
{
return;
}

if (IsEmpty)
{
this = rect;
return;
}

var left = Math.Min(Left, rect.Left);
var top = Math.Min(Top, rect.Top);
var right = Math.Max(Right, rect.Right);
var bottom = Math.Max(Bottom, rect.Bottom);
this = new PdfRect(left, top, right - left, bottom - top);
}

public void Intersect(PdfRect rect)
{
var left = Math.Max(Left, rect.Left);
var top = Math.Max(Top, rect.Top);
var right = Math.Min(Right, rect.Right);
var bottom = Math.Min(Bottom, rect.Bottom);
this = right < left || bottom < top
? Empty
: new PdfRect(left, top, right - left, bottom - top);
}
}

public readonly struct PdfColor
{
public PdfColor(byte alpha, byte red, byte green, byte blue)
{
Alpha = alpha;
Red = red;
Green = green;
Blue = blue;
}

public byte Alpha { get; }
public byte Red { get; }
public byte Green { get; }
public byte Blue { get; }

public byte A => Alpha;

public static PdfColor FromArgb(byte alpha, byte red, byte green, byte blue) =>
new(alpha, red, green, blue);

public static PdfColor FromRgb(byte red, byte green, byte blue) => new(255, red, green, blue);

public static PdfColor FromArgb(uint argb) => new(
(byte)(argb >> 24),
(byte)(argb >> 16),
(byte)(argb >> 8),
(byte)argb);

public static PdfColor FromGrayScale(double value)
{
var component = (byte)Math.Min(255, Math.Max(0, (int)Math.Round(value * 255)));
return FromRgb(component, component, component);
}

public static PdfColor Black => FromRgb(0, 0, 0);
public static PdfColor White => FromRgb(255, 255, 255);
public static PdfColor RedColor => FromRgb(255, 0, 0);
public static PdfColor Transparent => new(0, 0, 0, 0);

internal string Hex => $"#{Red:X2}{Green:X2}{Blue:X2}";
internal double Opacity => Alpha / 255d;
}

public static class PdfColors
{
private static readonly IReadOnlyDictionary<string, PdfColor> Colors =
new Dictionary<string, PdfColor>(StringComparer.OrdinalIgnoreCase)
{
["black"] = PdfColor.FromRgb(0, 0, 0),
["blue"] = PdfColor.FromRgb(0, 0, 255),
["crimson"] = PdfColor.FromRgb(220, 20, 60),
["darkblue"] = PdfColor.FromRgb(0, 0, 139),
["darkgreen"] = PdfColor.FromRgb(0, 100, 0),
["darkslategray"] = PdfColor.FromRgb(47, 79, 79),
["gold"] = PdfColor.FromRgb(255, 215, 0),
["gray"] = PdfColor.FromRgb(128, 128, 128),
["green"] = PdfColor.FromRgb(0, 128, 0),
["lightblue"] = PdfColor.FromRgb(173, 216, 230),
["lightgray"] = PdfColor.FromRgb(211, 211, 211),
["lightgreen"] = PdfColor.FromRgb(144, 238, 144),
["lightsalmon"] = PdfColor.FromRgb(255, 160, 122),
["lightseagreen"] = PdfColor.FromRgb(32, 178, 170),
["maroon"] = PdfColor.FromRgb(128, 0, 0),
["orange"] = PdfColor.FromRgb(255, 165, 0),
["purple"] = PdfColor.FromRgb(128, 0, 128),
["red"] = PdfColor.FromRgb(255, 0, 0),
["slategray"] = PdfColor.FromRgb(112, 128, 144),
["steelblue"] = PdfColor.FromRgb(70, 130, 180),
["tomato"] = PdfColor.FromRgb(255, 99, 71),
["transparent"] = PdfColor.Transparent,
["violet"] = PdfColor.FromRgb(238, 130, 238),
["white"] = PdfColor.FromRgb(255, 255, 255),
["yellow"] = PdfColor.FromRgb(255, 255, 0),
};

public static IEnumerable<string> Names => Colors.Keys;

public static PdfColor FromName(string name)
{
return Colors.TryGetValue(name, out var color) ? color : PdfColor.Black;
}
}

public enum PdfDashStyle
{
Solid,
Dash,
Dot,
DashDot,
DashDotDot,
}

public sealed class PdfPen
{
public PdfPen(PdfColor color, double width)
{
Color = color;
Width = width;
}

public PdfColor Color { get; }
public double Width { get; }
public PdfDashStyle DashStyle { get; set; } = PdfDashStyle.Solid;
}

public sealed class PdfBrush
{
public PdfBrush(PdfColor color)
{
Color = color;
}

public PdfColor Color { get; }
}

[Flags]
public enum PdfFontStyle
{
Regular = 0,
Bold = 1,
Italic = 2,
BoldItalic = Bold | Italic,
Underline = 4,
Strikeout = 8,
}

public sealed class PdfFont
{
public PdfFont(string familyName, double size, PdfFontStyle style = PdfFontStyle.Regular)
{
FamilyName = familyName;
Size = size;
Style = style;
}

public string FamilyName { get; }
public double Size { get; }
public PdfFontStyle Style { get; }
}

public sealed class PdfImage
{
private readonly byte[] _data;

public PdfImage(ReadOnlySpan<byte> data)
{
_data = data.ToArray();
}

public ReadOnlyMemory<byte> Data => _data;
}

public sealed class PdfMargins
{
private double _all;

public double All
{
set => Left = Top = Right = Bottom = _all = value;
get => _all;
}

public double Left { get; set; }
public double Top { get; set; }
public double Right { get; set; }
public double Bottom { get; set; }
}

public enum PdfHorizontalAlignment
{
Near,
Center,
Far,
}

public enum PdfVerticalAlignment
{
Near,
Center,
Far,
}

public enum PdfPageOrientation
{
Portrait,
Landscape,
}

public enum PdfPageSize
{
Undefined,
A0,
A1,
A2,
A3,
A4,
A5,
A6,
Letter,
Legal,
Ledger,
Tabloid,
}
}
Loading
Loading