summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKhaled Hosny <khaled@aliftype.com>2022-09-08 02:05:14 +0200
committerخالد حسني <khaled@aliftype.com>2022-09-08 16:32:01 +0200
commit8597aed8a8576ad0f6efe139ff03556217b01b31 (patch)
tree867f9b4831f0f03120e83864cb6347188d609fdd
parent05b3d7ea4673654e809be816bee0fa67fbf0308a (diff)
vcl: Get FontCharMap from HarfBuzz
Implement PhysicalFontFace::GetFontCharMap() on top hb_face_collect_unicodes() so that it is the same charmap as what shaping code will actually use. Change-Id: I486e9d296cec5bd897e4f628d14a2f19e63b70b5 Reviewed-on: https://gerrit.libreoffice.org/c/core/+/139623 Tested-by: Jenkins Reviewed-by: خالد حسني <khaled@aliftype.com>
-rw-r--r--vcl/inc/impfontcharmap.hxx1
-rw-r--r--vcl/inc/sft.hxx3
-rw-r--r--vcl/source/font/PhysicalFontFace.cxx37
-rw-r--r--vcl/source/font/fontcharmap.cxx26
-rw-r--r--vcl/source/fontsubset/sft.cxx8
5 files changed, 64 insertions, 11 deletions
diff --git a/vcl/inc/impfontcharmap.hxx b/vcl/inc/impfontcharmap.hxx
index 8a8428d7e34e..8a0b0c413d56 100644
--- a/vcl/inc/impfontcharmap.hxx
+++ b/vcl/inc/impfontcharmap.hxx
@@ -50,6 +50,7 @@ private:
const bool m_bSymbolic;
};
+bool VCL_DLLPUBLIC HasSymbolCmap(const char* pRawData, int nRawLength);
bool VCL_DLLPUBLIC ParseCMAP( const unsigned char* pRawData, int nRawLength, CmapResult& );
#endif // INCLUDED_VCL_INC_IMPFONTCHARMAP_HXX
diff --git a/vcl/inc/sft.hxx b/vcl/inc/sft.hxx
index fb43e51a174a..75af2af8044e 100644
--- a/vcl/inc/sft.hxx
+++ b/vcl/inc/sft.hxx
@@ -727,6 +727,7 @@ class VCL_DLLPUBLIC AbstractTrueTypeFont
sal_uInt32 m_nUnitsPerEm;
std::vector<sal_uInt32> m_aGlyphOffsets;
FontCharMapRef m_xCharMap;
+ bool m_bIsSymbolFont;
protected:
SFErrCodes indexGlyphData();
@@ -741,7 +742,7 @@ public:
sal_uInt32 horzMetricCount() const { return m_nHorzMetrics; }
sal_uInt32 vertMetricCount() const { return m_nVertMetrics; }
sal_uInt32 unitsPerEm() const { return m_nUnitsPerEm; }
- const FontCharMapRef & GetCharMap() const { return m_xCharMap; }
+ bool IsSymbolFont() const { return m_bIsSymbolFont; }
virtual bool hasTable(sal_uInt32 ord) const = 0;
virtual const sal_uInt8* table(sal_uInt32 ord, sal_uInt32& size) const = 0;
diff --git a/vcl/source/font/PhysicalFontFace.cxx b/vcl/source/font/PhysicalFontFace.cxx
index 5d90283fe1f4..1133b0d6a131 100644
--- a/vcl/source/font/PhysicalFontFace.cxx
+++ b/vcl/source/font/PhysicalFontFace.cxx
@@ -230,18 +230,45 @@ FontCharMapRef PhysicalFontFace::GetFontCharMap() const
if (mxCharMap.is())
return mxCharMap;
+ // Check if this font is using symbol cmap subtable, most likely redundant
+ // since HarfBuzz handles mapping symbol fonts for us.
+ bool bSymbol = false;
hb_blob_t* pBlob = GetHbTable(HB_TAG('c', 'm', 'a', 'p'));
if (pBlob)
{
unsigned int nSize = 0;
- auto* pData = reinterpret_cast<const unsigned char*>(hb_blob_get_data(pBlob, &nSize));
-
- CmapResult aCmapResult(IsSymbolFont());
- if (ParseCMAP(pData, nSize, aCmapResult))
- mxCharMap = new FontCharMap(aCmapResult);
+ auto* pData = hb_blob_get_data(pBlob, &nSize);
+ bSymbol = HasSymbolCmap(pData, nSize);
hb_blob_destroy(pBlob);
}
+ hb_face_t* pHbFace = GetHbFace();
+ hb_set_t* pUnicodes = hb_set_create();
+ hb_face_collect_unicodes(pHbFace, pUnicodes);
+
+ if (hb_set_get_population(pUnicodes))
+ {
+ // Convert HarfBuzz set to CmapResult ranges.
+ int nRangeCount = 0;
+ hb_codepoint_t nFirst, nLast = HB_SET_VALUE_INVALID;
+ while (hb_set_next_range(pUnicodes, &nFirst, &nLast))
+ nRangeCount++;
+
+ nLast = HB_SET_VALUE_INVALID;
+ auto* pRangeCodes(new sal_UCS4[nRangeCount * 2]);
+ auto* pCP = pRangeCodes;
+ while (hb_set_next_range(pUnicodes, &nFirst, &nLast))
+ {
+ *(pCP++) = nFirst;
+ *(pCP++) = nLast + 1;
+ }
+
+ CmapResult aCmapResult(bSymbol, pRangeCodes, nRangeCount);
+ mxCharMap = new FontCharMap(aCmapResult);
+ }
+
+ hb_set_destroy(pUnicodes);
+
if (!mxCharMap.is())
mxCharMap = FontCharMap::GetDefaultMap(IsSymbolFont());
diff --git a/vcl/source/font/fontcharmap.cxx b/vcl/source/font/fontcharmap.cxx
index cb42e3b9620c..24f1903f7165 100644
--- a/vcl/source/font/fontcharmap.cxx
+++ b/vcl/source/font/fontcharmap.cxx
@@ -83,6 +83,32 @@ bool ImplFontCharMap::isDefaultMap() const
return bIsDefault;
}
+static unsigned GetUShort(const char* p) { return((p[0]<<8) | p[1]);}
+
+bool HasSymbolCmap(const char* pCmap, int nLength)
+{
+ // parse the table header and check for validity
+ if( !pCmap || (nLength < 24) )
+ return false;
+
+ if( GetUShort( pCmap ) != 0x0000 ) // simple check for CMAP corruption
+ return false;
+
+ int nSubTables = GetUShort(pCmap + 2);
+ if( (nSubTables <= 0) || (nSubTables > (nLength - 24) / 8) )
+ return false;
+
+ for (const char* p = pCmap + 4; --nSubTables >= 0; p += 8)
+ {
+ int nPlatform = GetUShort(p);
+ int nEncoding = GetUShort(p + 2);
+ if (nPlatform == 3 && nEncoding == 0)
+ return true;
+ }
+
+ return false;
+}
+
static unsigned GetUInt( const unsigned char* p ) { return((p[0]<<24)+(p[1]<<16)+(p[2]<<8)+p[3]);}
static unsigned GetUShort( const unsigned char* p ){ return((p[0]<<8) | p[1]);}
diff --git a/vcl/source/fontsubset/sft.cxx b/vcl/source/fontsubset/sft.cxx
index a164757a886d..41918cb12e6f 100644
--- a/vcl/source/fontsubset/sft.cxx
+++ b/vcl/source/fontsubset/sft.cxx
@@ -1200,6 +1200,7 @@ AbstractTrueTypeFont::AbstractTrueTypeFont(const char* pFileName, const FontChar
, m_nVertMetrics(0)
, m_nUnitsPerEm(0)
, m_xCharMap(xCharMap)
+ , m_bIsSymbolFont(false)
{
if (pFileName)
m_sFileName = pFileName;
@@ -1297,11 +1298,8 @@ SFErrCodes AbstractTrueTypeFont::indexGlyphData()
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);
+ m_bIsSymbolFont = HasSymbolCmap(reinterpret_cast<const char*>(table), table_size);
}
return SFErrCodes::Ok;
@@ -2170,7 +2168,7 @@ void GetTTGlobalFontInfo(TrueTypeFont *ttf, TTGlobalFontInfo *info)
info->subfamily = ttf->subfamily;
info->usubfamily = ttf->usubfamily;
info->psname = ttf->psname;
- info->symbolEncoded = ttf->GetCharMap()->isSymbolic();
+ info->symbolEncoded = ttf->IsSymbolFont();
sal_uInt32 table_size;
const sal_uInt8* table = ttf->table(O_OS2, table_size);