1 /***************************************************************************/
5 /* FreeType PFR bitmap loader (body). */
7 /* Copyright 2002, 2003, 2006, 2009 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
= 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
);