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