1*cdf0e10cSrcweir /************************************************************************* 2*cdf0e10cSrcweir * 3*cdf0e10cSrcweir * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4*cdf0e10cSrcweir * 5*cdf0e10cSrcweir * Copyright 2000, 2010 Oracle and/or its affiliates. 6*cdf0e10cSrcweir * 7*cdf0e10cSrcweir * OpenOffice.org - a multi-platform office productivity suite 8*cdf0e10cSrcweir * 9*cdf0e10cSrcweir * This file is part of OpenOffice.org. 10*cdf0e10cSrcweir * 11*cdf0e10cSrcweir * OpenOffice.org is free software: you can redistribute it and/or modify 12*cdf0e10cSrcweir * it under the terms of the GNU Lesser General Public License version 3 13*cdf0e10cSrcweir * only, as published by the Free Software Foundation. 14*cdf0e10cSrcweir * 15*cdf0e10cSrcweir * OpenOffice.org is distributed in the hope that it will be useful, 16*cdf0e10cSrcweir * but WITHOUT ANY WARRANTY; without even the implied warranty of 17*cdf0e10cSrcweir * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 18*cdf0e10cSrcweir * GNU Lesser General Public License version 3 for more details 19*cdf0e10cSrcweir * (a copy is included in the LICENSE file that accompanied this code). 20*cdf0e10cSrcweir * 21*cdf0e10cSrcweir * You should have received a copy of the GNU Lesser General Public License 22*cdf0e10cSrcweir * version 3 along with OpenOffice.org. If not, see 23*cdf0e10cSrcweir * <http://www.openoffice.org/license.html> 24*cdf0e10cSrcweir * for a copy of the LGPLv3 License. 25*cdf0e10cSrcweir * 26*cdf0e10cSrcweir ************************************************************************/ 27*cdf0e10cSrcweir 28*cdf0e10cSrcweir /* 29*cdf0e10cSrcweir * TrueTypeCreator method implementation 30*cdf0e10cSrcweir * 31*cdf0e10cSrcweir * @author: Alexander Gelfenbain 32*cdf0e10cSrcweir * 33*cdf0e10cSrcweir */ 34*cdf0e10cSrcweir 35*cdf0e10cSrcweir #if OSL_DEBUG_LEVEL == 0 36*cdf0e10cSrcweir # ifndef NDEBUG 37*cdf0e10cSrcweir # define NDEBUG 38*cdf0e10cSrcweir # endif 39*cdf0e10cSrcweir #endif 40*cdf0e10cSrcweir #include <assert.h> 41*cdf0e10cSrcweir 42*cdf0e10cSrcweir #include "ttcr.hxx" 43*cdf0e10cSrcweir #include "list.h" 44*cdf0e10cSrcweir #include "string.h" 45*cdf0e10cSrcweir 46*cdf0e10cSrcweir 47*cdf0e10cSrcweir 48*cdf0e10cSrcweir namespace vcl 49*cdf0e10cSrcweir { 50*cdf0e10cSrcweir 51*cdf0e10cSrcweir /* 52*cdf0e10cSrcweir * Private Data Types 53*cdf0e10cSrcweir */ 54*cdf0e10cSrcweir 55*cdf0e10cSrcweir struct _TrueTypeCreator { 56*cdf0e10cSrcweir sal_uInt32 tag; /**< TrueType file tag */ 57*cdf0e10cSrcweir list tables; /**< List of table tags and pointers */ 58*cdf0e10cSrcweir }; 59*cdf0e10cSrcweir 60*cdf0e10cSrcweir /* These must be #defined so that they can be used in initializers */ 61*cdf0e10cSrcweir #define T_maxp 0x6D617870 62*cdf0e10cSrcweir #define T_glyf 0x676C7966 63*cdf0e10cSrcweir #define T_head 0x68656164 64*cdf0e10cSrcweir #define T_loca 0x6C6F6361 65*cdf0e10cSrcweir #define T_name 0x6E616D65 66*cdf0e10cSrcweir #define T_hhea 0x68686561 67*cdf0e10cSrcweir #define T_hmtx 0x686D7478 68*cdf0e10cSrcweir #define T_cmap 0x636D6170 69*cdf0e10cSrcweir #define T_vhea 0x76686561 70*cdf0e10cSrcweir #define T_vmtx 0x766D7478 71*cdf0e10cSrcweir #define T_OS2 0x4F532F32 72*cdf0e10cSrcweir #define T_post 0x706F7374 73*cdf0e10cSrcweir #define T_kern 0x6B65726E 74*cdf0e10cSrcweir #define T_cvt 0x63767420 75*cdf0e10cSrcweir 76*cdf0e10cSrcweir typedef struct { 77*cdf0e10cSrcweir sal_uInt32 tag; 78*cdf0e10cSrcweir sal_uInt32 length; 79*cdf0e10cSrcweir sal_uInt8 *data; 80*cdf0e10cSrcweir } TableEntry; 81*cdf0e10cSrcweir 82*cdf0e10cSrcweir /* 83*cdf0e10cSrcweir * this is a duplicate code from sft.c but it is left here for performance reasons 84*cdf0e10cSrcweir */ 85*cdf0e10cSrcweir #ifdef __GNUC__ 86*cdf0e10cSrcweir #define _inline static __inline__ 87*cdf0e10cSrcweir #else 88*cdf0e10cSrcweir #define _inline static 89*cdf0e10cSrcweir #endif 90*cdf0e10cSrcweir 91*cdf0e10cSrcweir _inline sal_uInt32 mkTag(sal_uInt8 a, sal_uInt8 b, sal_uInt8 c, sal_uInt8 d) { 92*cdf0e10cSrcweir return (a << 24) | (b << 16) | (c << 8) | d; 93*cdf0e10cSrcweir } 94*cdf0e10cSrcweir 95*cdf0e10cSrcweir /*- Data access macros for data stored in big-endian or little-endian format */ 96*cdf0e10cSrcweir _inline sal_Int16 GetInt16( const sal_uInt8* ptr, sal_uInt32 offset, int bigendian) 97*cdf0e10cSrcweir { 98*cdf0e10cSrcweir sal_Int16 t; 99*cdf0e10cSrcweir assert(ptr != 0); 100*cdf0e10cSrcweir 101*cdf0e10cSrcweir if (bigendian) { 102*cdf0e10cSrcweir t = (ptr+offset)[0] << 8 | (ptr+offset)[1]; 103*cdf0e10cSrcweir } else { 104*cdf0e10cSrcweir t = (ptr+offset)[1] << 8 | (ptr+offset)[0]; 105*cdf0e10cSrcweir } 106*cdf0e10cSrcweir 107*cdf0e10cSrcweir return t; 108*cdf0e10cSrcweir } 109*cdf0e10cSrcweir 110*cdf0e10cSrcweir _inline sal_uInt16 GetUInt16( const sal_uInt8* ptr, sal_uInt32 offset, int bigendian) 111*cdf0e10cSrcweir { 112*cdf0e10cSrcweir sal_uInt16 t; 113*cdf0e10cSrcweir assert(ptr != 0); 114*cdf0e10cSrcweir 115*cdf0e10cSrcweir if (bigendian) { 116*cdf0e10cSrcweir t = (ptr+offset)[0] << 8 | (ptr+offset)[1]; 117*cdf0e10cSrcweir } else { 118*cdf0e10cSrcweir t = (ptr+offset)[1] << 8 | (ptr+offset)[0]; 119*cdf0e10cSrcweir } 120*cdf0e10cSrcweir 121*cdf0e10cSrcweir return t; 122*cdf0e10cSrcweir } 123*cdf0e10cSrcweir 124*cdf0e10cSrcweir _inline sal_Int32 GetInt32( const sal_uInt8* ptr, sal_uInt32 offset, int bigendian) 125*cdf0e10cSrcweir { 126*cdf0e10cSrcweir sal_Int32 t; 127*cdf0e10cSrcweir assert(ptr != 0); 128*cdf0e10cSrcweir 129*cdf0e10cSrcweir if (bigendian) { 130*cdf0e10cSrcweir t = (ptr+offset)[0] << 24 | (ptr+offset)[1] << 16 | 131*cdf0e10cSrcweir (ptr+offset)[2] << 8 | (ptr+offset)[3]; 132*cdf0e10cSrcweir } else { 133*cdf0e10cSrcweir t = (ptr+offset)[3] << 24 | (ptr+offset)[2] << 16 | 134*cdf0e10cSrcweir (ptr+offset)[1] << 8 | (ptr+offset)[0]; 135*cdf0e10cSrcweir } 136*cdf0e10cSrcweir 137*cdf0e10cSrcweir return t; 138*cdf0e10cSrcweir } 139*cdf0e10cSrcweir 140*cdf0e10cSrcweir _inline sal_uInt32 GetUInt32( const sal_uInt8* ptr, sal_uInt32 offset, int bigendian) 141*cdf0e10cSrcweir { 142*cdf0e10cSrcweir sal_uInt32 t; 143*cdf0e10cSrcweir assert(ptr != 0); 144*cdf0e10cSrcweir 145*cdf0e10cSrcweir 146*cdf0e10cSrcweir if (bigendian) { 147*cdf0e10cSrcweir t = (ptr+offset)[0] << 24 | (ptr+offset)[1] << 16 | 148*cdf0e10cSrcweir (ptr+offset)[2] << 8 | (ptr+offset)[3]; 149*cdf0e10cSrcweir } else { 150*cdf0e10cSrcweir t = (ptr+offset)[3] << 24 | (ptr+offset)[2] << 16 | 151*cdf0e10cSrcweir (ptr+offset)[1] << 8 | (ptr+offset)[0]; 152*cdf0e10cSrcweir } 153*cdf0e10cSrcweir 154*cdf0e10cSrcweir return t; 155*cdf0e10cSrcweir } 156*cdf0e10cSrcweir 157*cdf0e10cSrcweir 158*cdf0e10cSrcweir _inline void PutInt16(sal_Int16 val, sal_uInt8 *ptr, sal_uInt32 offset, int bigendian) 159*cdf0e10cSrcweir { 160*cdf0e10cSrcweir assert(ptr != 0); 161*cdf0e10cSrcweir 162*cdf0e10cSrcweir if (bigendian) { 163*cdf0e10cSrcweir ptr[offset] = (sal_uInt8)((val >> 8) & 0xFF); 164*cdf0e10cSrcweir ptr[offset+1] = (sal_uInt8)(val & 0xFF); 165*cdf0e10cSrcweir } else { 166*cdf0e10cSrcweir ptr[offset+1] = (sal_uInt8)((val >> 8) & 0xFF); 167*cdf0e10cSrcweir ptr[offset] = (sal_uInt8)(val & 0xFF); 168*cdf0e10cSrcweir } 169*cdf0e10cSrcweir } 170*cdf0e10cSrcweir 171*cdf0e10cSrcweir _inline void PutUInt16(sal_uInt16 val, sal_uInt8 *ptr, sal_uInt32 offset, int bigendian) 172*cdf0e10cSrcweir { 173*cdf0e10cSrcweir assert(ptr != 0); 174*cdf0e10cSrcweir 175*cdf0e10cSrcweir if (bigendian) { 176*cdf0e10cSrcweir ptr[offset] = (sal_uInt8)((val >> 8) & 0xFF); 177*cdf0e10cSrcweir ptr[offset+1] = (sal_uInt8)(val & 0xFF); 178*cdf0e10cSrcweir } else { 179*cdf0e10cSrcweir ptr[offset+1] = (sal_uInt8)((val >> 8) & 0xFF); 180*cdf0e10cSrcweir ptr[offset] = (sal_uInt8)(val & 0xFF); 181*cdf0e10cSrcweir } 182*cdf0e10cSrcweir } 183*cdf0e10cSrcweir 184*cdf0e10cSrcweir _inline void PutUInt32(sal_uInt32 val, sal_uInt8 *ptr, sal_uInt32 offset, int bigendian) 185*cdf0e10cSrcweir { 186*cdf0e10cSrcweir assert(ptr != 0); 187*cdf0e10cSrcweir 188*cdf0e10cSrcweir if (bigendian) { 189*cdf0e10cSrcweir ptr[offset] = (sal_uInt8)((val >> 24) & 0xFF); 190*cdf0e10cSrcweir ptr[offset+1] = (sal_uInt8)((val >> 16) & 0xFF); 191*cdf0e10cSrcweir ptr[offset+2] = (sal_uInt8)((val >> 8) & 0xFF); 192*cdf0e10cSrcweir ptr[offset+3] = (sal_uInt8)(val & 0xFF); 193*cdf0e10cSrcweir } else { 194*cdf0e10cSrcweir ptr[offset+3] = (sal_uInt8)((val >> 24) & 0xFF); 195*cdf0e10cSrcweir ptr[offset+2] = (sal_uInt8)((val >> 16) & 0xFF); 196*cdf0e10cSrcweir ptr[offset+1] = (sal_uInt8)((val >> 8) & 0xFF); 197*cdf0e10cSrcweir ptr[offset] = (sal_uInt8)(val & 0xFF); 198*cdf0e10cSrcweir } 199*cdf0e10cSrcweir 200*cdf0e10cSrcweir } 201*cdf0e10cSrcweir 202*cdf0e10cSrcweir 203*cdf0e10cSrcweir _inline void PutInt32(sal_Int32 val, sal_uInt8 *ptr, sal_uInt32 offset, int bigendian) 204*cdf0e10cSrcweir { 205*cdf0e10cSrcweir assert(ptr != 0); 206*cdf0e10cSrcweir 207*cdf0e10cSrcweir if (bigendian) { 208*cdf0e10cSrcweir ptr[offset] = (sal_uInt8)((val >> 24) & 0xFF); 209*cdf0e10cSrcweir ptr[offset+1] = (sal_uInt8)((val >> 16) & 0xFF); 210*cdf0e10cSrcweir ptr[offset+2] = (sal_uInt8)((val >> 8) & 0xFF); 211*cdf0e10cSrcweir ptr[offset+3] = (sal_uInt8)(val & 0xFF); 212*cdf0e10cSrcweir } else { 213*cdf0e10cSrcweir ptr[offset+3] = (sal_uInt8)((val >> 24) & 0xFF); 214*cdf0e10cSrcweir ptr[offset+2] = (sal_uInt8)((val >> 16) & 0xFF); 215*cdf0e10cSrcweir ptr[offset+1] = (sal_uInt8)((val >> 8) & 0xFF); 216*cdf0e10cSrcweir ptr[offset] = (sal_uInt8)(val & 0xFF); 217*cdf0e10cSrcweir } 218*cdf0e10cSrcweir 219*cdf0e10cSrcweir } 220*cdf0e10cSrcweir 221*cdf0e10cSrcweir static int TableEntryCompareF(const void *l, const void *r) 222*cdf0e10cSrcweir { 223*cdf0e10cSrcweir return ((const TableEntry *) l)->tag - ((const TableEntry *) r)->tag; 224*cdf0e10cSrcweir } 225*cdf0e10cSrcweir 226*cdf0e10cSrcweir static int NameRecordCompareF(const void *l, const void *r) 227*cdf0e10cSrcweir { 228*cdf0e10cSrcweir NameRecord *ll = (NameRecord *) l; 229*cdf0e10cSrcweir NameRecord *rr = (NameRecord *) r; 230*cdf0e10cSrcweir 231*cdf0e10cSrcweir if (ll->platformID != rr->platformID) { 232*cdf0e10cSrcweir return ll->platformID - rr->platformID; 233*cdf0e10cSrcweir } else if (ll->encodingID != rr->encodingID) { 234*cdf0e10cSrcweir return ll->encodingID - rr->encodingID; 235*cdf0e10cSrcweir } else if (ll->languageID != rr->languageID) { 236*cdf0e10cSrcweir return ll->languageID - rr->languageID; 237*cdf0e10cSrcweir } else if (ll->nameID != rr->nameID) { 238*cdf0e10cSrcweir return ll->nameID - rr->nameID; 239*cdf0e10cSrcweir } 240*cdf0e10cSrcweir return 0; 241*cdf0e10cSrcweir } 242*cdf0e10cSrcweir 243*cdf0e10cSrcweir 244*cdf0e10cSrcweir static sal_uInt32 CheckSum(sal_uInt32 *ptr, sal_uInt32 length) 245*cdf0e10cSrcweir { 246*cdf0e10cSrcweir sal_uInt32 sum = 0; 247*cdf0e10cSrcweir sal_uInt32 *endptr = ptr + ((length + 3) & (sal_uInt32) ~3) / 4; 248*cdf0e10cSrcweir 249*cdf0e10cSrcweir while (ptr < endptr) sum += *ptr++; 250*cdf0e10cSrcweir 251*cdf0e10cSrcweir return sum; 252*cdf0e10cSrcweir } 253*cdf0e10cSrcweir 254*cdf0e10cSrcweir _inline void *smalloc(sal_uInt32 size) 255*cdf0e10cSrcweir { 256*cdf0e10cSrcweir void *res = malloc(size); 257*cdf0e10cSrcweir assert(res != 0); 258*cdf0e10cSrcweir return res; 259*cdf0e10cSrcweir } 260*cdf0e10cSrcweir 261*cdf0e10cSrcweir _inline void *scalloc(sal_uInt32 n, sal_uInt32 size) 262*cdf0e10cSrcweir { 263*cdf0e10cSrcweir void *res = calloc(n, size); 264*cdf0e10cSrcweir assert(res != 0); 265*cdf0e10cSrcweir return res; 266*cdf0e10cSrcweir } 267*cdf0e10cSrcweir 268*cdf0e10cSrcweir /* 269*cdf0e10cSrcweir * Public functions 270*cdf0e10cSrcweir */ 271*cdf0e10cSrcweir 272*cdf0e10cSrcweir void TrueTypeCreatorNewEmpty(sal_uInt32 tag, TrueTypeCreator **_this) 273*cdf0e10cSrcweir { 274*cdf0e10cSrcweir TrueTypeCreator* ptr = (TrueTypeCreator*)smalloc(sizeof(TrueTypeCreator)); 275*cdf0e10cSrcweir 276*cdf0e10cSrcweir ptr->tables = listNewEmpty(); 277*cdf0e10cSrcweir listSetElementDtor(ptr->tables, (list_destructor)TrueTypeTableDispose); 278*cdf0e10cSrcweir 279*cdf0e10cSrcweir ptr->tag = tag; 280*cdf0e10cSrcweir 281*cdf0e10cSrcweir *_this = ptr; 282*cdf0e10cSrcweir } 283*cdf0e10cSrcweir 284*cdf0e10cSrcweir int AddTable(TrueTypeCreator *_this, TrueTypeTable *table) 285*cdf0e10cSrcweir { 286*cdf0e10cSrcweir if (table != 0) { 287*cdf0e10cSrcweir listAppend(_this->tables, table); 288*cdf0e10cSrcweir } 289*cdf0e10cSrcweir return SF_OK; 290*cdf0e10cSrcweir } 291*cdf0e10cSrcweir 292*cdf0e10cSrcweir void RemoveTable(TrueTypeCreator *_this, sal_uInt32 tag) 293*cdf0e10cSrcweir { 294*cdf0e10cSrcweir int done = 0; 295*cdf0e10cSrcweir 296*cdf0e10cSrcweir if (listCount(_this->tables)) { 297*cdf0e10cSrcweir listToFirst(_this->tables); 298*cdf0e10cSrcweir do { 299*cdf0e10cSrcweir if (((TrueTypeTable *) listCurrent(_this->tables))->tag == tag) { 300*cdf0e10cSrcweir listRemove(_this->tables); 301*cdf0e10cSrcweir } else { 302*cdf0e10cSrcweir if (listNext(_this->tables)) { 303*cdf0e10cSrcweir done = 1; 304*cdf0e10cSrcweir } 305*cdf0e10cSrcweir } 306*cdf0e10cSrcweir } while (!done); 307*cdf0e10cSrcweir } 308*cdf0e10cSrcweir } 309*cdf0e10cSrcweir 310*cdf0e10cSrcweir static void ProcessTables(TrueTypeCreator *); 311*cdf0e10cSrcweir 312*cdf0e10cSrcweir int StreamToMemory(TrueTypeCreator *_this, sal_uInt8 **ptr, sal_uInt32 *length) 313*cdf0e10cSrcweir { 314*cdf0e10cSrcweir sal_uInt16 numTables, searchRange=1, entrySelector=0, rangeShift; 315*cdf0e10cSrcweir sal_uInt32 s, offset, checkSumAdjustment = 0; 316*cdf0e10cSrcweir sal_uInt32 *p; 317*cdf0e10cSrcweir int i=0, n; 318*cdf0e10cSrcweir sal_uInt8 *head = NULL; /* saved pointer to the head table data for checkSumAdjustment calculation */ 319*cdf0e10cSrcweir 320*cdf0e10cSrcweir if ((n = listCount(_this->tables)) == 0) return SF_TTFORMAT; 321*cdf0e10cSrcweir 322*cdf0e10cSrcweir ProcessTables(_this); 323*cdf0e10cSrcweir 324*cdf0e10cSrcweir /* ProcessTables() adds 'loca' and 'hmtx' */ 325*cdf0e10cSrcweir 326*cdf0e10cSrcweir n = listCount(_this->tables); 327*cdf0e10cSrcweir numTables = (sal_uInt16) n; 328*cdf0e10cSrcweir 329*cdf0e10cSrcweir 330*cdf0e10cSrcweir TableEntry* te = (TableEntry*)scalloc(n, sizeof(TableEntry)); 331*cdf0e10cSrcweir 332*cdf0e10cSrcweir listToFirst(_this->tables); 333*cdf0e10cSrcweir for (i = 0; i < n; i++) { 334*cdf0e10cSrcweir GetRawData((TrueTypeTable *) listCurrent(_this->tables), &te[i].data, &te[i].length, &te[i].tag); 335*cdf0e10cSrcweir listNext(_this->tables); 336*cdf0e10cSrcweir } 337*cdf0e10cSrcweir 338*cdf0e10cSrcweir qsort(te, n, sizeof(TableEntry), TableEntryCompareF); 339*cdf0e10cSrcweir 340*cdf0e10cSrcweir do { 341*cdf0e10cSrcweir searchRange *= 2; 342*cdf0e10cSrcweir entrySelector++; 343*cdf0e10cSrcweir } while (searchRange <= numTables); 344*cdf0e10cSrcweir 345*cdf0e10cSrcweir searchRange *= 8; 346*cdf0e10cSrcweir entrySelector--; 347*cdf0e10cSrcweir rangeShift = numTables * 16 - searchRange; 348*cdf0e10cSrcweir 349*cdf0e10cSrcweir s = offset = 12 + 16 * n; 350*cdf0e10cSrcweir 351*cdf0e10cSrcweir for (i = 0; i < n; i++) { 352*cdf0e10cSrcweir s += (te[i].length + 3) & (sal_uInt32) ~3; 353*cdf0e10cSrcweir /* if ((te[i].length & 3) != 0) s += (4 - (te[i].length & 3)) & 3; */ 354*cdf0e10cSrcweir } 355*cdf0e10cSrcweir 356*cdf0e10cSrcweir sal_uInt8* ttf = (sal_uInt8*)smalloc(s); 357*cdf0e10cSrcweir 358*cdf0e10cSrcweir /* Offset Table */ 359*cdf0e10cSrcweir PutUInt32(_this->tag, ttf, 0, 1); 360*cdf0e10cSrcweir PutUInt16(numTables, ttf, 4, 1); 361*cdf0e10cSrcweir PutUInt16(searchRange, ttf, 6, 1); 362*cdf0e10cSrcweir PutUInt16(entrySelector, ttf, 8, 1); 363*cdf0e10cSrcweir PutUInt16(rangeShift, ttf, 10, 1); 364*cdf0e10cSrcweir 365*cdf0e10cSrcweir /* Table Directory */ 366*cdf0e10cSrcweir for (i = 0; i < n; i++) { 367*cdf0e10cSrcweir PutUInt32(te[i].tag, ttf + 12, 16 * i, 1); 368*cdf0e10cSrcweir PutUInt32(CheckSum((sal_uInt32 *) te[i].data, te[i].length), ttf + 12, 16 * i + 4, 1); 369*cdf0e10cSrcweir PutUInt32(offset, ttf + 12, 16 * i + 8, 1); 370*cdf0e10cSrcweir PutUInt32(te[i].length, ttf + 12, 16 * i + 12, 1); 371*cdf0e10cSrcweir 372*cdf0e10cSrcweir if (te[i].tag == T_head) { 373*cdf0e10cSrcweir head = ttf + offset; 374*cdf0e10cSrcweir } 375*cdf0e10cSrcweir 376*cdf0e10cSrcweir memcpy(ttf+offset, te[i].data, (te[i].length + 3) & (sal_uInt32) ~3 ); 377*cdf0e10cSrcweir offset += (te[i].length + 3) & (sal_uInt32) ~3; 378*cdf0e10cSrcweir /* if ((te[i].length & 3) != 0) offset += (4 - (te[i].length & 3)) & 3; */ 379*cdf0e10cSrcweir } 380*cdf0e10cSrcweir 381*cdf0e10cSrcweir free(te); 382*cdf0e10cSrcweir 383*cdf0e10cSrcweir p = (sal_uInt32 *) ttf; 384*cdf0e10cSrcweir for (i = 0; i < (int)s / 4; i++) checkSumAdjustment += p[i]; 385*cdf0e10cSrcweir PutUInt32(0xB1B0AFBA - checkSumAdjustment, head, 8, 1); 386*cdf0e10cSrcweir 387*cdf0e10cSrcweir *ptr = ttf; 388*cdf0e10cSrcweir *length = s; 389*cdf0e10cSrcweir 390*cdf0e10cSrcweir return SF_OK; 391*cdf0e10cSrcweir } 392*cdf0e10cSrcweir 393*cdf0e10cSrcweir int StreamToFile(TrueTypeCreator *_this, const char* fname) 394*cdf0e10cSrcweir { 395*cdf0e10cSrcweir sal_uInt8 *ptr; 396*cdf0e10cSrcweir sal_uInt32 length; 397*cdf0e10cSrcweir int r; 398*cdf0e10cSrcweir FILE* fd; 399*cdf0e10cSrcweir 400*cdf0e10cSrcweir if ((r = StreamToMemory(_this, &ptr, &length)) != SF_OK) return r; 401*cdf0e10cSrcweir if (!fname) return SF_BADFILE; 402*cdf0e10cSrcweir if ((fd = fopen(fname, "wb")) == NULL) return SF_BADFILE; 403*cdf0e10cSrcweir 404*cdf0e10cSrcweir if (fwrite(ptr, 1, length, fd) != length) { 405*cdf0e10cSrcweir r = SF_FILEIO; 406*cdf0e10cSrcweir } else { 407*cdf0e10cSrcweir r = SF_OK; 408*cdf0e10cSrcweir } 409*cdf0e10cSrcweir 410*cdf0e10cSrcweir fclose(fd); 411*cdf0e10cSrcweir free(ptr); 412*cdf0e10cSrcweir return r; 413*cdf0e10cSrcweir } 414*cdf0e10cSrcweir 415*cdf0e10cSrcweir 416*cdf0e10cSrcweir 417*cdf0e10cSrcweir /* 418*cdf0e10cSrcweir * TrueTypeTable private methods 419*cdf0e10cSrcweir */ 420*cdf0e10cSrcweir 421*cdf0e10cSrcweir #define TABLESIZE_head 54 422*cdf0e10cSrcweir #define TABLESIZE_hhea 36 423*cdf0e10cSrcweir #define TABLESIZE_maxp 32 424*cdf0e10cSrcweir 425*cdf0e10cSrcweir 426*cdf0e10cSrcweir 427*cdf0e10cSrcweir /* Table data points to 428*cdf0e10cSrcweir * -------------------------------------------- 429*cdf0e10cSrcweir * generic tdata_generic struct 430*cdf0e10cSrcweir * 'head' TABLESIZE_head bytes of memory 431*cdf0e10cSrcweir * 'hhea' TABLESIZE_hhea bytes of memory 432*cdf0e10cSrcweir * 'loca' tdata_loca struct 433*cdf0e10cSrcweir * 'maxp' TABLESIZE_maxp bytes of memory 434*cdf0e10cSrcweir * 'glyf' list of GlyphData structs (defined in sft.h) 435*cdf0e10cSrcweir * 'name' list of NameRecord structs (defined in sft.h) 436*cdf0e10cSrcweir * 'post' tdata_post struct 437*cdf0e10cSrcweir * 438*cdf0e10cSrcweir */ 439*cdf0e10cSrcweir 440*cdf0e10cSrcweir 441*cdf0e10cSrcweir #define CMAP_SUBTABLE_INIT 10 442*cdf0e10cSrcweir #define CMAP_SUBTABLE_INCR 10 443*cdf0e10cSrcweir #define CMAP_PAIR_INIT 500 444*cdf0e10cSrcweir #define CMAP_PAIR_INCR 500 445*cdf0e10cSrcweir 446*cdf0e10cSrcweir typedef struct { 447*cdf0e10cSrcweir sal_uInt32 id; /* subtable ID (platform/encoding ID) */ 448*cdf0e10cSrcweir sal_uInt32 n; /* number of used translation pairs */ 449*cdf0e10cSrcweir sal_uInt32 m; /* number of allocated translation pairs */ 450*cdf0e10cSrcweir sal_uInt32 *xc; /* character array */ 451*cdf0e10cSrcweir sal_uInt32 *xg; /* glyph array */ 452*cdf0e10cSrcweir } CmapSubTable; 453*cdf0e10cSrcweir 454*cdf0e10cSrcweir typedef struct { 455*cdf0e10cSrcweir sal_uInt32 n; /* number of used CMAP sub-tables */ 456*cdf0e10cSrcweir sal_uInt32 m; /* number of allocated CMAP sub-tables */ 457*cdf0e10cSrcweir CmapSubTable *s; /* sotred array of sub-tables */ 458*cdf0e10cSrcweir } table_cmap; 459*cdf0e10cSrcweir 460*cdf0e10cSrcweir typedef struct { 461*cdf0e10cSrcweir sal_uInt32 tag; 462*cdf0e10cSrcweir sal_uInt32 nbytes; 463*cdf0e10cSrcweir sal_uInt8 *ptr; 464*cdf0e10cSrcweir } tdata_generic; 465*cdf0e10cSrcweir 466*cdf0e10cSrcweir typedef struct { 467*cdf0e10cSrcweir sal_uInt32 nbytes; /* number of bytes in loca table */ 468*cdf0e10cSrcweir sal_uInt8 *ptr; /* pointer to the data */ 469*cdf0e10cSrcweir } tdata_loca; 470*cdf0e10cSrcweir 471*cdf0e10cSrcweir typedef struct { 472*cdf0e10cSrcweir sal_uInt32 format; 473*cdf0e10cSrcweir sal_uInt32 italicAngle; 474*cdf0e10cSrcweir sal_Int16 underlinePosition; 475*cdf0e10cSrcweir sal_Int16 underlineThickness; 476*cdf0e10cSrcweir sal_uInt32 isFixedPitch; 477*cdf0e10cSrcweir void *ptr; /* format-specific pointer */ 478*cdf0e10cSrcweir } tdata_post; 479*cdf0e10cSrcweir 480*cdf0e10cSrcweir 481*cdf0e10cSrcweir /* allocate memory for a TT table */ 482*cdf0e10cSrcweir static sal_uInt8 *ttmalloc(sal_uInt32 nbytes) 483*cdf0e10cSrcweir { 484*cdf0e10cSrcweir sal_uInt32 n; 485*cdf0e10cSrcweir 486*cdf0e10cSrcweir n = (nbytes + 3) & (sal_uInt32) ~3; 487*cdf0e10cSrcweir sal_uInt8* res = (sal_uInt8*)malloc(n); 488*cdf0e10cSrcweir assert(res != 0); 489*cdf0e10cSrcweir memset(res, 0, n); 490*cdf0e10cSrcweir 491*cdf0e10cSrcweir return res; 492*cdf0e10cSrcweir } 493*cdf0e10cSrcweir 494*cdf0e10cSrcweir static void FreeGlyphData(void *ptr) 495*cdf0e10cSrcweir { 496*cdf0e10cSrcweir GlyphData *p = (GlyphData *) ptr; 497*cdf0e10cSrcweir if (p->ptr) free(p->ptr); 498*cdf0e10cSrcweir free(p); 499*cdf0e10cSrcweir } 500*cdf0e10cSrcweir 501*cdf0e10cSrcweir static void TrueTypeTableDispose_generic(TrueTypeTable *_this) 502*cdf0e10cSrcweir { 503*cdf0e10cSrcweir if (_this) { 504*cdf0e10cSrcweir if (_this->data) { 505*cdf0e10cSrcweir tdata_generic *pdata = (tdata_generic *) _this->data; 506*cdf0e10cSrcweir if (pdata->nbytes) free(pdata->ptr); 507*cdf0e10cSrcweir free(_this->data); 508*cdf0e10cSrcweir } 509*cdf0e10cSrcweir free(_this); 510*cdf0e10cSrcweir } 511*cdf0e10cSrcweir } 512*cdf0e10cSrcweir 513*cdf0e10cSrcweir static void TrueTypeTableDispose_head(TrueTypeTable *_this) 514*cdf0e10cSrcweir { 515*cdf0e10cSrcweir if (_this) { 516*cdf0e10cSrcweir if (_this->data) free(_this->data); 517*cdf0e10cSrcweir free(_this); 518*cdf0e10cSrcweir } 519*cdf0e10cSrcweir } 520*cdf0e10cSrcweir 521*cdf0e10cSrcweir static void TrueTypeTableDispose_hhea(TrueTypeTable *_this) 522*cdf0e10cSrcweir { 523*cdf0e10cSrcweir if (_this) { 524*cdf0e10cSrcweir if (_this->data) free(_this->data); 525*cdf0e10cSrcweir free(_this); 526*cdf0e10cSrcweir } 527*cdf0e10cSrcweir } 528*cdf0e10cSrcweir 529*cdf0e10cSrcweir static void TrueTypeTableDispose_loca(TrueTypeTable *_this) 530*cdf0e10cSrcweir { 531*cdf0e10cSrcweir if (_this) { 532*cdf0e10cSrcweir if (_this->data) { 533*cdf0e10cSrcweir tdata_loca *p = (tdata_loca *) _this->data; 534*cdf0e10cSrcweir if (p->ptr) free(p->ptr); 535*cdf0e10cSrcweir free(_this->data); 536*cdf0e10cSrcweir } 537*cdf0e10cSrcweir free(_this); 538*cdf0e10cSrcweir } 539*cdf0e10cSrcweir } 540*cdf0e10cSrcweir 541*cdf0e10cSrcweir static void TrueTypeTableDispose_maxp(TrueTypeTable *_this) 542*cdf0e10cSrcweir { 543*cdf0e10cSrcweir if (_this) { 544*cdf0e10cSrcweir if (_this->data) free(_this->data); 545*cdf0e10cSrcweir free(_this); 546*cdf0e10cSrcweir } 547*cdf0e10cSrcweir } 548*cdf0e10cSrcweir 549*cdf0e10cSrcweir static void TrueTypeTableDispose_glyf(TrueTypeTable *_this) 550*cdf0e10cSrcweir { 551*cdf0e10cSrcweir if (_this) { 552*cdf0e10cSrcweir if (_this->data) listDispose((list) _this->data); 553*cdf0e10cSrcweir free(_this); 554*cdf0e10cSrcweir } 555*cdf0e10cSrcweir } 556*cdf0e10cSrcweir 557*cdf0e10cSrcweir static void TrueTypeTableDispose_cmap(TrueTypeTable *_this) 558*cdf0e10cSrcweir { 559*cdf0e10cSrcweir table_cmap *t; 560*cdf0e10cSrcweir CmapSubTable *s; 561*cdf0e10cSrcweir sal_uInt32 i; 562*cdf0e10cSrcweir 563*cdf0e10cSrcweir if (_this) { 564*cdf0e10cSrcweir t = (table_cmap *) _this->data; 565*cdf0e10cSrcweir if (t) { 566*cdf0e10cSrcweir s = t->s; 567*cdf0e10cSrcweir if (s) { 568*cdf0e10cSrcweir for (i = 0; i < t->m; i++) { 569*cdf0e10cSrcweir if (s[i].xc) free(s[i].xc); 570*cdf0e10cSrcweir if (s[i].xg) free(s[i].xg); 571*cdf0e10cSrcweir } 572*cdf0e10cSrcweir free(s); 573*cdf0e10cSrcweir } 574*cdf0e10cSrcweir free(t); 575*cdf0e10cSrcweir } 576*cdf0e10cSrcweir free(_this); 577*cdf0e10cSrcweir } 578*cdf0e10cSrcweir } 579*cdf0e10cSrcweir 580*cdf0e10cSrcweir static void TrueTypeTableDispose_name(TrueTypeTable *_this) 581*cdf0e10cSrcweir { 582*cdf0e10cSrcweir if (_this) { 583*cdf0e10cSrcweir if (_this->data) listDispose((list) _this->data); 584*cdf0e10cSrcweir free(_this); 585*cdf0e10cSrcweir } 586*cdf0e10cSrcweir } 587*cdf0e10cSrcweir 588*cdf0e10cSrcweir static void TrueTypeTableDispose_post(TrueTypeTable *_this) 589*cdf0e10cSrcweir { 590*cdf0e10cSrcweir if (_this) { 591*cdf0e10cSrcweir tdata_post *p = (tdata_post *) _this->data; 592*cdf0e10cSrcweir if (p) { 593*cdf0e10cSrcweir if (p->format == 0x00030000) { 594*cdf0e10cSrcweir /* do nothing */ 595*cdf0e10cSrcweir } else { 596*cdf0e10cSrcweir fprintf(stderr, "Unsupported format of a 'post' table: %08X.\n", (int)p->format); 597*cdf0e10cSrcweir } 598*cdf0e10cSrcweir free(p); 599*cdf0e10cSrcweir } 600*cdf0e10cSrcweir free(_this); 601*cdf0e10cSrcweir } 602*cdf0e10cSrcweir } 603*cdf0e10cSrcweir 604*cdf0e10cSrcweir /* destructor vtable */ 605*cdf0e10cSrcweir 606*cdf0e10cSrcweir static struct { 607*cdf0e10cSrcweir sal_uInt32 tag; 608*cdf0e10cSrcweir void (*f)(TrueTypeTable *); 609*cdf0e10cSrcweir } vtable1[] = 610*cdf0e10cSrcweir { 611*cdf0e10cSrcweir {0, TrueTypeTableDispose_generic}, 612*cdf0e10cSrcweir {T_head, TrueTypeTableDispose_head}, 613*cdf0e10cSrcweir {T_hhea, TrueTypeTableDispose_hhea}, 614*cdf0e10cSrcweir {T_loca, TrueTypeTableDispose_loca}, 615*cdf0e10cSrcweir {T_maxp, TrueTypeTableDispose_maxp}, 616*cdf0e10cSrcweir {T_glyf, TrueTypeTableDispose_glyf}, 617*cdf0e10cSrcweir {T_cmap, TrueTypeTableDispose_cmap}, 618*cdf0e10cSrcweir {T_name, TrueTypeTableDispose_name}, 619*cdf0e10cSrcweir {T_post, TrueTypeTableDispose_post} 620*cdf0e10cSrcweir 621*cdf0e10cSrcweir }; 622*cdf0e10cSrcweir 623*cdf0e10cSrcweir static int GetRawData_generic(TrueTypeTable *_this, sal_uInt8 **ptr, sal_uInt32 *len, sal_uInt32 *tag) 624*cdf0e10cSrcweir { 625*cdf0e10cSrcweir assert(_this != 0); 626*cdf0e10cSrcweir assert(_this->data != 0); 627*cdf0e10cSrcweir 628*cdf0e10cSrcweir *ptr = ((tdata_generic *) _this->data)->ptr; 629*cdf0e10cSrcweir *len = ((tdata_generic *) _this->data)->nbytes; 630*cdf0e10cSrcweir *tag = ((tdata_generic *) _this->data)->tag; 631*cdf0e10cSrcweir 632*cdf0e10cSrcweir return TTCR_OK; 633*cdf0e10cSrcweir } 634*cdf0e10cSrcweir 635*cdf0e10cSrcweir 636*cdf0e10cSrcweir static int GetRawData_head(TrueTypeTable *_this, sal_uInt8 **ptr, sal_uInt32 *len, sal_uInt32 *tag) 637*cdf0e10cSrcweir { 638*cdf0e10cSrcweir *len = TABLESIZE_head; 639*cdf0e10cSrcweir *ptr = (sal_uInt8 *) _this->data; 640*cdf0e10cSrcweir *tag = T_head; 641*cdf0e10cSrcweir 642*cdf0e10cSrcweir return TTCR_OK; 643*cdf0e10cSrcweir } 644*cdf0e10cSrcweir 645*cdf0e10cSrcweir static int GetRawData_hhea(TrueTypeTable *_this, sal_uInt8 **ptr, sal_uInt32 *len, sal_uInt32 *tag) 646*cdf0e10cSrcweir { 647*cdf0e10cSrcweir *len = TABLESIZE_hhea; 648*cdf0e10cSrcweir *ptr = (sal_uInt8 *) _this->data; 649*cdf0e10cSrcweir *tag = T_hhea; 650*cdf0e10cSrcweir 651*cdf0e10cSrcweir return TTCR_OK; 652*cdf0e10cSrcweir } 653*cdf0e10cSrcweir 654*cdf0e10cSrcweir static int GetRawData_loca(TrueTypeTable *_this, sal_uInt8 **ptr, sal_uInt32 *len, sal_uInt32 *tag) 655*cdf0e10cSrcweir { 656*cdf0e10cSrcweir tdata_loca *p; 657*cdf0e10cSrcweir 658*cdf0e10cSrcweir assert(_this->data != 0); 659*cdf0e10cSrcweir 660*cdf0e10cSrcweir p = (tdata_loca *) _this->data; 661*cdf0e10cSrcweir 662*cdf0e10cSrcweir if (p->nbytes == 0) return TTCR_ZEROGLYPHS; 663*cdf0e10cSrcweir 664*cdf0e10cSrcweir *ptr = p->ptr; 665*cdf0e10cSrcweir *len = p->nbytes; 666*cdf0e10cSrcweir *tag = T_loca; 667*cdf0e10cSrcweir 668*cdf0e10cSrcweir return TTCR_OK; 669*cdf0e10cSrcweir } 670*cdf0e10cSrcweir 671*cdf0e10cSrcweir static int GetRawData_maxp(TrueTypeTable *_this, sal_uInt8 **ptr, sal_uInt32 *len, sal_uInt32 *tag) 672*cdf0e10cSrcweir { 673*cdf0e10cSrcweir *len = TABLESIZE_maxp; 674*cdf0e10cSrcweir *ptr = (sal_uInt8 *) _this->data; 675*cdf0e10cSrcweir *tag = T_maxp; 676*cdf0e10cSrcweir 677*cdf0e10cSrcweir return TTCR_OK; 678*cdf0e10cSrcweir } 679*cdf0e10cSrcweir 680*cdf0e10cSrcweir static int GetRawData_glyf(TrueTypeTable *_this, sal_uInt8 **ptr, sal_uInt32 *len, sal_uInt32 *tag) 681*cdf0e10cSrcweir { 682*cdf0e10cSrcweir sal_uInt32 n, nbytes = 0; 683*cdf0e10cSrcweir list l = (list) _this->data; 684*cdf0e10cSrcweir /* sal_uInt16 curID = 0; */ /* to check if glyph IDs are sequential and start from zero */ 685*cdf0e10cSrcweir sal_uInt8 *p; 686*cdf0e10cSrcweir 687*cdf0e10cSrcweir *ptr = 0; 688*cdf0e10cSrcweir *len = 0; 689*cdf0e10cSrcweir *tag = 0; 690*cdf0e10cSrcweir 691*cdf0e10cSrcweir if (listCount(l) == 0) return TTCR_ZEROGLYPHS; 692*cdf0e10cSrcweir 693*cdf0e10cSrcweir listToFirst(l); 694*cdf0e10cSrcweir do { 695*cdf0e10cSrcweir /* if (((GlyphData *) listCurrent(l))->glyphID != curID++) return TTCR_GLYPHSEQ; */ 696*cdf0e10cSrcweir nbytes += ((GlyphData *) listCurrent(l))->nbytes; 697*cdf0e10cSrcweir } while (listNext(l)); 698*cdf0e10cSrcweir 699*cdf0e10cSrcweir p = _this->rawdata = ttmalloc(nbytes); 700*cdf0e10cSrcweir 701*cdf0e10cSrcweir listToFirst(l); 702*cdf0e10cSrcweir do { 703*cdf0e10cSrcweir n = ((GlyphData *) listCurrent(l))->nbytes; 704*cdf0e10cSrcweir if (n != 0) { 705*cdf0e10cSrcweir memcpy(p, ((GlyphData *) listCurrent(l))->ptr, n); 706*cdf0e10cSrcweir p += n; 707*cdf0e10cSrcweir } 708*cdf0e10cSrcweir } while (listNext(l)); 709*cdf0e10cSrcweir 710*cdf0e10cSrcweir *len = nbytes; 711*cdf0e10cSrcweir *ptr = _this->rawdata; 712*cdf0e10cSrcweir *tag = T_glyf; 713*cdf0e10cSrcweir 714*cdf0e10cSrcweir return TTCR_OK; 715*cdf0e10cSrcweir } 716*cdf0e10cSrcweir 717*cdf0e10cSrcweir /* cmap packers */ 718*cdf0e10cSrcweir static sal_uInt8 *PackCmapType0(CmapSubTable *s, sal_uInt32 *length) 719*cdf0e10cSrcweir { 720*cdf0e10cSrcweir sal_uInt8* ptr = (sal_uInt8*)smalloc(262); 721*cdf0e10cSrcweir sal_uInt8 *p = ptr + 6; 722*cdf0e10cSrcweir sal_uInt32 i, j; 723*cdf0e10cSrcweir sal_uInt16 g; 724*cdf0e10cSrcweir 725*cdf0e10cSrcweir PutUInt16(0, ptr, 0, 1); 726*cdf0e10cSrcweir PutUInt16(262, ptr, 2, 1); 727*cdf0e10cSrcweir PutUInt16(0, ptr, 4, 1); 728*cdf0e10cSrcweir 729*cdf0e10cSrcweir for (i = 0; i < 256; i++) { 730*cdf0e10cSrcweir g = 0; 731*cdf0e10cSrcweir for (j = 0; j < s->n; j++) { 732*cdf0e10cSrcweir if (s->xc[j] == i) { 733*cdf0e10cSrcweir g = (sal_uInt16) s->xg[j]; 734*cdf0e10cSrcweir } 735*cdf0e10cSrcweir } 736*cdf0e10cSrcweir p[i] = (sal_uInt8) g; 737*cdf0e10cSrcweir } 738*cdf0e10cSrcweir *length = 262; 739*cdf0e10cSrcweir return ptr; 740*cdf0e10cSrcweir } 741*cdf0e10cSrcweir 742*cdf0e10cSrcweir static sal_uInt8 *PackCmapType6(CmapSubTable *s, sal_uInt32 *length) 743*cdf0e10cSrcweir { 744*cdf0e10cSrcweir sal_uInt8* ptr = (sal_uInt8*)smalloc(s->n*2 + 10); 745*cdf0e10cSrcweir sal_uInt8 *p = ptr + 10; 746*cdf0e10cSrcweir sal_uInt32 i, j; 747*cdf0e10cSrcweir sal_uInt16 g; 748*cdf0e10cSrcweir 749*cdf0e10cSrcweir PutUInt16(6, ptr, 0, 1); 750*cdf0e10cSrcweir PutUInt16((sal_uInt16)(s->n*2+10), ptr, 2, 1); 751*cdf0e10cSrcweir PutUInt16(0, ptr, 4, 1); 752*cdf0e10cSrcweir PutUInt16(0, ptr, 6, 1); 753*cdf0e10cSrcweir PutUInt16((sal_uInt16)(s->n), ptr, 8, 1 ); 754*cdf0e10cSrcweir 755*cdf0e10cSrcweir for (i = 0; i < s->n; i++) { 756*cdf0e10cSrcweir g = 0; 757*cdf0e10cSrcweir for (j = 0; j < s->n; j++) { 758*cdf0e10cSrcweir if (s->xc[j] == i) { 759*cdf0e10cSrcweir g = (sal_uInt16) s->xg[j]; 760*cdf0e10cSrcweir } 761*cdf0e10cSrcweir } 762*cdf0e10cSrcweir PutUInt16( g, p, 2*i, 1 ); 763*cdf0e10cSrcweir } 764*cdf0e10cSrcweir *length = s->n*2+10; 765*cdf0e10cSrcweir return ptr; 766*cdf0e10cSrcweir } 767*cdf0e10cSrcweir 768*cdf0e10cSrcweir 769*cdf0e10cSrcweir 770*cdf0e10cSrcweir /* XXX it only handles Format 0 encoding tables */ 771*cdf0e10cSrcweir static sal_uInt8 *PackCmap(CmapSubTable *s, sal_uInt32 *length) 772*cdf0e10cSrcweir { 773*cdf0e10cSrcweir if( s->xg[s->n-1] > 0xff ) 774*cdf0e10cSrcweir return PackCmapType6(s, length); 775*cdf0e10cSrcweir else 776*cdf0e10cSrcweir return PackCmapType0(s, length); 777*cdf0e10cSrcweir } 778*cdf0e10cSrcweir 779*cdf0e10cSrcweir static int GetRawData_cmap(TrueTypeTable *_this, sal_uInt8 **ptr, sal_uInt32 *len, sal_uInt32 *tag) 780*cdf0e10cSrcweir { 781*cdf0e10cSrcweir table_cmap *t; 782*cdf0e10cSrcweir sal_uInt32 i; 783*cdf0e10cSrcweir sal_uInt32 tlen = 0; 784*cdf0e10cSrcweir sal_uInt32 l; 785*cdf0e10cSrcweir sal_uInt32 cmapsize; 786*cdf0e10cSrcweir sal_uInt8 *cmap; 787*cdf0e10cSrcweir sal_uInt32 coffset; 788*cdf0e10cSrcweir 789*cdf0e10cSrcweir assert(_this != 0); 790*cdf0e10cSrcweir t = (table_cmap *) _this->data; 791*cdf0e10cSrcweir assert(t != 0); 792*cdf0e10cSrcweir assert(t->n != 0); 793*cdf0e10cSrcweir 794*cdf0e10cSrcweir sal_uInt8** subtables = (sal_uInt8**)scalloc(t->n, sizeof(sal_uInt8 *)); 795*cdf0e10cSrcweir sal_uInt32* sizes = (sal_uInt32*)scalloc(t->n, sizeof(sal_uInt32)); 796*cdf0e10cSrcweir 797*cdf0e10cSrcweir for (i = 0; i < t->n; i++) { 798*cdf0e10cSrcweir subtables[i] = PackCmap(t->s+i, &l); 799*cdf0e10cSrcweir sizes[i] = l; 800*cdf0e10cSrcweir tlen += l; 801*cdf0e10cSrcweir } 802*cdf0e10cSrcweir 803*cdf0e10cSrcweir cmapsize = tlen + 4 + 8 * t->n; 804*cdf0e10cSrcweir _this->rawdata = cmap = ttmalloc(cmapsize); 805*cdf0e10cSrcweir 806*cdf0e10cSrcweir PutUInt16(0, cmap, 0, 1); 807*cdf0e10cSrcweir PutUInt16((sal_uInt16)t->n, cmap, 2, 1); 808*cdf0e10cSrcweir coffset = 4 + t->n * 8; 809*cdf0e10cSrcweir 810*cdf0e10cSrcweir for (i = 0; i < t->n; i++) { 811*cdf0e10cSrcweir PutUInt16((sal_uInt16)(t->s[i].id >> 16), cmap + 4, i * 8, 1); 812*cdf0e10cSrcweir PutUInt16((sal_uInt16)(t->s[i].id & 0xFF), cmap + 4, 2 + i * 8, 1); 813*cdf0e10cSrcweir PutUInt32(coffset, cmap + 4, 4 + i * 8, 1); 814*cdf0e10cSrcweir memcpy(cmap + coffset, subtables[i], sizes[i]); 815*cdf0e10cSrcweir free(subtables[i]); 816*cdf0e10cSrcweir coffset += sizes[i]; 817*cdf0e10cSrcweir } 818*cdf0e10cSrcweir 819*cdf0e10cSrcweir free(subtables); 820*cdf0e10cSrcweir free(sizes); 821*cdf0e10cSrcweir 822*cdf0e10cSrcweir *ptr = cmap; 823*cdf0e10cSrcweir *len = cmapsize; 824*cdf0e10cSrcweir *tag = T_cmap; 825*cdf0e10cSrcweir 826*cdf0e10cSrcweir return TTCR_OK; 827*cdf0e10cSrcweir } 828*cdf0e10cSrcweir 829*cdf0e10cSrcweir 830*cdf0e10cSrcweir static int GetRawData_name(TrueTypeTable *_this, sal_uInt8 **ptr, sal_uInt32 *len, sal_uInt32 *tag) 831*cdf0e10cSrcweir { 832*cdf0e10cSrcweir list l; 833*cdf0e10cSrcweir sal_Int16 i=0, n; /* number of Name Records */ 834*cdf0e10cSrcweir int stringLen = 0; 835*cdf0e10cSrcweir sal_uInt8 *p1, *p2; 836*cdf0e10cSrcweir 837*cdf0e10cSrcweir *ptr = 0; 838*cdf0e10cSrcweir *len = 0; 839*cdf0e10cSrcweir *tag = 0; 840*cdf0e10cSrcweir 841*cdf0e10cSrcweir assert(_this != 0); 842*cdf0e10cSrcweir l = (list) _this->data; 843*cdf0e10cSrcweir assert(l != 0); 844*cdf0e10cSrcweir 845*cdf0e10cSrcweir if ((n = (sal_Int16)listCount(l)) == 0) return TTCR_NONAMES; 846*cdf0e10cSrcweir 847*cdf0e10cSrcweir NameRecord* nr = (NameRecord*)scalloc(n, sizeof(NameRecord)); 848*cdf0e10cSrcweir 849*cdf0e10cSrcweir listToFirst(l); 850*cdf0e10cSrcweir 851*cdf0e10cSrcweir do { 852*cdf0e10cSrcweir memcpy(nr+i, listCurrent(l), sizeof(NameRecord)); 853*cdf0e10cSrcweir stringLen += nr[i].slen; 854*cdf0e10cSrcweir i++; 855*cdf0e10cSrcweir } while (listNext(l)); 856*cdf0e10cSrcweir 857*cdf0e10cSrcweir if (stringLen > 65535) { 858*cdf0e10cSrcweir free(nr); 859*cdf0e10cSrcweir return TTCR_NAMETOOLONG; 860*cdf0e10cSrcweir } 861*cdf0e10cSrcweir 862*cdf0e10cSrcweir qsort(nr, n, sizeof(NameRecord), NameRecordCompareF); 863*cdf0e10cSrcweir 864*cdf0e10cSrcweir int nameLen = stringLen + 12 * n + 6; 865*cdf0e10cSrcweir sal_uInt8* name = (sal_uInt8*)ttmalloc(nameLen); 866*cdf0e10cSrcweir 867*cdf0e10cSrcweir PutUInt16(0, name, 0, 1); 868*cdf0e10cSrcweir PutUInt16(n, name, 2, 1); 869*cdf0e10cSrcweir PutUInt16((sal_uInt16)(6 + 12 * n), name, 4, 1); 870*cdf0e10cSrcweir 871*cdf0e10cSrcweir p1 = name + 6; 872*cdf0e10cSrcweir p2 = p1 + 12 * n; 873*cdf0e10cSrcweir 874*cdf0e10cSrcweir for (i = 0; i < n; i++) { 875*cdf0e10cSrcweir PutUInt16(nr[i].platformID, p1, 0, 1); 876*cdf0e10cSrcweir PutUInt16(nr[i].encodingID, p1, 2, 1); 877*cdf0e10cSrcweir PutUInt16(nr[i].languageID, p1, 4, 1); 878*cdf0e10cSrcweir PutUInt16(nr[i].nameID, p1, 6, 1); 879*cdf0e10cSrcweir PutUInt16(nr[i].slen, p1, 8, 1); 880*cdf0e10cSrcweir PutUInt16((sal_uInt16)(p2 - (name + 6 + 12 * n)), p1, 10, 1); 881*cdf0e10cSrcweir memcpy(p2, nr[i].sptr, nr[i].slen); 882*cdf0e10cSrcweir /* {int j; for(j=0; j<nr[i].slen; j++) printf("%c", nr[i].sptr[j]); printf("\n"); }; */ 883*cdf0e10cSrcweir p2 += nr[i].slen; 884*cdf0e10cSrcweir p1 += 12; 885*cdf0e10cSrcweir } 886*cdf0e10cSrcweir 887*cdf0e10cSrcweir free(nr); 888*cdf0e10cSrcweir _this->rawdata = name; 889*cdf0e10cSrcweir 890*cdf0e10cSrcweir *ptr = name; 891*cdf0e10cSrcweir *len = (sal_uInt16)nameLen; 892*cdf0e10cSrcweir *tag = T_name; 893*cdf0e10cSrcweir 894*cdf0e10cSrcweir /*{int j; for(j=0; j<nameLen; j++) printf("%c", name[j]); }; */ 895*cdf0e10cSrcweir 896*cdf0e10cSrcweir return TTCR_OK; 897*cdf0e10cSrcweir } 898*cdf0e10cSrcweir 899*cdf0e10cSrcweir static int GetRawData_post(TrueTypeTable *_this, sal_uInt8 **ptr, sal_uInt32 *len, sal_uInt32 *tag) 900*cdf0e10cSrcweir { 901*cdf0e10cSrcweir tdata_post *p = (tdata_post *) _this->data; 902*cdf0e10cSrcweir sal_uInt8 *post = 0; 903*cdf0e10cSrcweir sal_uInt32 postLen = 0; 904*cdf0e10cSrcweir int ret; 905*cdf0e10cSrcweir 906*cdf0e10cSrcweir if (_this->rawdata) free(_this->rawdata); 907*cdf0e10cSrcweir 908*cdf0e10cSrcweir if (p->format == 0x00030000) { 909*cdf0e10cSrcweir postLen = 32; 910*cdf0e10cSrcweir post = ttmalloc(postLen); 911*cdf0e10cSrcweir PutUInt32(0x00030000, post, 0, 1); 912*cdf0e10cSrcweir PutUInt32(p->italicAngle, post, 4, 1); 913*cdf0e10cSrcweir PutUInt16(p->underlinePosition, post, 8, 1); 914*cdf0e10cSrcweir PutUInt16(p->underlineThickness, post, 10, 1); 915*cdf0e10cSrcweir PutUInt16((sal_uInt16)p->isFixedPitch, post, 12, 1); 916*cdf0e10cSrcweir ret = TTCR_OK; 917*cdf0e10cSrcweir } else { 918*cdf0e10cSrcweir fprintf(stderr, "Unrecognized format of a post table: %08X.\n", (int)p->format); 919*cdf0e10cSrcweir ret = TTCR_POSTFORMAT; 920*cdf0e10cSrcweir } 921*cdf0e10cSrcweir 922*cdf0e10cSrcweir *ptr = _this->rawdata = post; 923*cdf0e10cSrcweir *len = postLen; 924*cdf0e10cSrcweir *tag = T_post; 925*cdf0e10cSrcweir 926*cdf0e10cSrcweir return ret; 927*cdf0e10cSrcweir } 928*cdf0e10cSrcweir 929*cdf0e10cSrcweir 930*cdf0e10cSrcweir 931*cdf0e10cSrcweir 932*cdf0e10cSrcweir 933*cdf0e10cSrcweir static struct { 934*cdf0e10cSrcweir sal_uInt32 tag; 935*cdf0e10cSrcweir int (*f)(TrueTypeTable *, sal_uInt8 **, sal_uInt32 *, sal_uInt32 *); 936*cdf0e10cSrcweir } vtable2[] = 937*cdf0e10cSrcweir { 938*cdf0e10cSrcweir {0, GetRawData_generic}, 939*cdf0e10cSrcweir {T_head, GetRawData_head}, 940*cdf0e10cSrcweir {T_hhea, GetRawData_hhea}, 941*cdf0e10cSrcweir {T_loca, GetRawData_loca}, 942*cdf0e10cSrcweir {T_maxp, GetRawData_maxp}, 943*cdf0e10cSrcweir {T_glyf, GetRawData_glyf}, 944*cdf0e10cSrcweir {T_cmap, GetRawData_cmap}, 945*cdf0e10cSrcweir {T_name, GetRawData_name}, 946*cdf0e10cSrcweir {T_post, GetRawData_post} 947*cdf0e10cSrcweir 948*cdf0e10cSrcweir 949*cdf0e10cSrcweir }; 950*cdf0e10cSrcweir 951*cdf0e10cSrcweir /* 952*cdf0e10cSrcweir * TrueTypeTable public methods 953*cdf0e10cSrcweir */ 954*cdf0e10cSrcweir 955*cdf0e10cSrcweir /* Note: Type42 fonts only need these tables: 956*cdf0e10cSrcweir * head, hhea, loca, maxp, cvt, prep, glyf, hmtx, fpgm 957*cdf0e10cSrcweir * 958*cdf0e10cSrcweir * Microsoft required tables 959*cdf0e10cSrcweir * cmap, glyf, head, hhea, hmtx, loca, maxp, name, post, OS/2 960*cdf0e10cSrcweir * 961*cdf0e10cSrcweir * Apple required tables 962*cdf0e10cSrcweir * cmap, glyf, head, hhea, hmtx, loca, maxp, name, post 963*cdf0e10cSrcweir * 964*cdf0e10cSrcweir */ 965*cdf0e10cSrcweir 966*cdf0e10cSrcweir TrueTypeTable *TrueTypeTableNew(sal_uInt32 tag, 967*cdf0e10cSrcweir sal_uInt32 nbytes, 968*cdf0e10cSrcweir const sal_uInt8* ptr) 969*cdf0e10cSrcweir { 970*cdf0e10cSrcweir TrueTypeTable* table = (TrueTypeTable*)smalloc(sizeof(TrueTypeTable)); 971*cdf0e10cSrcweir tdata_generic* pdata = (tdata_generic*)smalloc(sizeof(tdata_generic)); 972*cdf0e10cSrcweir pdata->nbytes = nbytes; 973*cdf0e10cSrcweir pdata->tag = tag; 974*cdf0e10cSrcweir if (nbytes) { 975*cdf0e10cSrcweir pdata->ptr = ttmalloc(nbytes); 976*cdf0e10cSrcweir memcpy(pdata->ptr, ptr, nbytes); 977*cdf0e10cSrcweir } else { 978*cdf0e10cSrcweir pdata->ptr = 0; 979*cdf0e10cSrcweir } 980*cdf0e10cSrcweir 981*cdf0e10cSrcweir table->tag = 0; 982*cdf0e10cSrcweir table->data = pdata; 983*cdf0e10cSrcweir table->rawdata = 0; 984*cdf0e10cSrcweir 985*cdf0e10cSrcweir return table; 986*cdf0e10cSrcweir } 987*cdf0e10cSrcweir 988*cdf0e10cSrcweir TrueTypeTable *TrueTypeTableNew_head(sal_uInt32 fontRevision, 989*cdf0e10cSrcweir sal_uInt16 flags, 990*cdf0e10cSrcweir sal_uInt16 unitsPerEm, 991*cdf0e10cSrcweir const sal_uInt8* created, 992*cdf0e10cSrcweir sal_uInt16 macStyle, 993*cdf0e10cSrcweir sal_uInt16 lowestRecPPEM, 994*cdf0e10cSrcweir sal_Int16 fontDirectionHint) 995*cdf0e10cSrcweir { 996*cdf0e10cSrcweir assert(created != 0); 997*cdf0e10cSrcweir 998*cdf0e10cSrcweir TrueTypeTable* table = (TrueTypeTable*)smalloc(sizeof(TrueTypeTable)); 999*cdf0e10cSrcweir sal_uInt8* ptr = (sal_uInt8*)ttmalloc(TABLESIZE_head); 1000*cdf0e10cSrcweir 1001*cdf0e10cSrcweir 1002*cdf0e10cSrcweir PutUInt32(0x00010000, ptr, 0, 1); /* version */ 1003*cdf0e10cSrcweir PutUInt32(fontRevision, ptr, 4, 1); 1004*cdf0e10cSrcweir PutUInt32(0x5F0F3CF5, ptr, 12, 1); /* magic number */ 1005*cdf0e10cSrcweir PutUInt16(flags, ptr, 16, 1); 1006*cdf0e10cSrcweir PutUInt16(unitsPerEm, ptr, 18, 1); 1007*cdf0e10cSrcweir memcpy(ptr+20, created, 8); /* Created Long Date */ 1008*cdf0e10cSrcweir memset(ptr+28, 0, 8); /* Modified Long Date */ 1009*cdf0e10cSrcweir PutUInt16(macStyle, ptr, 44, 1); 1010*cdf0e10cSrcweir PutUInt16(lowestRecPPEM, ptr, 46, 1); 1011*cdf0e10cSrcweir PutUInt16(fontDirectionHint, ptr, 48, 1); 1012*cdf0e10cSrcweir PutUInt16(0, ptr, 52, 1); /* glyph data format: 0 */ 1013*cdf0e10cSrcweir 1014*cdf0e10cSrcweir table->data = (void *) ptr; 1015*cdf0e10cSrcweir table->tag = T_head; 1016*cdf0e10cSrcweir table->rawdata = 0; 1017*cdf0e10cSrcweir 1018*cdf0e10cSrcweir return table; 1019*cdf0e10cSrcweir } 1020*cdf0e10cSrcweir 1021*cdf0e10cSrcweir TrueTypeTable *TrueTypeTableNew_hhea(sal_Int16 ascender, 1022*cdf0e10cSrcweir sal_Int16 descender, 1023*cdf0e10cSrcweir sal_Int16 linegap, 1024*cdf0e10cSrcweir sal_Int16 caretSlopeRise, 1025*cdf0e10cSrcweir sal_Int16 caretSlopeRun) 1026*cdf0e10cSrcweir { 1027*cdf0e10cSrcweir TrueTypeTable* table = (TrueTypeTable*)smalloc(sizeof(TrueTypeTable)); 1028*cdf0e10cSrcweir sal_uInt8* ptr = (sal_uInt8*)ttmalloc(TABLESIZE_hhea); 1029*cdf0e10cSrcweir 1030*cdf0e10cSrcweir PutUInt32(0x00010000, ptr, 0, 1); /* version */ 1031*cdf0e10cSrcweir PutUInt16(ascender, ptr, 4, 1); 1032*cdf0e10cSrcweir PutUInt16(descender, ptr, 6, 1); 1033*cdf0e10cSrcweir PutUInt16(linegap, ptr, 8, 1); 1034*cdf0e10cSrcweir PutUInt16(caretSlopeRise, ptr, 18, 1); 1035*cdf0e10cSrcweir PutUInt16(caretSlopeRun, ptr, 20, 1); 1036*cdf0e10cSrcweir PutUInt16(0, ptr, 22, 1); /* reserved 1 */ 1037*cdf0e10cSrcweir PutUInt16(0, ptr, 24, 1); /* reserved 2 */ 1038*cdf0e10cSrcweir PutUInt16(0, ptr, 26, 1); /* reserved 3 */ 1039*cdf0e10cSrcweir PutUInt16(0, ptr, 28, 1); /* reserved 4 */ 1040*cdf0e10cSrcweir PutUInt16(0, ptr, 30, 1); /* reserved 5 */ 1041*cdf0e10cSrcweir PutUInt16(0, ptr, 32, 1); /* metricDataFormat */ 1042*cdf0e10cSrcweir 1043*cdf0e10cSrcweir table->data = (void *) ptr; 1044*cdf0e10cSrcweir table->tag = T_hhea; 1045*cdf0e10cSrcweir table->rawdata = 0; 1046*cdf0e10cSrcweir 1047*cdf0e10cSrcweir return table; 1048*cdf0e10cSrcweir } 1049*cdf0e10cSrcweir 1050*cdf0e10cSrcweir TrueTypeTable *TrueTypeTableNew_loca(void) 1051*cdf0e10cSrcweir { 1052*cdf0e10cSrcweir TrueTypeTable* table = (TrueTypeTable*)smalloc(sizeof(TrueTypeTable)); 1053*cdf0e10cSrcweir table->data = smalloc(sizeof(tdata_loca)); 1054*cdf0e10cSrcweir 1055*cdf0e10cSrcweir ((tdata_loca *)table->data)->nbytes = 0; 1056*cdf0e10cSrcweir ((tdata_loca *)table->data)->ptr = 0; 1057*cdf0e10cSrcweir 1058*cdf0e10cSrcweir table->tag = T_loca; 1059*cdf0e10cSrcweir table->rawdata = 0; 1060*cdf0e10cSrcweir 1061*cdf0e10cSrcweir return table; 1062*cdf0e10cSrcweir } 1063*cdf0e10cSrcweir 1064*cdf0e10cSrcweir TrueTypeTable *TrueTypeTableNew_maxp( const sal_uInt8* maxp, int size) 1065*cdf0e10cSrcweir { 1066*cdf0e10cSrcweir TrueTypeTable* table = (TrueTypeTable*)smalloc(sizeof(TrueTypeTable)); 1067*cdf0e10cSrcweir table->data = ttmalloc(TABLESIZE_maxp); 1068*cdf0e10cSrcweir 1069*cdf0e10cSrcweir if (maxp && size == TABLESIZE_maxp) { 1070*cdf0e10cSrcweir memcpy(table->data, maxp, TABLESIZE_maxp); 1071*cdf0e10cSrcweir } 1072*cdf0e10cSrcweir 1073*cdf0e10cSrcweir table->tag = T_maxp; 1074*cdf0e10cSrcweir table->rawdata = 0; 1075*cdf0e10cSrcweir 1076*cdf0e10cSrcweir return table; 1077*cdf0e10cSrcweir } 1078*cdf0e10cSrcweir 1079*cdf0e10cSrcweir TrueTypeTable *TrueTypeTableNew_glyf(void) 1080*cdf0e10cSrcweir { 1081*cdf0e10cSrcweir TrueTypeTable* table = (TrueTypeTable*)smalloc(sizeof(TrueTypeTable)); 1082*cdf0e10cSrcweir list l = listNewEmpty(); 1083*cdf0e10cSrcweir 1084*cdf0e10cSrcweir assert(l != 0); 1085*cdf0e10cSrcweir 1086*cdf0e10cSrcweir listSetElementDtor(l, (list_destructor)FreeGlyphData); 1087*cdf0e10cSrcweir 1088*cdf0e10cSrcweir table->data = l; 1089*cdf0e10cSrcweir table->rawdata = 0; 1090*cdf0e10cSrcweir table->tag = T_glyf; 1091*cdf0e10cSrcweir 1092*cdf0e10cSrcweir return table; 1093*cdf0e10cSrcweir } 1094*cdf0e10cSrcweir 1095*cdf0e10cSrcweir TrueTypeTable *TrueTypeTableNew_cmap(void) 1096*cdf0e10cSrcweir { 1097*cdf0e10cSrcweir TrueTypeTable* table = (TrueTypeTable*)smalloc(sizeof(TrueTypeTable)); 1098*cdf0e10cSrcweir table_cmap* cmap = (table_cmap*)smalloc(sizeof(table_cmap)); 1099*cdf0e10cSrcweir 1100*cdf0e10cSrcweir cmap->n = 0; 1101*cdf0e10cSrcweir cmap->m = CMAP_SUBTABLE_INIT; 1102*cdf0e10cSrcweir cmap->s = (CmapSubTable *) scalloc(CMAP_SUBTABLE_INIT, sizeof(CmapSubTable)); 1103*cdf0e10cSrcweir memset(cmap->s, 0, sizeof(CmapSubTable) * CMAP_SUBTABLE_INIT); 1104*cdf0e10cSrcweir 1105*cdf0e10cSrcweir table->data = (table_cmap *) cmap; 1106*cdf0e10cSrcweir 1107*cdf0e10cSrcweir table->rawdata = 0; 1108*cdf0e10cSrcweir table->tag = T_cmap; 1109*cdf0e10cSrcweir 1110*cdf0e10cSrcweir return table; 1111*cdf0e10cSrcweir } 1112*cdf0e10cSrcweir 1113*cdf0e10cSrcweir static void DisposeNameRecord(void *ptr) 1114*cdf0e10cSrcweir { 1115*cdf0e10cSrcweir if (ptr != 0) { 1116*cdf0e10cSrcweir NameRecord *nr = (NameRecord *) ptr; 1117*cdf0e10cSrcweir if (nr->sptr) free(nr->sptr); 1118*cdf0e10cSrcweir free(ptr); 1119*cdf0e10cSrcweir } 1120*cdf0e10cSrcweir } 1121*cdf0e10cSrcweir 1122*cdf0e10cSrcweir static NameRecord* NameRecordNewCopy(NameRecord *nr) 1123*cdf0e10cSrcweir { 1124*cdf0e10cSrcweir NameRecord* p = (NameRecord*)smalloc(sizeof(NameRecord)); 1125*cdf0e10cSrcweir 1126*cdf0e10cSrcweir memcpy(p, nr, sizeof(NameRecord)); 1127*cdf0e10cSrcweir 1128*cdf0e10cSrcweir if (p->slen) { 1129*cdf0e10cSrcweir p->sptr = (sal_uInt8*)smalloc(p->slen); 1130*cdf0e10cSrcweir memcpy(p->sptr, nr->sptr, p->slen); 1131*cdf0e10cSrcweir } 1132*cdf0e10cSrcweir 1133*cdf0e10cSrcweir return p; 1134*cdf0e10cSrcweir } 1135*cdf0e10cSrcweir 1136*cdf0e10cSrcweir TrueTypeTable *TrueTypeTableNew_name(int n, NameRecord *nr) 1137*cdf0e10cSrcweir { 1138*cdf0e10cSrcweir TrueTypeTable* table = (TrueTypeTable*)smalloc(sizeof(TrueTypeTable)); 1139*cdf0e10cSrcweir list l = listNewEmpty(); 1140*cdf0e10cSrcweir 1141*cdf0e10cSrcweir assert(l != 0); 1142*cdf0e10cSrcweir 1143*cdf0e10cSrcweir listSetElementDtor(l, (list_destructor)DisposeNameRecord); 1144*cdf0e10cSrcweir 1145*cdf0e10cSrcweir if (n != 0) { 1146*cdf0e10cSrcweir int i; 1147*cdf0e10cSrcweir for (i = 0; i < n; i++) { 1148*cdf0e10cSrcweir listAppend(l, NameRecordNewCopy(nr+i)); 1149*cdf0e10cSrcweir } 1150*cdf0e10cSrcweir } 1151*cdf0e10cSrcweir 1152*cdf0e10cSrcweir table->data = l; 1153*cdf0e10cSrcweir table->rawdata = 0; 1154*cdf0e10cSrcweir table->tag = T_name; 1155*cdf0e10cSrcweir 1156*cdf0e10cSrcweir return table; 1157*cdf0e10cSrcweir } 1158*cdf0e10cSrcweir 1159*cdf0e10cSrcweir TrueTypeTable *TrueTypeTableNew_post(sal_uInt32 format, 1160*cdf0e10cSrcweir sal_uInt32 italicAngle, 1161*cdf0e10cSrcweir sal_Int16 underlinePosition, 1162*cdf0e10cSrcweir sal_Int16 underlineThickness, 1163*cdf0e10cSrcweir sal_uInt32 isFixedPitch) 1164*cdf0e10cSrcweir { 1165*cdf0e10cSrcweir assert(format == 0x00030000); /* Only format 3.0 is supported at this time */ 1166*cdf0e10cSrcweir TrueTypeTable* table = (TrueTypeTable*)smalloc(sizeof(TrueTypeTable)); 1167*cdf0e10cSrcweir tdata_post* post = (tdata_post*)smalloc(sizeof(tdata_post)); 1168*cdf0e10cSrcweir 1169*cdf0e10cSrcweir post->format = format; 1170*cdf0e10cSrcweir post->italicAngle = italicAngle; 1171*cdf0e10cSrcweir post->underlinePosition = underlinePosition; 1172*cdf0e10cSrcweir post->underlineThickness = underlineThickness; 1173*cdf0e10cSrcweir post->isFixedPitch = isFixedPitch; 1174*cdf0e10cSrcweir post->ptr = 0; 1175*cdf0e10cSrcweir 1176*cdf0e10cSrcweir table->data = post; 1177*cdf0e10cSrcweir table->rawdata = 0; 1178*cdf0e10cSrcweir table->tag = T_post; 1179*cdf0e10cSrcweir 1180*cdf0e10cSrcweir return table; 1181*cdf0e10cSrcweir } 1182*cdf0e10cSrcweir 1183*cdf0e10cSrcweir int GetRawData(TrueTypeTable *_this, sal_uInt8 **ptr, sal_uInt32 *len, sal_uInt32 *tag) 1184*cdf0e10cSrcweir { 1185*cdf0e10cSrcweir /* XXX do a binary search */ 1186*cdf0e10cSrcweir unsigned int i; 1187*cdf0e10cSrcweir 1188*cdf0e10cSrcweir assert(_this != 0); 1189*cdf0e10cSrcweir assert(ptr != 0); 1190*cdf0e10cSrcweir assert(len != 0); 1191*cdf0e10cSrcweir assert(tag != 0); 1192*cdf0e10cSrcweir 1193*cdf0e10cSrcweir *ptr = 0; *len = 0; *tag = 0; 1194*cdf0e10cSrcweir 1195*cdf0e10cSrcweir if (_this->rawdata) { 1196*cdf0e10cSrcweir free(_this->rawdata); 1197*cdf0e10cSrcweir _this->rawdata = 0; 1198*cdf0e10cSrcweir } 1199*cdf0e10cSrcweir 1200*cdf0e10cSrcweir for(i=0; i < sizeof(vtable2)/sizeof(*vtable2); i++) { 1201*cdf0e10cSrcweir if (_this->tag == vtable2[i].tag) { 1202*cdf0e10cSrcweir return vtable2[i].f(_this, ptr, len, tag); 1203*cdf0e10cSrcweir } 1204*cdf0e10cSrcweir } 1205*cdf0e10cSrcweir 1206*cdf0e10cSrcweir assert(!"Unknwon TrueType table.\n"); 1207*cdf0e10cSrcweir return TTCR_UNKNOWN; 1208*cdf0e10cSrcweir } 1209*cdf0e10cSrcweir 1210*cdf0e10cSrcweir void cmapAdd(TrueTypeTable *table, sal_uInt32 id, sal_uInt32 c, sal_uInt32 g) 1211*cdf0e10cSrcweir { 1212*cdf0e10cSrcweir sal_uInt32 i, found; 1213*cdf0e10cSrcweir table_cmap *t; 1214*cdf0e10cSrcweir CmapSubTable *s; 1215*cdf0e10cSrcweir 1216*cdf0e10cSrcweir assert(table != 0); 1217*cdf0e10cSrcweir assert(table->tag == T_cmap); 1218*cdf0e10cSrcweir t = (table_cmap *) table->data; assert(t != 0); 1219*cdf0e10cSrcweir s = t->s; assert(s != 0); 1220*cdf0e10cSrcweir 1221*cdf0e10cSrcweir found = 0; 1222*cdf0e10cSrcweir 1223*cdf0e10cSrcweir for (i = 0; i < t->n; i++) { 1224*cdf0e10cSrcweir if (s[i].id == id) { 1225*cdf0e10cSrcweir found = 1; 1226*cdf0e10cSrcweir break; 1227*cdf0e10cSrcweir } 1228*cdf0e10cSrcweir } 1229*cdf0e10cSrcweir 1230*cdf0e10cSrcweir if (!found) { 1231*cdf0e10cSrcweir if (t->n == t->m) { 1232*cdf0e10cSrcweir CmapSubTable* tmp = (CmapSubTable*)scalloc(t->m + CMAP_SUBTABLE_INCR, sizeof(CmapSubTable)); 1233*cdf0e10cSrcweir memset(tmp, 0, t->m + CMAP_SUBTABLE_INCR * sizeof(CmapSubTable)); 1234*cdf0e10cSrcweir memcpy(tmp, s, sizeof(CmapSubTable) * t->m); 1235*cdf0e10cSrcweir t->m += CMAP_SUBTABLE_INCR; 1236*cdf0e10cSrcweir free(s); 1237*cdf0e10cSrcweir s = tmp; 1238*cdf0e10cSrcweir t->s = s; 1239*cdf0e10cSrcweir } 1240*cdf0e10cSrcweir 1241*cdf0e10cSrcweir for (i = 0; i < t->n; i++) { 1242*cdf0e10cSrcweir if (s[i].id > id) break; 1243*cdf0e10cSrcweir } 1244*cdf0e10cSrcweir 1245*cdf0e10cSrcweir if (i < t->n) { 1246*cdf0e10cSrcweir memmove(s+i+1, s+i, t->n-i); 1247*cdf0e10cSrcweir } 1248*cdf0e10cSrcweir 1249*cdf0e10cSrcweir t->n++; 1250*cdf0e10cSrcweir 1251*cdf0e10cSrcweir s[i].id = id; 1252*cdf0e10cSrcweir s[i].n = 0; 1253*cdf0e10cSrcweir s[i].m = CMAP_PAIR_INIT; 1254*cdf0e10cSrcweir s[i].xc = (sal_uInt32*)scalloc(CMAP_PAIR_INIT, sizeof(sal_uInt32)); 1255*cdf0e10cSrcweir s[i].xg = (sal_uInt32*)scalloc(CMAP_PAIR_INIT, sizeof(sal_uInt32)); 1256*cdf0e10cSrcweir } 1257*cdf0e10cSrcweir 1258*cdf0e10cSrcweir if (s[i].n == s[i].m) { 1259*cdf0e10cSrcweir sal_uInt32* tmp1 = (sal_uInt32*)scalloc(s[i].m + CMAP_PAIR_INCR, sizeof(sal_uInt32)); 1260*cdf0e10cSrcweir sal_uInt32* tmp2 = (sal_uInt32*)scalloc(s[i].m + CMAP_PAIR_INCR, sizeof(sal_uInt32)); 1261*cdf0e10cSrcweir assert(tmp1 != 0); 1262*cdf0e10cSrcweir assert(tmp2 != 0); 1263*cdf0e10cSrcweir memcpy(tmp1, s[i].xc, sizeof(sal_uInt32) * s[i].m); 1264*cdf0e10cSrcweir memcpy(tmp2, s[i].xg, sizeof(sal_uInt32) * s[i].m); 1265*cdf0e10cSrcweir s[i].m += CMAP_PAIR_INCR; 1266*cdf0e10cSrcweir free(s[i].xc); 1267*cdf0e10cSrcweir free(s[i].xg); 1268*cdf0e10cSrcweir s[i].xc = tmp1; 1269*cdf0e10cSrcweir s[i].xg = tmp2; 1270*cdf0e10cSrcweir } 1271*cdf0e10cSrcweir 1272*cdf0e10cSrcweir s[i].xc[s[i].n] = c; 1273*cdf0e10cSrcweir s[i].xg[s[i].n] = g; 1274*cdf0e10cSrcweir s[i].n++; 1275*cdf0e10cSrcweir } 1276*cdf0e10cSrcweir 1277*cdf0e10cSrcweir sal_uInt32 glyfAdd(TrueTypeTable *table, GlyphData *glyphdata, TrueTypeFont *fnt) 1278*cdf0e10cSrcweir { 1279*cdf0e10cSrcweir list l; 1280*cdf0e10cSrcweir sal_uInt32 currentID; 1281*cdf0e10cSrcweir int ret, n, ncomponents; 1282*cdf0e10cSrcweir GlyphData *gd; 1283*cdf0e10cSrcweir 1284*cdf0e10cSrcweir assert(table != 0); 1285*cdf0e10cSrcweir assert(table->tag == T_glyf); 1286*cdf0e10cSrcweir 1287*cdf0e10cSrcweir if (!glyphdata) return (sal_uInt32)~0; 1288*cdf0e10cSrcweir 1289*cdf0e10cSrcweir std::vector< sal_uInt32 > glyphlist; 1290*cdf0e10cSrcweir 1291*cdf0e10cSrcweir ncomponents = GetTTGlyphComponents(fnt, glyphdata->glyphID, glyphlist); 1292*cdf0e10cSrcweir 1293*cdf0e10cSrcweir l = (list) table->data; 1294*cdf0e10cSrcweir if (listCount(l) > 0) { 1295*cdf0e10cSrcweir listToLast(l); 1296*cdf0e10cSrcweir ret = n = ((GlyphData *) listCurrent(l))->newID + 1; 1297*cdf0e10cSrcweir } else { 1298*cdf0e10cSrcweir ret = n = 0; 1299*cdf0e10cSrcweir } 1300*cdf0e10cSrcweir glyphdata->newID = n++; 1301*cdf0e10cSrcweir listAppend(l, glyphdata); 1302*cdf0e10cSrcweir 1303*cdf0e10cSrcweir if (ncomponents > 1 && glyphlist.size() > 1 ) 1304*cdf0e10cSrcweir { 1305*cdf0e10cSrcweir std::vector< sal_uInt32 >::const_iterator it = glyphlist.begin(); 1306*cdf0e10cSrcweir ++it; 1307*cdf0e10cSrcweir /* glyphData->glyphID is always the first glyph on the list */ 1308*cdf0e10cSrcweir do 1309*cdf0e10cSrcweir { 1310*cdf0e10cSrcweir int found = 0; 1311*cdf0e10cSrcweir currentID = *it; 1312*cdf0e10cSrcweir /* XXX expensive! should be rewritten with sorted arrays! */ 1313*cdf0e10cSrcweir listToFirst(l); 1314*cdf0e10cSrcweir do { 1315*cdf0e10cSrcweir if (((GlyphData *) listCurrent(l))->glyphID == currentID) { 1316*cdf0e10cSrcweir found = 1; 1317*cdf0e10cSrcweir break; 1318*cdf0e10cSrcweir } 1319*cdf0e10cSrcweir } while (listNext(l)); 1320*cdf0e10cSrcweir 1321*cdf0e10cSrcweir if (!found) { 1322*cdf0e10cSrcweir gd = GetTTRawGlyphData(fnt, currentID); 1323*cdf0e10cSrcweir gd->newID = n++; 1324*cdf0e10cSrcweir listAppend(l, gd); 1325*cdf0e10cSrcweir } 1326*cdf0e10cSrcweir } while( ++it != glyphlist.end() ); 1327*cdf0e10cSrcweir } 1328*cdf0e10cSrcweir 1329*cdf0e10cSrcweir return ret; 1330*cdf0e10cSrcweir } 1331*cdf0e10cSrcweir 1332*cdf0e10cSrcweir sal_uInt32 glyfCount(const TrueTypeTable *table) 1333*cdf0e10cSrcweir { 1334*cdf0e10cSrcweir assert(table != 0); 1335*cdf0e10cSrcweir assert(table->tag == T_glyf); 1336*cdf0e10cSrcweir return listCount((list) table->data); 1337*cdf0e10cSrcweir } 1338*cdf0e10cSrcweir 1339*cdf0e10cSrcweir 1340*cdf0e10cSrcweir void nameAdd(TrueTypeTable *table, NameRecord *nr) 1341*cdf0e10cSrcweir { 1342*cdf0e10cSrcweir list l; 1343*cdf0e10cSrcweir 1344*cdf0e10cSrcweir assert(table != 0); 1345*cdf0e10cSrcweir assert(table->tag == T_name); 1346*cdf0e10cSrcweir 1347*cdf0e10cSrcweir l = (list) table->data; 1348*cdf0e10cSrcweir 1349*cdf0e10cSrcweir listAppend(l, NameRecordNewCopy(nr)); 1350*cdf0e10cSrcweir } 1351*cdf0e10cSrcweir 1352*cdf0e10cSrcweir static TrueTypeTable *FindTable(TrueTypeCreator *tt, sal_uInt32 tag) 1353*cdf0e10cSrcweir { 1354*cdf0e10cSrcweir if (listIsEmpty(tt->tables)) return 0; 1355*cdf0e10cSrcweir 1356*cdf0e10cSrcweir listToFirst(tt->tables); 1357*cdf0e10cSrcweir 1358*cdf0e10cSrcweir do { 1359*cdf0e10cSrcweir if (((TrueTypeTable *) listCurrent(tt->tables))->tag == tag) { 1360*cdf0e10cSrcweir return (TrueTypeTable*)listCurrent(tt->tables); 1361*cdf0e10cSrcweir } 1362*cdf0e10cSrcweir } while (listNext(tt->tables)); 1363*cdf0e10cSrcweir 1364*cdf0e10cSrcweir return 0; 1365*cdf0e10cSrcweir } 1366*cdf0e10cSrcweir 1367*cdf0e10cSrcweir /* This function processes all the tables and synchronizes them before creating 1368*cdf0e10cSrcweir * the output TrueType stream. 1369*cdf0e10cSrcweir * 1370*cdf0e10cSrcweir * *** It adds two TrueType tables to the font: 'loca' and 'hmtx' *** 1371*cdf0e10cSrcweir * 1372*cdf0e10cSrcweir * It does: 1373*cdf0e10cSrcweir * 1374*cdf0e10cSrcweir * - Re-numbers glyph IDs and creates 'glyf', 'loca', and 'hmtx' tables. 1375*cdf0e10cSrcweir * - Calculates xMin, yMin, xMax, and yMax and stores values in 'head' table. 1376*cdf0e10cSrcweir * - Stores indexToLocFormat in 'head' 1377*cdf0e10cSrcweir * - updates 'maxp' table 1378*cdf0e10cSrcweir * - Calculates advanceWidthMax, minLSB, minRSB, xMaxExtent and numberOfHMetrics 1379*cdf0e10cSrcweir * in 'hhea' table 1380*cdf0e10cSrcweir * 1381*cdf0e10cSrcweir */ 1382*cdf0e10cSrcweir static void ProcessTables(TrueTypeCreator *tt) 1383*cdf0e10cSrcweir { 1384*cdf0e10cSrcweir TrueTypeTable *glyf, *loca, *head, *maxp, *hhea; 1385*cdf0e10cSrcweir list glyphlist; 1386*cdf0e10cSrcweir sal_uInt32 nGlyphs, locaLen = 0, glyfLen = 0; 1387*cdf0e10cSrcweir sal_Int16 xMin = 0, yMin = 0, xMax = 0, yMax = 0; 1388*cdf0e10cSrcweir sal_uInt32 i = 0; 1389*cdf0e10cSrcweir sal_Int16 indexToLocFormat; 1390*cdf0e10cSrcweir sal_uInt8 *hmtxPtr, *hheaPtr; 1391*cdf0e10cSrcweir sal_uInt32 hmtxSize; 1392*cdf0e10cSrcweir sal_uInt8 *p1, *p2; 1393*cdf0e10cSrcweir sal_uInt16 maxPoints = 0, maxContours = 0, maxCompositePoints = 0, maxCompositeContours = 0; 1394*cdf0e10cSrcweir int nlsb = 0; 1395*cdf0e10cSrcweir sal_uInt32 *gid; /* array of old glyphIDs */ 1396*cdf0e10cSrcweir 1397*cdf0e10cSrcweir glyf = FindTable(tt, T_glyf); 1398*cdf0e10cSrcweir glyphlist = (list) glyf->data; 1399*cdf0e10cSrcweir nGlyphs = listCount(glyphlist); 1400*cdf0e10cSrcweir assert(nGlyphs != 0); 1401*cdf0e10cSrcweir gid = (sal_uInt32*)scalloc(nGlyphs, sizeof(sal_uInt32)); 1402*cdf0e10cSrcweir 1403*cdf0e10cSrcweir RemoveTable(tt, T_loca); 1404*cdf0e10cSrcweir RemoveTable(tt, T_hmtx); 1405*cdf0e10cSrcweir 1406*cdf0e10cSrcweir /* XXX Need to make sure that composite glyphs do not break during glyph renumbering */ 1407*cdf0e10cSrcweir 1408*cdf0e10cSrcweir listToFirst(glyphlist); 1409*cdf0e10cSrcweir do { 1410*cdf0e10cSrcweir GlyphData *gd = (GlyphData *) listCurrent(glyphlist); 1411*cdf0e10cSrcweir sal_Int16 z; 1412*cdf0e10cSrcweir glyfLen += gd->nbytes; 1413*cdf0e10cSrcweir /* XXX if (gd->nbytes & 1) glyfLen++; */ 1414*cdf0e10cSrcweir 1415*cdf0e10cSrcweir 1416*cdf0e10cSrcweir assert(gd->newID == i); 1417*cdf0e10cSrcweir gid[i++] = gd->glyphID; 1418*cdf0e10cSrcweir /* gd->glyphID = i++; */ 1419*cdf0e10cSrcweir 1420*cdf0e10cSrcweir /* printf("IDs: %d %d.\n", gd->glyphID, gd->newID); */ 1421*cdf0e10cSrcweir 1422*cdf0e10cSrcweir if (gd->nbytes != 0) { 1423*cdf0e10cSrcweir z = GetInt16(gd->ptr, 2, 1); 1424*cdf0e10cSrcweir if (z < xMin) xMin = z; 1425*cdf0e10cSrcweir 1426*cdf0e10cSrcweir z = GetInt16(gd->ptr, 4, 1); 1427*cdf0e10cSrcweir if (z < yMin) yMin = z; 1428*cdf0e10cSrcweir 1429*cdf0e10cSrcweir z = GetInt16(gd->ptr, 6, 1); 1430*cdf0e10cSrcweir if (z > xMax) xMax = z; 1431*cdf0e10cSrcweir 1432*cdf0e10cSrcweir z = GetInt16(gd->ptr, 8, 1); 1433*cdf0e10cSrcweir if (z > yMax) yMax = z; 1434*cdf0e10cSrcweir } 1435*cdf0e10cSrcweir 1436*cdf0e10cSrcweir if (gd->compflag == 0) { /* non-composite glyph */ 1437*cdf0e10cSrcweir if (gd->npoints > maxPoints) maxPoints = gd->npoints; 1438*cdf0e10cSrcweir if (gd->ncontours > maxContours) maxContours = gd->ncontours; 1439*cdf0e10cSrcweir } else { /* composite glyph */ 1440*cdf0e10cSrcweir if (gd->npoints > maxCompositePoints) maxCompositePoints = gd->npoints; 1441*cdf0e10cSrcweir if (gd->ncontours > maxCompositeContours) maxCompositeContours = gd->ncontours; 1442*cdf0e10cSrcweir } 1443*cdf0e10cSrcweir 1444*cdf0e10cSrcweir } while (listNext(glyphlist)); 1445*cdf0e10cSrcweir 1446*cdf0e10cSrcweir indexToLocFormat = (glyfLen / 2 > 0xFFFF) ? 1 : 0; 1447*cdf0e10cSrcweir locaLen = indexToLocFormat ? (nGlyphs + 1) << 2 : (nGlyphs + 1) << 1; 1448*cdf0e10cSrcweir 1449*cdf0e10cSrcweir sal_uInt8* glyfPtr = ttmalloc(glyfLen); 1450*cdf0e10cSrcweir sal_uInt8* locaPtr = ttmalloc(locaLen); 1451*cdf0e10cSrcweir TTSimpleGlyphMetrics* met = (TTSimpleGlyphMetrics*)scalloc(nGlyphs, sizeof(TTSimpleGlyphMetrics)); 1452*cdf0e10cSrcweir i = 0; 1453*cdf0e10cSrcweir 1454*cdf0e10cSrcweir listToFirst(glyphlist); 1455*cdf0e10cSrcweir p1 = glyfPtr; 1456*cdf0e10cSrcweir p2 = locaPtr; 1457*cdf0e10cSrcweir do { 1458*cdf0e10cSrcweir GlyphData *gd = (GlyphData *) listCurrent(glyphlist); 1459*cdf0e10cSrcweir 1460*cdf0e10cSrcweir if (gd->compflag) { /* re-number all components */ 1461*cdf0e10cSrcweir sal_uInt16 flags, index; 1462*cdf0e10cSrcweir sal_uInt8 *ptr = gd->ptr + 10; 1463*cdf0e10cSrcweir do { 1464*cdf0e10cSrcweir sal_uInt32 j; 1465*cdf0e10cSrcweir flags = GetUInt16(ptr, 0, 1); 1466*cdf0e10cSrcweir index = GetUInt16(ptr, 2, 1); 1467*cdf0e10cSrcweir /* XXX use the sorted array of old to new glyphID mapping and do a binary search */ 1468*cdf0e10cSrcweir for (j = 0; j < nGlyphs; j++) { 1469*cdf0e10cSrcweir if (gid[j] == index) { 1470*cdf0e10cSrcweir break; 1471*cdf0e10cSrcweir } 1472*cdf0e10cSrcweir } 1473*cdf0e10cSrcweir /* printf("X: %d -> %d.\n", index, j); */ 1474*cdf0e10cSrcweir 1475*cdf0e10cSrcweir PutUInt16((sal_uInt16) j, ptr, 2, 1); 1476*cdf0e10cSrcweir 1477*cdf0e10cSrcweir ptr += 4; 1478*cdf0e10cSrcweir 1479*cdf0e10cSrcweir if (flags & ARG_1_AND_2_ARE_WORDS) { 1480*cdf0e10cSrcweir ptr += 4; 1481*cdf0e10cSrcweir } else { 1482*cdf0e10cSrcweir ptr += 2; 1483*cdf0e10cSrcweir } 1484*cdf0e10cSrcweir 1485*cdf0e10cSrcweir if (flags & WE_HAVE_A_SCALE) { 1486*cdf0e10cSrcweir ptr += 2; 1487*cdf0e10cSrcweir } else if (flags & WE_HAVE_AN_X_AND_Y_SCALE) { 1488*cdf0e10cSrcweir ptr += 4; 1489*cdf0e10cSrcweir } else if (flags & WE_HAVE_A_TWO_BY_TWO) { 1490*cdf0e10cSrcweir ptr += 8; 1491*cdf0e10cSrcweir } 1492*cdf0e10cSrcweir } while (flags & MORE_COMPONENTS); 1493*cdf0e10cSrcweir } 1494*cdf0e10cSrcweir 1495*cdf0e10cSrcweir if (gd->nbytes != 0) { 1496*cdf0e10cSrcweir memcpy(p1, gd->ptr, gd->nbytes); 1497*cdf0e10cSrcweir } 1498*cdf0e10cSrcweir if (indexToLocFormat == 1) { 1499*cdf0e10cSrcweir PutUInt32(p1 - glyfPtr, p2, 0, 1); 1500*cdf0e10cSrcweir p2 += 4; 1501*cdf0e10cSrcweir } else { 1502*cdf0e10cSrcweir PutUInt16((sal_uInt16)((p1 - glyfPtr) >> 1), p2, 0, 1); 1503*cdf0e10cSrcweir p2 += 2; 1504*cdf0e10cSrcweir } 1505*cdf0e10cSrcweir p1 += gd->nbytes; 1506*cdf0e10cSrcweir 1507*cdf0e10cSrcweir /* fill the array of metrics */ 1508*cdf0e10cSrcweir met[i].adv = gd->aw; 1509*cdf0e10cSrcweir met[i].sb = gd->lsb; 1510*cdf0e10cSrcweir i++; 1511*cdf0e10cSrcweir } while (listNext(glyphlist)); 1512*cdf0e10cSrcweir 1513*cdf0e10cSrcweir free(gid); 1514*cdf0e10cSrcweir 1515*cdf0e10cSrcweir if (indexToLocFormat == 1) { 1516*cdf0e10cSrcweir PutUInt32(p1 - glyfPtr, p2, 0, 1); 1517*cdf0e10cSrcweir } else { 1518*cdf0e10cSrcweir PutUInt16((sal_uInt16)((p1 - glyfPtr) >> 1), p2, 0, 1); 1519*cdf0e10cSrcweir } 1520*cdf0e10cSrcweir 1521*cdf0e10cSrcweir glyf->rawdata = glyfPtr; 1522*cdf0e10cSrcweir 1523*cdf0e10cSrcweir loca = TrueTypeTableNew_loca(); assert(loca != 0); 1524*cdf0e10cSrcweir ((tdata_loca *) loca->data)->ptr = locaPtr; 1525*cdf0e10cSrcweir ((tdata_loca *) loca->data)->nbytes = locaLen; 1526*cdf0e10cSrcweir 1527*cdf0e10cSrcweir AddTable(tt, loca); 1528*cdf0e10cSrcweir 1529*cdf0e10cSrcweir head = FindTable(tt, T_head); 1530*cdf0e10cSrcweir sal_uInt8* const pHeadData = (sal_uInt8*)head->data; 1531*cdf0e10cSrcweir PutInt16(xMin, pHeadData, 36, 1); 1532*cdf0e10cSrcweir PutInt16(yMin, pHeadData, 38, 1); 1533*cdf0e10cSrcweir PutInt16(xMax, pHeadData, 40, 1); 1534*cdf0e10cSrcweir PutInt16(yMax, pHeadData, 42, 1); 1535*cdf0e10cSrcweir PutInt16(indexToLocFormat, pHeadData, 50, 1); 1536*cdf0e10cSrcweir 1537*cdf0e10cSrcweir maxp = FindTable(tt, T_maxp); 1538*cdf0e10cSrcweir 1539*cdf0e10cSrcweir sal_uInt8* const pMaxpData = (sal_uInt8*)maxp->data; 1540*cdf0e10cSrcweir PutUInt16((sal_uInt16)nGlyphs, pMaxpData, 4, 1); 1541*cdf0e10cSrcweir PutUInt16(maxPoints, pMaxpData, 6, 1); 1542*cdf0e10cSrcweir PutUInt16(maxContours, pMaxpData, 8, 1); 1543*cdf0e10cSrcweir PutUInt16(maxCompositePoints, pMaxpData, 10, 1); 1544*cdf0e10cSrcweir PutUInt16(maxCompositeContours, pMaxpData, 12, 1); 1545*cdf0e10cSrcweir 1546*cdf0e10cSrcweir #if 0 1547*cdf0e10cSrcweir /* XXX do not overwrite the existing data. Fix: re-calculate these numbers here */ 1548*cdf0e10cSrcweir PutUInt16(2, maxp->data, 14, 1); /* maxZones is always 2 */ 1549*cdf0e10cSrcweir PutUInt16(0, maxp->data, 16, 1); /* maxTwilightPoints */ 1550*cdf0e10cSrcweir PutUInt16(0, maxp->data, 18, 1); /* maxStorage */ 1551*cdf0e10cSrcweir PutUInt16(0, maxp->data, 20, 1); /* maxFunctionDefs */ 1552*cdf0e10cSrcweir PutUint16(0, maxp->data, 22, 1); /* maxInstructionDefs */ 1553*cdf0e10cSrcweir PutUint16(0, maxp->data, 24, 1); /* maxStackElements */ 1554*cdf0e10cSrcweir PutUint16(0, maxp->data, 26, 1); /* maxSizeOfInstructions */ 1555*cdf0e10cSrcweir PutUint16(0, maxp->data, 28, 1); /* maxComponentElements */ 1556*cdf0e10cSrcweir PutUint16(0, maxp->data, 30, 1); /* maxComponentDepth */ 1557*cdf0e10cSrcweir #endif 1558*cdf0e10cSrcweir 1559*cdf0e10cSrcweir /* 1560*cdf0e10cSrcweir * Generate an htmx table and update hhea table 1561*cdf0e10cSrcweir */ 1562*cdf0e10cSrcweir hhea = FindTable(tt, T_hhea); assert(hhea != 0); 1563*cdf0e10cSrcweir hheaPtr = (sal_uInt8 *) hhea->data; 1564*cdf0e10cSrcweir if (nGlyphs > 2) { 1565*cdf0e10cSrcweir for (i = nGlyphs - 1; i > 0; i--) { 1566*cdf0e10cSrcweir if (met[i].adv != met[i-1].adv) break; 1567*cdf0e10cSrcweir } 1568*cdf0e10cSrcweir nlsb = nGlyphs - 1 - i; 1569*cdf0e10cSrcweir } 1570*cdf0e10cSrcweir hmtxSize = (nGlyphs - nlsb) * 4 + nlsb * 2; 1571*cdf0e10cSrcweir hmtxPtr = ttmalloc(hmtxSize); 1572*cdf0e10cSrcweir p1 = hmtxPtr; 1573*cdf0e10cSrcweir 1574*cdf0e10cSrcweir for (i = 0; i < nGlyphs; i++) { 1575*cdf0e10cSrcweir if (i < nGlyphs - nlsb) { 1576*cdf0e10cSrcweir PutUInt16(met[i].adv, p1, 0, 1); 1577*cdf0e10cSrcweir PutUInt16(met[i].sb, p1, 2, 1); 1578*cdf0e10cSrcweir p1 += 4; 1579*cdf0e10cSrcweir } else { 1580*cdf0e10cSrcweir PutUInt16(met[i].sb, p1, 0, 1); 1581*cdf0e10cSrcweir p1 += 2; 1582*cdf0e10cSrcweir } 1583*cdf0e10cSrcweir } 1584*cdf0e10cSrcweir 1585*cdf0e10cSrcweir AddTable(tt, TrueTypeTableNew(T_hmtx, hmtxSize, hmtxPtr)); 1586*cdf0e10cSrcweir PutUInt16((sal_uInt16)(nGlyphs - nlsb), hheaPtr, 34, 1); 1587*cdf0e10cSrcweir free(hmtxPtr); 1588*cdf0e10cSrcweir free(met); 1589*cdf0e10cSrcweir } 1590*cdf0e10cSrcweir 1591*cdf0e10cSrcweir } // namespace vcl 1592*cdf0e10cSrcweir 1593*cdf0e10cSrcweir extern "C" 1594*cdf0e10cSrcweir { 1595*cdf0e10cSrcweir /** 1596*cdf0e10cSrcweir * TrueTypeCreator destructor. It calls destructors for all TrueTypeTables added to it. 1597*cdf0e10cSrcweir */ 1598*cdf0e10cSrcweir void TrueTypeCreatorDispose(vcl::TrueTypeCreator *_this) 1599*cdf0e10cSrcweir { 1600*cdf0e10cSrcweir listDispose(_this->tables); 1601*cdf0e10cSrcweir free(_this); 1602*cdf0e10cSrcweir } 1603*cdf0e10cSrcweir 1604*cdf0e10cSrcweir 1605*cdf0e10cSrcweir /** 1606*cdf0e10cSrcweir * Destructor for the TrueTypeTable object. 1607*cdf0e10cSrcweir */ 1608*cdf0e10cSrcweir void TrueTypeTableDispose(vcl::TrueTypeTable *_this) 1609*cdf0e10cSrcweir { 1610*cdf0e10cSrcweir /* XXX do a binary search */ 1611*cdf0e10cSrcweir unsigned int i; 1612*cdf0e10cSrcweir 1613*cdf0e10cSrcweir assert(_this != 0); 1614*cdf0e10cSrcweir 1615*cdf0e10cSrcweir if (_this->rawdata) free(_this->rawdata); 1616*cdf0e10cSrcweir 1617*cdf0e10cSrcweir for(i=0; i < sizeof(vcl::vtable1)/sizeof(*vcl::vtable1); i++) { 1618*cdf0e10cSrcweir if (_this->tag == vcl::vtable1[i].tag) { 1619*cdf0e10cSrcweir vcl::vtable1[i].f(_this); 1620*cdf0e10cSrcweir return; 1621*cdf0e10cSrcweir } 1622*cdf0e10cSrcweir } 1623*cdf0e10cSrcweir assert(!"Unknown TrueType table.\n"); 1624*cdf0e10cSrcweir } 1625*cdf0e10cSrcweir } 1626*cdf0e10cSrcweir 1627*cdf0e10cSrcweir 1628*cdf0e10cSrcweir #ifdef TEST_TTCR 1629*cdf0e10cSrcweir int main(void) 1630*cdf0e10cSrcweir { 1631*cdf0e10cSrcweir TrueTypeCreator *ttcr; 1632*cdf0e10cSrcweir sal_uInt8 *t1, *t2, *t3, *t4, *t5, *t6, *t7; 1633*cdf0e10cSrcweir 1634*cdf0e10cSrcweir TrueTypeCreatorNewEmpty(mkTag('t','r','u','e'), &ttcr); 1635*cdf0e10cSrcweir 1636*cdf0e10cSrcweir t1 = malloc(1000); memset(t1, 'a', 1000); 1637*cdf0e10cSrcweir t2 = malloc(2000); memset(t2, 'b', 2000); 1638*cdf0e10cSrcweir t3 = malloc(3000); memset(t3, 'c', 3000); 1639*cdf0e10cSrcweir t4 = malloc(4000); memset(t4, 'd', 4000); 1640*cdf0e10cSrcweir t5 = malloc(5000); memset(t5, 'e', 5000); 1641*cdf0e10cSrcweir t6 = malloc(6000); memset(t6, 'f', 6000); 1642*cdf0e10cSrcweir t7 = malloc(7000); memset(t7, 'g', 7000); 1643*cdf0e10cSrcweir 1644*cdf0e10cSrcweir AddTable(ttcr, TrueTypeTableNew(0x6D617870, 1000, t1)); 1645*cdf0e10cSrcweir AddTable(ttcr, TrueTypeTableNew(0x4F532F32, 2000, t2)); 1646*cdf0e10cSrcweir AddTable(ttcr, TrueTypeTableNew(0x636D6170, 3000, t3)); 1647*cdf0e10cSrcweir AddTable(ttcr, TrueTypeTableNew(0x6C6F6361, 4000, t4)); 1648*cdf0e10cSrcweir AddTable(ttcr, TrueTypeTableNew(0x68686561, 5000, t5)); 1649*cdf0e10cSrcweir AddTable(ttcr, TrueTypeTableNew(0x676C7966, 6000, t6)); 1650*cdf0e10cSrcweir AddTable(ttcr, TrueTypeTableNew(0x6B65726E, 7000, t7)); 1651*cdf0e10cSrcweir 1652*cdf0e10cSrcweir free(t1); 1653*cdf0e10cSrcweir free(t2); 1654*cdf0e10cSrcweir free(t3); 1655*cdf0e10cSrcweir free(t4); 1656*cdf0e10cSrcweir free(t5); 1657*cdf0e10cSrcweir free(t6); 1658*cdf0e10cSrcweir free(t7); 1659*cdf0e10cSrcweir 1660*cdf0e10cSrcweir 1661*cdf0e10cSrcweir StreamToFile(ttcr, "ttcrout.ttf"); 1662*cdf0e10cSrcweir 1663*cdf0e10cSrcweir TrueTypeCreatorDispose(ttcr); 1664*cdf0e10cSrcweir return 0; 1665*cdf0e10cSrcweir } 1666*cdf0e10cSrcweir #endif 1667