Skip to content
Open
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
7 changes: 7 additions & 0 deletions PdfSharp.sln
Original file line number Diff line number Diff line change
Expand Up @@ -274,6 +274,8 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "docs-dummy", "docs\docs-dum
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "PdfSharp.Cryptography", "src\foundation\src\PDFsharp\src\PdfSharp.Cryptography\PdfSharp.Cryptography.csproj", "{769ED050-15AF-4EB5-A89F-D7123EE5AA95}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "PdfSharp.Benchmarks", "src\foundation\src\PDFsharp\src\PdfSharp.Benchmarks\PdfSharp.Benchmarks.csproj", "{24B3A17B-FDEE-496B-A2F4-A5F35127CCCF}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
Expand Down Expand Up @@ -568,6 +570,10 @@ Global
{769ED050-15AF-4EB5-A89F-D7123EE5AA95}.Debug|Any CPU.Build.0 = Debug|Any CPU
{769ED050-15AF-4EB5-A89F-D7123EE5AA95}.Release|Any CPU.ActiveCfg = Release|Any CPU
{769ED050-15AF-4EB5-A89F-D7123EE5AA95}.Release|Any CPU.Build.0 = Release|Any CPU
{24B3A17B-FDEE-496B-A2F4-A5F35127CCCF}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{24B3A17B-FDEE-496B-A2F4-A5F35127CCCF}.Debug|Any CPU.Build.0 = Debug|Any CPU
{24B3A17B-FDEE-496B-A2F4-A5F35127CCCF}.Release|Any CPU.ActiveCfg = Release|Any CPU
{24B3A17B-FDEE-496B-A2F4-A5F35127CCCF}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
Expand Down Expand Up @@ -675,6 +681,7 @@ Global
{F4AB506C-AD13-4383-9AF9-48D74085ECC1} = {7C753636-7947-46E0-95E0-135EAA7BFEB3}
{76B94284-402D-4951-8DA4-7FFAF15E6C95} = {76BA9372-65AE-479C-AEF7-D50E6B486CEF}
{769ED050-15AF-4EB5-A89F-D7123EE5AA95} = {7C753636-7947-46E0-95E0-135EAA7BFEB3}
{24B3A17B-FDEE-496B-A2F4-A5F35127CCCF} = {7C753636-7947-46E0-95E0-135EAA7BFEB3}
EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
SolutionGuid = {D5FF5562-3C79-434B-B951-B84542D01625}
Expand Down
4 changes: 2 additions & 2 deletions src/Directory.Build.props
Original file line number Diff line number Diff line change
Expand Up @@ -41,9 +41,9 @@
</PropertyGroup>

<ItemGroup>
<PackageReference Include="GitVersion.MsBuild">
<!--<PackageReference Include="GitVersion.MsBuild">
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
<PrivateAssets>all</PrivateAssets>
</PackageReference>
</PackageReference>-->
</ItemGroup>
</Project>
74 changes: 34 additions & 40 deletions src/Directory.Packages.props
Original file line number Diff line number Diff line change
@@ -1,41 +1,35 @@
<Project>
<!--<Import Condition="Exists('Local.Packages.props')" Project="$([MSBuild]::GetPathOfFileAbove('Local.Packages.props', '$(MSBuildThisFileDirectory)'))" />-->
<PropertyGroup>
<Logging_Abstractions_PackageVersion>8.0.3</Logging_Abstractions_PackageVersion>
<Logging_PackageVersion>8.0.1</Logging_PackageVersion>
<Cryptography_PackageVersion>8.0.1</Cryptography_PackageVersion>
</PropertyGroup>

<ItemGroup>

<!-- Logging packages used by all PDFsharp projects -->
<PackageVersion Include="Microsoft.Extensions.Logging.Abstractions" Version="$(Logging_Abstractions_PackageVersion)" />
<!-- Logging packages only used by PDFsharp sample projects and tests -->
<!--<PackageVersion Include="Microsoft.Extensions.Logging" Version="$(Logging_PackageVersion)" />-->
<PackageVersion Include="Microsoft.Extensions.Logging.Configuration" Version="$(Logging_PackageVersion)" />
<PackageVersion Include="Microsoft.Extensions.Logging.Console" Version="$(Logging_PackageVersion)" />

