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(-)
New commits: commit ece6f72de3d9487ccfea3094f028877dfd7e89a0 Author: Khaled Hosny <[email protected]> AuthorDate: Mon Mar 2 02:02:08 2026 +0200 Commit: Khaled Hosny <[email protected]> CommitDate: Mon Mar 2 21:43:58 2026 +0100 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 <[email protected]> Tested-by: Jenkins 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 <driverblocklist.hxx> #include <vcl/bitmap.hxx> #include <vcl/salgtype.hxx> +#include <font/LogicalFontInstance.hxx> #include <test/GraphicsRenderTests.hxx> #include <premac.h> #include <SkRegion.h> #include <SkSurface.h> +#include <SkTypeface.h> #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<SkTypeface> applyVariations(const sk_sp<SkTypeface>& 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 <SkRuntimeEffect.h> #include <SkStream.h> #include <SkTileMode.h> +#include <SkTypeface.h> +#include <SkFontArguments.h> #include <skia_compiler.hxx> #include <skia_opts.hxx> #if defined(MACOSX) @@ -909,6 +911,29 @@ void dump(const sk_sp<SkImage>& image, const char* file) ostream.write(static_cast<const char*>(data->data()), data->size()); } +sk_sp<SkTypeface> applyVariations(const sk_sp<SkTypeface>& skTypeface, + const LogicalFontInstance& font) +{ + const auto& variations = font.GetVariations(); + if (variations.empty() || !skTypeface) + return skTypeface; + + std::vector<SkFontArguments::VariationPosition::Coordinate> 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<int>(skCoords.size()) }; + fontArgs.setVariationDesignPosition(varPosition); + + sk_sp<SkTypeface> variationFace = skTypeface->makeClone(fontArgs); + if (variationFace) + return variationFace; + return skTypeface; +} + #ifdef DBG_UTIL void prefillSurface(const sk_sp<SkSurface>& 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<SkTypeface> typeface = SkMakeTypefaceFromCTFont(rFont.GetCTFont()); + sk_sp<SkTypeface> 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<SkTypeface> typeface - = SkFontMgr_createTypefaceFromFcPattern(fontManager, rFont.GetFontOptions()->GetPattern()); + sk_sp<SkTypeface> typeface = SkiaHelper::applyVariations( + SkFontMgr_createTypefaceFromFcPattern(fontManager, rFont.GetFontOptions()->GetPattern()), + rInstance); SkFont font(typeface); font.setSize(nHeight); font.setScaleX(nWidth / nHeight);
