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 );

Reply via email to