|
|
@@ -7,18 +7,18 @@ namespace QuestPDF.Drawing
|
|
|
{
|
|
|
internal class FontStyleSet
|
|
|
{
|
|
|
- private ConcurrentDictionary<SKFontStyle, SKTypeface> Styles = new ConcurrentDictionary<SKFontStyle, SKTypeface>();
|
|
|
+ private ConcurrentDictionary<SKFontStyle, SKTypeface> Styles { get; } = new();
|
|
|
|
|
|
public void Add(SKTypeface typeface)
|
|
|
{
|
|
|
- SKFontStyle style = typeface.FontStyle;
|
|
|
- Styles.AddOrUpdate(style, (_) => typeface, (_, _) => typeface);
|
|
|
+ var style = typeface.FontStyle;
|
|
|
+ Styles.AddOrUpdate(style, _ => typeface, (_, _) => typeface);
|
|
|
}
|
|
|
|
|
|
- public SKTypeface Match(SKFontStyle target)
|
|
|
+ public SKTypeface? Match(SKFontStyle target)
|
|
|
{
|
|
|
- SKFontStyle bestStyle = null;
|
|
|
- SKTypeface bestTypeface = null;
|
|
|
+ SKFontStyle? bestStyle = null;
|
|
|
+ SKTypeface? bestTypeface = null;
|
|
|
|
|
|
foreach (var entry in Styles)
|
|
|
{
|
|
|
@@ -40,40 +40,55 @@ namespace QuestPDF.Drawing
|
|
|
};
|
|
|
|
|
|
// Checks whether style a is a better match for the target then style b. Uses the CSS font style matching algorithm
|
|
|
- internal static bool IsBetterMatch(SKFontStyle target, SKFontStyle a, SKFontStyle b)
|
|
|
+ internal static bool IsBetterMatch(SKFontStyle? target, SKFontStyle? a, SKFontStyle? b)
|
|
|
{
|
|
|
// A font is better than no font
|
|
|
- if (b == null) return true;
|
|
|
- if (a == null) return false;
|
|
|
+ if (b == null)
|
|
|
+ return true;
|
|
|
+
|
|
|
+ if (a == null)
|
|
|
+ return false;
|
|
|
|
|
|
// First check font width
|
|
|
// For normal and condensed widths prefer smaller widths
|
|
|
// For expanded widths prefer larger widths
|
|
|
if (target.Width <= (int)SKFontStyleWidth.Normal)
|
|
|
{
|
|
|
- if (a.Width <= target.Width && b.Width > target.Width) return true;
|
|
|
- if (a.Width > target.Width && b.Width <= target.Width) return false;
|
|
|
+ if (a.Width <= target.Width && b.Width > target.Width)
|
|
|
+ return true;
|
|
|
+
|
|
|
+ if (a.Width > target.Width && b.Width <= target.Width)
|
|
|
+ return false;
|
|
|
}
|
|
|
else
|
|
|
{
|
|
|
- if (a.Width >= target.Width && b.Width < target.Width) return true;
|
|
|
- if (a.Width < target.Width && b.Width >= target.Width) return false;
|
|
|
+ if (a.Width >= target.Width && b.Width < target.Width)
|
|
|
+ return true;
|
|
|
+
|
|
|
+ if (a.Width < target.Width && b.Width >= target.Width)
|
|
|
+ return false;
|
|
|
}
|
|
|
|
|
|
// Prefer closest match
|
|
|
- int widthDifferenceA = Math.Abs(a.Width - target.Width);
|
|
|
- int widthDifferenceB = Math.Abs(b.Width - target.Width);
|
|
|
+ var widthDifferenceA = Math.Abs(a.Width - target.Width);
|
|
|
+ var widthDifferenceB = Math.Abs(b.Width - target.Width);
|
|
|
|
|
|
- if (widthDifferenceA < widthDifferenceB) return true;
|
|
|
- if (widthDifferenceB < widthDifferenceA) return false;
|
|
|
+ if (widthDifferenceA < widthDifferenceB)
|
|
|
+ return true;
|
|
|
+
|
|
|
+ if (widthDifferenceB < widthDifferenceA)
|
|
|
+ return false;
|
|
|
|
|
|
// Prefer closest slant based on provided fallback list
|
|
|
- List<SKFontStyleSlant> slantFallback = SlantFallbacks[target.Slant];
|
|
|
- int slantIndexA = slantFallback.IndexOf(a.Slant);
|
|
|
- int slantIndexB = slantFallback.IndexOf(b.Slant);
|
|
|
+ var slantFallback = SlantFallbacks[target.Slant];
|
|
|
+ var slantIndexA = slantFallback.IndexOf(a.Slant);
|
|
|
+ var slantIndexB = slantFallback.IndexOf(b.Slant);
|
|
|
|
|
|
- if (slantIndexA < slantIndexB) return true;
|
|
|
- if (slantIndexB < slantIndexA) return false;
|
|
|
+ if (slantIndexA < slantIndexB)
|
|
|
+ return true;
|
|
|
+
|
|
|
+ if (slantIndexB < slantIndexA)
|
|
|
+ return false;
|
|
|
|
|
|
// Check weight last
|
|
|
// For thin (<400) weights, prefer thinner weights
|
|
|
@@ -83,24 +98,33 @@ namespace QuestPDF.Drawing
|
|
|
|
|
|
if (target.Weight >= 400 && target.Weight <= 500)
|
|
|
{
|
|
|
- if ((a.Weight >= 400 && a.Weight <= 500) && !(b.Weight >= 400 && b.Weight <= 500)) return true;
|
|
|
- if (!(a.Weight >= 400 && a.Weight <= 500) && (b.Weight >= 400 && b.Weight <= 500)) return false;
|
|
|
+ if ((a.Weight >= 400 && a.Weight <= 500) && !(b.Weight >= 400 && b.Weight <= 500))
|
|
|
+ return true;
|
|
|
+
|
|
|
+ if (!(a.Weight >= 400 && a.Weight <= 500) && (b.Weight >= 400 && b.Weight <= 500))
|
|
|
+ return false;
|
|
|
}
|
|
|
|
|
|
if (target.Weight < 450)
|
|
|
{
|
|
|
- if (a.Weight <= target.Weight && b.Weight > target.Weight) return true;
|
|
|
- if (a.Weight > target.Weight && b.Weight <= target.Weight) return false;
|
|
|
+ if (a.Weight <= target.Weight && b.Weight > target.Weight)
|
|
|
+ return true;
|
|
|
+
|
|
|
+ if (a.Weight > target.Weight && b.Weight <= target.Weight)
|
|
|
+ return false;
|
|
|
}
|
|
|
else
|
|
|
{
|
|
|
- if (a.Weight >= target.Weight && b.Weight < target.Weight) return true;
|
|
|
- if (a.Weight < target.Weight && b.Weight >= target.Weight) return false;
|
|
|
+ if (a.Weight >= target.Weight && b.Weight < target.Weight)
|
|
|
+ return true;
|
|
|
+
|
|
|
+ if (a.Weight < target.Weight && b.Weight >= target.Weight)
|
|
|
+ return false;
|
|
|
}
|
|
|
|
|
|
// Prefer closest weight
|
|
|
- int weightDifferenceA = Math.Abs(a.Weight - target.Weight);
|
|
|
- int weightDifferenceB = Math.Abs(b.Weight - target.Weight);
|
|
|
+ var weightDifferenceA = Math.Abs(a.Weight - target.Weight);
|
|
|
+ var weightDifferenceB = Math.Abs(b.Weight - target.Weight);
|
|
|
|
|
|
return weightDifferenceA < weightDifferenceB;
|
|
|
}
|