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
3 changes: 3 additions & 0 deletions documents/README.nuget.md
Original file line number Diff line number Diff line change
Expand Up @@ -91,6 +91,9 @@ MiniPdf.RegisterFont("NotoSansSC", File.ReadAllBytes("Fonts/NotoSansSC-Regular.t
MiniPdf.ConvertToPdf("report.docx", "report.pdf");
```

Registrations are process-wide. `MiniPdf.ClearRegisteredFonts()` removes them when
the same process needs a different font set for a later conversion.
Comment thread
coderabbitai[bot] marked this conversation as resolved.

## Command Line

Install the .NET global tool:
Expand Down
10 changes: 10 additions & 0 deletions src/MiniPdf/MiniPdf.cs
Original file line number Diff line number Diff line change
Expand Up @@ -128,6 +128,16 @@ public static void RegisterFont(string name, byte[] fontData)
_registeredFonts.Add((name, fontData));
}

/// <summary>
/// Removes all fonts registered with <see cref="RegisterFont"/>.
/// Registrations are process-wide; clear them before registering a different font set.
/// </summary>
public static void ClearRegisteredFonts()
{
lock (_registeredFonts)
_registeredFonts.Clear();
}

/// <summary>
/// Returns a snapshot of all registered fonts.
/// </summary>
Expand Down
70 changes: 70 additions & 0 deletions tests/MiniPdf.Tests/RegisteredFontTests.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
namespace MiniSoftware.Tests;

/// <summary>
/// Runs registered-font tests apart from other collections. Registrations are process-wide,
/// so conversions running in parallel would otherwise read the fonts these tests register.
/// </summary>
[CollectionDefinition(Name, DisableParallelization = true)]
public class RegisteredFontCollection
{
public const string Name = "Registered fonts";
}

[Collection(RegisteredFontCollection.Name)]
public class RegisteredFontTests : IDisposable
{
/// <summary>
/// Starts each test with no registered fonts.
/// </summary>
public RegisteredFontTests() => MiniPdf.ClearRegisteredFonts();

/// <summary>
/// Clears the fonts a test registered so the next test starts from an empty list.
/// </summary>
public void Dispose() => MiniPdf.ClearRegisteredFonts();

/// <summary>
/// Clearing removes every registration, including repeated registrations of the same name.
/// </summary>
[Fact]
public void ClearRegisteredFonts_RemovesAllRegistrations()
{
MiniPdf.RegisterFont("First", new byte[] { 1 });
MiniPdf.RegisterFont("Second", new byte[] { 2 });
MiniPdf.RegisterFont("First", new byte[] { 3 });
Assert.Equal(3, MiniPdf.GetRegisteredFonts().Count);

MiniPdf.ClearRegisteredFonts();

Assert.Empty(MiniPdf.GetRegisteredFonts());
}

/// <summary>
/// A host can swap font sets between conversions by clearing and registering again.
/// </summary>
[Fact]
public void ClearRegisteredFonts_AllowsRegisteringADifferentFontSet()
{
MiniPdf.RegisterFont("NotoSansTC", new byte[] { 1 });

MiniPdf.ClearRegisteredFonts();
MiniPdf.RegisterFont("NotoSansJP", new byte[] { 2 });

var registered = Assert.Single(MiniPdf.GetRegisteredFonts());
Assert.Equal("NotoSansJP", registered.Name);
}

/// <summary>
/// A snapshot taken before clearing, such as the one a conversion in progress reads, is not changed.
/// </summary>
[Fact]
public void ClearRegisteredFonts_DoesNotChangeEarlierSnapshot()
{
MiniPdf.RegisterFont("NotoSansTC", new byte[] { 1 });
var snapshot = MiniPdf.GetRegisteredFonts();

MiniPdf.ClearRegisteredFonts();

Assert.Equal("NotoSansTC", Assert.Single(snapshot).Name);
}
}
Loading