1
/***************************************************************************/
5
/* FreeType PFR bitmap loader (body). */
7
/* Copyright 2002, 2003, 2006 by */
8
/* David Turner, Robert Wilhelm, and Werner Lemberg. */
10
/* This file is part of the FreeType project, and may only be used, */
11
/* modified, and distributed under the terms of the FreeType project */
12
/* license, LICENSE.TXT. By continuing to use, modify, or distribute */
13
/* this file you indicate that you have read the license and */
14
/* understand and accept it fully. */
16
/***************************************************************************/
21
#include FT_INTERNAL_DEBUG_H
22
#include FT_INTERNAL_STREAM_H
27
#define FT_COMPONENT trace_pfr
30
/*************************************************************************/
31
/*************************************************************************/
33
/***** PFR BIT WRITER *****/
35
/*************************************************************************/
36
/*************************************************************************/
38
typedef struct PFR_BitWriter_
40
FT_Byte* line; /* current line start */
41
FT_Int pitch; /* line size in bytes */
42
FT_Int width; /* width in pixels/bits */
43
FT_Int rows; /* number of remaining rows to scan */
44
FT_Int total; /* total number of bits to draw */
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 * ( target->rows-1 );
63
writer->pitch = -writer->pitch;
69
pfr_bitwriter_decode_bytes( PFR_BitWriter writer,
74
FT_Int left = writer->width;
75
FT_Byte* cur = writer->line;
81
n = (FT_Int)( 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 n, phase, count, counts[2], reload;
128
FT_Int left = writer->width;
129
FT_Byte* cur = writer->line;
168
} while ( count == 0 );
178
cur[0] = (FT_Byte) c;
179
left = writer->width;
182
writer->line += writer->pitch;
186
else if ( mask == 0 )
194
reload = ( --count <= 0 );
198
cur[0] = (FT_Byte) c;
203
pfr_bitwriter_decode_rle2( PFR_BitWriter writer,
207
FT_Int n, phase, count, reload;
208
FT_Int left = writer->width;
209
FT_Byte* cur = writer->line;
232
} while ( count == 0 );
242
cur[0] = (FT_Byte) c;
245
left = writer->width;
247
writer->line += writer->pitch;
250
else if ( mask == 0 )
258
reload = ( --count <= 0 );
262
cur[0] = (FT_Byte) c;
266
/*************************************************************************/
267
/*************************************************************************/
269
/***** BITMAP DATA DECODING *****/
271
/*************************************************************************/
272
/*************************************************************************/
275
pfr_lookup_bitmap_data( FT_Byte* base,
280
FT_ULong* found_offset,
281
FT_ULong* found_size )
283
FT_UInt left, right, char_len;
284
FT_Bool two = FT_BOOL( flags & 1 );
289
if ( two ) char_len += 1;
290
if ( flags & 2 ) char_len += 1;
291
if ( flags & 4 ) char_len += 1;
296
while ( left < right )
298
FT_UInt middle, code;
301
middle = ( left + right ) >> 1;
302
buff = base + middle * char_len;
304
/* check that we are not outside of the table -- */
305
/* this is possible with broken fonts... */
306
if ( buff + char_len > limit )
310
code = PFR_NEXT_USHORT( buff );
312
code = PFR_NEXT_BYTE( buff );
314
if ( code == char_code )
317
if ( code < char_code )
331
*found_size = PFR_NEXT_USHORT( buff );
333
*found_size = PFR_NEXT_BYTE( buff );
336
*found_offset = PFR_NEXT_ULONG( buff );
338
*found_offset = PFR_NEXT_USHORT( buff );
342
/* load bitmap metrics. "*padvance" must be set to the default value */
343
/* before calling this function... */
346
pfr_load_bitmap_metrics( FT_Byte** pdata,
348
FT_Long scaled_advance,
360
FT_Long xpos, ypos, advance;
361
FT_UInt xsize, ysize;
365
flags = PFR_NEXT_BYTE( p );
377
b = PFR_NEXT_INT8( p );
379
ypos = ( (FT_Char)( b << 4 ) ) >> 4;
384
xpos = PFR_NEXT_INT8( p );
385
ypos = PFR_NEXT_INT8( p );
390
xpos = PFR_NEXT_SHORT( p );
391
ypos = PFR_NEXT_SHORT( p );
396
xpos = PFR_NEXT_LONG( p );
397
ypos = PFR_NEXT_LONG( p );
415
b = PFR_NEXT_BYTE( p );
416
xsize = ( b >> 4 ) & 0xF;
422
xsize = PFR_NEXT_BYTE( p );
423
ysize = PFR_NEXT_BYTE( p );
428
xsize = PFR_NEXT_USHORT( p );
429
ysize = PFR_NEXT_USHORT( p );
440
advance = scaled_advance;
445
advance = PFR_NEXT_INT8( p ) << 8;
450
advance = PFR_NEXT_SHORT( p );
455
advance = PFR_NEXT_LONG( p );
467
*aformat = flags >> 2;
474
error = PFR_Err_Invalid_Table;
475
FT_ERROR(( "pfr_load_bitmap_metrics: invalid glyph data\n" ));
481
pfr_load_bitmap_bits( FT_Byte* p,
488
PFR_BitWriterRec writer;
491
if ( target->rows > 0 && target->width > 0 )
493
pfr_bitwriter_init( &writer, target, decreasing );
497
case 0: /* packed bits */
498
pfr_bitwriter_decode_bytes( &writer, p, limit );
502
pfr_bitwriter_decode_rle1( &writer, p, limit );
506
pfr_bitwriter_decode_rle2( &writer, p, limit );
510
FT_ERROR(( "pfr_read_bitmap_data: invalid image type\n" ));
511
error = PFR_Err_Invalid_File_Format;
519
/*************************************************************************/
520
/*************************************************************************/
522
/***** BITMAP LOADING *****/
524
/*************************************************************************/
525
/*************************************************************************/
528
pfr_slot_load_bitmap( PFR_Slot glyph,
530
FT_UInt glyph_index )
533
PFR_Face face = (PFR_Face) glyph->root.face;
534
FT_Stream stream = face->root.stream;
535
PFR_PhyFont phys = &face->phy_font;
542
character = &phys->chars[glyph_index];
544
/* Look-up a bitmap strike corresponding to the current */
545
/* character dimensions */
550
strike = phys->strikes;
551
for ( n = 0; n < phys->num_strikes; n++ )
553
if ( strike->x_ppm == (FT_UInt)size->root.metrics.x_ppem &&
554
strike->y_ppm == (FT_UInt)size->root.metrics.y_ppem )
562
/* couldn't find it */
563
return PFR_Err_Invalid_Argument;
568
/* Now lookup the glyph's position within the file */
574
if ( strike->flags & 1 ) char_len += 1;
575
if ( strike->flags & 2 ) char_len += 1;
576
if ( strike->flags & 4 ) char_len += 1;
578
/* Access data directly in the frame to speed lookups */
579
if ( FT_STREAM_SEEK( phys->bct_offset + strike->bct_offset ) ||
580
FT_FRAME_ENTER( char_len * strike->num_bitmaps ) )
583
pfr_lookup_bitmap_data( stream->cursor,
587
character->char_code,
595
/* Could not find a bitmap program string for this glyph */
596
error = PFR_Err_Invalid_Argument;
601
/* get the bitmap metrics */
603
FT_Long xpos, ypos, advance;
604
FT_UInt xsize, ysize, format;
608
/* compute linear advance */
609
advance = character->advance;
610
if ( phys->metrics_resolution != phys->outline_resolution )
611
advance = FT_MulDiv( advance,
612
phys->outline_resolution,
613
phys->metrics_resolution );
615
glyph->root.linearHoriAdvance = advance;
617
/* compute default advance, i.e., scaled advance. This can be */
618
/* overridden in the bitmap header of certain glyphs. */
619
advance = FT_MulDiv( (FT_Fixed)size->root.metrics.x_ppem << 8,
621
phys->metrics_resolution );
623
if ( FT_STREAM_SEEK( face->header.gps_section_offset + gps_offset ) ||
624
FT_FRAME_ENTER( gps_size ) )
628
error = pfr_load_bitmap_metrics( &p, stream->limit,
635
glyph->root.format = FT_GLYPH_FORMAT_BITMAP;
637
/* Set up glyph bitmap and metrics */
638
glyph->root.bitmap.width = (FT_Int)xsize;
639
glyph->root.bitmap.rows = (FT_Int)ysize;
640
glyph->root.bitmap.pitch = (FT_Long)( xsize + 7 ) >> 3;
641
glyph->root.bitmap.pixel_mode = FT_PIXEL_MODE_MONO;
643
glyph->root.metrics.width = (FT_Long)xsize << 6;
644
glyph->root.metrics.height = (FT_Long)ysize << 6;
645
glyph->root.metrics.horiBearingX = xpos << 6;
646
glyph->root.metrics.horiBearingY = ypos << 6;
647
glyph->root.metrics.horiAdvance = FT_PIX_ROUND( ( advance >> 2 ) );
648
glyph->root.metrics.vertBearingX = - glyph->root.metrics.width >> 1;
649
glyph->root.metrics.vertBearingY = 0;
650
glyph->root.metrics.vertAdvance = size->root.metrics.height;
652
glyph->root.bitmap_left = xpos;
653
glyph->root.bitmap_top = ypos + ysize;
655
/* Allocate and read bitmap data */
657
FT_ULong len = glyph->root.bitmap.pitch * ysize;
660
error = ft_glyphslot_alloc_bitmap( &glyph->root, len );
663
error = pfr_load_bitmap_bits(
667
FT_BOOL(face->header.color_flags & 2),
668
&glyph->root.bitmap );