vcl/inc/unx/fc_fontoptions.hxx                 |    6 +++-
 vcl/quartz/salgdi.cxx                          |   32 +++++++++++++++++++++++++
 vcl/unx/generic/fontmanager/fontconfig.cxx     |   21 +++++++++++++++-
 vcl/unx/generic/glyphs/freetype_glyphcache.cxx |    2 -
 4 files changed, 58 insertions(+), 3 deletions(-)

New commits:
commit 3de5214a77ebd1704e1ae256f999ac0485cca3c0
Author:     Khaled Hosny <[email protected]>
AuthorDate: Mon Mar 2 02:02:13 2026 +0200
Commit:     Khaled Hosny <[email protected]>
CommitDate: Mon Mar 2 21:44:29 2026 +0100

    Apply font variations when drawing text with CoreText
    
    Similar to the previous commit but for CoreText when Skia is disabled
    (e.g. when printing).
    
    Change-Id: I20645c4c5087e78957b3af3ea6e50eb9d34d55b5
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/200738
    Tested-by: Jenkins
    Reviewed-by: Khaled Hosny <[email protected]>

diff --git a/vcl/quartz/salgdi.cxx b/vcl/quartz/salgdi.cxx
index af5a620484c8..aff0b92add26 100644
--- a/vcl/quartz/salgdi.cxx
+++ b/vcl/quartz/salgdi.cxx
@@ -382,6 +382,38 @@ void AquaGraphicsBackend::drawTextLayout(const 
GenericSalLayout& rLayout)
     }
 
     CTFontRef pCTFont = rFont.GetCTFont();
+    CTFontRef pVarFont = nullptr;
+    comphelper::ScopeGuard aVarFontGuard([&]() { if (pVarFont) 
CFRelease(pVarFont); });
+    const auto& rVariations = rFont.GetVariations();
+    if (!rVariations.empty())
+    {
+        CFMutableDictionaryRef pVarDict = 
CFDictionaryCreateMutable(kCFAllocatorDefault, rVariations.size(),
+                                                                     
&kCFTypeDictionaryKeyCallBacks,
+                                                                     
&kCFTypeDictionaryValueCallBacks);
+        for (const auto& rVariation : rVariations)
+        {
+            hb_tag_t nTag = rVariation.tag;
+            CFNumberRef pTag = CFNumberCreate(kCFAllocatorDefault, 
kCFNumberSInt32Type, &nTag);
+            double fValue = rVariation.value;
+            CFNumberRef pValue = CFNumberCreate(kCFAllocatorDefault, 
kCFNumberDoubleType, &fValue);
+            CFDictionaryAddValue(pVarDict, pTag, pValue);
+            CFRelease(pTag);
+            CFRelease(pValue);
+        }
+        CFDictionaryRef pAttrDict = CFDictionaryCreate(kCFAllocatorDefault,
+                                                       (const 
void**)&kCTFontVariationAttribute,
+                                                       (const 
void**)&pVarDict, 1,
+                                                       
&kCFTypeDictionaryKeyCallBacks,
+                                                       
&kCFTypeDictionaryValueCallBacks);
+        CTFontDescriptorRef pVarDesc = 
CTFontDescriptorCreateWithAttributes(pAttrDict);
+        pVarFont = CTFontCreateCopyWithAttributes(pCTFont, 0.0, nullptr, 
pVarDesc);
+        pCTFont = pVarFont;
+
+        CFRelease(pVarDesc);
+        CFRelease(pAttrDict);
+        CFRelease(pVarDict);
+    }
+
     CGAffineTransform aRotMatrix = 
CGAffineTransformMakeRotation(-rFont.mfFontRotation);
 
     basegfx::B2DPoint aPos;
commit 6a0ac36db8c9017bfab8026dec37708924d0cdce
Author:     Khaled Hosny <[email protected]>
AuthorDate: Mon Mar 2 02:02:11 2026 +0200
Commit:     Khaled Hosny <[email protected]>
CommitDate: Mon Mar 2 21:44:14 2026 +0100

    Apply font variations when drawing text with cairo
    
    Similar to the previous commit but for cairo.
    
    Change-Id: I4631d9d67a52e4421346e67e3ce019eb8d677ff7
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/200737
    Reviewed-by: Khaled Hosny <[email protected]>
    Tested-by: Jenkins

diff --git a/vcl/inc/unx/fc_fontoptions.hxx b/vcl/inc/unx/fc_fontoptions.hxx
index 73bcf3421bc5..5e76c381b959 100644
--- a/vcl/inc/unx/fc_fontoptions.hxx
+++ b/vcl/inc/unx/fc_fontoptions.hxx
@@ -21,6 +21,8 @@
 
 #include <rtl/string.hxx>
 #include <vcl/dllapi.h>
