1*37da2899SCharles.Forsyth /***************************************************************************/ 2*37da2899SCharles.Forsyth /* */ 3*37da2899SCharles.Forsyth /* pfrsbit.c */ 4*37da2899SCharles.Forsyth /* */ 5*37da2899SCharles.Forsyth /* FreeType PFR bitmap loader (body). */ 6*37da2899SCharles.Forsyth /* */ 7*37da2899SCharles.Forsyth /* Copyright 2002 by */ 8*37da2899SCharles.Forsyth /* David Turner, Robert Wilhelm, and Werner Lemberg. */ 9*37da2899SCharles.Forsyth /* */ 10*37da2899SCharles.Forsyth /* This file is part of the FreeType project, and may only be used, */ 11*37da2899SCharles.Forsyth /* modified, and distributed under the terms of the FreeType project */ 12*37da2899SCharles.Forsyth /* license, LICENSE.TXT. By continuing to use, modify, or distribute */ 13*37da2899SCharles.Forsyth /* this file you indicate that you have read the license and */ 14*37da2899SCharles.Forsyth /* understand and accept it fully. */ 15*37da2899SCharles.Forsyth /* */ 16*37da2899SCharles.Forsyth /***************************************************************************/ 17*37da2899SCharles.Forsyth 18*37da2899SCharles.Forsyth 19*37da2899SCharles.Forsyth #include "pfrsbit.h" 20*37da2899SCharles.Forsyth #include "pfrload.h" 21*37da2899SCharles.Forsyth #include FT_INTERNAL_DEBUG_H 22*37da2899SCharles.Forsyth #include FT_INTERNAL_STREAM_H 23*37da2899SCharles.Forsyth 24*37da2899SCharles.Forsyth #include "pfrerror.h" 25*37da2899SCharles.Forsyth 26*37da2899SCharles.Forsyth #undef FT_COMPONENT 27*37da2899SCharles.Forsyth #define FT_COMPONENT trace_pfr 28*37da2899SCharles.Forsyth 29*37da2899SCharles.Forsyth 30*37da2899SCharles.Forsyth /*************************************************************************/ 31*37da2899SCharles.Forsyth /*************************************************************************/ 32*37da2899SCharles.Forsyth /***** *****/ 33*37da2899SCharles.Forsyth /***** PFR BIT WRITER *****/ 34*37da2899SCharles.Forsyth /***** *****/ 35*37da2899SCharles.Forsyth /*************************************************************************/ 36*37da2899SCharles.Forsyth /*************************************************************************/ 37*37da2899SCharles.Forsyth 38*37da2899SCharles.Forsyth typedef struct PFR_BitWriter_ 39*37da2899SCharles.Forsyth { 40*37da2899SCharles.Forsyth FT_Byte* line; /* current line start */ 41*37da2899SCharles.Forsyth FT_Int pitch; /* line size in bytes */ 42*37da2899SCharles.Forsyth FT_Int width; /* width in pixels/bits */ 43*37da2899SCharles.Forsyth FT_Int rows; /* number of remaining rows to scan */ 44*37da2899SCharles.Forsyth FT_Int total; /* total number of bits to draw */ 45*37da2899SCharles.Forsyth 46*37da2899SCharles.Forsyth } PFR_BitWriterRec, *PFR_BitWriter; 47*37da2899SCharles.Forsyth 48*37da2899SCharles.Forsyth 49*37da2899SCharles.Forsyth static void pfr_bitwriter_init(PFR_BitWriter writer,FT_Bitmap * target,FT_Bool decreasing)50*37da2899SCharles.Forsyth pfr_bitwriter_init( PFR_BitWriter writer, 51*37da2899SCharles.Forsyth FT_Bitmap* target, 52*37da2899SCharles.Forsyth FT_Bool decreasing ) 53*37da2899SCharles.Forsyth { 54*37da2899SCharles.Forsyth writer->line = target->buffer; 55*37da2899SCharles.Forsyth writer->pitch = target->pitch; 56*37da2899SCharles.Forsyth writer->width = target->width; 57*37da2899SCharles.Forsyth writer->rows = target->rows; 58*37da2899SCharles.Forsyth writer->total = writer->width * writer->rows; 59*37da2899SCharles.Forsyth 60*37da2899SCharles.Forsyth if ( !decreasing ) 61*37da2899SCharles.Forsyth { 62*37da2899SCharles.Forsyth writer->line += writer->pitch * ( target->rows-1 ); 63*37da2899SCharles.Forsyth writer->pitch = -writer->pitch; 64*37da2899SCharles.Forsyth } 65*37da2899SCharles.Forsyth } 66*37da2899SCharles.Forsyth 67*37da2899SCharles.Forsyth 68*37da2899SCharles.Forsyth static void pfr_bitwriter_decode_bytes(PFR_BitWriter writer,FT_Byte * p,FT_Byte * limit)69*37da2899SCharles.Forsyth pfr_bitwriter_decode_bytes( PFR_BitWriter writer, 70*37da2899SCharles.Forsyth FT_Byte* p, 71*37da2899SCharles.Forsyth FT_Byte* limit ) 72*37da2899SCharles.Forsyth { 73*37da2899SCharles.Forsyth FT_Int n, reload; 74*37da2899SCharles.Forsyth FT_Int left = writer->width; 75*37da2899SCharles.Forsyth FT_Byte* cur = writer->line; 76*37da2899SCharles.Forsyth FT_UInt mask = 0x80; 77*37da2899SCharles.Forsyth FT_UInt val = 0; 78*37da2899SCharles.Forsyth FT_UInt c = 0; 79*37da2899SCharles.Forsyth 80*37da2899SCharles.Forsyth 81*37da2899SCharles.Forsyth n = (FT_Int)( limit - p ) * 8; 82*37da2899SCharles.Forsyth if ( n > writer->total ) 83*37da2899SCharles.Forsyth n = writer->total; 84*37da2899SCharles.Forsyth 85*37da2899SCharles.Forsyth reload = n & 7; 86*37da2899SCharles.Forsyth 87*37da2899SCharles.Forsyth for ( ; n > 0; n-- ) 88*37da2899SCharles.Forsyth { 89*37da2899SCharles.Forsyth if ( ( n & 7 ) == reload ) 90*37da2899SCharles.Forsyth val = *p++; 91*37da2899SCharles.Forsyth 92*37da2899SCharles.Forsyth if ( val & 0x80 ) 93*37da2899SCharles.Forsyth c |= mask; 94*37da2899SCharles.Forsyth 95*37da2899SCharles.Forsyth val <<= 1; 96*37da2899SCharles.Forsyth mask >>= 1; 97*37da2899SCharles.Forsyth 98*37da2899SCharles.Forsyth if ( --left <= 0 ) 99*37da2899SCharles.Forsyth { 100*37da2899SCharles.Forsyth cur[0] = (FT_Byte)c; 101*37da2899SCharles.Forsyth left = writer->width; 102*37da2899SCharles.Forsyth mask = 0x80; 103*37da2899SCharles.Forsyth 104*37da2899SCharles.Forsyth writer->line += writer->pitch; 105*37da2899SCharles.Forsyth cur = writer->line; 106*37da2899SCharles.Forsyth c = 0; 107*37da2899SCharles.Forsyth } 108*37da2899SCharles.Forsyth else if ( mask == 0 ) 109*37da2899SCharles.Forsyth { 110*37da2899SCharles.Forsyth cur[0] = c; 111*37da2899SCharles.Forsyth mask = 0x80; 112*37da2899SCharles.Forsyth c = 0; 113*37da2899SCharles.Forsyth cur ++; 114*37da2899SCharles.Forsyth } 115*37da2899SCharles.Forsyth } 116*37da2899SCharles.Forsyth 117*37da2899SCharles.Forsyth if ( mask != 0x80 ) 118*37da2899SCharles.Forsyth cur[0] = c; 119*37da2899SCharles.Forsyth } 120*37da2899SCharles.Forsyth 121*37da2899SCharles.Forsyth 122*37da2899SCharles.Forsyth static void pfr_bitwriter_decode_rle1(PFR_BitWriter writer,FT_Byte * p,FT_Byte * limit)123*37da2899SCharles.Forsyth pfr_bitwriter_decode_rle1( PFR_BitWriter writer, 124*37da2899SCharles.Forsyth FT_Byte* p, 125*37da2899SCharles.Forsyth FT_Byte* limit ) 126*37da2899SCharles.Forsyth { 127*37da2899SCharles.Forsyth FT_Int n, phase, count, counts[2], reload; 128*37da2899SCharles.Forsyth FT_Int left = writer->width; 129*37da2899SCharles.Forsyth FT_Byte* cur = writer->line; 130*37da2899SCharles.Forsyth FT_UInt mask = 0x80; 131*37da2899SCharles.Forsyth FT_UInt c = 0; 132*37da2899SCharles.Forsyth 133*37da2899SCharles.Forsyth 134*37da2899SCharles.Forsyth n = writer->total; 135*37da2899SCharles.Forsyth 136*37da2899SCharles.Forsyth phase = 1; 137*37da2899SCharles.Forsyth counts[0] = 0; 138*37da2899SCharles.Forsyth counts[1] = 0; 139*37da2899SCharles.Forsyth count = 0; 140*37da2899SCharles.Forsyth reload = 1; 141*37da2899SCharles.Forsyth 142*37da2899SCharles.Forsyth for ( ; n > 0; n-- ) 143*37da2899SCharles.Forsyth { 144*37da2899SCharles.Forsyth if ( reload ) 145*37da2899SCharles.Forsyth { 146*37da2899SCharles.Forsyth do 147*37da2899SCharles.Forsyth { 148*37da2899SCharles.Forsyth if ( phase ) 149*37da2899SCharles.Forsyth { 150*37da2899SCharles.Forsyth FT_Int v; 151*37da2899SCharles.Forsyth 152*37da2899SCharles.Forsyth 153*37da2899SCharles.Forsyth if ( p >= limit ) 154*37da2899SCharles.Forsyth break; 155*37da2899SCharles.Forsyth 156*37da2899SCharles.Forsyth v = *p++; 157*37da2899SCharles.Forsyth counts[0] = v >> 4; 158*37da2899SCharles.Forsyth counts[1] = v & 15; 159*37da2899SCharles.Forsyth phase = 0; 160*37da2899SCharles.Forsyth count = counts[0]; 161*37da2899SCharles.Forsyth } 162*37da2899SCharles.Forsyth else 163*37da2899SCharles.Forsyth { 164*37da2899SCharles.Forsyth phase = 1; 165*37da2899SCharles.Forsyth count = counts[1]; 166*37da2899SCharles.Forsyth } 167*37da2899SCharles.Forsyth 168*37da2899SCharles.Forsyth } while ( count == 0 ); 169*37da2899SCharles.Forsyth } 170*37da2899SCharles.Forsyth 171*37da2899SCharles.Forsyth if ( phase ) 172*37da2899SCharles.Forsyth c |= mask; 173*37da2899SCharles.Forsyth 174*37da2899SCharles.Forsyth mask >>= 1; 175*37da2899SCharles.Forsyth 176*37da2899SCharles.Forsyth if ( --left <= 0 ) 177*37da2899SCharles.Forsyth { 178*37da2899SCharles.Forsyth cur[0] = (FT_Byte) c; 179*37da2899SCharles.Forsyth left = writer->width; 180*37da2899SCharles.Forsyth mask = 0x80; 181*37da2899SCharles.Forsyth 182*37da2899SCharles.Forsyth writer->line += writer->pitch; 183*37da2899SCharles.Forsyth cur = writer->line; 184*37da2899SCharles.Forsyth c = 0; 185*37da2899SCharles.Forsyth } 186*37da2899SCharles.Forsyth else if ( mask == 0 ) 187*37da2899SCharles.Forsyth { 188*37da2899SCharles.Forsyth cur[0] = c; 189*37da2899SCharles.Forsyth mask = 0x80; 190*37da2899SCharles.Forsyth c = 0; 191*37da2899SCharles.Forsyth cur ++; 192*37da2899SCharles.Forsyth } 193*37da2899SCharles.Forsyth 194*37da2899SCharles.Forsyth reload = ( --count <= 0 ); 195*37da2899SCharles.Forsyth } 196*37da2899SCharles.Forsyth 197*37da2899SCharles.Forsyth if ( mask != 0x80 ) 198*37da2899SCharles.Forsyth cur[0] = (FT_Byte) c; 199*37da2899SCharles.Forsyth } 200*37da2899SCharles.Forsyth 201*37da2899SCharles.Forsyth 202*37da2899SCharles.Forsyth static void pfr_bitwriter_decode_rle2(PFR_BitWriter writer,FT_Byte * p,FT_Byte * limit)203*37da2899SCharles.Forsyth pfr_bitwriter_decode_rle2( PFR_BitWriter writer, 204*37da2899SCharles.Forsyth FT_Byte* p, 205*37da2899SCharles.Forsyth FT_Byte* limit ) 206*37da2899SCharles.Forsyth { 207*37da2899SCharles.Forsyth FT_Int n, phase, count, reload; 208*37da2899SCharles.Forsyth FT_Int left = writer->width; 209*37da2899SCharles.Forsyth FT_Byte* cur = writer->line; 210*37da2899SCharles.Forsyth FT_UInt mask = 0x80; 211*37da2899SCharles.Forsyth FT_UInt c = 0; 212*37da2899SCharles.Forsyth 213*37da2899SCharles.Forsyth 214*37da2899SCharles.Forsyth n = writer->total; 215*37da2899SCharles.Forsyth 216*37da2899SCharles.Forsyth phase = 1; 217*37da2899SCharles.Forsyth count = 0; 218*37da2899SCharles.Forsyth reload = 1; 219*37da2899SCharles.Forsyth 220*37da2899SCharles.Forsyth for ( ; n > 0; n-- ) 221*37da2899SCharles.Forsyth { 222*37da2899SCharles.Forsyth if ( reload ) 223*37da2899SCharles.Forsyth { 224*37da2899SCharles.Forsyth do 225*37da2899SCharles.Forsyth { 226*37da2899SCharles.Forsyth if ( p >= limit ) 227*37da2899SCharles.Forsyth break; 228*37da2899SCharles.Forsyth 229*37da2899SCharles.Forsyth count = *p++; 230*37da2899SCharles.Forsyth phase = phase ^ 1; 231*37da2899SCharles.Forsyth 232*37da2899SCharles.Forsyth } while ( count == 0 ); 233*37da2899SCharles.Forsyth } 234*37da2899SCharles.Forsyth 235*37da2899SCharles.Forsyth if ( phase ) 236*37da2899SCharles.Forsyth c |= mask; 237*37da2899SCharles.Forsyth 238*37da2899SCharles.Forsyth mask >>= 1; 239*37da2899SCharles.Forsyth 240*37da2899SCharles.Forsyth if ( --left <= 0 ) 241*37da2899SCharles.Forsyth { 242*37da2899SCharles.Forsyth cur[0] = (FT_Byte) c; 243*37da2899SCharles.Forsyth c = 0; 244*37da2899SCharles.Forsyth mask = 0x80; 245*37da2899SCharles.Forsyth left = writer->width; 246*37da2899SCharles.Forsyth 247*37da2899SCharles.Forsyth writer->line += writer->pitch; 248*37da2899SCharles.Forsyth cur = writer->line; 249*37da2899SCharles.Forsyth } 250*37da2899SCharles.Forsyth else if ( mask == 0 ) 251*37da2899SCharles.Forsyth { 252*37da2899SCharles.Forsyth cur[0] = c; 253*37da2899SCharles.Forsyth c = 0; 254*37da2899SCharles.Forsyth mask = 0x80; 255*37da2899SCharles.Forsyth cur ++; 256*37da2899SCharles.Forsyth } 257*37da2899SCharles.Forsyth 258*37da2899SCharles.Forsyth reload = ( --count <= 0 ); 259*37da2899SCharles.Forsyth } 260*37da2899SCharles.Forsyth 261*37da2899SCharles.Forsyth if ( mask != 0x80 ) 262*37da2899SCharles.Forsyth cur[0] = (FT_Byte) c; 263*37da2899SCharles.Forsyth } 264*37da2899SCharles.Forsyth 265*37da2899SCharles.Forsyth 266*37da2899SCharles.Forsyth /*************************************************************************/ 267*37da2899SCharles.Forsyth /*************************************************************************/ 268*37da2899SCharles.Forsyth /***** *****/ 269*37da2899SCharles.Forsyth /***** BITMAP DATA DECODING *****/ 270*37da2899SCharles.Forsyth /***** *****/ 271*37da2899SCharles.Forsyth /*************************************************************************/ 272*37da2899SCharles.Forsyth /*************************************************************************/ 273*37da2899SCharles.Forsyth 274*37da2899SCharles.Forsyth static void pfr_lookup_bitmap_data(FT_Byte * base,FT_Byte * limit,FT_Int count,FT_Byte flags,FT_UInt char_code,FT_ULong * found_offset,FT_ULong * found_size)275*37da2899SCharles.Forsyth pfr_lookup_bitmap_data( FT_Byte* base, 276*37da2899SCharles.Forsyth FT_Byte* limit, 277*37da2899SCharles.Forsyth FT_Int count, 278*37da2899SCharles.Forsyth FT_Byte flags, 279*37da2899SCharles.Forsyth FT_UInt char_code, 280*37da2899SCharles.Forsyth FT_ULong* found_offset, 281*37da2899SCharles.Forsyth FT_ULong* found_size ) 282*37da2899SCharles.Forsyth { 283*37da2899SCharles.Forsyth FT_UInt left, right, char_len; 284*37da2899SCharles.Forsyth FT_Bool two = flags & 1; 285*37da2899SCharles.Forsyth FT_Byte* buff; 286*37da2899SCharles.Forsyth 287*37da2899SCharles.Forsyth 288*37da2899SCharles.Forsyth char_len = 4; 289*37da2899SCharles.Forsyth if ( two ) char_len += 1; 290*37da2899SCharles.Forsyth if ( flags & 2 ) char_len += 1; 291*37da2899SCharles.Forsyth if ( flags & 4 ) char_len += 1; 292*37da2899SCharles.Forsyth 293*37da2899SCharles.Forsyth left = 0; 294*37da2899SCharles.Forsyth right = count; 295*37da2899SCharles.Forsyth 296*37da2899SCharles.Forsyth while ( left < right ) 297*37da2899SCharles.Forsyth { 298*37da2899SCharles.Forsyth FT_UInt middle, code; 299*37da2899SCharles.Forsyth 300*37da2899SCharles.Forsyth 301*37da2899SCharles.Forsyth middle = ( left + right ) >> 1; 302*37da2899SCharles.Forsyth buff = base + middle * char_len; 303*37da2899SCharles.Forsyth 304*37da2899SCharles.Forsyth /* check that we are not outside of the table -- */ 305*37da2899SCharles.Forsyth /* this is possible with broken fonts... */ 306*37da2899SCharles.Forsyth if ( buff + char_len > limit ) 307*37da2899SCharles.Forsyth goto Fail; 308*37da2899SCharles.Forsyth 309*37da2899SCharles.Forsyth if ( two ) 310*37da2899SCharles.Forsyth code = PFR_NEXT_USHORT( buff ); 311*37da2899SCharles.Forsyth else 312*37da2899SCharles.Forsyth code = PFR_NEXT_BYTE( buff ); 313*37da2899SCharles.Forsyth 314*37da2899SCharles.Forsyth if ( code == char_code ) 315*37da2899SCharles.Forsyth goto Found_It; 316*37da2899SCharles.Forsyth 317*37da2899SCharles.Forsyth if ( code < char_code ) 318*37da2899SCharles.Forsyth left = middle; 319*37da2899SCharles.Forsyth else 320*37da2899SCharles.Forsyth right = middle; 321*37da2899SCharles.Forsyth } 322*37da2899SCharles.Forsyth 323*37da2899SCharles.Forsyth Fail: 324*37da2899SCharles.Forsyth /* Not found */ 325*37da2899SCharles.Forsyth *found_size = 0; 326*37da2899SCharles.Forsyth *found_offset = 0; 327*37da2899SCharles.Forsyth return; 328*37da2899SCharles.Forsyth 329*37da2899SCharles.Forsyth Found_It: 330*37da2899SCharles.Forsyth if ( flags & 2 ) 331*37da2899SCharles.Forsyth *found_size = PFR_NEXT_USHORT( buff ); 332*37da2899SCharles.Forsyth else 333*37da2899SCharles.Forsyth *found_size = PFR_NEXT_BYTE( buff ); 334*37da2899SCharles.Forsyth 335*37da2899SCharles.Forsyth if ( flags & 4 ) 336*37da2899SCharles.Forsyth *found_offset = PFR_NEXT_ULONG( buff ); 337*37da2899SCharles.Forsyth else 338*37da2899SCharles.Forsyth *found_offset = PFR_NEXT_USHORT( buff ); 339*37da2899SCharles.Forsyth } 340*37da2899SCharles.Forsyth 341*37da2899SCharles.Forsyth 342*37da2899SCharles.Forsyth /* load bitmap metrics. "*padvance" must be set to the default value */ 343*37da2899SCharles.Forsyth /* before calling this function... */ 344*37da2899SCharles.Forsyth /* */ 345*37da2899SCharles.Forsyth static FT_Error pfr_load_bitmap_metrics(FT_Byte ** pdata,FT_Byte * limit,FT_Long scaled_advance,FT_Long * axpos,FT_Long * aypos,FT_UInt * axsize,FT_UInt * aysize,FT_Long * aadvance,FT_UInt * aformat)346*37da2899SCharles.Forsyth pfr_load_bitmap_metrics( FT_Byte** pdata, 347*37da2899SCharles.Forsyth FT_Byte* limit, 348*37da2899SCharles.Forsyth FT_Long scaled_advance, 349*37da2899SCharles.Forsyth FT_Long *axpos, 350*37da2899SCharles.Forsyth FT_Long *aypos, 351*37da2899SCharles.Forsyth FT_UInt *axsize, 352*37da2899SCharles.Forsyth FT_UInt *aysize, 353*37da2899SCharles.Forsyth FT_Long *aadvance, 354*37da2899SCharles.Forsyth FT_UInt *aformat ) 355*37da2899SCharles.Forsyth { 356*37da2899SCharles.Forsyth FT_Error error = 0; 357*37da2899SCharles.Forsyth FT_Byte flags; 358*37da2899SCharles.Forsyth FT_Char b; 359*37da2899SCharles.Forsyth FT_Byte* p = *pdata; 360*37da2899SCharles.Forsyth FT_Long xpos, ypos, advance; 361*37da2899SCharles.Forsyth FT_UInt xsize, ysize; 362*37da2899SCharles.Forsyth 363*37da2899SCharles.Forsyth 364*37da2899SCharles.Forsyth PFR_CHECK( 1 ); 365*37da2899SCharles.Forsyth flags = PFR_NEXT_BYTE( p ); 366*37da2899SCharles.Forsyth 367*37da2899SCharles.Forsyth xpos = 0; 368*37da2899SCharles.Forsyth ypos = 0; 369*37da2899SCharles.Forsyth xsize = 0; 370*37da2899SCharles.Forsyth ysize = 0; 371*37da2899SCharles.Forsyth advance = 0; 372*37da2899SCharles.Forsyth 373*37da2899SCharles.Forsyth switch ( flags & 3 ) 374*37da2899SCharles.Forsyth { 375*37da2899SCharles.Forsyth case 0: 376*37da2899SCharles.Forsyth PFR_CHECK( 1 ); 377*37da2899SCharles.Forsyth b = PFR_NEXT_INT8( p ); 378*37da2899SCharles.Forsyth xpos = b >> 4; 379*37da2899SCharles.Forsyth ypos = ( (FT_Char)( b << 4 ) ) >> 4; 380*37da2899SCharles.Forsyth break; 381*37da2899SCharles.Forsyth 382*37da2899SCharles.Forsyth case 1: 383*37da2899SCharles.Forsyth PFR_CHECK( 2 ); 384*37da2899SCharles.Forsyth xpos = PFR_NEXT_INT8( p ); 385*37da2899SCharles.Forsyth ypos = PFR_NEXT_INT8( p ); 386*37da2899SCharles.Forsyth break; 387*37da2899SCharles.Forsyth 388*37da2899SCharles.Forsyth case 2: 389*37da2899SCharles.Forsyth PFR_CHECK( 4 ); 390*37da2899SCharles.Forsyth xpos = PFR_NEXT_SHORT( p ); 391*37da2899SCharles.Forsyth ypos = PFR_NEXT_SHORT( p ); 392*37da2899SCharles.Forsyth break; 393*37da2899SCharles.Forsyth 394*37da2899SCharles.Forsyth case 3: 395*37da2899SCharles.Forsyth PFR_CHECK( 6 ); 396*37da2899SCharles.Forsyth xpos = PFR_NEXT_LONG( p ); 397*37da2899SCharles.Forsyth ypos = PFR_NEXT_LONG( p ); 398*37da2899SCharles.Forsyth break; 399*37da2899SCharles.Forsyth 400*37da2899SCharles.Forsyth default: 401*37da2899SCharles.Forsyth ; 402*37da2899SCharles.Forsyth } 403*37da2899SCharles.Forsyth 404*37da2899SCharles.Forsyth flags >>= 2; 405*37da2899SCharles.Forsyth switch ( flags & 3 ) 406*37da2899SCharles.Forsyth { 407*37da2899SCharles.Forsyth case 0: 408*37da2899SCharles.Forsyth /* blank image */ 409*37da2899SCharles.Forsyth xsize = 0; 410*37da2899SCharles.Forsyth ysize = 0; 411*37da2899SCharles.Forsyth break; 412*37da2899SCharles.Forsyth 413*37da2899SCharles.Forsyth case 1: 414*37da2899SCharles.Forsyth PFR_CHECK( 1 ); 415*37da2899SCharles.Forsyth b = PFR_NEXT_BYTE( p ); 416*37da2899SCharles.Forsyth xsize = ( b >> 4 ) & 0xF; 417*37da2899SCharles.Forsyth ysize = b & 0xF; 418*37da2899SCharles.Forsyth break; 419*37da2899SCharles.Forsyth 420*37da2899SCharles.Forsyth case 2: 421*37da2899SCharles.Forsyth PFR_CHECK( 2 ); 422*37da2899SCharles.Forsyth xsize = PFR_NEXT_BYTE( p ); 423*37da2899SCharles.Forsyth ysize = PFR_NEXT_BYTE( p ); 424*37da2899SCharles.Forsyth break; 425*37da2899SCharles.Forsyth 426*37da2899SCharles.Forsyth case 3: 427*37da2899SCharles.Forsyth PFR_CHECK( 4 ); 428*37da2899SCharles.Forsyth xsize = PFR_NEXT_USHORT( p ); 429*37da2899SCharles.Forsyth ysize = PFR_NEXT_USHORT( p ); 430*37da2899SCharles.Forsyth break; 431*37da2899SCharles.Forsyth 432*37da2899SCharles.Forsyth default: 433*37da2899SCharles.Forsyth ; 434*37da2899SCharles.Forsyth } 435*37da2899SCharles.Forsyth 436*37da2899SCharles.Forsyth flags >>= 2; 437*37da2899SCharles.Forsyth switch ( flags & 3 ) 438*37da2899SCharles.Forsyth { 439*37da2899SCharles.Forsyth case 0: 440*37da2899SCharles.Forsyth advance = scaled_advance; 441*37da2899SCharles.Forsyth break; 442*37da2899SCharles.Forsyth 443*37da2899SCharles.Forsyth case 1: 444*37da2899SCharles.Forsyth PFR_CHECK( 1 ); 445*37da2899SCharles.Forsyth advance = PFR_NEXT_INT8( p ) << 8; 446*37da2899SCharles.Forsyth break; 447*37da2899SCharles.Forsyth 448*37da2899SCharles.Forsyth case 2: 449*37da2899SCharles.Forsyth PFR_CHECK( 2 ); 450*37da2899SCharles.Forsyth advance = PFR_NEXT_SHORT( p ); 451*37da2899SCharles.Forsyth break; 452*37da2899SCharles.Forsyth 453*37da2899SCharles.Forsyth case 3: 454*37da2899SCharles.Forsyth PFR_CHECK( 3 ); 455*37da2899SCharles.Forsyth advance = PFR_NEXT_LONG( p ); 456*37da2899SCharles.Forsyth break; 457*37da2899SCharles.Forsyth 458*37da2899SCharles.Forsyth default: 459*37da2899SCharles.Forsyth ; 460*37da2899SCharles.Forsyth } 461*37da2899SCharles.Forsyth 462*37da2899SCharles.Forsyth *axpos = xpos; 463*37da2899SCharles.Forsyth *aypos = ypos; 464*37da2899SCharles.Forsyth *axsize = xsize; 465*37da2899SCharles.Forsyth *aysize = ysize; 466*37da2899SCharles.Forsyth *aadvance = advance; 467*37da2899SCharles.Forsyth *aformat = flags >> 2; 468*37da2899SCharles.Forsyth *pdata = p; 469*37da2899SCharles.Forsyth 470*37da2899SCharles.Forsyth Exit: 471*37da2899SCharles.Forsyth return error; 472*37da2899SCharles.Forsyth 473*37da2899SCharles.Forsyth Too_Short: 474*37da2899SCharles.Forsyth error = PFR_Err_Invalid_Table; 475*37da2899SCharles.Forsyth FT_ERROR(( "pfr_load_bitmap_metrics: invalid glyph data\n" )); 476*37da2899SCharles.Forsyth goto Exit; 477*37da2899SCharles.Forsyth } 478*37da2899SCharles.Forsyth 479*37da2899SCharles.Forsyth 480*37da2899SCharles.Forsyth static FT_Error pfr_load_bitmap_bits(FT_Byte * p,FT_Byte * limit,FT_UInt format,FT_UInt decreasing,FT_Bitmap * target)481*37da2899SCharles.Forsyth pfr_load_bitmap_bits( FT_Byte* p, 482*37da2899SCharles.Forsyth FT_Byte* limit, 483*37da2899SCharles.Forsyth FT_UInt format, 484*37da2899SCharles.Forsyth FT_UInt decreasing, 485*37da2899SCharles.Forsyth FT_Bitmap* target ) 486*37da2899SCharles.Forsyth { 487*37da2899SCharles.Forsyth FT_Error error = 0; 488*37da2899SCharles.Forsyth PFR_BitWriterRec writer; 489*37da2899SCharles.Forsyth 490*37da2899SCharles.Forsyth 491*37da2899SCharles.Forsyth if ( target->rows > 0 && target->width > 0 ) 492*37da2899SCharles.Forsyth { 493*37da2899SCharles.Forsyth pfr_bitwriter_init( &writer, target, decreasing ); 494*37da2899SCharles.Forsyth 495*37da2899SCharles.Forsyth switch ( format ) 496*37da2899SCharles.Forsyth { 497*37da2899SCharles.Forsyth case 0: /* packed bits */ 498*37da2899SCharles.Forsyth pfr_bitwriter_decode_bytes( &writer, p, limit ); 499*37da2899SCharles.Forsyth break; 500*37da2899SCharles.Forsyth 501*37da2899SCharles.Forsyth case 1: /* RLE1 */ 502*37da2899SCharles.Forsyth pfr_bitwriter_decode_rle1( &writer, p, limit ); 503*37da2899SCharles.Forsyth break; 504*37da2899SCharles.Forsyth 505*37da2899SCharles.Forsyth case 2: /* RLE2 */ 506*37da2899SCharles.Forsyth pfr_bitwriter_decode_rle2( &writer, p, limit ); 507*37da2899SCharles.Forsyth break; 508*37da2899SCharles.Forsyth 509*37da2899SCharles.Forsyth default: 510*37da2899SCharles.Forsyth FT_ERROR(( "pfr_read_bitmap_data: invalid image type\n" )); 511*37da2899SCharles.Forsyth error = FT_Err_Invalid_File_Format; 512*37da2899SCharles.Forsyth } 513*37da2899SCharles.Forsyth } 514*37da2899SCharles.Forsyth 515*37da2899SCharles.Forsyth return error; 516*37da2899SCharles.Forsyth } 517*37da2899SCharles.Forsyth 518*37da2899SCharles.Forsyth 519*37da2899SCharles.Forsyth /*************************************************************************/ 520*37da2899SCharles.Forsyth /*************************************************************************/ 521*37da2899SCharles.Forsyth /***** *****/ 522*37da2899SCharles.Forsyth /***** BITMAP LOADING *****/ 523*37da2899SCharles.Forsyth /***** *****/ 524*37da2899SCharles.Forsyth /*************************************************************************/ 525*37da2899SCharles.Forsyth /*************************************************************************/ 526*37da2899SCharles.Forsyth 527*37da2899SCharles.Forsyth FT_LOCAL( FT_Error ) pfr_slot_load_bitmap(PFR_Slot glyph,PFR_Size size,FT_UInt glyph_index)528*37da2899SCharles.Forsyth pfr_slot_load_bitmap( PFR_Slot glyph, 529*37da2899SCharles.Forsyth PFR_Size size, 530*37da2899SCharles.Forsyth FT_UInt glyph_index ) 531*37da2899SCharles.Forsyth { 532*37da2899SCharles.Forsyth FT_Error error; 533*37da2899SCharles.Forsyth PFR_Face face = (PFR_Face) glyph->root.face; 534*37da2899SCharles.Forsyth FT_Stream stream = face->root.stream; 535*37da2899SCharles.Forsyth PFR_PhyFont phys = &face->phy_font; 536*37da2899SCharles.Forsyth FT_ULong gps_offset; 537*37da2899SCharles.Forsyth FT_ULong gps_size; 538*37da2899SCharles.Forsyth PFR_Char character; 539*37da2899SCharles.Forsyth PFR_Strike strike; 540*37da2899SCharles.Forsyth 541*37da2899SCharles.Forsyth 542*37da2899SCharles.Forsyth character = &phys->chars[glyph_index]; 543*37da2899SCharles.Forsyth 544*37da2899SCharles.Forsyth /* Look-up a bitmap strike corresponding to the current */ 545*37da2899SCharles.Forsyth /* character dimensions */ 546*37da2899SCharles.Forsyth { 547*37da2899SCharles.Forsyth FT_UInt n; 548*37da2899SCharles.Forsyth 549*37da2899SCharles.Forsyth 550*37da2899SCharles.Forsyth strike = phys->strikes; 551*37da2899SCharles.Forsyth for ( n = 0; n < phys->num_strikes; n++ ) 552*37da2899SCharles.Forsyth { 553*37da2899SCharles.Forsyth if ( strike->x_ppm == (FT_UInt)size->root.metrics.x_ppem && 554*37da2899SCharles.Forsyth strike->y_ppm == (FT_UInt)size->root.metrics.y_ppem ) 555*37da2899SCharles.Forsyth { 556*37da2899SCharles.Forsyth goto Found_Strike; 557*37da2899SCharles.Forsyth } 558*37da2899SCharles.Forsyth 559*37da2899SCharles.Forsyth strike++; 560*37da2899SCharles.Forsyth } 561*37da2899SCharles.Forsyth 562*37da2899SCharles.Forsyth /* couldn't find it */ 563*37da2899SCharles.Forsyth return FT_Err_Invalid_Argument; 564*37da2899SCharles.Forsyth } 565*37da2899SCharles.Forsyth 566*37da2899SCharles.Forsyth Found_Strike: 567*37da2899SCharles.Forsyth 568*37da2899SCharles.Forsyth /* Now lookup the glyph's position within the file */ 569*37da2899SCharles.Forsyth { 570*37da2899SCharles.Forsyth FT_UInt char_len; 571*37da2899SCharles.Forsyth 572*37da2899SCharles.Forsyth 573*37da2899SCharles.Forsyth char_len = 4; 574*37da2899SCharles.Forsyth if ( strike->flags & 1 ) char_len += 1; 575*37da2899SCharles.Forsyth if ( strike->flags & 2 ) char_len += 1; 576*37da2899SCharles.Forsyth if ( strike->flags & 4 ) char_len += 1; 577*37da2899SCharles.Forsyth 578*37da2899SCharles.Forsyth /* Access data directly in the frame to speed lookups */ 579*37da2899SCharles.Forsyth if ( FT_STREAM_SEEK( phys->bct_offset + strike->bct_offset ) || 580*37da2899SCharles.Forsyth FT_FRAME_ENTER( char_len * strike->num_bitmaps ) ) 581*37da2899SCharles.Forsyth goto Exit; 582*37da2899SCharles.Forsyth 583*37da2899SCharles.Forsyth pfr_lookup_bitmap_data( stream->cursor, 584*37da2899SCharles.Forsyth stream->limit, 585*37da2899SCharles.Forsyth strike->num_bitmaps, 586*37da2899SCharles.Forsyth strike->flags, 587*37da2899SCharles.Forsyth character->char_code, 588*37da2899SCharles.Forsyth &gps_offset, 589*37da2899SCharles.Forsyth &gps_size ); 590*37da2899SCharles.Forsyth 591*37da2899SCharles.Forsyth FT_FRAME_EXIT(); 592*37da2899SCharles.Forsyth 593*37da2899SCharles.Forsyth if ( gps_size == 0 ) 594*37da2899SCharles.Forsyth { 595*37da2899SCharles.Forsyth /* Could not find a bitmap program string for this glyph */ 596*37da2899SCharles.Forsyth error = FT_Err_Invalid_Argument; 597*37da2899SCharles.Forsyth goto Exit; 598*37da2899SCharles.Forsyth } 599*37da2899SCharles.Forsyth } 600*37da2899SCharles.Forsyth 601*37da2899SCharles.Forsyth /* get the bitmap metrics */ 602*37da2899SCharles.Forsyth { 603*37da2899SCharles.Forsyth FT_Long xpos, ypos, advance; 604*37da2899SCharles.Forsyth FT_UInt xsize, ysize, format; 605*37da2899SCharles.Forsyth FT_Byte* p; 606*37da2899SCharles.Forsyth 607*37da2899SCharles.Forsyth 608*37da2899SCharles.Forsyth advance = FT_MulDiv( size->root.metrics.x_ppem << 8, 609*37da2899SCharles.Forsyth character->advance, 610*37da2899SCharles.Forsyth phys->metrics_resolution ); 611*37da2899SCharles.Forsyth 612*37da2899SCharles.Forsyth /* XXX: handle linearHoriAdvance correctly! */ 613*37da2899SCharles.Forsyth 614*37da2899SCharles.Forsyth if ( FT_STREAM_SEEK( face->header.gps_section_offset + gps_offset ) || 615*37da2899SCharles.Forsyth FT_FRAME_ENTER( gps_size ) ) 616*37da2899SCharles.Forsyth goto Exit; 617*37da2899SCharles.Forsyth 618*37da2899SCharles.Forsyth p = stream->cursor; 619*37da2899SCharles.Forsyth error = pfr_load_bitmap_metrics( &p, stream->limit, 620*37da2899SCharles.Forsyth advance, 621*37da2899SCharles.Forsyth &xpos, &ypos, 622*37da2899SCharles.Forsyth &xsize, &ysize, 623*37da2899SCharles.Forsyth &advance, &format ); 624*37da2899SCharles.Forsyth if ( !error ) 625*37da2899SCharles.Forsyth { 626*37da2899SCharles.Forsyth glyph->root.format = FT_GLYPH_FORMAT_BITMAP; 627*37da2899SCharles.Forsyth 628*37da2899SCharles.Forsyth /* Set up glyph bitmap and metrics */ 629*37da2899SCharles.Forsyth glyph->root.bitmap.width = (FT_Int)xsize; 630*37da2899SCharles.Forsyth glyph->root.bitmap.rows = (FT_Int)ysize; 631*37da2899SCharles.Forsyth glyph->root.bitmap.pitch = (FT_Long)( xsize + 7 ) >> 3; 632*37da2899SCharles.Forsyth glyph->root.bitmap.pixel_mode = FT_PIXEL_MODE_MONO; 633*37da2899SCharles.Forsyth 634*37da2899SCharles.Forsyth glyph->root.metrics.width = (FT_Long)xsize << 6; 635*37da2899SCharles.Forsyth glyph->root.metrics.height = (FT_Long)ysize << 6; 636*37da2899SCharles.Forsyth glyph->root.metrics.horiBearingX = xpos << 6; 637*37da2899SCharles.Forsyth glyph->root.metrics.horiBearingY = ypos << 6; 638*37da2899SCharles.Forsyth glyph->root.metrics.horiAdvance = ( ( advance >> 2 ) + 32 ) & -64; 639*37da2899SCharles.Forsyth glyph->root.metrics.vertBearingX = - glyph->root.metrics.width >> 1; 640*37da2899SCharles.Forsyth glyph->root.metrics.vertBearingY = 0; 641*37da2899SCharles.Forsyth glyph->root.metrics.vertAdvance = size->root.metrics.height; 642*37da2899SCharles.Forsyth 643*37da2899SCharles.Forsyth glyph->root.bitmap_left = xpos; 644*37da2899SCharles.Forsyth glyph->root.bitmap_top = ypos + ysize; 645*37da2899SCharles.Forsyth 646*37da2899SCharles.Forsyth /* Allocate and read bitmap data */ 647*37da2899SCharles.Forsyth { 648*37da2899SCharles.Forsyth FT_Memory memory = face->root.memory; 649*37da2899SCharles.Forsyth FT_Long len = glyph->root.bitmap.pitch * ysize; 650*37da2899SCharles.Forsyth 651*37da2899SCharles.Forsyth 652*37da2899SCharles.Forsyth if ( !FT_ALLOC( glyph->root.bitmap.buffer, len ) ) 653*37da2899SCharles.Forsyth { 654*37da2899SCharles.Forsyth error = pfr_load_bitmap_bits( p, 655*37da2899SCharles.Forsyth stream->limit, 656*37da2899SCharles.Forsyth format, 657*37da2899SCharles.Forsyth face->header.color_flags & 2, 658*37da2899SCharles.Forsyth &glyph->root.bitmap ); 659*37da2899SCharles.Forsyth } 660*37da2899SCharles.Forsyth } 661*37da2899SCharles.Forsyth } 662*37da2899SCharles.Forsyth 663*37da2899SCharles.Forsyth FT_FRAME_EXIT(); 664*37da2899SCharles.Forsyth } 665*37da2899SCharles.Forsyth 666*37da2899SCharles.Forsyth Exit: 667*37da2899SCharles.Forsyth return error; 668*37da2899SCharles.Forsyth } 669*37da2899SCharles.Forsyth 670*37da2899SCharles.Forsyth /* END */ 671