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

New commits:
commit e5a797a9beb03b9d9759a94b98107f509a0d5488
Author:     Khaled Hosny <kha...@aliftype.com>
AuthorDate: Sun Sep 18 13:04:05 2022 +0200
Commit:     خالد حسني <kha...@aliftype.com>
CommitDate: Mon Sep 19 13:38:52 2022 +0200

    vcl: Fix Type 3 glyph widths
    
    It seems we need the values to be in unscaled font units not PS units.
    Modify LogicalFontInstance::GetGlyphWidth() to return unscaled values
    when requested and the TT-to-PS conversion conditionally in PDFWriter.
    
    Change-Id: I94e7cdc0ecf842a0cf87fddaa4467966f698ae3d
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/140126
    Tested-by: Jenkins
    Reviewed-by: خالد حسني <kha...@aliftype.com>

diff --git a/vcl/inc/font/LogicalFontInstance.hxx 
b/vcl/inc/font/LogicalFontInstance.hxx
index d1f19760a9a3..21c09dbafca0 100644
--- a/vcl/inc/font/LogicalFontInstance.hxx
+++ b/vcl/inc/font/LogicalFontInstance.hxx
@@ -102,7 +102,7 @@ public: // TODO: make data members private
 
     sal_GlyphId GetGlyphIndex(uint32_t, uint32_t = 0) const;
 
-    double GetGlyphWidth(sal_GlyphId, bool = false, bool = false) const;
+    double GetGlyphWidth(sal_GlyphId, bool = false, bool = true) const;
 
     int GetKashidaWidth() const;
 
diff --git a/vcl/source/font/LogicalFontInstance.cxx 
b/vcl/source/font/LogicalFontInstance.cxx
index b882ce93dfe4..6124d41b3dba 100644
--- a/vcl/source/font/LogicalFontInstance.cxx
+++ b/vcl/source/font/LogicalFontInstance.cxx
@@ -150,7 +150,7 @@ sal_GlyphId LogicalFontInstance::GetGlyphIndex(uint32_t 
nUnicode, uint32_t nVari
     return 0;
 }
 
-double LogicalFontInstance::GetGlyphWidth(sal_GlyphId nGlyph, bool bVertical, 
bool bPDF) const
+double LogicalFontInstance::GetGlyphWidth(sal_GlyphId nGlyph, bool bVertical, 
bool bScale) const
 {
     auto* pHbFont = const_cast<LogicalFontInstance*>(this)->GetHbFont();
     int nWidth;
@@ -159,16 +159,12 @@ double LogicalFontInstance::GetGlyphWidth(sal_GlyphId 
nGlyph, bool bVertical, bo
     else
         nWidth = hb_font_get_glyph_h_advance(pHbFont, nGlyph);
 
-    if (bPDF)
-    {
-        return (nWidth * 1000) / GetFontFace()->UnitsPerEm();
-    }
-    else
-    {
-        double nScale = 0;
-        GetScale(&nScale, nullptr);
-        return double(nWidth * nScale);
-    }
+    if (!bScale)
+        return nWidth;
+
+    double nScale = 0;
+    GetScale(&nScale, nullptr);
+    return double(nWidth * nScale);
 }
 
 bool LogicalFontInstance::IsGraphiteFont()
diff --git a/vcl/source/gdi/pdfwriter_impl.cxx 
b/vcl/source/gdi/pdfwriter_impl.cxx
index 61729e7e07b4..cc0fedd8cdc9 100644
--- a/vcl/source/gdi/pdfwriter_impl.cxx
+++ b/vcl/source/gdi/pdfwriter_impl.cxx
@@ -2313,6 +2313,12 @@ sal_Int32 PDFWriterImpl::emitBuildinFont(const 
pdf::BuildinFontFace* pFD, sal_In
     return nFontObject;
 }
 
+namespace
+{
+// Translate units from TT to PS (standard 1/1000)
+int XUnits(int nUPEM, int n) { return (n * 1000) / nUPEM; }
+}
+
 std::map< sal_Int32, sal_Int32 > PDFWriterImpl::emitSystemFont( const 
vcl::font::PhysicalFontFace* pFont, EmbedFont const & rEmbed )
 {
     std::map< sal_Int32, sal_Int32 > aRet;
@@ -2330,10 +2336,11 @@ std::map< sal_Int32, sal_Int32 > 
PDFWriterImpl::emitSystemFont( const vcl::font:
 
     sal_Int32 pWidths[256] = { 0 };
     const LogicalFontInstance* pFontInstance = rEmbed.m_pFontInstance;
+    auto nUPEM = pFont->UnitsPerEm();
     for( sal_Ucs c = 32; c < 256; c++ )
     {
         sal_GlyphId nGlyph = pFontInstance->GetGlyphIndex(c);
-        pWidths[c] = pFontInstance->GetGlyphWidth(nGlyph, false, true);
+        pWidths[c] = XUnits(nUPEM, pFontInstance->GetGlyphWidth(nGlyph, false, 
false));
     }
 
     // We are interested only in filling aInfo
@@ -4072,7 +4079,7 @@ void PDFWriterImpl::createDefaultCheckBoxAppearance( 
PDFWidget& rBox, const PDFW
     // make sure OpenSymbol is embedded, and includes our checkmark
     const sal_Unicode cMark=0x2713;
     const auto nGlyphId = pFontInstance->GetGlyphIndex(cMark);
-    const auto nGlyphWidth = pFontInstance->GetGlyphWidth(nGlyphId, false, 
true);
+    const auto nGlyphWidth = pFontInstance->GetGlyphWidth(nGlyphId, false, 
false);
 
     sal_uInt8 nMappedGlyph;
     sal_Int32 nMappedFontObject;
@@ -6006,7 +6013,7 @@ void PDFWriterImpl::registerGlyph(const sal_GlyphId 
nFontGlyphId,
         // add new glyph to emitted font subset
         GlyphEmit& rNewGlyphEmit = rSubset.m_aSubsets.back().m_aMapping[ 
nFontGlyphId ];
         rNewGlyphEmit.setGlyphId( nNewId );
-        rNewGlyphEmit.setGlyphWidth( nGlyphWidth );
+        rNewGlyphEmit.setGlyphWidth(XUnits(pFont->UnitsPerEm(), nGlyphWidth));
         for (const auto nCode : rCodeUnits)
             rNewGlyphEmit.addCode(nCode);
 
@@ -6533,7 +6540,7 @@ void PDFWriterImpl::drawLayout( SalLayout& rLayout, const 
OUString& rText, bool
 
         assert(!aCodeUnits.empty() || bUseActualText || pGlyph->IsInCluster());
 
-        auto nGlyphWidth = pGlyphFont->GetGlyphWidth(nGlyphId, 
pGlyph->IsVertical(), true);
+        auto nGlyphWidth = pGlyphFont->GetGlyphWidth(nGlyphId, 
pGlyph->IsVertical(), false);
 
         sal_uInt8 nMappedGlyph;
         sal_Int32 nMappedFontObject;
@@ -6545,7 +6552,7 @@ void PDFWriterImpl::drawLayout( SalLayout& rLayout, const 
OUString& rText, bool
 
         aGlyphs.emplace_back(aPos,
                              pGlyph,
-                             nGlyphWidth,
+                             XUnits(pFont->UnitsPerEm(), nGlyphWidth),
                              nMappedFontObject,
                              nMappedGlyph,
                              nCharPos);

Reply via email to