1 /***************************************************************************/
5 /* FreeType PFR bitmap loader (body). */
7 /* Copyright 2002, 2003, 2006, 2009, 2010 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,
356 FT_Error error = PFR_Err_Ok;
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,
487 FT_Error error = PFR_Err_Ok;
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 = 0, ypos = 0, advance = 0;
604 FT_UInt xsize = 0, ysize = 0, format = 0;
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 * XXX: on 16bit system, we return an error for huge bitmap
636 * which causes a size truncation, because truncated
637 * size properties makes bitmap glyph broken.
639 if ( xpos > FT_INT_MAX || ( ypos + ysize ) > FT_INT_MAX )
641 FT_TRACE1(( "pfr_slot_load_bitmap:" ));
642 FT_TRACE1(( "huge bitmap glyph %dx%d over FT_GlyphSlot\n",
644 error = PFR_Err_Invalid_Pixel_Size;
649 glyph->root.format = FT_GLYPH_FORMAT_BITMAP;
651 /* Set up glyph bitmap and metrics */
653 /* XXX: needs casts to fit FT_Bitmap.{width|rows|pitch} */
654 glyph->root.bitmap.width = (FT_Int)xsize;
655 glyph->root.bitmap.rows = (FT_Int)ysize;
656 glyph->root.bitmap.pitch = (FT_Int)( xsize + 7 ) >> 3;
657 glyph->root.bitmap.pixel_mode = FT_PIXEL_MODE_MONO;
659 /* XXX: needs casts to fit FT_Glyph_Metrics.{width|height} */
660 glyph->root.metrics.width = (FT_Pos)xsize << 6;
661 glyph->root.metrics.height = (FT_Pos)ysize << 6;
662 glyph->root.metrics.horiBearingX = xpos << 6;
663 glyph->root.metrics.horiBearingY = ypos << 6;
664 glyph->root.metrics.horiAdvance = FT_PIX_ROUND( ( advance >> 2 ) );
665 glyph->root.metrics.vertBearingX = - glyph->root.metrics.width >> 1;
666 glyph->root.metrics.vertBearingY = 0;
667 glyph->root.metrics.vertAdvance = size->root.metrics.height;
669 /* XXX: needs casts fit FT_GlyphSlotRec.bitmap_{left|top} */
670 glyph->root.bitmap_left = (FT_Int)xpos;
671 glyph->root.bitmap_top = (FT_Int)(ypos + ysize);
673 /* Allocate and read bitmap data */
675 FT_ULong len = glyph->root.bitmap.pitch * ysize;
678 error = ft_glyphslot_alloc_bitmap( &glyph->root, len );
681 error = pfr_load_bitmap_bits(
685 FT_BOOL(face->header.color_flags & 2),
686 &glyph->root.bitmap );