27#define FT_COMPONENT pfr
46 } PFR_BitWriterRec, *PFR_BitWriter;
50 pfr_bitwriter_init( PFR_BitWriter writer,
54 writer->line = target->buffer;
55 writer->pitch = target->pitch;
56 writer->width = target->width;
57 writer->rows = target->rows;
58 writer->total = writer->width * writer->rows;
62 writer->line += writer->pitch * (FT_Int)( target->rows - 1 );
63 writer->pitch = -writer->pitch;
69 pfr_bitwriter_decode_bytes( PFR_BitWriter writer,
74 FT_UInt left = writer->width;
75 FT_Byte* cur = writer->line;
81 n = (FT_UInt)( limit - p ) * 8;
82 if ( n > writer->total )
89 if ( ( n & 7 ) == reload )
101 left = writer->width;
104 writer->line += writer->pitch;
108 else if ( mask == 0 )
123 pfr_bitwriter_decode_rle1( PFR_BitWriter writer,
127 FT_Int phase, count, counts[2];
129 FT_UInt left = writer->width;
130 FT_Byte* cur = writer->line;
169 }
while ( count == 0 );
180 left = writer->width;
183 writer->line += writer->pitch;
187 else if ( mask == 0 )
195 reload = ( --count <= 0 );
199 cur[0] = (FT_Byte) c;
204 pfr_bitwriter_decode_rle2( PFR_BitWriter writer,
210 FT_UInt left = writer->width;
211 FT_Byte* cur = writer->line;
234 }
while ( count == 0 );
247 left = writer->width;
249 writer->line += writer->pitch;
252 else if ( mask == 0 )
260 reload = ( --count <= 0 );
264 cur[0] = (FT_Byte) c;
277 pfr_lookup_bitmap_data( FT_Byte* base,
282 FT_ULong* found_offset,
283 FT_ULong* found_size )
285 FT_UInt min, max, mid, char_len;
286 FT_Bool two = FT_BOOL( *flags & PFR_BITMAP_2BYTE_CHARCODE );
293 if ( *flags & PFR_BITMAP_2BYTE_SIZE )
295 if ( *flags & PFR_BITMAP_3BYTE_OFFSET )
298 if ( !( *flags & PFR_BITMAP_CHARCODES_VALIDATED ) )
306 *flags |= PFR_BITMAP_VALID_CHARCODES;
308 lim = base + count * char_len;
312 FT_TRACE0((
"pfr_lookup_bitmap_data:"
313 " number of bitmap records too large,\n" ));
315 " thus ignoring all bitmaps in this strike\n" ));
316 *flags &= ~PFR_BITMAP_VALID_CHARCODES;
321 for ( p = base; p < lim; p += char_len )
324 code = FT_PEEK_USHORT( p );
328 if ( (FT_Long)
code <= prev_code )
330 FT_TRACE0((
"pfr_lookup_bitmap_data:"
331 " bitmap records are not sorted,\n" ));
333 " thus ignoring all bitmaps in this strike\n" ));
334 *flags &= ~PFR_BITMAP_VALID_CHARCODES;
342 *flags |= PFR_BITMAP_CHARCODES_VALIDATED;
347 if ( !( *flags & PFR_BITMAP_VALID_CHARCODES ) )
352 mid = min + ( max - min ) / 2;
360 buff = base + mid * char_len;
363 code = PFR_NEXT_USHORT( buff );
365 code = PFR_NEXT_BYTE( buff );
367 if ( char_code <
code )
369 else if ( char_code >
code )
375 mid += char_code -
code;
376 if ( mid >= max || mid < min )
377 mid = min + ( max - min ) / 2;
387 if ( *flags & PFR_BITMAP_2BYTE_SIZE )
388 *found_size = PFR_NEXT_USHORT( buff );
390 *found_size = PFR_NEXT_BYTE( buff );
392 if ( *flags & PFR_BITMAP_3BYTE_OFFSET )
393 *found_offset = PFR_NEXT_ULONG( buff );
395 *found_offset = PFR_NEXT_USHORT( buff );
403 pfr_load_bitmap_metrics( FT_Byte** pdata,
405 FT_Long scaled_advance,
413 FT_Error error = FT_Err_Ok;
417 FT_Long xpos, ypos, advance;
418 FT_UInt xsize, ysize;
422 flags = PFR_NEXT_BYTE( p );
434 b = PFR_NEXT_BYTE( p );
435 xpos = (FT_Char)b >> 4;
436 ypos = ( (FT_Char)( b << 4 ) ) >> 4;
441 xpos = PFR_NEXT_INT8( p );
442 ypos = PFR_NEXT_INT8( p );
447 xpos = PFR_NEXT_SHORT( p );
448 ypos = PFR_NEXT_SHORT( p );
453 xpos = PFR_NEXT_LONG( p );
454 ypos = PFR_NEXT_LONG( p );
472 b = PFR_NEXT_BYTE( p );
473 xsize = ( b >> 4 ) & 0xF;
479 xsize = PFR_NEXT_BYTE( p );
480 ysize = PFR_NEXT_BYTE( p );
485 xsize = PFR_NEXT_USHORT( p );
486 ysize = PFR_NEXT_USHORT( p );
497 advance = scaled_advance;
502 advance = PFR_NEXT_INT8( p ) * 256;
507 advance = PFR_NEXT_SHORT( p );
512 advance = PFR_NEXT_LONG( p );
524 *aformat = flags >> 2;
531 error = FT_THROW( Invalid_Table );
532 FT_ERROR((
"pfr_load_bitmap_metrics: invalid glyph data\n" ));
538 pfr_load_bitmap_bits( FT_Byte* p,
544 FT_Error error = FT_Err_Ok;
545 PFR_BitWriterRec writer;
548 if ( target->rows > 0 && target->width > 0 )
550 pfr_bitwriter_init( &writer, target, decreasing );
555 pfr_bitwriter_decode_bytes( &writer, p, limit );
559 pfr_bitwriter_decode_rle1( &writer, p, limit );
563 pfr_bitwriter_decode_rle2( &writer, p, limit );
583 FT_LOCAL_DEF( FT_Error )
584 pfr_slot_load_bitmap( PFR_Slot glyph,
587 FT_Bool metrics_only )
590 PFR_Face face = (PFR_Face) glyph->root.face;
591 FT_Stream stream = face->root.stream;
592 PFR_PhyFont phys = &face->phy_font;
599 character = &phys->chars[glyph_index];
607 strike = phys->strikes;
608 for ( n = 0; n < phys->num_strikes; n++ )
610 if ( strike->x_ppm == (FT_UInt)size->root.metrics.x_ppem &&
611 strike->y_ppm == (FT_UInt)size->root.metrics.y_ppem )
618 return FT_THROW( Invalid_Argument );
629 if ( strike->flags & PFR_BITMAP_2BYTE_CHARCODE )
631 if ( strike->flags & PFR_BITMAP_2BYTE_SIZE )
633 if ( strike->flags & PFR_BITMAP_3BYTE_OFFSET )
637 if ( FT_STREAM_SEEK( phys->bct_offset + strike->bct_offset ) ||
638 FT_FRAME_ENTER( char_len * strike->num_bitmaps ) )
641 pfr_lookup_bitmap_data( stream->cursor,
645 character->char_code,
654 error = FT_THROW( Invalid_Argument );
661 FT_Long xpos = 0, ypos = 0, advance = 0;
662 FT_UInt xsize = 0, ysize = 0, format = 0;
667 advance = character->advance;
668 if ( phys->metrics_resolution != phys->outline_resolution )
669 advance = FT_MulDiv( advance,
670 (FT_Long)phys->outline_resolution,
671 (FT_Long)phys->metrics_resolution );
673 glyph->root.linearHoriAdvance = advance;
677 advance = FT_MulDiv( (FT_Fixed)size->root.metrics.x_ppem << 8,
679 (FT_Long)phys->metrics_resolution );
681 if ( FT_STREAM_SEEK( face->header.gps_section_offset + gps_offset ) ||
682 FT_FRAME_ENTER( gps_size ) )
686 error = pfr_load_bitmap_metrics( &p, stream->limit,
718 if ( ( (FT_ULong)xsize * ysize + 7 ) / 8 > gps_size )
719 error = FT_THROW( Invalid_Table );
722 if ( (FT_ULong)xsize * ysize > 15 * gps_size )
723 error = FT_THROW( Invalid_Table );
726 if ( (FT_ULong)xsize * ysize > 255 * ( ( gps_size + 1 ) / 2 ) )
727 error = FT_THROW( Invalid_Table );
730 FT_ERROR((
"pfr_slot_load_bitmap: invalid image type\n" ));
731 error = FT_THROW( Invalid_Table );
736 if ( FT_ERR_EQ( error, Invalid_Table ) )
737 FT_ERROR((
"pfr_slot_load_bitmap: invalid bitmap dimensions\n" ));
746 if ( xpos > FT_INT_MAX ||
748 ysize > FT_INT_MAX ||
749 ypos > FT_INT_MAX - (FT_Long)ysize ||
750 ypos + (FT_Long)ysize < FT_INT_MIN )
752 FT_TRACE1((
"pfr_slot_load_bitmap:"
753 " huge bitmap glyph %ldx%ld over FT_GlyphSlot\n",
755 error = FT_THROW( Invalid_Pixel_Size );
760 glyph->root.format = FT_GLYPH_FORMAT_BITMAP;
765 glyph->root.bitmap.width = xsize;
766 glyph->root.bitmap.rows = ysize;
767 glyph->root.bitmap.pitch = (FT_Int)( xsize + 7 ) >> 3;
768 glyph->root.bitmap.pixel_mode = FT_PIXEL_MODE_MONO;
771 glyph->root.metrics.width = (FT_Pos)xsize << 6;
772 glyph->root.metrics.height = (FT_Pos)ysize << 6;
773 glyph->root.metrics.horiBearingX = xpos * 64;
774 glyph->root.metrics.horiBearingY = ypos * 64;
775 glyph->root.metrics.horiAdvance = FT_PIX_ROUND( ( advance >> 2 ) );
776 glyph->root.metrics.vertBearingX = - glyph->root.metrics.width >> 1;
777 glyph->root.metrics.vertBearingY = 0;
778 glyph->root.metrics.vertAdvance = size->root.metrics.height;
781 glyph->root.bitmap_left = (FT_Int)xpos;
782 glyph->root.bitmap_top = (FT_Int)( ypos + (FT_Long)ysize );
789 FT_ULong len = (FT_ULong)glyph->root.bitmap.pitch * ysize;
792 error = ft_glyphslot_alloc_bitmap( &glyph->root, len );
794 error = pfr_load_bitmap_bits(
798 FT_BOOL( face->header.color_flags &
799 PFR_FLAG_INVERT_BITMAP ),
800 &glyph->root.bitmap );