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 // MARKER(update_precomp.py): autogen include statement, do not remove 29*cdf0e10cSrcweir #include "precompiled_vcl.hxx" 30*cdf0e10cSrcweir 31*cdf0e10cSrcweir /* 32*cdf0e10cSrcweir * Sun Font Tools 33*cdf0e10cSrcweir * 34*cdf0e10cSrcweir * Author: Alexander Gelfenbain 35*cdf0e10cSrcweir * 36*cdf0e10cSrcweir */ 37*cdf0e10cSrcweir 38*cdf0e10cSrcweir #if OSL_DEBUG_LEVEL == 0 39*cdf0e10cSrcweir # ifndef NDEBUG 40*cdf0e10cSrcweir # define NDEBUG 41*cdf0e10cSrcweir # endif 42*cdf0e10cSrcweir #endif 43*cdf0e10cSrcweir #include <assert.h> 44*cdf0e10cSrcweir 45*cdf0e10cSrcweir #include <stdlib.h> 46*cdf0e10cSrcweir #include <string.h> 47*cdf0e10cSrcweir #include <fcntl.h> 48*cdf0e10cSrcweir #ifdef UNX 49*cdf0e10cSrcweir #include <sys/mman.h> 50*cdf0e10cSrcweir #include <sys/stat.h> 51*cdf0e10cSrcweir #endif 52*cdf0e10cSrcweir #include "sft.hxx" 53*cdf0e10cSrcweir #include "gsub.h" 54*cdf0e10cSrcweir #if ! (defined(NO_TTCR) && defined(NO_TYPE42)) 55*cdf0e10cSrcweir #include "ttcr.hxx" 56*cdf0e10cSrcweir #endif 57*cdf0e10cSrcweir #ifndef NO_MAPPERS /* include MapChar() and MapString() */ 58*cdf0e10cSrcweir #include "xlat.hxx" 59*cdf0e10cSrcweir #endif 60*cdf0e10cSrcweir #ifndef NO_TYPE3 /* include CreateT3FromTTGlyphs() */ 61*cdf0e10cSrcweir #include <rtl/crc.h> 62*cdf0e10cSrcweir #endif 63*cdf0e10cSrcweir 64*cdf0e10cSrcweir #include <osl/endian.h> 65*cdf0e10cSrcweir #include <algorithm> 66*cdf0e10cSrcweir 67*cdf0e10cSrcweir #ifdef TEST7 68*cdf0e10cSrcweir #include <ctype.h> 69*cdf0e10cSrcweir #endif 70*cdf0e10cSrcweir 71*cdf0e10cSrcweir namespace vcl 72*cdf0e10cSrcweir { 73*cdf0e10cSrcweir 74*cdf0e10cSrcweir /*- module identification */ 75*cdf0e10cSrcweir 76*cdf0e10cSrcweir static const char *modname = "SunTypeTools-TT"; 77*cdf0e10cSrcweir static const char *modver = "1.0"; 78*cdf0e10cSrcweir static const char *modextra = "gelf"; 79*cdf0e10cSrcweir 80*cdf0e10cSrcweir /*- private functions, constants and data types */ /*FOLD00*/ 81*cdf0e10cSrcweir 82*cdf0e10cSrcweir enum PathSegmentType { 83*cdf0e10cSrcweir PS_NOOP = 0, 84*cdf0e10cSrcweir PS_MOVETO = 1, 85*cdf0e10cSrcweir PS_LINETO = 2, 86*cdf0e10cSrcweir PS_CURVETO = 3, 87*cdf0e10cSrcweir PS_CLOSEPATH = 4 88*cdf0e10cSrcweir }; 89*cdf0e10cSrcweir 90*cdf0e10cSrcweir struct PSPathElement 91*cdf0e10cSrcweir { 92*cdf0e10cSrcweir PathSegmentType type; 93*cdf0e10cSrcweir int x1, y1; 94*cdf0e10cSrcweir int x2, y2; 95*cdf0e10cSrcweir int x3, y3; 96*cdf0e10cSrcweir 97*cdf0e10cSrcweir PSPathElement( PathSegmentType i_eType ) : type( i_eType ), 98*cdf0e10cSrcweir x1( 0 ), y1( 0 ), 99*cdf0e10cSrcweir x2( 0 ), y2( 0 ), 100*cdf0e10cSrcweir x3( 0 ), y3( 0 ) 101*cdf0e10cSrcweir { 102*cdf0e10cSrcweir } 103*cdf0e10cSrcweir }; 104*cdf0e10cSrcweir 105*cdf0e10cSrcweir /*- In horisontal writing mode right sidebearing is calculated using this formula 106*cdf0e10cSrcweir *- rsb = aw - (lsb + xMax - xMin) -*/ 107*cdf0e10cSrcweir typedef struct { 108*cdf0e10cSrcweir sal_Int16 xMin; 109*cdf0e10cSrcweir sal_Int16 yMin; 110*cdf0e10cSrcweir sal_Int16 xMax; 111*cdf0e10cSrcweir sal_Int16 yMax; 112*cdf0e10cSrcweir sal_uInt16 aw; /*- Advance Width (horisontal writing mode) */ 113*cdf0e10cSrcweir sal_Int16 lsb; /*- Left sidebearing (horisontal writing mode) */ 114*cdf0e10cSrcweir sal_uInt16 ah; /*- advance height (vertical writing mode) */ 115*cdf0e10cSrcweir sal_Int16 tsb; /*- top sidebearing (vertical writing mode) */ 116*cdf0e10cSrcweir } TTGlyphMetrics; 117*cdf0e10cSrcweir 118*cdf0e10cSrcweir #define HFORMAT_LINELEN 64 119*cdf0e10cSrcweir 120*cdf0e10cSrcweir typedef struct { 121*cdf0e10cSrcweir FILE *o; 122*cdf0e10cSrcweir char buffer[HFORMAT_LINELEN]; 123*cdf0e10cSrcweir int bufpos; 124*cdf0e10cSrcweir int total; 125*cdf0e10cSrcweir } HexFmt; 126*cdf0e10cSrcweir 127*cdf0e10cSrcweir typedef struct { 128*cdf0e10cSrcweir sal_uInt32 nGlyphs; /* number of glyphs in the font + 1 */ 129*cdf0e10cSrcweir sal_uInt32 *offs; /* array of nGlyphs offsets */ 130*cdf0e10cSrcweir } GlyphOffsets; 131*cdf0e10cSrcweir 132*cdf0e10cSrcweir /* private tags */ 133*cdf0e10cSrcweir static const sal_uInt32 TTFontClassTag = 0x74746663; /* 'ttfc' */ 134*cdf0e10cSrcweir 135*cdf0e10cSrcweir static const sal_uInt32 T_true = 0x74727565; /* 'true' */ 136*cdf0e10cSrcweir static const sal_uInt32 T_ttcf = 0x74746366; /* 'ttcf' */ 137*cdf0e10cSrcweir static const sal_uInt32 T_otto = 0x4f54544f; /* 'OTTO' */ 138*cdf0e10cSrcweir 139*cdf0e10cSrcweir /* standard TrueType table tags */ 140*cdf0e10cSrcweir #define T_maxp 0x6D617870 141*cdf0e10cSrcweir #define T_glyf 0x676C7966 142*cdf0e10cSrcweir #define T_head 0x68656164 143*cdf0e10cSrcweir #define T_loca 0x6C6F6361 144*cdf0e10cSrcweir #define T_name 0x6E616D65 145*cdf0e10cSrcweir #define T_hhea 0x68686561 146*cdf0e10cSrcweir #define T_hmtx 0x686D7478 147*cdf0e10cSrcweir #define T_cmap 0x636D6170 148*cdf0e10cSrcweir #define T_vhea 0x76686561 149*cdf0e10cSrcweir #define T_vmtx 0x766D7478 150*cdf0e10cSrcweir #define T_OS2 0x4F532F32 151*cdf0e10cSrcweir #define T_post 0x706F7374 152*cdf0e10cSrcweir #define T_kern 0x6B65726E 153*cdf0e10cSrcweir #define T_cvt 0x63767420 154*cdf0e10cSrcweir #define T_prep 0x70726570 155*cdf0e10cSrcweir #define T_fpgm 0x6670676D 156*cdf0e10cSrcweir #define T_gsub 0x47535542 157*cdf0e10cSrcweir #define T_CFF 0x43464620 158*cdf0e10cSrcweir 159*cdf0e10cSrcweir #define LAST_URANGE_BIT 69 160*cdf0e10cSrcweir const char *ulcodes[LAST_URANGE_BIT+2] = { 161*cdf0e10cSrcweir /* 0 */ "Basic Latin", 162*cdf0e10cSrcweir /* 1 */ "Latin-1 Supplement", 163*cdf0e10cSrcweir /* 2 */ "Latin Extended-A", 164*cdf0e10cSrcweir /* 3 */ "Latin Extended-B", 165*cdf0e10cSrcweir /* 4 */ "IPA Extensions", 166*cdf0e10cSrcweir /* 5 */ "Spacing Modifier Letters", 167*cdf0e10cSrcweir /* 6 */ "Combining Diacritical Marks", 168*cdf0e10cSrcweir /* 7 */ "Basic Greek", 169*cdf0e10cSrcweir /* 8 */ "Greek Symbols And Coptic", 170*cdf0e10cSrcweir /* 9 */ "Cyrillic", 171*cdf0e10cSrcweir /* 10 */ "Armenian", 172*cdf0e10cSrcweir /* 11 */ "Basic Hebrew", 173*cdf0e10cSrcweir /* 12 */ "Hebrew Extended (A and B blocks combined)", 174*cdf0e10cSrcweir /* 13 */ "Basic Arabic", 175*cdf0e10cSrcweir /* 14 */ "Arabic Extended", 176*cdf0e10cSrcweir /* 15 */ "Devanagari", 177*cdf0e10cSrcweir /* 16 */ "Bengali", 178*cdf0e10cSrcweir /* 17 */ "Gurmukhi", 179*cdf0e10cSrcweir /* 18 */ "Gujarati", 180*cdf0e10cSrcweir /* 19 */ "Oriya", 181*cdf0e10cSrcweir /* 20 */ "Tamil", 182*cdf0e10cSrcweir /* 21 */ "Telugu", 183*cdf0e10cSrcweir /* 22 */ "Kannada", 184*cdf0e10cSrcweir /* 23 */ "Malayalam", 185*cdf0e10cSrcweir /* 24 */ "Thai", 186*cdf0e10cSrcweir /* 25 */ "Lao", 187*cdf0e10cSrcweir /* 26 */ "Basic Georgian", 188*cdf0e10cSrcweir /* 27 */ "Georgian Extended", 189*cdf0e10cSrcweir /* 28 */ "Hangul Jamo", 190*cdf0e10cSrcweir /* 29 */ "Latin Extended Additional", 191*cdf0e10cSrcweir /* 30 */ "Greek Extended", 192*cdf0e10cSrcweir /* 31 */ "General Punctuation", 193*cdf0e10cSrcweir /* 32 */ "Superscripts And Subscripts", 194*cdf0e10cSrcweir /* 33 */ "Currency Symbols", 195*cdf0e10cSrcweir /* 34 */ "Combining Diacritical Marks For Symbols", 196*cdf0e10cSrcweir /* 35 */ "Letterlike Symbols", 197*cdf0e10cSrcweir /* 36 */ "Number Forms", 198*cdf0e10cSrcweir /* 37 */ "Arrows", 199*cdf0e10cSrcweir /* 38 */ "Mathematical Operators", 200*cdf0e10cSrcweir /* 39 */ "Miscellaneous Technical", 201*cdf0e10cSrcweir /* 40 */ "Control Pictures", 202*cdf0e10cSrcweir /* 41 */ "Optical Character Recognition", 203*cdf0e10cSrcweir /* 42 */ "Enclosed Alphanumerics", 204*cdf0e10cSrcweir /* 43 */ "Box Drawing", 205*cdf0e10cSrcweir /* 44 */ "Block Elements", 206*cdf0e10cSrcweir /* 45 */ "Geometric Shapes", 207*cdf0e10cSrcweir /* 46 */ "Miscellaneous Symbols", 208*cdf0e10cSrcweir /* 47 */ "Dingbats", 209*cdf0e10cSrcweir /* 48 */ "CJK Symbols And Punctuation", 210*cdf0e10cSrcweir /* 49 */ "Hiragana", 211*cdf0e10cSrcweir /* 50 */ "Katakana", 212*cdf0e10cSrcweir /* 51 */ "Bopomofo", 213*cdf0e10cSrcweir /* 52 */ "Hangul Compatibility Jamo", 214*cdf0e10cSrcweir /* 53 */ "CJK Miscellaneous", 215*cdf0e10cSrcweir /* 54 */ "Enclosed CJK Letters And Months", 216*cdf0e10cSrcweir /* 55 */ "CJK Compatibility", 217*cdf0e10cSrcweir /* 56 */ "Hangul", 218*cdf0e10cSrcweir /* 57 */ "Reserved for Unicode SubRanges", 219*cdf0e10cSrcweir /* 58 */ "Reserved for Unicode SubRanges", 220*cdf0e10cSrcweir /* 59 */ "CJK Unified Ideographs", 221*cdf0e10cSrcweir /* 60 */ "Private Use Area", 222*cdf0e10cSrcweir /* 61 */ "CJK Compatibility Ideographs", 223*cdf0e10cSrcweir /* 62 */ "Alphabetic Presentation Forms", 224*cdf0e10cSrcweir /* 63 */ "Arabic Presentation Forms-A", 225*cdf0e10cSrcweir /* 64 */ "Combining Half Marks", 226*cdf0e10cSrcweir /* 65 */ "CJK Compatibility Forms", 227*cdf0e10cSrcweir /* 66 */ "Small Form Variants", 228*cdf0e10cSrcweir /* 67 */ "Arabic Presentation Forms-B", 229*cdf0e10cSrcweir /* 68 */ "Halfwidth And Fullwidth Forms", 230*cdf0e10cSrcweir /* 69 */ "Specials", 231*cdf0e10cSrcweir /*70-127*/ "Reserved for Unicode SubRanges" 232*cdf0e10cSrcweir }; 233*cdf0e10cSrcweir 234*cdf0e10cSrcweir 235*cdf0e10cSrcweir 236*cdf0e10cSrcweir /*- inline functions */ /*FOLD01*/ 237*cdf0e10cSrcweir #ifdef __GNUC__ 238*cdf0e10cSrcweir #define _inline static __inline__ 239*cdf0e10cSrcweir #else 240*cdf0e10cSrcweir #define _inline static 241*cdf0e10cSrcweir #endif 242*cdf0e10cSrcweir 243*cdf0e10cSrcweir _inline void *smalloc(size_t size) 244*cdf0e10cSrcweir { 245*cdf0e10cSrcweir void *res = malloc(size); 246*cdf0e10cSrcweir assert(res != 0); 247*cdf0e10cSrcweir return res; 248*cdf0e10cSrcweir } 249*cdf0e10cSrcweir 250*cdf0e10cSrcweir _inline void *scalloc(size_t n, size_t size) 251*cdf0e10cSrcweir { 252*cdf0e10cSrcweir void *res = calloc(n, size); 253*cdf0e10cSrcweir assert(res != 0); 254*cdf0e10cSrcweir return res; 255*cdf0e10cSrcweir } 256*cdf0e10cSrcweir 257*cdf0e10cSrcweir _inline sal_uInt32 mkTag(sal_uInt8 a, sal_uInt8 b, sal_uInt8 c, sal_uInt8 d) { 258*cdf0e10cSrcweir return (a << 24) | (b << 16) | (c << 8) | d; 259*cdf0e10cSrcweir } 260*cdf0e10cSrcweir 261*cdf0e10cSrcweir /*- Data access macros for data stored in big-endian or little-endian format */ 262*cdf0e10cSrcweir _inline sal_Int16 GetInt16(const sal_uInt8 *ptr, size_t offset, int bigendian) 263*cdf0e10cSrcweir { 264*cdf0e10cSrcweir sal_Int16 t; 265*cdf0e10cSrcweir assert(ptr != 0); 266*cdf0e10cSrcweir 267*cdf0e10cSrcweir if (bigendian) { 268*cdf0e10cSrcweir t = (ptr+offset)[0] << 8 | (ptr+offset)[1]; 269*cdf0e10cSrcweir } else { 270*cdf0e10cSrcweir t = (ptr+offset)[1] << 8 | (ptr+offset)[0]; 271*cdf0e10cSrcweir } 272*cdf0e10cSrcweir 273*cdf0e10cSrcweir return t; 274*cdf0e10cSrcweir } 275*cdf0e10cSrcweir 276*cdf0e10cSrcweir _inline sal_uInt16 GetUInt16(const sal_uInt8 *ptr, size_t offset, int bigendian) 277*cdf0e10cSrcweir { 278*cdf0e10cSrcweir sal_uInt16 t; 279*cdf0e10cSrcweir assert(ptr != 0); 280*cdf0e10cSrcweir 281*cdf0e10cSrcweir if (bigendian) { 282*cdf0e10cSrcweir t = (ptr+offset)[0] << 8 | (ptr+offset)[1]; 283*cdf0e10cSrcweir } else { 284*cdf0e10cSrcweir t = (ptr+offset)[1] << 8 | (ptr+offset)[0]; 285*cdf0e10cSrcweir } 286*cdf0e10cSrcweir 287*cdf0e10cSrcweir return t; 288*cdf0e10cSrcweir } 289*cdf0e10cSrcweir 290*cdf0e10cSrcweir _inline sal_Int32 GetInt32(const sal_uInt8 *ptr, size_t offset, int bigendian) 291*cdf0e10cSrcweir { 292*cdf0e10cSrcweir sal_Int32 t; 293*cdf0e10cSrcweir assert(ptr != 0); 294*cdf0e10cSrcweir 295*cdf0e10cSrcweir if (bigendian) { 296*cdf0e10cSrcweir t = (ptr+offset)[0] << 24 | (ptr+offset)[1] << 16 | 297*cdf0e10cSrcweir (ptr+offset)[2] << 8 | (ptr+offset)[3]; 298*cdf0e10cSrcweir } else { 299*cdf0e10cSrcweir t = (ptr+offset)[3] << 24 | (ptr+offset)[2] << 16 | 300*cdf0e10cSrcweir (ptr+offset)[1] << 8 | (ptr+offset)[0]; 301*cdf0e10cSrcweir } 302*cdf0e10cSrcweir 303*cdf0e10cSrcweir return t; 304*cdf0e10cSrcweir } 305*cdf0e10cSrcweir 306*cdf0e10cSrcweir _inline sal_uInt32 GetUInt32(const sal_uInt8 *ptr, size_t offset, int bigendian) 307*cdf0e10cSrcweir { 308*cdf0e10cSrcweir sal_uInt32 t; 309*cdf0e10cSrcweir assert(ptr != 0); 310*cdf0e10cSrcweir 311*cdf0e10cSrcweir 312*cdf0e10cSrcweir if (bigendian) { 313*cdf0e10cSrcweir t = (ptr+offset)[0] << 24 | (ptr+offset)[1] << 16 | 314*cdf0e10cSrcweir (ptr+offset)[2] << 8 | (ptr+offset)[3]; 315*cdf0e10cSrcweir } else { 316*cdf0e10cSrcweir t = (ptr+offset)[3] << 24 | (ptr+offset)[2] << 16 | 317*cdf0e10cSrcweir (ptr+offset)[1] << 8 | (ptr+offset)[0]; 318*cdf0e10cSrcweir } 319*cdf0e10cSrcweir 320*cdf0e10cSrcweir return t; 321*cdf0e10cSrcweir } 322*cdf0e10cSrcweir 323*cdf0e10cSrcweir _inline void PutInt16(sal_Int16 val, sal_uInt8 *ptr, size_t offset, int bigendian) 324*cdf0e10cSrcweir { 325*cdf0e10cSrcweir assert(ptr != 0); 326*cdf0e10cSrcweir 327*cdf0e10cSrcweir if (bigendian) { 328*cdf0e10cSrcweir ptr[offset] = (sal_uInt8)((val >> 8) & 0xFF); 329*cdf0e10cSrcweir ptr[offset+1] = (sal_uInt8)(val & 0xFF); 330*cdf0e10cSrcweir } else { 331*cdf0e10cSrcweir ptr[offset+1] = (sal_uInt8)((val >> 8) & 0xFF); 332*cdf0e10cSrcweir ptr[offset] = (sal_uInt8)(val & 0xFF); 333*cdf0e10cSrcweir } 334*cdf0e10cSrcweir 335*cdf0e10cSrcweir } 336*cdf0e10cSrcweir 337*cdf0e10cSrcweir #if defined(OSL_BIGENDIAN) 338*cdf0e10cSrcweir #define Int16FromMOTA(a) (a) 339*cdf0e10cSrcweir #define Int32FromMOTA(a) (a) 340*cdf0e10cSrcweir #else 341*cdf0e10cSrcweir static sal_uInt16 Int16FromMOTA(sal_uInt16 a) { 342*cdf0e10cSrcweir return (sal_uInt16) (((sal_uInt8)((a) >> 8)) | ((sal_uInt8)(a) << 8)); 343*cdf0e10cSrcweir } 344*cdf0e10cSrcweir static sal_uInt32 Int32FromMOTA(sal_uInt32 a) { 345*cdf0e10cSrcweir return ((a>>24)&0xFF) | (((a>>8)&0xFF00) | ((a&0xFF00)<<8) | ((a&0xFF)<<24)); 346*cdf0e10cSrcweir } 347*cdf0e10cSrcweir #endif 348*cdf0e10cSrcweir 349*cdf0e10cSrcweir _inline F16Dot16 fixedMul(F16Dot16 a, F16Dot16 b) 350*cdf0e10cSrcweir { 351*cdf0e10cSrcweir unsigned int a1, b1; 352*cdf0e10cSrcweir unsigned int a2, b2; 353*cdf0e10cSrcweir F16Dot16 res; 354*cdf0e10cSrcweir int sign; 355*cdf0e10cSrcweir 356*cdf0e10cSrcweir sign = (a & 0x80000000) ^ (b & 0x80000000); 357*cdf0e10cSrcweir if (a < 0) a = -a; 358*cdf0e10cSrcweir if (b < 0) b = -b; 359*cdf0e10cSrcweir 360*cdf0e10cSrcweir a1 = a >> 16; 361*cdf0e10cSrcweir b1 = a & 0xFFFF; 362*cdf0e10cSrcweir a2 = b >> 16; 363*cdf0e10cSrcweir b2 = b & 0xFFFF; 364*cdf0e10cSrcweir 365*cdf0e10cSrcweir res = a1 * a2; 366*cdf0e10cSrcweir 367*cdf0e10cSrcweir /* if (res > 0x7FFF) assert(!"fixedMul: F16Dot16 overflow"); */ 368*cdf0e10cSrcweir 369*cdf0e10cSrcweir res <<= 16; 370*cdf0e10cSrcweir res += a1 * b2 + b1 * a2 + ((b1 * b2) >> 16); 371*cdf0e10cSrcweir 372*cdf0e10cSrcweir return sign ? -res : res; 373*cdf0e10cSrcweir } 374*cdf0e10cSrcweir 375*cdf0e10cSrcweir 376*cdf0e10cSrcweir _inline F16Dot16 fixedDiv(F16Dot16 a, F16Dot16 b) 377*cdf0e10cSrcweir { 378*cdf0e10cSrcweir unsigned int f, r; 379*cdf0e10cSrcweir F16Dot16 res; 380*cdf0e10cSrcweir int sign; 381*cdf0e10cSrcweir 382*cdf0e10cSrcweir sign = (a & 0x80000000) ^ (b & 0x80000000); 383*cdf0e10cSrcweir if (a < 0) a = -a; 384*cdf0e10cSrcweir if (b < 0) b = -b; 385*cdf0e10cSrcweir 386*cdf0e10cSrcweir f = a / b; 387*cdf0e10cSrcweir r = a % b; 388*cdf0e10cSrcweir 389*cdf0e10cSrcweir /* if (f > 0x7FFFF) assert(!"fixedDiv: F16Dot16 overflow"); */ 390*cdf0e10cSrcweir 391*cdf0e10cSrcweir while (r > 0xFFFF) { 392*cdf0e10cSrcweir r >>= 1; 393*cdf0e10cSrcweir b >>= 1; 394*cdf0e10cSrcweir } 395*cdf0e10cSrcweir 396*cdf0e10cSrcweir res = (f << 16) + (r << 16) / b; 397*cdf0e10cSrcweir 398*cdf0e10cSrcweir return sign ? -res : res; 399*cdf0e10cSrcweir } 400*cdf0e10cSrcweir 401*cdf0e10cSrcweir /*- returns a * b / c -*/ 402*cdf0e10cSrcweir /* XXX provide a real implementation that preserves accuracy */ 403*cdf0e10cSrcweir _inline F16Dot16 fixedMulDiv(F16Dot16 a, F16Dot16 b, F16Dot16 c) 404*cdf0e10cSrcweir { 405*cdf0e10cSrcweir F16Dot16 res; 406*cdf0e10cSrcweir 407*cdf0e10cSrcweir res = fixedMul(a, b); 408*cdf0e10cSrcweir return fixedDiv(res, c); 409*cdf0e10cSrcweir } 410*cdf0e10cSrcweir 411*cdf0e10cSrcweir /*- Translate units from TT to PS (standard 1/1000) -*/ 412*cdf0e10cSrcweir _inline int XUnits(int unitsPerEm, int n) 413*cdf0e10cSrcweir { 414*cdf0e10cSrcweir return (n * 1000) / unitsPerEm; 415*cdf0e10cSrcweir } 416*cdf0e10cSrcweir 417*cdf0e10cSrcweir _inline const char *UnicodeRangeName(sal_uInt16 bit) 418*cdf0e10cSrcweir { 419*cdf0e10cSrcweir if (bit > LAST_URANGE_BIT) bit = LAST_URANGE_BIT+1; 420*cdf0e10cSrcweir 421*cdf0e10cSrcweir return ulcodes[bit]; 422*cdf0e10cSrcweir } 423*cdf0e10cSrcweir 424*cdf0e10cSrcweir _inline const sal_uInt8* getTable( TrueTypeFont *ttf, sal_uInt32 ord) 425*cdf0e10cSrcweir { 426*cdf0e10cSrcweir return (sal_uInt8*)ttf->tables[ord]; 427*cdf0e10cSrcweir } 428*cdf0e10cSrcweir 429*cdf0e10cSrcweir _inline sal_uInt32 getTableSize(TrueTypeFont *ttf, sal_uInt32 ord) 430*cdf0e10cSrcweir { 431*cdf0e10cSrcweir return ttf->tlens[ord]; 432*cdf0e10cSrcweir } 433*cdf0e10cSrcweir 434*cdf0e10cSrcweir #ifndef NO_TYPE42 435*cdf0e10cSrcweir /* Hex Formatter functions */ 436*cdf0e10cSrcweir static char HexChars[] = "0123456789ABCDEF"; 437*cdf0e10cSrcweir 438*cdf0e10cSrcweir static HexFmt *HexFmtNew(FILE *outf) 439*cdf0e10cSrcweir { 440*cdf0e10cSrcweir HexFmt* res = (HexFmt*)smalloc(sizeof(HexFmt)); 441*cdf0e10cSrcweir res->bufpos = res->total = 0; 442*cdf0e10cSrcweir res->o = outf; 443*cdf0e10cSrcweir return res; 444*cdf0e10cSrcweir } 445*cdf0e10cSrcweir 446*cdf0e10cSrcweir static void HexFmtFlush(HexFmt *_this) 447*cdf0e10cSrcweir { 448*cdf0e10cSrcweir if (_this->bufpos) { 449*cdf0e10cSrcweir fwrite(_this->buffer, 1, _this->bufpos, _this->o); 450*cdf0e10cSrcweir _this->bufpos = 0; 451*cdf0e10cSrcweir } 452*cdf0e10cSrcweir } 453*cdf0e10cSrcweir 454*cdf0e10cSrcweir 455*cdf0e10cSrcweir _inline void HexFmtOpenString(HexFmt *_this) 456*cdf0e10cSrcweir { 457*cdf0e10cSrcweir fputs("<\n", _this->o); 458*cdf0e10cSrcweir } 459*cdf0e10cSrcweir 460*cdf0e10cSrcweir _inline void HexFmtCloseString(HexFmt *_this) 461*cdf0e10cSrcweir { 462*cdf0e10cSrcweir HexFmtFlush(_this); 463*cdf0e10cSrcweir fputs("00\n>\n", _this->o); 464*cdf0e10cSrcweir } 465*cdf0e10cSrcweir 466*cdf0e10cSrcweir _inline void HexFmtDispose(HexFmt *_this) 467*cdf0e10cSrcweir { 468*cdf0e10cSrcweir HexFmtFlush(_this); 469*cdf0e10cSrcweir free(_this); 470*cdf0e10cSrcweir } 471*cdf0e10cSrcweir 472*cdf0e10cSrcweir static void HexFmtBlockWrite(HexFmt *_this, const void *ptr, sal_uInt32 size) 473*cdf0e10cSrcweir { 474*cdf0e10cSrcweir sal_uInt8 Ch; 475*cdf0e10cSrcweir sal_uInt32 i; 476*cdf0e10cSrcweir 477*cdf0e10cSrcweir if (_this->total + size > 65534) { 478*cdf0e10cSrcweir HexFmtFlush(_this); 479*cdf0e10cSrcweir HexFmtCloseString(_this); 480*cdf0e10cSrcweir _this->total = 0; 481*cdf0e10cSrcweir HexFmtOpenString(_this); 482*cdf0e10cSrcweir } 483*cdf0e10cSrcweir for (i=0; i<size; i++) { 484*cdf0e10cSrcweir Ch = ((sal_uInt8 *) ptr)[i]; 485*cdf0e10cSrcweir _this->buffer[_this->bufpos++] = HexChars[Ch >> 4]; 486*cdf0e10cSrcweir _this->buffer[_this->bufpos++] = HexChars[Ch & 0xF]; 487*cdf0e10cSrcweir if (_this->bufpos == HFORMAT_LINELEN) { 488*cdf0e10cSrcweir HexFmtFlush(_this); 489*cdf0e10cSrcweir fputc('\n', _this->o); 490*cdf0e10cSrcweir } 491*cdf0e10cSrcweir 492*cdf0e10cSrcweir } 493*cdf0e10cSrcweir _this->total += size; 494*cdf0e10cSrcweir } 495*cdf0e10cSrcweir #endif 496*cdf0e10cSrcweir 497*cdf0e10cSrcweir 498*cdf0e10cSrcweir 499*cdf0e10cSrcweir /* Outline Extraction functions */ /*FOLD01*/ 500*cdf0e10cSrcweir 501*cdf0e10cSrcweir /* fills the aw and lsb entries of the TTGlyphMetrics structure from hmtx table -*/ 502*cdf0e10cSrcweir static void GetMetrics(TrueTypeFont *ttf, sal_uInt32 glyphID, TTGlyphMetrics *metrics) 503*cdf0e10cSrcweir { 504*cdf0e10cSrcweir const sal_uInt8* table = getTable( ttf, O_hmtx ); 505*cdf0e10cSrcweir 506*cdf0e10cSrcweir metrics->aw = metrics->lsb = metrics->ah = metrics->tsb = 0; 507*cdf0e10cSrcweir if (!table || !ttf->numberOfHMetrics) return; 508*cdf0e10cSrcweir 509*cdf0e10cSrcweir if (glyphID < ttf->numberOfHMetrics) { 510*cdf0e10cSrcweir metrics->aw = GetUInt16(table, 4 * glyphID, 1); 511*cdf0e10cSrcweir metrics->lsb = GetInt16(table, 4 * glyphID + 2, 1); 512*cdf0e10cSrcweir } else { 513*cdf0e10cSrcweir metrics->aw = GetUInt16(table, 4 * (ttf->numberOfHMetrics - 1), 1); 514*cdf0e10cSrcweir metrics->lsb = GetInt16(table + ttf->numberOfHMetrics * 4, (glyphID - ttf->numberOfHMetrics) * 2, 1); 515*cdf0e10cSrcweir } 516*cdf0e10cSrcweir 517*cdf0e10cSrcweir table = getTable(ttf, O_vmtx); 518*cdf0e10cSrcweir if( !table || !ttf->numOfLongVerMetrics ) 519*cdf0e10cSrcweir return; 520*cdf0e10cSrcweir 521*cdf0e10cSrcweir if (glyphID < ttf->numOfLongVerMetrics) { 522*cdf0e10cSrcweir metrics->ah = GetUInt16(table, 4 * glyphID, 1); 523*cdf0e10cSrcweir metrics->tsb = GetInt16(table, 4 * glyphID + 2, 1); 524*cdf0e10cSrcweir } else { 525*cdf0e10cSrcweir metrics->ah = GetUInt16(table, 4 * (ttf->numOfLongVerMetrics - 1), 1); 526*cdf0e10cSrcweir metrics->tsb = GetInt16(table + ttf->numOfLongVerMetrics * 4, (glyphID - ttf->numOfLongVerMetrics) * 2, 1); 527*cdf0e10cSrcweir } 528*cdf0e10cSrcweir } 529*cdf0e10cSrcweir 530*cdf0e10cSrcweir static int GetTTGlyphOutline(TrueTypeFont *, sal_uInt32 , ControlPoint **, TTGlyphMetrics *, std::vector< sal_uInt32 >* ); 531*cdf0e10cSrcweir 532*cdf0e10cSrcweir /* returns the number of control points, allocates the pointArray */ 533*cdf0e10cSrcweir static int GetSimpleTTOutline(TrueTypeFont *ttf, sal_uInt32 glyphID, ControlPoint **pointArray, TTGlyphMetrics *metrics) /*FOLD02*/ 534*cdf0e10cSrcweir { 535*cdf0e10cSrcweir const sal_uInt8* table = getTable( ttf, O_glyf ); 536*cdf0e10cSrcweir sal_uInt8 flag, n; 537*cdf0e10cSrcweir sal_uInt16 t, lastPoint=0; 538*cdf0e10cSrcweir int i, j, z; 539*cdf0e10cSrcweir 540*cdf0e10cSrcweir *pointArray = 0; 541*cdf0e10cSrcweir 542*cdf0e10cSrcweir /* printf("GetSimpleTTOutline(%d)\n", glyphID); */ 543*cdf0e10cSrcweir 544*cdf0e10cSrcweir if( glyphID >= ttf->nglyphs ) /*- glyph is not present in the font */ 545*cdf0e10cSrcweir return 0; 546*cdf0e10cSrcweir const sal_uInt8* ptr = table + ttf->goffsets[glyphID]; 547*cdf0e10cSrcweir const sal_Int16 numberOfContours = GetInt16(ptr, 0, 1); 548*cdf0e10cSrcweir if( numberOfContours <= 0 ) /*- glyph is not simple */ 549*cdf0e10cSrcweir return 0; 550*cdf0e10cSrcweir 551*cdf0e10cSrcweir if (metrics) { /*- GetCompoundTTOutline() calls this function with NULL metrics -*/ 552*cdf0e10cSrcweir metrics->xMin = GetInt16(ptr, 2, 1); 553*cdf0e10cSrcweir metrics->yMin = GetInt16(ptr, 4, 1); 554*cdf0e10cSrcweir metrics->xMax = GetInt16(ptr, 6, 1); 555*cdf0e10cSrcweir metrics->yMax = GetInt16(ptr, 8, 1); 556*cdf0e10cSrcweir GetMetrics(ttf, glyphID, metrics); 557*cdf0e10cSrcweir } 558*cdf0e10cSrcweir 559*cdf0e10cSrcweir /* determine the last point and be extra safe about it. But probably this code is not needed */ 560*cdf0e10cSrcweir 561*cdf0e10cSrcweir for (i=0; i<numberOfContours; i++) { 562*cdf0e10cSrcweir if ((t = GetUInt16(ptr, 10+i*2, 1)) > lastPoint) lastPoint = t; 563*cdf0e10cSrcweir } 564*cdf0e10cSrcweir 565*cdf0e10cSrcweir sal_uInt16 instLen = GetUInt16(ptr, 10 + numberOfContours*2, 1); 566*cdf0e10cSrcweir const sal_uInt8* p = ptr + 10 + 2 * numberOfContours + 2 + instLen; 567*cdf0e10cSrcweir ControlPoint* pa = (ControlPoint*)calloc(lastPoint+1, sizeof(ControlPoint)); 568*cdf0e10cSrcweir 569*cdf0e10cSrcweir i = 0; 570*cdf0e10cSrcweir while (i <= lastPoint) { 571*cdf0e10cSrcweir pa[i++].flags = (sal_uInt32) (flag = *p++); 572*cdf0e10cSrcweir if (flag & 8) { /*- repeat flag */ 573*cdf0e10cSrcweir n = *p++; 574*cdf0e10cSrcweir for (j=0; j<n; j++) { 575*cdf0e10cSrcweir if (i > lastPoint) { /*- if the font is really broken */ 576*cdf0e10cSrcweir free(pa); 577*cdf0e10cSrcweir return 0; 578*cdf0e10cSrcweir } 579*cdf0e10cSrcweir pa[i++].flags = flag; 580*cdf0e10cSrcweir } 581*cdf0e10cSrcweir } 582*cdf0e10cSrcweir } 583*cdf0e10cSrcweir 584*cdf0e10cSrcweir /*- Process the X coordinate */ 585*cdf0e10cSrcweir z = 0; 586*cdf0e10cSrcweir for (i = 0; i <= lastPoint; i++) { 587*cdf0e10cSrcweir if (pa[i].flags & 0x02) { 588*cdf0e10cSrcweir if (pa[i].flags & 0x10) { 589*cdf0e10cSrcweir z += (int) (*p++); 590*cdf0e10cSrcweir } else { 591*cdf0e10cSrcweir z -= (int) (*p++); 592*cdf0e10cSrcweir } 593*cdf0e10cSrcweir } else if ( !(pa[i].flags & 0x10)) { 594*cdf0e10cSrcweir z += GetInt16(p, 0, 1); 595*cdf0e10cSrcweir p += 2; 596*cdf0e10cSrcweir } 597*cdf0e10cSrcweir pa[i].x = (sal_Int16)z; 598*cdf0e10cSrcweir } 599*cdf0e10cSrcweir 600*cdf0e10cSrcweir /*- Process the Y coordinate */ 601*cdf0e10cSrcweir z = 0; 602*cdf0e10cSrcweir for (i = 0; i <= lastPoint; i++) { 603*cdf0e10cSrcweir if (pa[i].flags & 0x04) { 604*cdf0e10cSrcweir if (pa[i].flags & 0x20) { 605*cdf0e10cSrcweir z += *p++; 606*cdf0e10cSrcweir } else { 607*cdf0e10cSrcweir z -= *p++; 608*cdf0e10cSrcweir } 609*cdf0e10cSrcweir } else if ( !(pa[i].flags & 0x20)) { 610*cdf0e10cSrcweir z += GetInt16(p, 0, 1); 611*cdf0e10cSrcweir p += 2; 612*cdf0e10cSrcweir } 613*cdf0e10cSrcweir pa[i].y = (sal_Int16)z; 614*cdf0e10cSrcweir } 615*cdf0e10cSrcweir 616*cdf0e10cSrcweir for (i=0; i<numberOfContours; i++) { 617*cdf0e10cSrcweir pa[GetUInt16(ptr, 10 + i * 2, 1)].flags |= 0x00008000; /*- set the end contour flag */ 618*cdf0e10cSrcweir } 619*cdf0e10cSrcweir 620*cdf0e10cSrcweir *pointArray = pa; 621*cdf0e10cSrcweir return lastPoint + 1; 622*cdf0e10cSrcweir } 623*cdf0e10cSrcweir 624*cdf0e10cSrcweir static int GetCompoundTTOutline(TrueTypeFont *ttf, sal_uInt32 glyphID, ControlPoint **pointArray, TTGlyphMetrics *metrics, std::vector< sal_uInt32 >& glyphlist) /*FOLD02*/ 625*cdf0e10cSrcweir { 626*cdf0e10cSrcweir sal_uInt16 flags, index; 627*cdf0e10cSrcweir sal_Int16 e, f, numberOfContours; 628*cdf0e10cSrcweir const sal_uInt8* table = getTable( ttf, O_glyf ); 629*cdf0e10cSrcweir std::vector<ControlPoint> myPoints; 630*cdf0e10cSrcweir ControlPoint *nextComponent, *pa; 631*cdf0e10cSrcweir int i, np; 632*cdf0e10cSrcweir F16Dot16 a = 0x10000, b = 0, c = 0, d = 0x10000, m, n, abs1, abs2, abs3; 633*cdf0e10cSrcweir 634*cdf0e10cSrcweir *pointArray = 0; 635*cdf0e10cSrcweir /* printf("GetCompoundTTOutline(%d)\n", glyphID); */ 636*cdf0e10cSrcweir 637*cdf0e10cSrcweir if (glyphID >= ttf->nglyphs) /*- incorrect glyphID */ 638*cdf0e10cSrcweir return 0; 639*cdf0e10cSrcweir 640*cdf0e10cSrcweir const sal_uInt8* ptr = table + ttf->goffsets[glyphID]; 641*cdf0e10cSrcweir if ((numberOfContours = GetInt16(ptr, 0, 1)) != -1) /*- glyph is not compound */ 642*cdf0e10cSrcweir return 0; 643*cdf0e10cSrcweir 644*cdf0e10cSrcweir if (metrics) { 645*cdf0e10cSrcweir metrics->xMin = GetInt16(ptr, 2, 1); 646*cdf0e10cSrcweir metrics->yMin = GetInt16(ptr, 4, 1); 647*cdf0e10cSrcweir metrics->xMax = GetInt16(ptr, 6, 1); 648*cdf0e10cSrcweir metrics->yMax = GetInt16(ptr, 8, 1); 649*cdf0e10cSrcweir GetMetrics(ttf, glyphID, metrics); 650*cdf0e10cSrcweir } 651*cdf0e10cSrcweir 652*cdf0e10cSrcweir ptr += 10; 653*cdf0e10cSrcweir 654*cdf0e10cSrcweir do { 655*cdf0e10cSrcweir flags = GetUInt16(ptr, 0, 1); 656*cdf0e10cSrcweir /* printf("flags: 0x%X\n", flags); */ 657*cdf0e10cSrcweir index = GetUInt16(ptr, 2, 1); 658*cdf0e10cSrcweir ptr += 4; 659*cdf0e10cSrcweir 660*cdf0e10cSrcweir if( std::find( glyphlist.begin(), glyphlist.end(), index ) != glyphlist.end() ) 661*cdf0e10cSrcweir { 662*cdf0e10cSrcweir #if OSL_DEBUG_LEVEL > 1 663*cdf0e10cSrcweir fprintf(stderr, "Endless loop found in a compound glyph.\n"); 664*cdf0e10cSrcweir fprintf(stderr, "%d -> ", index); 665*cdf0e10cSrcweir fprintf(stderr," ["); 666*cdf0e10cSrcweir for( std::vector< sal_uInt32 >::const_iterator it = glyphlist.begin(); 667*cdf0e10cSrcweir it != glyphlist.end(); ++it ) 668*cdf0e10cSrcweir { 669*cdf0e10cSrcweir fprintf( stderr,"%d ", (int) *it ); 670*cdf0e10cSrcweir } 671*cdf0e10cSrcweir fprintf(stderr,"]\n"); 672*cdf0e10cSrcweir /**/ 673*cdf0e10cSrcweir #endif 674*cdf0e10cSrcweir } 675*cdf0e10cSrcweir 676*cdf0e10cSrcweir glyphlist.push_back( index ); 677*cdf0e10cSrcweir 678*cdf0e10cSrcweir #ifdef DEBUG2 679*cdf0e10cSrcweir fprintf(stderr,"glyphlist: += %d\n", index); 680*cdf0e10cSrcweir #endif 681*cdf0e10cSrcweir 682*cdf0e10cSrcweir if ((np = GetTTGlyphOutline(ttf, index, &nextComponent, 0, &glyphlist)) == 0) 683*cdf0e10cSrcweir { 684*cdf0e10cSrcweir /* XXX that probably indicates a corrupted font */ 685*cdf0e10cSrcweir #if OSL_DEBUG_LEVEL > 1 686*cdf0e10cSrcweir fprintf(stderr, "An empty compound!\n"); 687*cdf0e10cSrcweir /* assert(!"An empty compound"); */ 688*cdf0e10cSrcweir #endif 689*cdf0e10cSrcweir } 690*cdf0e10cSrcweir 691*cdf0e10cSrcweir #ifdef DEBUG2 692*cdf0e10cSrcweir fprintf(stderr,"%d [", (int)glyphlist.size() ); 693*cdf0e10cSrcweir for( std::vector< sal_uInt32 >::const_iterator it = glyphlist.begin(); 694*cdf0e10cSrcweir it != glyphlist.end(); ++it ) 695*cdf0e10cSrcweir { 696*cdf0e10cSrcweir fprintf( stderr,"%d ", (int) *it ); 697*cdf0e10cSrcweir } 698*cdf0e10cSrcweir fprintf(stderr, "]\n"); 699*cdf0e10cSrcweir if( ! glyphlist.empty() ) 700*cdf0e10cSrcweir fprintf(stderr, "glyphlist: -= %d\n", (int) glyphlist.back()); 701*cdf0e10cSrcweir 702*cdf0e10cSrcweir #endif 703*cdf0e10cSrcweir if( ! glyphlist.empty() ) 704*cdf0e10cSrcweir glyphlist.pop_back(); 705*cdf0e10cSrcweir 706*cdf0e10cSrcweir if (flags & USE_MY_METRICS) { 707*cdf0e10cSrcweir if (metrics) GetMetrics(ttf, index, metrics); 708*cdf0e10cSrcweir } 709*cdf0e10cSrcweir 710*cdf0e10cSrcweir if (flags & ARG_1_AND_2_ARE_WORDS) { 711*cdf0e10cSrcweir e = GetInt16(ptr, 0, 1); 712*cdf0e10cSrcweir f = GetInt16(ptr, 2, 1); 713*cdf0e10cSrcweir /* printf("ARG_1_AND_2_ARE_WORDS: %d %d\n", e & 0xFFFF, f & 0xFFFF); */ 714*cdf0e10cSrcweir ptr += 4; 715*cdf0e10cSrcweir } else { 716*cdf0e10cSrcweir if (flags & ARGS_ARE_XY_VALUES) { /* args are signed */ 717*cdf0e10cSrcweir e = (sal_Int8) *ptr++; 718*cdf0e10cSrcweir f = (sal_Int8) *ptr++; 719*cdf0e10cSrcweir /* printf("ARGS_ARE_XY_VALUES: %d %d\n", e & 0xFF, f & 0xFF); */ 720*cdf0e10cSrcweir } else { /* args are unsigned */ 721*cdf0e10cSrcweir /* printf("!ARGS_ARE_XY_VALUES\n"); */ 722*cdf0e10cSrcweir e = *ptr++; 723*cdf0e10cSrcweir f = *ptr++; 724*cdf0e10cSrcweir } 725*cdf0e10cSrcweir 726*cdf0e10cSrcweir } 727*cdf0e10cSrcweir 728*cdf0e10cSrcweir a = d = 0x10000; 729*cdf0e10cSrcweir b = c = 0; 730*cdf0e10cSrcweir 731*cdf0e10cSrcweir if (flags & WE_HAVE_A_SCALE) { 732*cdf0e10cSrcweir #ifdef DEBUG2 733*cdf0e10cSrcweir fprintf(stderr, "WE_HAVE_A_SCALE\n"); 734*cdf0e10cSrcweir #endif 735*cdf0e10cSrcweir a = GetInt16(ptr, 0, 1) << 2; 736*cdf0e10cSrcweir d = a; 737*cdf0e10cSrcweir ptr += 2; 738*cdf0e10cSrcweir } else if (flags & WE_HAVE_AN_X_AND_Y_SCALE) { 739*cdf0e10cSrcweir #ifdef DEBUG2 740*cdf0e10cSrcweir fprintf(stderr, "WE_HAVE_AN_X_AND_Y_SCALE\n"); 741*cdf0e10cSrcweir #endif 742*cdf0e10cSrcweir a = GetInt16(ptr, 0, 1) << 2; 743*cdf0e10cSrcweir d = GetInt16(ptr, 2, 1) << 2; 744*cdf0e10cSrcweir ptr += 4; 745*cdf0e10cSrcweir } else if (flags & WE_HAVE_A_TWO_BY_TWO) { 746*cdf0e10cSrcweir #ifdef DEBUG2 747*cdf0e10cSrcweir fprintf(stderr, "WE_HAVE_A_TWO_BY_TWO\n"); 748*cdf0e10cSrcweir #endif 749*cdf0e10cSrcweir a = GetInt16(ptr, 0, 1) << 2; 750*cdf0e10cSrcweir b = GetInt16(ptr, 2, 1) << 2; 751*cdf0e10cSrcweir c = GetInt16(ptr, 4, 1) << 2; 752*cdf0e10cSrcweir d = GetInt16(ptr, 6, 1) << 2; 753*cdf0e10cSrcweir ptr += 8; 754*cdf0e10cSrcweir } 755*cdf0e10cSrcweir 756*cdf0e10cSrcweir abs1 = (a < 0) ? -a : a; 757*cdf0e10cSrcweir abs2 = (b < 0) ? -b : b; 758*cdf0e10cSrcweir m = (abs1 > abs2) ? abs1 : abs2; 759*cdf0e10cSrcweir abs3 = abs1 - abs2; 760*cdf0e10cSrcweir if (abs3 < 0) abs3 = -abs3; 761*cdf0e10cSrcweir if (abs3 <= 33) m *= 2; 762*cdf0e10cSrcweir 763*cdf0e10cSrcweir abs1 = (c < 0) ? -c : c; 764*cdf0e10cSrcweir abs2 = (d < 0) ? -d : d; 765*cdf0e10cSrcweir n = (abs1 > abs2) ? abs1 : abs2; 766*cdf0e10cSrcweir abs3 = abs1 - abs2; 767*cdf0e10cSrcweir if (abs3 < 0) abs3 = -abs3; 768*cdf0e10cSrcweir if (abs3 <= 33) n *= 2; 769*cdf0e10cSrcweir 770*cdf0e10cSrcweir if (!ARGS_ARE_XY_VALUES) { /* match the points */ 771*cdf0e10cSrcweir assert(!"ARGS_ARE_XY_VALUES is not implemented!!!\n"); 772*cdf0e10cSrcweir } 773*cdf0e10cSrcweir 774*cdf0e10cSrcweir #ifdef DEBUG2 775*cdf0e10cSrcweir fprintf(stderr, "a: %f, b: %f, c: %f, d: %f, e: %f, f: %f, m: %f, n: %f\n", 776*cdf0e10cSrcweir ((double) a) / 65536, 777*cdf0e10cSrcweir ((double) b) / 65536, 778*cdf0e10cSrcweir ((double) c) / 65536, 779*cdf0e10cSrcweir ((double) d) / 65536, 780*cdf0e10cSrcweir ((double) e) / 65536, 781*cdf0e10cSrcweir ((double) f) / 65536, 782*cdf0e10cSrcweir ((double) m) / 65536, 783*cdf0e10cSrcweir ((double) n) / 65536); 784*cdf0e10cSrcweir #endif 785*cdf0e10cSrcweir 786*cdf0e10cSrcweir for (i=0; i<np; i++) { 787*cdf0e10cSrcweir F16Dot16 t; 788*cdf0e10cSrcweir ControlPoint cp; 789*cdf0e10cSrcweir cp.flags = nextComponent[i].flags; 790*cdf0e10cSrcweir t = fixedMulDiv(a, nextComponent[i].x << 16, m) + fixedMulDiv(c, nextComponent[i].y << 16, m) + (e << 16); 791*cdf0e10cSrcweir cp.x = (sal_Int16)(fixedMul(t, m) >> 16); 792*cdf0e10cSrcweir t = fixedMulDiv(b, nextComponent[i].x << 16, n) + fixedMulDiv(d, nextComponent[i].y << 16, n) + (f << 16); 793*cdf0e10cSrcweir cp.y = (sal_Int16)(fixedMul(t, n) >> 16); 794*cdf0e10cSrcweir 795*cdf0e10cSrcweir #ifdef DEBUG2 796*cdf0e10cSrcweir fprintf(stderr, "( %d %d ) -> ( %d %d )\n", nextComponent[i].x, nextComponent[i].y, cp.x, cp.y); 797*cdf0e10cSrcweir #endif 798*cdf0e10cSrcweir 799*cdf0e10cSrcweir myPoints.push_back( cp ); 800*cdf0e10cSrcweir } 801*cdf0e10cSrcweir 802*cdf0e10cSrcweir free(nextComponent); 803*cdf0e10cSrcweir 804*cdf0e10cSrcweir } while (flags & MORE_COMPONENTS); 805*cdf0e10cSrcweir 806*cdf0e10cSrcweir 807*cdf0e10cSrcweir 808*cdf0e10cSrcweir np = myPoints.size(); 809*cdf0e10cSrcweir 810*cdf0e10cSrcweir pa = (ControlPoint*)calloc(np, sizeof(ControlPoint)); 811*cdf0e10cSrcweir assert(pa != 0); 812*cdf0e10cSrcweir 813*cdf0e10cSrcweir memcpy( pa, &myPoints[0], np*sizeof(ControlPoint) ); 814*cdf0e10cSrcweir 815*cdf0e10cSrcweir *pointArray = pa; 816*cdf0e10cSrcweir return np; 817*cdf0e10cSrcweir } 818*cdf0e10cSrcweir 819*cdf0e10cSrcweir /* NOTE: GetTTGlyphOutline() returns -1 if the glyphID is incorrect, 820*cdf0e10cSrcweir * but Get{Simple|Compound}GlyphOutline returns 0 in such a case. 821*cdf0e10cSrcweir * 822*cdf0e10cSrcweir * NOTE: glyphlist is the stack of glyphs traversed while constructing 823*cdf0e10cSrcweir * a composite glyph. This is a safequard against endless recursion 824*cdf0e10cSrcweir * in corrupted fonts. 825*cdf0e10cSrcweir */ 826*cdf0e10cSrcweir static int GetTTGlyphOutline(TrueTypeFont *ttf, sal_uInt32 glyphID, ControlPoint **pointArray, TTGlyphMetrics *metrics, std::vector< sal_uInt32 >* glyphlist) 827*cdf0e10cSrcweir { 828*cdf0e10cSrcweir const sal_uInt8 *table = getTable( ttf, O_glyf ); 829*cdf0e10cSrcweir sal_Int16 numberOfContours; 830*cdf0e10cSrcweir int res; 831*cdf0e10cSrcweir *pointArray = 0; 832*cdf0e10cSrcweir 833*cdf0e10cSrcweir if (metrics) { 834*cdf0e10cSrcweir memset(metrics, 0, sizeof(TTGlyphMetrics)); /*- metrics is initialized to all zeroes */ 835*cdf0e10cSrcweir } 836*cdf0e10cSrcweir 837*cdf0e10cSrcweir if (glyphID >= ttf->nglyphs) return -1; /**/ 838*cdf0e10cSrcweir 839*cdf0e10cSrcweir const sal_uInt8* ptr = table + ttf->goffsets[glyphID]; 840*cdf0e10cSrcweir int length = ttf->goffsets[glyphID+1] - ttf->goffsets[glyphID]; 841*cdf0e10cSrcweir 842*cdf0e10cSrcweir if (length == 0) { /*- empty glyphs still have hmtx and vmtx metrics values */ 843*cdf0e10cSrcweir if (metrics) GetMetrics(ttf, glyphID, metrics); 844*cdf0e10cSrcweir return 0; 845*cdf0e10cSrcweir } 846*cdf0e10cSrcweir 847*cdf0e10cSrcweir numberOfContours = GetInt16(ptr, 0, 1); 848*cdf0e10cSrcweir 849*cdf0e10cSrcweir if (numberOfContours >= 0) 850*cdf0e10cSrcweir { 851*cdf0e10cSrcweir res=GetSimpleTTOutline(ttf, glyphID, pointArray, metrics); 852*cdf0e10cSrcweir } 853*cdf0e10cSrcweir else 854*cdf0e10cSrcweir { 855*cdf0e10cSrcweir std::vector< sal_uInt32 > aPrivList; 856*cdf0e10cSrcweir aPrivList.push_back( glyphID ); 857*cdf0e10cSrcweir res = GetCompoundTTOutline(ttf, glyphID, pointArray, metrics, glyphlist ? *glyphlist : aPrivList ); 858*cdf0e10cSrcweir } 859*cdf0e10cSrcweir 860*cdf0e10cSrcweir #ifdef DEBUG3 861*cdf0e10cSrcweir { 862*cdf0e10cSrcweir int i; 863*cdf0e10cSrcweir FILE *out = fopen("points.dat", "a"); 864*cdf0e10cSrcweir assert(out != 0); 865*cdf0e10cSrcweir fprintf(out, "Glyph: %d\nPoints: %d\n", glyphID, res); 866*cdf0e10cSrcweir for (i=0; i<res; i++) { 867*cdf0e10cSrcweir fprintf(out, "%c ", ((*pointArray)[i].flags & 0x8000) ? 'X' : '.'); 868*cdf0e10cSrcweir fprintf(out, "%c ", ((*pointArray)[i].flags & 1) ? '+' : '-'); 869*cdf0e10cSrcweir fprintf(out, "%d %d\n", (*pointArray)[i].x, (*pointArray)[i].y); 870*cdf0e10cSrcweir } 871*cdf0e10cSrcweir fclose(out); 872*cdf0e10cSrcweir } 873*cdf0e10cSrcweir #endif 874*cdf0e10cSrcweir 875*cdf0e10cSrcweir return res; 876*cdf0e10cSrcweir } 877*cdf0e10cSrcweir 878*cdf0e10cSrcweir #ifndef NO_TYPE3 879*cdf0e10cSrcweir 880*cdf0e10cSrcweir /*- returns the number of items in the path -*/ 881*cdf0e10cSrcweir 882*cdf0e10cSrcweir static int BSplineToPSPath(ControlPoint *srcA, int srcCount, PSPathElement **path) 883*cdf0e10cSrcweir { 884*cdf0e10cSrcweir std::vector< PSPathElement > aPathList; 885*cdf0e10cSrcweir int nPathCount = 0; 886*cdf0e10cSrcweir PSPathElement p( PS_NOOP ); 887*cdf0e10cSrcweir 888*cdf0e10cSrcweir int x0 = 0, y0 = 0, x1 = 0, y1 = 0, x2, y2, curx, cury; 889*cdf0e10cSrcweir int lastOff = 0; /*- last point was off-contour */ 890*cdf0e10cSrcweir int scflag = 1; /*- start contour flag */ 891*cdf0e10cSrcweir int ecflag = 0; /*- end contour flag */ 892*cdf0e10cSrcweir int cp = 0; /*- current point */ 893*cdf0e10cSrcweir int StartContour = 0, EndContour = 1; 894*cdf0e10cSrcweir 895*cdf0e10cSrcweir *path = 0; 896*cdf0e10cSrcweir 897*cdf0e10cSrcweir /* if (srcCount > 0) for(;;) */ 898*cdf0e10cSrcweir while (srcCount > 0) { /*- srcCount does not get changed inside the loop. */ 899*cdf0e10cSrcweir if (scflag) { 900*cdf0e10cSrcweir int l = cp; 901*cdf0e10cSrcweir StartContour = cp; 902*cdf0e10cSrcweir while (!(srcA[l].flags & 0x8000)) l++; 903*cdf0e10cSrcweir EndContour = l; 904*cdf0e10cSrcweir if (StartContour == EndContour) { 905*cdf0e10cSrcweir if (cp + 1 < srcCount) { 906*cdf0e10cSrcweir cp++; 907*cdf0e10cSrcweir continue; 908*cdf0e10cSrcweir } else { 909*cdf0e10cSrcweir break; 910*cdf0e10cSrcweir } 911*cdf0e10cSrcweir } 912*cdf0e10cSrcweir p = PSPathElement(PS_MOVETO); 913*cdf0e10cSrcweir if (!(srcA[cp].flags & 1)) { 914*cdf0e10cSrcweir if (!(srcA[EndContour].flags & 1)) { 915*cdf0e10cSrcweir p.x1 = x0 = (srcA[cp].x + srcA[EndContour].x + 1) / 2; 916*cdf0e10cSrcweir p.y1 = y0 = (srcA[cp].y + srcA[EndContour].y + 1) / 2; 917*cdf0e10cSrcweir } else { 918*cdf0e10cSrcweir p.x1 = x0 = srcA[EndContour].x; 919*cdf0e10cSrcweir p.y1 = y0 = srcA[EndContour].y; 920*cdf0e10cSrcweir } 921*cdf0e10cSrcweir } else { 922*cdf0e10cSrcweir p.x1 = x0 = srcA[cp].x; 923*cdf0e10cSrcweir p.y1 = y0 = srcA[cp].y; 924*cdf0e10cSrcweir cp++; 925*cdf0e10cSrcweir } 926*cdf0e10cSrcweir aPathList.push_back( p ); 927*cdf0e10cSrcweir lastOff = 0; 928*cdf0e10cSrcweir scflag = 0; 929*cdf0e10cSrcweir } 930*cdf0e10cSrcweir 931*cdf0e10cSrcweir curx = srcA[cp].x; 932*cdf0e10cSrcweir cury = srcA[cp].y; 933*cdf0e10cSrcweir 934*cdf0e10cSrcweir if (srcA[cp].flags & 1) 935*cdf0e10cSrcweir { 936*cdf0e10cSrcweir if (lastOff) 937*cdf0e10cSrcweir { 938*cdf0e10cSrcweir p = PSPathElement(PS_CURVETO); 939*cdf0e10cSrcweir p.x1 = x0 + (2 * (x1 - x0) + 1) / 3; 940*cdf0e10cSrcweir p.y1 = y0 + (2 * (y1 - y0) + 1) / 3; 941*cdf0e10cSrcweir p.x2 = x1 + (curx - x1 + 1) / 3; 942*cdf0e10cSrcweir p.y2 = y1 + (cury - y1 + 1) / 3; 943*cdf0e10cSrcweir p.x3 = curx; 944*cdf0e10cSrcweir p.y3 = cury; 945*cdf0e10cSrcweir aPathList.push_back( p ); 946*cdf0e10cSrcweir } 947*cdf0e10cSrcweir else 948*cdf0e10cSrcweir { 949*cdf0e10cSrcweir if (!(x0 == curx && y0 == cury)) 950*cdf0e10cSrcweir { /* eliminate empty lines */ 951*cdf0e10cSrcweir p = PSPathElement(PS_LINETO); 952*cdf0e10cSrcweir p.x1 = curx; 953*cdf0e10cSrcweir p.y1 = cury; 954*cdf0e10cSrcweir aPathList.push_back( p ); 955*cdf0e10cSrcweir } 956*cdf0e10cSrcweir } 957*cdf0e10cSrcweir x0 = curx; y0 = cury; lastOff = 0; 958*cdf0e10cSrcweir } 959*cdf0e10cSrcweir else 960*cdf0e10cSrcweir { 961*cdf0e10cSrcweir if (lastOff) 962*cdf0e10cSrcweir { 963*cdf0e10cSrcweir x2 = (x1 + curx + 1) / 2; 964*cdf0e10cSrcweir y2 = (y1 + cury + 1) / 2; 965*cdf0e10cSrcweir p = PSPathElement(PS_CURVETO); 966*cdf0e10cSrcweir p.x1 = x0 + (2 * (x1 - x0) + 1) / 3; 967*cdf0e10cSrcweir p.y1 = y0 + (2 * (y1 - y0) + 1) / 3; 968*cdf0e10cSrcweir p.x2 = x1 + (x2 - x1 + 1) / 3; 969*cdf0e10cSrcweir p.y2 = y1 + (y2 - y1 + 1) / 3; 970*cdf0e10cSrcweir p.x3 = x2; 971*cdf0e10cSrcweir p.y3 = y2; 972*cdf0e10cSrcweir aPathList.push_back( p ); 973*cdf0e10cSrcweir x0 = x2; y0 = y2; 974*cdf0e10cSrcweir x1 = curx; y1 = cury; 975*cdf0e10cSrcweir } else { 976*cdf0e10cSrcweir x1 = curx; y1 = cury; 977*cdf0e10cSrcweir } 978*cdf0e10cSrcweir lastOff = true; 979*cdf0e10cSrcweir } 980*cdf0e10cSrcweir 981*cdf0e10cSrcweir if (ecflag) { 982*cdf0e10cSrcweir aPathList.push_back( PSPathElement(PS_CLOSEPATH) ); 983*cdf0e10cSrcweir scflag = 1; 984*cdf0e10cSrcweir ecflag = 0; 985*cdf0e10cSrcweir cp = EndContour + 1; 986*cdf0e10cSrcweir if (cp >= srcCount) break; 987*cdf0e10cSrcweir continue; 988*cdf0e10cSrcweir } 989*cdf0e10cSrcweir 990*cdf0e10cSrcweir 991*cdf0e10cSrcweir if (cp == EndContour) { 992*cdf0e10cSrcweir cp = StartContour; 993*cdf0e10cSrcweir ecflag = true; 994*cdf0e10cSrcweir } else { 995*cdf0e10cSrcweir cp++; 996*cdf0e10cSrcweir } 997*cdf0e10cSrcweir } 998*cdf0e10cSrcweir 999*cdf0e10cSrcweir if( (nPathCount = (int)aPathList.size()) > 0) 1000*cdf0e10cSrcweir { 1001*cdf0e10cSrcweir *path = (PSPathElement*)calloc(nPathCount, sizeof(PSPathElement)); 1002*cdf0e10cSrcweir assert(*path != 0); 1003*cdf0e10cSrcweir memcpy( *path, &aPathList[0], nPathCount * sizeof(PSPathElement) ); 1004*cdf0e10cSrcweir } 1005*cdf0e10cSrcweir 1006*cdf0e10cSrcweir return nPathCount; 1007*cdf0e10cSrcweir } 1008*cdf0e10cSrcweir 1009*cdf0e10cSrcweir #endif 1010*cdf0e10cSrcweir 1011*cdf0e10cSrcweir /*- Extracts a string from the name table and allocates memory for it -*/ 1012*cdf0e10cSrcweir 1013*cdf0e10cSrcweir static char *nameExtract( const sal_uInt8* name, int nTableSize, int n, int dbFlag, sal_uInt16** ucs2result ) 1014*cdf0e10cSrcweir { 1015*cdf0e10cSrcweir int i; 1016*cdf0e10cSrcweir char *res; 1017*cdf0e10cSrcweir const sal_uInt8* ptr = name + GetUInt16(name, 4, 1) + GetUInt16(name + 6, 12 * n + 10, 1); 1018*cdf0e10cSrcweir int len = GetUInt16(name+6, 12 * n + 8, 1); 1019*cdf0e10cSrcweir 1020*cdf0e10cSrcweir // sanity check 1021*cdf0e10cSrcweir if( (len <= 0) || ((ptr+len) > (name+nTableSize)) ) 1022*cdf0e10cSrcweir { 1023*cdf0e10cSrcweir if( ucs2result ) 1024*cdf0e10cSrcweir *ucs2result = NULL; 1025*cdf0e10cSrcweir return NULL; 1026*cdf0e10cSrcweir } 1027*cdf0e10cSrcweir 1028*cdf0e10cSrcweir if( ucs2result ) 1029*cdf0e10cSrcweir *ucs2result = NULL; 1030*cdf0e10cSrcweir if (dbFlag) { 1031*cdf0e10cSrcweir res = (char*)malloc(1 + len/2); 1032*cdf0e10cSrcweir assert(res != 0); 1033*cdf0e10cSrcweir for (i = 0; i < len/2; i++) res[i] = *(ptr + i * 2 + 1); 1034*cdf0e10cSrcweir res[len/2] = 0; 1035*cdf0e10cSrcweir if( ucs2result ) 1036*cdf0e10cSrcweir { 1037*cdf0e10cSrcweir *ucs2result = (sal_uInt16*)malloc( len+2 ); 1038*cdf0e10cSrcweir for (i = 0; i < len/2; i++ ) (*ucs2result)[i] = GetUInt16( ptr, 2*i, 1 ); 1039*cdf0e10cSrcweir (*ucs2result)[len/2] = 0; 1040*cdf0e10cSrcweir } 1041*cdf0e10cSrcweir } else { 1042*cdf0e10cSrcweir res = (char*)malloc(1 + len); 1043*cdf0e10cSrcweir assert(res != 0); 1044*cdf0e10cSrcweir memcpy(res, ptr, len); 1045*cdf0e10cSrcweir res[len] = 0; 1046*cdf0e10cSrcweir } 1047*cdf0e10cSrcweir 1048*cdf0e10cSrcweir return res; 1049*cdf0e10cSrcweir } 1050*cdf0e10cSrcweir 1051*cdf0e10cSrcweir static int findname( const sal_uInt8 *name, sal_uInt16 n, sal_uInt16 platformID, 1052*cdf0e10cSrcweir sal_uInt16 encodingID, sal_uInt16 languageID, sal_uInt16 nameID ) 1053*cdf0e10cSrcweir { 1054*cdf0e10cSrcweir int l = 0, r = n-1, i; 1055*cdf0e10cSrcweir sal_uInt32 t1, t2; 1056*cdf0e10cSrcweir sal_uInt32 m1, m2; 1057*cdf0e10cSrcweir 1058*cdf0e10cSrcweir if (n == 0) return -1; 1059*cdf0e10cSrcweir 1060*cdf0e10cSrcweir m1 = (platformID << 16) | encodingID; 1061*cdf0e10cSrcweir m2 = (languageID << 16) | nameID; 1062*cdf0e10cSrcweir 1063*cdf0e10cSrcweir do { 1064*cdf0e10cSrcweir i = (l + r) >> 1; 1065*cdf0e10cSrcweir t1 = GetUInt32(name + 6, i * 12 + 0, 1); 1066*cdf0e10cSrcweir t2 = GetUInt32(name + 6, i * 12 + 4, 1); 1067*cdf0e10cSrcweir 1068*cdf0e10cSrcweir if (! ((m1 < t1) || ((m1 == t1) && (m2 < t2)))) l = i + 1; 1069*cdf0e10cSrcweir if (! ((m1 > t1) || ((m1 == t1) && (m2 > t2)))) r = i - 1; 1070*cdf0e10cSrcweir } while (l <= r); 1071*cdf0e10cSrcweir 1072*cdf0e10cSrcweir if (l - r == 2) { 1073*cdf0e10cSrcweir return l - 1; 1074*cdf0e10cSrcweir } 1075*cdf0e10cSrcweir 1076*cdf0e10cSrcweir return -1; 1077*cdf0e10cSrcweir } 1078*cdf0e10cSrcweir 1079*cdf0e10cSrcweir /* XXX marlett.ttf uses (3, 0, 1033) instead of (3, 1, 1033) and does not have any Apple tables. 1080*cdf0e10cSrcweir * Fix: if (3, 1, 1033) is not found - need to check for (3, 0, 1033) 1081*cdf0e10cSrcweir * 1082*cdf0e10cSrcweir * /d/fonts/ttzh_tw/Big5/Hanyi/ma6b5p uses (1, 0, 19) for English strings, instead of (1, 0, 0) 1083*cdf0e10cSrcweir * and does not have (3, 1, 1033) 1084*cdf0e10cSrcweir * Fix: if (1, 0, 0) and (3, 1, 1033) are not found need to look for (1, 0, *) - that will 1085*cdf0e10cSrcweir * require a change in algorithm 1086*cdf0e10cSrcweir * 1087*cdf0e10cSrcweir * /d/fonts/fdltest/Korean/h2drrm has unsorted names and a an unknown (to me) Mac LanguageID, 1088*cdf0e10cSrcweir * but (1, 0, 1042) strings usable 1089*cdf0e10cSrcweir * Fix: change algorithm, and use (1, 0, *) if both standard Mac and MS strings are not found 1090*cdf0e10cSrcweir */ 1091*cdf0e10cSrcweir 1092*cdf0e10cSrcweir static void GetNames(TrueTypeFont *t) 1093*cdf0e10cSrcweir { 1094*cdf0e10cSrcweir const sal_uInt8* table = getTable( t, O_name ); 1095*cdf0e10cSrcweir int nTableSize = getTableSize(t, O_name); 1096*cdf0e10cSrcweir 1097*cdf0e10cSrcweir if (nTableSize < 4) 1098*cdf0e10cSrcweir { 1099*cdf0e10cSrcweir #if OSL_DEBUG_LEVEL > 1 1100*cdf0e10cSrcweir fprintf(stderr, "O_name table too small\n"); 1101*cdf0e10cSrcweir #endif 1102*cdf0e10cSrcweir return; 1103*cdf0e10cSrcweir } 1104*cdf0e10cSrcweir 1105*cdf0e10cSrcweir sal_uInt16 n = GetUInt16(table, 2, 1); 1106*cdf0e10cSrcweir int i, r; 1107*cdf0e10cSrcweir sal_Bool bPSNameOK = sal_True; 1108*cdf0e10cSrcweir 1109*cdf0e10cSrcweir /* #129743# simple sanity check for name table entry count */ 1110*cdf0e10cSrcweir if( nTableSize <= n * 12 + 6 ) 1111*cdf0e10cSrcweir n = 0; 1112*cdf0e10cSrcweir 1113*cdf0e10cSrcweir /* PostScript name: preferred Microsoft */ 1114*cdf0e10cSrcweir t->psname = NULL; 1115*cdf0e10cSrcweir if ((r = findname(table, n, 3, 1, 0x0409, 6)) != -1) 1116*cdf0e10cSrcweir t->psname = nameExtract(table, nTableSize, r, 1, NULL); 1117*cdf0e10cSrcweir if ( ! t->psname && (r = findname(table, n, 1, 0, 0, 6)) != -1) 1118*cdf0e10cSrcweir t->psname = nameExtract(table, nTableSize, r, 0, NULL); 1119*cdf0e10cSrcweir if ( ! t->psname && (r = findname(table, n, 3, 0, 0x0409, 6)) != -1) 1120*cdf0e10cSrcweir { 1121*cdf0e10cSrcweir // some symbol fonts like Marlett have a 3,0 name! 1122*cdf0e10cSrcweir t->psname = nameExtract(table, nTableSize, r, 1, NULL); 1123*cdf0e10cSrcweir } 1124*cdf0e10cSrcweir // for embedded font in Ghostscript PDFs 1125*cdf0e10cSrcweir if ( ! t->psname && (r = findname(table, n, 2, 2, 0, 6)) != -1) 1126*cdf0e10cSrcweir { 1127*cdf0e10cSrcweir t->psname = nameExtract(table, nTableSize, r, 0, NULL); 1128*cdf0e10cSrcweir } 1129*cdf0e10cSrcweir if ( ! t->psname ) 1130*cdf0e10cSrcweir { 1131*cdf0e10cSrcweir if ( t->fname ) 1132*cdf0e10cSrcweir { 1133*cdf0e10cSrcweir char* pReverse = t->fname + strlen(t->fname); 1134*cdf0e10cSrcweir /* take only last token of filename */ 1135*cdf0e10cSrcweir while(pReverse != t->fname && *pReverse != '/') pReverse--; 1136*cdf0e10cSrcweir if(*pReverse == '/') pReverse++; 1137*cdf0e10cSrcweir t->psname = strdup(pReverse); 1138*cdf0e10cSrcweir assert(t->psname != 0); 1139*cdf0e10cSrcweir for (i=strlen(t->psname) - 1; i > 0; i--) 1140*cdf0e10cSrcweir { 1141*cdf0e10cSrcweir /*- Remove the suffix -*/ 1142*cdf0e10cSrcweir if (t->psname[i] == '.' ) { 1143*cdf0e10cSrcweir t->psname[i] = 0; 1144*cdf0e10cSrcweir break; 1145*cdf0e10cSrcweir } 1146*cdf0e10cSrcweir } 1147*cdf0e10cSrcweir } 1148*cdf0e10cSrcweir else 1149*cdf0e10cSrcweir t->psname = strdup( "Unknown" ); 1150*cdf0e10cSrcweir } 1151*cdf0e10cSrcweir 1152*cdf0e10cSrcweir /* Font family and subfamily names: preferred Apple */ 1153*cdf0e10cSrcweir t->family = NULL; 1154*cdf0e10cSrcweir if ((r = findname(table, n, 0, 0, 0, 1)) != -1) 1155*cdf0e10cSrcweir t->family = nameExtract(table, nTableSize, r, 1, &t->ufamily); 1156*cdf0e10cSrcweir if ( ! t->family && (r = findname(table, n, 3, 1, 0x0409, 1)) != -1) 1157*cdf0e10cSrcweir t->family = nameExtract(table, nTableSize, r, 1, &t->ufamily); 1158*cdf0e10cSrcweir if ( ! t->family && (r = findname(table, n, 1, 0, 0, 1)) != -1) 1159*cdf0e10cSrcweir t->family = nameExtract(table, nTableSize, r, 0, NULL); 1160*cdf0e10cSrcweir if ( ! t->family && (r = findname(table, n, 3, 1, 0x0411, 1)) != -1) 1161*cdf0e10cSrcweir t->family = nameExtract(table, nTableSize, r, 1, &t->ufamily); 1162*cdf0e10cSrcweir if ( ! t->family && (r = findname(table, n, 3, 0, 0x0409, 1)) != -1) 1163*cdf0e10cSrcweir t->family = nameExtract(table, nTableSize, r, 1, &t->ufamily); 1164*cdf0e10cSrcweir if ( ! t->family ) 1165*cdf0e10cSrcweir { 1166*cdf0e10cSrcweir t->family = strdup(t->psname); 1167*cdf0e10cSrcweir assert(t->family != 0); 1168*cdf0e10cSrcweir } 1169*cdf0e10cSrcweir 1170*cdf0e10cSrcweir t->subfamily = NULL; 1171*cdf0e10cSrcweir t->usubfamily = NULL; 1172*cdf0e10cSrcweir if ((r = findname(table, n, 1, 0, 0, 2)) != -1) 1173*cdf0e10cSrcweir t->subfamily = nameExtract(table, nTableSize, r, 0, &t->usubfamily); 1174*cdf0e10cSrcweir if ( ! t->subfamily && (r = findname(table, n, 3, 1, 0x0409, 2)) != -1) 1175*cdf0e10cSrcweir t->subfamily = nameExtract(table, nTableSize, r, 1, &t->usubfamily); 1176*cdf0e10cSrcweir if ( ! t->subfamily ) 1177*cdf0e10cSrcweir { 1178*cdf0e10cSrcweir t->subfamily = strdup(""); 1179*cdf0e10cSrcweir } 1180*cdf0e10cSrcweir 1181*cdf0e10cSrcweir /* #i60349# sanity check psname 1182*cdf0e10cSrcweir * psname parctically has to be 7bit ascii and should not contains spaces 1183*cdf0e10cSrcweir * there is a class of broken fonts which do not fullfill that at all, so let's try 1184*cdf0e10cSrcweir * if the family name is 7bit ascii and take it instead if so 1185*cdf0e10cSrcweir */ 1186*cdf0e10cSrcweir /* check psname */ 1187*cdf0e10cSrcweir for( i = 0; t->psname[i] != 0 && bPSNameOK; i++ ) 1188*cdf0e10cSrcweir if( t->psname[ i ] < 33 || (t->psname[ i ] & 0x80) ) 1189*cdf0e10cSrcweir bPSNameOK = sal_False; 1190*cdf0e10cSrcweir if( bPSNameOK == sal_False ) 1191*cdf0e10cSrcweir { 1192*cdf0e10cSrcweir sal_Bool bReplace = sal_True; 1193*cdf0e10cSrcweir /* check if family is a suitable replacement */ 1194*cdf0e10cSrcweir if( t->ufamily && t->family ) 1195*cdf0e10cSrcweir { 1196*cdf0e10cSrcweir for( i = 0; t->ufamily[ i ] != 0 && bReplace; i++ ) 1197*cdf0e10cSrcweir if( t->ufamily[ i ] < 33 || t->ufamily[ i ] > 127 ) 1198*cdf0e10cSrcweir bReplace = sal_False; 1199*cdf0e10cSrcweir if( bReplace ) 1200*cdf0e10cSrcweir { 1201*cdf0e10cSrcweir free( t->psname ); 1202*cdf0e10cSrcweir t->psname = strdup( t->family ); 1203*cdf0e10cSrcweir } 1204*cdf0e10cSrcweir } 1205*cdf0e10cSrcweir } 1206*cdf0e10cSrcweir } 1207*cdf0e10cSrcweir 1208*cdf0e10cSrcweir enum cmapType { 1209*cdf0e10cSrcweir CMAP_NOT_USABLE = -1, 1210*cdf0e10cSrcweir CMAP_MS_Symbol = 10, 1211*cdf0e10cSrcweir CMAP_MS_Unicode = 11, 1212*cdf0e10cSrcweir CMAP_MS_ShiftJIS = 12, 1213*cdf0e10cSrcweir CMAP_MS_Big5 = 13, 1214*cdf0e10cSrcweir CMAP_MS_PRC = 14, 1215*cdf0e10cSrcweir CMAP_MS_Wansung = 15, 1216*cdf0e10cSrcweir CMAP_MS_Johab = 16 1217*cdf0e10cSrcweir }; 1218*cdf0e10cSrcweir 1219*cdf0e10cSrcweir #define MISSING_GLYPH_INDEX 0 1220*cdf0e10cSrcweir 1221*cdf0e10cSrcweir /* 1222*cdf0e10cSrcweir * getGlyph[0246]() functions and freinds are implemented by: 1223*cdf0e10cSrcweir * @author Manpreet Singh 1224*cdf0e10cSrcweir * getGlyph12() function and friends by: 1225*cdf0e10cSrcweir * @author HDU 1226*cdf0e10cSrcweir */ 1227*cdf0e10cSrcweir static sal_uInt32 getGlyph0(const sal_uInt8* cmap, sal_uInt32 c) { 1228*cdf0e10cSrcweir if (c <= 255) { 1229*cdf0e10cSrcweir return *(cmap + 6 + c); 1230*cdf0e10cSrcweir } else { 1231*cdf0e10cSrcweir return MISSING_GLYPH_INDEX; 1232*cdf0e10cSrcweir } 1233*cdf0e10cSrcweir } 1234*cdf0e10cSrcweir 1235*cdf0e10cSrcweir typedef struct _subHeader2 { 1236*cdf0e10cSrcweir sal_uInt16 firstCode; 1237*cdf0e10cSrcweir sal_uInt16 entryCount; 1238*cdf0e10cSrcweir sal_uInt16 idDelta; 1239*cdf0e10cSrcweir sal_uInt16 idRangeOffset; 1240*cdf0e10cSrcweir } subHeader2; 1241*cdf0e10cSrcweir 1242*cdf0e10cSrcweir static sal_uInt32 getGlyph2(const sal_uInt8 *cmap, sal_uInt32 c) { 1243*cdf0e10cSrcweir sal_uInt16 *CMAP2 = (sal_uInt16 *) cmap; 1244*cdf0e10cSrcweir sal_uInt8 theHighByte; 1245*cdf0e10cSrcweir 1246*cdf0e10cSrcweir sal_uInt8 theLowByte; 1247*cdf0e10cSrcweir subHeader2* subHeader2s; 1248*cdf0e10cSrcweir sal_uInt16* subHeader2Keys; 1249*cdf0e10cSrcweir sal_uInt16 firstCode; 1250*cdf0e10cSrcweir int k; 1251*cdf0e10cSrcweir sal_uInt32 ToReturn; 1252*cdf0e10cSrcweir 1253*cdf0e10cSrcweir theHighByte = (sal_uInt8)((c >> 8) & 0x00ff); 1254*cdf0e10cSrcweir theLowByte = (sal_uInt8)(c & 0x00ff); 1255*cdf0e10cSrcweir subHeader2Keys = CMAP2 + 3; 1256*cdf0e10cSrcweir subHeader2s = (subHeader2 *)(subHeader2Keys + 256); 1257*cdf0e10cSrcweir k = Int16FromMOTA(subHeader2Keys[theHighByte]) / 8; 1258*cdf0e10cSrcweir 1259*cdf0e10cSrcweir if(k == 0) { 1260*cdf0e10cSrcweir firstCode = Int16FromMOTA(subHeader2s[k].firstCode); 1261*cdf0e10cSrcweir if(theLowByte >= firstCode && theLowByte < (firstCode + Int16FromMOTA(subHeader2s[k].entryCount))) { 1262*cdf0e10cSrcweir return *((&(subHeader2s[0].idRangeOffset)) 1263*cdf0e10cSrcweir + (Int16FromMOTA(subHeader2s[0].idRangeOffset)/2) /* + offset */ 1264*cdf0e10cSrcweir + theLowByte /* + to_look */ 1265*cdf0e10cSrcweir - Int16FromMOTA(subHeader2s[0].firstCode) 1266*cdf0e10cSrcweir ); 1267*cdf0e10cSrcweir } else { 1268*cdf0e10cSrcweir return MISSING_GLYPH_INDEX; 1269*cdf0e10cSrcweir } 1270*cdf0e10cSrcweir } else if (k > 0) { 1271*cdf0e10cSrcweir firstCode = Int16FromMOTA(subHeader2s[k].firstCode); 1272*cdf0e10cSrcweir if(theLowByte >= firstCode && theLowByte < (firstCode + Int16FromMOTA(subHeader2s[k].entryCount))) { 1273*cdf0e10cSrcweir ToReturn = *((&(subHeader2s[k].idRangeOffset)) 1274*cdf0e10cSrcweir + (Int16FromMOTA(subHeader2s[k].idRangeOffset)/2) 1275*cdf0e10cSrcweir + theLowByte - firstCode); 1276*cdf0e10cSrcweir if(ToReturn == 0) { 1277*cdf0e10cSrcweir return MISSING_GLYPH_INDEX; 1278*cdf0e10cSrcweir } else { 1279*cdf0e10cSrcweir ToReturn += Int16FromMOTA(subHeader2s[k].idDelta); 1280*cdf0e10cSrcweir return (ToReturn & 0xFFFF); 1281*cdf0e10cSrcweir } 1282*cdf0e10cSrcweir } else { 1283*cdf0e10cSrcweir return MISSING_GLYPH_INDEX; 1284*cdf0e10cSrcweir } 1285*cdf0e10cSrcweir } else { 1286*cdf0e10cSrcweir return MISSING_GLYPH_INDEX; 1287*cdf0e10cSrcweir } 1288*cdf0e10cSrcweir } 1289*cdf0e10cSrcweir 1290*cdf0e10cSrcweir static sal_uInt32 getGlyph6(const sal_uInt8 *cmap, sal_uInt32 c) { 1291*cdf0e10cSrcweir sal_uInt16 firstCode, lastCode, count; 1292*cdf0e10cSrcweir sal_uInt16 *CMAP6 = (sal_uInt16 *) cmap; 1293*cdf0e10cSrcweir 1294*cdf0e10cSrcweir firstCode = Int16FromMOTA(*(CMAP6 + 3)); 1295*cdf0e10cSrcweir count = Int16FromMOTA(*(CMAP6 + 4)); 1296*cdf0e10cSrcweir lastCode = firstCode + count - 1; 1297*cdf0e10cSrcweir if (c < firstCode || c > lastCode) { 1298*cdf0e10cSrcweir return MISSING_GLYPH_INDEX; 1299*cdf0e10cSrcweir } else { 1300*cdf0e10cSrcweir return *((CMAP6 + 5)/*glyphIdArray*/ + (c - firstCode)); 1301*cdf0e10cSrcweir } 1302*cdf0e10cSrcweir } 1303*cdf0e10cSrcweir 1304*cdf0e10cSrcweir static sal_uInt16 GEbinsearch(sal_uInt16 *ar, sal_uInt16 length, sal_uInt16 toSearch) { 1305*cdf0e10cSrcweir signed int low, mid, high, lastfound = 0xffff; 1306*cdf0e10cSrcweir sal_uInt16 res; 1307*cdf0e10cSrcweir if(length == (sal_uInt16)0 || length == (sal_uInt16)0xFFFF) { 1308*cdf0e10cSrcweir return (sal_uInt16)0xFFFF; 1309*cdf0e10cSrcweir } 1310*cdf0e10cSrcweir low = 0; 1311*cdf0e10cSrcweir high = length - 1; 1312*cdf0e10cSrcweir while(high >= low) { 1313*cdf0e10cSrcweir mid = (high + low)/2; 1314*cdf0e10cSrcweir res = Int16FromMOTA(*(ar+mid)); 1315*cdf0e10cSrcweir if(res >= toSearch) { 1316*cdf0e10cSrcweir lastfound = mid; 1317*cdf0e10cSrcweir high = --mid; 1318*cdf0e10cSrcweir } else { 1319*cdf0e10cSrcweir low = ++mid; 1320*cdf0e10cSrcweir } 1321*cdf0e10cSrcweir } 1322*cdf0e10cSrcweir return (sal_uInt16)lastfound; 1323*cdf0e10cSrcweir } 1324*cdf0e10cSrcweir 1325*cdf0e10cSrcweir 1326*cdf0e10cSrcweir static sal_uInt32 getGlyph4(const sal_uInt8 *cmap, sal_uInt32 c) { 1327*cdf0e10cSrcweir sal_uInt16 i; 1328*cdf0e10cSrcweir int ToReturn; 1329*cdf0e10cSrcweir sal_uInt16 segCount; 1330*cdf0e10cSrcweir sal_uInt16 * startCode; 1331*cdf0e10cSrcweir sal_uInt16 * endCode; 1332*cdf0e10cSrcweir sal_uInt16 * idDelta; 1333*cdf0e10cSrcweir /* sal_uInt16 * glyphIdArray; */ 1334*cdf0e10cSrcweir sal_uInt16 * idRangeOffset; 1335*cdf0e10cSrcweir sal_uInt16 * glyphIndexArray; 1336*cdf0e10cSrcweir sal_uInt16 *CMAP4 = (sal_uInt16 *) cmap; 1337*cdf0e10cSrcweir /* sal_uInt16 GEbinsearch(sal_uInt16 *ar, sal_uInt16 length, sal_uInt16 toSearch); */ 1338*cdf0e10cSrcweir 1339*cdf0e10cSrcweir segCount = Int16FromMOTA(*(CMAP4 + 3))/2; 1340*cdf0e10cSrcweir endCode = CMAP4 + 7; 1341*cdf0e10cSrcweir i = GEbinsearch(endCode, segCount, (sal_uInt16)c); 1342*cdf0e10cSrcweir 1343*cdf0e10cSrcweir if (i == (sal_uInt16) 0xFFFF) { 1344*cdf0e10cSrcweir return MISSING_GLYPH_INDEX; 1345*cdf0e10cSrcweir } 1346*cdf0e10cSrcweir startCode = endCode + segCount + 1; 1347*cdf0e10cSrcweir 1348*cdf0e10cSrcweir if(Int16FromMOTA(startCode[i]) > c) { 1349*cdf0e10cSrcweir return MISSING_GLYPH_INDEX; 1350*cdf0e10cSrcweir } 1351*cdf0e10cSrcweir idDelta = startCode + segCount; 1352*cdf0e10cSrcweir idRangeOffset = idDelta + segCount; 1353*cdf0e10cSrcweir glyphIndexArray = idRangeOffset + segCount; 1354*cdf0e10cSrcweir 1355*cdf0e10cSrcweir if(Int16FromMOTA(idRangeOffset[i]) != 0) { 1356*cdf0e10cSrcweir c = Int16FromMOTA(*(&(idRangeOffset[i]) + (Int16FromMOTA(idRangeOffset[i])/2 + (c - Int16FromMOTA(startCode[i]))))); 1357*cdf0e10cSrcweir } 1358*cdf0e10cSrcweir 1359*cdf0e10cSrcweir ToReturn = (Int16FromMOTA(idDelta[i]) + c) & 0xFFFF; 1360*cdf0e10cSrcweir return ToReturn; 1361*cdf0e10cSrcweir } 1362*cdf0e10cSrcweir 1363*cdf0e10cSrcweir static sal_uInt32 getGlyph12(const sal_uInt8 *pCmap, sal_uInt32 cChar) { 1364*cdf0e10cSrcweir const sal_uInt32* pCMAP12 = (const sal_uInt32*)pCmap; 1365*cdf0e10cSrcweir int nLength = Int32FromMOTA( pCMAP12[1] ); 1366*cdf0e10cSrcweir int nGroups = Int32FromMOTA( pCMAP12[3] ); 1367*cdf0e10cSrcweir int nLower = 0; 1368*cdf0e10cSrcweir int nUpper = nGroups; 1369*cdf0e10cSrcweir 1370*cdf0e10cSrcweir if( nUpper > (nLength-16)/12 ) 1371*cdf0e10cSrcweir nUpper = (nLength-16)/12; 1372*cdf0e10cSrcweir 1373*cdf0e10cSrcweir /* binary search in "segmented coverage" subtable */ 1374*cdf0e10cSrcweir while( nLower < nUpper ) { 1375*cdf0e10cSrcweir int nIndex = (nLower + nUpper) / 2; 1376*cdf0e10cSrcweir const sal_uInt32* pEntry = &pCMAP12[ 4 + 3*nIndex ]; 1377*cdf0e10cSrcweir sal_uInt32 cStart = Int32FromMOTA( pEntry[0] ); 1378*cdf0e10cSrcweir sal_uInt32 cLast = Int32FromMOTA( pEntry[1] ); 1379*cdf0e10cSrcweir if( cChar < cStart ) 1380*cdf0e10cSrcweir nUpper = nIndex; 1381*cdf0e10cSrcweir else if( cChar > cLast ) 1382*cdf0e10cSrcweir nLower = nIndex + 1; 1383*cdf0e10cSrcweir else { /* found matching entry! */ 1384*cdf0e10cSrcweir sal_uInt32 nGlyph = Int32FromMOTA( pEntry[2] ); 1385*cdf0e10cSrcweir nGlyph += cChar - cStart; 1386*cdf0e10cSrcweir return nGlyph; 1387*cdf0e10cSrcweir } 1388*cdf0e10cSrcweir } 1389*cdf0e10cSrcweir 1390*cdf0e10cSrcweir return MISSING_GLYPH_INDEX; 1391*cdf0e10cSrcweir } 1392*cdf0e10cSrcweir 1393*cdf0e10cSrcweir 1394*cdf0e10cSrcweir static void FindCmap(TrueTypeFont *ttf) 1395*cdf0e10cSrcweir { 1396*cdf0e10cSrcweir const sal_uInt8* table = getTable(ttf, O_cmap); 1397*cdf0e10cSrcweir sal_uInt32 table_size = getTableSize(ttf, O_cmap); 1398*cdf0e10cSrcweir sal_uInt16 ncmaps = GetUInt16(table, 2, 1); 1399*cdf0e10cSrcweir unsigned int i; 1400*cdf0e10cSrcweir sal_uInt32 AppleUni = 0; // Apple Unicode 1401*cdf0e10cSrcweir sal_uInt32 ThreeZero = 0; /* MS Symbol */ 1402*cdf0e10cSrcweir sal_uInt32 ThreeOne = 0; /* MS UCS-2 */ 1403*cdf0e10cSrcweir sal_uInt32 ThreeTwo = 0; /* MS ShiftJIS */ 1404*cdf0e10cSrcweir sal_uInt32 ThreeThree = 0; /* MS Big5 */ 1405*cdf0e10cSrcweir sal_uInt32 ThreeFour = 0; /* MS PRC */ 1406*cdf0e10cSrcweir sal_uInt32 ThreeFive = 0; /* MS Wansung */ 1407*cdf0e10cSrcweir sal_uInt32 ThreeSix = 0; /* MS Johab */ 1408*cdf0e10cSrcweir 1409*cdf0e10cSrcweir for (i = 0; i < ncmaps; i++) { 1410*cdf0e10cSrcweir sal_uInt32 offset; 1411*cdf0e10cSrcweir sal_uInt16 pID, eID; 1412*cdf0e10cSrcweir 1413*cdf0e10cSrcweir /* sanity check, cmap entry must lie within table */ 1414*cdf0e10cSrcweir if( i*8+4 > table_size ) 1415*cdf0e10cSrcweir break; 1416*cdf0e10cSrcweir 1417*cdf0e10cSrcweir pID = GetUInt16(table, 4 + i * 8, 1); 1418*cdf0e10cSrcweir eID = GetUInt16(table, 6 + i * 8, 1); 1419*cdf0e10cSrcweir offset = GetUInt32(table, 8 + i * 8, 1); 1420*cdf0e10cSrcweir 1421*cdf0e10cSrcweir /* sanity check, cmap must lie within file */ 1422*cdf0e10cSrcweir if( (table - ttf->ptr) + offset > (sal_uInt32)ttf->fsize ) 1423*cdf0e10cSrcweir continue; 1424*cdf0e10cSrcweir 1425*cdf0e10cSrcweir /* Unicode tables in Apple fonts */ 1426*cdf0e10cSrcweir if (pID == 0) { 1427*cdf0e10cSrcweir AppleUni = offset; 1428*cdf0e10cSrcweir } 1429*cdf0e10cSrcweir 1430*cdf0e10cSrcweir if (pID == 3) { 1431*cdf0e10cSrcweir switch (eID) { 1432*cdf0e10cSrcweir case 0: ThreeZero = offset; break; 1433*cdf0e10cSrcweir case 10: // UCS-4 1434*cdf0e10cSrcweir case 1: ThreeOne = offset; break; 1435*cdf0e10cSrcweir case 2: ThreeTwo = offset; break; 1436*cdf0e10cSrcweir case 3: ThreeThree = offset; break; 1437*cdf0e10cSrcweir case 4: ThreeFour = offset; break; 1438*cdf0e10cSrcweir case 5: ThreeFive = offset; break; 1439*cdf0e10cSrcweir case 6: ThreeSix = offset; break; 1440*cdf0e10cSrcweir } 1441*cdf0e10cSrcweir } 1442*cdf0e10cSrcweir } 1443*cdf0e10cSrcweir 1444*cdf0e10cSrcweir // fall back to AppleUnicode if there are no ThreeOne/Threezero tables 1445*cdf0e10cSrcweir if( AppleUni && !ThreeZero && !ThreeOne) 1446*cdf0e10cSrcweir ThreeOne = AppleUni; 1447*cdf0e10cSrcweir 1448*cdf0e10cSrcweir if (ThreeOne) { 1449*cdf0e10cSrcweir ttf->cmapType = CMAP_MS_Unicode; 1450*cdf0e10cSrcweir ttf->cmap = table + ThreeOne; 1451*cdf0e10cSrcweir } else if (ThreeTwo) { 1452*cdf0e10cSrcweir ttf->cmapType = CMAP_MS_ShiftJIS; 1453*cdf0e10cSrcweir ttf->cmap = table + ThreeTwo; 1454*cdf0e10cSrcweir } else if (ThreeThree) { 1455*cdf0e10cSrcweir ttf->cmapType = CMAP_MS_Big5; 1456*cdf0e10cSrcweir ttf->cmap = table + ThreeThree; 1457*cdf0e10cSrcweir } else if (ThreeFour) { 1458*cdf0e10cSrcweir ttf->cmapType = CMAP_MS_PRC; 1459*cdf0e10cSrcweir ttf->cmap = table + ThreeFour; 1460*cdf0e10cSrcweir } else if (ThreeFive) { 1461*cdf0e10cSrcweir ttf->cmapType = CMAP_MS_Wansung; 1462*cdf0e10cSrcweir ttf->cmap = table + ThreeFive; 1463*cdf0e10cSrcweir } else if (ThreeSix) { 1464*cdf0e10cSrcweir ttf->cmapType = CMAP_MS_Johab; 1465*cdf0e10cSrcweir ttf->cmap = table + ThreeSix; 1466*cdf0e10cSrcweir } else if (ThreeZero) { 1467*cdf0e10cSrcweir ttf->cmapType = CMAP_MS_Symbol; 1468*cdf0e10cSrcweir ttf->cmap = table + ThreeZero; 1469*cdf0e10cSrcweir } else { 1470*cdf0e10cSrcweir ttf->cmapType = CMAP_NOT_USABLE; 1471*cdf0e10cSrcweir ttf->cmap = 0; 1472*cdf0e10cSrcweir } 1473*cdf0e10cSrcweir 1474*cdf0e10cSrcweir if (ttf->cmapType != CMAP_NOT_USABLE) { 1475*cdf0e10cSrcweir switch (GetUInt16(ttf->cmap, 0, 1)) { 1476*cdf0e10cSrcweir case 0: ttf->mapper = getGlyph0; break; 1477*cdf0e10cSrcweir case 2: ttf->mapper = getGlyph2; break; 1478*cdf0e10cSrcweir case 4: ttf->mapper = getGlyph4; break; 1479*cdf0e10cSrcweir case 6: ttf->mapper = getGlyph6; break; 1480*cdf0e10cSrcweir case 12: ttf->mapper= getGlyph12; break; 1481*cdf0e10cSrcweir default: 1482*cdf0e10cSrcweir #if OSL_DEBUG_LEVEL > 1 1483*cdf0e10cSrcweir /*- if the cmap table is really broken */ 1484*cdf0e10cSrcweir printf("%s: %d is not a recognized cmap format.\n", ttf->fname, GetUInt16(ttf->cmap, 0, 1)); 1485*cdf0e10cSrcweir #endif 1486*cdf0e10cSrcweir ttf->cmapType = CMAP_NOT_USABLE; 1487*cdf0e10cSrcweir ttf->cmap = 0; 1488*cdf0e10cSrcweir ttf->mapper = 0; 1489*cdf0e10cSrcweir } 1490*cdf0e10cSrcweir } 1491*cdf0e10cSrcweir } 1492*cdf0e10cSrcweir 1493*cdf0e10cSrcweir static void GetKern(TrueTypeFont *ttf) 1494*cdf0e10cSrcweir { 1495*cdf0e10cSrcweir const sal_uInt8* table = getTable(ttf, O_kern); 1496*cdf0e10cSrcweir const sal_uInt8 *ptr; 1497*cdf0e10cSrcweir 1498*cdf0e10cSrcweir if( !table ) 1499*cdf0e10cSrcweir goto badtable; 1500*cdf0e10cSrcweir 1501*cdf0e10cSrcweir if (GetUInt16(table, 0, 1) == 0) { /* Traditional Microsoft style table with sal_uInt16 version and nTables fields */ 1502*cdf0e10cSrcweir ttf->nkern = GetUInt16(table, 2, 1); 1503*cdf0e10cSrcweir ttf->kerntables = (const sal_uInt8**)calloc(ttf->nkern, sizeof(sal_uInt8 *)); 1504*cdf0e10cSrcweir assert(ttf->kerntables != 0); 1505*cdf0e10cSrcweir memset(ttf->kerntables, 0, ttf->nkern * sizeof(sal_uInt8 *)); 1506*cdf0e10cSrcweir ttf->kerntype = KT_MICROSOFT; 1507*cdf0e10cSrcweir ptr = table + 4; 1508*cdf0e10cSrcweir for( unsigned i = 0; i < ttf->nkern; ++i) { 1509*cdf0e10cSrcweir ttf->kerntables[i] = ptr; 1510*cdf0e10cSrcweir ptr += GetUInt16(ptr, 2, 1); 1511*cdf0e10cSrcweir /* sanity check */ 1512*cdf0e10cSrcweir if( ptr > ttf->ptr+ttf->fsize ) 1513*cdf0e10cSrcweir { 1514*cdf0e10cSrcweir free( ttf->kerntables ); 1515*cdf0e10cSrcweir goto badtable; 1516*cdf0e10cSrcweir } 1517*cdf0e10cSrcweir } 1518*cdf0e10cSrcweir return; 1519*cdf0e10cSrcweir } 1520*cdf0e10cSrcweir 1521*cdf0e10cSrcweir if (GetUInt32(table, 0, 1) == 0x00010000) { /* MacOS style kern tables: fixed32 version and sal_uInt32 nTables fields */ 1522*cdf0e10cSrcweir ttf->nkern = GetUInt32(table, 4, 1); 1523*cdf0e10cSrcweir ttf->kerntables = (const sal_uInt8**)calloc(ttf->nkern, sizeof(sal_uInt8*)); 1524*cdf0e10cSrcweir assert(ttf->kerntables != 0); 1525*cdf0e10cSrcweir memset(ttf->kerntables, 0, ttf->nkern * sizeof(sal_uInt8 *)); 1526*cdf0e10cSrcweir ttf->kerntype = KT_APPLE_NEW; 1527*cdf0e10cSrcweir ptr = table + 8; 1528*cdf0e10cSrcweir for( unsigned i = 0; i < ttf->nkern; ++i) { 1529*cdf0e10cSrcweir ttf->kerntables[i] = ptr; 1530*cdf0e10cSrcweir ptr += GetUInt32(ptr, 0, 1); 1531*cdf0e10cSrcweir /* sanity check; there are some fonts that are broken in this regard */ 1532*cdf0e10cSrcweir if( ptr > ttf->ptr+ttf->fsize ) 1533*cdf0e10cSrcweir { 1534*cdf0e10cSrcweir free( ttf->kerntables ); 1535*cdf0e10cSrcweir goto badtable; 1536*cdf0e10cSrcweir } 1537*cdf0e10cSrcweir } 1538*cdf0e10cSrcweir return; 1539*cdf0e10cSrcweir } 1540*cdf0e10cSrcweir 1541*cdf0e10cSrcweir badtable: 1542*cdf0e10cSrcweir ttf->kerntype = KT_NONE; 1543*cdf0e10cSrcweir ttf->kerntables = 0; 1544*cdf0e10cSrcweir 1545*cdf0e10cSrcweir return; 1546*cdf0e10cSrcweir } 1547*cdf0e10cSrcweir 1548*cdf0e10cSrcweir #ifdef TEST5 1549*cdf0e10cSrcweir /* KernGlyphsPrim?() functions expect the caller to ensure the validity of their arguments and 1550*cdf0e10cSrcweir * that x and y elements of the kern array are initialized to zeroes 1551*cdf0e10cSrcweir */ 1552*cdf0e10cSrcweir static void KernGlyphsPrim1(TrueTypeFont *ttf, sal_uInt16 *glyphs, int nglyphs, int wmode, KernData *kern) 1553*cdf0e10cSrcweir { 1554*cdf0e10cSrcweir (void)ttf; /* avoid warning */ 1555*cdf0e10cSrcweir (void)glyphs; /* avoid warning */ 1556*cdf0e10cSrcweir (void)nglyphs; /* avoid warning */ 1557*cdf0e10cSrcweir (void)wmode; /* avoid warning */ 1558*cdf0e10cSrcweir (void)nglyphs; /* avoid warning */ 1559*cdf0e10cSrcweir (void)kern; /* avoid warning */ 1560*cdf0e10cSrcweir fprintf(stderr, "MacOS kerning tables have not been implemented yet!\n"); 1561*cdf0e10cSrcweir } 1562*cdf0e10cSrcweir 1563*cdf0e10cSrcweir static void KernGlyphsPrim2(TrueTypeFont *ttf, sal_uInt16 *glyphs, int nglyphs, int wmode, KernData *kern) 1564*cdf0e10cSrcweir { 1565*cdf0e10cSrcweir sal_uInt32 i, j; 1566*cdf0e10cSrcweir sal_uInt32 gpair; 1567*cdf0e10cSrcweir 1568*cdf0e10cSrcweir if( ! nglyphs ) 1569*cdf0e10cSrcweir return; 1570*cdf0e10cSrcweir 1571*cdf0e10cSrcweir for (i = 0; i < (sal_uInt32)nglyphs - 1; i++) { 1572*cdf0e10cSrcweir gpair = (glyphs[i] << 16) | glyphs[i+1]; 1573*cdf0e10cSrcweir #ifdef DEBUG2 1574*cdf0e10cSrcweir /* All fonts with MS kern table that I've seen so far contain just one kern subtable. 1575*cdf0e10cSrcweir * MS kern documentation is very poor and I doubt that font developers will be using 1576*cdf0e10cSrcweir * several subtables. I expect them to be using OpenType tables instead. 1577*cdf0e10cSrcweir * According to MS documention, format 2 subtables are not supported by Windows and OS/2. 1578*cdf0e10cSrcweir */ 1579*cdf0e10cSrcweir if (ttf->nkern > 1) { 1580*cdf0e10cSrcweir fprintf(stderr, "KernGlyphsPrim2: %d kern tables found.\n", ttf->nkern); 1581*cdf0e10cSrcweir } 1582*cdf0e10cSrcweir #endif 1583*cdf0e10cSrcweir for (j = 0; j < ttf->nkern; j++) { 1584*cdf0e10cSrcweir sal_uInt16 coverage = GetUInt16(ttf->kerntables[j], 4, 1); 1585*cdf0e10cSrcweir sal_uInt8 *ptr; 1586*cdf0e10cSrcweir int npairs; 1587*cdf0e10cSrcweir sal_uInt32 t; 1588*cdf0e10cSrcweir int l, r, k; 1589*cdf0e10cSrcweir 1590*cdf0e10cSrcweir if (! ((coverage & 1) ^ wmode)) continue; 1591*cdf0e10cSrcweir if ((coverage & 0xFFFE) != 0) { 1592*cdf0e10cSrcweir #ifdef DEBUG2 1593*cdf0e10cSrcweir fprintf(stderr, "KernGlyphsPrim2: coverage flags are not supported: %04X.\n", coverage); 1594*cdf0e10cSrcweir #endif 1595*cdf0e10cSrcweir continue; 1596*cdf0e10cSrcweir } 1597*cdf0e10cSrcweir ptr = ttf->kerntables[j]; 1598*cdf0e10cSrcweir npairs = GetUInt16(ptr, 6, 1); 1599*cdf0e10cSrcweir ptr += 14; 1600*cdf0e10cSrcweir l = 0; 1601*cdf0e10cSrcweir r = npairs; 1602*cdf0e10cSrcweir do { 1603*cdf0e10cSrcweir k = (l + r) >> 1; 1604*cdf0e10cSrcweir t = GetUInt32(ptr, k * 6, 1); 1605*cdf0e10cSrcweir if (gpair >= t) l = k + 1; 1606*cdf0e10cSrcweir if (gpair <= t) r = k - 1; 1607*cdf0e10cSrcweir } while (l <= r); 1608*cdf0e10cSrcweir if (l - r == 2) { 1609*cdf0e10cSrcweir if (!wmode) { 1610*cdf0e10cSrcweir kern[i].x = XUnits(ttf->unitsPerEm, GetInt16(ptr, 4 + (l-1) * 6, 1)); 1611*cdf0e10cSrcweir } else { 1612*cdf0e10cSrcweir kern[i].y = XUnits(ttf->unitsPerEm, GetInt16(ptr, 4 + (l-1) * 6, 1)); 1613*cdf0e10cSrcweir } 1614*cdf0e10cSrcweir /* !wmode ? kern[i].x : kern[i].y = GetInt16(ptr, 4 + (l-1) * 6, 1); */ 1615*cdf0e10cSrcweir } 1616*cdf0e10cSrcweir } 1617*cdf0e10cSrcweir } 1618*cdf0e10cSrcweir } 1619*cdf0e10cSrcweir #endif 1620*cdf0e10cSrcweir 1621*cdf0e10cSrcweir /*- Public functions */ /*FOLD00*/ 1622*cdf0e10cSrcweir 1623*cdf0e10cSrcweir int CountTTCFonts(const char* fname) 1624*cdf0e10cSrcweir { 1625*cdf0e10cSrcweir int nFonts = 0; 1626*cdf0e10cSrcweir sal_uInt8 buffer[12]; 1627*cdf0e10cSrcweir FILE* fd = fopen(fname, "rb"); 1628*cdf0e10cSrcweir if( fd ) { 1629*cdf0e10cSrcweir if (fread(buffer, 1, 12, fd) == 12) { 1630*cdf0e10cSrcweir if(GetUInt32(buffer, 0, 1) == T_ttcf ) 1631*cdf0e10cSrcweir nFonts = GetUInt32(buffer, 8, 1); 1632*cdf0e10cSrcweir } 1633*cdf0e10cSrcweir fclose(fd); 1634*cdf0e10cSrcweir } 1635*cdf0e10cSrcweir return nFonts; 1636*cdf0e10cSrcweir } 1637*cdf0e10cSrcweir 1638*cdf0e10cSrcweir static void allocTrueTypeFont( TrueTypeFont** ttf ) 1639*cdf0e10cSrcweir { 1640*cdf0e10cSrcweir *ttf = (TrueTypeFont*)calloc(1,sizeof(TrueTypeFont)); 1641*cdf0e10cSrcweir if( *ttf != NULL ) 1642*cdf0e10cSrcweir { 1643*cdf0e10cSrcweir (*ttf)->tag = 0; 1644*cdf0e10cSrcweir (*ttf)->fname = 0; 1645*cdf0e10cSrcweir (*ttf)->fsize = -1; 1646*cdf0e10cSrcweir (*ttf)->ptr = 0; 1647*cdf0e10cSrcweir (*ttf)->nglyphs = 0xFFFFFFFF; 1648*cdf0e10cSrcweir (*ttf)->pGSubstitution = 0; 1649*cdf0e10cSrcweir } 1650*cdf0e10cSrcweir } 1651*cdf0e10cSrcweir 1652*cdf0e10cSrcweir /* forward declariotn for the two entry points to use*/ 1653*cdf0e10cSrcweir static int doOpenTTFont( sal_uInt32 facenum, TrueTypeFont* t ); 1654*cdf0e10cSrcweir 1655*cdf0e10cSrcweir #if !defined(WIN32) && !defined(OS2) 1656*cdf0e10cSrcweir int OpenTTFontFile( const char* fname, sal_uInt32 facenum, TrueTypeFont** ttf ) 1657*cdf0e10cSrcweir { 1658*cdf0e10cSrcweir int ret, fd = -1; 1659*cdf0e10cSrcweir struct stat st; 1660*cdf0e10cSrcweir 1661*cdf0e10cSrcweir if (!fname || !*fname) return SF_BADFILE; 1662*cdf0e10cSrcweir 1663*cdf0e10cSrcweir allocTrueTypeFont( ttf ); 1664*cdf0e10cSrcweir if( ! *ttf ) 1665*cdf0e10cSrcweir return SF_MEMORY; 1666*cdf0e10cSrcweir 1667*cdf0e10cSrcweir (*ttf)->fname = strdup(fname); 1668*cdf0e10cSrcweir if( ! (*ttf)->fname ) 1669*cdf0e10cSrcweir { 1670*cdf0e10cSrcweir ret = SF_MEMORY; 1671*cdf0e10cSrcweir goto cleanup; 1672*cdf0e10cSrcweir } 1673*cdf0e10cSrcweir 1674*cdf0e10cSrcweir fd = open(fname, O_RDONLY); 1675*cdf0e10cSrcweir 1676*cdf0e10cSrcweir if (fd == -1) { 1677*cdf0e10cSrcweir ret = SF_BADFILE; 1678*cdf0e10cSrcweir goto cleanup; 1679*cdf0e10cSrcweir } 1680*cdf0e10cSrcweir 1681*cdf0e10cSrcweir if (fstat(fd, &st) == -1) { 1682*cdf0e10cSrcweir ret = SF_FILEIO; 1683*cdf0e10cSrcweir goto cleanup; 1684*cdf0e10cSrcweir } 1685*cdf0e10cSrcweir 1686*cdf0e10cSrcweir (*ttf)->fsize = st.st_size; 1687*cdf0e10cSrcweir 1688*cdf0e10cSrcweir /* On Mac OS, most likely will happen if a Mac user renames a font file 1689*cdf0e10cSrcweir * to be .ttf when its really a Mac resource-based font. 1690*cdf0e10cSrcweir * Size will be 0, but fonts smaller than 4 bytes would be broken anyway. 1691*cdf0e10cSrcweir */ 1692*cdf0e10cSrcweir if ((*ttf)->fsize == 0) { 1693*cdf0e10cSrcweir ret = SF_BADFILE; 1694*cdf0e10cSrcweir goto cleanup; 1695*cdf0e10cSrcweir } 1696*cdf0e10cSrcweir 1697*cdf0e10cSrcweir if (((*ttf)->ptr = (sal_uInt8 *) mmap(0, (*ttf)->fsize, PROT_READ, MAP_SHARED, fd, 0)) == MAP_FAILED) { 1698*cdf0e10cSrcweir ret = SF_MEMORY; 1699*cdf0e10cSrcweir goto cleanup; 1700*cdf0e10cSrcweir } 1701*cdf0e10cSrcweir close(fd); 1702*cdf0e10cSrcweir 1703*cdf0e10cSrcweir return doOpenTTFont( facenum, *ttf ); 1704*cdf0e10cSrcweir 1705*cdf0e10cSrcweir cleanup: 1706*cdf0e10cSrcweir if (fd != -1) close(fd); 1707*cdf0e10cSrcweir /*- t and t->fname have been allocated! */ 1708*cdf0e10cSrcweir free((*ttf)->fname); 1709*cdf0e10cSrcweir free(*ttf); 1710*cdf0e10cSrcweir *ttf = NULL; 1711*cdf0e10cSrcweir return ret; 1712*cdf0e10cSrcweir } 1713*cdf0e10cSrcweir #endif 1714*cdf0e10cSrcweir 1715*cdf0e10cSrcweir int OpenTTFontBuffer(void* pBuffer, sal_uInt32 nLen, sal_uInt32 facenum, TrueTypeFont** ttf) 1716*cdf0e10cSrcweir { 1717*cdf0e10cSrcweir allocTrueTypeFont( ttf ); 1718*cdf0e10cSrcweir if( *ttf == NULL ) 1719*cdf0e10cSrcweir return SF_MEMORY; 1720*cdf0e10cSrcweir 1721*cdf0e10cSrcweir (*ttf)->fname = NULL; 1722*cdf0e10cSrcweir (*ttf)->fsize = nLen; 1723*cdf0e10cSrcweir (*ttf)->ptr = (sal_uInt8*)pBuffer; 1724*cdf0e10cSrcweir 1725*cdf0e10cSrcweir return doOpenTTFont( facenum, *ttf ); 1726*cdf0e10cSrcweir } 1727*cdf0e10cSrcweir 1728*cdf0e10cSrcweir static int doOpenTTFont( sal_uInt32 facenum, TrueTypeFont* t ) 1729*cdf0e10cSrcweir { 1730*cdf0e10cSrcweir int i; 1731*cdf0e10cSrcweir sal_uInt32 length, tag; 1732*cdf0e10cSrcweir sal_uInt32 tdoffset = 0; /* offset to TableDirectory in a TTC file. For TTF files is 0 */ 1733*cdf0e10cSrcweir int indexfmt, k; 1734*cdf0e10cSrcweir 1735*cdf0e10cSrcweir sal_uInt32 version = GetInt32(t->ptr, 0, 1); 1736*cdf0e10cSrcweir 1737*cdf0e10cSrcweir if ((version == 0x00010000) || (version == T_true)) { 1738*cdf0e10cSrcweir tdoffset = 0; 1739*cdf0e10cSrcweir } else if (version == T_otto) { /* PS-OpenType font */ 1740*cdf0e10cSrcweir tdoffset = 0; 1741*cdf0e10cSrcweir } else if (version == T_ttcf) { /* TrueType collection */ 1742*cdf0e10cSrcweir if (GetUInt32(t->ptr, 4, 1) != 0x00010000) { 1743*cdf0e10cSrcweir CloseTTFont(t); 1744*cdf0e10cSrcweir return SF_TTFORMAT; 1745*cdf0e10cSrcweir } 1746*cdf0e10cSrcweir if (facenum >= GetUInt32(t->ptr, 8, 1)) { 1747*cdf0e10cSrcweir CloseTTFont(t); 1748*cdf0e10cSrcweir return SF_FONTNO; 1749*cdf0e10cSrcweir } 1750*cdf0e10cSrcweir tdoffset = GetUInt32(t->ptr, 12 + 4 * facenum, 1); 1751*cdf0e10cSrcweir } else { 1752*cdf0e10cSrcweir CloseTTFont(t); 1753*cdf0e10cSrcweir return SF_TTFORMAT; 1754*cdf0e10cSrcweir } 1755*cdf0e10cSrcweir 1756*cdf0e10cSrcweir #ifdef DEBUG2 1757*cdf0e10cSrcweir fprintf(stderr, "tdoffset: %d\n", tdoffset); 1758*cdf0e10cSrcweir #endif 1759*cdf0e10cSrcweir 1760*cdf0e10cSrcweir /* magic number */ 1761*cdf0e10cSrcweir t->tag = TTFontClassTag; 1762*cdf0e10cSrcweir 1763*cdf0e10cSrcweir t->ntables = GetUInt16(t->ptr + tdoffset, 4, 1); 1764*cdf0e10cSrcweir if( t->ntables >= 128 ) 1765*cdf0e10cSrcweir return SF_TTFORMAT; 1766*cdf0e10cSrcweir 1767*cdf0e10cSrcweir t->tables = (const sal_uInt8**)calloc(NUM_TAGS, sizeof(sal_uInt8*)); 1768*cdf0e10cSrcweir assert(t->tables != 0); 1769*cdf0e10cSrcweir t->tlens = (sal_uInt32*)calloc(NUM_TAGS, sizeof(sal_uInt32)); 1770*cdf0e10cSrcweir assert(t->tlens != 0); 1771*cdf0e10cSrcweir 1772*cdf0e10cSrcweir memset(t->tables, 0, NUM_TAGS * sizeof(void *)); 1773*cdf0e10cSrcweir memset(t->tlens, 0, NUM_TAGS * sizeof(sal_uInt32)); 1774*cdf0e10cSrcweir 1775*cdf0e10cSrcweir /* parse the tables */ 1776*cdf0e10cSrcweir for (i=0; i<(int)t->ntables; i++) { 1777*cdf0e10cSrcweir int nIndex; 1778*cdf0e10cSrcweir tag = GetUInt32(t->ptr + tdoffset + 12, 16 * i, 1); 1779*cdf0e10cSrcweir switch( tag ) { 1780*cdf0e10cSrcweir case T_maxp: nIndex = O_maxp; break; 1781*cdf0e10cSrcweir case T_glyf: nIndex = O_glyf; break; 1782*cdf0e10cSrcweir case T_head: nIndex = O_head; break; 1783*cdf0e10cSrcweir case T_loca: nIndex = O_loca; break; 1784*cdf0e10cSrcweir case T_name: nIndex = O_name; break; 1785*cdf0e10cSrcweir case T_hhea: nIndex = O_hhea; break; 1786*cdf0e10cSrcweir case T_hmtx: nIndex = O_hmtx; break; 1787*cdf0e10cSrcweir case T_cmap: nIndex = O_cmap; break; 1788*cdf0e10cSrcweir case T_vhea: nIndex = O_vhea; break; 1789*cdf0e10cSrcweir case T_vmtx: nIndex = O_vmtx; break; 1790*cdf0e10cSrcweir case T_OS2 : nIndex = O_OS2; break; 1791*cdf0e10cSrcweir case T_post: nIndex = O_post; break; 1792*cdf0e10cSrcweir case T_kern: nIndex = O_kern; break; 1793*cdf0e10cSrcweir case T_cvt : nIndex = O_cvt; break; 1794*cdf0e10cSrcweir case T_prep: nIndex = O_prep; break; 1795*cdf0e10cSrcweir case T_fpgm: nIndex = O_fpgm; break; 1796*cdf0e10cSrcweir case T_gsub: nIndex = O_gsub; break; 1797*cdf0e10cSrcweir case T_CFF: nIndex = O_CFF; break; 1798*cdf0e10cSrcweir default: nIndex = -1; break; 1799*cdf0e10cSrcweir } 1800*cdf0e10cSrcweir if( nIndex >= 0 ) { 1801*cdf0e10cSrcweir sal_uInt32 nTableOffset = GetUInt32(t->ptr + tdoffset + 12, 16 * i + 8, 1); 1802*cdf0e10cSrcweir length = GetUInt32(t->ptr + tdoffset + 12, 16 * i + 12, 1); 1803*cdf0e10cSrcweir t->tables[nIndex] = t->ptr + nTableOffset; 1804*cdf0e10cSrcweir t->tlens[nIndex] = length; 1805*cdf0e10cSrcweir } 1806*cdf0e10cSrcweir } 1807*cdf0e10cSrcweir 1808*cdf0e10cSrcweir /* Fixup offsets when only a TTC extract was provided */ 1809*cdf0e10cSrcweir if( facenum == (sal_uInt32)~0 ) { 1810*cdf0e10cSrcweir sal_uInt8* pHead = (sal_uInt8*)t->tables[O_head]; 1811*cdf0e10cSrcweir if( !pHead ) 1812*cdf0e10cSrcweir return SF_TTFORMAT; 1813*cdf0e10cSrcweir /* limit Head candidate to TTC extract's limits */ 1814*cdf0e10cSrcweir if( pHead > t->ptr + (t->fsize - 54) ) 1815*cdf0e10cSrcweir pHead = t->ptr + (t->fsize - 54); 1816*cdf0e10cSrcweir /* TODO: find better method than searching head table's magic */ 1817*cdf0e10cSrcweir sal_uInt8* p = NULL; 1818*cdf0e10cSrcweir for( p = pHead + 12; p > t->ptr; --p ) { 1819*cdf0e10cSrcweir if( p[0]==0x5F && p[1]==0x0F && p[2]==0x3C && p[3]==0xF5 ) { 1820*cdf0e10cSrcweir int nDelta = (pHead + 12) - p, j; 1821*cdf0e10cSrcweir if( nDelta ) 1822*cdf0e10cSrcweir for( j=0; j<NUM_TAGS; ++j ) 1823*cdf0e10cSrcweir if( t->tables[j] ) 1824*cdf0e10cSrcweir *(char**)&t->tables[j] -= nDelta; 1825*cdf0e10cSrcweir break; 1826*cdf0e10cSrcweir } 1827*cdf0e10cSrcweir } 1828*cdf0e10cSrcweir if( p <= t->ptr ) 1829*cdf0e10cSrcweir return SF_TTFORMAT; 1830*cdf0e10cSrcweir } 1831*cdf0e10cSrcweir 1832*cdf0e10cSrcweir /* Check the table offsets after TTC correction */ 1833*cdf0e10cSrcweir for (i=0; i<NUM_TAGS; i++) { 1834*cdf0e10cSrcweir /* sanity check: table must lay completely within the file 1835*cdf0e10cSrcweir * at this point one could check the checksum of all contained 1836*cdf0e10cSrcweir * tables, but this would be quite time intensive. 1837*cdf0e10cSrcweir * Try to fix tables, so we can cope with minor problems. 1838*cdf0e10cSrcweir */ 1839*cdf0e10cSrcweir 1840*cdf0e10cSrcweir if( (sal_uInt8*)t->tables[i] < t->ptr ) 1841*cdf0e10cSrcweir { 1842*cdf0e10cSrcweir #if OSL_DEBUG_LEVEL > 1 1843*cdf0e10cSrcweir if( t->tables[i] ) 1844*cdf0e10cSrcweir fprintf( stderr, "font file %s has bad table offset %d (tagnum=%d)\n", t->fname, (sal_uInt8*)t->tables[i]-t->ptr, i ); 1845*cdf0e10cSrcweir #endif 1846*cdf0e10cSrcweir t->tlens[i] = 0; 1847*cdf0e10cSrcweir t->tables[i] = NULL; 1848*cdf0e10cSrcweir } 1849*cdf0e10cSrcweir else if( (sal_uInt8*)t->tables[i] + t->tlens[i] > t->ptr + t->fsize ) 1850*cdf0e10cSrcweir { 1851*cdf0e10cSrcweir int nMaxLen = (t->ptr + t->fsize) - (sal_uInt8*)t->tables[i]; 1852*cdf0e10cSrcweir if( nMaxLen < 0 ) 1853*cdf0e10cSrcweir nMaxLen = 0; 1854*cdf0e10cSrcweir t->tlens[i] = nMaxLen; 1855*cdf0e10cSrcweir #if OSL_DEBUG_LEVEL > 1 1856*cdf0e10cSrcweir fprintf( stderr, "font file %s has too big table (tagnum=%d)\n", t->fname, i ); 1857*cdf0e10cSrcweir #endif 1858*cdf0e10cSrcweir } 1859*cdf0e10cSrcweir } 1860*cdf0e10cSrcweir 1861*cdf0e10cSrcweir /* At this point TrueTypeFont is constructed, now need to verify the font format 1862*cdf0e10cSrcweir and read the basic font properties */ 1863*cdf0e10cSrcweir 1864*cdf0e10cSrcweir /* The following tables are absolutely required: 1865*cdf0e10cSrcweir * maxp, head, name, cmap 1866*cdf0e10cSrcweir */ 1867*cdf0e10cSrcweir 1868*cdf0e10cSrcweir if( !(getTable(t, O_maxp) && getTable(t, O_head) && getTable(t, O_name) && getTable(t, O_cmap)) ) { 1869*cdf0e10cSrcweir CloseTTFont(t); 1870*cdf0e10cSrcweir return SF_TTFORMAT; 1871*cdf0e10cSrcweir } 1872*cdf0e10cSrcweir 1873*cdf0e10cSrcweir const sal_uInt8* table = getTable(t, O_maxp); 1874*cdf0e10cSrcweir t->nglyphs = GetUInt16(table, 4, 1); 1875*cdf0e10cSrcweir 1876*cdf0e10cSrcweir table = getTable(t, O_head); 1877*cdf0e10cSrcweir t->unitsPerEm = GetUInt16(table, 18, 1); 1878*cdf0e10cSrcweir indexfmt = GetInt16(table, 50, 1); 1879*cdf0e10cSrcweir 1880*cdf0e10cSrcweir if( ((indexfmt != 0) && (indexfmt != 1)) || (t->unitsPerEm <= 0) ) { 1881*cdf0e10cSrcweir CloseTTFont(t); 1882*cdf0e10cSrcweir return SF_TTFORMAT; 1883*cdf0e10cSrcweir } 1884*cdf0e10cSrcweir 1885*cdf0e10cSrcweir if( getTable(t, O_glyf) && getTable(t, O_loca) ) { /* TTF or TTF-OpenType */ 1886*cdf0e10cSrcweir k = (getTableSize(t, O_loca) / (indexfmt ? 4 : 2)) - 1; 1887*cdf0e10cSrcweir if( k < (int)t->nglyphs ) /* Hack for broken Chinese fonts */ 1888*cdf0e10cSrcweir t->nglyphs = k; 1889*cdf0e10cSrcweir 1890*cdf0e10cSrcweir table = getTable(t, O_loca); 1891*cdf0e10cSrcweir t->goffsets = (sal_uInt32 *) calloc(1+t->nglyphs, sizeof(sal_uInt32)); 1892*cdf0e10cSrcweir assert(t->goffsets != 0); 1893*cdf0e10cSrcweir 1894*cdf0e10cSrcweir for( i = 0; i <= (int)t->nglyphs; ++i ) 1895*cdf0e10cSrcweir t->goffsets[i] = indexfmt ? GetUInt32(table, i << 2, 1) : (sal_uInt32)GetUInt16(table, i << 1, 1) << 1; 1896*cdf0e10cSrcweir } else if( getTable(t, O_CFF) ) { /* PS-OpenType */ 1897*cdf0e10cSrcweir t->goffsets = (sal_uInt32 *) calloc(1+t->nglyphs, sizeof(sal_uInt32)); 1898*cdf0e10cSrcweir /* TODO: implement to get subsetting */ 1899*cdf0e10cSrcweir assert(t->goffsets != 0); 1900*cdf0e10cSrcweir } else { 1901*cdf0e10cSrcweir CloseTTFont(t); 1902*cdf0e10cSrcweir return SF_TTFORMAT; 1903*cdf0e10cSrcweir } 1904*cdf0e10cSrcweir 1905*cdf0e10cSrcweir table = getTable(t, O_hhea); 1906*cdf0e10cSrcweir t->numberOfHMetrics = (table != 0) ? GetUInt16(table, 34, 1) : 0; 1907*cdf0e10cSrcweir 1908*cdf0e10cSrcweir table = getTable(t, O_vhea); 1909*cdf0e10cSrcweir t->numOfLongVerMetrics = (table != 0) ? GetUInt16(table, 34, 1) : 0; 1910*cdf0e10cSrcweir 1911*cdf0e10cSrcweir GetNames(t); 1912*cdf0e10cSrcweir FindCmap(t); 1913*cdf0e10cSrcweir GetKern(t); 1914*cdf0e10cSrcweir ReadGSUB( t, 0, 0 ); 1915*cdf0e10cSrcweir 1916*cdf0e10cSrcweir return SF_OK; 1917*cdf0e10cSrcweir } 1918*cdf0e10cSrcweir 1919*cdf0e10cSrcweir void CloseTTFont(TrueTypeFont *ttf) /*FOLD01*/ 1920*cdf0e10cSrcweir { 1921*cdf0e10cSrcweir if (ttf->tag != TTFontClassTag) return; 1922*cdf0e10cSrcweir 1923*cdf0e10cSrcweir #if !defined(WIN32) && !defined(OS2) 1924*cdf0e10cSrcweir if( ttf->fname ) 1925*cdf0e10cSrcweir munmap((char *) ttf->ptr, ttf->fsize); 1926*cdf0e10cSrcweir #endif 1927*cdf0e10cSrcweir free(ttf->fname); 1928*cdf0e10cSrcweir free(ttf->goffsets); 1929*cdf0e10cSrcweir free(ttf->psname); 1930*cdf0e10cSrcweir free(ttf->family); 1931*cdf0e10cSrcweir if( ttf->ufamily ) 1932*cdf0e10cSrcweir free( ttf->ufamily ); 1933*cdf0e10cSrcweir free(ttf->subfamily); 1934*cdf0e10cSrcweir if( ttf->usubfamily ) 1935*cdf0e10cSrcweir free( ttf->usubfamily ); 1936*cdf0e10cSrcweir free(ttf->tables); 1937*cdf0e10cSrcweir free(ttf->tlens); 1938*cdf0e10cSrcweir free(ttf->kerntables); 1939*cdf0e10cSrcweir 1940*cdf0e10cSrcweir ReleaseGSUB(ttf); 1941*cdf0e10cSrcweir 1942*cdf0e10cSrcweir free(ttf); 1943*cdf0e10cSrcweir return; 1944*cdf0e10cSrcweir } 1945*cdf0e10cSrcweir 1946*cdf0e10cSrcweir int GetTTGlyphPoints(TrueTypeFont *ttf, sal_uInt32 glyphID, ControlPoint **pointArray) 1947*cdf0e10cSrcweir { 1948*cdf0e10cSrcweir return GetTTGlyphOutline(ttf, glyphID, pointArray, 0, 0); 1949*cdf0e10cSrcweir } 1950*cdf0e10cSrcweir 1951*cdf0e10cSrcweir int GetTTGlyphComponents(TrueTypeFont *ttf, sal_uInt32 glyphID, std::vector< sal_uInt32 >& glyphlist) 1952*cdf0e10cSrcweir { 1953*cdf0e10cSrcweir int n = 1; 1954*cdf0e10cSrcweir 1955*cdf0e10cSrcweir if( glyphID >= ttf->nglyphs ) 1956*cdf0e10cSrcweir return 0; 1957*cdf0e10cSrcweir 1958*cdf0e10cSrcweir const sal_uInt8* glyf = getTable(ttf, O_glyf); 1959*cdf0e10cSrcweir const sal_uInt8* ptr = glyf + ttf->goffsets[glyphID]; 1960*cdf0e10cSrcweir 1961*cdf0e10cSrcweir glyphlist.push_back( glyphID ); 1962*cdf0e10cSrcweir 1963*cdf0e10cSrcweir if (GetInt16(ptr, 0, 1) == -1) { 1964*cdf0e10cSrcweir sal_uInt16 flags, index; 1965*cdf0e10cSrcweir ptr += 10; 1966*cdf0e10cSrcweir do { 1967*cdf0e10cSrcweir flags = GetUInt16(ptr, 0, 1); 1968*cdf0e10cSrcweir index = GetUInt16(ptr, 2, 1); 1969*cdf0e10cSrcweir 1970*cdf0e10cSrcweir ptr += 4; 1971*cdf0e10cSrcweir n += GetTTGlyphComponents(ttf, index, glyphlist); 1972*cdf0e10cSrcweir 1973*cdf0e10cSrcweir if (flags & ARG_1_AND_2_ARE_WORDS) { 1974*cdf0e10cSrcweir ptr += 4; 1975*cdf0e10cSrcweir } else { 1976*cdf0e10cSrcweir ptr += 2; 1977*cdf0e10cSrcweir } 1978*cdf0e10cSrcweir 1979*cdf0e10cSrcweir if (flags & WE_HAVE_A_SCALE) { 1980*cdf0e10cSrcweir ptr += 2; 1981*cdf0e10cSrcweir } else if (flags & WE_HAVE_AN_X_AND_Y_SCALE) { 1982*cdf0e10cSrcweir ptr += 4; 1983*cdf0e10cSrcweir } else if (flags & WE_HAVE_A_TWO_BY_TWO) { 1984*cdf0e10cSrcweir ptr += 8; 1985*cdf0e10cSrcweir } 1986*cdf0e10cSrcweir } while (flags & MORE_COMPONENTS); 1987*cdf0e10cSrcweir } 1988*cdf0e10cSrcweir 1989*cdf0e10cSrcweir return n; 1990*cdf0e10cSrcweir } 1991*cdf0e10cSrcweir 1992*cdf0e10cSrcweir #ifndef NO_TYPE3 1993*cdf0e10cSrcweir int CreateT3FromTTGlyphs(TrueTypeFont *ttf, FILE *outf, const char *fname, /*FOLD00*/ 1994*cdf0e10cSrcweir sal_uInt16 *glyphArray, sal_uInt8 *encoding, int nGlyphs, 1995*cdf0e10cSrcweir int wmode) 1996*cdf0e10cSrcweir { 1997*cdf0e10cSrcweir ControlPoint *pa; 1998*cdf0e10cSrcweir PSPathElement *path; 1999*cdf0e10cSrcweir int i, j, r, n; 2000*cdf0e10cSrcweir const sal_uInt8* table = getTable(ttf, O_head); 2001*cdf0e10cSrcweir TTGlyphMetrics metrics; 2002*cdf0e10cSrcweir int UPEm = ttf->unitsPerEm; 2003*cdf0e10cSrcweir 2004*cdf0e10cSrcweir const char *h01 = "%%!PS-AdobeFont-%d.%d-%d.%d\n"; 2005*cdf0e10cSrcweir const char *h02 = "%% Creator: %s %s %s\n"; 2006*cdf0e10cSrcweir const char *h09 = "%% Original font name: %s\n"; 2007*cdf0e10cSrcweir 2008*cdf0e10cSrcweir const char *h10 = 2009*cdf0e10cSrcweir "30 dict begin\n" 2010*cdf0e10cSrcweir "/PaintType 0 def\n" 2011*cdf0e10cSrcweir "/FontType 3 def\n" 2012*cdf0e10cSrcweir "/StrokeWidth 0 def\n"; 2013*cdf0e10cSrcweir 2014*cdf0e10cSrcweir const char *h11 = "/FontName (%s) cvn def\n"; 2015*cdf0e10cSrcweir 2016*cdf0e10cSrcweir /* 2017*cdf0e10cSrcweir const char *h12 = "%/UniqueID %d def\n"; 2018*cdf0e10cSrcweir */ 2019*cdf0e10cSrcweir const char *h13 = "/FontMatrix [.001 0 0 .001 0 0] def\n"; 2020*cdf0e10cSrcweir const char *h14 = "/FontBBox [%d %d %d %d] def\n"; 2021*cdf0e10cSrcweir 2022*cdf0e10cSrcweir const char *h15= 2023*cdf0e10cSrcweir "/Encoding 256 array def\n" 2024*cdf0e10cSrcweir " 0 1 255 {Encoding exch /.notdef put} for\n"; 2025*cdf0e10cSrcweir 2026*cdf0e10cSrcweir const char *h16 = " Encoding %d /glyph%d put\n"; 2027*cdf0e10cSrcweir const char *h17 = "/XUID [103 0 0 16#%08X %d 16#%08X 16#%08X] def\n"; 2028*cdf0e10cSrcweir 2029*cdf0e10cSrcweir const char *h30 = "/CharProcs %d dict def\n"; 2030*cdf0e10cSrcweir const char *h31 = " CharProcs begin\n"; 2031*cdf0e10cSrcweir const char *h32 = " /.notdef {} def\n"; 2032*cdf0e10cSrcweir const char *h33 = " /glyph%d {\n"; 2033*cdf0e10cSrcweir const char *h34 = " } bind def\n"; 2034*cdf0e10cSrcweir const char *h35 = " end\n"; 2035*cdf0e10cSrcweir 2036*cdf0e10cSrcweir const char *h40 = 2037*cdf0e10cSrcweir "/BuildGlyph {\n" 2038*cdf0e10cSrcweir " exch /CharProcs get exch\n" 2039*cdf0e10cSrcweir " 2 copy known not\n" 2040*cdf0e10cSrcweir " {pop /.notdef} if\n" 2041*cdf0e10cSrcweir " get exec\n" 2042*cdf0e10cSrcweir "} bind def\n" 2043*cdf0e10cSrcweir "/BuildChar {\n" 2044*cdf0e10cSrcweir " 1 index /Encoding get exch get\n" 2045*cdf0e10cSrcweir " 1 index /BuildGlyph get exec\n" 2046*cdf0e10cSrcweir "} bind def\n" 2047*cdf0e10cSrcweir "currentdict end\n"; 2048*cdf0e10cSrcweir 2049*cdf0e10cSrcweir const char *h41 = "(%s) cvn exch definefont pop\n"; 2050*cdf0e10cSrcweir 2051*cdf0e10cSrcweir 2052*cdf0e10cSrcweir if (!((nGlyphs > 0) && (nGlyphs <= 256))) return SF_GLYPHNUM; 2053*cdf0e10cSrcweir if (!glyphArray) return SF_BADARG; 2054*cdf0e10cSrcweir if (!fname) fname = ttf->psname; 2055*cdf0e10cSrcweir 2056*cdf0e10cSrcweir fprintf(outf, h01, GetInt16(table, 0, 1), GetUInt16(table, 2, 1), GetInt16(table, 4, 1), GetUInt16(table, 6, 1)); 2057*cdf0e10cSrcweir fprintf(outf, h02, modname, modver, modextra); 2058*cdf0e10cSrcweir fprintf(outf, h09, ttf->psname); 2059*cdf0e10cSrcweir 2060*cdf0e10cSrcweir fprintf(outf, h10); 2061*cdf0e10cSrcweir fprintf(outf, h11, fname); 2062*cdf0e10cSrcweir /* fprintf(outf, h12, 4000000); */ 2063*cdf0e10cSrcweir 2064*cdf0e10cSrcweir /* XUID generation: 2065*cdf0e10cSrcweir * 103 0 0 C1 C2 C3 C4 2066*cdf0e10cSrcweir * C1 - CRC-32 of the entire source TrueType font 2067*cdf0e10cSrcweir * C2 - number of glyphs in the subset 2068*cdf0e10cSrcweir * C3 - CRC-32 of the glyph array 2069*cdf0e10cSrcweir * C4 - CRC-32 of the encoding array 2070*cdf0e10cSrcweir * 2071*cdf0e10cSrcweir * All CRC-32 numbers are presented as hexadecimal numbers 2072*cdf0e10cSrcweir */ 2073*cdf0e10cSrcweir 2074*cdf0e10cSrcweir fprintf(outf, h17, rtl_crc32(0, ttf->ptr, ttf->fsize), nGlyphs, rtl_crc32(0, glyphArray, nGlyphs * 2), rtl_crc32(0, encoding, nGlyphs)); 2075*cdf0e10cSrcweir fprintf(outf, h13); 2076*cdf0e10cSrcweir fprintf(outf, h14, XUnits(UPEm, GetInt16(table, 36, 1)), XUnits(UPEm, GetInt16(table, 38, 1)), XUnits(UPEm, GetInt16(table, 40, 1)), XUnits(UPEm, GetInt16(table, 42, 1))); 2077*cdf0e10cSrcweir fprintf(outf, h15); 2078*cdf0e10cSrcweir 2079*cdf0e10cSrcweir for (i = 0; i < nGlyphs; i++) { 2080*cdf0e10cSrcweir fprintf(outf, h16, encoding[i], i); 2081*cdf0e10cSrcweir } 2082*cdf0e10cSrcweir 2083*cdf0e10cSrcweir fprintf(outf, h30, nGlyphs+1); 2084*cdf0e10cSrcweir fprintf(outf, h31); 2085*cdf0e10cSrcweir fprintf(outf, h32); 2086*cdf0e10cSrcweir 2087*cdf0e10cSrcweir for (i = 0; i < nGlyphs; i++) { 2088*cdf0e10cSrcweir fprintf(outf, h33, i); 2089*cdf0e10cSrcweir r = GetTTGlyphOutline(ttf, glyphArray[i] < ttf->nglyphs ? glyphArray[i] : 0, &pa, &metrics, 0); 2090*cdf0e10cSrcweir 2091*cdf0e10cSrcweir if (r > 0) { 2092*cdf0e10cSrcweir n = BSplineToPSPath(pa, r, &path); 2093*cdf0e10cSrcweir } else { 2094*cdf0e10cSrcweir n = 0; /* glyph might have zero contours but valid metrics ??? */ 2095*cdf0e10cSrcweir path = 0; 2096*cdf0e10cSrcweir if (r < 0) { /* glyph is not present in the font - pa array was not allocated, so no need to free it */ 2097*cdf0e10cSrcweir continue; 2098*cdf0e10cSrcweir } 2099*cdf0e10cSrcweir } 2100*cdf0e10cSrcweir fprintf(outf, "\t%d %d %d %d %d %d setcachedevice\n", 2101*cdf0e10cSrcweir wmode == 0 ? XUnits(UPEm, metrics.aw) : 0, 2102*cdf0e10cSrcweir wmode == 0 ? 0 : -XUnits(UPEm, metrics.ah), 2103*cdf0e10cSrcweir XUnits(UPEm, metrics.xMin), 2104*cdf0e10cSrcweir XUnits(UPEm, metrics.yMin), 2105*cdf0e10cSrcweir XUnits(UPEm, metrics.xMax), 2106*cdf0e10cSrcweir XUnits(UPEm, metrics.yMax)); 2107*cdf0e10cSrcweir 2108*cdf0e10cSrcweir for (j = 0; j < n; j++) 2109*cdf0e10cSrcweir { 2110*cdf0e10cSrcweir switch (path[j].type) 2111*cdf0e10cSrcweir { 2112*cdf0e10cSrcweir case PS_MOVETO: 2113*cdf0e10cSrcweir fprintf(outf, "\t%d %d moveto\n", XUnits(UPEm, path[j].x1), XUnits(UPEm, path[j].y1)); 2114*cdf0e10cSrcweir break; 2115*cdf0e10cSrcweir 2116*cdf0e10cSrcweir case PS_LINETO: 2117*cdf0e10cSrcweir fprintf(outf, "\t%d %d lineto\n", XUnits(UPEm, path[j].x1), XUnits(UPEm, path[j].y1)); 2118*cdf0e10cSrcweir break; 2119*cdf0e10cSrcweir 2120*cdf0e10cSrcweir case PS_CURVETO: 2121*cdf0e10cSrcweir fprintf(outf, "\t%d %d %d %d %d %d curveto\n", XUnits(UPEm, path[j].x1), XUnits(UPEm, path[j].y1), XUnits(UPEm, path[j].x2), XUnits(UPEm, path[j].y2), XUnits(UPEm, path[j].x3), XUnits(UPEm, path[j].y3)); 2122*cdf0e10cSrcweir break; 2123*cdf0e10cSrcweir 2124*cdf0e10cSrcweir case PS_CLOSEPATH: 2125*cdf0e10cSrcweir fprintf(outf, "\tclosepath\n"); 2126*cdf0e10cSrcweir break; 2127*cdf0e10cSrcweir case PS_NOOP: 2128*cdf0e10cSrcweir break; 2129*cdf0e10cSrcweir } 2130*cdf0e10cSrcweir } 2131*cdf0e10cSrcweir if (n > 0) fprintf(outf, "\tfill\n"); /* if glyph is not a whitespace character */ 2132*cdf0e10cSrcweir 2133*cdf0e10cSrcweir fprintf(outf, h34); 2134*cdf0e10cSrcweir 2135*cdf0e10cSrcweir free(pa); 2136*cdf0e10cSrcweir free(path); 2137*cdf0e10cSrcweir } 2138*cdf0e10cSrcweir fprintf(outf, h35); 2139*cdf0e10cSrcweir 2140*cdf0e10cSrcweir fprintf(outf, h40); 2141*cdf0e10cSrcweir fprintf(outf, h41, fname); 2142*cdf0e10cSrcweir 2143*cdf0e10cSrcweir return SF_OK; 2144*cdf0e10cSrcweir } 2145*cdf0e10cSrcweir #endif 2146*cdf0e10cSrcweir 2147*cdf0e10cSrcweir #ifndef NO_TTCR 2148*cdf0e10cSrcweir int CreateTTFromTTGlyphs(TrueTypeFont *ttf, 2149*cdf0e10cSrcweir const char *fname, 2150*cdf0e10cSrcweir sal_uInt16 *glyphArray, 2151*cdf0e10cSrcweir sal_uInt8 *encoding, 2152*cdf0e10cSrcweir int nGlyphs, 2153*cdf0e10cSrcweir int nNameRecs, 2154*cdf0e10cSrcweir NameRecord *nr, 2155*cdf0e10cSrcweir sal_uInt32 flags) 2156*cdf0e10cSrcweir { 2157*cdf0e10cSrcweir TrueTypeCreator *ttcr; 2158*cdf0e10cSrcweir TrueTypeTable *head=0, *hhea=0, *maxp=0, *cvt=0, *prep=0, *glyf=0, *fpgm=0, *cmap=0, *name=0, *post = 0, *os2 = 0; 2159*cdf0e10cSrcweir int i; 2160*cdf0e10cSrcweir int res; 2161*cdf0e10cSrcweir 2162*cdf0e10cSrcweir TrueTypeCreatorNewEmpty(T_true, &ttcr); 2163*cdf0e10cSrcweir 2164*cdf0e10cSrcweir /** name **/ 2165*cdf0e10cSrcweir 2166*cdf0e10cSrcweir if (flags & TTCF_AutoName) { 2167*cdf0e10cSrcweir /* not implemented yet 2168*cdf0e10cSrcweir NameRecord *names; 2169*cdf0e10cSrcweir NameRecord newname; 2170*cdf0e10cSrcweir int n = GetTTNameRecords(ttf, &names); 2171*cdf0e10cSrcweir int n1 = 0, n2 = 0, n3 = 0, n4 = 0, n5 = 0, n6 = 0; 2172*cdf0e10cSrcweir sal_uInt8 *cp1; 2173*cdf0e10cSrcweir sal_uInt8 suffix[32]; 2174*cdf0e10cSrcweir sal_uInt32 c1 = crc32(glyphArray, nGlyphs * 2); 2175*cdf0e10cSrcweir sal_uInt32 c2 = crc32(encoding, nGlyphs); 2176*cdf0e10cSrcweir int len; 2177*cdf0e10cSrcweir snprintf(suffix, 31, "S%08X%08X-%d", c1, c2, nGlyphs); 2178*cdf0e10cSrcweir 2179*cdf0e10cSrcweir name = TrueTypeTableNew_name(0, 0); 2180*cdf0e10cSrcweir for (i = 0; i < n; i++) { 2181*cdf0e10cSrcweir if (names[i].platformID == 1 && names[i].encodingID == 0 && names[i].languageID == 0 && names[i].nameID == 1) { 2182*cdf0e10cSrcweir 2183*cdf0e10cSrcweir memcpy(newname, names+i, sizeof(NameRecord)); 2184*cdf0e10cSrcweir newname.slen = name[i].slen + strlen(suffix); 2185*cdf0e10cSrcweir */ 2186*cdf0e10cSrcweir const sal_uInt8 ptr[] = {0,'T',0,'r',0,'u',0,'e',0,'T',0,'y',0,'p',0,'e',0,'S',0,'u',0,'b',0,'s',0,'e',0,'t'}; 2187*cdf0e10cSrcweir NameRecord n1 = {1, 0, 0, 6, 14, (sal_uInt8*)"TrueTypeSubset"}; 2188*cdf0e10cSrcweir NameRecord n2 = {3, 1, 1033, 6, 28, 0}; 2189*cdf0e10cSrcweir n2.sptr = (sal_uInt8 *) ptr; 2190*cdf0e10cSrcweir name = TrueTypeTableNew_name(0, 0); 2191*cdf0e10cSrcweir nameAdd(name, &n1); 2192*cdf0e10cSrcweir nameAdd(name, &n2); 2193*cdf0e10cSrcweir } else { 2194*cdf0e10cSrcweir if (nNameRecs == 0) { 2195*cdf0e10cSrcweir NameRecord *names; 2196*cdf0e10cSrcweir int n = GetTTNameRecords(ttf, &names); 2197*cdf0e10cSrcweir name = TrueTypeTableNew_name(n, names); 2198*cdf0e10cSrcweir DisposeNameRecords(names, n); 2199*cdf0e10cSrcweir } else { 2200*cdf0e10cSrcweir name = TrueTypeTableNew_name(nNameRecs, nr); 2201*cdf0e10cSrcweir } 2202*cdf0e10cSrcweir } 2203*cdf0e10cSrcweir 2204*cdf0e10cSrcweir /** maxp **/ 2205*cdf0e10cSrcweir maxp = TrueTypeTableNew_maxp(getTable(ttf, O_maxp), getTableSize(ttf, O_maxp)); 2206*cdf0e10cSrcweir 2207*cdf0e10cSrcweir /** hhea **/ 2208*cdf0e10cSrcweir const sal_uInt8* p = getTable(ttf, O_hhea); 2209*cdf0e10cSrcweir if (p) { 2210*cdf0e10cSrcweir hhea = TrueTypeTableNew_hhea(GetUInt16(p, 4, 1), GetUInt16(p, 6, 1), GetUInt16(p, 8, 1), GetUInt16(p, 18, 1), GetUInt16(p, 20, 1)); 2211*cdf0e10cSrcweir } else { 2212*cdf0e10cSrcweir hhea = TrueTypeTableNew_hhea(0, 0, 0, 0, 0); 2213*cdf0e10cSrcweir } 2214*cdf0e10cSrcweir 2215*cdf0e10cSrcweir /** head **/ 2216*cdf0e10cSrcweir 2217*cdf0e10cSrcweir p = getTable(ttf, O_head); 2218*cdf0e10cSrcweir assert(p != 0); 2219*cdf0e10cSrcweir head = TrueTypeTableNew_head(GetUInt32(p, 4, 1), 2220*cdf0e10cSrcweir GetUInt16(p, 16, 1), 2221*cdf0e10cSrcweir GetUInt16(p, 18, 1), 2222*cdf0e10cSrcweir p+20, 2223*cdf0e10cSrcweir GetUInt16(p, 44, 1), 2224*cdf0e10cSrcweir GetUInt16(p, 46, 1), 2225*cdf0e10cSrcweir GetInt16(p, 48, 1)); 2226*cdf0e10cSrcweir 2227*cdf0e10cSrcweir 2228*cdf0e10cSrcweir /** glyf **/ 2229*cdf0e10cSrcweir 2230*cdf0e10cSrcweir glyf = TrueTypeTableNew_glyf(); 2231*cdf0e10cSrcweir sal_uInt32* gID = (sal_uInt32*)scalloc(nGlyphs, sizeof(sal_uInt32)); 2232*cdf0e10cSrcweir 2233*cdf0e10cSrcweir for (i = 0; i < nGlyphs; i++) { 2234*cdf0e10cSrcweir gID[i] = glyfAdd(glyf, GetTTRawGlyphData(ttf, glyphArray[i]), ttf); 2235*cdf0e10cSrcweir } 2236*cdf0e10cSrcweir 2237*cdf0e10cSrcweir /** cmap **/ 2238*cdf0e10cSrcweir cmap = TrueTypeTableNew_cmap(); 2239*cdf0e10cSrcweir 2240*cdf0e10cSrcweir for (i=0; i < nGlyphs; i++) { 2241*cdf0e10cSrcweir cmapAdd(cmap, 0x010000, encoding[i], gID[i]); 2242*cdf0e10cSrcweir } 2243*cdf0e10cSrcweir 2244*cdf0e10cSrcweir /** cvt **/ 2245*cdf0e10cSrcweir if ((p = getTable(ttf, O_cvt)) != 0) { 2246*cdf0e10cSrcweir cvt = TrueTypeTableNew(T_cvt, getTableSize(ttf, O_cvt), p); 2247*cdf0e10cSrcweir } 2248*cdf0e10cSrcweir 2249*cdf0e10cSrcweir /** prep **/ 2250*cdf0e10cSrcweir if ((p = getTable(ttf, O_prep)) != 0) { 2251*cdf0e10cSrcweir prep = TrueTypeTableNew(T_prep, getTableSize(ttf, O_prep), p); 2252*cdf0e10cSrcweir } 2253*cdf0e10cSrcweir 2254*cdf0e10cSrcweir /** fpgm **/ 2255*cdf0e10cSrcweir if ((p = getTable(ttf, O_fpgm)) != 0) { 2256*cdf0e10cSrcweir fpgm = TrueTypeTableNew(T_fpgm, getTableSize(ttf, O_fpgm), p); 2257*cdf0e10cSrcweir } 2258*cdf0e10cSrcweir 2259*cdf0e10cSrcweir /** post **/ 2260*cdf0e10cSrcweir if ((p = getTable(ttf, O_post)) != 0) { 2261*cdf0e10cSrcweir post = TrueTypeTableNew_post(0x00030000, 2262*cdf0e10cSrcweir GetUInt32(p, 4, 1), 2263*cdf0e10cSrcweir GetUInt16(p, 8, 1), 2264*cdf0e10cSrcweir GetUInt16(p, 10, 1), 2265*cdf0e10cSrcweir GetUInt16(p, 12, 1)); 2266*cdf0e10cSrcweir } else { 2267*cdf0e10cSrcweir post = TrueTypeTableNew_post(0x00030000, 0, 0, 0, 0); 2268*cdf0e10cSrcweir } 2269*cdf0e10cSrcweir 2270*cdf0e10cSrcweir if (flags & TTCF_IncludeOS2) { 2271*cdf0e10cSrcweir if ((p = getTable(ttf, O_OS2)) != 0) { 2272*cdf0e10cSrcweir os2 = TrueTypeTableNew(T_OS2, getTableSize(ttf, O_OS2), p); 2273*cdf0e10cSrcweir } 2274*cdf0e10cSrcweir } 2275*cdf0e10cSrcweir 2276*cdf0e10cSrcweir AddTable(ttcr, name); AddTable(ttcr, maxp); AddTable(ttcr, hhea); 2277*cdf0e10cSrcweir AddTable(ttcr, head); AddTable(ttcr, glyf); AddTable(ttcr, cmap); 2278*cdf0e10cSrcweir AddTable(ttcr, cvt ); AddTable(ttcr, prep); AddTable(ttcr, fpgm); 2279*cdf0e10cSrcweir AddTable(ttcr, post); AddTable(ttcr, os2); 2280*cdf0e10cSrcweir 2281*cdf0e10cSrcweir if ((res = StreamToFile(ttcr, fname)) != SF_OK) { 2282*cdf0e10cSrcweir #if OSL_DEBUG_LEVEL > 1 2283*cdf0e10cSrcweir fprintf(stderr, "StreamToFile: error code: %d.\n", res); 2284*cdf0e10cSrcweir #endif 2285*cdf0e10cSrcweir } 2286*cdf0e10cSrcweir 2287*cdf0e10cSrcweir TrueTypeCreatorDispose(ttcr); 2288*cdf0e10cSrcweir free(gID); 2289*cdf0e10cSrcweir 2290*cdf0e10cSrcweir return res; 2291*cdf0e10cSrcweir } 2292*cdf0e10cSrcweir #endif 2293*cdf0e10cSrcweir 2294*cdf0e10cSrcweir 2295*cdf0e10cSrcweir #ifndef NO_TYPE42 2296*cdf0e10cSrcweir static GlyphOffsets *GlyphOffsetsNew(sal_uInt8 *sfntP) 2297*cdf0e10cSrcweir { 2298*cdf0e10cSrcweir GlyphOffsets* res = (GlyphOffsets*)smalloc(sizeof(GlyphOffsets)); 2299*cdf0e10cSrcweir sal_uInt8 *loca = NULL; 2300*cdf0e10cSrcweir sal_uInt16 i, numTables = GetUInt16(sfntP, 4, 1); 2301*cdf0e10cSrcweir sal_uInt32 locaLen = 0; 2302*cdf0e10cSrcweir sal_Int16 indexToLocFormat = 0; 2303*cdf0e10cSrcweir 2304*cdf0e10cSrcweir for (i = 0; i < numTables; i++) { 2305*cdf0e10cSrcweir sal_uInt32 tag = GetUInt32(sfntP + 12, 16 * i, 1); 2306*cdf0e10cSrcweir sal_uInt32 off = GetUInt32(sfntP + 12, 16 * i + 8, 1); 2307*cdf0e10cSrcweir sal_uInt32 len = GetUInt32(sfntP + 12, 16 * i + 12, 1); 2308*cdf0e10cSrcweir 2309*cdf0e10cSrcweir if (tag == T_loca) { 2310*cdf0e10cSrcweir loca = sfntP + off; 2311*cdf0e10cSrcweir locaLen = len; 2312*cdf0e10cSrcweir } else if (tag == T_head) { 2313*cdf0e10cSrcweir indexToLocFormat = GetInt16(sfntP + off, 50, 1); 2314*cdf0e10cSrcweir } 2315*cdf0e10cSrcweir } 2316*cdf0e10cSrcweir 2317*cdf0e10cSrcweir res->nGlyphs = locaLen / ((indexToLocFormat == 1) ? 4 : 2); 2318*cdf0e10cSrcweir assert(res->nGlyphs != 0); 2319*cdf0e10cSrcweir res->offs = (sal_uInt32*)scalloc(res->nGlyphs, sizeof(sal_uInt32)); 2320*cdf0e10cSrcweir 2321*cdf0e10cSrcweir for (i = 0; i < res->nGlyphs; i++) { 2322*cdf0e10cSrcweir if (indexToLocFormat == 1) { 2323*cdf0e10cSrcweir res->offs[i] = GetUInt32(loca, i * 4, 1); 2324*cdf0e10cSrcweir } else { 2325*cdf0e10cSrcweir res->offs[i] = GetUInt16(loca, i * 2, 1) << 1; 2326*cdf0e10cSrcweir } 2327*cdf0e10cSrcweir } 2328*cdf0e10cSrcweir return res; 2329*cdf0e10cSrcweir } 2330*cdf0e10cSrcweir 2331*cdf0e10cSrcweir static void GlyphOffsetsDispose(GlyphOffsets *_this) 2332*cdf0e10cSrcweir { 2333*cdf0e10cSrcweir if (_this) { 2334*cdf0e10cSrcweir free(_this->offs); 2335*cdf0e10cSrcweir free(_this); 2336*cdf0e10cSrcweir } 2337*cdf0e10cSrcweir } 2338*cdf0e10cSrcweir 2339*cdf0e10cSrcweir static void DumpSfnts(FILE *outf, sal_uInt8 *sfntP) 2340*cdf0e10cSrcweir { 2341*cdf0e10cSrcweir HexFmt *h = HexFmtNew(outf); 2342*cdf0e10cSrcweir sal_uInt16 i, numTables = GetUInt16(sfntP, 4, 1); 2343*cdf0e10cSrcweir GlyphOffsets *go = GlyphOffsetsNew(sfntP); 2344*cdf0e10cSrcweir sal_uInt8 pad[] = {0,0,0,0}; /* zeroes */ 2345*cdf0e10cSrcweir 2346*cdf0e10cSrcweir assert(numTables <= 9); /* Type42 has 9 required tables */ 2347*cdf0e10cSrcweir 2348*cdf0e10cSrcweir sal_uInt32* offs = (sal_uInt32*)scalloc(numTables, sizeof(sal_uInt32)); 2349*cdf0e10cSrcweir // sal_uInt32* lens = (sal_uInt32*)scalloc(numTables, sizeof(sal_uInt32)); 2350*cdf0e10cSrcweir 2351*cdf0e10cSrcweir fputs("/sfnts [", outf); 2352*cdf0e10cSrcweir HexFmtOpenString(h); 2353*cdf0e10cSrcweir HexFmtBlockWrite(h, sfntP, 12); /* stream out the Offset Table */ 2354*cdf0e10cSrcweir HexFmtBlockWrite(h, sfntP+12, 16 * numTables); /* stream out the Table Directory */ 2355*cdf0e10cSrcweir 2356*cdf0e10cSrcweir for (i=0; i<numTables; i++) { 2357*cdf0e10cSrcweir sal_uInt32 tag = GetUInt32(sfntP + 12, 16 * i, 1); 2358*cdf0e10cSrcweir sal_uInt32 off = GetUInt32(sfntP + 12, 16 * i + 8, 1); 2359*cdf0e10cSrcweir sal_uInt32 len = GetUInt32(sfntP + 12, 16 * i + 12, 1); 2360*cdf0e10cSrcweir 2361*cdf0e10cSrcweir if (tag != T_glyf) { 2362*cdf0e10cSrcweir HexFmtBlockWrite(h, sfntP + off, len); 2363*cdf0e10cSrcweir } else { 2364*cdf0e10cSrcweir sal_uInt8 *glyf = sfntP + off; 2365*cdf0e10cSrcweir sal_uInt32 o, l, j; 2366*cdf0e10cSrcweir for (j = 0; j < go->nGlyphs - 1; j++) { 2367*cdf0e10cSrcweir o = go->offs[j]; 2368*cdf0e10cSrcweir l = go->offs[j + 1] - o; 2369*cdf0e10cSrcweir HexFmtBlockWrite(h, glyf + o, l); 2370*cdf0e10cSrcweir } 2371*cdf0e10cSrcweir } 2372*cdf0e10cSrcweir HexFmtBlockWrite(h, pad, (4 - (len & 3)) & 3); 2373*cdf0e10cSrcweir } 2374*cdf0e10cSrcweir HexFmtCloseString(h); 2375*cdf0e10cSrcweir fputs("] def\n", outf); 2376*cdf0e10cSrcweir GlyphOffsetsDispose(go); 2377*cdf0e10cSrcweir HexFmtDispose(h); 2378*cdf0e10cSrcweir free(offs); 2379*cdf0e10cSrcweir // free(lens); 2380*cdf0e10cSrcweir } 2381*cdf0e10cSrcweir 2382*cdf0e10cSrcweir int CreateT42FromTTGlyphs(TrueTypeFont *ttf, 2383*cdf0e10cSrcweir FILE *outf, 2384*cdf0e10cSrcweir const char *psname, 2385*cdf0e10cSrcweir sal_uInt16 *glyphArray, 2386*cdf0e10cSrcweir sal_uInt8 *encoding, 2387*cdf0e10cSrcweir int nGlyphs) 2388*cdf0e10cSrcweir { 2389*cdf0e10cSrcweir TrueTypeCreator *ttcr; 2390*cdf0e10cSrcweir TrueTypeTable *head=0, *hhea=0, *maxp=0, *cvt=0, *prep=0, *glyf=0, *fpgm=0; 2391*cdf0e10cSrcweir int i; 2392*cdf0e10cSrcweir int res; 2393*cdf0e10cSrcweir 2394*cdf0e10cSrcweir sal_uInt32 ver, rev; 2395*cdf0e10cSrcweir 2396*cdf0e10cSrcweir sal_uInt8 *sfntP; 2397*cdf0e10cSrcweir sal_uInt32 sfntLen; 2398*cdf0e10cSrcweir int UPEm = ttf->unitsPerEm; 2399*cdf0e10cSrcweir 2400*cdf0e10cSrcweir if (nGlyphs >= 256) return SF_GLYPHNUM; 2401*cdf0e10cSrcweir 2402*cdf0e10cSrcweir assert(psname != 0); 2403*cdf0e10cSrcweir 2404*cdf0e10cSrcweir TrueTypeCreatorNewEmpty(T_true, &ttcr); 2405*cdf0e10cSrcweir 2406*cdf0e10cSrcweir /* head */ 2407*cdf0e10cSrcweir const sal_uInt8* p = getTable(ttf, O_head); 2408*cdf0e10cSrcweir const sal_uInt8* headP = p; 2409*cdf0e10cSrcweir assert(p != 0); 2410*cdf0e10cSrcweir head = TrueTypeTableNew_head(GetUInt32(p, 4, 1), GetUInt16(p, 16, 1), GetUInt16(p, 18, 1), p+20, GetUInt16(p, 44, 1), GetUInt16(p, 46, 1), GetInt16(p, 48, 1)); 2411*cdf0e10cSrcweir ver = GetUInt32(p, 0, 1); 2412*cdf0e10cSrcweir rev = GetUInt32(p, 4, 1); 2413*cdf0e10cSrcweir 2414*cdf0e10cSrcweir /** hhea **/ 2415*cdf0e10cSrcweir p = getTable(ttf, O_hhea); 2416*cdf0e10cSrcweir if (p) { 2417*cdf0e10cSrcweir hhea = TrueTypeTableNew_hhea(GetUInt16(p, 4, 1), GetUInt16(p, 6, 1), GetUInt16(p, 8, 1), GetUInt16(p, 18, 1), GetUInt16(p, 20, 1)); 2418*cdf0e10cSrcweir } else { 2419*cdf0e10cSrcweir hhea = TrueTypeTableNew_hhea(0, 0, 0, 0, 0); 2420*cdf0e10cSrcweir } 2421*cdf0e10cSrcweir 2422*cdf0e10cSrcweir /** maxp **/ 2423*cdf0e10cSrcweir maxp = TrueTypeTableNew_maxp(getTable(ttf, O_maxp), getTableSize(ttf, O_maxp)); 2424*cdf0e10cSrcweir 2425*cdf0e10cSrcweir /** cvt **/ 2426*cdf0e10cSrcweir if ((p = getTable(ttf, O_cvt)) != 0) { 2427*cdf0e10cSrcweir cvt = TrueTypeTableNew(T_cvt, getTableSize(ttf, O_cvt), p); 2428*cdf0e10cSrcweir } 2429*cdf0e10cSrcweir 2430*cdf0e10cSrcweir /** prep **/ 2431*cdf0e10cSrcweir if ((p = getTable(ttf, O_prep)) != 0) { 2432*cdf0e10cSrcweir prep = TrueTypeTableNew(T_prep, getTableSize(ttf, O_prep), p); 2433*cdf0e10cSrcweir } 2434*cdf0e10cSrcweir 2435*cdf0e10cSrcweir /** fpgm **/ 2436*cdf0e10cSrcweir if ((p = getTable(ttf, O_fpgm)) != 0) { 2437*cdf0e10cSrcweir fpgm = TrueTypeTableNew(T_fpgm, getTableSize(ttf, O_fpgm), p); 2438*cdf0e10cSrcweir } 2439*cdf0e10cSrcweir 2440*cdf0e10cSrcweir /** glyf **/ 2441*cdf0e10cSrcweir glyf = TrueTypeTableNew_glyf(); 2442*cdf0e10cSrcweir sal_uInt16* gID = (sal_uInt16*)scalloc(nGlyphs, sizeof(sal_uInt32)); 2443*cdf0e10cSrcweir 2444*cdf0e10cSrcweir for (i = 0; i < nGlyphs; i++) { 2445*cdf0e10cSrcweir gID[i] = (sal_uInt16)glyfAdd(glyf, GetTTRawGlyphData(ttf, glyphArray[i]), ttf); 2446*cdf0e10cSrcweir } 2447*cdf0e10cSrcweir 2448*cdf0e10cSrcweir AddTable(ttcr, head); AddTable(ttcr, hhea); AddTable(ttcr, maxp); AddTable(ttcr, cvt); 2449*cdf0e10cSrcweir AddTable(ttcr, prep); AddTable(ttcr, glyf); AddTable(ttcr, fpgm); 2450*cdf0e10cSrcweir 2451*cdf0e10cSrcweir if ((res = StreamToMemory(ttcr, &sfntP, &sfntLen)) != SF_OK) { 2452*cdf0e10cSrcweir TrueTypeCreatorDispose(ttcr); 2453*cdf0e10cSrcweir free(gID); 2454*cdf0e10cSrcweir return res; 2455*cdf0e10cSrcweir } 2456*cdf0e10cSrcweir 2457*cdf0e10cSrcweir fprintf(outf, "%%!PS-TrueTypeFont-%d.%d-%d.%d\n", (int)(ver>>16), (int)(ver & 0xFFFF), (int)(rev>>16), (int)(rev & 0xFFFF)); 2458*cdf0e10cSrcweir fprintf(outf, "%%%%Creator: %s %s %s\n", modname, modver, modextra); 2459*cdf0e10cSrcweir fprintf(outf, "%%- Font subset generated from a source font file: '%s'\n", ttf->fname); 2460*cdf0e10cSrcweir fprintf(outf, "%%- Original font name: %s\n", ttf->psname); 2461*cdf0e10cSrcweir fprintf(outf, "%%- Original font family: %s\n", ttf->family); 2462*cdf0e10cSrcweir fprintf(outf, "%%- Original font sub-family: %s\n", ttf->subfamily); 2463*cdf0e10cSrcweir fprintf(outf, "11 dict begin\n"); 2464*cdf0e10cSrcweir fprintf(outf, "/FontName (%s) cvn def\n", psname); 2465*cdf0e10cSrcweir fprintf(outf, "/PaintType 0 def\n"); 2466*cdf0e10cSrcweir fprintf(outf, "/FontMatrix [1 0 0 1 0 0] def\n"); 2467*cdf0e10cSrcweir fprintf(outf, "/FontBBox [%d %d %d %d] def\n", XUnits(UPEm, GetInt16(headP, 36, 1)), XUnits(UPEm, GetInt16(headP, 38, 1)), XUnits(UPEm, GetInt16(headP, 40, 1)), XUnits(UPEm, GetInt16(headP, 42, 1))); 2468*cdf0e10cSrcweir fprintf(outf, "/FontType 42 def\n"); 2469*cdf0e10cSrcweir fprintf(outf, "/Encoding 256 array def\n"); 2470*cdf0e10cSrcweir fprintf(outf, " 0 1 255 {Encoding exch /.notdef put} for\n"); 2471*cdf0e10cSrcweir 2472*cdf0e10cSrcweir for (i = 1; i<nGlyphs; i++) { 2473*cdf0e10cSrcweir fprintf(outf, "Encoding %d /glyph%d put\n", encoding[i], gID[i]); 2474*cdf0e10cSrcweir } 2475*cdf0e10cSrcweir fprintf(outf, "/XUID [103 0 1 16#%08X %d 16#%08X 16#%08X] def\n", (unsigned int)rtl_crc32(0, ttf->ptr, ttf->fsize), (unsigned int)nGlyphs, (unsigned int)rtl_crc32(0, glyphArray, nGlyphs * 2), (unsigned int)rtl_crc32(0, encoding, nGlyphs)); 2476*cdf0e10cSrcweir 2477*cdf0e10cSrcweir DumpSfnts(outf, sfntP); 2478*cdf0e10cSrcweir 2479*cdf0e10cSrcweir /* dump charstrings */ 2480*cdf0e10cSrcweir fprintf(outf, "/CharStrings %d dict dup begin\n", nGlyphs); 2481*cdf0e10cSrcweir fprintf(outf, "/.notdef 0 def\n"); 2482*cdf0e10cSrcweir for (i = 1; i < (int)glyfCount(glyf); i++) { 2483*cdf0e10cSrcweir fprintf(outf,"/glyph%d %d def\n", i, i); 2484*cdf0e10cSrcweir } 2485*cdf0e10cSrcweir fprintf(outf, "end readonly def\n"); 2486*cdf0e10cSrcweir 2487*cdf0e10cSrcweir fprintf(outf, "FontName currentdict end definefont pop\n"); 2488*cdf0e10cSrcweir TrueTypeCreatorDispose(ttcr); 2489*cdf0e10cSrcweir free(gID); 2490*cdf0e10cSrcweir free(sfntP); 2491*cdf0e10cSrcweir return SF_OK; 2492*cdf0e10cSrcweir } 2493*cdf0e10cSrcweir #endif 2494*cdf0e10cSrcweir 2495*cdf0e10cSrcweir 2496*cdf0e10cSrcweir #ifndef NO_MAPPERS 2497*cdf0e10cSrcweir int MapString(TrueTypeFont *ttf, sal_uInt16 *str, int nchars, sal_uInt16 *glyphArray, int bvertical) 2498*cdf0e10cSrcweir { 2499*cdf0e10cSrcweir int i; 2500*cdf0e10cSrcweir sal_uInt16 *cp; 2501*cdf0e10cSrcweir 2502*cdf0e10cSrcweir if (ttf->cmapType == CMAP_NOT_USABLE ) return -1; 2503*cdf0e10cSrcweir if (!nchars) return 0; 2504*cdf0e10cSrcweir 2505*cdf0e10cSrcweir if (glyphArray == 0) { 2506*cdf0e10cSrcweir cp = str; 2507*cdf0e10cSrcweir } else { 2508*cdf0e10cSrcweir cp = glyphArray; 2509*cdf0e10cSrcweir } 2510*cdf0e10cSrcweir 2511*cdf0e10cSrcweir switch (ttf->cmapType) { 2512*cdf0e10cSrcweir case CMAP_MS_Symbol: 2513*cdf0e10cSrcweir if( ttf->mapper == getGlyph0 ) { 2514*cdf0e10cSrcweir sal_uInt16 aChar; 2515*cdf0e10cSrcweir for( i = 0; i < nchars; i++ ) { 2516*cdf0e10cSrcweir aChar = str[i]; 2517*cdf0e10cSrcweir if( ( aChar & 0xf000 ) == 0xf000 ) 2518*cdf0e10cSrcweir aChar &= 0x00ff; 2519*cdf0e10cSrcweir cp[i] = aChar; 2520*cdf0e10cSrcweir } 2521*cdf0e10cSrcweir } 2522*cdf0e10cSrcweir else if( glyphArray ) 2523*cdf0e10cSrcweir memcpy(glyphArray, str, nchars * 2); 2524*cdf0e10cSrcweir break; 2525*cdf0e10cSrcweir 2526*cdf0e10cSrcweir case CMAP_MS_Unicode: 2527*cdf0e10cSrcweir if (glyphArray != 0) { 2528*cdf0e10cSrcweir memcpy(glyphArray, str, nchars * 2); 2529*cdf0e10cSrcweir } 2530*cdf0e10cSrcweir break; 2531*cdf0e10cSrcweir 2532*cdf0e10cSrcweir case CMAP_MS_ShiftJIS: TranslateString12(str, cp, nchars); break; 2533*cdf0e10cSrcweir case CMAP_MS_Big5: TranslateString13(str, cp, nchars); break; 2534*cdf0e10cSrcweir case CMAP_MS_PRC: TranslateString14(str, cp, nchars); break; 2535*cdf0e10cSrcweir case CMAP_MS_Wansung: TranslateString15(str, cp, nchars); break; 2536*cdf0e10cSrcweir case CMAP_MS_Johab: TranslateString16(str, cp, nchars); break; 2537*cdf0e10cSrcweir } 2538*cdf0e10cSrcweir 2539*cdf0e10cSrcweir for (i = 0; i < nchars; i++) { 2540*cdf0e10cSrcweir cp[i] = (sal_uInt16)ttf->mapper(ttf->cmap, cp[i]); 2541*cdf0e10cSrcweir if (cp[i]!=0 && bvertical!=0) 2542*cdf0e10cSrcweir cp[i] = (sal_uInt16)UseGSUB(ttf,cp[i],bvertical); 2543*cdf0e10cSrcweir } 2544*cdf0e10cSrcweir return nchars; 2545*cdf0e10cSrcweir } 2546*cdf0e10cSrcweir 2547*cdf0e10cSrcweir sal_uInt16 MapChar(TrueTypeFont *ttf, sal_uInt16 ch, int bvertical) 2548*cdf0e10cSrcweir { 2549*cdf0e10cSrcweir switch (ttf->cmapType) { 2550*cdf0e10cSrcweir case CMAP_MS_Symbol: 2551*cdf0e10cSrcweir 2552*cdf0e10cSrcweir if( ttf->mapper == getGlyph0 && ( ch & 0xf000 ) == 0xf000 ) 2553*cdf0e10cSrcweir ch &= 0x00ff; 2554*cdf0e10cSrcweir return (sal_uInt16)ttf->mapper(ttf->cmap, ch ); 2555*cdf0e10cSrcweir 2556*cdf0e10cSrcweir case CMAP_MS_Unicode: break; 2557*cdf0e10cSrcweir case CMAP_MS_ShiftJIS: ch = TranslateChar12(ch); break; 2558*cdf0e10cSrcweir case CMAP_MS_Big5: ch = TranslateChar13(ch); break; 2559*cdf0e10cSrcweir case CMAP_MS_PRC: ch = TranslateChar14(ch); break; 2560*cdf0e10cSrcweir case CMAP_MS_Wansung: ch = TranslateChar15(ch); break; 2561*cdf0e10cSrcweir case CMAP_MS_Johab: ch = TranslateChar16(ch); break; 2562*cdf0e10cSrcweir default: return 0; 2563*cdf0e10cSrcweir } 2564*cdf0e10cSrcweir ch = (sal_uInt16)ttf->mapper(ttf->cmap, ch); 2565*cdf0e10cSrcweir if (ch!=0 && bvertical!=0) 2566*cdf0e10cSrcweir ch = (sal_uInt16)UseGSUB(ttf,ch,bvertical); 2567*cdf0e10cSrcweir return ch; 2568*cdf0e10cSrcweir } 2569*cdf0e10cSrcweir 2570*cdf0e10cSrcweir int DoesVerticalSubstitution( TrueTypeFont *ttf, int bvertical) 2571*cdf0e10cSrcweir { 2572*cdf0e10cSrcweir int nRet = 0; 2573*cdf0e10cSrcweir if( bvertical) 2574*cdf0e10cSrcweir nRet = HasVerticalGSUB( ttf); 2575*cdf0e10cSrcweir return nRet; 2576*cdf0e10cSrcweir } 2577*cdf0e10cSrcweir 2578*cdf0e10cSrcweir #endif 2579*cdf0e10cSrcweir 2580*cdf0e10cSrcweir int GetTTGlyphCount( TrueTypeFont* ttf ) 2581*cdf0e10cSrcweir { 2582*cdf0e10cSrcweir return ttf->nglyphs; 2583*cdf0e10cSrcweir } 2584*cdf0e10cSrcweir 2585*cdf0e10cSrcweir bool GetSfntTable( TrueTypeFont* ttf, int nSubtableIndex, 2586*cdf0e10cSrcweir const sal_uInt8** ppRawBytes, int* pRawLength ) 2587*cdf0e10cSrcweir { 2588*cdf0e10cSrcweir if( (nSubtableIndex < 0) || (nSubtableIndex >= NUM_TAGS) ) 2589*cdf0e10cSrcweir return false; 2590*cdf0e10cSrcweir *pRawLength = ttf->tlens[ nSubtableIndex ]; 2591*cdf0e10cSrcweir *ppRawBytes = ttf->tables[ nSubtableIndex ]; 2592*cdf0e10cSrcweir bool bOk = (*pRawLength > 0) && (ppRawBytes != NULL); 2593*cdf0e10cSrcweir return bOk; 2594*cdf0e10cSrcweir } 2595*cdf0e10cSrcweir 2596*cdf0e10cSrcweir TTSimpleGlyphMetrics *GetTTSimpleGlyphMetrics(TrueTypeFont *ttf, sal_uInt16 *glyphArray, int nGlyphs, int mode) 2597*cdf0e10cSrcweir { 2598*cdf0e10cSrcweir const sal_uInt8* pTable; 2599*cdf0e10cSrcweir sal_uInt32 n; 2600*cdf0e10cSrcweir int nTableSize; 2601*cdf0e10cSrcweir 2602*cdf0e10cSrcweir if (mode == 0) { 2603*cdf0e10cSrcweir n = ttf->numberOfHMetrics; 2604*cdf0e10cSrcweir pTable = getTable( ttf, O_hmtx ); 2605*cdf0e10cSrcweir nTableSize = getTableSize( ttf, O_hmtx ); 2606*cdf0e10cSrcweir } else { 2607*cdf0e10cSrcweir n = ttf->numOfLongVerMetrics; 2608*cdf0e10cSrcweir pTable = getTable( ttf, O_vmtx ); 2609*cdf0e10cSrcweir nTableSize = getTableSize( ttf, O_vmtx ); 2610*cdf0e10cSrcweir } 2611*cdf0e10cSrcweir 2612*cdf0e10cSrcweir if (!nGlyphs || !glyphArray) return 0; /* invalid parameters */ 2613*cdf0e10cSrcweir if (!n || !pTable) return 0; /* the font does not contain the requested metrics */ 2614*cdf0e10cSrcweir 2615*cdf0e10cSrcweir TTSimpleGlyphMetrics* res = (TTSimpleGlyphMetrics*)calloc(nGlyphs, sizeof(TTSimpleGlyphMetrics)); 2616*cdf0e10cSrcweir assert(res != 0); 2617*cdf0e10cSrcweir 2618*cdf0e10cSrcweir const int UPEm = ttf->unitsPerEm; 2619*cdf0e10cSrcweir for( int i = 0; i < nGlyphs; ++i) { 2620*cdf0e10cSrcweir int nAdvOffset, nLsbOffset; 2621*cdf0e10cSrcweir sal_uInt16 glyphID = glyphArray[i]; 2622*cdf0e10cSrcweir 2623*cdf0e10cSrcweir if (glyphID < n) { 2624*cdf0e10cSrcweir nAdvOffset = 4 * glyphID; 2625*cdf0e10cSrcweir nLsbOffset = nAdvOffset + 2; 2626*cdf0e10cSrcweir } else { 2627*cdf0e10cSrcweir nAdvOffset = 4 * (n - 1); 2628*cdf0e10cSrcweir if( glyphID < ttf->nglyphs ) 2629*cdf0e10cSrcweir nLsbOffset = 4 * n + 2 * (glyphID - n); 2630*cdf0e10cSrcweir else /* font is broken -> use lsb of last hmetrics */ 2631*cdf0e10cSrcweir nLsbOffset = nAdvOffset + 2; 2632*cdf0e10cSrcweir } 2633*cdf0e10cSrcweir 2634*cdf0e10cSrcweir if( nAdvOffset >= nTableSize) 2635*cdf0e10cSrcweir res[i].adv = 0; /* better than a crash for buggy fonts */ 2636*cdf0e10cSrcweir else 2637*cdf0e10cSrcweir res[i].adv = static_cast<sal_uInt16>( 2638*cdf0e10cSrcweir XUnits( UPEm, GetUInt16( pTable, nAdvOffset, 1) ) ); 2639*cdf0e10cSrcweir 2640*cdf0e10cSrcweir if( nLsbOffset >= nTableSize) 2641*cdf0e10cSrcweir res[i].sb = 0; /* better than a crash for buggy fonts */ 2642*cdf0e10cSrcweir else 2643*cdf0e10cSrcweir res[i].sb = static_cast<sal_Int16>( 2644*cdf0e10cSrcweir XUnits( UPEm, GetInt16( pTable, nLsbOffset, 1) ) ); 2645*cdf0e10cSrcweir } 2646*cdf0e10cSrcweir 2647*cdf0e10cSrcweir return res; 2648*cdf0e10cSrcweir } 2649*cdf0e10cSrcweir 2650*cdf0e10cSrcweir #ifndef NO_MAPPERS 2651*cdf0e10cSrcweir TTSimpleGlyphMetrics *GetTTSimpleCharMetrics(TrueTypeFont * ttf, sal_uInt16 firstChar, int nChars, int mode) 2652*cdf0e10cSrcweir { 2653*cdf0e10cSrcweir TTSimpleGlyphMetrics *res = 0; 2654*cdf0e10cSrcweir int i, n; 2655*cdf0e10cSrcweir 2656*cdf0e10cSrcweir sal_uInt16* str = (sal_uInt16*)malloc(nChars * 2); 2657*cdf0e10cSrcweir assert(str != 0); 2658*cdf0e10cSrcweir 2659*cdf0e10cSrcweir for (i=0; i<nChars; i++) str[i] = (sal_uInt16)(firstChar + i); 2660*cdf0e10cSrcweir if ((n = MapString(ttf, str, nChars, 0, mode)) != -1) { 2661*cdf0e10cSrcweir res = GetTTSimpleGlyphMetrics(ttf, str, n, mode); 2662*cdf0e10cSrcweir } 2663*cdf0e10cSrcweir 2664*cdf0e10cSrcweir free(str); 2665*cdf0e10cSrcweir 2666*cdf0e10cSrcweir return res; 2667*cdf0e10cSrcweir } 2668*cdf0e10cSrcweir #endif 2669*cdf0e10cSrcweir 2670*cdf0e10cSrcweir void GetTTGlobalFontInfo(TrueTypeFont *ttf, TTGlobalFontInfo *info) 2671*cdf0e10cSrcweir { 2672*cdf0e10cSrcweir int UPEm = ttf->unitsPerEm; 2673*cdf0e10cSrcweir 2674*cdf0e10cSrcweir memset(info, 0, sizeof(TTGlobalFontInfo)); 2675*cdf0e10cSrcweir 2676*cdf0e10cSrcweir info->family = ttf->family; 2677*cdf0e10cSrcweir info->ufamily = ttf->ufamily; 2678*cdf0e10cSrcweir info->subfamily = ttf->subfamily; 2679*cdf0e10cSrcweir info->usubfamily = ttf->usubfamily; 2680*cdf0e10cSrcweir info->psname = ttf->psname; 2681*cdf0e10cSrcweir info->symbolEncoded = (ttf->cmapType == CMAP_MS_Symbol); 2682*cdf0e10cSrcweir 2683*cdf0e10cSrcweir const sal_uInt8* table = getTable(ttf, O_OS2); 2684*cdf0e10cSrcweir if (table) { 2685*cdf0e10cSrcweir info->weight = GetUInt16(table, 4, 1); 2686*cdf0e10cSrcweir info->width = GetUInt16(table, 6, 1); 2687*cdf0e10cSrcweir 2688*cdf0e10cSrcweir /* There are 3 different versions of OS/2 table: original (68 bytes long), 2689*cdf0e10cSrcweir * Microsoft old (78 bytes long) and Microsoft new (86 bytes long,) 2690*cdf0e10cSrcweir * Apple's documentation recommends looking at the table length. 2691*cdf0e10cSrcweir */ 2692*cdf0e10cSrcweir if (getTableSize(ttf, O_OS2) > 68) { 2693*cdf0e10cSrcweir info->typoAscender = XUnits(UPEm,GetInt16(table, 68, 1)); 2694*cdf0e10cSrcweir info->typoDescender = XUnits(UPEm, GetInt16(table, 70, 1)); 2695*cdf0e10cSrcweir info->typoLineGap = XUnits(UPEm, GetInt16(table, 72, 1)); 2696*cdf0e10cSrcweir info->winAscent = XUnits(UPEm, GetUInt16(table, 74, 1)); 2697*cdf0e10cSrcweir info->winDescent = XUnits(UPEm, GetUInt16(table, 76, 1)); 2698*cdf0e10cSrcweir /* sanity check; some fonts treat winDescent as signed 2699*cdf0e10cSrcweir * violating the standard */ 2700*cdf0e10cSrcweir if( info->winDescent > 5*UPEm ) 2701*cdf0e10cSrcweir info->winDescent = XUnits(UPEm, GetInt16(table, 76,1)); 2702*cdf0e10cSrcweir } 2703*cdf0e10cSrcweir if (ttf->cmapType == CMAP_MS_Unicode) { 2704*cdf0e10cSrcweir info->rangeFlag = 1; 2705*cdf0e10cSrcweir info->ur1 = GetUInt32(table, 42, 1); 2706*cdf0e10cSrcweir info->ur2 = GetUInt32(table, 46, 1); 2707*cdf0e10cSrcweir info->ur3 = GetUInt32(table, 50, 1); 2708*cdf0e10cSrcweir info->ur4 = GetUInt32(table, 54, 1); 2709*cdf0e10cSrcweir } 2710*cdf0e10cSrcweir memcpy(info->panose, table + 32, 10); 2711*cdf0e10cSrcweir info->typeFlags = GetUInt16( table, 8, 1 ); 2712*cdf0e10cSrcweir if( getTable(ttf, O_CFF) ) 2713*cdf0e10cSrcweir info->typeFlags |= TYPEFLAG_PS_OPENTYPE; 2714*cdf0e10cSrcweir } 2715*cdf0e10cSrcweir 2716*cdf0e10cSrcweir table = getTable(ttf, O_post); 2717*cdf0e10cSrcweir if (table && getTableSize(ttf, O_post) >= 12+sizeof(sal_uInt32)) { 2718*cdf0e10cSrcweir info->pitch = GetUInt32(table, 12, 1); 2719*cdf0e10cSrcweir info->italicAngle = GetInt32(table, 4, 1); 2720*cdf0e10cSrcweir } 2721*cdf0e10cSrcweir 2722*cdf0e10cSrcweir table = getTable(ttf, O_head); /* 'head' tables is always there */ 2723*cdf0e10cSrcweir info->xMin = XUnits(UPEm, GetInt16(table, 36, 1)); 2724*cdf0e10cSrcweir info->yMin = XUnits(UPEm, GetInt16(table, 38, 1)); 2725*cdf0e10cSrcweir info->xMax = XUnits(UPEm, GetInt16(table, 40, 1)); 2726*cdf0e10cSrcweir info->yMax = XUnits(UPEm, GetInt16(table, 42, 1)); 2727*cdf0e10cSrcweir info->macStyle = GetInt16(table, 44, 1); 2728*cdf0e10cSrcweir 2729*cdf0e10cSrcweir table = getTable(ttf, O_hhea); 2730*cdf0e10cSrcweir if (table) { 2731*cdf0e10cSrcweir info->ascender = XUnits(UPEm, GetInt16(table, 4, 1)); 2732*cdf0e10cSrcweir info->descender = XUnits(UPEm, GetInt16(table, 6, 1)); 2733*cdf0e10cSrcweir info->linegap = XUnits(UPEm, GetInt16(table, 8, 1)); 2734*cdf0e10cSrcweir } 2735*cdf0e10cSrcweir 2736*cdf0e10cSrcweir table = getTable(ttf, O_vhea); 2737*cdf0e10cSrcweir if (table) { 2738*cdf0e10cSrcweir info->vascent = XUnits(UPEm, GetInt16(table, 4, 1)); 2739*cdf0e10cSrcweir info->vdescent = XUnits(UPEm, GetInt16(table, 6, 1)); 2740*cdf0e10cSrcweir } 2741*cdf0e10cSrcweir } 2742*cdf0e10cSrcweir 2743*cdf0e10cSrcweir #ifdef TEST5 2744*cdf0e10cSrcweir void KernGlyphs(TrueTypeFont *ttf, sal_uInt16 *glyphs, int nglyphs, int wmode, KernData *kern) 2745*cdf0e10cSrcweir { 2746*cdf0e10cSrcweir int i; 2747*cdf0e10cSrcweir 2748*cdf0e10cSrcweir if (!nglyphs || !glyphs || !kern) return; 2749*cdf0e10cSrcweir 2750*cdf0e10cSrcweir for (i = 0; i < nglyphs-1; i++) kern[i].x = kern[i].y = 0; 2751*cdf0e10cSrcweir 2752*cdf0e10cSrcweir switch (ttf->kerntype) { 2753*cdf0e10cSrcweir case KT_APPLE_NEW: KernGlyphsPrim1(ttf, glyphs, nglyphs, wmode, kern); return; 2754*cdf0e10cSrcweir case KT_MICROSOFT: KernGlyphsPrim2(ttf, glyphs, nglyphs, wmode, kern); return; 2755*cdf0e10cSrcweir default: return; 2756*cdf0e10cSrcweir } 2757*cdf0e10cSrcweir } 2758*cdf0e10cSrcweir #endif 2759*cdf0e10cSrcweir 2760*cdf0e10cSrcweir GlyphData *GetTTRawGlyphData(TrueTypeFont *ttf, sal_uInt32 glyphID) 2761*cdf0e10cSrcweir { 2762*cdf0e10cSrcweir const sal_uInt8* glyf = getTable(ttf, O_glyf); 2763*cdf0e10cSrcweir const sal_uInt8* hmtx = getTable(ttf, O_hmtx); 2764*cdf0e10cSrcweir int i, n, m; 2765*cdf0e10cSrcweir 2766*cdf0e10cSrcweir if( glyphID >= ttf->nglyphs ) 2767*cdf0e10cSrcweir return 0; 2768*cdf0e10cSrcweir 2769*cdf0e10cSrcweir /* #127161# check the glyph offsets */ 2770*cdf0e10cSrcweir sal_uInt32 length = getTableSize( ttf, O_glyf ); 2771*cdf0e10cSrcweir if( length < ttf->goffsets[ glyphID+1 ] ) 2772*cdf0e10cSrcweir return 0; 2773*cdf0e10cSrcweir 2774*cdf0e10cSrcweir length = ttf->goffsets[glyphID+1] - ttf->goffsets[glyphID]; 2775*cdf0e10cSrcweir 2776*cdf0e10cSrcweir GlyphData* d = (GlyphData*)malloc(sizeof(GlyphData)); assert(d != 0); 2777*cdf0e10cSrcweir 2778*cdf0e10cSrcweir if (length > 0) { 2779*cdf0e10cSrcweir const sal_uInt8* srcptr = glyf + ttf->goffsets[glyphID]; 2780*cdf0e10cSrcweir d->ptr = (sal_uInt8*)malloc((length + 1) & ~1); assert(d->ptr != 0); 2781*cdf0e10cSrcweir memcpy( d->ptr, srcptr, length ); 2782*cdf0e10cSrcweir d->compflag = (GetInt16( srcptr, 0, 1 ) < 0); 2783*cdf0e10cSrcweir } else { 2784*cdf0e10cSrcweir d->ptr = 0; 2785*cdf0e10cSrcweir d->compflag = 0; 2786*cdf0e10cSrcweir } 2787*cdf0e10cSrcweir 2788*cdf0e10cSrcweir d->glyphID = glyphID; 2789*cdf0e10cSrcweir d->nbytes = (sal_uInt16)((length + 1) & ~1); 2790*cdf0e10cSrcweir 2791*cdf0e10cSrcweir /* now calculate npoints and ncontours */ 2792*cdf0e10cSrcweir ControlPoint *cp; 2793*cdf0e10cSrcweir n = GetTTGlyphPoints(ttf, glyphID, &cp); 2794*cdf0e10cSrcweir if (n != -1) { 2795*cdf0e10cSrcweir m = 0; 2796*cdf0e10cSrcweir for (i = 0; i < n; i++) { 2797*cdf0e10cSrcweir if (cp[i].flags & 0x8000) m++; 2798*cdf0e10cSrcweir } 2799*cdf0e10cSrcweir d->npoints = (sal_uInt16)n; 2800*cdf0e10cSrcweir d->ncontours = (sal_uInt16)m; 2801*cdf0e10cSrcweir free(cp); 2802*cdf0e10cSrcweir } else { 2803*cdf0e10cSrcweir d->npoints = 0; 2804*cdf0e10cSrcweir d->ncontours = 0; 2805*cdf0e10cSrcweir } 2806*cdf0e10cSrcweir 2807*cdf0e10cSrcweir /* get advance width and left sidebearing */ 2808*cdf0e10cSrcweir if (glyphID < ttf->numberOfHMetrics) { 2809*cdf0e10cSrcweir d->aw = GetUInt16(hmtx, 4 * glyphID, 1); 2810*cdf0e10cSrcweir d->lsb = GetInt16(hmtx, 4 * glyphID + 2, 1); 2811*cdf0e10cSrcweir } else { 2812*cdf0e10cSrcweir d->aw = GetUInt16(hmtx, 4 * (ttf->numberOfHMetrics - 1), 1); 2813*cdf0e10cSrcweir d->lsb = GetInt16(hmtx + ttf->numberOfHMetrics * 4, (glyphID - ttf->numberOfHMetrics) * 2, 1); 2814*cdf0e10cSrcweir } 2815*cdf0e10cSrcweir 2816*cdf0e10cSrcweir return d; 2817*cdf0e10cSrcweir } 2818*cdf0e10cSrcweir 2819*cdf0e10cSrcweir int GetTTNameRecords(TrueTypeFont *ttf, NameRecord **nr) 2820*cdf0e10cSrcweir { 2821*cdf0e10cSrcweir const sal_uInt8* table = getTable(ttf, O_name); 2822*cdf0e10cSrcweir int nTableSize = getTableSize(ttf, O_name ); 2823*cdf0e10cSrcweir 2824*cdf0e10cSrcweir if (nTableSize < 6) 2825*cdf0e10cSrcweir { 2826*cdf0e10cSrcweir #if OSL_DEBUG_LEVEL > 1 2827*cdf0e10cSrcweir fprintf(stderr, "O_name table too small\n"); 2828*cdf0e10cSrcweir #endif 2829*cdf0e10cSrcweir return 0; 2830*cdf0e10cSrcweir } 2831*cdf0e10cSrcweir 2832*cdf0e10cSrcweir sal_uInt16 n = GetUInt16(table, 2, 1); 2833*cdf0e10cSrcweir int nStrBase = GetUInt16(table, 4, 1); 2834*cdf0e10cSrcweir int i; 2835*cdf0e10cSrcweir 2836*cdf0e10cSrcweir *nr = 0; 2837*cdf0e10cSrcweir if (n == 0) return 0; 2838*cdf0e10cSrcweir 2839*cdf0e10cSrcweir NameRecord* rec = (NameRecord*)calloc(n, sizeof(NameRecord)); 2840*cdf0e10cSrcweir 2841*cdf0e10cSrcweir for (i = 0; i < n; i++) { 2842*cdf0e10cSrcweir int nStrOffset = GetUInt16(table + 6, 10 + 12 * i, 1); 2843*cdf0e10cSrcweir rec[i].platformID = GetUInt16(table + 6, 12 * i, 1); 2844*cdf0e10cSrcweir rec[i].encodingID = GetUInt16(table + 6, 2 + 12 * i, 1); 2845*cdf0e10cSrcweir rec[i].languageID = GetUInt16(table + 6, 4 + 12 * i, 1); 2846*cdf0e10cSrcweir rec[i].nameID = GetUInt16(table + 6, 6 + 12 * i, 1); 2847*cdf0e10cSrcweir rec[i].slen = GetUInt16(table + 6, 8 + 12 * i, 1); 2848*cdf0e10cSrcweir if (rec[i].slen) { 2849*cdf0e10cSrcweir if( nStrBase+nStrOffset+rec[i].slen >= nTableSize ) { 2850*cdf0e10cSrcweir rec[i].sptr = 0; 2851*cdf0e10cSrcweir rec[i].slen = 0; 2852*cdf0e10cSrcweir continue; 2853*cdf0e10cSrcweir } 2854*cdf0e10cSrcweir 2855*cdf0e10cSrcweir const sal_uInt8* rec_string = table + nStrBase + nStrOffset; 2856*cdf0e10cSrcweir // sanity check 2857*cdf0e10cSrcweir if( rec_string > (sal_uInt8*)ttf->ptr && rec_string < ((sal_uInt8*)ttf->ptr + ttf->fsize - rec[i].slen ) ) 2858*cdf0e10cSrcweir { 2859*cdf0e10cSrcweir rec[i].sptr = (sal_uInt8 *) malloc(rec[i].slen); assert(rec[i].sptr != 0); 2860*cdf0e10cSrcweir memcpy(rec[i].sptr, rec_string, rec[i].slen); 2861*cdf0e10cSrcweir } 2862*cdf0e10cSrcweir else 2863*cdf0e10cSrcweir { 2864*cdf0e10cSrcweir #ifdef DEBUG 2865*cdf0e10cSrcweir fprintf( stderr, "found invalid name record %d with name id %d for file %s\n", 2866*cdf0e10cSrcweir i, rec[i].nameID, ttf->fname ); 2867*cdf0e10cSrcweir #endif 2868*cdf0e10cSrcweir rec[i].sptr = 0; 2869*cdf0e10cSrcweir rec[i].slen = 0; 2870*cdf0e10cSrcweir } 2871*cdf0e10cSrcweir } else { 2872*cdf0e10cSrcweir rec[i].sptr = 0; 2873*cdf0e10cSrcweir } 2874*cdf0e10cSrcweir // some fonts have 3.0 names => fix them to 3.1 2875*cdf0e10cSrcweir if( (rec[i].platformID == 3) && (rec[i].encodingID == 0) ) 2876*cdf0e10cSrcweir rec[i].encodingID = 1; 2877*cdf0e10cSrcweir } 2878*cdf0e10cSrcweir 2879*cdf0e10cSrcweir *nr = rec; 2880*cdf0e10cSrcweir return n; 2881*cdf0e10cSrcweir } 2882*cdf0e10cSrcweir 2883*cdf0e10cSrcweir void DisposeNameRecords(NameRecord* nr, int n) 2884*cdf0e10cSrcweir { 2885*cdf0e10cSrcweir int i; 2886*cdf0e10cSrcweir for (i = 0; i < n; i++) { 2887*cdf0e10cSrcweir if (nr[i].sptr) free(nr[i].sptr); 2888*cdf0e10cSrcweir } 2889*cdf0e10cSrcweir free(nr); 2890*cdf0e10cSrcweir } 2891*cdf0e10cSrcweir 2892*cdf0e10cSrcweir } // namespace vcl 2893*cdf0e10cSrcweir 2894*cdf0e10cSrcweir 2895*cdf0e10cSrcweir #ifdef TEST1 2896*cdf0e10cSrcweir /* This example creates a subset of a TrueType font with two encoded characters */ 2897*cdf0e10cSrcweir int main(int ac, char **av) 2898*cdf0e10cSrcweir { 2899*cdf0e10cSrcweir TrueTypeFont *fnt; 2900*cdf0e10cSrcweir int r; 2901*cdf0e10cSrcweir 2902*cdf0e10cSrcweir /* Array of Unicode source characters */ 2903*cdf0e10cSrcweir sal_uInt16 chars[2]; 2904*cdf0e10cSrcweir 2905*cdf0e10cSrcweir /* Encoding vector maps character encoding to the ordinal number 2906*cdf0e10cSrcweir * of the glyph in the output file */ 2907*cdf0e10cSrcweir sal_uInt8 encoding[2]; 2908*cdf0e10cSrcweir 2909*cdf0e10cSrcweir /* This array is for glyph IDs that source characters map to */ 2910*cdf0e10cSrcweir sal_uInt16 g[2]; 2911*cdf0e10cSrcweir 2912*cdf0e10cSrcweir 2913*cdf0e10cSrcweir if (ac < 2) return 0; 2914*cdf0e10cSrcweir 2915*cdf0e10cSrcweir if ((r = OpenTTFont(av[1], 0, &fnt)) != SF_OK) { 2916*cdf0e10cSrcweir fprintf(stderr, "Error %d opening font file: `%s`.\n", r, av[1]); 2917*cdf0e10cSrcweir return 0; 2918*cdf0e10cSrcweir } 2919*cdf0e10cSrcweir 2920*cdf0e10cSrcweir 2921*cdf0e10cSrcweir /* We want to create the output file that only contains two Unicode characters: 2922*cdf0e10cSrcweir * L'a' and L'A' */ 2923*cdf0e10cSrcweir 2924*cdf0e10cSrcweir chars[0] = L'a'; 2925*cdf0e10cSrcweir chars[1] = L'A'; 2926*cdf0e10cSrcweir 2927*cdf0e10cSrcweir /* Figure out what glyphs do these characters map in our font */ 2928*cdf0e10cSrcweir MapString(fnt, chars, 2, g); 2929*cdf0e10cSrcweir 2930*cdf0e10cSrcweir /* Encode the characters. Value of encoding[i] is the number 0..255 which maps to glyph i of the 2931*cdf0e10cSrcweir * newly generated font */ 2932*cdf0e10cSrcweir encoding[0] = chars[0]; 2933*cdf0e10cSrcweir encoding[1] = chars[1]; 2934*cdf0e10cSrcweir 2935*cdf0e10cSrcweir 2936*cdf0e10cSrcweir /* Generate a subset */ 2937*cdf0e10cSrcweir CreateT3FromTTGlyphs(fnt, stdout, 0, g, encoding, 2, 0); 2938*cdf0e10cSrcweir 2939*cdf0e10cSrcweir /* Now call the dtor for the font */ 2940*cdf0e10cSrcweir CloseTTFont(fnt); 2941*cdf0e10cSrcweir return 0; 2942*cdf0e10cSrcweir } 2943*cdf0e10cSrcweir #endif 2944*cdf0e10cSrcweir 2945*cdf0e10cSrcweir #ifdef TEST2 2946*cdf0e10cSrcweir /* This example extracts first 224 glyphs from a TT fonts and encodes them starting at 32 */ 2947*cdf0e10cSrcweir int main(int ac, char **av) 2948*cdf0e10cSrcweir { 2949*cdf0e10cSrcweir TrueTypeFont *fnt; 2950*cdf0e10cSrcweir int i, r; 2951*cdf0e10cSrcweir 2952*cdf0e10cSrcweir /* Array of Unicode source characters */ 2953*cdf0e10cSrcweir sal_uInt16 glyphs[224]; 2954*cdf0e10cSrcweir 2955*cdf0e10cSrcweir /* Encoding vector maps character encoding to the ordinal number 2956*cdf0e10cSrcweir * of the glyph in the output file */ 2957*cdf0e10cSrcweir sal_uInt8 encoding[224]; 2958*cdf0e10cSrcweir 2959*cdf0e10cSrcweir 2960*cdf0e10cSrcweir 2961*cdf0e10cSrcweir for (i=0; i<224; i++) { 2962*cdf0e10cSrcweir glyphs[i] = i; 2963*cdf0e10cSrcweir encoding[i] = 32 + i; 2964*cdf0e10cSrcweir } 2965*cdf0e10cSrcweir 2966*cdf0e10cSrcweir if (ac < 2) return 0; 2967*cdf0e10cSrcweir 2968*cdf0e10cSrcweir if ((r = OpenTTFont(av[1], 0, &fnt)) != SF_OK) { 2969*cdf0e10cSrcweir fprintf(stderr, "Error %d opening font file: `%s`.\n", r, av[1]); 2970*cdf0e10cSrcweir return 0; 2971*cdf0e10cSrcweir } 2972*cdf0e10cSrcweir 2973*cdf0e10cSrcweir 2974*cdf0e10cSrcweir /* Encode the characters. Value of encoding[i] is the number 0..255 which maps to glyph i of the 2975*cdf0e10cSrcweir * newly generated font */ 2976*cdf0e10cSrcweir 2977*cdf0e10cSrcweir /* Generate a subset */ 2978*cdf0e10cSrcweir CreateT3FromTTGlyphs(fnt, stdout, 0, glyphs, encoding, 224, 0); 2979*cdf0e10cSrcweir 2980*cdf0e10cSrcweir /* Now call the dtor for the font */ 2981*cdf0e10cSrcweir CloseTTFont(fnt); 2982*cdf0e10cSrcweir return 0; 2983*cdf0e10cSrcweir } 2984*cdf0e10cSrcweir #endif 2985*cdf0e10cSrcweir 2986*cdf0e10cSrcweir #ifdef TEST3 2987*cdf0e10cSrcweir /* Glyph metrics example */ 2988*cdf0e10cSrcweir int main(int ac, char **av) 2989*cdf0e10cSrcweir { 2990*cdf0e10cSrcweir TrueTypeFont *fnt; 2991*cdf0e10cSrcweir int i, r; 2992*cdf0e10cSrcweir sal_uInt16 glyphs[224]; 2993*cdf0e10cSrcweir TTSimpleGlyphMetrics *m; 2994*cdf0e10cSrcweir 2995*cdf0e10cSrcweir for (i=0; i<224; i++) { 2996*cdf0e10cSrcweir glyphs[i] = i; 2997*cdf0e10cSrcweir } 2998*cdf0e10cSrcweir 2999*cdf0e10cSrcweir if (ac < 2) return 0; 3000*cdf0e10cSrcweir 3001*cdf0e10cSrcweir if ((r = OpenTTFont(av[1], 0, &fnt)) != SF_OK) { 3002*cdf0e10cSrcweir fprintf(stderr, "Error %d opening font file: `%s`.\n", r, av[1]); 3003*cdf0e10cSrcweir return 0; 3004*cdf0e10cSrcweir } 3005*cdf0e10cSrcweir 3006*cdf0e10cSrcweir if ((m = GetTTSimpleGlyphMetrics(fnt, glyphs, 224, 0)) == 0) { 3007*cdf0e10cSrcweir printf("Requested metrics is not available\n"); 3008*cdf0e10cSrcweir } else { 3009*cdf0e10cSrcweir for (i=0; i<224; i++) { 3010*cdf0e10cSrcweir printf("%d. advWid: %5d, LSBear: %5d\n", i, m[i].adv, m[i].sb); 3011*cdf0e10cSrcweir } 3012*cdf0e10cSrcweir } 3013*cdf0e10cSrcweir 3014*cdf0e10cSrcweir /* Now call the dtor for the font */ 3015*cdf0e10cSrcweir free(m); 3016*cdf0e10cSrcweir CloseTTFont(fnt); 3017*cdf0e10cSrcweir return 0; 3018*cdf0e10cSrcweir } 3019*cdf0e10cSrcweir #endif 3020*cdf0e10cSrcweir 3021*cdf0e10cSrcweir #ifdef TEST4 3022*cdf0e10cSrcweir int main(int ac, char **av) 3023*cdf0e10cSrcweir { 3024*cdf0e10cSrcweir TrueTypeFont *fnt; 3025*cdf0e10cSrcweir TTGlobalFontInfo info; 3026*cdf0e10cSrcweir int i, r; 3027*cdf0e10cSrcweir 3028*cdf0e10cSrcweir 3029*cdf0e10cSrcweir if ((r = OpenTTFont(av[1], 0, &fnt)) != SF_OK) { 3030*cdf0e10cSrcweir fprintf(stderr, "Error %d opening font file: `%s`.\n", r, av[1]); 3031*cdf0e10cSrcweir return 0; 3032*cdf0e10cSrcweir } 3033*cdf0e10cSrcweir 3034*cdf0e10cSrcweir printf("Font file: %s\n", av[1]); 3035*cdf0e10cSrcweir 3036*cdf0e10cSrcweir #ifdef PRINT_KERN 3037*cdf0e10cSrcweir switch (fnt->kerntype) { 3038*cdf0e10cSrcweir case KT_MICROSOFT: 3039*cdf0e10cSrcweir printf("\tkern: MICROSOFT, ntables: %d.", fnt->nkern); 3040*cdf0e10cSrcweir if (fnt->nkern) { 3041*cdf0e10cSrcweir printf(" ["); 3042*cdf0e10cSrcweir for (i=0; i<fnt->nkern; i++) { 3043*cdf0e10cSrcweir printf("%04X ", GetUInt16(fnt->kerntables[i], 4, 1)); 3044*cdf0e10cSrcweir } 3045*cdf0e10cSrcweir printf("]"); 3046*cdf0e10cSrcweir } 3047*cdf0e10cSrcweir printf("\n"); 3048*cdf0e10cSrcweir break; 3049*cdf0e10cSrcweir 3050*cdf0e10cSrcweir case KT_APPLE_NEW: 3051*cdf0e10cSrcweir printf("\tkern: APPLE_NEW, ntables: %d.", fnt->nkern); 3052*cdf0e10cSrcweir if (fnt->nkern) { 3053*cdf0e10cSrcweir printf(" ["); 3054*cdf0e10cSrcweir for (i=0; i<fnt->nkern; i++) { 3055*cdf0e10cSrcweir printf("%04X ", GetUInt16(fnt->kerntables[i], 4, 1)); 3056*cdf0e10cSrcweir } 3057*cdf0e10cSrcweir printf("]"); 3058*cdf0e10cSrcweir } 3059*cdf0e10cSrcweir printf("\n"); 3060*cdf0e10cSrcweir break; 3061*cdf0e10cSrcweir 3062*cdf0e10cSrcweir case KT_NONE: 3063*cdf0e10cSrcweir printf("\tkern: none.\n"); 3064*cdf0e10cSrcweir break; 3065*cdf0e10cSrcweir 3066*cdf0e10cSrcweir default: 3067*cdf0e10cSrcweir printf("\tkern: unrecoginzed.\n"); 3068*cdf0e10cSrcweir break; 3069*cdf0e10cSrcweir } 3070*cdf0e10cSrcweir printf("\n"); 3071*cdf0e10cSrcweir #endif 3072*cdf0e10cSrcweir 3073*cdf0e10cSrcweir GetTTGlobalFontInfo(fnt, &info); 3074*cdf0e10cSrcweir printf("\tfamily name: `%s`\n", info.family); 3075*cdf0e10cSrcweir printf("\tsubfamily name: `%s`\n", info.subfamily); 3076*cdf0e10cSrcweir printf("\tpostscript name: `%s`\n", info.psname); 3077*cdf0e10cSrcweir printf("\tweight: %d\n", info.weight); 3078*cdf0e10cSrcweir printf("\twidth: %d\n", info.width); 3079*cdf0e10cSrcweir printf("\tpitch: %d\n", info.pitch); 3080*cdf0e10cSrcweir printf("\titalic angle: %d\n", info.italicAngle); 3081*cdf0e10cSrcweir printf("\tbouding box: [%d %d %d %d]\n", info.xMin, info.yMin, info.xMax, info.yMax); 3082*cdf0e10cSrcweir printf("\tascender: %d\n", info.ascender); 3083*cdf0e10cSrcweir printf("\tdescender: %d\n", info.descender); 3084*cdf0e10cSrcweir printf("\tlinegap: %d\n", info.linegap); 3085*cdf0e10cSrcweir printf("\tvascent: %d\n", info.vascent); 3086*cdf0e10cSrcweir printf("\tvdescent: %d\n", info.vdescent); 3087*cdf0e10cSrcweir printf("\ttypoAscender: %d\n", info.typoAscender); 3088*cdf0e10cSrcweir printf("\ttypoDescender: %d\n", info.typoDescender); 3089*cdf0e10cSrcweir printf("\ttypoLineGap: %d\n", info.typoLineGap); 3090*cdf0e10cSrcweir printf("\twinAscent: %d\n", info.winAscent); 3091*cdf0e10cSrcweir printf("\twinDescent: %d\n", info.winDescent); 3092*cdf0e10cSrcweir printf("\tUnicode ranges:\n"); 3093*cdf0e10cSrcweir for (i = 0; i < 32; i++) { 3094*cdf0e10cSrcweir if ((info.ur1 >> i) & 1) { 3095*cdf0e10cSrcweir printf("\t\t\t%s\n", UnicodeRangeName(i)); 3096*cdf0e10cSrcweir } 3097*cdf0e10cSrcweir } 3098*cdf0e10cSrcweir for (i = 0; i < 32; i++) { 3099*cdf0e10cSrcweir if ((info.ur2 >> i) & 1) { 3100*cdf0e10cSrcweir printf("\t\t\t%s\n", UnicodeRangeName(i+32)); 3101*cdf0e10cSrcweir } 3102*cdf0e10cSrcweir } 3103*cdf0e10cSrcweir for (i = 0; i < 32; i++) { 3104*cdf0e10cSrcweir if ((info.ur3 >> i) & 1) { 3105*cdf0e10cSrcweir printf("\t\t\t%s\n", UnicodeRangeName(i+64)); 3106*cdf0e10cSrcweir } 3107*cdf0e10cSrcweir } 3108*cdf0e10cSrcweir for (i = 0; i < 32; i++) { 3109*cdf0e10cSrcweir if ((info.ur4 >> i) & 1) { 3110*cdf0e10cSrcweir printf("\t\t\t%s\n", UnicodeRangeName(i+96)); 3111*cdf0e10cSrcweir } 3112*cdf0e10cSrcweir } 3113*cdf0e10cSrcweir 3114*cdf0e10cSrcweir CloseTTFont(fnt); 3115*cdf0e10cSrcweir return 0; 3116*cdf0e10cSrcweir } 3117*cdf0e10cSrcweir #endif 3118*cdf0e10cSrcweir 3119*cdf0e10cSrcweir #ifdef TEST5 3120*cdf0e10cSrcweir /* Kerning example */ 3121*cdf0e10cSrcweir int main(int ac, char **av) 3122*cdf0e10cSrcweir { 3123*cdf0e10cSrcweir TrueTypeFont *fnt; 3124*cdf0e10cSrcweir sal_uInt16 g[224]; 3125*cdf0e10cSrcweir KernData d[223]; 3126*cdf0e10cSrcweir int r, i, k = 0; 3127*cdf0e10cSrcweir 3128*cdf0e10cSrcweir g[k++] = 11; 3129*cdf0e10cSrcweir g[k++] = 36; 3130*cdf0e10cSrcweir g[k++] = 11; 3131*cdf0e10cSrcweir g[k++] = 98; 3132*cdf0e10cSrcweir g[k++] = 11; 3133*cdf0e10cSrcweir g[k++] = 144; 3134*cdf0e10cSrcweir g[k++] = 41; 3135*cdf0e10cSrcweir g[k++] = 171; 3136*cdf0e10cSrcweir g[k++] = 51; 3137*cdf0e10cSrcweir g[k++] = 15; 3138*cdf0e10cSrcweir 3139*cdf0e10cSrcweir if (ac < 2) return 0; 3140*cdf0e10cSrcweir 3141*cdf0e10cSrcweir if ((r = OpenTTFont(av[1], 0, &fnt)) != SF_OK) { 3142*cdf0e10cSrcweir fprintf(stderr, "Error %d opening font file: `%s`.\n", r, av[1]); 3143*cdf0e10cSrcweir return 0; 3144*cdf0e10cSrcweir } 3145*cdf0e10cSrcweir 3146*cdf0e10cSrcweir KernGlyphs(fnt, g, k, 0, d); 3147*cdf0e10cSrcweir 3148*cdf0e10cSrcweir for (i = 0; i < k-1; i++) { 3149*cdf0e10cSrcweir printf("%3d %3d: [%3d %3d]\n", g[i], g[i+1], d[i].x, d[i].y); 3150*cdf0e10cSrcweir } 3151*cdf0e10cSrcweir 3152*cdf0e10cSrcweir CloseTTFont(fnt); 3153*cdf0e10cSrcweir return 0; 3154*cdf0e10cSrcweir } 3155*cdf0e10cSrcweir #endif 3156*cdf0e10cSrcweir 3157*cdf0e10cSrcweir 3158*cdf0e10cSrcweir 3159*cdf0e10cSrcweir #ifdef TEST6 3160*cdf0e10cSrcweir /* This example extracts a single glyph from a font */ 3161*cdf0e10cSrcweir int main(int ac, char **av) 3162*cdf0e10cSrcweir { 3163*cdf0e10cSrcweir TrueTypeFont *fnt; 3164*cdf0e10cSrcweir int r, i; 3165*cdf0e10cSrcweir 3166*cdf0e10cSrcweir sal_uInt16 glyphs[256]; 3167*cdf0e10cSrcweir sal_uInt8 encoding[256]; 3168*cdf0e10cSrcweir 3169*cdf0e10cSrcweir for (i=0; i<256; i++) { 3170*cdf0e10cSrcweir glyphs[i] = 512 + i; 3171*cdf0e10cSrcweir encoding[i] = i; 3172*cdf0e10cSrcweir } 3173*cdf0e10cSrcweir 3174*cdf0e10cSrcweir #if 0 3175*cdf0e10cSrcweir i=0; 3176*cdf0e10cSrcweir glyphs[i++] = 2001; 3177*cdf0e10cSrcweir glyphs[i++] = 2002; 3178*cdf0e10cSrcweir glyphs[i++] = 2003; 3179*cdf0e10cSrcweir glyphs[i++] = 2004; 3180*cdf0e10cSrcweir glyphs[i++] = 2005; 3181*cdf0e10cSrcweir glyphs[i++] = 2006; 3182*cdf0e10cSrcweir glyphs[i++] = 2007; 3183*cdf0e10cSrcweir glyphs[i++] = 2008; 3184*cdf0e10cSrcweir glyphs[i++] = 2009; 3185*cdf0e10cSrcweir glyphs[i++] = 2010; 3186*cdf0e10cSrcweir glyphs[i++] = 2011; 3187*cdf0e10cSrcweir glyphs[i++] = 2012; 3188*cdf0e10cSrcweir glyphs[i++] = 2013; 3189*cdf0e10cSrcweir glyphs[i++] = 2014; 3190*cdf0e10cSrcweir glyphs[i++] = 2015; 3191*cdf0e10cSrcweir glyphs[i++] = 2016; 3192*cdf0e10cSrcweir glyphs[i++] = 2017; 3193*cdf0e10cSrcweir glyphs[i++] = 2018; 3194*cdf0e10cSrcweir glyphs[i++] = 2019; 3195*cdf0e10cSrcweir glyphs[i++] = 2020; 3196*cdf0e10cSrcweir 3197*cdf0e10cSrcweir 3198*cdf0e10cSrcweir r = 97; 3199*cdf0e10cSrcweir i = 0; 3200*cdf0e10cSrcweir encoding[i++] = r++; 3201*cdf0e10cSrcweir encoding[i++] = r++; 3202*cdf0e10cSrcweir encoding[i++] = r++; 3203*cdf0e10cSrcweir encoding[i++] = r++; 3204*cdf0e10cSrcweir encoding[i++] = r++; 3205*cdf0e10cSrcweir encoding[i++] = r++; 3206*cdf0e10cSrcweir encoding[i++] = r++; 3207*cdf0e10cSrcweir encoding[i++] = r++; 3208*cdf0e10cSrcweir encoding[i++] = r++; 3209*cdf0e10cSrcweir encoding[i++] = r++; 3210*cdf0e10cSrcweir encoding[i++] = r++; 3211*cdf0e10cSrcweir encoding[i++] = r++; 3212*cdf0e10cSrcweir encoding[i++] = r++; 3213*cdf0e10cSrcweir encoding[i++] = r++; 3214*cdf0e10cSrcweir encoding[i++] = r++; 3215*cdf0e10cSrcweir encoding[i++] = r++; 3216*cdf0e10cSrcweir encoding[i++] = r++; 3217*cdf0e10cSrcweir encoding[i++] = r++; 3218*cdf0e10cSrcweir encoding[i++] = r++; 3219*cdf0e10cSrcweir encoding[i++] = r++; 3220*cdf0e10cSrcweir #endif 3221*cdf0e10cSrcweir 3222*cdf0e10cSrcweir if (ac < 2) return 0; 3223*cdf0e10cSrcweir 3224*cdf0e10cSrcweir if ((r = OpenTTFont(av[1], 0, &fnt)) != SF_OK) { 3225*cdf0e10cSrcweir fprintf(stderr, "Error %d opening font file: `%s`.\n", r, av[1]); 3226*cdf0e10cSrcweir return 0; 3227*cdf0e10cSrcweir } 3228*cdf0e10cSrcweir 3229*cdf0e10cSrcweir /* Generate a subset */ 3230*cdf0e10cSrcweir CreateT3FromTTGlyphs(fnt, stdout, 0, glyphs, encoding, 256, 0); 3231*cdf0e10cSrcweir 3232*cdf0e10cSrcweir fprintf(stderr, "UnitsPerEm: %d.\n", fnt->unitsPerEm); 3233*cdf0e10cSrcweir 3234*cdf0e10cSrcweir /* Now call the dtor for the font */ 3235*cdf0e10cSrcweir CloseTTFont(fnt); 3236*cdf0e10cSrcweir return 0; 3237*cdf0e10cSrcweir } 3238*cdf0e10cSrcweir #endif 3239*cdf0e10cSrcweir 3240*cdf0e10cSrcweir #ifdef TEST7 3241*cdf0e10cSrcweir /* NameRecord extraction example */ 3242*cdf0e10cSrcweir int main(int ac, char **av) 3243*cdf0e10cSrcweir { 3244*cdf0e10cSrcweir TrueTypeFont *fnt; 3245*cdf0e10cSrcweir int r, i, j, n; 3246*cdf0e10cSrcweir NameRecord *nr; 3247*cdf0e10cSrcweir 3248*cdf0e10cSrcweir if ((r = OpenTTFont(av[1], 0, &fnt)) != SF_OK) { 3249*cdf0e10cSrcweir fprintf(stderr, "Error %d opening font file: `%s`.\n", r, av[1]); 3250*cdf0e10cSrcweir return 0; 3251*cdf0e10cSrcweir } 3252*cdf0e10cSrcweir 3253*cdf0e10cSrcweir if ((n = GetTTNameRecords(fnt, &nr)) == 0) { 3254*cdf0e10cSrcweir fprintf(stderr, "No name records in the font.\n"); 3255*cdf0e10cSrcweir return 0; 3256*cdf0e10cSrcweir } 3257*cdf0e10cSrcweir 3258*cdf0e10cSrcweir printf("Number of name records: %d.\n", n); 3259*cdf0e10cSrcweir for (i = 0; i < n; i++) { 3260*cdf0e10cSrcweir printf("%d %d %04X %d [", nr[i].platformID, nr[i].encodingID, nr[i].languageID, nr[i].nameID); 3261*cdf0e10cSrcweir for (j=0; j<nr[i].slen; j++) { 3262*cdf0e10cSrcweir printf("%c", isprint(nr[i].sptr[j]) ? nr[i].sptr[j] : '.'); 3263*cdf0e10cSrcweir } 3264*cdf0e10cSrcweir printf("]\n"); 3265*cdf0e10cSrcweir } 3266*cdf0e10cSrcweir 3267*cdf0e10cSrcweir 3268*cdf0e10cSrcweir DisposeNameRecords(nr, n); 3269*cdf0e10cSrcweir CloseTTFont(fnt); 3270*cdf0e10cSrcweir return 0; 3271*cdf0e10cSrcweir } 3272*cdf0e10cSrcweir #endif 3273*cdf0e10cSrcweir 3274*cdf0e10cSrcweir #ifdef TEST8 3275*cdf0e10cSrcweir /* TrueType -> TrueType subsetting */ 3276*cdf0e10cSrcweir int main(int ac, char **av) 3277*cdf0e10cSrcweir { 3278*cdf0e10cSrcweir TrueTypeFont *fnt; 3279*cdf0e10cSrcweir sal_uInt16 glyphArray[] = { 0, 98, 99, 22, 24, 25, 26, 27, 28, 29, 30, 31, 1270, 1289, 34}; 3280*cdf0e10cSrcweir sal_uInt8 encoding[] = {32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46}; 3281*cdf0e10cSrcweir int r; 3282*cdf0e10cSrcweir 3283*cdf0e10cSrcweir if ((r = OpenTTFont(av[1], 0, &fnt)) != SF_OK) { 3284*cdf0e10cSrcweir fprintf(stderr, "Error %d opening font file: `%s`.\n", r, av[1]); 3285*cdf0e10cSrcweir return 0; 3286*cdf0e10cSrcweir } 3287*cdf0e10cSrcweir 3288*cdf0e10cSrcweir CreateTTFromTTGlyphs(fnt, "subfont.ttf", glyphArray, encoding, 15, 0, 0, TTCF_AutoName | TTCF_IncludeOS2); 3289*cdf0e10cSrcweir 3290*cdf0e10cSrcweir 3291*cdf0e10cSrcweir CloseTTFont(fnt); 3292*cdf0e10cSrcweir 3293*cdf0e10cSrcweir return 0; 3294*cdf0e10cSrcweir } 3295*cdf0e10cSrcweir #endif 3296*cdf0e10cSrcweir 3297*cdf0e10cSrcweir #ifdef TEST9 3298*cdf0e10cSrcweir /* TrueType -> Type42 subsetting */ 3299*cdf0e10cSrcweir int main(int ac, char **av) 3300*cdf0e10cSrcweir { 3301*cdf0e10cSrcweir TrueTypeFont *fnt; 3302*cdf0e10cSrcweir /* 3303*cdf0e10cSrcweir sal_uInt16 glyphArray[] = { 0, 20, 21, 22, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34}; 3304*cdf0e10cSrcweir sal_uInt8 encoding[] = {32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46}; 3305*cdf0e10cSrcweir */ 3306*cdf0e10cSrcweir sal_uInt16 glyphArray[] = { 0, 6711, 6724, 11133, 11144, 14360, 26, 27, 28, 29, 30, 31, 1270, 1289, 34}; 3307*cdf0e10cSrcweir sal_uInt8 encoding[] = {32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46}; 3308*cdf0e10cSrcweir int r; 3309*cdf0e10cSrcweir 3310*cdf0e10cSrcweir if ((r = OpenTTFont(av[1], 0, &fnt)) != SF_OK) { 3311*cdf0e10cSrcweir fprintf(stderr, "Error %d opening font file: `%s`.\n", r, av[1]); 3312*cdf0e10cSrcweir return 0; 3313*cdf0e10cSrcweir } 3314*cdf0e10cSrcweir 3315*cdf0e10cSrcweir CreateT42FromTTGlyphs(fnt, stdout, "testfont", glyphArray, encoding, 15); 3316*cdf0e10cSrcweir 3317*cdf0e10cSrcweir CloseTTFont(fnt); 3318*cdf0e10cSrcweir 3319*cdf0e10cSrcweir return 0; 3320*cdf0e10cSrcweir } 3321*cdf0e10cSrcweir #endif 3322*cdf0e10cSrcweir 3323*cdf0e10cSrcweir #ifdef TEST10 3324*cdf0e10cSrcweir /* Component glyph test */ 3325*cdf0e10cSrcweir int main(int ac, char **av) 3326*cdf0e10cSrcweir { 3327*cdf0e10cSrcweir TrueTypeFont *fnt; 3328*cdf0e10cSrcweir int r, i; 3329*cdf0e10cSrcweir list glyphlist = listNewEmpty(); 3330*cdf0e10cSrcweir 3331*cdf0e10cSrcweir 3332*cdf0e10cSrcweir if ((r = OpenTTFont(av[1], 0, &fnt)) != SF_OK) { 3333*cdf0e10cSrcweir fprintf(stderr, "Error %d opening font file: `%s`.\n", r, av[1]); 3334*cdf0e10cSrcweir return 0; 3335*cdf0e10cSrcweir } 3336*cdf0e10cSrcweir 3337*cdf0e10cSrcweir for (i = 0; i < fnt->nglyphs; i++) { 3338*cdf0e10cSrcweir r = GetTTGlyphComponents(fnt, i, glyphlist); 3339*cdf0e10cSrcweir if (r > 1) { 3340*cdf0e10cSrcweir printf("%d -> ", i); 3341*cdf0e10cSrcweir listToFirst(glyphlist); 3342*cdf0e10cSrcweir do { 3343*cdf0e10cSrcweir printf("%d ", (int) listCurrent(glyphlist)); 3344*cdf0e10cSrcweir } while (listNext(glyphlist)); 3345*cdf0e10cSrcweir printf("\n"); 3346*cdf0e10cSrcweir } else { 3347*cdf0e10cSrcweir printf("%d: single glyph.\n", i); 3348*cdf0e10cSrcweir } 3349*cdf0e10cSrcweir listClear(glyphlist); 3350*cdf0e10cSrcweir } 3351*cdf0e10cSrcweir 3352*cdf0e10cSrcweir CloseTTFont(fnt); 3353*cdf0e10cSrcweir listDispose(glyphlist); 3354*cdf0e10cSrcweir 3355*cdf0e10cSrcweir return 0; 3356*cdf0e10cSrcweir } 3357*cdf0e10cSrcweir #endif 3358*cdf0e10cSrcweir 3359*cdf0e10cSrcweir 3360