vcl/inc/font/LogicalFontInstance.hxx    |    9 +++++++++
 vcl/inc/pdf/pdfwriter_impl.hxx          |    2 +-
 vcl/source/font/LogicalFontInstance.cxx |   26 +++++++++++++++++++++++---
 3 files changed, 33 insertions(+), 4 deletions(-)

New commits:
commit c992dc2c534bebad70de4327a4046a6b357c8571
Author:     Khaled Hosny <[email protected]>
AuthorDate: Tue Feb 24 17:52:51 2026 +0200
Commit:     Khaled Hosny <[email protected]>
CommitDate: Mon Mar 2 21:43:24 2026 +0100

    Add LogicalFontInstance::[G|S]etVariations()
    
    First step towards supporting font variations beyond named instances.
    
    Change-Id: Ia339654b1ea269d72c50d5193103c889dcc61afb
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/200496
    Reviewed-by: Khaled Hosny <[email protected]>
    Tested-by: Jenkins

diff --git a/vcl/inc/font/LogicalFontInstance.hxx 
b/vcl/inc/font/LogicalFontInstance.hxx
index 943fd2555558..34ce611685b6 100644
--- a/vcl/inc/font/LogicalFontInstance.hxx
+++ b/vcl/inc/font/LogicalFontInstance.hxx
@@ -101,6 +101,13 @@ public: // TODO: make data members private
     double GetAverageWidthFactor() const { return m_nAveWidthFactor; }
     const vcl::font::FontSelectPattern& GetFontSelectPattern() const { return 
m_aFontSelData; }
 
+    void SetVariations(const std::vector<hb_variation_t>& rVariations)
+    {
+        m_aVariations = rVariations;
+        mxVariations.reset();
+    }
+    const std::vector<hb_variation_t>& GetVariations() const;
+
     const vcl::font::PhysicalFontFace* GetFontFace() const { return 
m_pFontFace.get(); }
     vcl::font::PhysicalFontFace* GetFontFace() { return m_pFontFace.get(); }
     const ImplFontCache* GetFontCache() const { return mpFontCache; }
@@ -148,6 +155,8 @@ private:
     double m_nAveWidthFactor;
     rtl::Reference<vcl::font::PhysicalFontFace> m_pFontFace;
     std::optional<bool> m_xbIsGraphiteFont;
+    std::vector<hb_variation_t> m_aVariations;
+    mutable std::optional<std::vector<hb_variation_t>> mxVariations;
 
     mutable hb_draw_funcs_t* m_pHbDrawFuncs = nullptr;
     basegfx::B2DPolygon m_aDrawPolygon;
diff --git a/vcl/inc/pdf/pdfwriter_impl.hxx b/vcl/inc/pdf/pdfwriter_impl.hxx
index c762a6fb0959..0df877351230 100644
--- a/vcl/inc/pdf/pdfwriter_impl.hxx
+++ b/vcl/inc/pdf/pdfwriter_impl.hxx
@@ -356,7 +356,7 @@ struct FontSubsetKey
 
     FontSubsetKey(const vcl::font::PhysicalFontFace* pFace, const 
LogicalFontInstance* pFont)
         : m_pFace(pFace)
-        , m_rVariations(pFace->GetVariations(*pFont))
+        , m_rVariations(pFont->GetVariations())
         , m_nHash(0)
     {
         o3tl::hash_combine(m_nHash, m_rVariations.size());
diff --git a/vcl/source/font/LogicalFontInstance.cxx 
b/vcl/source/font/LogicalFontInstance.cxx
index e79b06bf15d9..ae418ccfad3f 100644
--- a/vcl/source/font/LogicalFontInstance.cxx
+++ b/vcl/source/font/LogicalFontInstance.cxx
@@ -60,6 +60,26 @@ LogicalFontInstance::~LogicalFontInstance()
         hb_draw_funcs_destroy(m_pHbDrawFuncs);
 }
 
+const std::vector<hb_variation_t>& LogicalFontInstance::GetVariations() const
+{
+    if (!mxVariations)
+    {
+        mxVariations = GetFontFace()->GetVariations(*this);
+        for (const auto& rVariation : m_aVariations)
+        {
+            auto it = std::find_if(mxVariations->begin(), mxVariations->end(),
+                                   [&rVariation](const hb_variation_t& rOther) 
{
+                                       return rOther.tag == rVariation.tag;
+                                   });
+            if (it != mxVariations->end())
+                it->value = rVariation.value;
+            else
+                mxVariations->push_back(rVariation);
+        }
+    }
+    return *mxVariations;
+}
+
 hb_font_t* LogicalFontInstance::InitHbFont()
 {
     auto pFace = GetFontFace();
@@ -71,9 +91,9 @@ hb_font_t* LogicalFontInstance::InitHbFont()
     hb_font_set_scale(pHbFont, nUPEM, nUPEM);
     hb_ot_font_set_funcs(pHbFont);
 
-    auto aVariations = pFace->GetVariations(*this);
-    if (!aVariations.empty())
-        hb_font_set_variations(pHbFont, aVariations.data(), 
aVariations.size());
+    const auto& rVariations = GetVariations();
+    if (!rVariations.empty())
+        hb_font_set_variations(pHbFont, rVariations.data(), 
rVariations.size());
 
     // If we are applying artificial italic, instruct HarfBuzz to do the same
     // so that mark positioning is also transformed.

Reply via email to