diff --git a/vcl/inc/fontsubset.hxx b/vcl/inc/fontsubset.hxx index a1ba31aa58d8..1b218ed2e389 100644 --- a/vcl/inc/fontsubset.hxx +++ b/vcl/inc/fontsubset.hxx @@ -38,8 +38,6 @@ enum class FontType { TYPE1_PFA = 1<<3, ///< PSType1 Postscript Font Ascii TYPE1_PFB = 1<<4, ///< PSType1 Postscript Font Binary CFF_FONT = 1<<5, ///< CFF-container with PSType2 glyphs - TYPE3_FONT = 1<<6, ///< PSType3 Postscript font - TYPE42_FONT = 1<<7, ///< PSType42 wrapper for an SFNT_TTF ANY_SFNT = SFNT_TTF | SFNT_CFF, ANY_TYPE1 = TYPE1_PFA | TYPE1_PFB }; @@ -55,7 +53,6 @@ public: void LoadFont( FontType eInFontType, const unsigned char* pFontBytes, int nByteLength ); - void LoadFont( vcl::TrueTypeFont* pSftTrueTypeFont ); bool CreateFontSubset( FontType nOutFontTypeMask, SvStream* pOutFile, const char* pOutFontName, @@ -77,7 +74,6 @@ private: unsigned const char* mpInFontBytes; int mnInByteLength; FontType meInFontType; ///< allowed mask of input font-types - vcl::TrueTypeFont* mpSftTTFont; // subset-request details FontType mnReqFontTypeMask; ///< allowed subset-target font types @@ -88,7 +84,6 @@ private: int mnReqGlyphCount; bool CreateFontSubsetFromCff(); - bool CreateFontSubsetFromSfnt(); }; int VCL_DLLPUBLIC TestFontSubset(const void* data, sal_uInt32 size); diff --git a/vcl/inc/sft.hxx b/vcl/inc/sft.hxx index b5fc71b44530..339914e4fb73 100644 --- a/vcl/inc/sft.hxx +++ b/vcl/inc/sft.hxx @@ -61,7 +61,7 @@ namespace vcl typedef sal_Int32 F16Dot16; /**< fixed: 16.16 */ /*@}*/ -/** Return value of OpenTTFont() and CreateT3FromTTGlyphs() */ +/** Return value of OpenTTFont() */ enum class SFErrCodes { Ok, /**< no error */ BadFile, /**< file not found */ @@ -565,25 +565,6 @@ class TrueTypeFont; void GetTTNameRecords(AbstractTrueTypeFont const *ttf, std::vector& nr); -/** - * Generates a new PostScript Type 3 font and dumps it to outf file. - * This function substitutes glyph 0 for all glyphIDs that are not found in the font. - * @param ttf pointer to the TrueTypeFont structure - * @param outf the resulting font is written to this stream - * @param fname font name for the new font. If it is NULL the PostScript name of the - * original font will be used - * @param glyphArray pointer to an array of glyphs that are to be extracted from ttf - * @param encoding array of encoding values. encoding[i] specifies the position of the glyph - * glyphArray[i] in the encoding vector of the resulting Type3 font - * @param nGlyphs number of glyph IDs in glyphArray and encoding values in encoding - * @param wmode writing mode for the output file: 0 - horizontal, 1 - vertical - * @return return the value of SFErrCodes enum - * @see SFErrCodes - * @ingroup sft - * - */ - SFErrCodes CreateT3FromTTGlyphs(TrueTypeFont *ttf, SvStream *outf, const char *fname, sal_uInt16 const *glyphArray, sal_uInt8 *encoding, int nGlyphs, int wmode); - /** * Generates a new TrueType font and dumps it to outf file. * This function substitutes glyph 0 for all glyphIDs that are not found in the font. @@ -612,32 +593,6 @@ class TrueTypeFont; const sal_GlyphId* pGlyphIds, const sal_uInt8* pEncoding, int nGlyphCount, FontSubsetInfo& rInfo); -/** - * Generates a new PostScript Type42 font and dumps it to outf file. - * This function substitutes glyph 0 for all glyphIDs that are not found in the font. - * @param ttf pointer to the TrueTypeFont structure - * @param outf output stream for a resulting font - * @param psname PostScript name of the resulting font - * @param glyphArray pointer to an array of glyphs that are to be extracted from ttf. The first - * element of this array has to be glyph 0 (default glyph) - * @param encoding array of encoding values. encoding[i] specifies character code for - * the glyphID glyphArray[i]. Character code 0 usually points to a default - * glyph (glyphID 0) - * @param nGlyphs number of glyph IDs in glyphArray and encoding values in encoding - * @return SFErrCodes::Ok - no errors - * SFErrCodes::GlyphNum - too many glyphs (> 255) - * SFErrCodes::TtFormat - corrupted TrueType fonts - * - * @see SFErrCodes - * @ingroup sft - * - */ - SFErrCodes CreateT42FromTTGlyphs(TrueTypeFont *ttf, - SvStream *outf, - const char *psname, - sal_uInt16 const *glyphArray, - sal_uInt8 *encoding, - int nGlyphs); /** * Returns global font information about the TrueType font. diff --git a/vcl/source/fontsubset/fontsubset.cxx b/vcl/source/fontsubset/fontsubset.cxx index 1ecd358727bf..2a45a1194e1a 100644 --- a/vcl/source/fontsubset/fontsubset.cxx +++ b/vcl/source/fontsubset/fontsubset.cxx @@ -33,7 +33,6 @@ FontSubsetInfo::FontSubsetInfo() , mpInFontBytes( nullptr) , mnInByteLength( 0) , meInFontType( FontType::NO_FONT) - , mpSftTTFont( nullptr) , mnReqFontTypeMask( FontType::NO_FONT ) , mpOutFile(nullptr) , mpReqFontName(nullptr) @@ -52,20 +51,11 @@ void FontSubsetInfo::LoadFont( FontType eInFontType, const unsigned char* pInFontBytes, int nInByteLength) { - SAL_WARN_IF( (mpSftTTFont != nullptr), "vcl", "Subset from SFT and from mapped font-file requested"); meInFontType = eInFontType; mpInFontBytes = pInFontBytes; mnInByteLength = nInByteLength; } -// prepare subsetting for fonts that are known to the SFT-parser -void FontSubsetInfo::LoadFont( vcl::TrueTypeFont* pSftTTFont ) -{ - SAL_WARN_IF( (mpInFontBytes != nullptr), "vcl", "Subset from SFT and from mapped font-file requested"); - mpSftTTFont = pSftTTFont; - meInFontType = FontType::ANY_SFNT; -} - bool FontSubsetInfo::CreateFontSubset( FontType nReqFontTypeMask, SvStream* pOutFile, const char* pReqFontName, @@ -90,18 +80,9 @@ bool FontSubsetInfo::CreateFontSubset( // TODO: better match available input-type to possible subset-types switch( meInFontType) { - case FontType::SFNT_TTF: - case FontType::SFNT_CFF: - case FontType::ANY_SFNT: - bOK = CreateFontSubsetFromSfnt(); - break; case FontType::CFF_FONT: bOK = CreateFontSubsetFromCff(); break; - case FontType::TYPE1_PFA: - case FontType::TYPE1_PFB: - case FontType::ANY_TYPE1: - case FontType::NO_FONT: default: OSL_FAIL( "unhandled type in CreateFontSubset()"); break; @@ -110,48 +91,4 @@ bool FontSubsetInfo::CreateFontSubset( return bOK; } -// TODO: move function to sft.cxx to replace dummy implementation -bool FontSubsetInfo::CreateFontSubsetFromSfnt() -{ - // handle SFNT_CFF fonts - sal_uInt32 nCffLength = 0; - const sal_uInt8* pCffBytes = mpSftTTFont->table(vcl::O_CFF, nCffLength); - if (pCffBytes) - { - LoadFont( FontType::CFF_FONT, pCffBytes, nCffLength); - const bool bOK = CreateFontSubsetFromCff(); - return bOK; - } - - // handle SFNT_TTF fonts - // by forwarding the subset request to AG's sft subsetter -#if 1 // TODO: remove conversion tp 16bit glyphids when sft-subsetter has been updated - std::vector aShortGlyphIds; - aShortGlyphIds.reserve(mnReqGlyphCount); - for (int i = 0; i < mnReqGlyphCount; ++i) - aShortGlyphIds.push_back(static_cast(mpReqGlyphIds[i])); - // remove const_cast when sft-subsetter is const-correct - sal_uInt8* pEncArray = const_cast( mpReqEncodedIds ); -#endif - vcl::SFErrCodes nSFTErr = vcl::SFErrCodes::BadArg; - if( mnReqFontTypeMask & FontType::TYPE42_FONT ) - { - nSFTErr = CreateT42FromTTGlyphs( mpSftTTFont, mpOutFile, mpReqFontName, - aShortGlyphIds.data(), pEncArray, mnReqGlyphCount ); - } - else if( mnReqFontTypeMask & FontType::TYPE3_FONT ) - { - nSFTErr = CreateT3FromTTGlyphs( mpSftTTFont, mpOutFile, mpReqFontName, - aShortGlyphIds.data(), pEncArray, mnReqGlyphCount, - 0 /* 0 = horizontal, 1 = vertical */ ); - } - else if( mnReqFontTypeMask & FontType::SFNT_TTF ) - { - // TODO: use CreateTTFromTTGlyphs() - // TODO: move functionality from callers here - } - - return (nSFTErr != vcl::SFErrCodes::Ok); -} - /* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/vcl/source/fontsubset/sft.cxx b/vcl/source/fontsubset/sft.cxx index 0eee2fee38b8..d34095d25d71 100644 --- a/vcl/source/fontsubset/sft.cxx +++ b/vcl/source/fontsubset/sft.cxx @@ -58,46 +58,8 @@ namespace vcl { -/*- module identification */ - -const char * const modname = "SunTypeTools-TT"; -const char * const modver = "1.0"; -const char * const modextra = "gelf"; - -/*- private functions, constants and data types */ - namespace { -enum PathSegmentType { - PS_NOOP = 0, - PS_MOVETO = 1, - PS_LINETO = 2, - PS_CURVETO = 3, - PS_CLOSEPATH = 4 -}; - -struct PSPathElement -{ - PathSegmentType type; - int x1, y1; - int x2, y2; - int x3, y3; - - explicit PSPathElement( PathSegmentType i_eType ) : type( i_eType ), - x1( 0 ), y1( 0 ), - x2( 0 ), y2( 0 ), - x3( 0 ), y3( 0 ) - { - } - - PSPathElement() : type( PS_NOOP ), - x1( 0 ), y1( 0 ), - x2( 0 ), y2( 0 ), - x3( 0 ), y3( 0 ) - { - } -}; - /*- In horizontal writing mode right sidebearing is calculated using this formula *- rsb = aw - (lsb + xMax - xMin) -*/ struct TTGlyphMetrics { @@ -110,34 +72,6 @@ struct TTGlyphMetrics { sal_uInt16 ah; /*- advance height (vertical writing mode) */ }; -constexpr int HFORMAT_LINELEN = 64; - -class HexFmt { -public: - HexFmt(SvStream *outf) : o(outf) {} - ~HexFmt() - { - Flush(); - } - bool Flush(); - void OpenString(); - void CloseString(); - void BlockWrite(const void *ptr, sal_uInt32 size); - -private: - SvStream *o; - char buffer[HFORMAT_LINELEN]; - size_t bufpos = 0; - int total = 0; -}; - -class GlyphOffsets { -public: - GlyphOffsets(sal_uInt8 *sfntP, sal_uInt32 sfntLen); - sal_uInt32 nGlyphs; /* number of glyphs in the font + 1 */ - std::unique_ptr offs; /* array of nGlyphs offsets */ -}; - } /*- Data access methods for data stored in big-endian format */ @@ -207,58 +141,6 @@ static int XUnits(int unitsPerEm, int n) return (n * 1000) / unitsPerEm; } -static char toHex(sal_uInt8 nIndex) -{ - /* Hex Formatter functions */ - static const char HexChars[] = "0123456789ABCDEF"; - assert(nIndex < SAL_N_ELEMENTS(HexChars)); - return HexChars[nIndex]; -} - -bool HexFmt::Flush() -{ - bool bRet = true; - if (bufpos) { - size_t nWritten = o->WriteBytes(buffer, bufpos); - bRet = nWritten == bufpos; - bufpos = 0; - } - return bRet; -} - -void HexFmt::OpenString() -{ - o->WriteOString("<\n"); -} - -void HexFmt::CloseString() -{ - Flush(); - o->WriteOString("00\n>\n"); -} - -void HexFmt::BlockWrite(const void *ptr, sal_uInt32 size) -{ - if (total + size > 65534) { - Flush(); - CloseString(); - total = 0; - OpenString(); - } - - for (sal_uInt32 i = 0; i < size; ++i) { - sal_uInt8 Ch = static_cast(ptr)[i]; - buffer[bufpos++] = toHex(Ch >> 4); - buffer[bufpos++] = toHex(Ch & 0xF); - if (bufpos == HFORMAT_LINELEN) { - Flush(); - o->WriteOString("\n"); - } - - } - total += size; -} - /* Outline Extraction functions */ /* fills the aw and lsb entries of the TTGlyphMetrics structure from hmtx table -*/ @@ -742,133 +624,6 @@ static int GetTTGlyphOutline(AbstractTrueTypeFont *ttf, sal_uInt32 glyphID, std: return res; } -/*- returns the number of items in the path -*/ - -static int BSplineToPSPath(ControlPoint const *srcA, int srcCount, std::unique_ptr& path) -{ - std::vector< PSPathElement > aPathList; - int nPathCount = 0; - PSPathElement p( PS_NOOP ); - - int x0 = 0, y0 = 0, x1 = 0, y1 = 0, x2, y2, curx, cury; - bool lastOff = false; /*- last point was off-contour */ - int scflag = 1; /*- start contour flag */ - bool ecflag = false; /*- end contour flag */ - int cp = 0; /*- current point */ - int StartContour = 0, EndContour = 1; - - path.reset(); - - /* if (srcCount > 0) for(;;) */ - while (srcCount > 0) { /*- srcCount does not get changed inside the loop. */ - if (scflag) { - int l = cp; - StartContour = cp; - while (!(srcA[l].flags & 0x8000)) l++; - EndContour = l; - if (StartContour == EndContour) { - if (cp + 1 < srcCount) { - cp++; - continue; - } else { - break; - } - } - p = PSPathElement(PS_MOVETO); - if (!(srcA[cp].flags & 1)) { - if (!(srcA[EndContour].flags & 1)) { - p.x1 = x0 = (srcA[cp].x + srcA[EndContour].x + 1) / 2; - p.y1 = y0 = (srcA[cp].y + srcA[EndContour].y + 1) / 2; - } else { - p.x1 = x0 = srcA[EndContour].x; - p.y1 = y0 = srcA[EndContour].y; - } - } else { - p.x1 = x0 = srcA[cp].x; - p.y1 = y0 = srcA[cp].y; - cp++; - } - aPathList.push_back( p ); - lastOff = false; - scflag = 0; - } - - curx = srcA[cp].x; - cury = srcA[cp].y; - - if (srcA[cp].flags & 1) - { - if (lastOff) - { - p = PSPathElement(PS_CURVETO); - p.x1 = x0 + (2 * (x1 - x0) + 1) / 3; - p.y1 = y0 + (2 * (y1 - y0) + 1) / 3; - p.x2 = x1 + (curx - x1 + 1) / 3; - p.y2 = y1 + (cury - y1 + 1) / 3; - p.x3 = curx; - p.y3 = cury; - aPathList.push_back( p ); - } - else - { - if (x0 != curx || y0 != cury) - { /* eliminate empty lines */ - p = PSPathElement(PS_LINETO); - p.x1 = curx; - p.y1 = cury; - aPathList.push_back( p ); - } - } - x0 = curx; y0 = cury; lastOff = false; - } - else - { - if (lastOff) - { - x2 = (x1 + curx + 1) / 2; - y2 = (y1 + cury + 1) / 2; - p = PSPathElement(PS_CURVETO); - p.x1 = x0 + (2 * (x1 - x0) + 1) / 3; - p.y1 = y0 + (2 * (y1 - y0) + 1) / 3; - p.x2 = x1 + (x2 - x1 + 1) / 3; - p.y2 = y1 + (y2 - y1 + 1) / 3; - p.x3 = x2; - p.y3 = y2; - aPathList.push_back( p ); - x0 = x2; y0 = y2; - x1 = curx; y1 = cury; - } else { - x1 = curx; y1 = cury; - } - lastOff = true; - } - - if (ecflag) { - aPathList.emplace_back(PS_CLOSEPATH ); - scflag = 1; - ecflag = false; - cp = EndContour + 1; - if (cp >= srcCount) break; - continue; - } - - if (cp == EndContour) { - cp = StartContour; - ecflag = true; - } else { - cp++; - } - } - - if( (nPathCount = static_cast(aPathList.size())) > 0) - { - path.reset(new PSPathElement[nPathCount]); - memcpy( path.get(), aPathList.data(), nPathCount * sizeof(PSPathElement) ); - } - - return nPathCount; -} - /*- Extracts a string from the name table and allocates memory for it -*/ static OString nameExtract( const sal_uInt8* name, int nTableSize, int n, int dbFlag, OUString* ucs2result ) @@ -1561,188 +1316,6 @@ int GetTTGlyphComponents(AbstractTrueTypeFont *ttf, sal_uInt32 glyphID, std::vec return n; } -SFErrCodes CreateT3FromTTGlyphs(TrueTypeFont *ttf, SvStream *outf, const char *fname, - sal_uInt16 const *glyphArray, sal_uInt8 *encoding, int nGlyphs, - int wmode) -{ - std::vector pa; - std::unique_ptr path; - int i, j, n; - sal_uInt32 nSize; - const sal_uInt8* table = ttf->table(O_head, nSize); - TTGlyphMetrics metrics; - int UPEm = ttf->unitsPerEm(); - - const char * const h01 = "%%!PS-AdobeFont-%d.%d-%d.%d\n"; - const char * const h02 = "%% Creator: %s %s %s\n"; - const char * const h09 = "%% Original font name: %s\n"; - - const char * const h10 = - "30 dict begin\n" - "/PaintType 0 def\n" - "/FontType 3 def\n" - "/StrokeWidth 0 def\n"; - - const char * const h11 = "/FontName (%s) cvn def\n"; - - /* - const char *h12 = "%/UniqueID %d def\n"; - */ - const char * const h13 = "/FontMatrix [.001 0 0 .001 0 0] def\n"; - const char * const h14 = "/FontBBox [%d %d %d %d] def\n"; - - const char * const h15= - "/Encoding 256 array def\n" - " 0 1 255 {Encoding exch /.notdef put} for\n"; - - const char * const h16 = " Encoding %d /glyph%d put\n"; - const char * const h17 = "/XUID [103 0 0 16#%08" SAL_PRIXUINT32 " %d 16#%08" SAL_PRIXUINT32 " 16#%08" SAL_PRIXUINT32 "] def\n"; - - const char * const h30 = "/CharProcs %d dict def\n"; - const char * const h31 = " CharProcs begin\n"; - const char * const h32 = " /.notdef {} def\n"; - const char * const h33 = " /glyph%d {\n"; - const char * const h34 = " } bind def\n"; - const char * const h35 = " end\n"; - - const char * const h40 = - "/BuildGlyph {\n" - " exch /CharProcs get exch\n" - " 2 copy known not\n" - " {pop /.notdef} if\n" - " get exec\n" - "} bind def\n" - "/BuildChar {\n" - " 1 index /Encoding get exch get\n" - " 1 index /BuildGlyph get exec\n" - "} bind def\n" - "currentdict end\n"; - - const char * const h41 = "(%s) cvn exch definefont pop\n"; - - if ((nGlyphs <= 0) || (nGlyphs > 256)) return SFErrCodes::GlyphNum; - if (!glyphArray) return SFErrCodes::BadArg; - if (!fname) fname = ttf->psname.getStr(); - - constexpr int bufmax = 256; - char buf[bufmax]; - - snprintf(buf, bufmax, h01, GetInt16(table, 0), GetUInt16(table, 2), GetInt16(table, 4), GetUInt16(table, 6)); - outf->WriteOString(buf); - snprintf(buf, bufmax, h02, modname, modver, modextra); - outf->WriteOString(buf); - snprintf(buf, bufmax, h09, ttf->psname.getStr()); - outf->WriteOString(buf); - - snprintf(buf, bufmax, "%s", h10); - outf->WriteOString(buf); - snprintf(buf, bufmax, h11, fname); - outf->WriteOString(buf); -/* snprintf(buf, bufmax, h12, 4000000); */ - - /* XUID generation: - * 103 0 0 C1 C2 C3 C4 - * C1 - CRC-32 of the entire source TrueType font - * C2 - number of glyphs in the subset - * C3 - CRC-32 of the glyph array - * C4 - CRC-32 of the encoding array - * - * All CRC-32 numbers are presented as hexadecimal numbers - */ - - snprintf(buf, bufmax, h17, rtl_crc32(0, ttf->ptr, ttf->fsize), nGlyphs, rtl_crc32(0, glyphArray, nGlyphs * 2), rtl_crc32(0, encoding, nGlyphs)); - outf->WriteOString(buf); - snprintf(buf, bufmax, "%s", h13); - outf->WriteOString(buf); - snprintf(buf, bufmax, h14, XUnits(UPEm, GetInt16(table, 36)), XUnits(UPEm, GetInt16(table, 38)), XUnits(UPEm, GetInt16(table, 40)), XUnits(UPEm, GetInt16(table, 42))); - outf->WriteOString(buf); - snprintf(buf, bufmax, "%s", h15); - outf->WriteOString(buf); - - for (i = 0; i < nGlyphs; i++) { - snprintf(buf, bufmax, h16, encoding[i], i); - outf->WriteOString(buf); - } - - snprintf(buf, bufmax, h30, nGlyphs+1); - outf->WriteOString(buf); - snprintf(buf, bufmax, "%s", h31); - outf->WriteOString(buf); - snprintf(buf, bufmax, "%s", h32); - outf->WriteOString(buf); - - for (i = 0; i < nGlyphs; i++) { - snprintf(buf, bufmax, h33, i); - outf->WriteOString(buf); - int r = GetTTGlyphOutline(ttf, glyphArray[i] < ttf->glyphCount() ? glyphArray[i] : 0, pa, &metrics, nullptr); - - if (r > 0) { - n = BSplineToPSPath(pa.data(), r, path); - } else { - n = 0; /* glyph might have zero contours but valid metrics ??? */ - path = nullptr; - if (r < 0) { /* glyph is not present in the font - pa array was not allocated, so no need to free it */ - continue; - } - } - snprintf(buf, bufmax, "\t%d %d %d %d %d %d setcachedevice\n", - wmode == 0 ? XUnits(UPEm, metrics.aw) : 0, - wmode == 0 ? 0 : -XUnits(UPEm, metrics.ah), - XUnits(UPEm, metrics.xMin), - XUnits(UPEm, metrics.yMin), - XUnits(UPEm, metrics.xMax), - XUnits(UPEm, metrics.yMax)); - outf->WriteOString(buf); - - for (j = 0; j < n; j++) - { - switch (path[j].type) - { - case PS_MOVETO: - snprintf(buf, bufmax, "\t%d %d moveto\n", XUnits(UPEm, path[j].x1), XUnits(UPEm, path[j].y1)); - outf->WriteOString(buf); - break; - - case PS_LINETO: - snprintf(buf, bufmax, "\t%d %d lineto\n", XUnits(UPEm, path[j].x1), XUnits(UPEm, path[j].y1)); - outf->WriteOString(buf); - break; - - case PS_CURVETO: - snprintf(buf, bufmax, "\t%d %d %d %d %d %d curveto\n", XUnits(UPEm, path[j].x1), XUnits(UPEm, path[j].y1), XUnits(UPEm, path[j].x2), XUnits(UPEm, path[j].y2), XUnits(UPEm, path[j].x3), XUnits(UPEm, path[j].y3)); - outf->WriteOString(buf); - break; - - case PS_CLOSEPATH: - snprintf(buf, bufmax, "\tclosepath\n"); - outf->WriteOString(buf); - break; - case PS_NOOP: - break; - } - } - if (n > 0) - { - snprintf(buf, bufmax, "\tfill\n"); /* if glyph is not a whitespace character */ - outf->WriteOString(buf); - } - - snprintf(buf, bufmax, "%s", h34); - outf->WriteOString(buf); - - path.reset(); - } - snprintf(buf, bufmax, "%s", h35); - outf->WriteOString(buf); - - snprintf(buf, bufmax, "%s", h40); - outf->WriteOString(buf); - snprintf(buf, bufmax, h41, fname); - outf->WriteOString(buf); - - return SFErrCodes::Ok; -} - SFErrCodes CreateTTFromTTGlyphs(AbstractTrueTypeFont *ttf, std::vector& rOutBuffer, sal_uInt16 const *glyphArray, @@ -1977,289 +1550,6 @@ bool CreateTTFfontSubset(vcl::AbstractTrueTypeFont& rTTF, std::vector == vcl::SFErrCodes::Ok); } -GlyphOffsets::GlyphOffsets(sal_uInt8 *sfntP, sal_uInt32 sfntLen) -{ - sal_uInt8 *loca = nullptr; - sal_uInt16 numTables = GetUInt16(sfntP, 4); - sal_uInt32 locaLen = 0; - sal_Int16 indexToLocFormat = 0; - - sal_uInt32 nMaxPossibleTables = sfntLen / (3*sizeof(sal_uInt32)); /*the three GetUInt32 calls*/ - if (numTables > nMaxPossibleTables) - { - SAL_WARN( "vcl.fonts", "GlyphOffsetsNew claimed to have " - << numTables << " tables, but that's impossibly large"); - numTables = nMaxPossibleTables; - } - - for (sal_uInt16 i = 0; i < numTables; i++) { - sal_uInt32 nLargestFixedOffsetPos = 12 + 16 * i + 12; - sal_uInt32 nMinSize = nLargestFixedOffsetPos + sizeof(sal_uInt32); - if (nMinSize > sfntLen) - { - SAL_WARN( "vcl.fonts", "GlyphOffsetsNew claimed to have " - << numTables << " tables, but only space for " << i); - break; - } - - sal_uInt32 tag = GetUInt32(sfntP, 12 + 16 * i); - sal_uInt32 off = GetUInt32(sfntP, 12 + 16 * i + 8); - sal_uInt32 len = GetUInt32(sfntP, nLargestFixedOffsetPos); - - if (tag == T_loca) { - loca = sfntP + off; - locaLen = len; - } else if (tag == T_head) { - indexToLocFormat = GetInt16(sfntP + off, 50); - } - } - - this->nGlyphs = locaLen / ((indexToLocFormat == 1) ? 4 : 2); - assert(this->nGlyphs != 0); - this->offs = std::make_unique(this->nGlyphs); - - for (sal_uInt32 i = 0; i < this->nGlyphs; i++) { - if (indexToLocFormat == 1) { - this->offs[i] = GetUInt32(loca, i * 4); - } else { - this->offs[i] = GetUInt16(loca, i * 2) << 1; - } - } -} - -static void DumpSfnts(SvStream *outf, sal_uInt8 *sfntP, sal_uInt32 sfntLen) -{ - if (sfntLen < 12) - { - SAL_WARN( "vcl.fonts", "DumpSfnts sfntLen is too short: " - << sfntLen << " legal min is: " << 12); - return; - } - - const sal_uInt32 nSpaceForTables = sfntLen - 12; - const sal_uInt32 nTableSize = 16; - const sal_uInt32 nMaxPossibleTables = nSpaceForTables/nTableSize; - - HexFmt h(outf); - sal_uInt16 i, numTables = GetUInt16(sfntP, 4); - GlyphOffsets go(sfntP, sfntLen); - sal_uInt8 const pad[] = {0,0,0,0}; /* zeroes */ - - if (numTables > nMaxPossibleTables) - { - SAL_WARN( "vcl.fonts", "DumpSfnts claimed to have " - << numTables << " tables, but only space for " << nMaxPossibleTables); - numTables = nMaxPossibleTables; - } - - assert(numTables <= 9); /* Type42 has 9 required tables */ - - std::unique_ptr offs(new sal_uInt32[numTables]); - - outf->WriteOString("/sfnts ["); - h.OpenString(); - h.BlockWrite(sfntP, 12); /* stream out the Offset Table */ - h.BlockWrite(sfntP+12, 16 * numTables); /* stream out the Table Directory */ - - for (i=0; i sfntLen) - { - SAL_WARN( "vcl.fonts", "DumpSfnts claimed to have " - << numTables << " tables, but only space for " << i); - break; - } - - sal_uInt32 tag = GetUInt32(sfntP, 12 + 16 * i); - sal_uInt32 off = GetUInt32(sfntP, 12 + 16 * i + 8); - if (off > sfntLen) - { - SAL_WARN( "vcl.fonts", "DumpSfnts claims offset of " - << off << " but max possible is " << sfntLen); - break; - } - sal_uInt8 *pRecordStart = sfntP + off; - sal_uInt32 len = GetUInt32(sfntP, nLargestFixedOffsetPos); - sal_uInt32 nMaxLenPossible = sfntLen - off; - if (len > nMaxLenPossible) - { - SAL_WARN( "vcl.fonts", "DumpSfnts claims len of " - << len << " but only space for " << nMaxLenPossible); - break; - } - - if (tag != T_glyf) - { - h.BlockWrite(pRecordStart, len); - } - else - { - sal_uInt8 *glyf = pRecordStart; - sal_uInt8 *eof = pRecordStart + nMaxLenPossible; - for (sal_uInt32 j = 0; j < go.nGlyphs - 1; j++) - { - sal_uInt32 nStartOffset = go.offs[j]; - sal_uInt8 *pSubRecordStart = glyf + nStartOffset; - if (pSubRecordStart > eof) - { - SAL_WARN( "vcl.fonts", "DumpSfnts start glyf claims offset of " - << pSubRecordStart - sfntP << " but max possible is " << eof - sfntP); - break; - } - - sal_uInt32 nEndOffset = go.offs[j + 1]; - sal_uInt8 *pSubRecordEnd = glyf + nEndOffset; - if (pSubRecordEnd > eof) - { - SAL_WARN( "vcl.fonts", "DumpSfnts end glyf offset of " - << pSubRecordEnd - sfntP << " but max possible is " << eof - sfntP); - break; - } - - sal_uInt32 l = pSubRecordEnd - pSubRecordStart; - h.BlockWrite(pSubRecordStart, l); - } - } - h.BlockWrite(pad, (4 - (len & 3)) & 3); - } - h.CloseString(); - outf->WriteOString("] def\n"); -} - -SFErrCodes CreateT42FromTTGlyphs(TrueTypeFont *ttf, - SvStream *outf, - const char *psname, - sal_uInt16 const *glyphArray, - sal_uInt8 *encoding, - int nGlyphs) -{ - std::unique_ptr head, hhea, maxp, cvt, prep, fpgm; - std::unique_ptr glyf; - int i; - SFErrCodes res; - - sal_uInt16 ver; - sal_Int32 rev; - - int UPEm = ttf->unitsPerEm(); - - if (nGlyphs >= 256) return SFErrCodes::GlyphNum; - - assert(psname != nullptr); - - TrueTypeCreator ttcr(T_true); - - /* head */ - sal_uInt32 nTableSize; - const sal_uInt8* p = ttf->table(O_head, nTableSize); - const sal_uInt8* headP = p; - assert(p != nullptr); - head.reset(new TrueTypeTableHead(GetInt32(p, HEAD_fontRevision_offset), GetUInt16(p, HEAD_flags_offset), GetUInt16(p, HEAD_unitsPerEm_offset), p+HEAD_created_offset, GetUInt16(p, HEAD_macStyle_offset), GetUInt16(p, HEAD_lowestRecPPEM_offset), GetInt16(p, HEAD_fontDirectionHint_offset))); - ver = GetUInt16(p, HEAD_majorVersion_offset); - rev = GetInt32(p, HEAD_fontRevision_offset); - - /** hhea **/ - p = ttf->table(O_hhea, nTableSize); - if (p) - hhea.reset(new TrueTypeTableHhea(GetInt16(p, HHEA_ascender_offset), GetInt16(p, HHEA_descender_offset), GetInt16(p, HHEA_lineGap_offset), GetInt16(p, HHEA_caretSlopeRise_offset), GetInt16(p, HHEA_caretSlopeRun_offset))); - else - hhea.reset(new TrueTypeTableHhea(0, 0, 0, 0, 0)); - - /** maxp **/ - p = ttf->table(O_maxp, nTableSize); - maxp.reset(new TrueTypeTableMaxp(p, nTableSize)); - - /** cvt **/ - if ((p = ttf->table(O_cvt, nTableSize)) != nullptr) - cvt.reset(new TrueTypeTableGeneric(T_cvt, nTableSize, p)); - - /** prep **/ - if ((p = ttf->table(O_prep, nTableSize)) != nullptr) - prep.reset(new TrueTypeTableGeneric(T_prep, nTableSize, p)); - - /** fpgm **/ - if ((p = ttf->table(O_fpgm, nTableSize)) != nullptr) - fpgm.reset(new TrueTypeTableGeneric(T_fpgm, nTableSize, p)); - - /** glyf **/ - glyf.reset(new TrueTypeTableGlyf()); - std::unique_ptr gID(new sal_uInt16[nGlyphs]); - - for (i = 0; i < nGlyphs; i++) { - gID[i] = static_cast(glyf->glyfAdd(GetTTRawGlyphData(ttf, glyphArray[i]), ttf)); - } - - const int nGlyfCount = static_cast(glyf->glyfCount()); - - ttcr.AddTable(std::move(head)); ttcr.AddTable(std::move(hhea)); ttcr.AddTable(std::move(maxp)); ttcr.AddTable(std::move(cvt)); - ttcr.AddTable(std::move(prep)); ttcr.AddTable(std::move(glyf)); ttcr.AddTable(std::move(fpgm)); - - std::vector aOutBuffer; - if ((res = ttcr.StreamToMemory(aOutBuffer)) != SFErrCodes::Ok) { - return res; - } - - constexpr int bufmax = 256; - char buf[bufmax]; - - snprintf(buf, bufmax, "%%!PS-TrueTypeFont-%d.%d-%d.%d\n", static_cast(ver), static_cast(ver & 0xFF), static_cast(rev>>16), static_cast(rev & 0xFFFF)); - outf->WriteOString(buf); - snprintf(buf, bufmax, "%%%%Creator: %s %s %s\n", modname, modver, modextra); - outf->WriteOString(buf); - snprintf(buf, bufmax, "%%- Font subset generated from a source font file: '%s'\n", ttf->fileName().data()); - outf->WriteOString(buf); - snprintf(buf, bufmax, "%%- Original font name: %s\n", ttf->psname.getStr()); - outf->WriteOString(buf); - snprintf(buf, bufmax, "%%- Original font family: %s\n", ttf->family.getStr()); - outf->WriteOString(buf); - snprintf(buf, bufmax, "%%- Original font sub-family: %s\n", ttf->subfamily.getStr()); - outf->WriteOString(buf); - snprintf(buf, bufmax, "11 dict begin\n"); - outf->WriteOString(buf); - snprintf(buf, bufmax, "/FontName (%s) cvn def\n", psname); - outf->WriteOString(buf); - snprintf(buf, bufmax, "/PaintType 0 def\n"); - outf->WriteOString(buf); - snprintf(buf, bufmax, "/FontMatrix [1 0 0 1 0 0] def\n"); - outf->WriteOString(buf); - snprintf(buf, bufmax, "/FontBBox [%d %d %d %d] def\n", XUnits(UPEm, GetInt16(headP, HEAD_xMin_offset)), XUnits(UPEm, GetInt16(headP, HEAD_yMin_offset)), XUnits(UPEm, GetInt16(headP, HEAD_xMax_offset)), XUnits(UPEm, GetInt16(headP, HEAD_yMax_offset))); - outf->WriteOString(buf); - snprintf(buf, bufmax, "/FontType 42 def\n"); - outf->WriteOString(buf); - snprintf(buf, bufmax, "/Encoding 256 array def\n"); - outf->WriteOString(buf); - snprintf(buf, bufmax, " 0 1 255 {Encoding exch /.notdef put} for\n"); - outf->WriteOString(buf); - - for (i = 1; iWriteOString(buf); - } - snprintf(buf, bufmax, "/XUID [103 0 1 16#%08X %u 16#%08X 16#%08X] def\n", static_cast(rtl_crc32(0, ttf->ptr, ttf->fsize)), static_cast(nGlyphs), static_cast(rtl_crc32(0, glyphArray, nGlyphs * 2)), static_cast(rtl_crc32(0, encoding, nGlyphs))); - outf->WriteOString(buf); - - DumpSfnts(outf, aOutBuffer.data(), aOutBuffer.size()); - - /* dump charstrings */ - snprintf(buf, bufmax, "/CharStrings %d dict dup begin\n", nGlyphs); - outf->WriteOString(buf); - snprintf(buf, bufmax, "/.notdef 0 def\n"); - outf->WriteOString(buf); - for (i = 1; i < nGlyfCount; i++) { - snprintf(buf, bufmax, "/glyph%d %d def\n", i, i); - outf->WriteOString(buf); - } - snprintf(buf, bufmax, "end readonly def\n"); - outf->WriteOString(buf); - - snprintf(buf, bufmax, "FontName currentdict end definefont pop\n"); - outf->WriteOString(buf); - - return SFErrCodes::Ok; -} - bool GetTTGlobalFontHeadInfo(const AbstractTrueTypeFont *ttf, int& xMin, int& yMin, int& xMax, int& yMax, sal_uInt16& macStyle) { sal_uInt32 table_size;