1 /***************************************************************************/
5 /* TrueType and OpenType embedded bitmap support (body). */
6 /* This is a heap-optimized version. */
8 /* Copyright 2005, 2006, 2007 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 static const FT_Frame_Field tt_sbit_line_metrics_fields
[] =
45 #define FT_STRUCTURE TT_SBit_LineMetricsRec
47 /* no FT_FRAME_START */
48 FT_FRAME_CHAR( ascender
),
49 FT_FRAME_CHAR( descender
),
50 FT_FRAME_BYTE( max_width
),
52 FT_FRAME_CHAR( caret_slope_numerator
),
53 FT_FRAME_CHAR( caret_slope_denominator
),
54 FT_FRAME_CHAR( caret_offset
),
56 FT_FRAME_CHAR( min_origin_SB
),
57 FT_FRAME_CHAR( min_advance_SB
),
58 FT_FRAME_CHAR( max_before_BL
),
59 FT_FRAME_CHAR( min_after_BL
),
60 FT_FRAME_CHAR( pads
[0] ),
61 FT_FRAME_CHAR( pads
[1] ),
65 static const FT_Frame_Field tt_strike_start_fields
[] =
68 #define FT_STRUCTURE TT_SBit_StrikeRec
70 /* no FT_FRAME_START */
71 FT_FRAME_ULONG( ranges_offset
),
73 FT_FRAME_ULONG( num_ranges
),
74 FT_FRAME_ULONG( color_ref
),
78 static const FT_Frame_Field tt_strike_end_fields
[] =
80 /* no FT_FRAME_START */
81 FT_FRAME_USHORT( start_glyph
),
82 FT_FRAME_USHORT( end_glyph
),
83 FT_FRAME_BYTE ( x_ppem
),
84 FT_FRAME_BYTE ( y_ppem
),
85 FT_FRAME_BYTE ( bit_depth
),
86 FT_FRAME_CHAR ( flags
),
91 FT_LOCAL_DEF( FT_Error
)
92 tt_face_load_eblc( TT_Face face
,
95 FT_Error error
= SFNT_Err_Ok
;
97 FT_ULong num_strikes
, table_size
;
103 face
->sbit_num_strikes
= 0;
105 /* this table is optional */
106 error
= face
->goto_table( face
, TTAG_EBLC
, stream
, &table_size
);
108 error
= face
->goto_table( face
, TTAG_bloc
, stream
, &table_size
);
112 if ( table_size
< 8 )
114 FT_ERROR(( "%s: table too short!\n", "tt_face_load_sbit_strikes" ));
115 error
= SFNT_Err_Invalid_File_Format
;
119 if ( FT_FRAME_EXTRACT( table_size
, face
->sbit_table
) )
122 face
->sbit_table_size
= table_size
;
124 p
= face
->sbit_table
;
125 p_limit
= p
+ table_size
;
127 version
= FT_NEXT_ULONG( p
);
128 num_strikes
= FT_NEXT_ULONG( p
);
130 if ( version
!= 0x00020000UL
|| num_strikes
>= 0x10000UL
)
132 FT_ERROR(( "%s: invalid table version!\n",
133 "tt_face_load_sbit_strikes" ));
134 error
= SFNT_Err_Invalid_File_Format
;
139 * Count the number of strikes available in the table. We are a bit
140 * paranoid there and don't trust the data.
142 count
= (FT_UInt
)num_strikes
;
143 if ( 8 + 48UL * count
> table_size
)
144 count
= (FT_UInt
)( ( p_limit
- p
) / 48 );
146 face
->sbit_num_strikes
= count
;
148 FT_TRACE3(( "sbit_num_strikes: %u\n", count
));
153 FT_FRAME_RELEASE( face
->sbit_table
);
154 face
->sbit_table_size
= 0;
160 tt_face_free_eblc( TT_Face face
)
162 FT_Stream stream
= face
->root
.stream
;
165 FT_FRAME_RELEASE( face
->sbit_table
);
166 face
->sbit_table_size
= 0;
167 face
->sbit_num_strikes
= 0;
171 FT_LOCAL_DEF( FT_Error
)
172 tt_face_set_sbit_strike( TT_Face face
,
174 FT_ULong
* astrike_index
)
176 return FT_Match_Size( (FT_Face
)face
, req
, 0, astrike_index
);
180 FT_LOCAL_DEF( FT_Error
)
181 tt_face_load_strike_metrics( TT_Face face
,
182 FT_ULong strike_index
,
183 FT_Size_Metrics
* metrics
)
188 if ( strike_index
>= (FT_ULong
)face
->sbit_num_strikes
)
189 return SFNT_Err_Invalid_Argument
;
191 strike
= face
->sbit_table
+ 8 + strike_index
* 48;
193 metrics
->x_ppem
= (FT_UShort
)strike
[44];
194 metrics
->y_ppem
= (FT_UShort
)strike
[45];
196 metrics
->ascender
= (FT_Char
)strike
[16] << 6; /* hori.ascender */
197 metrics
->descender
= (FT_Char
)strike
[17] << 6; /* hori.descender */
198 metrics
->height
= metrics
->ascender
- metrics
->descender
;
200 /* XXX: Is this correct? */
201 metrics
->max_advance
= ( (FT_Char
)strike
[22] + /* min_origin_SB */
202 strike
[18] + /* max_width */
203 (FT_Char
)strike
[23] /* min_advance_SB */
215 TT_SBit_Metrics metrics
;
216 FT_Bool metrics_loaded
;
217 FT_Bool bitmap_allocated
;
223 FT_ULong strike_index_array
;
224 FT_ULong strike_index_count
;
228 } TT_SBitDecoderRec
, *TT_SBitDecoder
;
232 tt_sbit_decoder_init( TT_SBitDecoder decoder
,
234 FT_ULong strike_index
,
235 TT_SBit_MetricsRec
* metrics
)
238 FT_Stream stream
= face
->root
.stream
;
242 error
= face
->goto_table( face
, TTAG_EBDT
, stream
, &ebdt_size
);
244 error
= face
->goto_table( face
, TTAG_bdat
, stream
, &ebdt_size
);
248 decoder
->face
= face
;
249 decoder
->stream
= stream
;
250 decoder
->bitmap
= &face
->root
.glyph
->bitmap
;
251 decoder
->metrics
= metrics
;
253 decoder
->metrics_loaded
= 0;
254 decoder
->bitmap_allocated
= 0;
256 decoder
->ebdt_start
= FT_STREAM_POS();
257 decoder
->ebdt_size
= ebdt_size
;
259 decoder
->eblc_base
= face
->sbit_table
;
260 decoder
->eblc_limit
= face
->sbit_table
+ face
->sbit_table_size
;
262 /* now find the strike corresponding to the index */
267 if ( 8 + 48 * strike_index
+ 3 * 4 + 34 + 1 > face
->sbit_table_size
)
269 error
= SFNT_Err_Invalid_File_Format
;
273 p
= decoder
->eblc_base
+ 8 + 48 * strike_index
;
275 decoder
->strike_index_array
= FT_NEXT_ULONG( p
);
277 decoder
->strike_index_count
= FT_NEXT_ULONG( p
);
279 decoder
->bit_depth
= *p
;
281 if ( decoder
->strike_index_array
> face
->sbit_table_size
||
282 decoder
->strike_index_array
+ 8 * decoder
->strike_index_count
>
283 face
->sbit_table_size
)
284 error
= SFNT_Err_Invalid_File_Format
;
293 tt_sbit_decoder_done( TT_SBitDecoder decoder
)
295 FT_UNUSED( decoder
);
300 tt_sbit_decoder_alloc_bitmap( TT_SBitDecoder decoder
)
302 FT_Error error
= SFNT_Err_Ok
;
303 FT_UInt width
, height
;
304 FT_Bitmap
* map
= decoder
->bitmap
;
308 if ( !decoder
->metrics_loaded
)
310 error
= SFNT_Err_Invalid_Argument
;
314 width
= decoder
->metrics
->width
;
315 height
= decoder
->metrics
->height
;
317 map
->width
= (int)width
;
318 map
->rows
= (int)height
;
320 switch ( decoder
->bit_depth
)
323 map
->pixel_mode
= FT_PIXEL_MODE_MONO
;
324 map
->pitch
= ( map
->width
+ 7 ) >> 3;
328 map
->pixel_mode
= FT_PIXEL_MODE_GRAY2
;
329 map
->pitch
= ( map
->width
+ 3 ) >> 2;
333 map
->pixel_mode
= FT_PIXEL_MODE_GRAY4
;
334 map
->pitch
= ( map
->width
+ 1 ) >> 1;
338 map
->pixel_mode
= FT_PIXEL_MODE_GRAY
;
339 map
->pitch
= map
->width
;
343 error
= SFNT_Err_Invalid_File_Format
;
347 size
= map
->rows
* map
->pitch
;
349 /* check that there is no empty image */
351 goto Exit
; /* exit successfully! */
353 error
= ft_glyphslot_alloc_bitmap( decoder
->face
->root
.glyph
, size
);
357 decoder
->bitmap_allocated
= 1;
365 tt_sbit_decoder_load_metrics( TT_SBitDecoder decoder
,
371 TT_SBit_Metrics metrics
= decoder
->metrics
;
377 if ( !decoder
->metrics_loaded
)
379 metrics
->height
= p
[0];
380 metrics
->width
= p
[1];
381 metrics
->horiBearingX
= (FT_Char
)p
[2];
382 metrics
->horiBearingY
= (FT_Char
)p
[3];
383 metrics
->horiAdvance
= p
[4];
392 if ( !decoder
->metrics_loaded
)
394 metrics
->vertBearingX
= (FT_Char
)p
[0];
395 metrics
->vertBearingY
= (FT_Char
)p
[1];
396 metrics
->vertAdvance
= p
[2];
402 decoder
->metrics_loaded
= 1;
407 return SFNT_Err_Invalid_Argument
;
411 /* forward declaration */
413 tt_sbit_decoder_load_image( TT_SBitDecoder decoder
,
418 typedef FT_Error (*TT_SBitDecoder_LoadFunc
)( TT_SBitDecoder decoder
,
426 tt_sbit_decoder_load_byte_aligned( TT_SBitDecoder decoder
,
432 FT_Error error
= SFNT_Err_Ok
;
434 FT_Int bit_height
, bit_width
, pitch
, width
, height
, h
;
438 if ( !decoder
->bitmap_allocated
)
440 error
= tt_sbit_decoder_alloc_bitmap( decoder
);
445 /* check that we can write the glyph into the bitmap */
446 bitmap
= decoder
->bitmap
;
447 bit_width
= bitmap
->width
;
448 bit_height
= bitmap
->rows
;
449 pitch
= bitmap
->pitch
;
450 line
= bitmap
->buffer
;
452 width
= decoder
->metrics
->width
;
453 height
= decoder
->metrics
->height
;
455 if ( x_pos
< 0 || x_pos
+ width
> bit_width
||
456 y_pos
< 0 || y_pos
+ height
> bit_height
)
458 error
= SFNT_Err_Invalid_File_Format
;
462 if ( p
+ ( ( width
+ 7 ) >> 3 ) * height
> limit
)
464 error
= SFNT_Err_Invalid_File_Format
;
468 /* now do the blit */
469 line
+= y_pos
* pitch
+ ( x_pos
>> 3 );
472 if ( x_pos
== 0 ) /* the easy one */
474 for ( h
= height
; h
> 0; h
--, line
+= pitch
)
476 FT_Byte
* write
= line
;
480 for ( w
= width
; w
>= 8; w
-= 8 )
482 write
[0] = (FT_Byte
)( write
[0] | *p
++ );
487 write
[0] = (FT_Byte
)( write
[0] | ( *p
++ & ( 0xFF00U
>> w
) ) );
492 for ( h
= height
; h
> 0; h
--, line
+= pitch
)
494 FT_Byte
* write
= line
;
499 for ( w
= width
; w
>= 8; w
-= 8 )
501 wval
= (FT_UInt
)( wval
| *p
++ );
502 write
[0] = (FT_Byte
)( write
[0] | ( wval
>> x_pos
) );
508 wval
= (FT_UInt
)( wval
| ( *p
++ & ( 0xFF00U
>> w
) ) );
510 /* all bits read and there are ( x_pos + w ) bits to be written */
512 write
[0] = (FT_Byte
)( write
[0] | ( wval
>> x_pos
) );
518 write
[0] = (FT_Byte
)( write
[0] | ( wval
>> x_pos
) );
529 tt_sbit_decoder_load_bit_aligned( TT_SBitDecoder decoder
,
535 FT_Error error
= SFNT_Err_Ok
;
537 FT_Int bit_height
, bit_width
, pitch
, width
, height
, h
, nbits
;
542 if ( !decoder
->bitmap_allocated
)
544 error
= tt_sbit_decoder_alloc_bitmap( decoder
);
549 /* check that we can write the glyph into the bitmap */
550 bitmap
= decoder
->bitmap
;
551 bit_width
= bitmap
->width
;
552 bit_height
= bitmap
->rows
;
553 pitch
= bitmap
->pitch
;
554 line
= bitmap
->buffer
;
556 width
= decoder
->metrics
->width
;
557 height
= decoder
->metrics
->height
;
559 if ( x_pos
< 0 || x_pos
+ width
> bit_width
||
560 y_pos
< 0 || y_pos
+ height
> bit_height
)
562 error
= SFNT_Err_Invalid_File_Format
;
566 if ( p
+ ( ( width
* height
+ 7 ) >> 3 ) > limit
)
568 error
= SFNT_Err_Invalid_File_Format
;
572 /* now do the blit */
573 line
+= y_pos
* pitch
+ ( x_pos
>> 3 );
576 /* the higher byte of `rval' is used as a buffer */
580 for ( h
= height
; h
> 0; h
--, line
+= pitch
)
582 FT_Byte
* write
= line
;
588 w
= ( width
< 8 - x_pos
) ? width
: 8 - x_pos
;
601 *write
++ |= ( ( rval
>> nbits
) & 0xFF ) & ~( 0xFF << w
);
607 for ( ; w
>= 8; w
-= 8 )
610 *write
++ |= ( rval
>> nbits
) & 0xFF;
620 *write
|= ( ( rval
>> nbits
) & 0xFF ) & ( 0xFF00U
>> w
);
627 *write
|= ( ( rval
>> nbits
) & 0xFF ) & ( 0xFF00U
>> w
);
639 tt_sbit_decoder_load_compound( TT_SBitDecoder decoder
,
645 FT_Error error
= SFNT_Err_Ok
;
646 FT_UInt num_components
, nn
;
652 num_components
= FT_NEXT_USHORT( p
);
653 if ( p
+ 4 * num_components
> limit
)
656 for ( nn
= 0; nn
< num_components
; nn
++ )
658 FT_UInt gindex
= FT_NEXT_USHORT( p
);
659 FT_Byte dx
= FT_NEXT_BYTE( p
);
660 FT_Byte dy
= FT_NEXT_BYTE( p
);
663 /* NB: a recursive call */
664 error
= tt_sbit_decoder_load_image( decoder
, gindex
,
665 x_pos
+ dx
, y_pos
+ dy
);
674 error
= SFNT_Err_Invalid_File_Format
;
680 tt_sbit_decoder_load_bitmap( TT_SBitDecoder decoder
,
681 FT_UInt glyph_format
,
682 FT_ULong glyph_start
,
688 FT_Stream stream
= decoder
->stream
;
694 /* seek into the EBDT table now */
695 if ( glyph_start
+ glyph_size
> decoder
->ebdt_size
)
697 error
= SFNT_Err_Invalid_Argument
;
701 if ( FT_STREAM_SEEK( decoder
->ebdt_start
+ glyph_start
) ||
702 FT_FRAME_EXTRACT( glyph_size
, data
) )
706 p_limit
= p
+ glyph_size
;
708 /* read the data, depending on the glyph format */
709 switch ( glyph_format
)
714 error
= tt_sbit_decoder_load_metrics( decoder
, &p
, p_limit
, 0 );
720 error
= tt_sbit_decoder_load_metrics( decoder
, &p
, p_limit
, 1 );
731 TT_SBitDecoder_LoadFunc loader
;
734 switch ( glyph_format
)
738 loader
= tt_sbit_decoder_load_byte_aligned
;
744 loader
= tt_sbit_decoder_load_bit_aligned
;
748 if ( p
+ 1 > p_limit
)
751 p
+= 1; /* skip padding */
755 loader
= tt_sbit_decoder_load_compound
;
762 error
= loader( decoder
, p
, p_limit
, x_pos
, y_pos
);
766 FT_FRAME_RELEASE( data
);
774 tt_sbit_decoder_load_image( TT_SBitDecoder decoder
,
780 * First, we find the correct strike range that applies to this
784 FT_Byte
* p
= decoder
->eblc_base
+ decoder
->strike_index_array
;
785 FT_Byte
* p_limit
= decoder
->eblc_limit
;
786 FT_ULong num_ranges
= decoder
->strike_index_count
;
787 FT_UInt start
, end
, index_format
, image_format
;
788 FT_ULong image_start
= 0, image_end
= 0, image_offset
;
791 for ( ; num_ranges
> 0; num_ranges
-- )
793 start
= FT_NEXT_USHORT( p
);
794 end
= FT_NEXT_USHORT( p
);
796 if ( glyph_index
>= start
&& glyph_index
<= end
)
799 p
+= 4; /* ignore index offset */
804 image_offset
= FT_NEXT_ULONG( p
);
807 if ( decoder
->eblc_base
+ decoder
->strike_index_array
+ image_offset
<
811 p
= decoder
->eblc_base
+ decoder
->strike_index_array
+ image_offset
;
812 if ( p
+ 8 > p_limit
)
815 /* now find the glyph's location and extend within the ebdt table */
816 index_format
= FT_NEXT_USHORT( p
);
817 image_format
= FT_NEXT_USHORT( p
);
818 image_offset
= FT_NEXT_ULONG ( p
);
820 switch ( index_format
)
822 case 1: /* 4-byte offsets relative to `image_offset' */
824 p
+= 4 * ( glyph_index
- start
);
825 if ( p
+ 8 > p_limit
)
828 image_start
= FT_NEXT_ULONG( p
);
829 image_end
= FT_NEXT_ULONG( p
);
831 if ( image_start
== image_end
) /* missing glyph */
836 case 2: /* big metrics, constant image size */
841 if ( p
+ 12 > p_limit
)
844 image_size
= FT_NEXT_ULONG( p
);
846 if ( tt_sbit_decoder_load_metrics( decoder
, &p
, p_limit
, 1 ) )
849 image_start
= image_size
* ( glyph_index
- start
);
850 image_end
= image_start
+ image_size
;
854 case 3: /* 2-byte offsets relative to 'image_offset' */
856 p
+= 2 * ( glyph_index
- start
);
857 if ( p
+ 4 > p_limit
)
860 image_start
= FT_NEXT_USHORT( p
);
861 image_end
= FT_NEXT_USHORT( p
);
863 if ( image_start
== image_end
) /* missing glyph */
868 case 4: /* sparse glyph array with (glyph,offset) pairs */
870 FT_ULong mm
, num_glyphs
;
873 if ( p
+ 4 > p_limit
)
876 num_glyphs
= FT_NEXT_ULONG( p
);
879 if ( p
+ ( num_glyphs
+ 1 ) * 4 < p
)
882 if ( p
+ ( num_glyphs
+ 1 ) * 4 > p_limit
)
885 for ( mm
= 0; mm
< num_glyphs
; mm
++ )
887 FT_UInt gindex
= FT_NEXT_USHORT( p
);
890 if ( gindex
== glyph_index
)
892 image_start
= FT_NEXT_USHORT( p
);
894 image_end
= FT_PEEK_USHORT( p
);
900 if ( mm
>= num_glyphs
)
905 case 5: /* constant metrics with sparse glyph codes */
907 FT_ULong image_size
, mm
, num_glyphs
;
910 if ( p
+ 16 > p_limit
)
913 image_size
= FT_NEXT_ULONG( p
);
915 if ( tt_sbit_decoder_load_metrics( decoder
, &p
, p_limit
, 1 ) )
918 num_glyphs
= FT_NEXT_ULONG( p
);
921 if ( p
+ 2 * num_glyphs
< p
)
924 if ( p
+ 2 * num_glyphs
> p_limit
)
927 for ( mm
= 0; mm
< num_glyphs
; mm
++ )
929 FT_UInt gindex
= FT_NEXT_USHORT( p
);
932 if ( gindex
== glyph_index
)
936 if ( mm
>= num_glyphs
)
939 image_start
= image_size
* mm
;
940 image_end
= image_start
+ image_size
;
948 if ( image_start
> image_end
)
951 image_end
-= image_start
;
952 image_start
= image_offset
+ image_start
;
954 return tt_sbit_decoder_load_bitmap( decoder
,
962 return SFNT_Err_Invalid_Table
;
965 return SFNT_Err_Invalid_Argument
;
970 tt_face_load_sbit_image( TT_Face face
,
971 FT_ULong strike_index
,
976 TT_SBit_MetricsRec
*metrics
)
978 TT_SBitDecoderRec decoder
[1];
981 FT_UNUSED( load_flags
);
986 error
= tt_sbit_decoder_init( decoder
, face
, strike_index
, metrics
);
989 error
= tt_sbit_decoder_load_image( decoder
, glyph_index
, 0, 0 );
990 tt_sbit_decoder_done( decoder
);