<!-- Digital signature packages used by PdfSharp.Cryptography and for testing -->
<PackageVersion Include="System.Security.Cryptography.Pkcs" Version="$(Cryptography_PackageVersion)" />
<PackageVersion Include="BouncyCastle.Cryptography" Version="2.5.0" />

<!-- Unit test packages used for testing only-->
<PackageVersion Include="Microsoft.NET.Test.Sdk" Version="17.12.0" />
<PackageVersion Include="xunit.core" Version="2.9.3" />
<PackageVersion Include="xunit.assert" Version="2.4.2" />
<PackageVersion Include="xunit.runner.visualstudio" Version="2.8.2" />
<PackageVersion Include="Xunit.Priority" Version="1.1.6" />
<PackageVersion Include="Xunit.SkippableFact" Version="1.5.23" />
<PackageVersion Include="XunitXml.TestLogger" Version="4.1.0" />
<PackageVersion Include="FluentAssertions" Version="6.12.2" />

<!-- GitVersion used for Semantic Versioning -->
<PackageVersion Include="GitVersion.MsBuild" Version="5.12.0" />
<!-- GitVersion 6 does not work in VS because of .NET Framework -->
<!--<PackageVersion Include="GitVersion.MsBuild" Version="6.1.0" />-->

<!-- Other packages -->
<PackageVersion Include="System.Resources.Extensions" Version="8.0.0" />
</ItemGroup>

<Project>
<!--<Import Condition="Exists('Local.Packages.props')" Project="$([MSBuild]::GetPathOfFileAbove('Local.Packages.props', '$(MSBuildThisFileDirectory)'))" />-->
<PropertyGroup>
<Logging_Abstractions_PackageVersion>8.0.3</Logging_Abstractions_PackageVersion>
<Logging_PackageVersion>8.0.1</Logging_PackageVersion>
<Cryptography_PackageVersion>8.0.1</Cryptography_PackageVersion>
</PropertyGroup>
<ItemGroup>
<!-- Logging packages used by all PDFsharp projects -->
<PackageVersion Include="BenchmarkDotNet" Version="0.15.8" />
<PackageVersion Include="Microsoft.Extensions.Logging.Abstractions" Version="$(Logging_Abstractions_PackageVersion)" />
<!-- Logging packages only used by PDFsharp sample projects and tests -->
<!--<PackageVersion Include="Microsoft.Extensions.Logging" Version="$(Logging_PackageVersion)" />-->
<PackageVersion Include="Microsoft.Extensions.Logging.Configuration" Version="$(Logging_PackageVersion)" />
<PackageVersion Include="Microsoft.Extensions.Logging.Console" Version="$(Logging_PackageVersion)" />
<!-- Digital signature packages used by PdfSharp.Cryptography and for testing -->
<PackageVersion Include="System.Security.Cryptography.Pkcs" Version="$(Cryptography_PackageVersion)" />
<PackageVersion Include="BouncyCastle.Cryptography" Version="2.5.0" />
<!-- Unit test packages used for testing only-->
<PackageVersion Include="Microsoft.NET.Test.Sdk" Version="17.12.0" />
<PackageVersion Include="xunit.core" Version="2.9.3" />
<PackageVersion Include="xunit.assert" Version="2.4.2" />
<PackageVersion Include="xunit.runner.visualstudio" Version="2.8.2" />
<PackageVersion Include="Xunit.Priority" Version="1.1.6" />
<PackageVersion Include="Xunit.SkippableFact" Version="1.5.23" />
<PackageVersion Include="XunitXml.TestLogger" Version="4.1.0" />
<PackageVersion Include="FluentAssertions" Version="6.12.2" />
<!-- GitVersion used for Semantic Versioning -->
<!--<PackageVersion Include="GitVersion.MsBuild" Version="5.12.0" />-->
<!-- GitVersion 6 does not work in VS because of .NET Framework -->
<!--<PackageVersion Include="GitVersion.MsBuild" Version="6.1.0" />-->
<!-- Other packages -->
<PackageVersion Include="System.Resources.Extensions" Version="8.0.0" />
</ItemGroup>
</Project>
Original file line number Diff line number Diff line change
Expand Up @@ -93,9 +93,9 @@
</ItemGroup>

<ItemGroup>
<PackageReference Update="GitVersion.MsBuild">
<!--<PackageReference Update="GitVersion.MsBuild">
<PrivateAssets>all</PrivateAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
</PackageReference>
</PackageReference>-->
</ItemGroup>
</Project>
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
<Project Sdk="Microsoft.NET.Sdk">

<PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFramework>net8.0</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
<NoWarn>NETSDK1138</NoWarn>
</PropertyGroup>

<ItemGroup>
<ProjectReference Include="..\PdfSharp\PdfSharp.csproj" SetTargetFramework="TargetFramework=net8.0" />
</ItemGroup>

<ItemGroup>
<PackageReference Include="BenchmarkDotNet" />
</ItemGroup>

</Project>
53 changes: 53 additions & 0 deletions src/foundation/src/PDFsharp/src/PdfSharp.Benchmarks/Program.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
using BenchmarkDotNet.Attributes;
using BenchmarkDotNet.Engines;
using BenchmarkDotNet.Jobs;
using BenchmarkDotNet.Running;
using PdfSharp.Drawing;
using PdfSharp.Fonts;

BenchmarkRunner.Run<FontCacheBenchmarks>();

[SimpleJob(RuntimeMoniker.Net80)]
public class FontCacheBenchmarks
{
private static readonly XGlyphTypeface GlyphTypeface = new(
XFontSource.CreateFromFile(@"C:\Windows\Fonts\arial.ttf"));
private static readonly Consumer Consumer = new();

[Params(1, 10, 100)]
public int Iterations { get; set; }

[GlobalSetup]
public void GlobalSetup()
{
FontDescriptorCache.Reset();
FontDescriptorCacheV2.Reset();
}

[GlobalCleanup]
public void GlobalCleanup()
{
FontDescriptorCache.Reset();
FontDescriptorCacheV2.Reset();
}

[Benchmark(Baseline = true)]
public void LockFactory()
{
for (var i = 0; i < Iterations; i++)
{
Consumer.Consume(
FontDescriptorCache.GetOrCreateDescriptorFor(GlyphTypeface));
}
}

[Benchmark]
public void ConcurrentDictionary()
{
for (var i = 0; i < Iterations; i++)
{
Consumer.Consume(
FontDescriptorCacheV2.GetOrCreateDescriptorFor(GlyphTypeface));
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ namespace PdfSharp.Fonts.OpenType
/// Base class for all font descriptors.
/// Currently only OpenTypeDescriptor is derived from this base class.
/// </summary>
class FontDescriptor
public class FontDescriptor
{
protected FontDescriptor(string key)
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,14 +3,13 @@

using PdfSharp.Drawing;
using PdfSharp.Fonts.OpenType;
using PdfSharp.Internal;

namespace PdfSharp.Fonts
{
/// <summary>
/// Global table of OpenType font descriptor objects.
/// </summary>
static class FontDescriptorCache
public static class FontDescriptorCache
{
/// <summary>
/// Gets the FontDescriptor identified by the specified XFont. If no such object
Expand Down Expand Up @@ -88,7 +87,7 @@ public static FontDescriptor GetOrCreateDescriptor(string fontFamilyName, XFontS
finally { Locks.ExitFontFactory(); }
}

internal static void Reset()
public static void Reset()
{
Globals.Global.Fonts.FontDescriptorCache.Clear();
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,95 @@
// PDFsharp - A .NET library for processing PDF
// See the LICENSE file in the solution root for more information.

using System.Collections.Concurrent;
using PdfSharp.Drawing;
using PdfSharp.Fonts.OpenType;

namespace PdfSharp.Fonts
{
/// <summary>
/// Global table of OpenType font descriptor objects.
/// </summary>
public static class FontDescriptorCacheV2
{
/// <summary>
/// Gets the FontDescriptor identified by the specified XFont. If no such object
/// exists, a new FontDescriptor is created and added to the cache.
/// </summary>
public static FontDescriptor GetOrCreateDescriptorFor(XFont font)
{
if (font == null)
throw new ArgumentNullException(nameof(font));

font.GlyphTypeface.CheckVersion();

//FontSelector1 selector = new FontSelector1(font);
string fontDescriptorKey = font.GlyphTypeface.Key;
var cache = Globals.Global.Fonts.FontDescriptorCacheV2;
if (cache.TryGetValue(fontDescriptorKey, out var descriptor))
return descriptor;

descriptor = new OpenTypeDescriptor(fontDescriptorKey, font);
cache.TryAdd(fontDescriptorKey, descriptor);
return descriptor;
}

public static FontDescriptor GetOrCreateDescriptorFor(XGlyphTypeface glyphTypeface)
{
glyphTypeface.CheckVersion();

string fontDescriptorKey = glyphTypeface.Key;
var cache = Globals.Global.Fonts.FontDescriptorCacheV2;
if (cache.TryGetValue(fontDescriptorKey, out var descriptor))
return descriptor;

descriptor = new OpenTypeDescriptor(fontDescriptorKey, glyphTypeface);
cache.TryAdd(fontDescriptorKey, descriptor);
return descriptor;
}

/// <summary>
/// Gets the FontDescriptor identified by the specified FontSelector. If no such object
/// exists, a new FontDescriptor is created and added to the stock.
/// </summary>
public static FontDescriptor GetOrCreateDescriptor(string fontFamilyName, XFontStyleEx style)
{
if (String.IsNullOrEmpty(fontFamilyName))
throw new ArgumentNullException(nameof(fontFamilyName));

//FontSelector1 selector = new FontSelector1(fontFamilyName, style);
string fontDescriptorKey = FontDescriptor.ComputeFdKey(fontFamilyName, style);
var cache = Globals.Global.Fonts.FontDescriptorCacheV2;
if (!cache.TryGetValue(fontDescriptorKey, out var descriptor))
{
var font = new XFont(fontFamilyName, 10, style);
descriptor = GetOrCreateDescriptorFor(font);
// ReSharper disable once CanSimplifyDictionaryLookupWithTryAdd because there is not TryAdd in .NET Framework
if (cache.ContainsKey(fontDescriptorKey))
_ = typeof(int); // Just a NOP for a break point.
else
cache.TryAdd(fontDescriptorKey, descriptor);
}
return descriptor;
}

public static void Reset()
{
Globals.Global.Fonts.FontDescriptorCacheV2.Clear();
}
}
}

namespace PdfSharp.Internal
{
partial class Globals
{
partial class FontStorage
{
/// <summary>
/// Maps font descriptor key to font descriptor which is currently only an OpenTypeFontDescriptor.
/// </summary>
public readonly ConcurrentDictionary<string, FontDescriptor> FontDescriptorCacheV2 = [];
}
}
}
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
// PDFsharp - A .NET library for processing PDF
// See the LICENSE file in the solution root for more information.

using System.Globalization;

namespace PdfSharp.Internal
{
/// <summary>
Expand All @@ -11,46 +13,46 @@ public static class PdfSharpGitVersionInformation
/// <summary>
/// The major version number of the product.
/// </summary>
public static string Major = global::GitVersionInformation.Major;
public static string Major = "1";//global::GitVersionInformation.Major;

/// <summary>
/// The minor version number of the product.
/// </summary>
public static string Minor = global::GitVersionInformation.Minor;
public static string Minor = "1";//global::GitVersionInformation.Minor;

/// <summary>
/// The patch number of the product.
/// </summary>
public static string Patch = global::GitVersionInformation.Patch;
public static string Patch = "1";//global::GitVersionInformation.Patch;

/// <summary>
/// The Version pre-release string for NuGet.
/// </summary>
public static string PreReleaseLabel = global::GitVersionInformation.PreReleaseLabel;
public static string PreReleaseLabel = string.Empty;//global::GitVersionInformation.PreReleaseLabel;

/// <summary>
/// The full version number.
/// </summary>
public static string MajorMinorPatch = global::GitVersionInformation.MajorMinorPatch;
public static string MajorMinorPatch = "1.1.1";//global::GitVersionInformation.MajorMinorPatch;

/// <summary>
/// The full semantic version number created by GitVersion.
/// </summary>
public static string SemVer = global::GitVersionInformation.SemVer;
public static string SemVer = "1.1.1";//global::GitVersionInformation.SemVer;

/// <summary>
/// The full informational version number created by GitVersion.
/// </summary>
public static string InformationalVersion = global::GitVersionInformation.InformationalVersion;
public static string InformationalVersion = "1.1.1";//global::GitVersionInformation.InformationalVersion;

/// <summary>
/// The branch name of the product.
/// </summary>
public static string BranchName = global::GitVersionInformation.BranchName;
public static string BranchName = "refactoring/locks";//global::GitVersionInformation.BranchName;

/// <summary>
/// The commit date of the product.
/// </summary>
public static string CommitDate = global::GitVersionInformation.CommitDate;
public static string CommitDate = DateTime.Today.ToString(CultureInfo.InvariantCulture);//global::GitVersionInformation.CommitDate;
}
}