vcl/inc/font/LogicalFontInstance.hxx    |    2 ++
 vcl/source/font/LogicalFontInstance.cxx |   28 +++++++++++++++++++++++-----
 vcl/source/gdi/pdfwriter_impl.cxx       |   19 ++++---------------
 3 files changed, 29 insertions(+), 20 deletions(-)

New commits:
commit 60fd694ac362e9314f54fa992e31e8baa5bdf80f
Author:     Khaled Hosny <kha...@aliftype.com>
AuthorDate: Tue Sep 6 00:56:37 2022 +0200
Commit:     خالد حسني <kha...@aliftype.com>
CommitDate: Tue Sep 6 15:05:39 2022 +0200

    vcl: Add LogicalFontInstance::GetGlyphWidth()
    
    To be used it in PDF export where we need the unshaped glyph width to
    calculate PDF glyph adjustments.
    
    Getting the advances from HarfBuzz instead of reading them font the font
    makes sure we are always getting the correct values (e.g. when
    using variable fonts, though we still don’t correctly embed them in
    PDF).
    
    Change-Id: I91365a1580d3848c2f93044adcb366fd01173155
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/139462
    Tested-by: Jenkins
    Reviewed-by: خالد حسني <kha...@aliftype.com>

diff --git a/vcl/inc/font/LogicalFontInstance.hxx 
b/vcl/inc/font/LogicalFontInstance.hxx
index 8187ccc2e7e0..c08e3e5bc937 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;
 
+    double GetGlyphWidth(sal_GlyphId, bool = false, bool = false) const;
+
     int GetKashidaWidth() const;
 
     void GetScale(double* nXScale, double* nYScale) const;
diff --git a/vcl/source/font/LogicalFontInstance.cxx 
b/vcl/source/font/LogicalFontInstance.cxx
index 0936bb7286b9..611c84f44610 100644
--- a/vcl/source/font/LogicalFontInstance.cxx
+++ b/vcl/source/font/LogicalFontInstance.cxx
@@ -71,11 +71,7 @@ int LogicalFontInstance::GetKashidaWidth() const
     hb_codepoint_t nIndex = 0;
 
     if (hb_font_get_glyph(pHbFont, 0x0640, 0, &nIndex))
-    {
-        double nXScale = 0;
-        GetScale(&nXScale, nullptr);
-        nWidth = std::ceil(hb_font_get_glyph_h_advance(pHbFont, nIndex) * 
nXScale);
-    }
+        nWidth = std::ceil(GetGlyphWidth(nIndex));
 
     return nWidth;
 }
@@ -150,6 +146,28 @@ bool LogicalFontInstance::GetGlyphBoundRect(sal_GlyphId 
nID, tools::Rectangle& r
     return res;
 }
 
+double LogicalFontInstance::GetGlyphWidth(sal_GlyphId nGlyph, bool bVertical, 
bool bPDF) const
+{
+    auto* pHbFont = const_cast<LogicalFontInstance*>(this)->GetHbFont();
+    int nWidth;
+    if (bVertical)
+        nWidth = hb_font_get_glyph_v_advance(pHbFont, nGlyph);
+    else
+        nWidth = hb_font_get_glyph_h_advance(pHbFont, nGlyph);
+
+    if (bPDF)
+    {
+        unsigned int nUPEM = hb_face_get_upem(hb_font_get_face(pHbFont));
+        return (nWidth * 1000) / nUPEM;
+    }
+    else
+    {
+        double nScale = 0;
+        GetScale(&nScale, nullptr);
+        return double(nWidth * nScale);
+    }
+}
+
 bool LogicalFontInstance::IsGraphiteFont()
 {
     if (!m_xbIsGraphiteFont)
diff --git a/vcl/source/gdi/pdfwriter_impl.cxx 
b/vcl/source/gdi/pdfwriter_impl.cxx
index 9fe9dab2ecd8..76c47b54ba45 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);
+    auto nGlyphWidth = pFontInstance->GetGlyphWidth(aItem.glyphId(), 
aItem.IsVertical(), true);
 
     sal_uInt8 nMappedGlyph;
     sal_Int32 nMappedFontObject;
@@ -6240,13 +6234,14 @@ void PDFWriterImpl::drawLayout( SalLayout& rLayout, 
const OUString& rText, bool
     const vcl::font::PhysicalFontFace* pDevFont = 
GetFontInstance()->GetFontFace();
     const GlyphItem* pGlyph = nullptr;
     const vcl::font::PhysicalFontFace* pFallbackFont = nullptr;
+    const LogicalFontInstance* pGlyphFont = nullptr;
 
     // collect the glyphs into a single array
     std::vector< PDFGlyph > aGlyphs;
     aGlyphs.reserve( nMaxGlyphs );
     // first get all the glyphs and register them; coordinates still in Pixel
     DevicePoint aPos;
-    while (rLayout.GetNextGlyph(&pGlyph, aPos, nIndex, nullptr, 
&pFallbackFont))
+    while (rLayout.GetNextGlyph(&pGlyph, aPos, nIndex, &pGlyphFont, 
&pFallbackFont))
     {
         const auto* pFont = pFallbackFont ? pFallbackFont : pDevFont;
 
@@ -6302,13 +6297,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);
+        auto nGlyphWidth = pGlyphFont->GetGlyphWidth(pGlyph->glyphId(), 
pGlyph->IsVertical(), true);
 
         sal_uInt8 nMappedGlyph;
         sal_Int32 nMappedFontObject;

Reply via email to