vcl/inc/font/PhysicalFontFace.hxx              |    9 +++----
 vcl/inc/quartz/salgdi.h                        |    2 -
 vcl/inc/unx/freetype_glyphcache.hxx            |    2 -
 vcl/inc/unx/glyphcache.hxx                     |    2 -
 vcl/inc/win/salgdi.h                           |    2 -
 vcl/quartz/ctfonts.cxx                         |    9 ++++---
 vcl/source/font/PhysicalFontFace.cxx           |   30 +++++++++++++++----------
 vcl/unx/generic/glyphs/freetype_glyphcache.cxx |   17 +++++++-------
 vcl/win/gdi/salfont.cxx                        |   11 +++++----
 9 files changed, 46 insertions(+), 38 deletions(-)

New commits:
commit a38bb773bb568ef942293f23d0701da933817e8f
Author:     Khaled Hosny <kha...@aliftype.com>
AuthorDate: Sat Nov 19 14:58:40 2022 +0200
Commit:     خالد حسني <kha...@aliftype.com>
CommitDate: Sat Nov 19 15:45:21 2022 +0100

    vcl: use std::optional in PhysicalFontFace
    
    Otherwise when a font does not, say, support variations or color
    palettes, we keep querying the font each time they are requested.
    
    Change-Id: I3a41bc73dd814b25af3a8b5b009632ecf7ef27ab
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/142963
    Tested-by: Jenkins
    Reviewed-by: خالد حسني <kha...@aliftype.com>

diff --git a/vcl/inc/font/PhysicalFontFace.hxx 
b/vcl/inc/font/PhysicalFontFace.hxx
index ae0e6ad7d5bf..6e99ae4a098c 100644
--- a/vcl/inc/font/PhysicalFontFace.hxx
+++ b/vcl/inc/font/PhysicalFontFace.hxx
@@ -194,16 +194,15 @@ public:
         return nullptr;
     }
 
-    virtual std::vector<hb_variation_t> GetVariations() const { return {}; };
+    virtual const std::vector<hb_variation_t>& GetVariations() const;
 
 protected:
     mutable hb_face_t* mpHbFace;
     mutable hb_font_t* mpHbUnscaledFont;
     mutable FontCharMapRef mxCharMap;
-    mutable vcl::FontCapabilities maFontCapabilities;
-    mutable bool mbFontCapabilitiesRead;
-    mutable std::vector<ColorPalette> maColorPalettes;
-    mutable std::vector<hb_variation_t> m_aVariations;
+    mutable std::optional<vcl::FontCapabilities> mxFontCapabilities;
+    mutable std::optional<std::vector<ColorPalette>> mxColorPalettes;
+    mutable std::optional<std::vector<hb_variation_t>> mxVariations;
 
     explicit PhysicalFontFace(const FontAttributes&);
 
diff --git a/vcl/inc/quartz/salgdi.h b/vcl/inc/quartz/salgdi.h
index 121aef3cf59a..79ea9e32e0d6 100644
--- a/vcl/inc/quartz/salgdi.h
+++ b/vcl/inc/quartz/salgdi.h
@@ -72,7 +72,7 @@ public:
 
     hb_blob_t* GetHbTable(hb_tag_t nTag) const override;
 
-    std::vector<hb_variation_t> GetVariations() const override;
+    const std::vector<hb_variation_t>& GetVariations() const override;
 
 private:
     CTFontDescriptorRef             mxFontDescriptor;
diff --git a/vcl/inc/unx/freetype_glyphcache.hxx 
b/vcl/inc/unx/freetype_glyphcache.hxx
index 0ec53c073006..4cf982c50a12 100644
--- a/vcl/inc/unx/freetype_glyphcache.hxx
+++ b/vcl/inc/unx/freetype_glyphcache.hxx
@@ -101,7 +101,7 @@ public:
     virtual hb_face_t* GetHbFace() const override;
     virtual hb_blob_t* GetHbTable(hb_tag_t nTag) const override;
 
-    std::vector<hb_variation_t> GetVariations() const override;
+    const std::vector<hb_variation_t>& GetVariations() const override;
 };
 
 class SAL_DLLPUBLIC_RTTI FreetypeFontInstance final : public 
LogicalFontInstance
diff --git a/vcl/inc/unx/glyphcache.hxx b/vcl/inc/unx/glyphcache.hxx
index a6be9e872da6..22e2f0e173d9 100644
--- a/vcl/inc/unx/glyphcache.hxx
+++ b/vcl/inc/unx/glyphcache.hxx
@@ -129,8 +129,6 @@ public:
     bool                    GetGlyphOutline(sal_GlyphId, 
basegfx::B2DPolyPolygon&, bool) const;
     bool                    GetAntialiasAdvice() const;
 
-    std::vector<hb_variation_t> GetVariations() const;
-
 private:
     friend class FreetypeFontInstance;
     friend class FreetypeManager;
