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.