+#include <hb.h>
+#include <vector>
 
 typedef struct _FcPattern   FcPattern;
 class VCL_DLLPUBLIC FontConfigFontOptions
@@ -30,7 +32,9 @@ public:
                             mpPattern(pPattern) {}
                         ~FontConfigFontOptions();
 
-    void                SyncPattern(const OString& rFileName, sal_uInt32 
nFontFace, sal_uInt32 nFontVariation, bool bEmbolden);
+    void                SyncPattern(const OString& rFileName, sal_uInt32 
nFontFace,
+                                    sal_uInt32 nFontVariation, bool bEmbolden,
+                                    const std::vector<hb_variation_t>& 
rFontVariations);
     FcPattern*          GetPattern() const;
     static void         cairo_font_options_substitute(FcPattern* pPattern);
 private:
diff --git a/vcl/unx/generic/fontmanager/fontconfig.cxx 
b/vcl/unx/generic/fontmanager/fontconfig.cxx
index b33675cd7b2a..ab4b04bd29bd 100644
--- a/vcl/unx/generic/fontmanager/fontconfig.cxx
+++ b/vcl/unx/generic/fontmanager/fontconfig.cxx
@@ -1295,7 +1295,11 @@ FcPattern *FontConfigFontOptions::GetPattern() const
     return mpPattern;
 }
 
-void FontConfigFontOptions::SyncPattern(const OString& rFileName, sal_uInt32 
nIndex, sal_uInt32 nVariation, bool bEmbolden)
+#ifndef FC_FONT_VARIATIONS
+#define FC_FONT_VARIATIONS "fontvariations"
+#endif
+
+void FontConfigFontOptions::SyncPattern(const OString& rFileName, sal_uInt32 
nIndex, sal_uInt32 nVariation, bool bEmbolden, const 
std::vector<hb_variation_t>& rVariations)
 {
     FcPatternDel(mpPattern, FC_FILE);
     FcPatternAddString(mpPattern, FC_FILE, reinterpret_cast<FcChar8 const 
*>(rFileName.getStr()));
@@ -1304,6 +1308,21 @@ void FontConfigFontOptions::SyncPattern(const OString& 
rFileName, sal_uInt32 nIn
     FcPatternAddInteger(mpPattern, FC_INDEX, nFcIndex);
     FcPatternDel(mpPattern, FC_EMBOLDEN);
     FcPatternAddBool(mpPattern, FC_EMBOLDEN, bEmbolden ? FcTrue : FcFalse);
+
+    FcPatternDel(mpPattern, FC_FONT_VARIATIONS);
+    if (!rVariations.empty())
+    {
+        OStringBuffer aVariationsString;
+        char buf[128];
+        for (const auto& rVariation : rVariations)
+        {
+            if (!aVariationsString.isEmpty())
+                aVariationsString.append(',');
+            hb_variation_to_string(const_cast<hb_variation_t*>(&rVariation), 
buf, sizeof(buf));
+            aVariationsString.append(buf);
+        }
+        FcPatternAddString(mpPattern, FC_FONT_VARIATIONS, 
reinterpret_cast<const FcChar8*>(aVariationsString.getStr()));
+    }
 }
 
 std::unique_ptr<FontConfigFontOptions> PrintFontManager::getFontOptions(const 
FontAttributes& rInfo, int nSize)
diff --git a/vcl/unx/generic/glyphs/freetype_glyphcache.cxx 
b/vcl/unx/generic/glyphs/freetype_glyphcache.cxx
index b2d47f717ed3..20836be4750c 100644
--- a/vcl/unx/generic/glyphs/freetype_glyphcache.cxx
+++ b/vcl/unx/generic/glyphs/freetype_glyphcache.cxx
@@ -476,7 +476,7 @@ const FontConfigFontOptions* FreetypeFont::GetFontOptions() 
const
     if (!mxFontOptions)
     {
         mxFontOptions = GetFCFontOptions(mxFontInfo->GetFontAttributes(), 
mrFontInstance.GetFontSelectPattern().mnHeight);
-        mxFontOptions->SyncPattern(GetFontFileName(), GetFontFaceIndex(), 
GetFontFaceVariation(), mrFontInstance.NeedsArtificialBold());
+        mxFontOptions->SyncPattern(GetFontFileName(), GetFontFaceIndex(), 
GetFontFaceVariation(), mrFontInstance.NeedsArtificialBold(), 
mrFontInstance.GetVariations());
     }
     return mxFontOptions.get();
 }

Reply via email to