00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019 #include "pfrsbit.h"
00020 #include "pfrload.h"
00021 #include FT_INTERNAL_DEBUG_H
00022 #include FT_INTERNAL_STREAM_H
00023
00024 #include "pfrerror.h"
00025
00026 #undef FT_COMPONENT
00027 #define FT_COMPONENT trace_pfr
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038 typedef struct PFR_BitWriter_
00039 {
00040 FT_Byte* line;
00041 FT_Int pitch;
00042 FT_Int width;
00043 FT_Int rows;
00044 FT_Int total;
00045
00046 } PFR_BitWriterRec, *PFR_BitWriter;
00047
00048
00049 static void
00050 pfr_bitwriter_init( PFR_BitWriter writer,
00051 FT_Bitmap* target,
00052 FT_Bool decreasing )
00053 {
00054 writer->line = target->buffer;
00055 writer->pitch = target->pitch;
00056 writer->width = target->width;
00057 writer->rows = target->rows;
00058 writer->total = writer->width * writer->rows;
00059
00060 if ( !decreasing )
00061 {
00062 writer->line += writer->pitch * ( target->rows-1 );
00063 writer->pitch = -writer->pitch;
00064 }
00065 }
00066
00067
00068 static void
00069 pfr_bitwriter_decode_bytes( PFR_BitWriter writer,
00070 FT_Byte* p,
00071 FT_Byte* limit )
00072 {
00073 FT_Int n, reload;
00074 FT_Int left = writer->width;
00075 FT_Byte* cur = writer->line;
00076 FT_UInt mask = 0x80;
00077 FT_UInt val = 0;
00078 FT_UInt c = 0;
00079
00080
00081 n = (FT_Int)( limit - p ) * 8;
00082 if ( n > writer->total )
00083 n = writer->total;
00084
00085 reload = n & 7;
00086
00087 for ( ; n > 0; n-- )
00088 {
00089 if ( ( n & 7 ) == reload )
00090 val = *p++;
00091
00092 if ( val & 0x80 )
00093 c |= mask;
00094
00095 val <<= 1;
00096 mask >>= 1;
00097
00098 if ( --left <= 0 )
00099 {
00100 cur[0] = (FT_Byte)c;
00101 left = writer->width;
00102 mask = 0x80;
00103
00104 writer->line += writer->pitch;
00105 cur = writer->line;
00106 c = 0;
00107 }
00108 else if ( mask == 0 )
00109 {
00110 cur[0] = (FT_Byte)c;
00111 mask = 0x80;
00112 c = 0;
00113 cur ++;
00114 }
00115 }
00116
00117 if ( mask != 0x80 )
00118 cur[0] = (FT_Byte)c;
00119 }
00120
00121
00122 static void
00123 pfr_bitwriter_decode_rle1( PFR_BitWriter writer,
00124 FT_Byte* p,
00125 FT_Byte* limit )
00126 {
00127 FT_Int n, phase, count, counts[2], reload;
00128 FT_Int left = writer->width;
00129 FT_Byte* cur = writer->line;
00130 FT_UInt mask = 0x80;
00131 FT_UInt c = 0;
00132
00133
00134 n = writer->total;
00135
00136 phase = 1;
00137 counts[0] = 0;
00138 counts[1] = 0;
00139 count = 0;
00140 reload = 1;
00141
00142 for ( ; n > 0; n-- )
00143 {
00144 if ( reload )
00145 {
00146 do
00147 {
00148 if ( phase )
00149 {
00150 FT_Int v;
00151
00152
00153 if ( p >= limit )
00154 break;
00155
00156 v = *p++;
00157 counts[0] = v >> 4;
00158 counts[1] = v & 15;
00159 phase = 0;
00160 count = counts[0];
00161 }
00162 else
00163 {
00164 phase = 1;
00165 count = counts[1];
00166 }
00167
00168 } while ( count == 0 );
00169 }
00170
00171 if ( phase )
00172 c |= mask;
00173
00174 mask >>= 1;
00175
00176 if ( --left <= 0 )
00177 {
00178 cur[0] = (FT_Byte) c;
00179 left = writer->width;
00180 mask = 0x80;
00181
00182 writer->line += writer->pitch;
00183 cur = writer->line;
00184 c = 0;
00185 }
00186 else if ( mask == 0 )
00187 {
00188 cur[0] = (FT_Byte)c;
00189 mask = 0x80;
00190 c = 0;
00191 cur ++;
00192 }
00193
00194 reload = ( --count <= 0 );
00195 }
00196
00197 if ( mask != 0x80 )
00198 cur[0] = (FT_Byte) c;
00199 }
00200
00201
00202 static void
00203 pfr_bitwriter_decode_rle2( PFR_BitWriter writer,
00204 FT_Byte* p,
00205 FT_Byte* limit )
00206 {
00207 FT_Int n, phase, count, reload;
00208 FT_Int left = writer->width;
00209 FT_Byte* cur = writer->line;
00210 FT_UInt mask = 0x80;
00211 FT_UInt c = 0;
00212
00213
00214 n = writer->total;
00215
00216 phase = 1;
00217 count = 0;
00218 reload = 1;
00219
00220 for ( ; n > 0; n-- )
00221 {
00222 if ( reload )
00223 {
00224 do
00225 {
00226 if ( p >= limit )
00227 break;
00228
00229 count = *p++;
00230 phase = phase ^ 1;
00231
00232 } while ( count == 0 );
00233 }
00234
00235 if ( phase )
00236 c |= mask;
00237
00238 mask >>= 1;
00239
00240 if ( --left <= 0 )
00241 {
00242 cur[0] = (FT_Byte) c;
00243 c = 0;
00244 mask = 0x80;
00245 left = writer->width;
00246
00247 writer->line += writer->pitch;
00248 cur = writer->line;
00249 }
00250 else if ( mask == 0 )
00251 {
00252 cur[0] = (FT_Byte)c;
00253 c = 0;
00254 mask = 0x80;
00255 cur ++;
00256 }
00257
00258 reload = ( --count <= 0 );
00259 }
00260
00261 if ( mask != 0x80 )
00262 cur[0] = (FT_Byte) c;
00263 }
00264
00265
00266
00267
00268
00269
00270
00271
00272
00273
00274 static void
00275 pfr_lookup_bitmap_data( FT_Byte* base,
00276 FT_Byte* limit,
00277 FT_UInt count,
00278 FT_UInt flags,
00279 FT_UInt char_code,
00280 FT_ULong* found_offset,
00281 FT_ULong* found_size )
00282 {
00283 FT_UInt left, right, char_len;
00284 FT_Bool two = FT_BOOL( flags & 1 );
00285 FT_Byte* buff;
00286
00287
00288 char_len = 4;
00289 if ( two ) char_len += 1;
00290 if ( flags & 2 ) char_len += 1;
00291 if ( flags & 4 ) char_len += 1;
00292
00293 left = 0;
00294 right = count;
00295
00296 while ( left < right )
00297 {
00298 FT_UInt middle, code;
00299
00300
00301 middle = ( left + right ) >> 1;
00302 buff = base + middle * char_len;
00303
00304
00305
00306 if ( buff + char_len > limit )
00307 goto Fail;
00308
00309 if ( two )
00310 code = PFR_NEXT_USHORT( buff );
00311 else
00312 code = PFR_NEXT_BYTE( buff );
00313
00314 if ( code == char_code )
00315 goto Found_It;
00316
00317 if ( code < char_code )
00318 left = middle;
00319 else
00320 right = middle;
00321 }
00322
00323 Fail:
00324
00325 *found_size = 0;
00326 *found_offset = 0;
00327 return;
00328
00329 Found_It:
00330 if ( flags & 2 )
00331 *found_size = PFR_NEXT_USHORT( buff );
00332 else
00333 *found_size = PFR_NEXT_BYTE( buff );
00334
00335 if ( flags & 4 )
00336 *found_offset = PFR_NEXT_ULONG( buff );
00337 else
00338 *found_offset = PFR_NEXT_USHORT( buff );
00339 }
00340
00341
00342
00343
00344
00345 static FT_Error
00346 pfr_load_bitmap_metrics( FT_Byte** pdata,
00347 FT_Byte* limit,
00348 FT_Long scaled_advance,
00349 FT_Long *axpos,
00350 FT_Long *aypos,
00351 FT_UInt *axsize,
00352 FT_UInt *aysize,
00353 FT_Long *aadvance,
00354 FT_UInt *aformat )
00355 {
00356 FT_Error error = 0;
00357 FT_Byte flags;
00358 FT_Char b;
00359 FT_Byte* p = *pdata;
00360 FT_Long xpos, ypos, advance;
00361 FT_UInt xsize, ysize;
00362
00363
00364 PFR_CHECK( 1 );
00365 flags = PFR_NEXT_BYTE( p );
00366
00367 xpos = 0;
00368 ypos = 0;
00369 xsize = 0;
00370 ysize = 0;
00371 advance = 0;
00372
00373 switch ( flags & 3 )
00374 {
00375 case 0:
00376 PFR_CHECK( 1 );
00377 b = PFR_NEXT_INT8( p );
00378 xpos = b >> 4;
00379 ypos = ( (FT_Char)( b << 4 ) ) >> 4;
00380 break;
00381
00382 case 1:
00383 PFR_CHECK( 2 );
00384 xpos = PFR_NEXT_INT8( p );
00385 ypos = PFR_NEXT_INT8( p );
00386 break;
00387
00388 case 2:
00389 PFR_CHECK( 4 );
00390 xpos = PFR_NEXT_SHORT( p );
00391 ypos = PFR_NEXT_SHORT( p );
00392 break;
00393
00394 case 3:
00395 PFR_CHECK( 6 );
00396 xpos = PFR_NEXT_LONG( p );
00397 ypos = PFR_NEXT_LONG( p );
00398 break;
00399
00400 default:
00401 ;
00402 }
00403
00404 flags >>= 2;
00405 switch ( flags & 3 )
00406 {
00407 case 0:
00408
00409 xsize = 0;
00410 ysize = 0;
00411 break;
00412
00413 case 1:
00414 PFR_CHECK( 1 );
00415 b = PFR_NEXT_BYTE( p );
00416 xsize = ( b >> 4 ) & 0xF;
00417 ysize = b & 0xF;
00418 break;
00419
00420 case 2:
00421 PFR_CHECK( 2 );
00422 xsize = PFR_NEXT_BYTE( p );
00423 ysize = PFR_NEXT_BYTE( p );
00424 break;
00425
00426 case 3:
00427 PFR_CHECK( 4 );
00428 xsize = PFR_NEXT_USHORT( p );
00429 ysize = PFR_NEXT_USHORT( p );
00430 break;
00431
00432 default:
00433 ;
00434 }
00435
00436 flags >>= 2;
00437 switch ( flags & 3 )
00438 {
00439 case 0:
00440 advance = scaled_advance;
00441 break;
00442
00443 case 1:
00444 PFR_CHECK( 1 );
00445 advance = PFR_NEXT_INT8( p ) << 8;
00446 break;
00447
00448 case 2:
00449 PFR_CHECK( 2 );
00450 advance = PFR_NEXT_SHORT( p );
00451 break;
00452
00453 case 3:
00454 PFR_CHECK( 3 );
00455 advance = PFR_NEXT_LONG( p );
00456 break;
00457
00458 default:
00459 ;
00460 }
00461
00462 *axpos = xpos;
00463 *aypos = ypos;
00464 *axsize = xsize;
00465 *aysize = ysize;
00466 *aadvance = advance;
00467 *aformat = flags >> 2;
00468 *pdata = p;
00469
00470 Exit:
00471 return error;
00472
00473 Too_Short:
00474 error = PFR_Err_Invalid_Table;
00475 FT_ERROR(( "pfr_load_bitmap_metrics: invalid glyph data\n" ));
00476 goto Exit;
00477 }
00478
00479
00480 static FT_Error
00481 pfr_load_bitmap_bits( FT_Byte* p,
00482 FT_Byte* limit,
00483 FT_UInt format,
00484 FT_Bool decreasing,
00485 FT_Bitmap* target )
00486 {
00487 FT_Error error = 0;
00488 PFR_BitWriterRec writer;
00489
00490
00491 if ( target->rows > 0 && target->width > 0 )
00492 {
00493 pfr_bitwriter_init( &writer, target, decreasing );
00494
00495 switch ( format )
00496 {
00497 case 0:
00498 pfr_bitwriter_decode_bytes( &writer, p, limit );
00499 break;
00500
00501 case 1:
00502 pfr_bitwriter_decode_rle1( &writer, p, limit );
00503 break;
00504
00505 case 2:
00506 pfr_bitwriter_decode_rle2( &writer, p, limit );
00507 break;
00508
00509 default:
00510 FT_ERROR(( "pfr_read_bitmap_data: invalid image type\n" ));
00511 error = PFR_Err_Invalid_File_Format;
00512 }
00513 }
00514
00515 return error;
00516 }
00517
00518
00519
00520
00521
00522
00523
00524
00525
00526
00527 FT_LOCAL( FT_Error )
00528 pfr_slot_load_bitmap( PFR_Slot glyph,
00529 PFR_Size size,
00530 FT_UInt glyph_index )
00531 {
00532 FT_Error error;
00533 PFR_Face face = (PFR_Face) glyph->root.face;
00534 FT_Stream stream = face->root.stream;
00535 PFR_PhyFont phys = &face->phy_font;
00536 FT_ULong gps_offset;
00537 FT_ULong gps_size;
00538 PFR_Char character;
00539 PFR_Strike strike;
00540
00541
00542 character = &phys->chars[glyph_index];
00543
00544
00545
00546 {
00547 FT_UInt n;
00548
00549
00550 strike = phys->strikes;
00551 for ( n = 0; n < phys->num_strikes; n++ )
00552 {
00553 if ( strike->x_ppm == (FT_UInt)size->root.metrics.x_ppem &&
00554 strike->y_ppm == (FT_UInt)size->root.metrics.y_ppem )
00555 {
00556 goto Found_Strike;
00557 }
00558
00559 strike++;
00560 }
00561
00562
00563 return PFR_Err_Invalid_Argument;
00564 }
00565
00566 Found_Strike:
00567
00568
00569 {
00570 FT_UInt char_len;
00571
00572
00573 char_len = 4;
00574 if ( strike->flags & 1 ) char_len += 1;
00575 if ( strike->flags & 2 ) char_len += 1;
00576 if ( strike->flags & 4 ) char_len += 1;
00577
00578
00579 if ( FT_STREAM_SEEK( phys->bct_offset + strike->bct_offset ) ||
00580 FT_FRAME_ENTER( char_len * strike->num_bitmaps ) )
00581 goto Exit;
00582
00583 pfr_lookup_bitmap_data( stream->cursor,
00584 stream->limit,
00585 strike->num_bitmaps,
00586 strike->flags,
00587 character->char_code,
00588 &gps_offset,
00589 &gps_size );
00590
00591 FT_FRAME_EXIT();
00592
00593 if ( gps_size == 0 )
00594 {
00595
00596 error = PFR_Err_Invalid_Argument;
00597 goto Exit;
00598 }
00599 }
00600
00601
00602 {
00603 FT_Long xpos = 0, ypos = 0, advance = 0;
00604 FT_UInt xsize = 0, ysize = 0, format = 0;
00605 FT_Byte* p;
00606
00607
00608
00609 advance = character->advance;
00610 if ( phys->metrics_resolution != phys->outline_resolution )
00611 advance = FT_MulDiv( advance,
00612 phys->outline_resolution,
00613 phys->metrics_resolution );
00614
00615 glyph->root.linearHoriAdvance = advance;
00616
00617
00618
00619 advance = FT_MulDiv( (FT_Fixed)size->root.metrics.x_ppem << 8,
00620 character->advance,
00621 phys->metrics_resolution );
00622
00623 if ( FT_STREAM_SEEK( face->header.gps_section_offset + gps_offset ) ||
00624 FT_FRAME_ENTER( gps_size ) )
00625 goto Exit;
00626
00627 p = stream->cursor;
00628 error = pfr_load_bitmap_metrics( &p, stream->limit,
00629 advance,
00630 &xpos, &ypos,
00631 &xsize, &ysize,
00632 &advance, &format );
00633
00634
00635
00636
00637
00638
00639 if ( xpos > FT_INT_MAX || ( ypos + ysize ) > FT_INT_MAX )
00640 {
00641 FT_TRACE1(( "pfr_slot_load_bitmap:" ));
00642 FT_TRACE1(( "huge bitmap glyph %dx%d over FT_GlyphSlot\n",
00643 xpos, ypos ));
00644 error = PFR_Err_Invalid_Pixel_Size;
00645 }
00646
00647 if ( !error )
00648 {
00649 glyph->root.format = FT_GLYPH_FORMAT_BITMAP;
00650
00651
00652
00653
00654 glyph->root.bitmap.width = (FT_Int)xsize;
00655 glyph->root.bitmap.rows = (FT_Int)ysize;
00656 glyph->root.bitmap.pitch = (FT_Int)( xsize + 7 ) >> 3;
00657 glyph->root.bitmap.pixel_mode = FT_PIXEL_MODE_MONO;
00658
00659
00660 glyph->root.metrics.width = (FT_Pos)xsize << 6;
00661 glyph->root.metrics.height = (FT_Pos)ysize << 6;
00662 glyph->root.metrics.horiBearingX = xpos << 6;
00663 glyph->root.metrics.horiBearingY = ypos << 6;
00664 glyph->root.metrics.horiAdvance = FT_PIX_ROUND( ( advance >> 2 ) );
00665 glyph->root.metrics.vertBearingX = - glyph->root.metrics.width >> 1;
00666 glyph->root.metrics.vertBearingY = 0;
00667 glyph->root.metrics.vertAdvance = size->root.metrics.height;
00668
00669
00670 glyph->root.bitmap_left = (FT_Int)xpos;
00671 glyph->root.bitmap_top = (FT_Int)(ypos + ysize);
00672
00673
00674 {
00675 FT_ULong len = glyph->root.bitmap.pitch * ysize;
00676
00677
00678 error = ft_glyphslot_alloc_bitmap( &glyph->root, len );
00679 if ( !error )
00680 {
00681 error = pfr_load_bitmap_bits(
00682 p,
00683 stream->limit,
00684 format,
00685 FT_BOOL(face->header.color_flags & 2),
00686 &glyph->root.bitmap );
00687 }
00688 }
00689 }
00690
00691 FT_FRAME_EXIT();
00692 }
00693
00694 Exit:
00695 return error;
00696 }
00697
00698