From ece6f72de3d9487ccfea3094f028877dfd7e89a0 Mon Sep 17 00:00:00 2001 From: Khaled Hosny Date: Mon, 2 Mar 2026 02:02:08 +0200 Subject: [PATCH] Apply font variations when drawing text with Skia Set variations on the Skia font since now we allow the user to set font variations, and they can be different from the variations the font was created with. Previously we only supported named instances and these got their variations set by the platform font API. Change-Id: I2cda0409273a8ae00f40dacb1deb166af65ebbe5 Reviewed-on: https://gerrit.libreoffice.org/c/core/+/200673 Reviewed-by: Khaled Hosny Tested-by: Jenkins --- vcl/CppunitTest_vcl_skia.mk | 1 + vcl/inc/skia/utils.hxx | 5 +++++ vcl/skia/SkiaHelper.cxx | 25 +++++++++++++++++++++++++ vcl/skia/osx/gdiimpl.cxx | 3 ++- vcl/skia/win/gdiimpl.cxx | 1 + vcl/skia/x11/textrender.cxx | 5 +++-- 6 files changed, 37 insertions(+), 3 deletions(-) diff --git a/vcl/CppunitTest_vcl_skia.mk b/vcl/CppunitTest_vcl_skia.mk index 094bba75fafa..668791d58834 100644 --- a/vcl/CppunitTest_vcl_skia.mk +++ b/vcl/CppunitTest_vcl_skia.mk @@ -37,6 +37,7 @@ $(eval $(call gb_CppunitTest_use_libraries,vcl_skia, \ $(eval $(call gb_CppunitTest_use_externals,vcl_skia, \ boost_headers \ $(if $(filter SKIA,$(BUILD_TYPE)),skia) \ + harfbuzz \ )) $(eval $(call gb_CppunitTest_use_sdk_api,vcl_skia)) diff --git a/vcl/inc/skia/utils.hxx b/vcl/inc/skia/utils.hxx index e78abdd5ab70..e699f8b86790 100644 --- a/vcl/inc/skia/utils.hxx +++ b/vcl/inc/skia/utils.hxx @@ -27,12 +27,14 @@ #include #include #include +#include #include #include #include #include +#include #if defined __GNUC__ && !defined __clang__ #pragma GCC diagnostic push #pragma GCC diagnostic ignored "-Wattributes" @@ -138,6 +140,9 @@ VCL_DLLPUBLIC const SkSurfaceProps* surfaceProps(); // Set pixel geometry to be used by SkSurfaceProps. VCL_DLLPUBLIC void setPixelGeometry(SkPixelGeometry pixelGeometry); +VCL_DLLPUBLIC sk_sp applyVariations(const sk_sp& skTypeface, + const LogicalFontInstance& font); + inline bool isUnitTestRunning(const char* name = nullptr) { if (name == nullptr) diff --git a/vcl/skia/SkiaHelper.cxx b/vcl/skia/SkiaHelper.cxx index cc84c26e1d21..3884319c53d6 100644 --- a/vcl/skia/SkiaHelper.cxx +++ b/vcl/skia/SkiaHelper.cxx @@ -57,6 +57,8 @@ bool isAlphaMaskBlendingEnabled() { return false; } #include #include #include +#include +#include #include #include #if defined(MACOSX) @@ -909,6 +911,29 @@ void dump(const sk_sp& image, const char* file) ostream.write(static_cast(data->data()), data->size()); } +sk_sp applyVariations(const sk_sp& skTypeface, + const LogicalFontInstance& font) +{ + const auto& variations = font.GetVariations(); + if (variations.empty() || !skTypeface) + return skTypeface; + + std::vector skCoords; + skCoords.reserve(variations.size()); + for (const auto& var : variations) + skCoords.push_back({ var.tag, var.value }); + + SkFontArguments fontArgs; + SkFontArguments::VariationPosition varPosition + = { skCoords.data(), static_cast(skCoords.size()) }; + fontArgs.setVariationDesignPosition(varPosition); + + sk_sp variationFace = skTypeface->makeClone(fontArgs); + if (variationFace) + return variationFace; + return skTypeface; +} + #ifdef DBG_UTIL void prefillSurface(const sk_sp& surface) { diff --git a/vcl/skia/osx/gdiimpl.cxx b/vcl/skia/osx/gdiimpl.cxx index 5dd219ba429e..c5c5a9aa7e2f 100644 --- a/vcl/skia/osx/gdiimpl.cxx +++ b/vcl/skia/osx/gdiimpl.cxx @@ -381,7 +381,8 @@ void AquaSkiaSalGraphicsImpl::drawTextLayout(const GenericSalLayout& rLayout) } } - sk_sp typeface = SkMakeTypefaceFromCTFont(rFont.GetCTFont()); + sk_sp typeface + = SkiaHelper::applyVariations(SkMakeTypefaceFromCTFont(rFont.GetCTFont()), rFont); SkFont font(typeface); font.setSize(nHeight); // font.setScaleX(rFont.mfFontStretch); TODO diff --git a/vcl/skia/win/gdiimpl.cxx b/vcl/skia/win/gdiimpl.cxx index f085f915ef7e..7ab8d2bbff45 100644 --- a/vcl/skia/win/gdiimpl.cxx +++ b/vcl/skia/win/gdiimpl.cxx @@ -268,6 +268,7 @@ bool WinSkiaSalGraphicsImpl::DrawTextLayout(const GenericSalLayout& rLayout) if (!typeface) return false; } + typeface = SkiaHelper::applyVariations(typeface, rWinFont); // Cache the typeface. rWinFont.SetSkiaTypeface(typeface, dwrite); } diff --git a/vcl/skia/x11/textrender.cxx b/vcl/skia/x11/textrender.cxx index 4899dff28379..07ce167c045a 100644 --- a/vcl/skia/x11/textrender.cxx +++ b/vcl/skia/x11/textrender.cxx @@ -64,8 +64,9 @@ void SkiaTextRender::DrawTextLayout(const GenericSalLayout& rLayout, const SalGr fontManager = SkFontMgr_New_FontConfig(FcConfigReference(nullptr), SkFontScanner_Make_FreeType()); } - sk_sp typeface - = SkFontMgr_createTypefaceFromFcPattern(fontManager, rFont.GetFontOptions()->GetPattern()); + sk_sp typeface = SkiaHelper::applyVariations( + SkFontMgr_createTypefaceFromFcPattern(fontManager, rFont.GetFontOptions()->GetPattern()), + rInstance); SkFont font(typeface); font.setSize(nHeight); font.setScaleX(nWidth / nHeight);