diff --git a/vcl/inc/win/salgdi.h b/vcl/inc/win/salgdi.h
index e0661dec5a1c..999bb39a1812 100644
--- a/vcl/inc/win/salgdi.h
+++ b/vcl/inc/win/salgdi.h
@@ -76,7 +76,7 @@ public:
 
     hb_blob_t*              GetHbTable(hb_tag_t nTag) const override;
 
-    std::vector<hb_variation_t> GetVariations() const override;
+    const std::vector<hb_variation_t>& GetVariations() const override;
 
 private:
     sal_IntPtr              mnId;
diff --git a/vcl/quartz/ctfonts.cxx b/vcl/quartz/ctfonts.cxx
index 0ca4ffc953ec..c2f6a8a55c00 100644
--- a/vcl/quartz/ctfonts.cxx
+++ b/vcl/quartz/ctfonts.cxx
@@ -268,12 +268,13 @@ hb_blob_t* CoreTextFontFace::GetHbTable(hb_tag_t nTag) 
const
     return pBlob;
 }
 
-std::vector<hb_variation_t> CoreTextFontFace::GetVariations() const
+const std::vector<hb_variation_t>& CoreTextFontFace::GetVariations() const
 {
     CTFontRef pFont = CTFontCreateWithFontDescriptor(mxFontDescriptor, 0.0, 
nullptr);
 
-    if (m_aVariations.empty())
+    if (!mxVariations)
     {
+        mxVariations.emplace();
         CFArrayRef pAxes = CTFontCopyVariationAxes(pFont);
         if (pAxes)
         {
@@ -300,7 +301,7 @@ std::vector<hb_variation_t> 
CoreTextFontFace::GetVariations() const
                             continue;
                         CFNumberGetValue(pValue, kCFNumberFloatType, &fValue);
 
-                        m_aVariations.push_back({ nTag, fValue });
+                        mxVariations->push_back({ nTag, fValue });
                     }
                 }
                 CFRelease(pVariations);
@@ -309,7 +310,7 @@ std::vector<hb_variation_t> 
CoreTextFontFace::GetVariations() const
         }
     }
 
-    return m_aVariations;
+    return *mxVariations;
 }
 
 rtl::Reference<LogicalFontInstance> CoreTextFontFace::CreateFontInstance(const 
vcl::font::FontSelectPattern& rFSD) const
diff --git a/vcl/source/font/PhysicalFontFace.cxx 
b/vcl/source/font/PhysicalFontFace.cxx
index 81f63d221013..d0670f51a1e2 100644
--- a/vcl/source/font/PhysicalFontFace.cxx
+++ b/vcl/source/font/PhysicalFontFace.cxx
@@ -44,7 +44,6 @@ PhysicalFontFace::PhysicalFontFace(const FontAttributes& rDFA)
     : FontAttributes(rDFA)
     , mpHbFace(nullptr)
     , mpHbUnscaledFont(nullptr)
-    , mbFontCapabilitiesRead(false)
 {
     // OpenSymbol is a unicode font, but it still deserves the symbol flag
     if (!IsSymbolFont())
@@ -287,16 +286,15 @@ FontCharMapRef PhysicalFontFace::GetFontCharMap() const
 
 bool PhysicalFontFace::GetFontCapabilities(vcl::FontCapabilities& 
rFontCapabilities) const
 {
-    if (!mbFontCapabilitiesRead)
+    if (!mxFontCapabilities)
     {
-        mbFontCapabilitiesRead = true;
-
+        mxFontCapabilities.emplace();
         RawFontData aData(GetRawFontData(HB_TAG('O', 'S', '/', '2')));
-        getTTCoverage(maFontCapabilities.oUnicodeRange, 
maFontCapabilities.oCodePageRange,
+        getTTCoverage(mxFontCapabilities->oUnicodeRange, 
mxFontCapabilities->oCodePageRange,
                       aData.data(), aData.size());
     }
 
-    rFontCapabilities = maFontCapabilities;
+    rFontCapabilities = *mxFontCapabilities;
     return rFontCapabilities.oUnicodeRange || rFontCapabilities.oCodePageRange;
 }
 
@@ -391,12 +389,12 @@ bool PhysicalFontFace::HasColorLayers() const
 
 const ColorPalette& PhysicalFontFace::GetColorPalette(size_t nIndex) const
 {
-    if (maColorPalettes.empty())
+    if (!mxColorPalettes)
     {
+        mxColorPalettes.emplace();
         const auto pHbFace = GetHbFace();
-
         auto nPalettes = hb_ot_color_palette_get_count(pHbFace);
-        maColorPalettes.reserve(nPalettes);
+        mxColorPalettes->reserve(nPalettes);
         for (auto nPalette = 0u; nPalette < nPalettes; nPalette++)
         {
             auto nColors = hb_ot_color_palette_get_colors(pHbFace, nPalette, 
0, nullptr, nullptr);
@@ -412,11 +410,11 @@ const ColorPalette& 
PhysicalFontFace::GetColorPalette(size_t nIndex) const
                 auto b = hb_color_get_blue(aColor);
                 aPalette[nColor] = Color(ColorAlphaTag::ColorAlpha, a, r, g, 
b);
             }
-            maColorPalettes.push_back(aPalette);
+            mxColorPalettes->push_back(aPalette);
         }
     }
 
-    return maColorPalettes[nIndex];
+    return (*mxColorPalettes)[nIndex];
 }
 
 std::vector<ColorLayer> PhysicalFontFace::GetGlyphColorLayers(sal_GlyphId 
nGlyphIndex) const
@@ -511,6 +509,16 @@ OUString PhysicalFontFace::GetName(NameID aNameID, const 
LanguageTag& rLanguageT
 
     return sName;
 }
+
+const std::vector<hb_variation_t>& PhysicalFontFace::GetVariations() const
+{
+    if (!mxVariations)
+    {
+        SAL_WARN("vcl.fonts", "Getting font variations is not supported.");
+        mxVariations.emplace();
+    }
+    return *mxVariations;
+}
 }
 
 /* vim:set shiftwidth=4 softtabstop=4 expandtab cinoptions=b1,g0,N-s 
cinkeys+=0=break: */
diff --git a/vcl/unx/generic/glyphs/freetype_glyphcache.cxx 
b/vcl/unx/generic/glyphs/freetype_glyphcache.cxx
index d0f9e2588c5e..4d430e6d8f9a 100644
--- a/vcl/unx/generic/glyphs/freetype_glyphcache.cxx
+++ b/vcl/unx/generic/glyphs/freetype_glyphcache.cxx
@@ -367,33 +367,34 @@ hb_blob_t* FreetypeFontFace::GetHbTable(hb_tag_t nTag) 
const
     return hb_face_reference_table(mpHbFace, nTag);
 }
 
