[Libreoffice-commits] core.git: Branch 'feature/drop-findcmap' - 4 commits - include/vcl vcl/inc vcl/qt5 vcl/quartz vcl/source vcl/win

Jan-Marek Glogowski (via logerrit) logerrit at kemper.freedesktop.org
Sat Sep 12 03:55:34 UTC 2020


Rebased ref, commits from common ancestor:
commit ae879f7cc2fe1e23f070d9b35d31a273d9862ea4
Author:     Jan-Marek Glogowski <glogow at fbihome.de>
AuthorDate: Fri Sep 11 22:34:11 2020 +0200
Commit:     Jan-Marek Glogowski <glogow at fbihome.de>
CommitDate: Sat Sep 12 05:54:56 2020 +0200

    Qt5 implement GetGlyphWidths
    
    Basically implement it the same way then Windows and MacOS.
    
    Change-Id: I643581af49aeb9274505e90e12acbe5bcf0c98fb

diff --git a/vcl/qt5/Qt5Graphics_Text.cxx b/vcl/qt5/Qt5Graphics_Text.cxx
index 39d117b8ca12..26b09b8bdc26 100644
--- a/vcl/qt5/Qt5Graphics_Text.cxx
+++ b/vcl/qt5/Qt5Graphics_Text.cxx
@@ -297,9 +297,13 @@ const void* Qt5Graphics::GetEmbedFontData(const PhysicalFontFace*, long* /*pData
 
 void Qt5Graphics::FreeEmbedFontData(const void* /*pData*/, long /*nDataLen*/) {}
 
-void Qt5Graphics::GetGlyphWidths(const PhysicalFontFace* /*pPFF*/, bool /*bVertical*/,
-                                 std::vector<sal_Int32>& /*rWidths*/, Ucs2UIntMap& /*rUnicodeEnc*/)
+void Qt5Graphics::GetGlyphWidths(const PhysicalFontFace* pFontFace, bool bVertical,
+                                 std::vector<sal_Int32>& rWidths, Ucs2UIntMap& rUnicodeEnc)
 {
+    const Qt5FontFace* pQt5FontFace = static_cast<const Qt5FontFace*>(pFontFace);
+    const QRawFont aRawFont(QRawFont::fromFont(pQt5FontFace->CreateFont()));
+    Qt5TrueTypeFont aTTF(*pQt5FontFace, aRawFont);
+    SalGraphics::GetGlyphWidths(aTTF, *pFontFace, bVertical, rWidths, rUnicodeEnc);
 }
 
 namespace
commit 69b02e1db6025123d6168f3e62ab7b381e5a63c3
Author:     Jan-Marek Glogowski <glogow at fbihome.de>
AuthorDate: Fri Sep 11 22:31:51 2020 +0200
Commit:     Jan-Marek Glogowski <glogow at fbihome.de>
CommitDate: Sat Sep 12 05:54:55 2020 +0200

    Forward existing FontCharMap from PhysicalFontFace
    
    Since removed code in the previous commit is primary used in
    CreateFontSubset and GetGlyphWidths, you have a high chance, that
    the CMAP was already used for displaying a font, so it's already
    decoded and can be forwarded. Also the lookup should be faster in
    general this way.
    
    Change-Id: Icf4d8a1a84ff6ccdaccb7e870abe5df3837f9541

diff --git a/vcl/inc/sft.hxx b/vcl/inc/sft.hxx
index bcbf74b07aa1..86cb718809b3 100644
--- a/vcl/inc/sft.hxx
+++ b/vcl/inc/sft.hxx
@@ -470,11 +470,13 @@ class TrueTypeFont;
  * @param  nLen    - size of memory buffer
  * @param  facenum - logical font number within a TTC file. This value is ignored
  *                   for TrueType fonts
- * @param  ttf     - array of TrueTypeFonts
+ * @param  ttf     - returns the opened TrueTypeFont
+ * @param  xCharMap  - optional parsed character map
  * @return value of SFErrCodes enum
  * @ingroup sft
  */
-    SFErrCodes VCL_DLLPUBLIC OpenTTFontBuffer(const void* pBuffer, sal_uInt32 nLen, sal_uInt32 facenum, TrueTypeFont** ttf);
+    SFErrCodes VCL_DLLPUBLIC OpenTTFontBuffer(const void* pBuffer, sal_uInt32 nLen, sal_uInt32 facenum,
+                                              TrueTypeFont** ttf, const FontCharMapRef xCharMap = nullptr);
 #if !defined(_WIN32)
 /**
  * TrueTypeFont constructor.
@@ -483,11 +485,13 @@ class TrueTypeFont;
  * @param  fname   - name of TrueType font file
  * @param  facenum - logical font number within a TTC file. This value is ignored
  *                   for TrueType fonts
- * @param  ttf     - array of TrueTypeFonts
+ * @param  ttf     - returns the opened TrueTypeFont
+ * @param  xCharMap  - optional parsed character map
  * @return value of SFErrCodes enum
  * @ingroup sft
  */
-    SFErrCodes VCL_DLLPUBLIC OpenTTFontFile(const char *fname, sal_uInt32 facenum, TrueTypeFont** ttf);
+    SFErrCodes VCL_DLLPUBLIC OpenTTFontFile(const char *fname, sal_uInt32 facenum, TrueTypeFont** ttf,
+                                            const FontCharMapRef xCharMap = nullptr);
 #endif
 
     bool VCL_DLLPUBLIC getTTCoverage(
@@ -728,7 +732,7 @@ protected:
     SFErrCodes indexGlyphData();
 
 public:
-    AbstractTrueTypeFont(const char* fileName = nullptr);
+    AbstractTrueTypeFont(const char* fileName = nullptr, const FontCharMapRef xCharMap = nullptr);
     virtual ~AbstractTrueTypeFont();
 
     const char* fileName() const { return m_pFileName; }
@@ -765,7 +769,7 @@ public:
 
         sal_uInt32  ntables;
 
-    TrueTypeFont(const char* pFileName = nullptr);
+    TrueTypeFont(const char* pFileName = nullptr, const FontCharMapRef xCharMap = nullptr);
     ~TrueTypeFont() override;
 
     SFErrCodes open(sal_uInt32 facenum);
diff --git a/vcl/qt5/Qt5Graphics_Text.cxx b/vcl/qt5/Qt5Graphics_Text.cxx
index 1c137f37bfc4..39d117b8ca12 100644
--- a/vcl/qt5/Qt5Graphics_Text.cxx
+++ b/vcl/qt5/Qt5Graphics_Text.cxx
@@ -137,14 +137,15 @@ class Qt5TrueTypeFont : public vcl::AbstractTrueTypeFont
     mutable QByteArray m_aFontTable[vcl::NUM_TAGS];
 
 public:
-    Qt5TrueTypeFont(const QRawFont& aRawFont);
+    Qt5TrueTypeFont(const Qt5FontFace& aFontFace, const QRawFont& aRawFont);
 
     bool hasTable(sal_uInt32 ord) const override;
     const sal_uInt8* table(sal_uInt32 ord, sal_uInt32& size) const override;
 };
 
