Skip to content

Commit

Permalink
Font fallback: improved implementation when application does not use …
Browse files Browse the repository at this point in the history
…global environment fonts
  • Loading branch information
MarcinZiabek committed Mar 6, 2024
1 parent 90624e3 commit a1b9f31
Show file tree
Hide file tree
Showing 6 changed files with 45 additions and 42 deletions.
4 changes: 2 additions & 2 deletions managed/NativeSkia.Tests/DataTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ public void CreateFromFile()

// read file via C# API
var expectedContent = File.ReadAllBytes(path);
expectedContent.Length.Should().Be(30_167);
expectedContent.Length.Should().Be(28_357);

// // read file via NativeSkia API
using var data = SkData.FromFile(path);
Expand All @@ -30,7 +30,7 @@ public void CreateFromBinary()

// read file via C# API
var expectedContent = File.ReadAllBytes(path);
expectedContent.Length.Should().Be(30_167);
expectedContent.Length.Should().Be(28_357);

// read file via NativeSkia API
using var data = SkData.FromBinary(expectedContent);
Expand Down
39 changes: 26 additions & 13 deletions managed/NativeSkia.Tests/ParagraphTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ public void DrawParagraphOnPdfCanvas()
typefaceProvider.AddTypefaceFromData(latoTypefaceData);

// build simple paragraph;
var fontCollection = SkFontCollection.Create(typefaceProvider, true, true);
var fontCollection = SkFontCollection.Create(typefaceProvider, SkFontManager.Global);

var paragraphStyleConfiguration = new ParagraphStyleConfiguration
{
Expand All @@ -35,7 +35,7 @@ public void DrawParagraphOnPdfCanvas()
FontSize = 18,
FontWeight = TextStyleConfiguration.FontWeights.Normal,

FontFamily = new SkText("Times New Roman"),
FontFamilies = GetFontFamilyPointers("Times New Roman"),

BackgroundColor = 0x00000000,
ForegroundColor = 0xFF000000,
Expand All @@ -53,8 +53,8 @@ public void DrawParagraphOnPdfCanvas()
using var textStyle = new SkTextStyle(textStyleConfiguration);
using var textStyleUnderline = new SkTextStyle(textStyleConfiguration with { DecorationType = TextStyleConfiguration.TextDecoration.Underline });

using var monoTypefaceStyle = new SkTextStyle(textStyleConfiguration with { FontFamily = new SkText("JetBrains Mono"), BackgroundColor = 0x33000000 });
using var latoTypefaceStyle = new SkTextStyle(textStyleConfiguration with { FontFamily = new SkText("Lato"), BackgroundColor = 0x22000000 });
using var monoTypefaceStyle = new SkTextStyle(textStyleConfiguration with { FontFamilies = GetFontFamilyPointers("JetBrains Mono"), BackgroundColor = 0x33000000 });
using var latoTypefaceStyle = new SkTextStyle(textStyleConfiguration with { FontFamilies = GetFontFamilyPointers("Lato"), BackgroundColor = 0x22000000 });

paragraphBuilder.AddText("Lorem Ipsum is simply \ndummy text of the printing and typesetting industry. ", textStyle);
paragraphBuilder.AddText("🥰😅🥰🥰🥰 ", textStyle);
Expand Down Expand Up @@ -100,7 +100,8 @@ public void DrawParagraphOnPdfCanvas()
[Test]
public void GetLineHeights()
{
using var fontCollection = SkFontCollection.Create(null, true, true);
using var typefaceProvider = new SkTypefaceProvider();
using var fontCollection = SkFontCollection.Create(typefaceProvider, SkFontManager.Global);

var paragraphStyleConfiguration = new ParagraphStyleConfiguration
{
Expand All @@ -114,7 +115,7 @@ public void GetLineHeights()
{
FontSize = 18,
FontWeight = TextStyleConfiguration.FontWeights.Normal,
FontFamily = new SkText("Times New Roman")
FontFamilies = GetFontFamilyPointers("Times New Roman")
});

paragraphBuilder.AddPlaceholder(new SkPlaceholderStyle { Width = 20, Height = 20, Alignment = SkPlaceholderStyle.PlaceholderAlignment.Bottom });
Expand All @@ -141,7 +142,7 @@ public void GetUnresolvedCodepoints()
using var latoTypefaceData = SkData.FromFile("input/Lato/Lato-Light.ttf");
typefaceProvider.AddTypefaceFromData(latoTypefaceData);

using var fontCollection = SkFontCollection.Create(typefaceProvider, false, true);
using var fontCollection = SkFontCollection.Create(typefaceProvider, SkFontManager.Empty);

var paragraphStyleConfiguration = new ParagraphStyleConfiguration();
using var paragraphBuilder = SkParagraphBuilder.Create(paragraphStyleConfiguration, fontCollection);
Expand All @@ -151,7 +152,7 @@ public void GetUnresolvedCodepoints()
FontSize = 20,
FontWeight = TextStyleConfiguration.FontWeights.Normal,
ForegroundColor = 0xFF000000,
FontFamily = new SkText("Lato")
FontFamilies = GetFontFamilyPointers("Lato")
});

