vcl/inc/sft.hxx | 26 vcl/inc/unx/fontmanager.hxx | 3 vcl/source/fontsubset/sft.cxx | 190 ++--- vcl/source/fontsubset/ttcr.cxx | 930 +++++++++------------------- vcl/source/fontsubset/ttcr.hxx | 242 ++++--- vcl/unx/generic/fontmanager/fontmanager.cxx | 63 - 6 files changed, 598 insertions(+), 856 deletions(-)
New commits: commit 590796ca0866168e3129d2abd0a0197114cddcdc Author: Noel Grandin <noelgran...@gmail.com> AuthorDate: Wed Sep 21 20:44:42 2022 +0200 Commit: Noel Grandin <noel.gran...@collabora.co.uk> CommitDate: Thu Sep 22 14:48:27 2022 +0200 convert TrueTypeTable to C++ class Change-Id: I06f01c79414380e37dc006cc7f7fdce1976035f2 Reviewed-on: https://gerrit.libreoffice.org/c/core/+/140357 Tested-by: Jenkins Reviewed-by: Noel Grandin <noel.gran...@collabora.co.uk> diff --git a/vcl/inc/sft.hxx b/vcl/inc/sft.hxx index a870baf57033..05f62de655ec 100644 --- a/vcl/inc/sft.hxx +++ b/vcl/inc/sft.hxx @@ -124,7 +124,7 @@ namespace vcl typedef struct { sal_uInt32 glyphID; /**< glyph ID */ sal_uInt16 nbytes; /**< number of bytes in glyph data */ - sal_uInt8 *ptr; /**< pointer to glyph data */ + std::unique_ptr<sal_uInt8[]> ptr; /**< pointer to glyph data */ sal_uInt16 aw; /**< advance width */ sal_Int16 lsb; /**< left sidebearing */ bool compflag; /**< false- if non-composite */ @@ -135,14 +135,13 @@ namespace vcl } GlyphData; /** Structure used by the TrueType Creator and CreateTTFromTTGlyphs() */ - typedef struct { + struct NameRecord { sal_uInt16 platformID; /**< Platform ID */ sal_uInt16 encodingID; /**< Platform-specific encoding ID */ LanguageType languageID; /**< Language ID */ sal_uInt16 nameID; /**< Name ID */ - sal_uInt16 slen; /**< String length in bytes */ - sal_uInt8 *sptr; /**< Pointer to string data (not zero-terminated!) */ - } NameRecord; + std::vector<sal_uInt8> sptr; /**< string data (not zero-terminated!) */ + }; /** Return value of GetTTGlobalFontInfo() */ @@ -535,7 +534,7 @@ class TrueTypeFace; * @ingroup sft * */ - GlyphData *GetTTRawGlyphData(AbstractTrueTypeFont *ttf, sal_uInt32 glyphID); + std::unique_ptr<GlyphData> GetTTRawGlyphData(AbstractTrueTypeFont *ttf, sal_uInt32 glyphID); /** * For a specified glyph adds all component glyphs IDs to the list and @@ -559,23 +558,12 @@ class TrueTypeFace; * array of NameRecord structs * * @param ttf pointer to the TrueTypeFont struct - * @param nr pointer to the array of NameRecord structs + * @param nr reference to the vector of NameRecord structs * - * @return number of NameRecord structs * @ingroup sft */ - int GetTTNameRecords(AbstractTrueTypeFont const *ttf, NameRecord **nr); - -/** - * Deallocates previously allocated array of NameRecords. - * - * @param nr array of NameRecord structs - * @param n number of elements in the array - * - * @ingroup sft - */ - void DisposeNameRecords(NameRecord* nr, int n); + void GetTTNameRecords(AbstractTrueTypeFont const *ttf, std::vector<NameRecord>& nr); /** * Generates a new PostScript Type 3 font and dumps it to <b>outf</b> file. diff --git a/vcl/inc/unx/fontmanager.hxx b/vcl/inc/unx/fontmanager.hxx index 059ffe1a7e58..2ec06afcb435 100644 --- a/vcl/inc/unx/fontmanager.hxx +++ b/vcl/inc/unx/fontmanager.hxx @@ -50,6 +50,7 @@ namespace vcl::font { class FontSelectPattern; } +namespace vcl { struct NameRecord; } class GenericUnixSalData; namespace psp { @@ -154,7 +155,7 @@ class VCL_PLUGIN_PUBLIC PrintFontManager OString getFontFile(const PrintFont& rFont) const; std::vector<PrintFont> analyzeFontFile(int nDirID, const OString& rFileName, const char *pFormat=nullptr) const; - static OUString convertSfntName( void* pNameRecord ); // actually a NameRecord* format font subsetting code + static OUString convertSfntName( const vcl::NameRecord& rNameRecord ); // format font subsetting code static void analyzeSfntFamilyName( void const * pTTFont, std::vector< OUString >& rnames ); // actually a TrueTypeFont* from font subsetting code bool analyzeSfntFile(PrintFont& rFont) const; // finds the font id for the nFaceIndex face in this font file diff --git a/vcl/source/fontsubset/sft.cxx b/vcl/source/fontsubset/sft.cxx index 4058caef2faf..4c2bb4b3e062 100644 --- a/vcl/source/fontsubset/sft.cxx +++ b/vcl/source/fontsubset/sft.cxx @@ -89,6 +89,13 @@ struct PSPathElement 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 @@ -133,13 +140,6 @@ public: } -static void *scalloc(size_t n, size_t size) -{ - void *res = calloc(n, size); - assert(res != nullptr); - return res; -} - /*- Data access methods for data stored in big-endian format */ static sal_Int16 GetInt16(const sal_uInt8 *ptr, size_t offset) { @@ -744,7 +744,7 @@ static int GetTTGlyphOutline(AbstractTrueTypeFont *ttf, sal_uInt32 glyphID, std: /*- returns the number of items in the path -*/ -static int BSplineToPSPath(ControlPoint const *srcA, int srcCount, PSPathElement **path) +static int BSplineToPSPath(ControlPoint const *srcA, int srcCount, std::unique_ptr<PSPathElement[]>& path) { std::vector< PSPathElement > aPathList; int nPathCount = 0; @@ -757,7 +757,7 @@ static int BSplineToPSPath(ControlPoint const *srcA, int srcCount, PSPathElement int cp = 0; /*- current point */ int StartContour = 0, EndContour = 1; - *path = nullptr; + path.reset(); /* if (srcCount > 0) for(;;) */ while (srcCount > 0) { /*- srcCount does not get changed inside the loop. */ @@ -862,9 +862,8 @@ static int BSplineToPSPath(ControlPoint const *srcA, int srcCount, PSPathElement if( (nPathCount = static_cast<int>(aPathList.size())) > 0) { - *path = static_cast<PSPathElement*>(calloc(nPathCount, sizeof(PSPathElement))); - assert(*path != nullptr); - memcpy( *path, aPathList.data(), nPathCount * sizeof(PSPathElement) ); + path.reset(new PSPathElement[nPathCount]); + memcpy( path.get(), aPathList.data(), nPathCount * sizeof(PSPathElement) ); } return nPathCount; @@ -1580,7 +1579,7 @@ SFErrCodes CreateT3FromTTGlyphs(TrueTypeFont *ttf, FILE *outf, const char *fname int wmode) { std::vector<ControlPoint> pa; - PSPathElement *path; + std::unique_ptr<PSPathElement[]> path; int i, j, n; sal_uInt32 nSize; const sal_uInt8* table = ttf->table(O_head, nSize); @@ -1674,7 +1673,7 @@ SFErrCodes CreateT3FromTTGlyphs(TrueTypeFont *ttf, FILE *outf, const char *fname int r = GetTTGlyphOutline(ttf, glyphArray[i] < ttf->glyphCount() ? glyphArray[i] : 0, pa, &metrics, nullptr); if (r > 0) { - n = BSplineToPSPath(pa.data(), r, &path); + n = BSplineToPSPath(pa.data(), r, path); } else { n = 0; /* glyph might have zero contours but valid metrics ??? */ path = nullptr; @@ -1717,7 +1716,7 @@ SFErrCodes CreateT3FromTTGlyphs(TrueTypeFont *ttf, FILE *outf, const char *fname fprintf(outf, "%s", h34); - free(path); + path.reset(); } fprintf(outf, "%s", h35); @@ -1733,7 +1732,14 @@ SFErrCodes CreateTTFromTTGlyphs(AbstractTrueTypeFont *ttf, sal_uInt8 const *encoding, int nGlyphs) { - TrueTypeTable *head=nullptr, *hhea=nullptr, *maxp=nullptr, *cvt=nullptr, *prep=nullptr, *glyf=nullptr, *fpgm=nullptr, *cmap=nullptr, *name=nullptr, *post = nullptr, *os2 = nullptr; + std::unique_ptr<TrueTypeTableGeneric> cvt, prep, fpgm, os2; + std::unique_ptr<TrueTypeTableName> name; + std::unique_ptr<TrueTypeTableMaxp> maxp; + std::unique_ptr<TrueTypeTableHhea> hhea; + std::unique_ptr<TrueTypeTableHead> head; + std::unique_ptr<TrueTypeTableGlyf> glyf; + std::unique_ptr<TrueTypeTableCmap> cmap; + std::unique_ptr<TrueTypeTablePost> post; int i; SFErrCodes res; @@ -1741,62 +1747,61 @@ SFErrCodes CreateTTFromTTGlyphs(AbstractTrueTypeFont *ttf, /** name **/ - NameRecord *names = nullptr; - int n = GetTTNameRecords(ttf, &names); - name = TrueTypeTableNew_name(n, names); - DisposeNameRecords(names, n); + std::vector<NameRecord> names; + GetTTNameRecords(ttf, names); + name.reset(new TrueTypeTableName(std::move(names))); /** maxp **/ sal_uInt32 nTableSize; const sal_uInt8* p = ttf->table(O_maxp, nTableSize); - maxp = TrueTypeTableNew_maxp(p, nTableSize); + maxp.reset(new TrueTypeTableMaxp(p, nTableSize)); /** hhea **/ p = ttf->table(O_hhea, nTableSize); if (p && nTableSize >= HHEA_caretSlopeRun_offset + 2) - hhea = TrueTypeTableNew_hhea(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)); + 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 = TrueTypeTableNew_hhea(0, 0, 0, 0, 0); + hhea.reset(new TrueTypeTableHhea(0, 0, 0, 0, 0)); /** head **/ p = ttf->table(O_head, nTableSize); assert(p != nullptr); - head = TrueTypeTableNew_head(GetInt32(p, HEAD_fontRevision_offset), + 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)); + GetInt16(p, HEAD_fontDirectionHint_offset))); /** glyf **/ - glyf = TrueTypeTableNew_glyf(); - sal_uInt32* gID = static_cast<sal_uInt32*>(scalloc(nGlyphs, sizeof(sal_uInt32))); + glyf.reset(new TrueTypeTableGlyf()); + std::unique_ptr<sal_uInt32[]> gID(new sal_uInt32[nGlyphs]); for (i = 0; i < nGlyphs; i++) { - gID[i] = glyfAdd(glyf, GetTTRawGlyphData(ttf, glyphArray[i]), ttf); + gID[i] = glyf->glyfAdd(GetTTRawGlyphData(ttf, glyphArray[i]), ttf); } /** cmap **/ - cmap = TrueTypeTableNew_cmap(); + cmap.reset(new TrueTypeTableCmap()); for (i=0; i < nGlyphs; i++) { - cmapAdd(cmap, 0x010000, encoding[i], gID[i]); + cmap->cmapAdd(0x010000, encoding[i], gID[i]); } /** cvt **/ if ((p = ttf->table(O_cvt, nTableSize)) != nullptr) - cvt = TrueTypeTableNew(T_cvt, nTableSize, p); + cvt.reset(new TrueTypeTableGeneric(T_cvt, nTableSize, p)); /** prep **/ if ((p = ttf->table(O_prep, nTableSize)) != nullptr) - prep = TrueTypeTableNew(T_prep, nTableSize, p); + prep.reset(new TrueTypeTableGeneric(T_prep, nTableSize, p)); /** fpgm **/ if ((p = ttf->table(O_fpgm, nTableSize)) != nullptr) - fpgm = TrueTypeTableNew(T_fpgm, nTableSize, p); + fpgm.reset(new TrueTypeTableGeneric(T_fpgm, nTableSize, p)); /** post **/ if ((p = ttf->table(O_post, nTableSize)) != nullptr) @@ -1810,17 +1815,17 @@ SFErrCodes CreateTTFromTTGlyphs(AbstractTrueTypeFont *ttf, sal_uInt32 nFixedPitch = (POST_isFixedPitch_offset + 4 < nTableSize) ? GetUInt32(p, POST_isFixedPitch_offset) : 0; - post = TrueTypeTableNew_post(0x00030000, + post.reset(new TrueTypeTablePost(0x00030000, nItalic, nPosition, - nThickness, nFixedPitch); + nThickness, nFixedPitch)); } else - post = TrueTypeTableNew_post(0x00030000, 0, 0, 0, 0); + post.reset(new TrueTypeTablePost(0x00030000, 0, 0, 0, 0)); - ttcr.AddTable(name); ttcr.AddTable(maxp); ttcr.AddTable(hhea); - ttcr.AddTable(head); ttcr.AddTable(glyf); ttcr.AddTable(cmap); - ttcr.AddTable(cvt ); ttcr.AddTable(prep); ttcr.AddTable(fpgm); - ttcr.AddTable(post); ttcr.AddTable(os2); + ttcr.AddTable(std::move(name)); ttcr.AddTable(std::move(maxp)); ttcr.AddTable(std::move(hhea)); + ttcr.AddTable(std::move(head)); ttcr.AddTable(std::move(glyf)); ttcr.AddTable(std::move(cmap)); + ttcr.AddTable(std::move(cvt)); ttcr.AddTable(std::move(prep)); ttcr.AddTable(std::move(fpgm)); + ttcr.AddTable(std::move(post)); ttcr.AddTable(std::move(os2)); res = ttcr.StreamToMemory(rOutBuffer); #if OSL_DEBUG_LEVEL > 1 @@ -1828,8 +1833,6 @@ SFErrCodes CreateTTFromTTGlyphs(AbstractTrueTypeFont *ttf, << (int) res << "."); #endif - free(gID); - return res; } @@ -2000,7 +2003,7 @@ static void DumpSfnts(FILE *outf, sal_uInt8 *sfntP, sal_uInt32 sfntLen) assert(numTables <= 9); /* Type42 has 9 required tables */ - sal_uInt32* offs = static_cast<sal_uInt32*>(scalloc(numTables, sizeof(sal_uInt32))); + std::unique_ptr<sal_uInt32[]> offs(new sal_uInt32[numTables]); fputs("/sfnts [", outf); h.OpenString(); @@ -2072,7 +2075,6 @@ static void DumpSfnts(FILE *outf, sal_uInt8 *sfntP, sal_uInt32 sfntLen) } h.CloseString(); fputs("] def\n", outf); - free(offs); } SFErrCodes CreateT42FromTTGlyphs(TrueTypeFont *ttf, @@ -2082,7 +2084,8 @@ SFErrCodes CreateT42FromTTGlyphs(TrueTypeFont *ttf, sal_uInt8 *encoding, int nGlyphs) { - TrueTypeTable *head=nullptr, *hhea=nullptr, *maxp=nullptr, *cvt=nullptr, *prep=nullptr, *glyf=nullptr, *fpgm=nullptr; + std::unique_ptr<TrueTypeTable> head, hhea, maxp, cvt, prep, fpgm; + std::unique_ptr<TrueTypeTableGlyf> glyf; int i; SFErrCodes res; @@ -2102,47 +2105,46 @@ SFErrCodes CreateT42FromTTGlyphs(TrueTypeFont *ttf, const sal_uInt8* p = ttf->table(O_head, nTableSize); const sal_uInt8* headP = p; assert(p != nullptr); - head = TrueTypeTableNew_head(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)); + 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 = TrueTypeTableNew_hhea(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)); + 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 = TrueTypeTableNew_hhea(0, 0, 0, 0, 0); + hhea.reset(new TrueTypeTableHhea(0, 0, 0, 0, 0)); /** maxp **/ p = ttf->table(O_maxp, nTableSize); - maxp = TrueTypeTableNew_maxp(p, nTableSize); + maxp.reset(new TrueTypeTableMaxp(p, nTableSize)); /** cvt **/ if ((p = ttf->table(O_cvt, nTableSize)) != nullptr) - cvt = TrueTypeTableNew(T_cvt, nTableSize, p); + cvt.reset(new TrueTypeTableGeneric(T_cvt, nTableSize, p)); /** prep **/ if ((p = ttf->table(O_prep, nTableSize)) != nullptr) - prep = TrueTypeTableNew(T_prep, nTableSize, p); + prep.reset(new TrueTypeTableGeneric(T_prep, nTableSize, p)); /** fpgm **/ if ((p = ttf->table(O_fpgm, nTableSize)) != nullptr) - fpgm = TrueTypeTableNew(T_fpgm, nTableSize, p); + fpgm.reset(new TrueTypeTableGeneric(T_fpgm, nTableSize, p)); /** glyf **/ - glyf = TrueTypeTableNew_glyf(); - sal_uInt16* gID = static_cast<sal_uInt16*>(scalloc(nGlyphs, sizeof(sal_uInt32))); + glyf.reset(new TrueTypeTableGlyf()); + std::unique_ptr<sal_uInt16[]> gID(new sal_uInt16[nGlyphs]); for (i = 0; i < nGlyphs; i++) { - gID[i] = static_cast<sal_uInt16>(glyfAdd(glyf, GetTTRawGlyphData(ttf, glyphArray[i]), ttf)); + gID[i] = static_cast<sal_uInt16>(glyf->glyfAdd(GetTTRawGlyphData(ttf, glyphArray[i]), ttf)); } - ttcr.AddTable(head); ttcr.AddTable(hhea); ttcr.AddTable(maxp); ttcr.AddTable(cvt); - ttcr.AddTable(prep); ttcr.AddTable(glyf); ttcr.AddTable(fpgm); + 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<sal_uInt8> aOutBuffer; if ((res = ttcr.StreamToMemory(aOutBuffer)) != SFErrCodes::Ok) { - free(gID); return res; } @@ -2171,13 +2173,12 @@ SFErrCodes CreateT42FromTTGlyphs(TrueTypeFont *ttf, /* dump charstrings */ fprintf(outf, "/CharStrings %d dict dup begin\n", nGlyphs); fprintf(outf, "/.notdef 0 def\n"); - for (i = 1; i < static_cast<int>(glyfCount(glyf)); i++) { + for (i = 1; i < static_cast<int>(glyf->glyfCount()); i++) { fprintf(outf,"/glyph%d %d def\n", i, i); } fprintf(outf, "end readonly def\n"); fprintf(outf, "FontName currentdict end definefont pop\n"); - free(gID); return SFErrCodes::Ok; } @@ -2344,7 +2345,7 @@ void FillFontSubsetInfo(AbstractTrueTypeFont *ttf, FontSubsetInfo& rInfo) rInfo.m_nDescent = -aTTInfo.descender; } -GlyphData *GetTTRawGlyphData(AbstractTrueTypeFont *ttf, sal_uInt32 glyphID) +std::unique_ptr<GlyphData> GetTTRawGlyphData(AbstractTrueTypeFont *ttf, sal_uInt32 glyphID) { if (glyphID >= ttf->glyphCount()) return nullptr; @@ -2370,14 +2371,14 @@ GlyphData *GetTTRawGlyphData(AbstractTrueTypeFont *ttf, sal_uInt32 glyphID) sal_uInt32 length = nNextOffset - nOffset; - GlyphData* d = static_cast<GlyphData*>(malloc(sizeof(GlyphData))); assert(d != nullptr); + std::unique_ptr<GlyphData> d(new GlyphData); if (length > 0) { const sal_uInt8* srcptr = glyf + ttf->glyphOffset(glyphID); const size_t nChunkLen = ((length + 1) & ~1); - d->ptr = static_cast<sal_uInt8*>(malloc(nChunkLen)); assert(d->ptr != nullptr); - memcpy(d->ptr, srcptr, length); - memset(d->ptr + length, 0, nChunkLen - length); + d->ptr.reset(new sal_uInt8[nChunkLen]); + memcpy(d->ptr.get(), srcptr, length); + memset(d->ptr.get() + length, 0, nChunkLen - length); d->compflag = (GetInt16( srcptr, 0 ) < 0); } else { d->ptr = nullptr; @@ -2434,25 +2435,26 @@ GlyphData *GetTTRawGlyphData(AbstractTrueTypeFont *ttf, sal_uInt32 glyphID) return d; } -int GetTTNameRecords(AbstractTrueTypeFont const *ttf, NameRecord **nr) +void GetTTNameRecords(AbstractTrueTypeFont const *ttf, std::vector<NameRecord>& nr) { sal_uInt32 nTableSize; const sal_uInt8* table = ttf->table(O_name, nTableSize); + nr.clear(); + if (nTableSize < 6) { #if OSL_DEBUG_LEVEL > 1 SAL_WARN("vcl.fonts", "O_name table too small."); #endif - return 0; + return; } sal_uInt16 n = GetUInt16(table, 2); sal_uInt32 nStrBase = GetUInt16(table, 4); int i; - *nr = nullptr; - if (n == 0) return 0; + if (n == 0) return; const sal_uInt32 remaining_table_size = nTableSize-6; const sal_uInt32 nMinRecordSize = 12; @@ -2465,8 +2467,7 @@ int GetTTNameRecords(AbstractTrueTypeFont const *ttf, NameRecord **nr) n = nMaxRecords; } - NameRecord* rec = static_cast<NameRecord*>(calloc(n, sizeof(NameRecord))); - assert(rec); + nr.resize(n); for (i = 0; i < n; i++) { sal_uInt32 nLargestFixedOffsetPos = 6 + 10 + 12 * i; @@ -2479,51 +2480,28 @@ int GetTTNameRecords(AbstractTrueTypeFont const *ttf, NameRecord **nr) break; } - rec[i].platformID = GetUInt16(table, 6 + 0 + 12 * i); - rec[i].encodingID = GetUInt16(table, 6 + 2 + 12 * i); - rec[i].languageID = LanguageType(GetUInt16(table, 6 + 4 + 12 * i)); - rec[i].nameID = GetUInt16(table, 6 + 6 + 12 * i); - rec[i].slen = GetUInt16(table, 6 + 8 + 12 * i); + nr[i].platformID = GetUInt16(table, 6 + 0 + 12 * i); + nr[i].encodingID = GetUInt16(table, 6 + 2 + 12 * i); + nr[i].languageID = LanguageType(GetUInt16(table, 6 + 4 + 12 * i)); + nr[i].nameID = GetUInt16(table, 6 + 6 + 12 * i); + sal_uInt16 slen = GetUInt16(table, 6 + 8 + 12 * i); sal_uInt32 nStrOffset = GetUInt16(table, nLargestFixedOffsetPos); - if (rec[i].slen) { - if (nStrBase + nStrOffset + rec[i].slen >= nTableSize) - { - rec[i].sptr = nullptr; - rec[i].slen = 0; + if (slen) { + if (nStrBase + nStrOffset + slen >= nTableSize) continue; - } const sal_uInt32 rec_string = nStrBase + nStrOffset; const size_t available_space = rec_string > nTableSize ? 0 : (nTableSize - rec_string); - if (rec[i].slen <= available_space) + if (slen <= available_space) { - rec[i].sptr = static_cast<sal_uInt8 *>(malloc(rec[i].slen)); assert(rec[i].sptr != nullptr); - memcpy(rec[i].sptr, table + rec_string, rec[i].slen); + nr[i].sptr.resize(slen); + memcpy(nr[i].sptr.data(), table + rec_string, slen); } - else - { - rec[i].sptr = nullptr; - rec[i].slen = 0; - } - } else { - rec[i].sptr = nullptr; } // some fonts have 3.0 names => fix them to 3.1 - if( (rec[i].platformID == 3) && (rec[i].encodingID == 0) ) - rec[i].encodingID = 1; - } - - *nr = rec; - return n; -} - -void DisposeNameRecords(NameRecord* nr, int n) -{ - int i; - for (i = 0; i < n; i++) { - if (nr[i].sptr) free(nr[i].sptr); + if( (nr[i].platformID == 3) && (nr[i].encodingID == 0) ) + nr[i].encodingID = 1; } - free(nr); } template<size_t N> static void diff --git a/vcl/source/fontsubset/ttcr.cxx b/vcl/source/fontsubset/ttcr.cxx index cf775cc5219d..6e6620a5edb2 100644 --- a/vcl/source/fontsubset/ttcr.cxx +++ b/vcl/source/fontsubset/ttcr.cxx @@ -36,16 +36,12 @@ namespace vcl * Private Data Types */ -namespace { - struct TableEntry { sal_uInt32 tag; sal_uInt32 length; sal_uInt8 *data; }; -} - /*- Data access macros for data stored in big-endian or little-endian format */ static sal_Int16 GetInt16( const sal_uInt8* ptr, sal_uInt32 offset) { @@ -94,21 +90,23 @@ static int TableEntryCompareF(const void *l, const void *r) return (ltag == rtag) ? 0 : (ltag < rtag) ? -1 : 1; } -static int NameRecordCompareF(const void *l, const void *r) +namespace { +struct NameRecordCompareF { - NameRecord const *ll = static_cast<NameRecord const *>(l); - NameRecord const *rr = static_cast<NameRecord const *>(r); - - if (ll->platformID != rr->platformID) { - return (ll->platformID < rr->platformID) ? -1 : 1; - } else if (ll->encodingID != rr->encodingID) { - return (ll->encodingID < rr->encodingID) ? -1 : 1; - } else if (ll->languageID != rr->languageID) { - return (ll->languageID < rr->languageID) ? -1 : 1; - } else if (ll->nameID != rr->nameID) { - return (ll->nameID < rr->nameID) ? -1 : 1; + bool operator()(const NameRecord& l, const NameRecord& r) const + { + if (l.platformID != r.platformID) { + return l.platformID < r.platformID; + } else if (l.encodingID != r.encodingID) { + return l.encodingID < r.encodingID; + } else if (l.languageID != r.languageID) { + return l.languageID < r.languageID; + } else if (l.nameID != r.nameID) { + return l.nameID < r.nameID; + } + return false; } - return 0; +}; } static sal_uInt32 CheckSum(sal_uInt32 *ptr, sal_uInt32 length) @@ -121,59 +119,31 @@ static sal_uInt32 CheckSum(sal_uInt32 *ptr, sal_uInt32 length) return sum; } -static void *smalloc(sal_uInt32 size) -{ - void *res = malloc(size); - assert(res != nullptr); - return res; -} - -static void *scalloc(sal_uInt32 n, sal_uInt32 size) -{ - void *res = calloc(n, size); - assert(res != nullptr); - return res; -} - /* * Public functions */ TrueTypeCreator::TrueTypeCreator(sal_uInt32 _tag) { - this->tables = listNewEmpty(); - listSetElementDtor(this->tables, TrueTypeTableDispose); - - this->tag = _tag; + this->m_tag = _tag; } -void TrueTypeCreator::AddTable(TrueTypeTable *table) +void TrueTypeCreator::AddTable(std::unique_ptr<TrueTypeTable> table) { if (table != nullptr) { - listAppend(this->tables, table); + this->m_tables.push_back(std::move(table)); } } void TrueTypeCreator::RemoveTable(sal_uInt32 tableTag) { - if (!listCount(this->tables)) - return; - - listToFirst(this->tables); - int done = 0; - do { - if (static_cast<TrueTypeTable *>(listCurrent(this->tables))->tag == tableTag) - { - listRemove(this->tables); - } - else + for (auto it = this->m_tables.begin(); it != this->m_tables.end(); ++it) + { + if ((*it)->m_tag == tableTag) { - if (listNext(this->tables)) - { - done = 1; - } + this->m_tables.erase(it); } - } while (!done); + } } SFErrCodes TrueTypeCreator::StreamToMemory(std::vector<sal_uInt8>& rOutBuffer) @@ -183,24 +153,25 @@ SFErrCodes TrueTypeCreator::StreamToMemory(std::vector<sal_uInt8>& rOutBuffer) sal_uInt32 *p; sal_uInt8 *head = nullptr; /* saved pointer to the head table data for checkSumAdjustment calculation */ - if (listIsEmpty(this->tables)) return SFErrCodes::TtFormat; + if (this->m_tables.empty()) + return SFErrCodes::TtFormat; ProcessTables(); /* ProcessTables() adds 'loca' and 'hmtx' */ - sal_uInt16 numTables = listCount(this->tables); + sal_uInt16 numTables = this->m_tables.size(); - TableEntry* te = static_cast<TableEntry*>(scalloc(numTables, sizeof(TableEntry))); - TableEntry* e = te; + std::unique_ptr<TableEntry[]> te(new TableEntry[numTables]); - listToFirst(this->tables); - do { - GetRawData(static_cast<TrueTypeTable *>(listCurrent(this->tables)), &e->data, &e->length, &e->tag); - ++e; - } while (listNext(this->tables)); + int teIdx = 0; + for (auto const & e : this->m_tables) + { + e->GetRawData(&te[teIdx]); + ++teIdx; + } - qsort(te, numTables, sizeof(TableEntry), TableEntryCompareF); + qsort(te.get(), numTables, sizeof(TableEntry), TableEntryCompareF); do { searchRange *= 2; @@ -222,7 +193,7 @@ SFErrCodes TrueTypeCreator::StreamToMemory(std::vector<sal_uInt8>& rOutBuffer) sal_uInt8* ttf = rOutBuffer.data(); /* Offset Table */ - PutUInt32(this->tag, ttf, 0); + PutUInt32(this->m_tag, ttf, 0); PutUInt16(numTables, ttf, 4); PutUInt16(searchRange, ttf, 6); PutUInt16(entrySelector, ttf, 8); @@ -244,7 +215,7 @@ SFErrCodes TrueTypeCreator::StreamToMemory(std::vector<sal_uInt8>& rOutBuffer) /* if ((te[i].length & 3) != 0) offset += (4 - (te[i].length & 3)) & 3; */ } - free(te); + te.reset(); p = reinterpret_cast<sal_uInt32 *>(ttf); for (int i = 0; i < static_cast<int>(s) / 4; ++i) checkSumAdjustment += p[i]; @@ -304,25 +275,27 @@ struct CmapSubTable { sal_uInt32 id; /* subtable ID (platform/encoding ID) */ sal_uInt32 n; /* number of used translation pairs */ sal_uInt32 m; /* number of allocated translation pairs */ - sal_uInt32 *xc; /* character array */ - sal_uInt32 *xg; /* glyph array */ + std::unique_ptr<sal_uInt32[]> xc; /* character array */ + std::unique_ptr<sal_uInt32[]> xg; /* glyph array */ }; +} + struct table_cmap { sal_uInt32 n; /* number of used CMAP sub-tables */ sal_uInt32 m; /* number of allocated CMAP sub-tables */ - CmapSubTable *s; /* sorted array of sub-tables */ + std::unique_ptr<CmapSubTable[]> s; /* sorted array of sub-tables */ }; struct tdata_generic { sal_uInt32 tag; sal_uInt32 nbytes; - sal_uInt8 *ptr; + std::unique_ptr<sal_uInt8[]> ptr; }; struct tdata_loca { sal_uInt32 nbytes; /* number of bytes in loca table */ - sal_uInt8 *ptr; /* pointer to the data */ + std::unique_ptr<sal_uInt8[]> ptr; /* pointer to the data */ }; struct tdata_post { @@ -334,115 +307,50 @@ struct tdata_post { void *ptr; /* format-specific pointer */ }; -} - /* allocate memory for a TT table */ -static sal_uInt8 *ttmalloc(sal_uInt32 nbytes) +static std::unique_ptr<sal_uInt8[]> ttmalloc(sal_uInt32 nbytes) { - sal_uInt32 n; - - n = (nbytes + 3) & sal_uInt32(~3); - sal_uInt8* res = static_cast<sal_uInt8*>(calloc(n, 1)); - assert(res != nullptr); - - return res; + sal_uInt32 n = (nbytes + 3) & sal_uInt32(~3); + return std::make_unique<sal_uInt8[]>(n); } -static void FreeGlyphData(void *ptr) -{ - GlyphData *p = static_cast<GlyphData *>(ptr); - if (p->ptr) free(p->ptr); - free(p); -} +TrueTypeTable::~TrueTypeTable() {} -static void TrueTypeTableDispose_generic(TrueTypeTable *_this) +TrueTypeTableGeneric::~TrueTypeTableGeneric() { - if (_this) { - if (_this->data) { - tdata_generic *pdata = static_cast<tdata_generic *>(_this->data); - if (pdata->nbytes) free(pdata->ptr); - free(_this->data); - } - free(_this); - } } -static void TrueTypeTableDispose_head(TrueTypeTable *_this) +TrueTypeTableHead::~TrueTypeTableHead() { - if (_this) { - if (_this->data) free(_this->data); - free(_this); - } } -static void TrueTypeTableDispose_hhea(TrueTypeTable *_this) +TrueTypeTableHhea::~TrueTypeTableHhea() { - if (_this) { - if (_this->data) free(_this->data); - free(_this); - } } -static void TrueTypeTableDispose_loca(TrueTypeTable *_this) +TrueTypeTableLoca::~TrueTypeTableLoca() { - if (_this) { - if (_this->data) { - tdata_loca *p = static_cast<tdata_loca *>(_this->data); - if (p->ptr) free(p->ptr); - free(_this->data); - } - free(_this); - } } -static void TrueTypeTableDispose_maxp(TrueTypeTable *_this) +TrueTypeTableMaxp::~TrueTypeTableMaxp() { - if (_this) { - if (_this->data) free(_this->data); - free(_this); - } } -static void TrueTypeTableDispose_glyf(TrueTypeTable *_this) +TrueTypeTableGlyf::~TrueTypeTableGlyf() { - if (_this) { - if (_this->data) listDispose(static_cast<list>(_this->data)); - free(_this); - } } -static void TrueTypeTableDispose_cmap(TrueTypeTable *_this) +TrueTypeTableCmap::~TrueTypeTableCmap() { - if (!_this) return; - - table_cmap *t = static_cast<table_cmap *>(_this->data); - if (t) { - CmapSubTable *s = t->s; - if (s) { - for (sal_uInt32 i = 0; i < t->m; i++) { - if (s[i].xc) free(s[i].xc); - if (s[i].xg) free(s[i].xg); - } - free(s); - } - free(t); - } - free(_this); } -static void TrueTypeTableDispose_name(TrueTypeTable *_this) +TrueTypeTableName::~TrueTypeTableName() { - if (_this) { - if (_this->data) listDispose(static_cast<list>(_this->data)); - free(_this); - } } -static void TrueTypeTableDispose_post(TrueTypeTable *_this) +TrueTypeTablePost::~TrueTypeTablePost() { - if (!_this) return; - - tdata_post *p = static_cast<tdata_post *>(_this->data); + tdata_post *p = this->m_postdata.get(); if (p) { if (p->format == 0x00030000) { /* do nothing */ @@ -454,134 +362,108 @@ static void TrueTypeTableDispose_post(TrueTypeTable *_this) << std::uppercase << static_cast<int>(p->format) << "."); } - free(p); } - free(_this); } -/* destructor vtable */ -struct { - sal_uInt32 tag; - void (*f)(TrueTypeTable *); -} const vtable1[] = +int TrueTypeTableGeneric::GetRawData(TableEntry* te) { - {0, TrueTypeTableDispose_generic}, - {T_head, TrueTypeTableDispose_head}, - {T_hhea, TrueTypeTableDispose_hhea}, - {T_loca, TrueTypeTableDispose_loca}, - {T_maxp, TrueTypeTableDispose_maxp}, - {T_glyf, TrueTypeTableDispose_glyf}, - {T_cmap, TrueTypeTableDispose_cmap}, - {T_name, TrueTypeTableDispose_name}, - {T_post, TrueTypeTableDispose_post} + assert(this->m_generic != nullptr); -}; - -static int GetRawData_generic(TrueTypeTable *_this, sal_uInt8 **ptr, sal_uInt32 *len, sal_uInt32 *tag) -{ - assert(_this != nullptr); - assert(_this->data != nullptr); - - *ptr = static_cast<tdata_generic *>(_this->data)->ptr; - *len = static_cast<tdata_generic *>(_this->data)->nbytes; - *tag = static_cast<tdata_generic *>(_this->data)->tag; + te->data = this->m_generic->ptr.get(); + te->length = this->m_generic->nbytes; + te->tag = this->m_generic->tag; return TTCR_OK; } -static int GetRawData_head(TrueTypeTable *_this, sal_uInt8 **ptr, sal_uInt32 *len, sal_uInt32 *tag) +int TrueTypeTableHead::GetRawData(TableEntry* te) { - *len = HEAD_Length; - *ptr = static_cast<sal_uInt8 *>(_this->data); - *tag = T_head; + te->length = HEAD_Length; + te->data = this->m_head.get(); + te->tag = T_head; return TTCR_OK; } -static int GetRawData_hhea(TrueTypeTable *_this, sal_uInt8 **ptr, sal_uInt32 *len, sal_uInt32 *tag) +int TrueTypeTableHhea::GetRawData(TableEntry* te) { - *len = HHEA_Length; - *ptr = static_cast<sal_uInt8 *>(_this->data); - *tag = T_hhea; + te->length = HHEA_Length; + te->data = this->m_hhea.get(); + te->tag = T_hhea; return TTCR_OK; } -static int GetRawData_loca(TrueTypeTable *_this, sal_uInt8 **ptr, sal_uInt32 *len, sal_uInt32 *tag) +int TrueTypeTableLoca::GetRawData(TableEntry* te) { - tdata_loca *p; - - assert(_this->data != nullptr); + assert(this->m_loca != nullptr); - p = static_cast<tdata_loca *>(_this->data); + if (m_loca->nbytes == 0) return TTCR_ZEROGLYPHS; - if (p->nbytes == 0) return TTCR_ZEROGLYPHS; - - *ptr = p->ptr; - *len = p->nbytes; - *tag = T_loca; + te->data = m_loca->ptr.get(); + te->length = m_loca->nbytes; + te->tag = T_loca; return TTCR_OK; } -static int GetRawData_maxp(TrueTypeTable *_this, sal_uInt8 **ptr, sal_uInt32 *len, sal_uInt32 *tag) +int TrueTypeTableMaxp::GetRawData(TableEntry* te) { - *len = MAXP_Version1Length; - *ptr = static_cast<sal_uInt8 *>(_this->data); - *tag = T_maxp; + te->length = MAXP_Version1Length; + te->data = this->m_maxp.get(); + te->tag = T_maxp; return TTCR_OK; } -static int GetRawData_glyf(TrueTypeTable *_this, sal_uInt8 **ptr, sal_uInt32 *len, sal_uInt32 *tag) +int TrueTypeTableGlyf::GetRawData(TableEntry* te) { sal_uInt32 n, nbytes = 0; - list l = static_cast<list>(_this->data); /* sal_uInt16 curID = 0; */ /* to check if glyph IDs are sequential and start from zero */ - sal_uInt8 *p; - *ptr = nullptr; - *len = 0; - *tag = 0; + te->data = nullptr; + te->length = 0; + te->tag = 0; - if (listCount(l) == 0) return TTCR_ZEROGLYPHS; + if (m_list.size() == 0) return TTCR_ZEROGLYPHS; - listToFirst(l); - do { + for (const std::unique_ptr<GlyphData>& pGlyph : m_list) + { /* if (((GlyphData *) listCurrent(l))->glyphID != curID++) return TTCR_GLYPHSEQ; */ - nbytes += static_cast<GlyphData *>(listCurrent(l))->nbytes; - } while (listNext(l)); + nbytes += pGlyph->nbytes; + } - p = _this->rawdata = ttmalloc(nbytes); + m_rawdata = ttmalloc(nbytes); - listToFirst(l); - do { - n = static_cast<GlyphData *>(listCurrent(l))->nbytes; + auto p = m_rawdata.get(); + for (const std::unique_ptr<GlyphData>& pGlyph : m_list) + { + n = pGlyph->nbytes; if (n != 0) { - memcpy(p, static_cast<GlyphData *>(listCurrent(l))->ptr, n); + memcpy(p, pGlyph->ptr.get(), n); p += n; } - } while (listNext(l)); + } - *len = nbytes; - *ptr = _this->rawdata; - *tag = T_glyf; + te->length = nbytes; + te->data = m_rawdata.get(); + te->tag = T_glyf; return TTCR_OK; } /* cmap packers */ -static sal_uInt8 *PackCmapType0(CmapSubTable const *s, sal_uInt32 *length) +static std::unique_ptr<sal_uInt8[]> PackCmapType0(CmapSubTable const *s, sal_uInt32 *length) { - sal_uInt8* ptr = static_cast<sal_uInt8*>(smalloc(262)); - sal_uInt8 *p = ptr + 6; + std::unique_ptr<sal_uInt8[]> ptr(new sal_uInt8[262]); + sal_uInt8 *p = ptr.get() + 6; sal_uInt32 i, j; sal_uInt16 g; - PutUInt16(0, ptr, 0); - PutUInt16(262, ptr, 2); - PutUInt16(0, ptr, 4); + PutUInt16(0, ptr.get(), 0); + PutUInt16(262, ptr.get(), 2); + PutUInt16(0, ptr.get(), 4); for (i = 0; i < 256; i++) { g = 0; @@ -596,18 +478,18 @@ static sal_uInt8 *PackCmapType0(CmapSubTable const *s, sal_uInt32 *length) return ptr; } -static sal_uInt8 *PackCmapType6(CmapSubTable const *s, sal_uInt32 *length) +static std::unique_ptr<sal_uInt8[]> PackCmapType6(CmapSubTable const *s, sal_uInt32 *length) { - sal_uInt8* ptr = static_cast<sal_uInt8*>(smalloc(s->n*2 + 10)); - sal_uInt8 *p = ptr + 10; + std::unique_ptr<sal_uInt8[]> ptr(new sal_uInt8[s->n*2 + 10]); + sal_uInt8 *p = ptr.get() + 10; sal_uInt32 i, j; sal_uInt16 g; - PutUInt16(6, ptr, 0); - PutUInt16(static_cast<sal_uInt16>(s->n*2+10), ptr, 2); - PutUInt16(0, ptr, 4); - PutUInt16(0, ptr, 6); - PutUInt16(static_cast<sal_uInt16>(s->n), ptr, 8 ); + PutUInt16(6, ptr.get(), 0); + PutUInt16(static_cast<sal_uInt16>(s->n*2+10), ptr.get(), 2); + PutUInt16(0, ptr.get(), 4); + PutUInt16(0, ptr.get(), 6); + PutUInt16(static_cast<sal_uInt16>(s->n), ptr.get(), 8 ); for (i = 0; i < s->n; i++) { g = 0; @@ -623,7 +505,7 @@ static sal_uInt8 *PackCmapType6(CmapSubTable const *s, sal_uInt32 *length) } /* XXX it only handles Format 0 encoding tables */ -static sal_uInt8 *PackCmap(CmapSubTable const *s, sal_uInt32 *length) +static std::unique_ptr<sal_uInt8[]> PackCmap(CmapSubTable const *s, sal_uInt32 *length) { if( s->xg[s->n-1] > 0xff ) return PackCmapType6(s, length); @@ -631,9 +513,8 @@ static sal_uInt8 *PackCmap(CmapSubTable const *s, sal_uInt32 *length) return PackCmapType0(s, length); } -static int GetRawData_cmap(TrueTypeTable *_this, sal_uInt8 **ptr, sal_uInt32 *len, sal_uInt32 *tag) +int TrueTypeTableCmap::GetRawData(TableEntry* te) { - table_cmap *t; sal_uInt32 i; sal_uInt32 tlen = 0; sal_uInt32 l; @@ -641,88 +522,76 @@ static int GetRawData_cmap(TrueTypeTable *_this, sal_uInt8 **ptr, sal_uInt32 *le sal_uInt8 *cmap; sal_uInt32 coffset; - assert(_this != nullptr); - t = static_cast<table_cmap *>(_this->data); - assert(t != nullptr); - assert(t->n != 0); + assert(m_cmap); + assert(m_cmap->n != 0); - sal_uInt8** subtables = static_cast<sal_uInt8**>(scalloc(t->n, sizeof(sal_uInt8 *))); - sal_uInt32* sizes = static_cast<sal_uInt32*>(scalloc(t->n, sizeof(sal_uInt32))); + std::unique_ptr<std::unique_ptr<sal_uInt8[]>[]> subtables(new std::unique_ptr<sal_uInt8[]>[m_cmap->n]); + std::unique_ptr<sal_uInt32[]> sizes(new sal_uInt32[m_cmap->n]); - for (i = 0; i < t->n; i++) { - subtables[i] = PackCmap(t->s+i, &l); + for (i = 0; i < m_cmap->n; i++) { + subtables[i] = PackCmap(m_cmap->s.get()+i, &l); sizes[i] = l; tlen += l; } - cmapsize = tlen + 4 + 8 * t->n; - _this->rawdata = cmap = ttmalloc(cmapsize); + cmapsize = tlen + 4 + 8 * m_cmap->n; + this->m_rawdata = ttmalloc(cmapsize); + cmap = this->m_rawdata.get(); PutUInt16(0, cmap, 0); - PutUInt16(static_cast<sal_uInt16>(t->n), cmap, 2); - coffset = 4 + t->n * 8; + PutUInt16(static_cast<sal_uInt16>(m_cmap->n), cmap, 2); + coffset = 4 + m_cmap->n * 8; - for (i = 0; i < t->n; i++) { - PutUInt16(static_cast<sal_uInt16>(t->s[i].id >> 16), cmap + 4, i * 8); - PutUInt16(static_cast<sal_uInt16>(t->s[i].id & 0xFF), cmap + 4, 2 + i * 8); + for (i = 0; i < m_cmap->n; i++) { + PutUInt16(static_cast<sal_uInt16>(m_cmap->s[i].id >> 16), cmap + 4, i * 8); + PutUInt16(static_cast<sal_uInt16>(m_cmap->s[i].id & 0xFF), cmap + 4, 2 + i * 8); PutUInt32(coffset, cmap + 4, 4 + i * 8); - memcpy(cmap + coffset, subtables[i], sizes[i]); - free(subtables[i]); + memcpy(cmap + coffset, subtables[i].get(), sizes[i]); + subtables[i].reset(); coffset += sizes[i]; } - free(subtables); - free(sizes); + subtables.reset(); + sizes.reset(); - *ptr = cmap; - *len = cmapsize; - *tag = T_cmap; + te->data = cmap; + te->length = cmapsize; + te->tag = T_cmap; return TTCR_OK; } -static int GetRawData_name(TrueTypeTable *_this, sal_uInt8 **ptr, sal_uInt32 *len, sal_uInt32 *tag) +int TrueTypeTableName::GetRawData(TableEntry* te) { - list l; sal_Int16 i=0, n; /* number of Name Records */ int stringLen = 0; sal_uInt8 *p1, *p2; - *ptr = nullptr; - *len = 0; - *tag = 0; + te->data = nullptr; + te->length = 0; + te->tag = 0; - assert(_this != nullptr); - l = static_cast<list>(_this->data); - assert(l != nullptr); + if ((n = static_cast<sal_Int16>(m_list.size())) == 0) return TTCR_NONAMES; - if ((n = static_cast<sal_Int16>(listCount(l))) == 0) return TTCR_NONAMES; + std::vector<NameRecord> nr = m_list; - NameRecord* nr = static_cast<NameRecord*>(scalloc(n, sizeof(NameRecord))); - - listToFirst(l); - - do { - memcpy(nr+i, listCurrent(l), sizeof(NameRecord)); - stringLen += nr[i].slen; - i++; - } while (listNext(l)); + for (const NameRecord & rName : m_list) + stringLen += rName.sptr.size(); if (stringLen > 65535) { - free(nr); return TTCR_NAMETOOLONG; } - qsort(nr, n, sizeof(NameRecord), NameRecordCompareF); + std::sort(nr.begin(), nr.end(), NameRecordCompareF()); int nameLen = stringLen + 12 * n + 6; - sal_uInt8* name = ttmalloc(nameLen); + std::unique_ptr<sal_uInt8[]> name = ttmalloc(nameLen); - PutUInt16(0, name, 0); - PutUInt16(n, name, 2); - PutUInt16(static_cast<sal_uInt16>(6 + 12 * n), name, 4); + PutUInt16(0, name.get(), 0); + PutUInt16(n, name.get(), 2); + PutUInt16(static_cast<sal_uInt16>(6 + 12 * n), name.get(), 4); - p1 = name + 6; + p1 = name.get() + 6; p2 = p1 + 12 * n; for (i = 0; i < n; i++) { @@ -730,45 +599,45 @@ static int GetRawData_name(TrueTypeTable *_this, sal_uInt8 **ptr, sal_uInt32 *le PutUInt16(nr[i].encodingID, p1, 2); PutUInt16(static_cast<sal_uInt16>(nr[i].languageID), p1, 4); PutUInt16(nr[i].nameID, p1, 6); - PutUInt16(nr[i].slen, p1, 8); - PutUInt16(static_cast<sal_uInt16>(p2 - (name + 6 + 12 * n)), p1, 10); - if (nr[i].slen) { - memcpy(p2, nr[i].sptr, nr[i].slen); + PutUInt16(nr[i].sptr.size(), p1, 8); + PutUInt16(static_cast<sal_uInt16>(p2 - (name.get() + 6 + 12 * n)), p1, 10); + if (nr[i].sptr.size()) { + memcpy(p2, nr[i].sptr.data(), nr[i].sptr.size()); } /* {int j; for(j=0; j<nr[i].slen; j++) printf("%c", nr[i].sptr[j]); printf("\n"); }; */ - p2 += nr[i].slen; + p2 += nr[i].sptr.size(); p1 += 12; } - free(nr); - _this->rawdata = name; + nr.clear(); + this->m_rawdata = std::move(name); - *ptr = name; - *len = static_cast<sal_uInt16>(nameLen); - *tag = T_name; + te->data = this->m_rawdata.get(); + te->length = static_cast<sal_uInt16>(nameLen); + te->tag = T_name; /*{int j; for(j=0; j<nameLen; j++) printf("%c", name[j]); }; */ return TTCR_OK; } -static int GetRawData_post(TrueTypeTable *_this, sal_uInt8 **ptr, sal_uInt32 *len, sal_uInt32 *tag) +int TrueTypeTablePost::GetRawData(TableEntry* te) { - tdata_post *p = static_cast<tdata_post *>(_this->data); - sal_uInt8 *post = nullptr; + tdata_post *p = this->m_postdata.get(); + std::unique_ptr<sal_uInt8[]> post; sal_uInt32 postLen = 0; int ret; - if (_this->rawdata) free(_this->rawdata); + this->m_rawdata.reset(); if (p->format == 0x00030000) { postLen = 32; post = ttmalloc(postLen); - PutUInt32(0x00030000, post, 0); - PutUInt32(p->italicAngle, post, 4); - PutUInt16(p->underlinePosition, post, 8); - PutUInt16(p->underlineThickness, post, 10); - PutUInt16(static_cast<sal_uInt16>(p->isFixedPitch), post, 12); + PutUInt32(0x00030000, post.get(), 0); + PutUInt32(p->italicAngle, post.get(), 4); + PutUInt16(p->underlinePosition, post.get(), 8); + PutUInt16(p->underlineThickness, post.get(), 10); + PutUInt16(static_cast<sal_uInt16>(p->isFixedPitch), post.get(), 12); ret = TTCR_OK; } else { SAL_WARN("vcl.fonts", "Unrecognized format of a post table: " @@ -780,30 +649,14 @@ static int GetRawData_post(TrueTypeTable *_this, sal_uInt8 **ptr, sal_uInt32 *le ret = TTCR_POSTFORMAT; } - *ptr = _this->rawdata = post; - *len = postLen; - *tag = T_post; + this->m_rawdata = std::move(post); + te->data = this->m_rawdata.get(); + te->length = postLen; + te->tag = T_post; return ret; } -struct { - sal_uInt32 tag; - int (*f)(TrueTypeTable *, sal_uInt8 **, sal_uInt32 *, sal_uInt32 *); -} const vtable2[] = -{ - {0, GetRawData_generic}, - {T_head, GetRawData_head}, - {T_hhea, GetRawData_hhea}, - {T_loca, GetRawData_loca}, - {T_maxp, GetRawData_maxp}, - {T_glyf, GetRawData_glyf}, - {T_cmap, GetRawData_cmap}, - {T_name, GetRawData_name}, - {T_post, GetRawData_post} - -}; - /* * TrueTypeTable public methods */ @@ -819,40 +672,46 @@ struct { * */ -TrueTypeTable *TrueTypeTableNew(sal_uInt32 tag, +TrueTypeTableGeneric::TrueTypeTableGeneric(sal_uInt32 tag, sal_uInt32 nbytes, const sal_uInt8* ptr) + : TrueTypeTable(0), + m_generic(new tdata_generic) { - TrueTypeTable* table = static_cast<TrueTypeTable*>(smalloc(sizeof(TrueTypeTable))); - tdata_generic* pdata = static_cast<tdata_generic*>(smalloc(sizeof(tdata_generic))); - pdata->nbytes = nbytes; - pdata->tag = tag; + m_generic->nbytes = nbytes; + m_generic->tag = tag; if (nbytes) { - pdata->ptr = ttmalloc(nbytes); - memcpy(pdata->ptr, ptr, nbytes); - } else { - pdata->ptr = nullptr; + m_generic->ptr = ttmalloc(nbytes); + memcpy(m_generic->ptr.get(), ptr, nbytes); } +} - table->tag = 0; - table->data = pdata; - table->rawdata = nullptr; - - return table; +TrueTypeTableGeneric::TrueTypeTableGeneric(sal_uInt32 tag, + sal_uInt32 nbytes, + std::unique_ptr<sal_uInt8[]> ptr) + : TrueTypeTable(0), + m_generic(new tdata_generic) +{ + m_generic->nbytes = nbytes; + m_generic->tag = tag; + if (nbytes) { + m_generic->ptr = std::move(ptr); + } } -TrueTypeTable *TrueTypeTableNew_head(sal_uInt32 fontRevision, +TrueTypeTableHead::TrueTypeTableHead(sal_uInt32 fontRevision, sal_uInt16 flags, sal_uInt16 unitsPerEm, const sal_uInt8* created, sal_uInt16 macStyle, sal_uInt16 lowestRecPPEM, sal_Int16 fontDirectionHint) + : TrueTypeTable(T_head) + , m_head(ttmalloc(HEAD_Length)) { assert(created != nullptr); - TrueTypeTable* table = static_cast<TrueTypeTable*>(smalloc(sizeof(TrueTypeTable))); - sal_uInt8* ptr = ttmalloc(HEAD_Length); + sal_uInt8* ptr = m_head.get(); PutUInt32(0x00010000, ptr, 0); /* version */ PutUInt32(fontRevision, ptr, 4); @@ -865,22 +724,17 @@ TrueTypeTable *TrueTypeTableNew_head(sal_uInt32 fontRevision, PutUInt16(lowestRecPPEM, ptr, 46); PutUInt16(fontDirectionHint, ptr, 48); PutUInt16(0, ptr, 52); /* glyph data format: 0 */ - - table->data = static_cast<void *>(ptr); - table->tag = T_head; - table->rawdata = nullptr; - - return table; } -TrueTypeTable *TrueTypeTableNew_hhea(sal_Int16 ascender, +TrueTypeTableHhea::TrueTypeTableHhea(sal_Int16 ascender, sal_Int16 descender, sal_Int16 linegap, sal_Int16 caretSlopeRise, sal_Int16 caretSlopeRun) + : TrueTypeTable(T_hhea), + m_hhea(ttmalloc(HHEA_Length)) { - TrueTypeTable* table = static_cast<TrueTypeTable*>(smalloc(sizeof(TrueTypeTable))); - sal_uInt8* ptr = ttmalloc(HHEA_Length); + sal_uInt8* ptr = m_hhea.get(); PutUInt32(0x00010000, ptr, 0); /* version */ PutUInt16(ascender, ptr, 4); @@ -894,185 +748,85 @@ TrueTypeTable *TrueTypeTableNew_hhea(sal_Int16 ascender, PutUInt16(0, ptr, 28); /* reserved 4 */ PutUInt16(0, ptr, 30); /* reserved 5 */ PutUInt16(0, ptr, 32); /* metricDataFormat */ - - table->data = static_cast<void *>(ptr); - table->tag = T_hhea; - table->rawdata = nullptr; - - return table; } -TrueTypeTable *TrueTypeTableNew_loca() +TrueTypeTableLoca::TrueTypeTableLoca() + : TrueTypeTable(T_loca), + m_loca(new tdata_loca) { - TrueTypeTable* table = static_cast<TrueTypeTable*>(smalloc(sizeof(TrueTypeTable))); - table->data = smalloc(sizeof(tdata_loca)); - - static_cast<tdata_loca *>(table->data)->nbytes = 0; - static_cast<tdata_loca *>(table->data)->ptr = nullptr; - - table->tag = T_loca; - table->rawdata = nullptr; - - return table; + this->m_loca->nbytes = 0; + this->m_loca->ptr = nullptr; } -TrueTypeTable *TrueTypeTableNew_maxp( const sal_uInt8* maxp, int size) +TrueTypeTableMaxp::TrueTypeTableMaxp( const sal_uInt8* maxp, int size) + : TrueTypeTable(T_maxp) { - TrueTypeTable* table = static_cast<TrueTypeTable*>(smalloc(sizeof(TrueTypeTable))); - table->data = ttmalloc(MAXP_Version1Length); + this->m_maxp = ttmalloc(MAXP_Version1Length); if (maxp && size == MAXP_Version1Length) { - memcpy(table->data, maxp, MAXP_Version1Length); + memcpy(this->m_maxp.get(), maxp, MAXP_Version1Length); } - - table->tag = T_maxp; - table->rawdata = nullptr; - - return table; } -TrueTypeTable *TrueTypeTableNew_glyf() +TrueTypeTableGlyf::TrueTypeTableGlyf() + : TrueTypeTable(T_glyf) { - TrueTypeTable* table = static_cast<TrueTypeTable*>(smalloc(sizeof(TrueTypeTable))); - list l = listNewEmpty(); - - assert(l != nullptr); - - listSetElementDtor(l, FreeGlyphData); - - table->data = l; - table->rawdata = nullptr; - table->tag = T_glyf; - - return table; } -TrueTypeTable *TrueTypeTableNew_cmap() +TrueTypeTableCmap::TrueTypeTableCmap() + : TrueTypeTable(T_cmap) + , m_cmap(new table_cmap) { - TrueTypeTable* table = static_cast<TrueTypeTable*>(smalloc(sizeof(TrueTypeTable))); - table_cmap* cmap = static_cast<table_cmap*>(smalloc(sizeof(table_cmap))); - - cmap->n = 0; - cmap->m = CMAP_SUBTABLE_INIT; - cmap->s = static_cast<CmapSubTable *>(scalloc(CMAP_SUBTABLE_INIT, sizeof(CmapSubTable))); - - table->data = cmap; - - table->rawdata = nullptr; - table->tag = T_cmap; - - return table; + m_cmap->n = 0; + m_cmap->m = CMAP_SUBTABLE_INIT; + m_cmap->s.reset(new CmapSubTable[CMAP_SUBTABLE_INIT]); } -static void DisposeNameRecord(void *ptr) +TrueTypeTableName::TrueTypeTableName(int n, NameRecord const *nr) + : TrueTypeTable(T_name) { - if (ptr != nullptr) { - NameRecord *nr = static_cast<NameRecord *>(ptr); - if (nr->sptr) free(nr->sptr); - free(ptr); + m_list.resize(n); + for (int i = 0; i < n; i++) { + const NameRecord* p = nr + i; + m_list[i] = *p; } } -static NameRecord* NameRecordNewCopy(NameRecord const *nr) +TrueTypeTableName::TrueTypeTableName(std::vector<NameRecord> nr) + : TrueTypeTable(T_name) + , m_list(std::move(nr)) { - NameRecord* p = static_cast<NameRecord*>(smalloc(sizeof(NameRecord))); - - memcpy(p, nr, sizeof(NameRecord)); - - if (p->slen) { - p->sptr = static_cast<sal_uInt8*>(smalloc(p->slen)); - memcpy(p->sptr, nr->sptr, p->slen); - } - - return p; -} - -TrueTypeTable *TrueTypeTableNew_name(int n, NameRecord const *nr) -{ - TrueTypeTable* table = static_cast<TrueTypeTable*>(smalloc(sizeof(TrueTypeTable))); - list l = listNewEmpty(); - - assert(l != nullptr); - - listSetElementDtor(l, DisposeNameRecord); - - if (n != 0) { - int i; - for (i = 0; i < n; i++) { - listAppend(l, NameRecordNewCopy(nr+i)); - } - } - - table->data = l; - table->rawdata = nullptr; - table->tag = T_name; - - return table; } -TrueTypeTable *TrueTypeTableNew_post(sal_Int32 format, +TrueTypeTablePost::TrueTypeTablePost(sal_Int32 format, sal_Int32 italicAngle, sal_Int16 underlinePosition, sal_Int16 underlineThickness, sal_uInt32 isFixedPitch) + : TrueTypeTable(T_post) + , m_postdata(new tdata_post) { assert(format == 0x00030000); /* Only format 3.0 is supported at this time */ - TrueTypeTable* table = static_cast<TrueTypeTable*>(smalloc(sizeof(TrueTypeTable))); - tdata_post* post = static_cast<tdata_post*>(smalloc(sizeof(tdata_post))); - - post->format = format; - post->italicAngle = italicAngle; - post->underlinePosition = underlinePosition; - post->underlineThickness = underlineThickness; - post->isFixedPitch = isFixedPitch; - post->ptr = nullptr; - - table->data = post; - table->rawdata = nullptr; - table->tag = T_post; - - return table; -} - -int GetRawData(TrueTypeTable *_this, sal_uInt8 **ptr, sal_uInt32 *len, sal_uInt32 *tag) -{ - /* XXX do a binary search */ - assert(_this != nullptr); - assert(ptr != nullptr); - assert(len != nullptr); - assert(tag != nullptr); - - *ptr = nullptr; *len = 0; *tag = 0; - - if (_this->rawdata) { - free(_this->rawdata); - _this->rawdata = nullptr; - } - - for(size_t i=0; i < SAL_N_ELEMENTS(vtable2); i++) { - if (_this->tag == vtable2[i].tag) { - return vtable2[i].f(_this, ptr, len, tag); - } - } - assert(!"Unknown TrueType table."); - return TTCR_UNKNOWN; + m_postdata->format = format; + m_postdata->italicAngle = italicAngle; + m_postdata->underlinePosition = underlinePosition; + m_postdata->underlineThickness = underlineThickness; + m_postdata->isFixedPitch = isFixedPitch; + m_postdata->ptr = nullptr; } -void cmapAdd(TrueTypeTable *table, sal_uInt32 id, sal_uInt32 c, sal_uInt32 g) +void TrueTypeTableCmap::cmapAdd(sal_uInt32 id, sal_uInt32 c, sal_uInt32 g) { sal_uInt32 i, found; - table_cmap *t; CmapSubTable *s; - assert(table != nullptr); - assert(table->tag == T_cmap); - t = static_cast<table_cmap *>(table->data); assert(t != nullptr); - s = t->s; assert(s != nullptr); + assert(m_cmap); + s = m_cmap->s.get(); assert(s != nullptr); found = 0; - for (i = 0; i < t->n; i++) { + for (i = 0; i < m_cmap->n; i++) { if (s[i].id == id) { found = 1; break; @@ -1080,44 +834,39 @@ void cmapAdd(TrueTypeTable *table, sal_uInt32 id, sal_uInt32 c, sal_uInt32 g) } if (!found) { - if (t->n == t->m) { - CmapSubTable* tmp = static_cast<CmapSubTable*>(scalloc(t->m + CMAP_SUBTABLE_INCR, sizeof(CmapSubTable))); - memcpy(tmp, s, sizeof(CmapSubTable) * t->m); - t->m += CMAP_SUBTABLE_INCR; - free(s); - s = tmp; - t->s = s; + if (m_cmap->n == m_cmap->m) { + std::unique_ptr<CmapSubTable[]> tmp(new CmapSubTable[m_cmap->m + CMAP_SUBTABLE_INCR]); + memcpy(tmp.get(), s, sizeof(CmapSubTable) * m_cmap->m); + m_cmap->m += CMAP_SUBTABLE_INCR; + s = tmp.get(); + m_cmap->s = std::move(tmp); } - for (i = 0; i < t->n; i++) { + for (i = 0; i < m_cmap->n; i++) { if (s[i].id > id) break; } - if (i < t->n) { - memmove(s+i+1, s+i, t->n-i); + if (i < m_cmap->n) { + memmove(s+i+1, s+i, m_cmap->n-i); } - t->n++; + m_cmap->n++; s[i].id = id; s[i].n = 0; s[i].m = CMAP_PAIR_INIT; - s[i].xc = static_cast<sal_uInt32*>(scalloc(CMAP_PAIR_INIT, sizeof(sal_uInt32))); - s[i].xg = static_cast<sal_uInt32*>(scalloc(CMAP_PAIR_INIT, sizeof(sal_uInt32))); + s[i].xc.reset(new sal_uInt32[CMAP_PAIR_INIT]); + s[i].xg.reset(new sal_uInt32[CMAP_PAIR_INIT]); } if (s[i].n == s[i].m) { - sal_uInt32* tmp1 = static_cast<sal_uInt32*>(scalloc(s[i].m + CMAP_PAIR_INCR, sizeof(sal_uInt32))); - sal_uInt32* tmp2 = static_cast<sal_uInt32*>(scalloc(s[i].m + CMAP_PAIR_INCR, sizeof(sal_uInt32))); - assert(tmp1 != nullptr); - assert(tmp2 != nullptr); - memcpy(tmp1, s[i].xc, sizeof(sal_uInt32) * s[i].m); - memcpy(tmp2, s[i].xg, sizeof(sal_uInt32) * s[i].m); + std::unique_ptr<sal_uInt32[]> tmp1(new sal_uInt32[s[i].m + CMAP_PAIR_INCR]); + std::unique_ptr<sal_uInt32[]> tmp2(new sal_uInt32[s[i].m + CMAP_PAIR_INCR]); + memcpy(tmp1.get(), s[i].xc.get(), sizeof(sal_uInt32) * s[i].m); + memcpy(tmp2.get(), s[i].xg.get(), sizeof(sal_uInt32) * s[i].m); s[i].m += CMAP_PAIR_INCR; - free(s[i].xc); - free(s[i].xg); - s[i].xc = tmp1; - s[i].xg = tmp2; + s[i].xc = std::move(tmp1); + s[i].xg = std::move(tmp2); } s[i].xc[s[i].n] = c; @@ -1125,30 +874,24 @@ void cmapAdd(TrueTypeTable *table, sal_uInt32 id, sal_uInt32 c, sal_uInt32 g) s[i].n++; } -sal_uInt32 glyfAdd(TrueTypeTable *table, GlyphData *glyphdata, AbstractTrueTypeFont *fnt) +sal_uInt32 TrueTypeTableGlyf::glyfAdd(std::unique_ptr<GlyphData> glyphdata, AbstractTrueTypeFont *fnt) { - list l; sal_uInt32 currentID; int ret, n, ncomponents; - assert(table != nullptr); - assert(table->tag == T_glyf); - if (!glyphdata) return sal_uInt32(~0); std::vector< sal_uInt32 > glyphlist; ncomponents = GetTTGlyphComponents(fnt, glyphdata->glyphID, glyphlist); - l = static_cast<list>(table->data); - if (listCount(l) > 0) { - listToLast(l); - ret = n = static_cast<GlyphData *>(listCurrent(l))->newID + 1; + if (m_list.size() > 0) { + ret = n = m_list.back()->newID + 1; } else { ret = n = 0; } glyphdata->newID = n++; - listAppend(l, glyphdata); + m_list.push_back(std::move(glyphdata)); if (ncomponents > 1 && glyphlist.size() > 1 ) { @@ -1160,43 +903,31 @@ sal_uInt32 glyfAdd(TrueTypeTable *table, GlyphData *glyphdata, AbstractTrueTypeF int found = 0; currentID = *it; /* XXX expensive! should be rewritten with sorted arrays! */ - listToFirst(l); - do { - if (static_cast<GlyphData *>(listCurrent(l))->glyphID == currentID) { + for (const std::unique_ptr<GlyphData>& pGlyph : m_list) + { + if (pGlyph->glyphID == currentID) { found = 1; break; } - } while (listNext(l)); + } if (!found) { - GlyphData *gd = GetTTRawGlyphData(fnt, currentID); + std::unique_ptr<GlyphData> gd = GetTTRawGlyphData(fnt, currentID); gd->newID = n++; - listAppend(l, gd); + m_list.push_back(std::move(gd)); } - } while( ++it != glyphlist.end() ); + } while( ++it != glyphlist.end() ); } return ret; } -sal_uInt32 glyfCount(const TrueTypeTable *table) -{ - assert(table != nullptr); - assert(table->tag == T_glyf); - return listCount(static_cast<list>(table->data)); -} - TrueTypeTable *TrueTypeCreator::FindTable(sal_uInt32 tableTag) { - if (listIsEmpty(this->tables)) return nullptr; - - listToFirst(this->tables); - - do { - if (static_cast<TrueTypeTable *>(listCurrent(this->tables))->tag == tableTag) { - return static_cast<TrueTypeTable*>(listCurrent(this->tables)); + for (const std::unique_ptr<TrueTypeTable>& p : this->m_tables) + if (p->m_tag == tableTag) { + return p.get(); } - } while (listNext(this->tables)); return nullptr; } @@ -1218,37 +949,40 @@ TrueTypeTable *TrueTypeCreator::FindTable(sal_uInt32 tableTag) */ void TrueTypeCreator::ProcessTables() { - TrueTypeTable *glyf, *loca, *head, *maxp, *hhea; - list glyphlist; + TrueTypeTableHhea *hhea = nullptr; + TrueTypeTableMaxp *maxp = nullptr; + TrueTypeTableHead *head = nullptr; + std::unique_ptr<TrueTypeTableLoca> loca; + TrueTypeTableGlyf *glyf = nullptr; sal_uInt32 nGlyphs, locaLen = 0, glyfLen = 0; sal_Int16 xMin = 0, yMin = 0, xMax = 0, yMax = 0; sal_uInt32 i = 0; sal_Int16 indexToLocFormat; - sal_uInt8 *hmtxPtr, *hheaPtr; + std::unique_ptr<sal_uInt8[]> hmtxPtr; + sal_uInt8 *hheaPtr; sal_uInt32 hmtxSize; sal_uInt8 *p1, *p2; sal_uInt16 maxPoints = 0, maxContours = 0, maxCompositePoints = 0, maxCompositeContours = 0; int nlsb = 0; - sal_uInt32 *gid; /* array of old glyphIDs */ + std::unique_ptr<sal_uInt32[]> gid; /* array of old glyphIDs */ - glyf = FindTable(T_glyf); - glyphlist = static_cast<list>(glyf->data); - nGlyphs = listCount(glyphlist); + glyf = static_cast<TrueTypeTableGlyf*>(FindTable(T_glyf)); + std::vector<std::unique_ptr<GlyphData>>& glyphlist = glyf->m_list; + nGlyphs = glyphlist.size(); if (!nGlyphs) { SAL_WARN("vcl.fonts", "no glyphs found in ProcessTables"); return; } - gid = static_cast<sal_uInt32*>(scalloc(nGlyphs, sizeof(sal_uInt32))); + gid.reset(new sal_uInt32[nGlyphs]); RemoveTable(T_loca); RemoveTable(T_hmtx); /* XXX Need to make sure that composite glyphs do not break during glyph renumbering */ - listToFirst(glyphlist); - do { - GlyphData *gd = static_cast<GlyphData *>(listCurrent(glyphlist)); + for (const std::unique_ptr<GlyphData>& gd : glyphlist) + { glyfLen += gd->nbytes; /* XXX if (gd->nbytes & 1) glyfLen++; */ @@ -1259,16 +993,16 @@ void TrueTypeCreator::ProcessTables() /* printf("IDs: %d %d.\n", gd->glyphID, gd->newID); */ if (gd->nbytes >= 10) { - sal_Int16 z = GetInt16(gd->ptr, 2); + sal_Int16 z = GetInt16(gd->ptr.get(), 2); if (z < xMin) xMin = z; - z = GetInt16(gd->ptr, 4); + z = GetInt16(gd->ptr.get(), 4); if (z < yMin) yMin = z; - z = GetInt16(gd->ptr, 6); + z = GetInt16(gd->ptr.get(), 6); if (z > xMax) xMax = z; - z = GetInt16(gd->ptr, 8); + z = GetInt16(gd->ptr.get(), 8); if (z > yMax) yMax = z; } @@ -1280,25 +1014,23 @@ void TrueTypeCreator::ProcessTables() if (gd->ncontours > maxCompositeContours) maxCompositeContours = gd->ncontours; } - } while (listNext(glyphlist)); + } indexToLocFormat = (glyfLen / 2 > 0xFFFF) ? 1 : 0; locaLen = indexToLocFormat ? (nGlyphs + 1) << 2 : (nGlyphs + 1) << 1; - sal_uInt8* glyfPtr = ttmalloc(glyfLen); - sal_uInt8* locaPtr = ttmalloc(locaLen); - TTSimpleGlyphMetrics* met = static_cast<TTSimpleGlyphMetrics*>(scalloc(nGlyphs, sizeof(TTSimpleGlyphMetrics))); + std::unique_ptr<sal_uInt8[]> glyfPtr = ttmalloc(glyfLen); + std::unique_ptr<sal_uInt8[]> locaPtr = ttmalloc(locaLen); + std::unique_ptr<TTSimpleGlyphMetrics[]> met(new TTSimpleGlyphMetrics[nGlyphs]); i = 0; - listToFirst(glyphlist); - p1 = glyfPtr; - p2 = locaPtr; - do { - GlyphData *gd = static_cast<GlyphData *>(listCurrent(glyphlist)); - + p1 = glyfPtr.get(); + p2 = locaPtr.get(); + for (const std::unique_ptr<GlyphData>& gd : glyphlist) + { if (gd->compflag && gd->nbytes > 10) { /* re-number all components */ sal_uInt16 flags, index; - sal_uInt8 *ptr = gd->ptr + 10; + sal_uInt8 *ptr = gd->ptr.get() + 10; size_t nRemaining = gd->nbytes - 10; do { if (nRemaining < 4) @@ -1351,13 +1083,13 @@ void TrueTypeCreator::ProcessTables() } if (gd->nbytes != 0) { - memcpy(p1, gd->ptr, gd->nbytes); + memcpy(p1, gd->ptr.get(), gd->nbytes); } if (indexToLocFormat == 1) { - PutUInt32(p1 - glyfPtr, p2, 0); + PutUInt32(p1 - glyfPtr.get(), p2, 0); p2 += 4; } else { - PutUInt16(static_cast<sal_uInt16>((p1 - glyfPtr) >> 1), p2, 0); + PutUInt16(static_cast<sal_uInt16>((p1 - glyfPtr.get()) >> 1), p2, 0); p2 += 2; } p1 += gd->nbytes; @@ -1366,35 +1098,35 @@ void TrueTypeCreator::ProcessTables() met[i].adv = gd->aw; met[i].sb = gd->lsb; i++; - } while (listNext(glyphlist)); + } - free(gid); + gid.reset(); if (indexToLocFormat == 1) { - PutUInt32(p1 - glyfPtr, p2, 0); + PutUInt32(p1 - glyfPtr.get(), p2, 0); } else { - PutUInt16(static_cast<sal_uInt16>((p1 - glyfPtr) >> 1), p2, 0); + PutUInt16(static_cast<sal_uInt16>((p1 - glyfPtr.get()) >> 1), p2, 0); } - glyf->rawdata = glyfPtr; + glyf->m_rawdata = std::move(glyfPtr); - loca = TrueTypeTableNew_loca(); assert(loca != nullptr); - static_cast<tdata_loca *>(loca->data)->ptr = locaPtr; - static_cast<tdata_loca *>(loca->data)->nbytes = locaLen; + loca.reset(new TrueTypeTableLoca()); + loca->m_loca->ptr = std::move(locaPtr); + loca->m_loca->nbytes = locaLen; - AddTable(loca); + AddTable(std::move(loca)); - head = FindTable(T_head); - sal_uInt8* const pHeadData = static_cast<sal_uInt8*>(head->data); + head = static_cast<TrueTypeTableHead*>(FindTable(T_head)); + sal_uInt8* const pHeadData = head->m_head.get(); PutInt16(xMin, pHeadData, HEAD_xMin_offset); PutInt16(yMin, pHeadData, HEAD_yMin_offset); PutInt16(xMax, pHeadData, HEAD_xMax_offset); PutInt16(yMax, pHeadData, HEAD_yMax_offset); PutInt16(indexToLocFormat, pHeadData, HEAD_indexToLocFormat_offset); - maxp = FindTable(T_maxp); + maxp = static_cast<TrueTypeTableMaxp*>(FindTable(T_maxp)); - sal_uInt8* const pMaxpData = static_cast<sal_uInt8*>(maxp->data); + sal_uInt8* const pMaxpData = maxp->m_maxp.get(); PutUInt16(static_cast<sal_uInt16>(nGlyphs), pMaxpData, MAXP_numGlyphs_offset); PutUInt16(maxPoints, pMaxpData, MAXP_maxPoints_offset); PutUInt16(maxContours, pMaxpData, MAXP_maxContours_offset); @@ -1404,8 +1136,8 @@ void TrueTypeCreator::ProcessTables() /* * Generate an htmx table and update hhea table */ - hhea = FindTable(T_hhea); assert(hhea != nullptr); - hheaPtr = static_cast<sal_uInt8 *>(hhea->data); + hhea = static_cast<TrueTypeTableHhea*>(FindTable(T_hhea)); assert(hhea != nullptr); + hheaPtr = hhea->m_hhea.get(); if (nGlyphs > 2) { for (i = nGlyphs - 1; i > 0; i--) { if (met[i].adv != met[i-1].adv) break; @@ -1414,7 +1146,7 @@ void TrueTypeCreator::ProcessTables() } hmtxSize = (nGlyphs - nlsb) * 4 + nlsb * 2; hmtxPtr = ttmalloc(hmtxSize); - p1 = hmtxPtr; + p1 = hmtxPtr.get(); for (i = 0; i < nGlyphs; i++) { if (i < nGlyphs - nlsb) { @@ -1427,10 +1159,8 @@ void TrueTypeCreator::ProcessTables() } } - AddTable(TrueTypeTableNew(T_hmtx, hmtxSize, hmtxPtr)); + AddTable(std::make_unique<TrueTypeTableGeneric>(T_hmtx, hmtxSize, std::move(hmtxPtr))); PutUInt16(static_cast<sal_uInt16>(nGlyphs - nlsb), hheaPtr, 34); - free(hmtxPtr); - free(met); } /** @@ -1438,34 +1168,10 @@ void TrueTypeCreator::ProcessTables() */ TrueTypeCreator::~TrueTypeCreator() { - listDispose(this->tables); } } // namespace vcl -extern "C" -{ - /** - * Destructor for the TrueTypeTable object. - */ - void TrueTypeTableDispose(void * arg) - { - vcl::TrueTypeTable *_this = static_cast<vcl::TrueTypeTable *>(arg); - /* XXX do a binary search */ - assert(_this != nullptr); - - if (_this->rawdata) free(_this->rawdata); - - for(size_t i=0; i < SAL_N_ELEMENTS(vcl::vtable1); i++) { - if (_this->tag == vcl::vtable1[i].tag) { - vcl::vtable1[i].f(_this); - return; - } - } - assert(!"Unknown TrueType table."); - } -} - #ifdef TEST_TTCR static sal_uInt32 mkTag(sal_uInt8 a, sal_uInt8 b, sal_uInt8 c, sal_uInt8 d) { return (a << 24) | (b << 16) | (c << 8) | d; diff --git a/vcl/source/fontsubset/ttcr.hxx b/vcl/source/fontsubset/ttcr.hxx index 6eeea93a8d01..27cea69b9693 100644 --- a/vcl/source/fontsubset/ttcr.hxx +++ b/vcl/source/fontsubset/ttcr.hxx @@ -24,13 +24,17 @@ #pragma once -#include "list.h" #include <sft.hxx> #include <vector> namespace vcl { -struct TrueTypeTable; +class TrueTypeTable; +struct tdata_post; +struct tdata_loca; +struct table_cmap; +struct tdata_generic; +struct TableEntry; /* TrueType data types */ @@ -39,13 +43,6 @@ struct TrueTypeTable; sal_Int16 lsb; } longHorMetrics; -/* A generic base class for all TrueType tables */ - struct TrueTypeTable { - sal_uInt32 tag; /* table tag */ - sal_uInt8 *rawdata; /* raw data allocated by GetRawData_*() */ - void *data; /* table specific data */ - }; - /** Error codes for most functions */ enum TTCRErrCodes { TTCR_OK, /**< no error */ @@ -67,7 +64,7 @@ struct TrueTypeTable; /** * Adds a TrueType table to the TrueType creator. */ - void AddTable(TrueTypeTable *table); + void AddTable(std::unique_ptr<TrueTypeTable> table); /** * Removes a TrueType table from the TrueType creator if it is stored there. * It also calls a TrueTypeTable destructor. @@ -93,32 +90,54 @@ struct TrueTypeTable; TrueTypeTable *FindTable(sal_uInt32 tag); void ProcessTables(); - sal_uInt32 tag; /**< TrueType file tag */ - list tables; /**< List of table tags and pointers */ + sal_uInt32 m_tag; /**< TrueType file tag */ + std::vector<std::unique_ptr<TrueTypeTable>> m_tables; /**< List of table tags and pointers */ }; -/** - * This function converts the data of a TrueType table to a raw array of bytes. - * It may allocates the memory for it and returns the size of the raw data in bytes. - * If memory is allocated it does not need to be freed by the caller of this function, - * since the pointer to it is stored in the TrueTypeTable and it is freed by the destructor - * @return TTCRErrCode - * - */ + /* A generic base class for all TrueType tables */ + class TrueTypeTable { + protected: + TrueTypeTable(sal_uInt32 tag_) : m_tag(tag_) {} - int GetRawData(TrueTypeTable *, sal_uInt8 **ptr, sal_uInt32 *len, sal_uInt32 *tag); + public: + virtual ~TrueTypeTable(); -/** - * - * Creates a new raw TrueType table. The difference between this constructor and - * TrueTypeTableNew_tag constructors is that the latter create structured tables - * while this constructor just copies memory pointed to by ptr to its buffer - * and stores its length. This constructor is suitable for data that is not - * supposed to be processed in any way, just written to the resulting TTF file. - */ - TrueTypeTable *TrueTypeTableNew(sal_uInt32 tag, - sal_uInt32 nbytes, - const sal_uInt8* ptr); + /** + * This function converts the data of a TrueType table to a raw array of bytes. + * It may allocates the memory for it and returns the size of the raw data in bytes. + * If memory is allocated it does not need to be freed by the caller of this function, + * since the pointer to it is stored in the TrueTypeTable and it is freed by the destructor + * @return TTCRErrCode + * + */ + virtual int GetRawData(TableEntry*) = 0; + + sal_uInt32 m_tag = 0; /* table tag */ + std::unique_ptr<sal_uInt8[]> m_rawdata; /* raw data allocated by GetRawData_*() */ + }; + + class TrueTypeTableGeneric : public TrueTypeTable + { + public: + /** + * + * Creates a new raw TrueType table. The difference between this constructor and + * TrueTypeTableNew_tag constructors is that the latter create structured tables + * while this constructor just copies memory pointed to by ptr to its buffer + * and stores its length. This constructor is suitable for data that is not + * supposed to be processed in any way, just written to the resulting TTF file. + */ + TrueTypeTableGeneric(sal_uInt32 tag, + sal_uInt32 nbytes, + const sal_uInt8* ptr); + TrueTypeTableGeneric(sal_uInt32 tag, + sal_uInt32 nbytes, + std::unique_ptr<sal_uInt8[]> ptr); + virtual ~TrueTypeTableGeneric() override; + virtual int GetRawData(TableEntry*) override; + private: + std::unique_ptr<tdata_generic> m_generic; + }; /** * Creates a new 'head' table for a TrueType font. @@ -126,30 +145,54 @@ struct TrueTypeTable; * rest of the tables in the TrueType font this table should be the last one added * to the font. */ - TrueTypeTable *TrueTypeTableNew_head(sal_uInt32 fontRevision, - sal_uInt16 flags, - sal_uInt16 unitsPerEm, - const sal_uInt8 *created, - sal_uInt16 macStyle, - sal_uInt16 lowestRecPPEM, - sal_Int16 fontDirectionHint); + class TrueTypeTableHead : public TrueTypeTable + { + public: + TrueTypeTableHead(sal_uInt32 fontRevision, + sal_uInt16 flags, + sal_uInt16 unitsPerEm, + const sal_uInt8 *created, + sal_uInt16 macStyle, + sal_uInt16 lowestRecPPEM, + sal_Int16 fontDirectionHint); + virtual ~TrueTypeTableHead() override; + virtual int GetRawData(TableEntry*) override; + + std::unique_ptr<sal_uInt8[]> m_head; + }; /** * Creates a new 'hhea' table for a TrueType font. * Allocates memory for it and stores it in the hhea pointer. */ - TrueTypeTable *TrueTypeTableNew_hhea(sal_Int16 ascender, + class TrueTypeTableHhea : public TrueTypeTable + { + public: + TrueTypeTableHhea(sal_Int16 ascender, sal_Int16 descender, sal_Int16 linegap, sal_Int16 caretSlopeRise, sal_Int16 caretSlopeRun); + virtual ~TrueTypeTableHhea() override; + virtual int GetRawData(TableEntry*) override; + + std::unique_ptr<sal_uInt8[]> m_hhea; + }; /** * Creates a new empty 'loca' table for a TrueType font. * * INTERNAL: gets called only from ProcessTables(); */ - TrueTypeTable *TrueTypeTableNew_loca(); + class TrueTypeTableLoca : public TrueTypeTable + { + public: + TrueTypeTableLoca(); + virtual ~TrueTypeTableLoca() override; + virtual int GetRawData(TableEntry*) override; + + std::unique_ptr<tdata_loca> m_loca; + }; /** * Creates a new 'maxp' table based on an existing maxp table. @@ -157,17 +200,63 @@ struct TrueTypeTable; * size specifies the size of existing maxp table for * error-checking purposes */ - TrueTypeTable *TrueTypeTableNew_maxp( const sal_uInt8* maxp, int size); + class TrueTypeTableMaxp : public TrueTypeTable + { + public: + TrueTypeTableMaxp(const sal_uInt8* maxp, int size); + virtual ~TrueTypeTableMaxp() override; + virtual int GetRawData(TableEntry*) override; + + std::unique_ptr<sal_uInt8[]> m_maxp; + }; /** * Creates a new empty 'glyf' table. */ - TrueTypeTable *TrueTypeTableNew_glyf(); + class TrueTypeTableGlyf : public TrueTypeTable + { + public: + TrueTypeTableGlyf(); + virtual ~TrueTypeTableGlyf() override; + virtual int GetRawData(TableEntry*) override; + + /** + * Add a glyph to a glyf table. + * + * @return glyphID of the glyph in the new font + * + * NOTE: This function does not duplicate GlyphData, so memory will be + * deallocated in the table destructor + */ + sal_uInt32 glyfAdd(std::unique_ptr<GlyphData> glyphdata, AbstractTrueTypeFont *fnt); + + /** + * Query the number of glyphs currently stored in the 'glyf' table + * + */ + sal_uInt32 glyfCount() { return m_list.size(); } + + std::vector<std::unique_ptr<GlyphData>> m_list; + }; /** * Creates a new empty 'cmap' table. */ - TrueTypeTable *TrueTypeTableNew_cmap(); + class TrueTypeTableCmap : public TrueTypeTable + { + public: + TrueTypeTableCmap(); + virtual ~TrueTypeTableCmap() override; + virtual int GetRawData(TableEntry*) override; + + /** + * Add a character/glyph pair to a cmap table + */ + void cmapAdd(sal_uInt32 id, sal_uInt32 c, sal_uInt32 g); + + private: + std::unique_ptr<table_cmap> m_cmap; + }; /** * Creates a new 'name' table. If n != 0 the table gets populated by @@ -175,53 +264,34 @@ struct TrueTypeTable; * memory for its own copy of NameRecords, so nr array has to * be explicitly deallocated when it is not needed. */ - TrueTypeTable *TrueTypeTableNew_name(int n, NameRecord const *nr); + class TrueTypeTableName : public TrueTypeTable + { + public: + TrueTypeTableName(int n, NameRecord const *nr); + TrueTypeTableName(std::vector<NameRecord> nr); + virtual ~TrueTypeTableName() override; + virtual int GetRawData(TableEntry*) override; + private: + std::vector<NameRecord> m_list; + }; /** * Creates a new 'post' table of one of the supported formats */ - TrueTypeTable *TrueTypeTableNew_post(sal_Int32 format, - sal_Int32 italicAngle, - sal_Int16 underlinePosition, - sal_Int16 underlineThickness, - sal_uInt32 isFixedPitch); - -// Table manipulation functions - -/** - * Add a character/glyph pair to a cmap table - */ - void cmapAdd(TrueTypeTable *, sal_uInt32 id, sal_uInt32 c, sal_uInt32 g); - -/** - * Add a glyph to a glyf table. - * - * @return glyphID of the glyph in the new font - * - * NOTE: This function does not duplicate GlyphData, so memory will be - * deallocated in the table destructor - */ - sal_uInt32 glyfAdd(TrueTypeTable *, GlyphData *glyphdata, AbstractTrueTypeFont *fnt); - -/** - * Query the number of glyphs currently stored in the 'glyf' table - * - */ - sal_uInt32 glyfCount(const TrueTypeTable *); + class TrueTypeTablePost : public TrueTypeTable + { + public: + TrueTypeTablePost(sal_Int32 format, + sal_Int32 italicAngle, + sal_Int16 underlinePosition, + sal_Int16 underlineThickness, + sal_uInt32 isFixedPitch); + virtual ~TrueTypeTablePost() override; + virtual int GetRawData(TableEntry*) override; + private: + std::unique_ptr<tdata_post> m_postdata; + }; } // namespace -extern "C" -{ -/** - * Destructor for the TrueTypeTable object. - */ - void TrueTypeTableDispose(void *); - -/** - * TrueTypeCreator destructor. It calls destructors for all TrueTypeTables added to it. - */ - void TrueTypeCreatorDispose(vcl::TrueTypeCreator *_this); -} - /* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/vcl/unx/generic/fontmanager/fontmanager.cxx b/vcl/unx/generic/fontmanager/fontmanager.cxx index 1a5a598427a4..8a95cebb3aec 100644 --- a/vcl/unx/generic/fontmanager/fontmanager.cxx +++ b/vcl/unx/generic/fontmanager/fontmanager.cxx @@ -29,6 +29,7 @@ #include <tools/urlobj.hxx> +#include <o3tl/string_view.hxx> #include <osl/file.hxx> #include <rtl/ustrbuf.hxx> @@ -313,25 +314,24 @@ std::vector<fontID> PrintFontManager::findFontFileIDs( int nDirID, const OString return aIds; } -OUString PrintFontManager::convertSfntName( void* pRecord ) +OUString PrintFontManager::convertSfntName( const NameRecord& rNameRecord ) { - NameRecord* pNameRecord = static_cast<NameRecord*>(pRecord); OUString aValue; if( - ( pNameRecord->platformID == 3 && ( pNameRecord->encodingID == 0 || pNameRecord->encodingID == 1 ) ) // MS, Unicode + ( rNameRecord.platformID == 3 && ( rNameRecord.encodingID == 0 || rNameRecord.encodingID == 1 ) ) // MS, Unicode || - ( pNameRecord->platformID == 0 ) // Apple, Unicode + ( rNameRecord.platformID == 0 ) // Apple, Unicode ) { - OUStringBuffer aName( pNameRecord->slen/2 ); - const sal_uInt8* pNameBuffer = pNameRecord->sptr; - for(int n = 0; n < pNameRecord->slen/2; n++ ) + OUStringBuffer aName( rNameRecord.sptr.size()/2 ); + const sal_uInt8* pNameBuffer = rNameRecord.sptr.data(); + for(size_t n = 0; n < rNameRecord.sptr.size()/2; n++ ) aName.append( static_cast<sal_Unicode>(getUInt16BE( pNameBuffer )) ); aValue = aName.makeStringAndClear(); } - else if( pNameRecord->platformID == 3 ) + else if( rNameRecord.platformID == 3 ) { - if( pNameRecord->encodingID >= 2 && pNameRecord->encodingID <= 6 ) + if( rNameRecord.encodingID >= 2 && rNameRecord.encodingID <= 6 ) { /* * and now for a special kind of madness: @@ -340,8 +340,8 @@ OUString PrintFontManager::convertSfntName( void* pRecord ) * while others code two bytes as a uint16 and swap to BE */ OStringBuffer aName; - const sal_uInt8* pNameBuffer = pNameRecord->sptr; - for(int n = 0; n < pNameRecord->slen/2; n++ ) + const sal_uInt8* pNameBuffer = rNameRecord.sptr.data(); + for(size_t n = 0; n < rNameRecord.sptr.size()/2; n++ ) { sal_Unicode aCode = static_cast<sal_Unicode>(getUInt16BE( pNameBuffer )); char aChar = aCode >> 8; @@ -351,7 +351,7 @@ OUString PrintFontManager::convertSfntName( void* pRecord ) if( aChar ) aName.append( aChar ); } - switch( pNameRecord->encodingID ) + switch( rNameRecord.encodingID ) { case 2: aValue = OStringToOUString( aName, RTL_TEXTENCODING_MS_932 ); @@ -371,11 +371,11 @@ OUString PrintFontManager::convertSfntName( void* pRecord ) } } } - else if( pNameRecord->platformID == 1 ) + else if( rNameRecord.platformID == 1 ) { - OString aName(reinterpret_cast<char*>(pNameRecord->sptr), pNameRecord->slen); + std::string_view aName(reinterpret_cast<const char*>(rNameRecord.sptr.data()), rNameRecord.sptr.size()); rtl_TextEncoding eEncoding = RTL_TEXTENCODING_DONTKNOW; - switch (pNameRecord->encodingID) + switch (rNameRecord.encodingID) { case 0: eEncoding = RTL_TEXTENCODING_APPLE_ROMAN; @@ -423,9 +423,9 @@ OUString PrintFontManager::convertSfntName( void* pRecord ) eEncoding = RTL_TEXTENCODING_UTF8; break; default: - if (aName.startsWith("Khmer OS")) + if (o3tl::starts_with(aName, "Khmer OS")) eEncoding = RTL_TEXTENCODING_UTF8; - SAL_WARN_IF(eEncoding == RTL_TEXTENCODING_DONTKNOW, "vcl.fonts", "Unimplemented mac encoding " << pNameRecord->encodingID << " to unicode conversion for fontname " << aName); + SAL_WARN_IF(eEncoding == RTL_TEXTENCODING_DONTKNOW, "vcl.fonts", "Unimplemented mac encoding " << rNameRecord.encodingID << " to unicode conversion for fontname " << aName); break; } if (eEncoding != RTL_TEXTENCODING_DONTKNOW) @@ -465,36 +465,36 @@ void PrintFontManager::analyzeSfntFamilyName( void const * pTTFont, ::std::vecto rNames.clear(); ::std::set< OUString > aSet; - NameRecord* pNameRecords = nullptr; - int nNameRecords = GetTTNameRecords( static_cast<TrueTypeFont const *>(pTTFont), &pNameRecords ); - if( nNameRecords && pNameRecords ) + std::vector<NameRecord> aNameRecords; + GetTTNameRecords( static_cast<TrueTypeFont const *>(pTTFont), aNameRecords ); + if( !aNameRecords.empty() ) { LanguageTag aSystem(""); LanguageType eLang = aSystem.getLanguageType(); int nLastMatch = -1; - for( int i = 0; i < nNameRecords; i++ ) + for( size_t i = 0; i < aNameRecords.size(); i++ ) { - if( pNameRecords[i].nameID != 1 || pNameRecords[i].sptr == nullptr ) + if( aNameRecords[i].nameID != 1 || aNameRecords[i].sptr.empty() ) continue; int nMatch = -1; - if( pNameRecords[i].platformID == 0 ) // Unicode + if( aNameRecords[i].platformID == 0 ) // Unicode nMatch = 4000; - else if( pNameRecords[i].platformID == 3 ) + else if( aNameRecords[i].platformID == 3 ) { // this bases on the LanguageType actually being a Win LCID - if (pNameRecords[i].languageID == eLang) + if (aNameRecords[i].languageID == eLang) nMatch = 8000; - else if( pNameRecords[i].languageID == LANGUAGE_ENGLISH_US ) + else if( aNameRecords[i].languageID == LANGUAGE_ENGLISH_US ) nMatch = 2000; - else if( pNameRecords[i].languageID == LANGUAGE_ENGLISH || - pNameRecords[i].languageID == LANGUAGE_ENGLISH_UK ) + else if( aNameRecords[i].languageID == LANGUAGE_ENGLISH || + aNameRecords[i].languageID == LANGUAGE_ENGLISH_UK ) nMatch = 1500; else nMatch = 1000; } - else if (pNameRecords[i].platformID == 1) + else if (aNameRecords[i].platformID == 1) { - AppleLanguageId aAppleId = static_cast<AppleLanguageId>(static_cast<sal_uInt16>(pNameRecords[i].languageID)); + AppleLanguageId aAppleId = static_cast<AppleLanguageId>(static_cast<sal_uInt16>(aNameRecords[i].languageID)); LanguageTag aApple(makeLanguageTagFromAppleLanguageId(aAppleId)); if (aApple == aSystem) nMatch = 8000; @@ -503,7 +503,7 @@ void PrintFontManager::analyzeSfntFamilyName( void const * pTTFont, ::std::vecto else nMatch = 1000; } - OUString aName = convertSfntName( pNameRecords + i ); + OUString aName = convertSfntName( aNameRecords[i] ); aSet.insert( aName ); if (aName.isEmpty()) continue; @@ -514,7 +514,6 @@ void PrintFontManager::analyzeSfntFamilyName( void const * pTTFont, ::std::vecto } } } - DisposeNameRecords( pNameRecords, nNameRecords ); if( !aFamily.isEmpty() ) { rNames.push_back( aFamily );