vcl/inc/font/LogicalFontInstance.hxx    |   17 +++++++++++++++++
 vcl/source/font/LogicalFontInstance.cxx |   11 +++++++++++
 vcl/source/gdi/pdfwriter_impl.cxx       |   16 ++--------------
 3 files changed, 30 insertions(+), 14 deletions(-)

New commits:
commit fa1835db77b38047d8c3cea7041d38762c329867
Author:     Khaled Hosny <kha...@aliftype.com>
AuthorDate: Mon Sep 5 19:18:36 2022 +0200
Commit:     خالد حسني <kha...@aliftype.com>
CommitDate: Mon Sep 5 20:13:57 2022 +0200

    vcl: Add LogicalFontInstance::GetUnscaledGLyphWidth()
    
    To get glyph width in font units (i.e. scaled at font units per EM), and
    use it in PDF export.
    
    First step towards dropping SalGraphics::GetGlyphWidths().
    
    Change-Id: Ic0ef165e8aed6f94caf68bf01ef7ecc0620ce7c7
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/139448
    Tested-by: Jenkins
    Reviewed-by: خالد حسني <kha...@aliftype.com>

diff --git a/vcl/inc/font/LogicalFontInstance.hxx 
b/vcl/inc/font/LogicalFontInstance.hxx
index 8187ccc2e7e0..7e3adcb3e15e 100644
--- a/vcl/inc/font/LogicalFontInstance.hxx
+++ b/vcl/inc/font/LogicalFontInstance.hxx
@@ -100,6 +100,8 @@ public: // TODO: make data members private
     bool GetGlyphBoundRect(sal_GlyphId, tools::Rectangle&, bool) const;
     virtual bool GetGlyphOutline(sal_GlyphId, basegfx::B2DPolyPolygon&, bool) 
const = 0;
 
+    sal_Int32 GetUnscaledGlyphWidth(sal_GlyphId, bool) const;
+
     int GetKashidaWidth() const;
 
     void GetScale(double* nXScale, double* nYScale) const;
@@ -128,6 +130,7 @@ private:
     mutable ImplFontCache* mpFontCache;
     const vcl::font::FontSelectPattern m_aFontSelData;
     hb_font_t* m_pHbFont;
+    hb_font_t* m_pUnscaledHbFont;
     double m_nAveWidthFactor;
     rtl::Reference<vcl::font::PhysicalFontFace> m_pFontFace;
     std::optional<bool> m_xbIsGraphiteFont;
@@ -140,6 +143,8 @@ private:
 
     // The value is initialized and used in NeedOffsetCorrection().
     std::optional<FontFamilyEnum> m_xeFontFamilyEnum;
+
+    inline hb_font_t* GetUnscaledHbFont();
 };
 
 inline hb_font_t* LogicalFontInstance::GetHbFont()
@@ -149,4 +154,16 @@ inline hb_font_t* LogicalFontInstance::GetHbFont()
     return m_pHbFont;
 }
 
+inline hb_font_t* LogicalFontInstance::GetUnscaledHbFont()
+{
+    if (!m_pUnscaledHbFont)
+    {
+        auto* pHbFont = GetHbFont();
+        auto nUPEM = hb_face_get_upem(hb_font_get_face(pHbFont));
+        m_pUnscaledHbFont = hb_font_create_sub_font(pHbFont);
+        hb_font_set_scale(m_pUnscaledHbFont, nUPEM, nUPEM);
+    }
+    return m_pUnscaledHbFont;
+}
+
 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/vcl/source/font/LogicalFontInstance.cxx 
b/vcl/source/font/LogicalFontInstance.cxx
index 0936bb7286b9..542a814fb9ac 100644
--- a/vcl/source/font/LogicalFontInstance.cxx
+++ b/vcl/source/font/LogicalFontInstance.cxx
@@ -37,6 +37,7 @@ LogicalFontInstance::LogicalFontInstance(const 
vcl::font::PhysicalFontFace& rFon
     , mpFontCache(nullptr)
     , m_aFontSelData(rFontSelData)
     , m_pHbFont(nullptr)
+    , m_pUnscaledHbFont(nullptr)
     , m_nAveWidthFactor(1.0f)
     , m_pFontFace(&const_cast<vcl::font::PhysicalFontFace&>(rFontFace))
 {
@@ -50,6 +51,8 @@ LogicalFontInstance::~LogicalFontInstance()
 
     if (m_pHbFont)
         hb_font_destroy(m_pHbFont);
+    if (m_pUnscaledHbFont)
+        hb_font_destroy(m_pUnscaledHbFont);
 }
 
 hb_font_t* LogicalFontInstance::InitHbFont()
@@ -150,6 +153,14 @@ bool LogicalFontInstance::GetGlyphBoundRect(sal_GlyphId 
nID, tools::Rectangle& r
     return res;
 }
 
+sal_Int32 LogicalFontInstance::GetUnscaledGlyphWidth(sal_GlyphId nGlyph, bool 
bVertical) const
+{
+    auto* pHbFont = 
const_cast<LogicalFontInstance*>(this)->GetUnscaledHbFont();
+    if (bVertical)
+        hb_font_get_glyph_v_advance(pHbFont, nGlyph);
+    return hb_font_get_glyph_h_advance(pHbFont, nGlyph);
+}
+
 bool LogicalFontInstance::IsGraphiteFont()
 {
     if (!m_xbIsGraphiteFont)
diff --git a/vcl/source/gdi/pdfwriter_impl.cxx 
b/vcl/source/gdi/pdfwriter_impl.cxx
index f1c01944a48f..dc5e443374ba 100644
--- a/vcl/source/gdi/pdfwriter_impl.cxx
+++ b/vcl/source/gdi/pdfwriter_impl.cxx
@@ -3905,13 +3905,7 @@ void PDFWriterImpl::createDefaultCheckBoxAppearance( 
PDFWidget& rBox, const PDFW
     const GlyphItem aItem(0, 0, pMap->GetGlyphIndex(cMark),
                           DevicePoint(), GlyphItemFlags::NONE, 0, 0, 0);
     const std::vector<sal_Ucs> aCodeUnits={ cMark };
-    sal_Int32 nGlyphWidth = 0;
-    SalGraphics *pGraphics = GetGraphics();
-    if (pGraphics)
-        nGlyphWidth = m_aFontCache.getGlyphWidth(pDevFont,
-                                                 aItem.glyphId(),
-                                                 aItem.IsVertical(),
-                                                 pGraphics);
+    sal_Int32 nGlyphWidth = 
GetFontInstance()->GetUnscaledGlyphWidth(aItem.glyphId(), aItem.IsVertical());
 
     sal_uInt8 nMappedGlyph;
     sal_Int32 nMappedFontObject;
@@ -6302,13 +6296,7 @@ void PDFWriterImpl::drawLayout( SalLayout& rLayout, 
const OUString& rText, bool
 
         assert(!aCodeUnits.empty() || bUseActualText || pGlyph->IsInCluster());
 
-        sal_Int32 nGlyphWidth = 0;
-        SalGraphics *pGraphics = GetGraphics();
-        if (pGraphics)
-            nGlyphWidth = m_aFontCache.getGlyphWidth(pFont,
-                                                     pGlyph->glyphId(),
-                                                     pGlyph->IsVertical(),
-                                                     pGraphics);
+        sal_Int32 nGlyphWidth = 
GetFontInstance()->GetUnscaledGlyphWidth(pGlyph->glyphId(), 
pGlyph->IsVertical());
 
         sal_uInt8 nMappedGlyph;
         sal_Int32 nMappedFontObject;

Reply via email to