const string text = "Fire as emoji 🔥 and in Japanese 火.";
Expand All @@ -168,8 +169,9 @@ public void GetUnresolvedCodepoints()
[Test]
public void Subscript()
{
// build simple paragraph;
var fontCollection = SkFontCollection.Create(null, true, true);
// build simple paragraph
using var typefaceProvider = new SkTypefaceProvider();
var fontCollection = SkFontCollection.Create(typefaceProvider, SkFontManager.Global);

var paragraphStyleConfiguration = new ParagraphStyleConfiguration
{
Expand All @@ -185,7 +187,7 @@ public void Subscript()
FontSize = 18,
FontWeight = TextStyleConfiguration.FontWeights.Normal,

FontFamily = new SkText("Times New Roman"),
FontFamilies = GetFontFamilyPointers("Times New Roman"),

BackgroundColor = 0x00000000,
ForegroundColor = 0xFF000000,
Expand Down Expand Up @@ -232,7 +234,8 @@ public void Subscript()
[Test]
public void DrawParagraphWithHyperlink()
{
using var fontCollection = SkFontCollection.Create(null, true, true);
using var typefaceProvider = new SkTypefaceProvider();
using var fontCollection = SkFontCollection.Create(typefaceProvider, SkFontManager.Global);

using var stream = new SkWriteStream();
using var pdf = SkPdfDocument.Create(stream, new SkPdfDocumentMetadata());
Expand Down Expand Up @@ -271,7 +274,7 @@ SkParagraph BuildParagraph()
FontSize = 18,
ForegroundColor = 0xFF000000,
FontWeight = TextStyleConfiguration.FontWeights.Medium,
FontFamily = new SkText("Times New Roman")
FontFamilies = GetFontFamilyPointers("Times New Roman")
};

var linkStyleConfiguration = baseTextStyleConfiguration with
Expand All @@ -293,4 +296,14 @@ SkParagraph BuildParagraph()
return paragraphBuilder.CreateParagraph();
}
}

IntPtr[] GetFontFamilyPointers(params string[] texts)
{
var result = new IntPtr[TextStyleConfiguration.FONT_FAMILIES_LENGTH];

for (var i = 0; i < Math.Min(result.Length, texts.Length); i++)
result[i] = new SkText(texts[i]).Instance;

return result;
}
}
16 changes: 4 additions & 12 deletions managed/NativeSkia/Text/SkFontCollection.cs
Original file line number Diff line number Diff line change
Expand Up @@ -16,22 +16,14 @@ private struct CreateCommand
{
public IntPtr FontManager;
public IntPtr TypefaceProvider;
[MarshalAs(UnmanagedType.I1)] public bool EnableFontFallback;
}