-Qt5TrueTypeFont::Qt5TrueTypeFont(const QRawFont& aRawFont)
-    : m_aRawFont(aRawFont)
+Qt5TrueTypeFont::Qt5TrueTypeFont(const Qt5FontFace& aFontFace, const QRawFont& aRawFont)
+    : vcl::AbstractTrueTypeFont(nullptr, aFontFace.GetFontCharMap())
+    , m_aRawFont(aRawFont)
 {
     indexGlyphData();
 }
@@ -224,7 +225,8 @@ bool Qt5Graphics::CreateFontSubset(const OUString& rToFile, const PhysicalFontFa
         return false;
 
     // get the raw-bytes from the font to be subset
-    const QFont aFont = static_cast<const Qt5FontFace*>(pFontFace)->CreateFont();
+    const Qt5FontFace* pQt5FontFace = static_cast<const Qt5FontFace*>(pFontFace);
+    const QFont aFont = pQt5FontFace->CreateFont();
     const QRawFont aRawFont(QRawFont::fromFont(aFont));
     const QFontInfo aFontInfo(aFont);
     const OString aToFile(OUStringToOString(aSysPath, osl_getThreadTextEncoding()));
@@ -237,7 +239,7 @@ bool Qt5Graphics::CreateFontSubset(const OUString& rToFile, const PhysicalFontFa
     rInfo.m_nAscent = aRawFont.ascent();
     rInfo.m_nDescent = aRawFont.descent();
 
-    Qt5TrueTypeFont aTTF(aRawFont);
+    Qt5TrueTypeFont aTTF(*pQt5FontFace, aRawFont);
     int nXmin, nYmin, nXmax, nYmax;
     sal_uInt16 nMacStyleFlags;
     if (GetTTGlobalFontHeadInfo(&aTTF, nXmin, nYmin, nXmax, nYmax, nMacStyleFlags))
diff --git a/vcl/quartz/salgdi.cxx b/vcl/quartz/salgdi.cxx
index 2c1fdff16eec..1501043924b6 100644
--- a/vcl/quartz/salgdi.cxx
+++ b/vcl/quartz/salgdi.cxx
@@ -759,7 +759,8 @@ void AquaSalGraphics::GetGlyphWidths( const PhysicalFontFace* pFontData, bool bV
 
     // use the font subsetter to get the widths
     TrueTypeFont* pSftFont = nullptr;
-    SFErrCodes nRC = ::OpenTTFontBuffer( static_cast<void*>(aBuffer.data()), aBuffer.size(), 0, &pSftFont);
+    SFErrCodes nRC = ::OpenTTFontBuffer(static_cast<void*>(aBuffer.data()), aBuffer.size(), 0, &pSftFont,
+                                        pFontData->GetFontCharMap());
     if( nRC != SFErrCodes::Ok )
         return;
 
diff --git a/vcl/source/fontsubset/sft.cxx b/vcl/source/fontsubset/sft.cxx
index 812c539d6700..6aba6d6d48d2 100644
--- a/vcl/source/fontsubset/sft.cxx
+++ b/vcl/source/fontsubset/sft.cxx
@@ -1021,7 +1021,8 @@ int CountTTCFonts(const char* fname)
 }
 
 #if !defined(_WIN32)
-SFErrCodes OpenTTFontFile( const char* fname, sal_uInt32 facenum, TrueTypeFont** ttf )
+SFErrCodes OpenTTFontFile(const char* fname, sal_uInt32 facenum, TrueTypeFont** ttf,
+                          const FontCharMapRef xCharMap)
 {
     SFErrCodes ret;
     int fd = -1;
@@ -1029,7 +1030,7 @@ SFErrCodes OpenTTFontFile( const char* fname, sal_uInt32 facenum, TrueTypeFont**
 
     if (!fname || !*fname) return SFErrCodes::BadFile;
 
-    *ttf = new TrueTypeFont(fname);
+    *ttf = new TrueTypeFont(fname, xCharMap);
     if( ! *ttf )
         return SFErrCodes::Memory;
 
@@ -1080,9 +1081,10 @@ cleanup:
 }
 #endif
 
-SFErrCodes OpenTTFontBuffer(const void* pBuffer, sal_uInt32 nLen, sal_uInt32 facenum, TrueTypeFont** ttf)
+SFErrCodes OpenTTFontBuffer(const void* pBuffer, sal_uInt32 nLen, sal_uInt32 facenum, TrueTypeFont** ttf,
+                            const FontCharMapRef xCharMap)
 {
-    *ttf = new TrueTypeFont();
+    *ttf = new TrueTypeFont(nullptr, xCharMap);
     if( *ttf == nullptr )
         return SFErrCodes::Memory;
 
@@ -1111,13 +1113,14 @@ bool withinBounds(sal_uInt32 tdoffset, sal_uInt32 moreoffset, sal_uInt32 len, sa
 }
 }
 
-AbstractTrueTypeFont::AbstractTrueTypeFont(const char* pFileName)
+AbstractTrueTypeFont::AbstractTrueTypeFont(const char* pFileName, const FontCharMapRef xCharMap)
     : m_pFileName(nullptr)
     , m_nGlyphs(0xFFFFFFFF)
     , m_pGlyphOffsets(nullptr)
     , m_nHorzMetrics(0)
     , m_nVertMetrics(0)
     , m_nUnitsPerEm(0)
+    , m_xCharMap(xCharMap)
 {
     if (pFileName)
         m_pFileName = strdup(pFileName);
@@ -1129,8 +1132,8 @@ AbstractTrueTypeFont::~AbstractTrueTypeFont()
     free(m_pGlyphOffsets);
 }
 
-TrueTypeFont::TrueTypeFont(const char* pFileName)
-    : AbstractTrueTypeFont(pFileName)
+TrueTypeFont::TrueTypeFont(const char* pFileName, const FontCharMapRef xCharMap)
+    : AbstractTrueTypeFont(pFileName, xCharMap)
     , fsize(-1)
     , ptr(nullptr)
     , psname(nullptr)
diff --git a/vcl/win/gdi/salfont.cxx b/vcl/win/gdi/salfont.cxx
index f5f69f3eab33..bc7f83b8b6f2 100644
--- a/vcl/win/gdi/salfont.cxx
+++ b/vcl/win/gdi/salfont.cxx
@@ -1543,7 +1543,7 @@ public:
 
     ~ScopedTrueTypeFont();
 
-    SFErrCodes open(void const * pBuffer, sal_uInt32 nLen, sal_uInt32 nFaceNum);
+    SFErrCodes open(void const * pBuffer, sal_uInt32 nLen, sal_uInt32 nFaceNum, const FontCharMapRef xCharMap = nullptr);
 
     TrueTypeFont * get() const { return m_pFont; }
     TrueTypeFont* operator->() { return m_pFont; }
@@ -1561,10 +1561,10 @@ ScopedTrueTypeFont::~ScopedTrueTypeFont()
 }
 
 SFErrCodes ScopedTrueTypeFont::open(void const * pBuffer, sal_uInt32 nLen,
-                             sal_uInt32 nFaceNum)
+                             sal_uInt32 nFaceNum, const FontCharMapRef xCharMap)
 {
     OSL_ENSURE(m_pFont == nullptr, "already open");
-    return OpenTTFontBuffer(pBuffer, nLen, nFaceNum, &m_pFont);
+    return OpenTTFontBuffer(pBuffer, nLen, nFaceNum, &m_pFont, xCharMap);
 }
 
 bool WinSalGraphics::CreateFontSubset( const OUString& rToFile,
@@ -1629,7 +1629,7 @@ bool WinSalGraphics::CreateFontSubset( const OUString& rToFile,
         nFaceNum = ~0U;  // indicate "TTC font extracts only"
 
     ScopedTrueTypeFont aSftTTF;
-    SFErrCodes nRC = aSftTTF.open( xRawFontData.get(), xRawFontData.size(), nFaceNum );
+    SFErrCodes nRC = aSftTTF.open( xRawFontData.get(), xRawFontData.size(), nFaceNum, pFont->GetFontCharMap());
     if( nRC != SFErrCodes::Ok )
         return false;
 
@@ -1745,7 +1745,7 @@ void WinSalGraphics::GetGlyphWidths( const PhysicalFontFace* pFont,
         nFaceNum = ~0U;  // indicate "TTC font extracts only"
 
     ScopedTrueTypeFont aSftTTF;
-    SFErrCodes nRC = aSftTTF.open( xRawFontData.get(), xRawFontData.size(), nFaceNum );
+    SFErrCodes nRC = aSftTTF.open(xRawFontData.get(), xRawFontData.size(), nFaceNum, pFont->GetFontCharMap());
     if( nRC != SFErrCodes::Ok )
         return;
 
commit b6b8b2b44d051858e6eb0ebe9d03cbb91c56d1c9
Author:     Jan-Marek Glogowski <glogow at fbihome.de>
AuthorDate: Fri Sep 11 22:07:12 2020 +0200
Commit:     Jan-Marek Glogowski <glogow at fbihome.de>
CommitDate: Sat Sep 12 05:54:55 2020 +0200

    Replace FindCmap with ParseCMAP
    
    This introduces a potential performance regression, because
    FindCmap works on the existing font tables and just sets up
    a lookup function, while ParseCMAP creates some optimized,
    unicode-only lookup table, which needs a bit more work, but
    is faster in it's usage. At least the initial usage is faster
    this way, as the CMAPs aren't decoded at all.
    
    As you can see, the old code is just used on Windows and
    MacOS / iOS. Deep in the bowels of the PrintFontManager, the
    CMAP is also decoded using ParseCMAP... so I'm not sure how
    hard this really hits.
    
    Change-Id: I52caac1264cd3ff11a2a3fa6e9c800f67f146a79

diff --git a/include/vcl/fontcharmap.hxx b/include/vcl/fontcharmap.hxx
index 2a4e1dd08ff1..f600c3e6849f 100644
--- a/include/vcl/fontcharmap.hxx
+++ b/include/vcl/fontcharmap.hxx
@@ -39,7 +39,11 @@ public:
         all codepoints in the Unicode BMP range, including surrogates.
      **/
     FontCharMap();
+
+    /** A new FontCharMap is created based on the CmapResult
+     */
     FontCharMap( const CmapResult& rCR );
+
     virtual ~FontCharMap() override;
 
     /** Get the default font character map
@@ -134,6 +138,8 @@ public:
 
     int                 GetGlyphIndex( sal_UCS4 ) const;
 
+    bool isSymbolic() const;
+
 private:
     ImplFontCharMapRef mpImplFontCharMap;
 
diff --git a/vcl/inc/impfontcharmap.hxx b/vcl/inc/impfontcharmap.hxx
index eaa99dbe2d4d..287b663b4820 100644
--- a/vcl/inc/impfontcharmap.hxx
+++ b/vcl/inc/impfontcharmap.hxx
@@ -49,6 +49,7 @@ private:
     const sal_uInt16*   mpGlyphIds;       // individual glyphid mappings
     int                 mnRangeCount;
     int                 mnCharCount;      // covered codepoints
+    const bool m_bSymbolic;
 };
 
 bool VCL_DLLPUBLIC ParseCMAP( const unsigned char* pRawData, int nRawLength, CmapResult& );
diff --git a/vcl/inc/sft.hxx b/vcl/inc/sft.hxx
index 89853335db54..bcbf74b07aa1 100644
--- a/vcl/inc/sft.hxx
+++ b/vcl/inc/sft.hxx
@@ -42,6 +42,7 @@
 
 #include <vcl/dllapi.h>
 #include <vcl/fontcapabilities.hxx>
+#include <vcl/fontcharmap.hxx>
 #include <i18nlangtag/lang.h>
 
 #include <array>
@@ -650,19 +651,6 @@ class TrueTypeFont;
  */
     VCL_DLLPUBLIC std::unique_ptr<sal_uInt16[]> GetTTSimpleGlyphMetrics(AbstractTrueTypeFont const *ttf, const sal_uInt16 *glyphArray, int nGlyphs, bool vertical);
 
-#if defined(_WIN32) || defined(MACOSX) || defined(IOS)
-/**
- * Maps a Unicode (UCS-2) character to a glyph ID and returns it. Missing glyph has
- * a glyphID of 0 so this function can be used to test if a character is encoded in the font.
- *
- * @param ttf         pointer to the TrueTypeFont structure
- * @param ch          Unicode (UCS-2) character
- * @return glyph ID, if the character is missing in the font, the return value is 0.
- * @ingroup sft
- */
-    VCL_DLLPUBLIC sal_uInt16 MapChar(TrueTypeFont const *ttf, sal_uInt16 ch);
-#endif
-
 /**
  * Returns global font information about the TrueType font.
  * @see TTGlobalFontInfo
@@ -734,6 +722,7 @@ class VCL_DLLPUBLIC AbstractTrueTypeFont
     sal_uInt32 m_nHorzMetrics;
     sal_uInt32 m_nVertMetrics; /* if not 0 => font has vertical metrics information */
     sal_uInt32 m_nUnitsPerEm;
+    FontCharMapRef m_xCharMap;
 
 protected:
     SFErrCodes indexGlyphData();
@@ -748,6 +737,7 @@ public:
     sal_uInt32 horzMetricCount() const { return m_nHorzMetrics; }
     sal_uInt32 vertMetricCount() const { return m_nVertMetrics; }
     sal_uInt32 unitsPerEm() const { return m_nUnitsPerEm; }
+    FontCharMapRef GetCharMap() const { return m_xCharMap; }
 
     virtual bool hasTable(sal_uInt32 ord) const = 0;
     virtual const sal_uInt8* table(sal_uInt32 ord, sal_uInt32& size) const = 0;
@@ -774,9 +764,6 @@ public:
         sal_Unicode *usubfamily;
 
         sal_uInt32  ntables;
-        const sal_uInt8* cmap;
-        int         cmapType;
-        sal_uInt32 (*mapper)(const sal_uInt8 *, sal_uInt32, sal_uInt32); /* character to glyphID translation function                          */
 
     TrueTypeFont(const char* pFileName = nullptr);
     ~TrueTypeFont() override;
diff --git a/vcl/source/font/fontcharmap.cxx b/vcl/source/font/fontcharmap.cxx
index 61f22f48f141..05a800fe1af7 100644
--- a/vcl/source/font/fontcharmap.cxx
+++ b/vcl/source/font/fontcharmap.cxx
@@ -54,6 +54,7 @@ ImplFontCharMap::ImplFontCharMap( const CmapResult& rCR )
 ,   mpGlyphIds( rCR.mpGlyphIds )
 ,   mnRangeCount( rCR.mnRangeCount )
 ,   mnCharCount( 0 )
+    , m_bSymbolic(rCR.mbSymbolic)
 {
     const sal_UCS4* pRangePtr = mpRangeCodes;
     for( int i = mnRangeCount; --i >= 0; pRangePtr += 2 )
@@ -429,6 +430,8 @@ bool FontCharMap::IsDefaultMap() const
     return mpImplFontCharMap->isDefaultMap();
 }
 
+bool FontCharMap::isSymbolic() const { return mpImplFontCharMap->m_bSymbolic; }
+
 int FontCharMap::GetCharCount() const
 {
     return mpImplFontCharMap->mnCharCount;
diff --git a/vcl/source/fontsubset/sft.cxx b/vcl/source/fontsubset/sft.cxx
index 6eabe8480608..812c539d6700 100644
--- a/vcl/source/fontsubset/sft.cxx
+++ b/vcl/source/fontsubset/sft.cxx
@@ -35,6 +35,7 @@
 #include <unistd.h>
 #endif
 #include <sft.hxx>
+#include <impfontcharmap.hxx>
 #include "ttcr.hxx"
 #include "xlat.hxx"
 #include <rtl/crc.h>
@@ -165,18 +166,6 @@ static sal_uInt32 GetUInt32(const sal_uInt8 *ptr, size_t offset)
     return t;
 }
 
-#if defined(OSL_BIGENDIAN)
-#define Int16FromMOTA(a) (a)
-#define Int32FromMOTA(a) (a)
-#else
-static sal_uInt16 Int16FromMOTA(sal_uInt16 a) {
-  return static_cast<sal_uInt16>(static_cast<sal_uInt8>(a >> 8) | (static_cast<sal_uInt8>(a) << 8));
-}
-static sal_uInt32 Int32FromMOTA(sal_uInt32 a) {
-  return ((a>>24)&0xFF) | (((a>>8)&0xFF00) | ((a&0xFF00)<<8) | ((a&0xFF)<<24));
-}
-#endif
-
 static F16Dot16 fixedMul(F16Dot16 a, F16Dot16 b)
 {
     unsigned int a1, b1;
@@ -1014,332 +1003,6 @@ static void GetNames(TrueTypeFont *t)
     }
 }
 
-namespace {
-
-enum cmapType {
-    CMAP_NOT_USABLE           = -1,
-    CMAP_MS_Symbol            = 10,
-    CMAP_MS_Unicode           = 11,
-    CMAP_MS_ShiftJIS          = 12,
-    CMAP_MS_PRC               = 13,
-    CMAP_MS_Big5              = 14,
-    CMAP_MS_Wansung           = 15,
-    CMAP_MS_Johab             = 16
-};
-
-}
-
-#define MISSING_GLYPH_INDEX 0
-
-static sal_uInt32 getGlyph0(const sal_uInt8* cmap, sal_uInt32, sal_uInt32 c) {
-    if (c <= 255) {
-        return *(cmap + 6 + c);
-    } else {
-        return MISSING_GLYPH_INDEX;
-    }
-}
-
-namespace {
-
-struct subHeader2 {
-    sal_uInt16 firstCode;
-    sal_uInt16 entryCount;
-    sal_uInt16 idDelta;
-    sal_uInt16 idRangeOffset;
-};
-
-}
-
-static sal_uInt32 getGlyph2(const sal_uInt8 *cmap, const sal_uInt32 nMaxCmapSize, sal_uInt32 c) {
-    sal_uInt16 const *CMAP2 = reinterpret_cast<sal_uInt16 const *>(cmap);
-    sal_uInt8 theHighByte;
-
-    sal_uInt8 theLowByte;
-    subHeader2 const * subHeader2s;
-    sal_uInt16 const * subHeader2Keys;
-    sal_uInt16 firstCode;
-    int k = -1;
-    sal_uInt32 ToReturn;
-
-    theHighByte = static_cast<sal_uInt8>((c >> 8) & 0x00ff);
-    theLowByte = static_cast<sal_uInt8>(c & 0x00ff);
-    subHeader2Keys = CMAP2 + 3;
-    subHeader2s = reinterpret_cast<subHeader2 const *>(subHeader2Keys + 256);
-    if(reinterpret_cast<sal_uInt8 const *>(&subHeader2Keys[theHighByte]) - cmap < int(nMaxCmapSize - 2))
-    {
-        k = Int16FromMOTA(subHeader2Keys[theHighByte]) / 8;
-        // check if the subheader record fits into available space
-        if(reinterpret_cast<sal_uInt8 const *>(&subHeader2s[k]) - cmap >= int(nMaxCmapSize - sizeof(subHeader2)))
-            k = -1;
-    }
-
-    if(k == 0) {
-        firstCode = Int16FromMOTA(subHeader2s[0].firstCode);
-        if(theLowByte >= firstCode && theLowByte < (firstCode + Int16FromMOTA(subHeader2s[k].entryCount))) {
-            sal_uInt16 const * pGlyph = (&(subHeader2s[0].idRangeOffset))
-                     + (Int16FromMOTA(subHeader2s[0].idRangeOffset)/2)             /* + offset        */
-                     + theLowByte                                                  /* + to_look       */
-                     - firstCode
-                     ;
-            if (reinterpret_cast<sal_uInt8 const *>(pGlyph) - cmap < int(nMaxCmapSize) - 4)
-                return *pGlyph;
-            else
-                return MISSING_GLYPH_INDEX;
-        } else {
-            return MISSING_GLYPH_INDEX;
-        }
-    } else if (k > 0) {
-        firstCode = Int16FromMOTA(subHeader2s[k].firstCode);
-        if(theLowByte >= firstCode && theLowByte < (firstCode + Int16FromMOTA(subHeader2s[k].entryCount))) {
-            ToReturn = *((&(subHeader2s[k].idRangeOffset))
-                         + (Int16FromMOTA(subHeader2s[k].idRangeOffset)/2)
-                         + theLowByte - firstCode);
-            if(ToReturn == 0) {
-                return MISSING_GLYPH_INDEX;
-            } else {
-                ToReturn += Int16FromMOTA(subHeader2s[k].idDelta);
-                return (ToReturn & 0xFFFF);
-            }
-        } else {
-            return MISSING_GLYPH_INDEX;
-        }
-    } else {
-        return MISSING_GLYPH_INDEX;
-    }
-}
-
-static sal_uInt32 getGlyph6(const sal_uInt8 *cmap, sal_uInt32, sal_uInt32 c) {
-    sal_uInt16 firstCode, lastCode, count;
-    sal_uInt16 const *CMAP6 = reinterpret_cast<sal_uInt16 const *>(cmap);
-
-    firstCode = Int16FromMOTA(*(CMAP6 + 3));
-    count = Int16FromMOTA(*(CMAP6 + 4));
-    lastCode = firstCode + count - 1;
-    if (c < firstCode || c > lastCode) {
-        return MISSING_GLYPH_INDEX;
-    } else {
-        return *((CMAP6 + 5)/*glyphIdArray*/ + (c - firstCode));
-    }
-}
-
-static sal_uInt16 GEbinsearch(sal_uInt16 const *ar, sal_uInt16 length, sal_uInt16 toSearch) {
-    signed int low, high, lastfound = 0xffff;
-    sal_uInt16 res;
-    if(length == sal_uInt16(0) || length == sal_uInt16(0xFFFF)) {
-        return sal_uInt16(0xFFFF);
-    }
-    low = 0;
-    high = length - 1;
-    while(high >= low) {
-        int mid = (high + low)/2;
-        res = Int16FromMOTA(*(ar+mid));
-        if(res >= toSearch) {
-            lastfound = mid;
-            high = --mid;
-        } else {
-            low = ++mid;
-        }
-    }
-    return static_cast<sal_uInt16>(lastfound);
-}
-
-static sal_uInt32 getGlyph4(const sal_uInt8 *cmap, const sal_uInt32 nMaxCmapSize, sal_uInt32 c) {
-    sal_uInt16  i;
-    int ToReturn;
-    sal_uInt16  segCount;
-    sal_uInt16 const * startCode;
-    sal_uInt16 const * endCode;
-    sal_uInt16 const * idDelta;
-    /* sal_uInt16 * glyphIdArray; */
-    sal_uInt16 const * idRangeOffset;
-    /*sal_uInt16 * glyphIndexArray;*/
-    sal_uInt16 const *CMAP4 = reinterpret_cast<sal_uInt16 const *>(cmap);
-    /* sal_uInt16  GEbinsearch(sal_uInt16 *ar, sal_uInt16 length, sal_uInt16 toSearch); */
-
-    segCount = Int16FromMOTA(*(CMAP4 + 3))/2;
-    endCode = CMAP4 + 7;
-    i = GEbinsearch(endCode, segCount, static_cast<sal_uInt16>(c));
-
-    if (i == sal_uInt16(0xFFFF)) {
-        return MISSING_GLYPH_INDEX;
-    }
-    startCode = endCode + segCount + 1;
-
-    if((reinterpret_cast<sal_uInt8 const *>(&startCode[i]) - cmap >= int(nMaxCmapSize - 2)) || Int16FromMOTA(startCode[i]) > c) {
-        return MISSING_GLYPH_INDEX;
-    }
-    idDelta = startCode + segCount;
-    idRangeOffset = idDelta + segCount;
-    /*glyphIndexArray = idRangeOffset + segCount;*/
-
-    if((reinterpret_cast<sal_uInt8 const *>(&idRangeOffset[i]) - cmap < int(nMaxCmapSize - 2)) && Int16FromMOTA(idRangeOffset[i]) != 0) {
-        sal_uInt16 const * pGlyphOffset = &(idRangeOffset[i]) + (Int16FromMOTA(idRangeOffset[i])/2 + (c - Int16FromMOTA(startCode[i])));
-        if(reinterpret_cast<sal_uInt8 const *>(pGlyphOffset) - cmap >= int(nMaxCmapSize - 2))
-            return MISSING_GLYPH_INDEX;
-        c = Int16FromMOTA(*pGlyphOffset);
-    }
-
-    ToReturn = (Int16FromMOTA(idDelta[i]) + c) & 0xFFFF;
-    return ToReturn;
-}
-
-static sal_uInt32 getGlyph12(const sal_uInt8 *pCmap, sal_uInt32, sal_uInt32 cChar) {
-    const sal_uInt32* pCMAP12 = reinterpret_cast<const sal_uInt32*>(pCmap);
-    int nLength = Int32FromMOTA( pCMAP12[1] );
-    int nGroups = Int32FromMOTA( pCMAP12[3] );
-    int nLower = 0;
-    int nUpper = nGroups;
-
-    if( nUpper > (nLength-16)/12 )
-        nUpper = (nLength-16)/12;
-
-    /* binary search in "segmented coverage" subtable */
-    while( nLower < nUpper ) {
-        int nIndex = (nLower + nUpper) / 2;
-        const sal_uInt32* pEntry = &pCMAP12[ 4 + 3*nIndex ];
-        sal_uInt32 cStart = Int32FromMOTA( pEntry[0] );
-        sal_uInt32 cLast  = Int32FromMOTA( pEntry[1] );
-        if( cChar < cStart )
-            nUpper = nIndex;
-        else if( cChar > cLast )
-            nLower = nIndex + 1;
-        else { /* found matching entry! */
-            sal_uInt32 nGlyph  = Int32FromMOTA( pEntry[2] );
-            nGlyph += cChar - cStart;
-            return nGlyph;
-        }
-    }
-
-    return MISSING_GLYPH_INDEX;
-}
-
-static void FindCmap(TrueTypeFont *ttf)
-{
-    sal_uInt32 table_size;
-    const sal_uInt8* table = ttf->table(O_cmap, table_size);
-    if (table_size < 4)
-    {
-        SAL_WARN("vcl.fonts", "Parsing error in " << OUString::createFromAscii(ttf->fileName()) <<
-                 "cmap table size too short");
-        return;
-    }
-    sal_uInt16 ncmaps = GetUInt16(table, 2);
-    sal_uInt32 AppleUni   = 0;              // Apple Unicode
-    sal_uInt32 ThreeZero  = 0;              /* MS Symbol            */
-    sal_uInt32 ThreeOne   = 0;              /* MS UCS-2             */
-    sal_uInt32 ThreeTwo   = 0;              /* MS ShiftJIS          */
-    sal_uInt32 ThreeThree = 0;              /* MS PRC               */
-    sal_uInt32 ThreeFour  = 0;              /* MS Big5              */
-    sal_uInt32 ThreeFive  = 0;              /* MS Wansung           */
-    sal_uInt32 ThreeSix   = 0;              /* MS Johab             */
-
-    const sal_uInt32 remaining_table_size = table_size-4;
-    const sal_uInt32 nMinRecordSize = 8;
-    const sal_uInt32 nMaxRecords = remaining_table_size / nMinRecordSize;
-    if (ncmaps > nMaxRecords)
-    {
-        SAL_WARN("vcl.fonts", "Parsing error in " << OUString::createFromAscii(ttf->fileName()) <<
-                 ": " << nMaxRecords << " max possible entries, but " <<
-                 ncmaps << " claimed, truncating");
-        ncmaps = nMaxRecords;
-    }
-
-    for (unsigned int i = 0; i < ncmaps; i++) {
-        /* sanity check, cmap entry must lie within table */
-        sal_uInt32 nLargestFixedOffsetPos = 8 + i * 8;
-        sal_uInt32 nMinSize = nLargestFixedOffsetPos + sizeof(sal_uInt32);
-        if (nMinSize > table_size)
-        {
-            SAL_WARN( "vcl.fonts", "Font " << OUString::createFromAscii(ttf->fileName()) << " claimed to have "
-                << ncmaps << " cmaps, but only space for " << i);
-            break;
-        }
-
-        sal_uInt16 pID = GetUInt16(table, 4 + i * 8);
-        sal_uInt16 eID = GetUInt16(table, 6 + i * 8);
-        sal_uInt32 offset = GetUInt32(table, nLargestFixedOffsetPos);
-
-         /* sanity check, cmap must lie within file */
-        if( (table - ttf->ptr) + offset > static_cast<sal_uInt32>(ttf->fsize) )
-            continue;
-
-        /* Unicode tables in Apple fonts */
-        if (pID == 0) {
-            AppleUni = offset;
-        }
-
-        if (pID == 3) {
-            switch (eID) {
-                case 0: ThreeZero  = offset; break;
-                case 10: // UCS-4
-                case 1: ThreeOne   = offset; break;
-                case 2: ThreeTwo   = offset; break;
-                case 3: ThreeThree = offset; break;
-                case 4: ThreeFour  = offset; break;
-                case 5: ThreeFive  = offset; break;
-                case 6: ThreeSix   = offset; break;
-            }
-        }
-    }
-
-    // fall back to AppleUnicode if there are no ThreeOne/Threezero tables
-    if( AppleUni && !ThreeZero && !ThreeOne)
-        ThreeOne = AppleUni;
-
-    if (ThreeOne) {
-        ttf->cmapType = CMAP_MS_Unicode;
-        ttf->cmap = table + ThreeOne;
-    } else if (ThreeTwo) {
-        ttf->cmapType = CMAP_MS_ShiftJIS;
-        ttf->cmap = table + ThreeTwo;
-    } else if (ThreeThree) {
-        ttf->cmapType = CMAP_MS_PRC;
-        ttf->cmap = table + ThreeThree;
-    } else if (ThreeFour) {
-        ttf->cmapType = CMAP_MS_Big5;
-        ttf->cmap = table + ThreeFour;
-    } else if (ThreeFive) {
-        ttf->cmapType = CMAP_MS_Wansung;
-        ttf->cmap = table + ThreeFive;
-    } else if (ThreeSix) {
-        ttf->cmapType = CMAP_MS_Johab;
-        ttf->cmap = table + ThreeSix;
-    } else if (ThreeZero) {
-        ttf->cmapType = CMAP_MS_Symbol;
-        ttf->cmap = table + ThreeZero;
-    } else {
-        ttf->cmapType = CMAP_NOT_USABLE;
-        ttf->cmap = nullptr;
-    }
-
-    if (ttf->cmapType != CMAP_NOT_USABLE) {
-        if( (ttf->cmap - ttf->ptr + 2U) > static_cast<sal_uInt32>(ttf->fsize) ) {
-            ttf->cmapType = CMAP_NOT_USABLE;
-            ttf->cmap = nullptr;
-        }
-    }
-
-    if (ttf->cmapType == CMAP_NOT_USABLE)        return;
-
-    switch (GetUInt16(ttf->cmap, 0)) {
-        case 0: ttf->mapper = getGlyph0; break;
-        case 2: ttf->mapper = getGlyph2; break;
-        case 4: ttf->mapper = getGlyph4; break;
-        case 6: ttf->mapper = getGlyph6; break;
-        case 12: ttf->mapper= getGlyph12; break;
-        default:
-#if OSL_DEBUG_LEVEL > 1
-            /*- if the cmap table is really broken */
-            SAL_WARN("vcl.fonts", ttf->fileName() << ": "
-                    << GetUInt16(ttf->cmap, 0)
-                    << " is not a recognized cmap format..");
-#endif
-            ttf->cmapType = CMAP_NOT_USABLE;
-            ttf->cmap = nullptr;
-            ttf->mapper = nullptr;
-    }
-}
-
 /*- Public functions */
 
 int CountTTCFonts(const char* fname)
@@ -1476,9 +1139,6 @@ TrueTypeFont::TrueTypeFont(const char* pFileName)
     , subfamily(nullptr)
     , usubfamily(nullptr)
     , ntables(0)
-    , cmap(nullptr)
-    , cmapType(0)
-    , mapper(nullptr)
 {
 }
 
@@ -1554,6 +1214,15 @@ SFErrCodes AbstractTrueTypeFont::indexGlyphData()
     table = this->table(O_vhea, table_size);
     m_nVertMetrics = (table && table_size >= 36) ? GetUInt16(table, 34) : 0;
 
+    if (!m_xCharMap.is())
+    {
+        CmapResult aCmapResult;
+        table = this->table(O_cmap, table_size);
+        if (!ParseCMAP(table, table_size, aCmapResult))
+            return SFErrCodes::TtFormat;
+        m_xCharMap = new FontCharMap(aCmapResult);
+    }
+
     return SFErrCodes::Ok;
 }
 
@@ -1695,16 +1364,11 @@ SFErrCodes TrueTypeFont::open(sal_uInt32 facenum)
     /* At this point TrueTypeFont is constructed, now need to verify the font format
        and read the basic font properties */
 
-    /* The following tables are absolutely required:
-     * maxp, head, name, cmap
-     */
-
     SFErrCodes ret = indexGlyphData();
     if (ret != SFErrCodes::Ok)
         return ret;
 
     GetNames(this);
-    FindCmap(this);
 
     return SFErrCodes::Ok;
 }
@@ -2268,33 +1932,6 @@ SFErrCodes CreateT42FromTTGlyphs(TrueTypeFont  *ttf,
     return SFErrCodes::Ok;
 }
 
-#if defined(_WIN32) || defined(MACOSX) || defined(IOS)
-sal_uInt16 MapChar(TrueTypeFont const *ttf, sal_uInt16 ch)
-{
-    switch (ttf->cmapType) {
-        case CMAP_MS_Symbol:
-        {
-            const sal_uInt32 nMaxCmapSize = ttf->ptr + ttf->fsize - ttf->cmap;
-            if( ttf->mapper == getGlyph0 && ( ch & 0xf000 ) == 0xf000 )
-                ch &= 0x00ff;
-            return static_cast<sal_uInt16>(ttf->mapper(ttf->cmap, nMaxCmapSize, ch ));
-        }
-
-        case CMAP_MS_Unicode:   break;
-        case CMAP_MS_ShiftJIS:  ch = TranslateChar12(ch); break;
-        case CMAP_MS_PRC:       ch = TranslateChar13(ch); break;
-        case CMAP_MS_Big5:      ch = TranslateChar14(ch); break;
-        case CMAP_MS_Wansung:   ch = TranslateChar15(ch); break;
-        case CMAP_MS_Johab:     ch = TranslateChar16(ch); break;
-        default:                return 0;
-    }
-    const sal_uInt32 nMaxCmapSize = ttf->ptr + ttf->fsize - ttf->cmap;
-    ch = static_cast<sal_uInt16>(ttf->mapper(ttf->cmap, nMaxCmapSize, ch));
-    return ch;
-}
-#endif
-
-
 std::unique_ptr<sal_uInt16[]> GetTTSimpleGlyphMetrics(AbstractTrueTypeFont const *ttf, const sal_uInt16 *glyphArray, int nGlyphs, bool vertical)
 {
     const sal_uInt8* pTable;
@@ -2391,7 +2028,7 @@ void GetTTGlobalFontInfo(TrueTypeFont *ttf, TTGlobalFontInfo *info)
     info->subfamily = ttf->subfamily;
     info->usubfamily = ttf->usubfamily;
     info->psname = ttf->psname;
-    info->symbolEncoded = (ttf->cmapType == CMAP_MS_Symbol);
+    info->symbolEncoded = ttf->GetCharMap()->isSymbolic();
 
     sal_uInt32 table_size;
     const sal_uInt8* table = ttf->table(O_OS2, table_size);
diff --git a/vcl/source/gdi/salgdilayout.cxx b/vcl/source/gdi/salgdilayout.cxx
index f7958a661965..752e30422ffa 100644
--- a/vcl/source/gdi/salgdilayout.cxx
+++ b/vcl/source/gdi/salgdilayout.cxx
@@ -938,7 +938,7 @@ void SalGraphics::GetGlyphWidths(const vcl::AbstractTrueTypeFont& rTTF, const Ph
             continue;
 
         sal_Ucs nUcsChar = static_cast<sal_Ucs>(nChar);
-        sal_uInt32 nGlyph = ::MapChar(&rTTF, nUcsChar);
+        sal_uInt32 nGlyph = xFCMap->GetGlyphIndex(nUcsChar);
         if (nGlyph > 0)
             rUnicodeEnc[nUcsChar] = nGlyph;
     }
commit 81f33c397f122c086dfbb6718f097522b49008b1
Author:     Jan-Marek Glogowski <glogow at fbihome.de>
AuthorDate: Fri Sep 11 17:24:59 2020 +0200
Commit:     Jan-Marek Glogowski <glogow at fbihome.de>
CommitDate: Sat Sep 12 05:54:55 2020 +0200

    WIN OSX unify GetGlyphWidths code
    
    Now that GetFontChatMap is a member of PhysicalFontFace, we can
    copy the common part of both architectures into a SalGraphics
    helper function.
    
    Change-Id: Iad379ea690a1c5346b69b5042188506ccf575cc2

diff --git a/vcl/inc/salgdi.hxx b/vcl/inc/salgdi.hxx
index d2b92c65110f..15f0b519f7c6 100644
--- a/vcl/inc/salgdi.hxx
+++ b/vcl/inc/salgdi.hxx
@@ -54,6 +54,11 @@ namespace basegfx {
     class B2DPolyPolygon;
 }
 
+namespace vcl
+{
+class AbstractTrueTypeFont;
+}
+
 typedef sal_Unicode sal_Ucs; // TODO: use sal_UCS4 instead of sal_Unicode
 typedef std::map< sal_Ucs, sal_uInt32 >   Ucs2UIntMap;
 
@@ -613,6 +618,10 @@ protected:
 
     std::unique_ptr<vcl::WidgetDrawInterface> m_pWidgetDraw;
     vcl::WidgetDrawInterface* forWidget() { return m_pWidgetDraw ? m_pWidgetDraw.get() : this; }
+
+    static void GetGlyphWidths(const vcl::AbstractTrueTypeFont& rTTF, const PhysicalFontFace& rFontFace,
+                               bool bVertical, std::vector< sal_Int32 >& rWidths,
+                               Ucs2UIntMap& rUnicodeEnc) const;
 };
 
 bool SalGraphics::IsNativeControlSupported(ControlType eType, ControlPart ePart)
diff --git a/vcl/quartz/salgdi.cxx b/vcl/quartz/salgdi.cxx
index 4cab7731eca5..2c1fdff16eec 100644
--- a/vcl/quartz/salgdi.cxx
+++ b/vcl/quartz/salgdi.cxx
@@ -763,51 +763,7 @@ void AquaSalGraphics::GetGlyphWidths( const PhysicalFontFace* pFontData, bool bV
     if( nRC != SFErrCodes::Ok )
         return;
 
-    const int nGlyphCount = pSftFont->glyphCount();
-    if( nGlyphCount > 0 )
-    {
-        // get glyph metrics
-        rGlyphWidths.resize(nGlyphCount);
-        std::vector<sal_uInt16> aGlyphIds(nGlyphCount);
-        for( int i = 0; i < nGlyphCount; i++ )
-        {
-            aGlyphIds[i] = static_cast<sal_uInt16>(i);
-        }
-
-        std::unique_ptr<sal_uInt16[]> pGlyphMetrics = ::GetTTSimpleGlyphMetrics( pSftFont, aGlyphIds.data(),
-                                                                               nGlyphCount, bVertical );
-        if( pGlyphMetrics )
-        {
-            for( int i = 0; i < nGlyphCount; ++i )
-            {
-                rGlyphWidths[i] = pGlyphMetrics[i];
-            }
-            pGlyphMetrics.reset();
-        }
-
-        rtl::Reference<CoreTextFontFace> rCTFontData(new CoreTextFontFace(*pFontData, pFontData->GetFontId()));
-        FontCharMapRef xFCMap = rCTFontData->GetFontCharMap();
-        SAL_WARN_IF( !xFCMap.is() || !xFCMap->GetCharCount(), "vcl", "no charmap" );
-
-        // get unicode<->glyph encoding
-        // TODO? avoid sft mapping by using the xFCMap itself
-        int nCharCount = xFCMap->GetCharCount();
-        sal_uInt32 nChar = xFCMap->GetFirstChar();
-        for( ; --nCharCount >= 0; nChar = xFCMap->GetNextChar( nChar ) )
-        {
-            if( nChar > 0xFFFF ) // TODO: allow UTF-32 chars
-                break;
-
-            sal_Ucs nUcsChar = static_cast<sal_Ucs>(nChar);
-            sal_uInt32 nGlyph = ::MapChar( pSftFont, nUcsChar );
-            if( nGlyph > 0 )
-            {
-                rUnicodeEnc[ nUcsChar ] = nGlyph;
-            }
-        }
-
-        xFCMap = nullptr;
-    }
+    SalGraphics::GetGlyphWidths(*pSftFont, *pFontData, bVertical, rGlyphWidths, rUnicodeEnc);
 
     ::CloseTTFont( pSftFont );
 }
diff --git a/vcl/source/gdi/salgdilayout.cxx b/vcl/source/gdi/salgdilayout.cxx
index 21844bff732a..f7958a661965 100644
--- a/vcl/source/gdi/salgdilayout.cxx
+++ b/vcl/source/gdi/salgdilayout.cxx
@@ -28,8 +28,10 @@
 #include <svsys.h>
 #endif
 #endif
+#include <PhysicalFontFace.hxx>
 #include <salgdi.hxx>
 #include <salframe.hxx>
+#include <sft.hxx>
 #include <basegfx/matrix/b2dhommatrix.hxx>
 #include <basegfx/matrix/b2dhommatrixtools.hxx>
 #include <FileDefinitionWidgetDraw.hxx>
@@ -894,4 +896,52 @@ OUString SalGraphics::getRenderBackendName() const
     return OUString();
 }
 