-std::vector<hb_variation_t> FreetypeFontFace::GetVariations() const
+const std::vector<hb_variation_t>& FreetypeFontFace::GetVariations() const
 {
-    if (m_aVariations.empty())
+    if (!mxVariations)
     {
+        mxVariations.emplace();
         FT_Face aFaceFT = mpFreetypeFontInfo->GetFaceFT();
         sal_uInt32 nFaceVariation = mpFreetypeFontInfo->GetFontFaceVariation();
         if (!(aFaceFT && nFaceVariation))
-            return m_aVariations;
+            return *mxVariations;
 
         FT_MM_Var* pFtMMVar;
         if (FT_Get_MM_Var(aFaceFT, &pFtMMVar) != 0)
-            return m_aVariations;
+            return *mxVariations;
 
         if (nFaceVariation <= pFtMMVar->num_namedstyles)
         {
             FT_Var_Named_Style* instance = 
&pFtMMVar->namedstyle[nFaceVariation - 1];
-            m_aVariations.resize(pFtMMVar->num_axis);
+            mxVariations->resize(pFtMMVar->num_axis);
             for (FT_UInt i = 0; i < pFtMMVar->num_axis; ++i)
             {
-                m_aVariations[i].tag = pFtMMVar->axis[i].tag;
-                m_aVariations[i].value = instance->coords[i] / 65536.0;
+                (*mxVariations)[i].tag = pFtMMVar->axis[i].tag;
+                (*mxVariations)[i].value = instance->coords[i] / 65536.0;
             }
         }
         dlFT_Done_MM_Var(aLibFT, pFtMMVar);
     }
 
-    return m_aVariations;
+    return *mxVariations;
 }
 
 // FreetypeFont
diff --git a/vcl/win/gdi/salfont.cxx b/vcl/win/gdi/salfont.cxx
index 986b09433da1..8719829ee8d4 100644
--- a/vcl/win/gdi/salfont.cxx
+++ b/vcl/win/gdi/salfont.cxx
@@ -566,10 +566,11 @@ IDWriteFontFace* WinFontFace::GetDWFontFace() const
     return mxDWFontFace;
 }
 
-std::vector<hb_variation_t> WinFontFace::GetVariations() const
+const std::vector<hb_variation_t>& WinFontFace::GetVariations() const
 {
-    if (m_aVariations.empty())
+    if (!mxVariations)
     {
+        mxVariations.emplace();
         auto pDWFontFace = WinFontFace::GetDWFontFace();
         if (pDWFontFace)
         {
@@ -583,16 +584,16 @@ std::vector<hb_variation_t> WinFontFace::GetVariations() 
const
                 hr = xDWFontFace5->GetFontAxisValues(aAxisValues.data(), 
aAxisValues.size());
                 if (SUCCEEDED(hr))
                 {
-                    m_aVariations.reserve(aAxisValues.size());
+                    mxVariations->reserve(aAxisValues.size());
                     for (auto& rAxisValue : aAxisValues)
-                        m_aVariations.push_back(
+                        mxVariations->push_back(
                             { OSL_NETDWORD(rAxisValue.axisTag), 
rAxisValue.value });
                 }
             }
         }
     }
 
-    return m_aVariations;
+    return *mxVariations;
 }
 
 namespace

Reply via email to