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);

Reply via email to