From 8cec0059d8795f996cba04e9df04caa62f66b600 Mon Sep 17 00:00:00 2001 From: MarcinZiabek Date: Wed, 19 Apr 2023 20:25:58 +0200 Subject: [PATCH] Fixed applying text style for fallback styles --- Source/QuestPDF.Examples/TextExamples.cs | 34 +++++++++++ .../QuestPDF.UnitTests.csproj | 1 + Source/QuestPDF.UnitTests/TextStyleTests.cs | 58 +++++++++++++++++++ Source/QuestPDF/Drawing/DocumentGenerator.cs | 9 +-- .../Infrastructure/TextStyleManager.cs | 17 +++--- 5 files changed, 108 insertions(+), 11 deletions(-) create mode 100644 Source/QuestPDF.UnitTests/TextStyleTests.cs diff --git a/Source/QuestPDF.Examples/TextExamples.cs b/Source/QuestPDF.Examples/TextExamples.cs index 3aa3df3..384af37 100644 --- a/Source/QuestPDF.Examples/TextExamples.cs +++ b/Source/QuestPDF.Examples/TextExamples.cs @@ -1004,5 +1004,39 @@ namespace QuestPDF.Examples }); }); } + + [Test] + public void FontFallback_Nested() + { + RenderingTest + .Create() + .ProduceImages() + .ShowResults() + .RenderDocument(container => + { + container.Page(page => + { + page.Margin(50); + page.PageColor(Colors.White); + page.Size(PageSizes.A6.Landscape()); + + page.DefaultTextStyle(x => x + .FontSize(24) + .Bold() + .Fallback(y => y + .FontFamily("Microsoft YaHei") + .Underline() + .BackgroundColor(Colors.Red.Lighten2))); + + page.Content().Text(text => + { + text.Line("Normal 中文文本 text."); + text.Line("Background 中文文本 text.").NormalWeight().BackgroundColor(Colors.Green.Lighten2); + text.Line("Background 中文文本 text.").Strikethrough().Underline(false); + text.Line("Background 中文文本 text.").Italic(); + }); + }); + }); + } } } \ No newline at end of file diff --git a/Source/QuestPDF.UnitTests/QuestPDF.UnitTests.csproj b/Source/QuestPDF.UnitTests/QuestPDF.UnitTests.csproj index e062de1..622e661 100644 --- a/Source/QuestPDF.UnitTests/QuestPDF.UnitTests.csproj +++ b/Source/QuestPDF.UnitTests/QuestPDF.UnitTests.csproj @@ -3,6 +3,7 @@ netcoreapp3.1 false + 9 diff --git a/Source/QuestPDF.UnitTests/TextStyleTests.cs b/Source/QuestPDF.UnitTests/TextStyleTests.cs new file mode 100644 index 0000000..13d2dcb --- /dev/null +++ b/Source/QuestPDF.UnitTests/TextStyleTests.cs @@ -0,0 +1,58 @@ +using FluentAssertions; +using NUnit.Framework; +using QuestPDF.Fluent; +using QuestPDF.Helpers; +using QuestPDF.Infrastructure; + +namespace QuestPDF.UnitTests +{ + [TestFixture] + public class TextStyleTests + { + [Test] + public void Font() + { + // arrange + var defaultTextStyle = TextStyle + .Default + .FontSize(20) + .FontFamily("Arial") + .BackgroundColor(Colors.Green.Lighten2) + .Fallback(y => y + .FontFamily("Microsoft YaHei") + .Underline() + .NormalWeight() + .BackgroundColor(Colors.Blue.Lighten2)); + + var spanTextStyle = TextStyle + .Default + .Bold() + .Strikethrough() + .BackgroundColor(Colors.Red.Lighten2); + + // act + var targetStyle = spanTextStyle.ApplyGlobalStyle(defaultTextStyle, true).ApplyGlobalStyle(TextStyle.LibraryDefault, false); + + // assert + var expectedStyle = TextStyle.LibraryDefault with + { + Size = 20, + FontFamily = "Arial", + FontWeight = FontWeight.Bold, + BackgroundColor = Colors.Red.Lighten2, + HasStrikethrough = true, + Fallback = TextStyle.LibraryDefault with + { + Size = 20, + FontFamily = "Microsoft YaHei", + FontWeight = FontWeight.Bold, + BackgroundColor = Colors.Red.Lighten2, + HasUnderline = true, + HasStrikethrough = true + } + }; + + targetStyle.Should().BeEquivalentTo(expectedStyle); + } + } +} \ No newline at end of file diff --git a/Source/QuestPDF/Drawing/DocumentGenerator.cs b/Source/QuestPDF/Drawing/DocumentGenerator.cs index d982e3b..e6ac5fd 100644 --- a/Source/QuestPDF/Drawing/DocumentGenerator.cs +++ b/Source/QuestPDF/Drawing/DocumentGenerator.cs @@ -64,7 +64,7 @@ namespace QuestPDF.Drawing var container = new DocumentContainer(); document.Compose(container); var content = container.Compose(); - ApplyDefaultTextStyle(content, TextStyle.LibraryDefault); + ApplyDefaultTextStyle(content, TextStyle.Default); ApplyContentDirection(content, ContentDirection.LeftToRight); var debuggingState = Settings.EnableDebugging ? ApplyDebugging(content) : null; @@ -203,7 +203,8 @@ namespace QuestPDF.Drawing { if (textBlockItem is TextBlockSpan textSpan) { - textSpan.Style = textSpan.Style.ApplyGlobalStyle(documentDefaultTextStyle); + textSpan.Style = textSpan.Style.ApplyGlobalStyle(documentDefaultTextStyle, true); + textSpan.Style = textSpan.Style.ApplyGlobalStyle(TextStyle.LibraryDefault, false); } else if (textBlockItem is TextBlockElement textElement) { @@ -215,10 +216,10 @@ namespace QuestPDF.Drawing } if (content is DynamicHost dynamicHost) - dynamicHost.TextStyle = dynamicHost.TextStyle.ApplyGlobalStyle(documentDefaultTextStyle); + dynamicHost.TextStyle = dynamicHost.TextStyle.ApplyGlobalStyle(documentDefaultTextStyle, true); if (content is DefaultTextStyle defaultTextStyleElement) - documentDefaultTextStyle = defaultTextStyleElement.TextStyle.ApplyGlobalStyle(documentDefaultTextStyle); + documentDefaultTextStyle = defaultTextStyleElement.TextStyle.ApplyGlobalStyle(documentDefaultTextStyle, true); foreach (var child in content.GetChildren()) ApplyDefaultTextStyle(child, documentDefaultTextStyle); diff --git a/Source/QuestPDF/Infrastructure/TextStyleManager.cs b/Source/QuestPDF/Infrastructure/TextStyleManager.cs index 444dee9..b2976ab 100644 --- a/Source/QuestPDF/Infrastructure/TextStyleManager.cs +++ b/Source/QuestPDF/Infrastructure/TextStyleManager.cs @@ -224,18 +224,18 @@ namespace QuestPDF.Infrastructure 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) + internal static TextStyle ApplyGlobalStyle(this TextStyle style, TextStyle parent, bool overrideStyle) { var cacheKey = (style, parent); - return TextStyleApplyGlobalCache.GetOrAdd(cacheKey, key => ApplyStyle(key.origin, key.parent, overrideStyle: false).ApplyFontFallback()); + return TextStyleApplyGlobalCache.GetOrAdd(cacheKey, key => ApplyStyle(key.origin, key.parent, overrideStyle: false).ApplyFontFallback(overrideStyle)); } - private static TextStyle ApplyFontFallback(this TextStyle style) + private static TextStyle ApplyFontFallback(this TextStyle style, bool overrideStyle) { var targetFallbackStyle = style ?.Fallback - ?.ApplyStyle(style, overrideStyle: false, applyFallback: false) - ?.ApplyFontFallback(); + ?.ApplyStyle(style, overrideStyle: overrideStyle, overrideFontFamily: false, applyFallback: false) + ?.ApplyFontFallback(overrideStyle); return MutateStyle(style, TextStyleProperty.Fallback, targetFallbackStyle); } @@ -251,13 +251,16 @@ namespace QuestPDF.Infrastructure }); } - private static TextStyle ApplyStyle(this TextStyle style, TextStyle parent, bool overrideStyle = true, bool applyFallback = true) + private static TextStyle ApplyStyle(this TextStyle style, TextStyle parent, bool overrideStyle = true, bool overrideFontFamily = true, bool applyFallback = true) { var result = style; result = MutateStyle(result, TextStyleProperty.Color, parent.Color, overrideStyle); result = MutateStyle(result, TextStyleProperty.BackgroundColor, parent.BackgroundColor, overrideStyle); - result = MutateStyle(result, TextStyleProperty.FontFamily, parent.FontFamily, overrideStyle); + + if (style.FontFamily == null) + result = MutateStyle(result, TextStyleProperty.FontFamily, parent.FontFamily, overrideFontFamily); + result = MutateStyle(result, TextStyleProperty.Size, parent.Size, overrideStyle); result = MutateStyle(result, TextStyleProperty.LineHeight, parent.LineHeight, overrideStyle); result = MutateStyle(result, TextStyleProperty.LetterSpacing, parent.LetterSpacing, overrideStyle);