+void SalGraphics::GetGlyphWidths(const vcl::AbstractTrueTypeFont& rTTF, const PhysicalFontFace& rFontFace,
+                                 const bool bVertical, std::vector< sal_Int32 >& rWidths,
+                                 Ucs2UIntMap& rUnicodeEnc) const
+{
+    rWidths.clear();
+    rUnicodeEnc.clear();
+
+    const int nGlyphCount = rTTF.glyphCount();
+    if (nGlyphCount <= 0)
+        return;
+
+    FontCharMapRef xFCMap = rFontFace.GetFontCharMap();
+    if (!xFCMap.is() || !xFCMap->GetCharCount())
+    {
+        SAL_WARN("vcl.fonts", "no charmap");
+        return;
+    }
+
+    // get glyph metrics
+    rWidths.resize(nGlyphCount);
+    std::vector<sal_uInt16> aGlyphIds(nGlyphCount);
+    for (int i = 0; i < nGlyphCount; i++)
+        aGlyphIds[i] = static_cast<sal_uInt16>(i);
+
+    std::unique_ptr<sal_uInt16[]> pGlyphMetrics
+        = GetTTSimpleGlyphMetrics(&rTTF, aGlyphIds.data(), nGlyphCount, bVertical);
+    if (pGlyphMetrics)
+    {
+        for (int i = 0; i < nGlyphCount; ++i)
+            rWidths[i] = pGlyphMetrics[i];
+        pGlyphMetrics.reset();
+    }
+
+    // get unicode<->glyph encoding
+    int nCharCount = xFCMap->GetCharCount();
+    sal_uInt32 nChar = xFCMap->GetFirstChar();
+    for (; --nCharCount >= 0; nChar = xFCMap->GetNextChar(nChar))
+    {
+        if (nChar > 0xFFFF)
+            continue;
+
+        sal_Ucs nUcsChar = static_cast<sal_Ucs>(nChar);
+        sal_uInt32 nGlyph = ::MapChar(&rTTF, nUcsChar);
+        if (nGlyph > 0)
+            rUnicodeEnc[nUcsChar] = nGlyph;
+    }
+}
+
 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/vcl/win/gdi/salfont.cxx b/vcl/win/gdi/salfont.cxx
