Files
QuestPDF/QuestPDF/Infrastructure/TextStyleManager.cs
T
2022-09-09 11:32:05 +02:00

215 lines
8.0 KiB
C#

using System;
using System.Collections.Concurrent;
using QuestPDF.Fluent;
namespace QuestPDF.Infrastructure
{
internal enum TextStyleProperty
{
Color,
BackgroundColor,
FontFamily,
Size,
LineHeight,
FontWeight,
FontPosition,
IsItalic,
HasStrikethrough,
HasUnderline,
WrapAnywhere
}
internal static class TextStyleManager
{
public static ConcurrentDictionary<(TextStyle origin, TextStyleProperty property, object value), TextStyle> TextStyleMutateCache = new();
public static ConcurrentDictionary<(TextStyle origin, TextStyle parent, bool overrideValue), TextStyle> TextStyleApplyCache = new();
public static TextStyle Mutate(this TextStyle origin, TextStyleProperty property, object value)
{
var cacheKey = (origin, property, value);
return TextStyleMutateCache.GetOrAdd(cacheKey, x => MutateStyle(x.origin, x.property, x.value));
}
private static TextStyle MutateStyle(TextStyle origin, TextStyleProperty property, object value, bool overrideValue = true)
{
if (overrideValue && value == null)
return origin;
if (property == TextStyleProperty.Color)
{
if (!overrideValue && origin.Color != null)
return origin;
var castedValue = (string?)value;
if (origin.Color == castedValue)
return origin;
return origin with { Color = castedValue };
}
if (property == TextStyleProperty.BackgroundColor)
{
if (!overrideValue && origin.BackgroundColor != null)
return origin;
var castedValue = (string?)value;
if (origin.BackgroundColor == castedValue)
return origin;
return origin with { BackgroundColor = castedValue };
}
if (property == TextStyleProperty.FontFamily)
{
if (!overrideValue && origin.FontFamily != null)
return origin;
var castedValue = (string?)value;
if (origin.FontFamily == castedValue)
return origin;
return origin with { FontFamily = castedValue };
}
if (property == TextStyleProperty.Size)
{
if (!overrideValue && origin.Size != null)
return origin;
var castedValue = (float?)value;
if (origin.Size == castedValue)
return origin;
return origin with { Size = castedValue };
}
if (property == TextStyleProperty.LineHeight)
{
if (!overrideValue && origin.LineHeight != null)
return origin;
var castedValue = (float?)value;
if (origin.LineHeight == castedValue)
return origin;
return origin with { LineHeight = castedValue };
}
if (property == TextStyleProperty.FontWeight)
{
if (!overrideValue && origin.FontWeight != null)
return origin;
var castedValue = (FontWeight?)value;
if (origin.FontWeight == castedValue)
return origin;
return origin with { FontWeight = castedValue };
}
if (property == TextStyleProperty.FontPosition)
{
if (!overrideValue && origin.FontPosition != null)
return origin;
var castedValue = (FontPosition?)value;
if (origin.FontPosition == castedValue)
return origin;
return origin with { FontPosition = castedValue };
}
if (property == TextStyleProperty.IsItalic)
{
if (!overrideValue && origin.IsItalic != null)
return origin;
var castedValue = (bool?)value;
if (origin.IsItalic == castedValue)
return origin;
return origin with { IsItalic = castedValue };
}
if (property == TextStyleProperty.HasStrikethrough)
{
if (!overrideValue && origin.HasStrikethrough != null)
return origin;
var castedValue = (bool?)value;
if (origin.HasStrikethrough == castedValue)
return origin;
return origin with { HasStrikethrough = castedValue };
}
if (property == TextStyleProperty.HasUnderline)
{
if (!overrideValue && origin.HasUnderline != null)
return origin;
var castedValue = (bool?)value;
if (origin.HasUnderline == castedValue)
return origin;
return origin with { HasUnderline = castedValue };
}
if (property == TextStyleProperty.WrapAnywhere)
{
if (!overrideValue && origin.WrapAnywhere != null)
return origin;
var castedValue = (bool?)value;
if (origin.WrapAnywhere == castedValue)
return origin;
return origin with { WrapAnywhere = castedValue };
}
throw new ArgumentOutOfRangeException(nameof(property), property, "Expected to mutate the TextStyle object. Provided property type is not supported.");
}
internal static TextStyle ApplyGlobalStyle(this TextStyle style, TextStyle parent)
{
var cacheKey = (style, parent, false);
return TextStyleApplyCache.GetOrAdd(cacheKey, key => ApplyStyle(key.origin, key.parent, key.overrideValue));
}
internal static TextStyle OverrideStyle(this TextStyle style, TextStyle parent)
{
var cacheKey = (style, parent, true);
return TextStyleApplyCache.GetOrAdd(cacheKey, key => ApplyStyle(key.origin, key.parent, key.overrideValue));
}
private static TextStyle ApplyStyle(TextStyle style, TextStyle parent, bool overrideValue)
{
var result = style;
result = MutateStyle(result, TextStyleProperty.Color, parent.Color, overrideValue);
result = MutateStyle(result, TextStyleProperty.BackgroundColor, parent.BackgroundColor, overrideValue);
result = MutateStyle(result, TextStyleProperty.FontFamily, parent.FontFamily, overrideValue);
result = MutateStyle(result, TextStyleProperty.Size, parent.Size, overrideValue);
result = MutateStyle(result, TextStyleProperty.LineHeight, parent.LineHeight, overrideValue);
result = MutateStyle(result, TextStyleProperty.FontWeight, parent.FontWeight, overrideValue);
result = MutateStyle(result, TextStyleProperty.FontPosition, parent.FontPosition, overrideValue);
result = MutateStyle(result, TextStyleProperty.IsItalic, parent.IsItalic, overrideValue);
result = MutateStyle(result, TextStyleProperty.HasStrikethrough, parent.HasStrikethrough, overrideValue);
result = MutateStyle(result, TextStyleProperty.HasUnderline, parent.HasUnderline, overrideValue);
result = MutateStyle(result, TextStyleProperty.WrapAnywhere, parent.WrapAnywhere, overrideValue);
return result;
}
}
}