public static SkFontCollection Create(SkTypefaceProvider? typefaceProvider = null, bool useGlobalFonts = false, bool enableFontFallback = false)
public static SkFontCollection Create(SkTypefaceProvider typefaceProvider, SkFontManager fontManager)
{
typefaceProvider ??= new SkTypefaceProvider();

var fontManager = useGlobalFonts
? SkFontManager.Global
: SkFontManager.Empty;

var command = new CreateCommand
{
FontManager = fontManager.Instance,
TypefaceProvider = typefaceProvider.Instance,
EnableFontFallback = enableFontFallback
TypefaceProvider = typefaceProvider.Instance
};

var instance = API.font_collection_create(command);
Expand All @@ -42,7 +34,7 @@ public static SkFontCollection Create(SkTypefaceProvider? typefaceProvider = nul
{
Dispose();
}

public void Dispose()
{
if (Instance == IntPtr.Zero)
Expand All @@ -60,4 +52,4 @@ private static class API
[DllImport(SkiaAPI.LibraryName)]
public static extern void font_collection_unref(IntPtr fontCollection);
}
}
}
6 changes: 3 additions & 3 deletions managed/NativeSkia/Text/SkTextStyle.cs
Original file line number Diff line number Diff line change
Expand Up @@ -9,9 +9,9 @@ internal struct TextStyleConfiguration
public FontWeights FontWeight;
public bool IsItalic;

public IntPtr FontFamily;
public IntPtr FontFamilyFallback;
public const int FONT_FAMILIES_LENGTH = 16;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = FONT_FAMILIES_LENGTH)] public IntPtr[] FontFamilies;

public uint ForegroundColor;
public uint BackgroundColor;

Expand Down
8 changes: 1 addition & 7 deletions native/src/text/fontCollection.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -8,20 +8,14 @@ extern "C" {
struct CreateFontCollectionCommand {
SkFontMgr *fontManager;
skia::textlayout::TypefaceFontProvider *typefaceFontProvider;
bool enableFontFallback;
};

QUEST_API skia::textlayout::FontCollection *font_collection_create(CreateFontCollectionCommand command) {
auto fontCollection = new skia::textlayout::FontCollection();

fontCollection->setAssetFontManager(sk_ref_sp(command.typefaceFontProvider));
fontCollection->setDefaultFontManager(sk_ref_sp(command.fontManager));

if (command.enableFontFallback) {
fontCollection->enableFontFallback();
} else {
fontCollection->disableFontFallback();
}
fontCollection->enableFontFallback();

return fontCollection;
}
Expand Down
14 changes: 9 additions & 5 deletions native/src/text/textStyle.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -5,12 +5,13 @@
extern "C" {

struct TextStyleConfiguration {
static const int FONT_FAMILIES_LENGTH = 16;

SkScalar fontSize;
SkFontStyle::Weight fontWeight;
bool isItalic;

char *fontFamily;
char *fontFamilyFallback;
char* fontFamilies[FONT_FAMILIES_LENGTH];

SkColor foregroundColor;
SkColor backgroundColor;
Expand All @@ -37,11 +38,13 @@ QUEST_API skia::textlayout::TextStyle *text_style_create(TextStyleConfiguration

// set font families
std::vector<SkString> fontFamilies;
fontFamilies.emplace_back(configuration.fontFamily);

if (configuration.fontFamilyFallback)
fontFamilies.emplace_back(configuration.fontFamilyFallback);
for (auto & fontFamily : configuration.fontFamilies) {
if (fontFamily == nullptr)
continue;

fontFamilies.emplace_back(fontFamily);
}

textStyle->setFontFamilies(fontFamilies);
// end
Expand Down Expand Up @@ -76,4 +79,5 @@ QUEST_API skia::textlayout::TextStyle *text_style_create(TextStyleConfiguration
QUEST_API void text_style_delete(skia::textlayout::TextStyle *textStyle) {
delete textStyle;
}

}

0 comments on commit a1b9f31

Please # to comment.