index 4dac58aaafb2..f5f69f3eab33 100644
--- a/vcl/win/gdi/salfont.cxx
+++ b/vcl/win/gdi/salfont.cxx
@@ -1749,44 +1749,7 @@ void WinSalGraphics::GetGlyphWidths( const PhysicalFontFace* pFont,
     if( nRC != SFErrCodes::Ok )
         return;
 
-    int nGlyphs = aSftTTF->glyphCount();
-    if( nGlyphs > 0 )
-    {
-        rWidths.resize(nGlyphs);
-        std::vector<sal_uInt16> aGlyphIds(nGlyphs);
-        for( int i = 0; i < nGlyphs; i++ )
-            aGlyphIds[i] = sal_uInt16(i);
-        std::unique_ptr<sal_uInt16[]> pMetrics = ::GetTTSimpleGlyphMetrics( aSftTTF.get(),
-                                                                    aGlyphIds.data(),
-                                                                    nGlyphs,
-                                                                    bVertical );
-        if( pMetrics )
-        {
-            for( int i = 0; i< nGlyphs; i++ )
-                rWidths[i] = pMetrics[i];
-            pMetrics.reset();
-            rUnicodeEnc.clear();
-        }
-        const WinFontFace* pWinFont = static_cast<const WinFontFace*>(pFont);
-        FontCharMapRef xFCMap = pWinFont->GetFontCharMap();
-        SAL_WARN_IF( !xFCMap.is() || !xFCMap->GetCharCount(), "vcl", "no map" );
-
-        int nCharCount = xFCMap->GetCharCount();
-        sal_uInt32 nChar = xFCMap->GetFirstChar();
-        for( int i = 0; i < nCharCount; i++ )
-        {
-            if( nChar < 0x00010000 )
-            {
-                sal_uInt16 nGlyph = ::MapChar( aSftTTF.get(),
-                                               static_cast<sal_Ucs>(nChar));
-                if( nGlyph )
-                    rUnicodeEnc[ static_cast<sal_Unicode>(nChar) ] = nGlyph;
-            }
-            nChar = xFCMap->GetNextChar( nChar );
-        }
-
-        xFCMap = nullptr;
-    }
+    SalGraphics::GetGlyphWidths(*aSftTTF.get(), *pFont, bVertical, rWidths, rUnicodeEnc);
 }
 
 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */


More information about the Libreoffice-commits mailing list