diff options
-rw-r--r-- | include/vcl/fontcharmap.hxx | 1 | ||||
-rw-r--r-- | vcl/inc/impfontcharmap.hxx | 1 | ||||
-rw-r--r-- | vcl/source/font/fontcharmap.cxx | 284 |
3 files changed, 0 insertions, 286 deletions
diff --git a/include/vcl/fontcharmap.hxx b/include/vcl/fontcharmap.hxx index 4b21142509da..d79ffce7be92 100644 --- a/include/vcl/fontcharmap.hxx +++ b/include/vcl/fontcharmap.hxx @@ -164,7 +164,6 @@ public: const sal_UCS4* mpRangeCodes; int mnRangeCount; bool mbSymbolic; - bool mbRecoded; }; #endif // INCLUDED_FONTCHARMAP_HXX diff --git a/vcl/inc/impfontcharmap.hxx b/vcl/inc/impfontcharmap.hxx index 8a0b0c413d56..36809cdd986b 100644 --- a/vcl/inc/impfontcharmap.hxx +++ b/vcl/inc/impfontcharmap.hxx @@ -51,7 +51,6 @@ private: }; 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/source/font/fontcharmap.cxx b/vcl/source/font/fontcharmap.cxx index 24f1903f7165..5896e786eca0 100644 --- a/vcl/source/font/fontcharmap.cxx +++ b/vcl/source/font/fontcharmap.cxx @@ -18,20 +18,16 @@ #include <utility> #include <vcl/fontcharmap.hxx> #include <impfontcharmap.hxx> -#include <rtl/textcvt.h> -#include <rtl/textenc.h> #include <sal/log.hxx> #include <algorithm> #include <vector> -#include <o3tl/sorted_vector.hxx> CmapResult::CmapResult( bool bSymbolic, const sal_UCS4* pRangeCodes, int nRangeCount ) : mpRangeCodes( pRangeCodes) , mnRangeCount( nRangeCount) , mbSymbolic( bSymbolic) -, mbRecoded( false) {} static ImplFontCharMapRef g_pDefaultImplFontCharMap; @@ -109,286 +105,6 @@ bool HasSymbolCmap(const char* pCmap, int nLength) 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]);} - -// TODO: move CMAP parsing directly into the ImplFontCharMap class -bool ParseCMAP( const unsigned char* pCmap, int nLength, CmapResult& rResult ) -{ - rResult.mpRangeCodes = nullptr; - rResult.mnRangeCount = 0; - rResult.mbRecoded = false; - rResult.mbSymbolic = false; - - // 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; - - // find the most interesting subtable in the CMAP - rtl_TextEncoding eRecodeFrom = RTL_TEXTENCODING_UNICODE; - int nOffset = 0; - int nFormat = -1; - int nBestVal = 0; - for( const unsigned char* p = pCmap + 4; --nSubTables >= 0; p += 8 ) - { - int nPlatform = GetUShort( p ); - int nEncoding = GetUShort( p+2 ); - int nPlatformEncoding = (nPlatform << 8) + nEncoding; - - int nValue; - rtl_TextEncoding eTmpEncoding = RTL_TEXTENCODING_UNICODE; - switch( nPlatformEncoding ) - { - case 0x000: nValue = 20; break; // Unicode 1.0 - case 0x001: nValue = 21; break; // Unicode 1.1 - case 0x002: nValue = 22; break; // iso10646_1993 - case 0x003: nValue = 23; break; // UCS-2 - case 0x004: nValue = 24; break; // UCS-4 - case 0x100: nValue = 22; break; // Mac Unicode<2.0 - case 0x103: nValue = 23; break; // Mac Unicode>2.0 - case 0x300: nValue = 5; rResult.mbSymbolic = true; break; // Win Symbol - case 0x301: nValue = 28; break; // Win UCS-2 - case 0x30A: nValue = 29; break; // Win-UCS-4 - case 0x302: nValue = 11; eTmpEncoding = RTL_TEXTENCODING_SHIFT_JIS; break; - case 0x303: nValue = 12; eTmpEncoding = RTL_TEXTENCODING_GB_18030; break; - case 0x304: nValue = 11; eTmpEncoding = RTL_TEXTENCODING_BIG5; break; - case 0x305: nValue = 11; eTmpEncoding = RTL_TEXTENCODING_MS_949; break; - case 0x306: nValue = 11; eTmpEncoding = RTL_TEXTENCODING_MS_1361; break; - default: nValue = 0; break; - } - - if( nValue <= 0 ) // ignore unknown encodings - continue; - - int nTmpOffset = GetUInt( p+4 ); - - if (nTmpOffset > nLength - 2 || nTmpOffset < 0) - continue; - - int nTmpFormat = GetUShort( pCmap + nTmpOffset ); - if( nTmpFormat == 12 ) // 32bit code -> glyph map format - nValue += 3; - else if( nTmpFormat != 4 ) // 16bit code -> glyph map format - continue; // ignore other formats - - if( nBestVal < nValue ) - { - nBestVal = nValue; - nOffset = nTmpOffset; - nFormat = nTmpFormat; - eRecodeFrom = eTmpEncoding; - } - } - - // parse the best CMAP subtable - int nRangeCount = 0; - sal_UCS4* pCodePairs = nullptr; - - // format 4, the most common 16bit char mapping table - if( (nFormat == 4) && ((nOffset+16) < nLength) ) - { - int nSegCountX2 = GetUShort( pCmap + nOffset + 6 ); - nRangeCount = nSegCountX2/2 - 1; - if (nRangeCount < 0) - { - SAL_WARN("vcl.gdi", "negative RangeCount"); - nRangeCount = 0; - } - - const unsigned char* pLimitBase = pCmap + nOffset + 14; - const unsigned char* pBeginBase = pLimitBase + nSegCountX2 + 2; - const unsigned char* pDeltaBase = pBeginBase + nSegCountX2; - const unsigned char* pOffsetBase = pDeltaBase + nSegCountX2; - - const int nOffsetBaseStart = pOffsetBase - pCmap; - const int nRemainingLen = nLength - nOffsetBaseStart; - const int nMaxPossibleRangeOffsets = nRemainingLen / 2; - if (nRangeCount > nMaxPossibleRangeOffsets) - { - SAL_WARN("vcl.gdi", "more range offsets requested then space available"); - nRangeCount = std::max(0, nMaxPossibleRangeOffsets); - } - - pCodePairs = new sal_UCS4[ nRangeCount * 2 ]; - - sal_UCS4* pCP = pCodePairs; - for( int i = 0; i < nRangeCount; ++i ) - { - const sal_UCS4 cMinChar = GetUShort( pBeginBase + 2*i ); - const sal_UCS4 cMaxChar = GetUShort( pLimitBase + 2*i ); - if( cMinChar > cMaxChar ) { // no sane font should trigger this - SAL_WARN("vcl.gdi", "Min char should never be more than the max char!"); - break; - } - if( cMaxChar == 0xFFFF ) { - SAL_WARN("vcl.gdi", "Format 4 char should not be 0xFFFF"); - break; - } - *(pCP++) = cMinChar; - *(pCP++) = cMaxChar + 1; - } - nRangeCount = (pCP - pCodePairs) / 2; - } - // format 12, the most common 32bit char mapping table - else if( (nFormat == 12) && ((nOffset+16) < nLength) ) - { - nRangeCount = GetUInt( pCmap + nOffset + 12 ); - if (nRangeCount < 0) - { - SAL_WARN("vcl.gdi", "negative RangeCount"); - nRangeCount = 0; - } - - const int nGroupOffset = nOffset + 16; - const int nRemainingLen = nLength - nGroupOffset; - const int nMaxPossiblePairs = nRemainingLen / 12; - if (nRangeCount > nMaxPossiblePairs) - { - SAL_WARN("vcl.gdi", "more code pairs requested then space available"); - nRangeCount = std::max(0, nMaxPossiblePairs); - } - - pCodePairs = new sal_UCS4[ nRangeCount * 2 ]; - - const unsigned char* pGroup = pCmap + nGroupOffset; - sal_UCS4* pCP = pCodePairs; - for( int i = 0; i < nRangeCount; ++i ) - { - sal_UCS4 cMinChar = GetUInt( pGroup + 0 ); - sal_UCS4 cMaxChar = GetUInt( pGroup + 4 ); - pGroup += 12; - - if( cMinChar > cMaxChar ) { // no sane font should trigger this - SAL_WARN("vcl.gdi", "Min char should never be more than the max char!"); - break; - } - - *(pCP++) = cMinChar; - *(pCP++) = cMaxChar + 1; - } - nRangeCount = (pCP - pCodePairs) / 2; - } - - // check if any subtable resulted in something usable - if( nRangeCount <= 0 ) - { - delete[] pCodePairs; - - // even when no CMAP is available we know it for symbol fonts - if( rResult.mbSymbolic ) - { - pCodePairs = new sal_UCS4[4]; - pCodePairs[0] = 0x0020; // aliased symbols - pCodePairs[1] = 0x0100; - pCodePairs[2] = 0xF020; // original symbols - pCodePairs[3] = 0xF100; - rResult.mpRangeCodes = pCodePairs; - rResult.mnRangeCount = 2; - return true; - } - - return false; - } - - // recode the code ranges to their unicode encoded ranges if needed - rtl_TextToUnicodeConverter aConverter = nullptr; - rtl_UnicodeToTextContext aCvtContext = nullptr; - - rResult.mbRecoded = ( eRecodeFrom != RTL_TEXTENCODING_UNICODE ); - if( rResult.mbRecoded ) - { - aConverter = rtl_createTextToUnicodeConverter( eRecodeFrom ); - aCvtContext = rtl_createTextToUnicodeContext( aConverter ); - } - - if( aConverter && aCvtContext ) - { - // determine the set of supported code points from encoded ranges - o3tl::sorted_vector<sal_UCS4> aSupportedCodePoints; - aSupportedCodePoints.reserve(256); - - static const int NINSIZE = 64; - static const int NOUTSIZE = 64; - std::vector<char> cCharsInp; - cCharsInp.reserve(NINSIZE); - sal_Unicode cCharsOut[ NOUTSIZE ]; - sal_UCS4* pCP = pCodePairs; - for( int i = 0; i < nRangeCount; ++i ) - { - sal_UCS4 cMin = *(pCP++); - sal_UCS4 cEnd = *(pCP++); - // ofz#25868 the conversion only makes sense with - // input codepoints in 0..SAL_MAX_UINT16 range - while (cMin < cEnd && cMin <= SAL_MAX_UINT16) - { - for (int j = 0; (cMin < cEnd) && (j < NINSIZE); ++cMin, ++j) - { - if( cMin >= 0x0100 ) - cCharsInp.push_back(static_cast<char>(cMin >> 8)); - if( (cMin >= 0x0100) || (cMin < 0x00A0) ) - cCharsInp.push_back(static_cast<char>(cMin)); - } - - sal_uInt32 nCvtInfo; - sal_Size nSrcCvtBytes; - int nOutLen = rtl_convertTextToUnicode( - aConverter, aCvtContext, - cCharsInp.data(), cCharsInp.size(), cCharsOut, NOUTSIZE, - RTL_TEXTTOUNICODE_FLAGS_INVALID_IGNORE - | RTL_TEXTTOUNICODE_FLAGS_UNDEFINED_IGNORE, - &nCvtInfo, &nSrcCvtBytes ); - - cCharsInp.clear(); - - for (int j = 0; j < nOutLen; ++j) - aSupportedCodePoints.insert( cCharsOut[j] ); - } - } - - rtl_destroyTextToUnicodeConverter( aCvtContext ); - rtl_destroyTextToUnicodeConverter( aConverter ); - - // convert the set of supported code points to ranges - std::vector<sal_UCS4> aSupportedRanges; - - for (auto const& supportedPoint : aSupportedCodePoints) - { - if( aSupportedRanges.empty() - || (aSupportedRanges.back() != supportedPoint) ) - { - // add new range beginning with current unicode - aSupportedRanges.push_back(supportedPoint); - aSupportedRanges.push_back( 0 ); - } - - // extend existing range to include current unicode - aSupportedRanges.back() = supportedPoint + 1; - } - - // make a pCodePairs array using the vector from above - delete[] pCodePairs; - nRangeCount = aSupportedRanges.size() / 2; - if( nRangeCount <= 0 ) - return false; - pCodePairs = new sal_UCS4[ nRangeCount * 2 ]; - pCP = pCodePairs; - for (auto const& supportedRange : aSupportedRanges) - *(pCP++) = supportedRange; - } - - // update the result struct - rResult.mpRangeCodes = pCodePairs; - rResult.mnRangeCount = nRangeCount; - return true; -} - FontCharMap::FontCharMap() : mpImplFontCharMap( ImplFontCharMap::getDefaultMap() ) { |