1 /***************************************************************************/
5 /* TrueType and OpenType embedded bitmap support (body). */
6 /* This is a heap-optimized version. */
8 /* Copyright 2005, 2006, 2007, 2008, 2009 by */
9 /* David Turner, Robert Wilhelm, and Werner Lemberg. */
11 /* This file is part of the FreeType project, and may only be used, */
12 /* modified, and distributed under the terms of the FreeType project */
13 /* license, LICENSE.TXT. By continuing to use, modify, or distribute */
14 /* this file you indicate that you have read the license and */
15 /* understand and accept it fully. */
17 /***************************************************************************/
20 /* This file is included by ttsbit.c */
24 #include FT_INTERNAL_DEBUG_H
25 #include FT_INTERNAL_STREAM_H
26 #include FT_TRUETYPE_TAGS_H
32 /*************************************************************************/
34 /* The macro FT_COMPONENT is used in trace mode. It is an implicit */
35 /* parameter of the FT_TRACE() and FT_ERROR() macros, used to print/log */
36 /* messages during execution. */
39 #define FT_COMPONENT trace_ttsbit
42 FT_LOCAL_DEF( FT_Error
)
43 tt_face_load_eblc( TT_Face face
,
46 FT_Error error
= SFNT_Err_Ok
;
48 FT_ULong num_strikes
, table_size
;
54 face
->sbit_num_strikes
= 0;
56 /* this table is optional */
57 error
= face
->goto_table( face
, TTAG_EBLC
, stream
, &table_size
);
59 error
= face
->goto_table( face
, TTAG_bloc
, stream
, &table_size
);
65 FT_ERROR(( "tt_face_load_sbit_strikes: table too short\n" ));
66 error
= SFNT_Err_Invalid_File_Format
;
70 if ( FT_FRAME_EXTRACT( table_size
, face
->sbit_table
) )
73 face
->sbit_table_size
= table_size
;
76 p_limit
= p
+ table_size
;
78 version
= FT_NEXT_ULONG( p
);
79 num_strikes
= FT_NEXT_ULONG( p
);
81 if ( version
!= 0x00020000UL
|| num_strikes
>= 0x10000UL
)
83 FT_ERROR(( "tt_face_load_sbit_strikes: invalid table version\n" ));
84 error
= SFNT_Err_Invalid_File_Format
;
89 * Count the number of strikes available in the table. We are a bit
90 * paranoid there and don't trust the data.
92 count
= (FT_UInt
)num_strikes
;
93 if ( 8 + 48UL * count
> table_size
)
94 count
= (FT_UInt
)( ( p_limit
- p
) / 48 );
96 face
->sbit_num_strikes
= count
;
98 FT_TRACE3(( "sbit_num_strikes: %u\n", count
));
103 FT_FRAME_RELEASE( face
->sbit_table
);
104 face
->sbit_table_size
= 0;
110 tt_face_free_eblc( TT_Face face
)
112 FT_Stream stream
= face
->root
.stream
;
115 FT_FRAME_RELEASE( face
->sbit_table
);
116 face
->sbit_table_size
= 0;
117 face
->sbit_num_strikes
= 0;
121 FT_LOCAL_DEF( FT_Error
)
122 tt_face_set_sbit_strike( TT_Face face
,
124 FT_ULong
* astrike_index
)
126 return FT_Match_Size( (FT_Face
)face
, req
, 0, astrike_index
);
130 FT_LOCAL_DEF( FT_Error
)
131 tt_face_load_strike_metrics( TT_Face face
,
132 FT_ULong strike_index
,
133 FT_Size_Metrics
* metrics
)
138 if ( strike_index
>= (FT_ULong
)face
->sbit_num_strikes
)
139 return SFNT_Err_Invalid_Argument
;
141 strike
= face
->sbit_table
+ 8 + strike_index
* 48;
143 metrics
->x_ppem
= (FT_UShort
)strike
[44];
144 metrics
->y_ppem
= (FT_UShort
)strike
[45];
146 metrics
->ascender
= (FT_Char
)strike
[16] << 6; /* hori.ascender */
147 metrics
->descender
= (FT_Char
)strike
[17] << 6; /* hori.descender */
148 metrics
->height
= metrics
->ascender
- metrics
->descender
;
150 /* XXX: Is this correct? */
151 metrics
->max_advance
= ( (FT_Char
)strike
[22] + /* min_origin_SB */
152 strike
[18] + /* max_width */
153 (FT_Char
)strike
[23] /* min_advance_SB */
160 typedef struct TT_SBitDecoderRec_
165 TT_SBit_Metrics metrics
;
166 FT_Bool metrics_loaded
;
167 FT_Bool bitmap_allocated
;
173 FT_ULong strike_index_array
;
174 FT_ULong strike_index_count
;
178 } TT_SBitDecoderRec
, *TT_SBitDecoder
;
182 tt_sbit_decoder_init( TT_SBitDecoder decoder
,
184 FT_ULong strike_index
,
185 TT_SBit_MetricsRec
* metrics
)
188 FT_Stream stream
= face
->root
.stream
;
192 error
= face
->goto_table( face
, TTAG_EBDT
, stream
, &ebdt_size
);
194 error
= face
->goto_table( face
, TTAG_bdat
, stream
, &ebdt_size
);
198 decoder
->face
= face
;
199 decoder
->stream
= stream
;
200 decoder
->bitmap
= &face
->root
.glyph
->bitmap
;
201 decoder
->metrics
= metrics
;
203 decoder
->metrics_loaded
= 0;
204 decoder
->bitmap_allocated
= 0;
206 decoder
->ebdt_start
= FT_STREAM_POS();
207 decoder
->ebdt_size
= ebdt_size
;
209 decoder
->eblc_base
= face
->sbit_table
;
210 decoder
->eblc_limit
= face
->sbit_table
+ face
->sbit_table_size
;
212 /* now find the strike corresponding to the index */
217 if ( 8 + 48 * strike_index
+ 3 * 4 + 34 + 1 > face
->sbit_table_size
)
219 error
= SFNT_Err_Invalid_File_Format
;
223 p
= decoder
->eblc_base
+ 8 + 48 * strike_index
;
225 decoder
->strike_index_array
= FT_NEXT_ULONG( p
);
227 decoder
->strike_index_count
= FT_NEXT_ULONG( p
);
229 decoder
->bit_depth
= *p
;
231 if ( decoder
->strike_index_array
> face
->sbit_table_size
||
232 decoder
->strike_index_array
+ 8 * decoder
->strike_index_count
>
233 face
->sbit_table_size
)
234 error
= SFNT_Err_Invalid_File_Format
;
243 tt_sbit_decoder_done( TT_SBitDecoder decoder
)
245 FT_UNUSED( decoder
);
250 tt_sbit_decoder_alloc_bitmap( TT_SBitDecoder decoder
)
252 FT_Error error
= SFNT_Err_Ok
;
253 FT_UInt width
, height
;
254 FT_Bitmap
* map
= decoder
->bitmap
;
258 if ( !decoder
->metrics_loaded
)
260 error
= SFNT_Err_Invalid_Argument
;
264 width
= decoder
->metrics
->width
;
265 height
= decoder
->metrics
->height
;
267 map
->width
= (int)width
;
268 map
->rows
= (int)height
;
270 switch ( decoder
->bit_depth
)
273 map
->pixel_mode
= FT_PIXEL_MODE_MONO
;
274 map
->pitch
= ( map
->width
+ 7 ) >> 3;
278 map
->pixel_mode
= FT_PIXEL_MODE_GRAY2
;
279 map
->pitch
= ( map
->width
+ 3 ) >> 2;
283 map
->pixel_mode
= FT_PIXEL_MODE_GRAY4
;
284 map
->pitch
= ( map
->width
+ 1 ) >> 1;
288 map
->pixel_mode
= FT_PIXEL_MODE_GRAY
;
289 map
->pitch
= map
->width
;
293 error
= SFNT_Err_Invalid_File_Format
;
297 size
= map
->rows
* map
->pitch
;
299 /* check that there is no empty image */
301 goto Exit
; /* exit successfully! */
303 error
= ft_glyphslot_alloc_bitmap( decoder
->face
->root
.glyph
, size
);
307 decoder
->bitmap_allocated
= 1;
315 tt_sbit_decoder_load_metrics( TT_SBitDecoder decoder
,
321 TT_SBit_Metrics metrics
= decoder
->metrics
;
327 metrics
->height
= p
[0];
328 metrics
->width
= p
[1];
329 metrics
->horiBearingX
= (FT_Char
)p
[2];
330 metrics
->horiBearingY
= (FT_Char
)p
[3];
331 metrics
->horiAdvance
= p
[4];
339 metrics
->vertBearingX
= (FT_Char
)p
[0];
340 metrics
->vertBearingY
= (FT_Char
)p
[1];
341 metrics
->vertAdvance
= p
[2];
346 decoder
->metrics_loaded
= 1;
351 return SFNT_Err_Invalid_Argument
;
355 /* forward declaration */
357 tt_sbit_decoder_load_image( TT_SBitDecoder decoder
,
362 typedef FT_Error (*TT_SBitDecoder_LoadFunc
)( TT_SBitDecoder decoder
,
370 tt_sbit_decoder_load_byte_aligned( TT_SBitDecoder decoder
,
376 FT_Error error
= SFNT_Err_Ok
;
378 FT_Int bit_height
, bit_width
, pitch
, width
, height
, h
;
382 if ( !decoder
->bitmap_allocated
)
384 error
= tt_sbit_decoder_alloc_bitmap( decoder
);
389 /* check that we can write the glyph into the bitmap */
390 bitmap
= decoder
->bitmap
;
391 bit_width
= bitmap
->width
;
392 bit_height
= bitmap
->rows
;
393 pitch
= bitmap
->pitch
;
394 line
= bitmap
->buffer
;
396 width
= decoder
->metrics
->width
;
397 height
= decoder
->metrics
->height
;
399 if ( x_pos
< 0 || x_pos
+ width
> bit_width
||
400 y_pos
< 0 || y_pos
+ height
> bit_height
)
402 error
= SFNT_Err_Invalid_File_Format
;
406 if ( p
+ ( ( width
+ 7 ) >> 3 ) * height
> limit
)
408 error
= SFNT_Err_Invalid_File_Format
;
412 /* now do the blit */
413 line
+= y_pos
* pitch
+ ( x_pos
>> 3 );
416 if ( x_pos
== 0 ) /* the easy one */
418 for ( h
= height
; h
> 0; h
--, line
+= pitch
)
420 FT_Byte
* write
= line
;
424 for ( w
= width
; w
>= 8; w
-= 8 )
426 write
[0] = (FT_Byte
)( write
[0] | *p
++ );
431 write
[0] = (FT_Byte
)( write
[0] | ( *p
++ & ( 0xFF00U
>> w
) ) );
436 for ( h
= height
; h
> 0; h
--, line
+= pitch
)
438 FT_Byte
* write
= line
;
443 for ( w
= width
; w
>= 8; w
-= 8 )
445 wval
= (FT_UInt
)( wval
| *p
++ );
446 write
[0] = (FT_Byte
)( write
[0] | ( wval
>> x_pos
) );
452 wval
= (FT_UInt
)( wval
| ( *p
++ & ( 0xFF00U
>> w
) ) );
454 /* all bits read and there are `x_pos + w' bits to be written */
456 write
[0] = (FT_Byte
)( write
[0] | ( wval
>> x_pos
) );
462 write
[0] = (FT_Byte
)( write
[0] | ( wval
>> x_pos
) );
473 * Load a bit-aligned bitmap (with pointer `p') into a line-aligned bitmap
474 * (with pointer `write'). In the example below, the width is 3 pixel,
475 * and `x_pos' is 1 pixel.
479 * | 7 6 5 4 3 2 1 0 | 7 6 5 4 3 2 1 0 |...
481 * +-------+ +-------+ +-------+ ...
487 * | 7 6 5 4 3 2 1 0 | .
494 * | 7 6 5 4 3 2 1 0 |
501 * | 7 6 5 4 3 2 1 0 |
508 tt_sbit_decoder_load_bit_aligned( TT_SBitDecoder decoder
,
514 FT_Error error
= SFNT_Err_Ok
;
516 FT_Int bit_height
, bit_width
, pitch
, width
, height
, h
, nbits
;
521 if ( !decoder
->bitmap_allocated
)
523 error
= tt_sbit_decoder_alloc_bitmap( decoder
);
528 /* check that we can write the glyph into the bitmap */
529 bitmap
= decoder
->bitmap
;
530 bit_width
= bitmap
->width
;
531 bit_height
= bitmap
->rows
;
532 pitch
= bitmap
->pitch
;
533 line
= bitmap
->buffer
;
535 width
= decoder
->metrics
->width
;
536 height
= decoder
->metrics
->height
;
538 if ( x_pos
< 0 || x_pos
+ width
> bit_width
||
539 y_pos
< 0 || y_pos
+ height
> bit_height
)
541 error
= SFNT_Err_Invalid_File_Format
;
545 if ( p
+ ( ( width
* height
+ 7 ) >> 3 ) > limit
)
547 error
= SFNT_Err_Invalid_File_Format
;
551 /* now do the blit */
553 /* adjust `line' to point to the first byte of the bitmap */
554 line
+= y_pos
* pitch
+ ( x_pos
>> 3 );
557 /* the higher byte of `rval' is used as a buffer */
561 for ( h
= height
; h
> 0; h
--, line
+= pitch
)
563 FT_Byte
* write
= line
;
567 /* handle initial byte (in target bitmap) specially if necessary */
570 w
= ( width
< 8 - x_pos
) ? width
: 8 - x_pos
;
577 else if ( nbits
< w
)
589 *write
++ |= ( ( rval
>> nbits
) & 0xFF ) &
590 ( ~( 0xFF << w
) << ( 8 - w
- x_pos
) );
596 /* handle medial bytes */
597 for ( ; w
>= 8; w
-= 8 )
600 *write
++ |= ( rval
>> nbits
) & 0xFF;
605 /* handle final byte if necessary */
612 *write
|= ( ( rval
>> nbits
) & 0xFF ) & ( 0xFF00U
>> w
);
619 *write
|= ( ( rval
>> nbits
) & 0xFF ) & ( 0xFF00U
>> w
);
631 tt_sbit_decoder_load_compound( TT_SBitDecoder decoder
,
637 FT_Error error
= SFNT_Err_Ok
;
638 FT_UInt num_components
, nn
;
640 FT_Char horiBearingX
= decoder
->metrics
->horiBearingX
;
641 FT_Char horiBearingY
= decoder
->metrics
->horiBearingY
;
642 FT_Byte horiAdvance
= decoder
->metrics
->horiAdvance
;
643 FT_Char vertBearingX
= decoder
->metrics
->vertBearingX
;
644 FT_Char vertBearingY
= decoder
->metrics
->vertBearingY
;
645 FT_Byte vertAdvance
= decoder
->metrics
->vertAdvance
;
651 num_components
= FT_NEXT_USHORT( p
);
652 if ( p
+ 4 * num_components
> limit
)
655 if ( !decoder
->bitmap_allocated
)
657 error
= tt_sbit_decoder_alloc_bitmap( decoder
);
662 for ( nn
= 0; nn
< num_components
; nn
++ )
664 FT_UInt gindex
= FT_NEXT_USHORT( p
);
665 FT_Byte dx
= FT_NEXT_BYTE( p
);
666 FT_Byte dy
= FT_NEXT_BYTE( p
);
669 /* NB: a recursive call */
670 error
= tt_sbit_decoder_load_image( decoder
, gindex
,
671 x_pos
+ dx
, y_pos
+ dy
);
676 decoder
->metrics
->horiBearingX
= horiBearingX
;
677 decoder
->metrics
->horiBearingY
= horiBearingY
;
678 decoder
->metrics
->horiAdvance
= horiAdvance
;
679 decoder
->metrics
->vertBearingX
= vertBearingX
;
680 decoder
->metrics
->vertBearingY
= vertBearingY
;
681 decoder
->metrics
->vertAdvance
= vertAdvance
;
682 decoder
->metrics
->width
= (FT_UInt
)decoder
->bitmap
->width
;
683 decoder
->metrics
->height
= (FT_UInt
)decoder
->bitmap
->rows
;
689 error
= SFNT_Err_Invalid_File_Format
;
695 tt_sbit_decoder_load_bitmap( TT_SBitDecoder decoder
,
696 FT_UInt glyph_format
,
697 FT_ULong glyph_start
,
703 FT_Stream stream
= decoder
->stream
;
709 /* seek into the EBDT table now */
710 if ( glyph_start
+ glyph_size
> decoder
->ebdt_size
)
712 error
= SFNT_Err_Invalid_Argument
;
716 if ( FT_STREAM_SEEK( decoder
->ebdt_start
+ glyph_start
) ||
717 FT_FRAME_EXTRACT( glyph_size
, data
) )
721 p_limit
= p
+ glyph_size
;
723 /* read the data, depending on the glyph format */
724 switch ( glyph_format
)
729 error
= tt_sbit_decoder_load_metrics( decoder
, &p
, p_limit
, 0 );
735 error
= tt_sbit_decoder_load_metrics( decoder
, &p
, p_limit
, 1 );
746 TT_SBitDecoder_LoadFunc loader
;
749 switch ( glyph_format
)
753 loader
= tt_sbit_decoder_load_byte_aligned
;
759 loader
= tt_sbit_decoder_load_bit_aligned
;
763 if ( p
+ 1 > p_limit
)
766 p
+= 1; /* skip padding */
770 loader
= tt_sbit_decoder_load_compound
;
777 error
= loader( decoder
, p
, p_limit
, x_pos
, y_pos
);
781 FT_FRAME_RELEASE( data
);
789 tt_sbit_decoder_load_image( TT_SBitDecoder decoder
,
795 * First, we find the correct strike range that applies to this
799 FT_Byte
* p
= decoder
->eblc_base
+ decoder
->strike_index_array
;
800 FT_Byte
* p_limit
= decoder
->eblc_limit
;
801 FT_ULong num_ranges
= decoder
->strike_index_count
;
802 FT_UInt start
, end
, index_format
, image_format
;
803 FT_ULong image_start
= 0, image_end
= 0, image_offset
;
806 for ( ; num_ranges
> 0; num_ranges
-- )
808 start
= FT_NEXT_USHORT( p
);
809 end
= FT_NEXT_USHORT( p
);
811 if ( glyph_index
>= start
&& glyph_index
<= end
)
814 p
+= 4; /* ignore index offset */
819 image_offset
= FT_NEXT_ULONG( p
);
822 if ( decoder
->eblc_base
+ decoder
->strike_index_array
+ image_offset
<
826 p
= decoder
->eblc_base
+ decoder
->strike_index_array
+ image_offset
;
827 if ( p
+ 8 > p_limit
)
830 /* now find the glyph's location and extend within the ebdt table */
831 index_format
= FT_NEXT_USHORT( p
);
832 image_format
= FT_NEXT_USHORT( p
);
833 image_offset
= FT_NEXT_ULONG ( p
);
835 switch ( index_format
)
837 case 1: /* 4-byte offsets relative to `image_offset' */
839 p
+= 4 * ( glyph_index
- start
);
840 if ( p
+ 8 > p_limit
)
843 image_start
= FT_NEXT_ULONG( p
);
844 image_end
= FT_NEXT_ULONG( p
);
846 if ( image_start
== image_end
) /* missing glyph */
851 case 2: /* big metrics, constant image size */
856 if ( p
+ 12 > p_limit
)
859 image_size
= FT_NEXT_ULONG( p
);
861 if ( tt_sbit_decoder_load_metrics( decoder
, &p
, p_limit
, 1 ) )
864 image_start
= image_size
* ( glyph_index
- start
);
865 image_end
= image_start
+ image_size
;
869 case 3: /* 2-byte offsets relative to 'image_offset' */
871 p
+= 2 * ( glyph_index
- start
);
872 if ( p
+ 4 > p_limit
)
875 image_start
= FT_NEXT_USHORT( p
);
876 image_end
= FT_NEXT_USHORT( p
);
878 if ( image_start
== image_end
) /* missing glyph */
883 case 4: /* sparse glyph array with (glyph,offset) pairs */
885 FT_ULong mm
, num_glyphs
;
888 if ( p
+ 4 > p_limit
)
891 num_glyphs
= FT_NEXT_ULONG( p
);
894 if ( p
+ ( num_glyphs
+ 1 ) * 4 < p
)
897 if ( p
+ ( num_glyphs
+ 1 ) * 4 > p_limit
)
900 for ( mm
= 0; mm
< num_glyphs
; mm
++ )
902 FT_UInt gindex
= FT_NEXT_USHORT( p
);
905 if ( gindex
== glyph_index
)
907 image_start
= FT_NEXT_USHORT( p
);
909 image_end
= FT_PEEK_USHORT( p
);
915 if ( mm
>= num_glyphs
)
920 case 5: /* constant metrics with sparse glyph codes */
922 FT_ULong image_size
, mm
, num_glyphs
;
925 if ( p
+ 16 > p_limit
)
928 image_size
= FT_NEXT_ULONG( p
);
930 if ( tt_sbit_decoder_load_metrics( decoder
, &p
, p_limit
, 1 ) )
933 num_glyphs
= FT_NEXT_ULONG( p
);
936 if ( p
+ 2 * num_glyphs
< p
)
939 if ( p
+ 2 * num_glyphs
> p_limit
)
942 for ( mm
= 0; mm
< num_glyphs
; mm
++ )
944 FT_UInt gindex
= FT_NEXT_USHORT( p
);
947 if ( gindex
== glyph_index
)
951 if ( mm
>= num_glyphs
)
954 image_start
= image_size
* mm
;
955 image_end
= image_start
+ image_size
;
963 if ( image_start
> image_end
)
966 image_end
-= image_start
;
967 image_start
= image_offset
+ image_start
;
969 return tt_sbit_decoder_load_bitmap( decoder
,
977 return SFNT_Err_Invalid_Table
;
980 return SFNT_Err_Invalid_Argument
;
985 tt_face_load_sbit_image( TT_Face face
,
986 FT_ULong strike_index
,
991 TT_SBit_MetricsRec
*metrics
)
993 TT_SBitDecoderRec decoder
[1];
996 FT_UNUSED( load_flags
);
1001 error
= tt_sbit_decoder_init( decoder
, face
, strike_index
, metrics
);
1004 error
= tt_sbit_decoder_load_image( decoder
, glyph_index
, 0, 0 );
1005 tt_sbit_decoder_done( decoder
);