1 /***************************************************************************/
5 /* TrueType and OpenType embedded bitmap support (body). */
7 /* Copyright 2005-2016 by */
8 /* David Turner, Robert Wilhelm, and Werner Lemberg. */
10 /* Copyright 2013 by Google, Inc. */
11 /* Google Author(s): Behdad Esfahbod. */
13 /* This file is part of the FreeType project, and may only be used, */
14 /* modified, and distributed under the terms of the FreeType project */
15 /* license, LICENSE.TXT. By continuing to use, modify, or distribute */
16 /* this file you indicate that you have read the license and */
17 /* understand and accept it fully. */
19 /***************************************************************************/
23 #include FT_INTERNAL_DEBUG_H
24 #include FT_INTERNAL_STREAM_H
25 #include FT_TRUETYPE_TAGS_H
35 /*************************************************************************/
37 /* The macro FT_COMPONENT is used in trace mode. It is an implicit */
38 /* parameter of the FT_TRACE() and FT_ERROR() macros, used to print/log */
39 /* messages during execution. */
42 #define FT_COMPONENT trace_ttsbit
45 FT_LOCAL_DEF( FT_Error
)
46 tt_face_load_sbit( TT_Face face
,
54 face
->sbit_table
= NULL
;
55 face
->sbit_table_size
= 0;
56 face
->sbit_table_type
= TT_SBIT_TABLE_TYPE_NONE
;
57 face
->sbit_num_strikes
= 0;
59 error
= face
->goto_table( face
, TTAG_CBLC
, stream
, &table_size
);
61 face
->sbit_table_type
= TT_SBIT_TABLE_TYPE_CBLC
;
64 error
= face
->goto_table( face
, TTAG_EBLC
, stream
, &table_size
);
66 error
= face
->goto_table( face
, TTAG_bloc
, stream
, &table_size
);
68 face
->sbit_table_type
= TT_SBIT_TABLE_TYPE_EBLC
;
73 error
= face
->goto_table( face
, TTAG_sbix
, stream
, &table_size
);
75 face
->sbit_table_type
= TT_SBIT_TABLE_TYPE_SBIX
;
82 FT_ERROR(( "tt_face_load_sbit_strikes: table too short\n" ));
83 error
= FT_THROW( Invalid_File_Format
);
87 table_start
= FT_STREAM_POS();
89 switch ( (FT_UInt
)face
->sbit_table_type
)
91 case TT_SBIT_TABLE_TYPE_EBLC
:
92 case TT_SBIT_TABLE_TYPE_CBLC
:
100 if ( FT_FRAME_EXTRACT( table_size
, face
->sbit_table
) )
103 face
->sbit_table_size
= table_size
;
105 p
= face
->sbit_table
;
107 version
= FT_NEXT_LONG( p
);
108 num_strikes
= FT_NEXT_ULONG( p
);
110 /* there's at least one font (FZShuSong-Z01, version 3) */
111 /* that uses the wrong byte order for the `version' field */
112 if ( ( (FT_ULong
)version
& 0xFFFF0000UL
) != 0x00020000UL
&&
113 ( (FT_ULong
)version
& 0x0000FFFFUL
) != 0x00000200UL
&&
114 ( (FT_ULong
)version
& 0xFFFF0000UL
) != 0x00030000UL
&&
115 ( (FT_ULong
)version
& 0x0000FFFFUL
) != 0x00000300UL
)
117 error
= FT_THROW( Unknown_File_Format
);
121 if ( num_strikes
>= 0x10000UL
)
123 error
= FT_THROW( Invalid_File_Format
);
128 * Count the number of strikes available in the table. We are a bit
129 * paranoid there and don't trust the data.
131 count
= (FT_UInt
)num_strikes
;
132 if ( 8 + 48UL * count
> table_size
)
133 count
= (FT_UInt
)( ( table_size
- 8 ) / 48 );
135 face
->sbit_num_strikes
= count
;
139 case TT_SBIT_TABLE_TYPE_SBIX
:
143 FT_ULong num_strikes
;
147 if ( FT_FRAME_ENTER( 8 ) )
150 version
= FT_GET_USHORT();
151 flags
= FT_GET_USHORT();
152 num_strikes
= FT_GET_ULONG();
158 error
= FT_THROW( Unknown_File_Format
);
162 /* Bit 0 must always be `1'. */
163 /* Bit 1 controls the overlay of bitmaps with outlines. */
164 /* All other bits should be zero. */
165 if ( !( flags
== 1 || flags
== 3 ) ||
166 num_strikes
>= 0x10000UL
)
168 error
= FT_THROW( Invalid_File_Format
);
172 /* we currently don't support bit 1; however, it is better to */
173 /* draw at least something... */
175 FT_TRACE1(( "tt_face_load_sbit_strikes:"
176 " sbix overlay not supported yet\n"
178 " expect bad rendering results\n" ));
181 * Count the number of strikes available in the table. We are a bit
182 * paranoid there and don't trust the data.
184 count
= (FT_UInt
)num_strikes
;
185 if ( 8 + 4UL * count
> table_size
)
186 count
= (FT_UInt
)( ( table_size
- 8 ) / 4 );
188 if ( FT_STREAM_SEEK( FT_STREAM_POS() - 8 ) )
191 face
->sbit_table_size
= 8 + count
* 4;
192 if ( FT_FRAME_EXTRACT( face
->sbit_table_size
, face
->sbit_table
) )
195 face
->sbit_num_strikes
= count
;
200 /* we ignore unknown table formats */
201 error
= FT_THROW( Unknown_File_Format
);
206 FT_TRACE3(( "tt_face_load_sbit_strikes: found %u strikes\n",
207 face
->sbit_num_strikes
));
209 face
->ebdt_start
= 0;
212 if ( face
->sbit_table_type
== TT_SBIT_TABLE_TYPE_SBIX
)
214 /* the `sbix' table is self-contained; */
215 /* it has no associated data table */
216 face
->ebdt_start
= table_start
;
217 face
->ebdt_size
= table_size
;
219 else if ( face
->sbit_table_type
!= TT_SBIT_TABLE_TYPE_NONE
)
224 error
= face
->goto_table( face
, TTAG_CBDT
, stream
, &ebdt_size
);
226 error
= face
->goto_table( face
, TTAG_EBDT
, stream
, &ebdt_size
);
228 error
= face
->goto_table( face
, TTAG_bdat
, stream
, &ebdt_size
);
232 face
->ebdt_start
= FT_STREAM_POS();
233 face
->ebdt_size
= ebdt_size
;
237 if ( !face
->ebdt_size
)
239 FT_TRACE2(( "tt_face_load_sbit_strikes:"
240 " no embedded bitmap data table found;\n"
242 " resetting number of strikes to zero\n" ));
243 face
->sbit_num_strikes
= 0;
251 if ( face
->sbit_table
)
252 FT_FRAME_RELEASE( face
->sbit_table
);
253 face
->sbit_table_size
= 0;
254 face
->sbit_table_type
= TT_SBIT_TABLE_TYPE_NONE
;
262 tt_face_free_sbit( TT_Face face
)
264 FT_Stream stream
= face
->root
.stream
;
267 FT_FRAME_RELEASE( face
->sbit_table
);
268 face
->sbit_table_size
= 0;
269 face
->sbit_table_type
= TT_SBIT_TABLE_TYPE_NONE
;
270 face
->sbit_num_strikes
= 0;
274 FT_LOCAL_DEF( FT_Error
)
275 tt_face_set_sbit_strike( TT_Face face
,
277 FT_ULong
* astrike_index
)
279 return FT_Match_Size( (FT_Face
)face
, req
, 0, astrike_index
);
283 FT_LOCAL_DEF( FT_Error
)
284 tt_face_load_strike_metrics( TT_Face face
,
285 FT_ULong strike_index
,
286 FT_Size_Metrics
* metrics
)
288 /* we have to test for the existence of `sbit_strike_map' */
289 /* because the function gets also used at the very beginning */
290 /* to construct `sbit_strike_map' itself */
291 if ( face
->sbit_strike_map
)
293 if ( strike_index
>= (FT_ULong
)face
->root
.num_fixed_sizes
)
294 return FT_THROW( Invalid_Argument
);
296 /* map to real index */
297 strike_index
= face
->sbit_strike_map
[strike_index
];
301 if ( strike_index
>= (FT_ULong
)face
->sbit_num_strikes
)
302 return FT_THROW( Invalid_Argument
);
305 switch ( (FT_UInt
)face
->sbit_table_type
)
307 case TT_SBIT_TABLE_TYPE_EBLC
:
308 case TT_SBIT_TABLE_TYPE_CBLC
:
311 FT_Char max_before_bl
;
312 FT_Char min_after_bl
;
315 strike
= face
->sbit_table
+ 8 + strike_index
* 48;
317 metrics
->x_ppem
= (FT_UShort
)strike
[44];
318 metrics
->y_ppem
= (FT_UShort
)strike
[45];
320 metrics
->ascender
= (FT_Char
)strike
[16] * 64; /* hori.ascender */
321 metrics
->descender
= (FT_Char
)strike
[17] * 64; /* hori.descender */
323 /* Due to fuzzy wording in the EBLC documentation, we find both */
324 /* positive and negative values for `descender'. Additionally, */
325 /* many fonts have both `ascender' and `descender' set to zero */
326 /* (which is definitely wrong). MS Windows simply ignores all */
327 /* those values... For these reasons we apply some heuristics */
328 /* to get a reasonable, non-zero value for the height. */
330 max_before_bl
= (FT_Char
)strike
[24];
331 min_after_bl
= (FT_Char
)strike
[25];
333 if ( metrics
->descender
> 0 )
335 /* compare sign of descender with `min_after_bl' */
336 if ( min_after_bl
< 0 )
337 metrics
->descender
= -metrics
->descender
;
340 else if ( metrics
->descender
== 0 )
342 if ( metrics
->ascender
== 0 )
344 FT_TRACE2(( "tt_face_load_strike_metrics:"
345 " sanitizing invalid ascender and descender\n"
347 " values for strike %d (%dppem, %dppem)\n",
349 metrics
->x_ppem
, metrics
->y_ppem
));
351 /* sanitize buggy ascender and descender values */
352 if ( max_before_bl
|| min_after_bl
)
354 metrics
->ascender
= max_before_bl
* 64;
355 metrics
->descender
= min_after_bl
* 64;
359 metrics
->ascender
= metrics
->y_ppem
* 64;
360 metrics
->descender
= 0;
367 ; /* if we have a negative descender, simply use it */
370 metrics
->height
= metrics
->ascender
- metrics
->descender
;
371 if ( metrics
->height
== 0 )
373 FT_TRACE2(( "tt_face_load_strike_metrics:"
374 " sanitizing invalid height value\n"
376 " for strike (%d, %d)\n",
377 metrics
->x_ppem
, metrics
->y_ppem
));
378 metrics
->height
= metrics
->y_ppem
* 64;
379 metrics
->descender
= metrics
->ascender
- metrics
->height
;
382 /* Is this correct? */
383 metrics
->max_advance
= ( (FT_Char
)strike
[22] + /* min_origin_SB */
384 strike
[18] + /* max_width */
385 (FT_Char
)strike
[23] /* min_advance_SB */
388 /* set the scale values (in 16.16 units) so advances */
389 /* from the hmtx and vmtx table are scaled correctly */
390 metrics
->x_scale
= FT_MulDiv( metrics
->x_ppem
,
392 face
->header
.Units_Per_EM
);
393 metrics
->y_scale
= FT_MulDiv( metrics
->y_ppem
,
395 face
->header
.Units_Per_EM
);
400 case TT_SBIT_TABLE_TYPE_SBIX
:
402 FT_Stream stream
= face
->root
.stream
;
404 FT_UShort upem
, ppem
, resolution
;
406 FT_Pos ppem_
; /* to reduce casts */
412 p
= face
->sbit_table
+ 8 + 4 * strike_index
;
413 offset
= FT_NEXT_ULONG( p
);
415 if ( offset
+ 4 > face
->ebdt_size
)
416 return FT_THROW( Invalid_File_Format
);
418 if ( FT_STREAM_SEEK( face
->ebdt_start
+ offset
) ||
419 FT_FRAME_ENTER( 4 ) )
422 ppem
= FT_GET_USHORT();
423 resolution
= FT_GET_USHORT();
425 FT_UNUSED( resolution
); /* What to do with this? */
429 upem
= face
->header
.Units_Per_EM
;
430 hori
= &face
->horizontal
;
432 metrics
->x_ppem
= ppem
;
433 metrics
->y_ppem
= ppem
;
435 ppem_
= (FT_Pos
)ppem
;
438 FT_MulDiv( hori
->Ascender
, ppem_
* 64, upem
);
440 FT_MulDiv( hori
->Descender
, ppem_
* 64, upem
);
442 FT_MulDiv( hori
->Ascender
- hori
->Descender
+ hori
->Line_Gap
,
444 metrics
->max_advance
=
445 FT_MulDiv( hori
->advance_Width_Max
, ppem_
* 64, upem
);
451 return FT_THROW( Unknown_File_Format
);
456 typedef struct TT_SBitDecoderRec_
461 TT_SBit_Metrics metrics
;
462 FT_Bool metrics_loaded
;
463 FT_Bool bitmap_allocated
;
469 FT_ULong strike_index_array
;
470 FT_ULong strike_index_count
;
474 } TT_SBitDecoderRec
, *TT_SBitDecoder
;
478 tt_sbit_decoder_init( TT_SBitDecoder decoder
,
480 FT_ULong strike_index
,
481 TT_SBit_MetricsRec
* metrics
)
483 FT_Error error
= FT_ERR( Table_Missing
);
484 FT_Stream stream
= face
->root
.stream
;
487 strike_index
= face
->sbit_strike_map
[strike_index
];
489 if ( !face
->ebdt_size
)
491 if ( FT_STREAM_SEEK( face
->ebdt_start
) )
494 decoder
->face
= face
;
495 decoder
->stream
= stream
;
496 decoder
->bitmap
= &face
->root
.glyph
->bitmap
;
497 decoder
->metrics
= metrics
;
499 decoder
->metrics_loaded
= 0;
500 decoder
->bitmap_allocated
= 0;
502 decoder
->ebdt_start
= face
->ebdt_start
;
503 decoder
->ebdt_size
= face
->ebdt_size
;
505 decoder
->eblc_base
= face
->sbit_table
;
506 decoder
->eblc_limit
= face
->sbit_table
+ face
->sbit_table_size
;
508 /* now find the strike corresponding to the index */
513 if ( 8 + 48 * strike_index
+ 3 * 4 + 34 + 1 > face
->sbit_table_size
)
515 error
= FT_THROW( Invalid_File_Format
);
519 p
= decoder
->eblc_base
+ 8 + 48 * strike_index
;
521 decoder
->strike_index_array
= FT_NEXT_ULONG( p
);
523 decoder
->strike_index_count
= FT_NEXT_ULONG( p
);
525 decoder
->bit_depth
= *p
;
527 /* decoder->strike_index_array + */
528 /* 8 * decoder->strike_index_count > face->sbit_table_size ? */
529 if ( decoder
->strike_index_array
> face
->sbit_table_size
||
530 decoder
->strike_index_count
>
531 ( face
->sbit_table_size
- decoder
->strike_index_array
) / 8 )
532 error
= FT_THROW( Invalid_File_Format
);
541 tt_sbit_decoder_done( TT_SBitDecoder decoder
)
543 FT_UNUSED( decoder
);
548 tt_sbit_decoder_alloc_bitmap( TT_SBitDecoder decoder
,
549 FT_Bool metrics_only
)
551 FT_Error error
= FT_Err_Ok
;
552 FT_UInt width
, height
;
553 FT_Bitmap
* map
= decoder
->bitmap
;
557 if ( !decoder
->metrics_loaded
)
559 error
= FT_THROW( Invalid_Argument
);
563 width
= decoder
->metrics
->width
;
564 height
= decoder
->metrics
->height
;
569 switch ( decoder
->bit_depth
)
572 map
->pixel_mode
= FT_PIXEL_MODE_MONO
;
573 map
->pitch
= (int)( ( map
->width
+ 7 ) >> 3 );
578 map
->pixel_mode
= FT_PIXEL_MODE_GRAY2
;
579 map
->pitch
= (int)( ( map
->width
+ 3 ) >> 2 );
584 map
->pixel_mode
= FT_PIXEL_MODE_GRAY4
;
585 map
->pitch
= (int)( ( map
->width
+ 1 ) >> 1 );
590 map
->pixel_mode
= FT_PIXEL_MODE_GRAY
;
591 map
->pitch
= (int)( map
->width
);
592 map
->num_grays
= 256;
596 map
->pixel_mode
= FT_PIXEL_MODE_BGRA
;
597 map
->pitch
= (int)( map
->width
* 4 );
598 map
->num_grays
= 256;
602 error
= FT_THROW( Invalid_File_Format
);
606 size
= map
->rows
* (FT_ULong
)map
->pitch
;
608 /* check that there is no empty image */
610 goto Exit
; /* exit successfully! */
613 goto Exit
; /* only metrics are requested */
615 error
= ft_glyphslot_alloc_bitmap( decoder
->face
->root
.glyph
, size
);
619 decoder
->bitmap_allocated
= 1;
627 tt_sbit_decoder_load_metrics( TT_SBitDecoder decoder
,
633 TT_SBit_Metrics metrics
= decoder
->metrics
;
639 metrics
->height
= p
[0];
640 metrics
->width
= p
[1];
641 metrics
->horiBearingX
= (FT_Char
)p
[2];
642 metrics
->horiBearingY
= (FT_Char
)p
[3];
643 metrics
->horiAdvance
= p
[4];
651 metrics
->vertBearingX
= (FT_Char
)p
[0];
652 metrics
->vertBearingY
= (FT_Char
)p
[1];
653 metrics
->vertAdvance
= p
[2];
659 /* avoid uninitialized data in case there is no vertical info -- */
660 metrics
->vertBearingX
= 0;
661 metrics
->vertBearingY
= 0;
662 metrics
->vertAdvance
= 0;
665 decoder
->metrics_loaded
= 1;
670 FT_TRACE1(( "tt_sbit_decoder_load_metrics: broken table\n" ));
671 return FT_THROW( Invalid_Argument
);
675 /* forward declaration */
677 tt_sbit_decoder_load_image( TT_SBitDecoder decoder
,
681 FT_UInt recurse_count
,
682 FT_Bool metrics_only
);
684 typedef FT_Error (*TT_SBitDecoder_LoadFunc
)(
685 TT_SBitDecoder decoder
,
690 FT_UInt recurse_count
);
694 tt_sbit_decoder_load_byte_aligned( TT_SBitDecoder decoder
,
699 FT_UInt recurse_count
)
701 FT_Error error
= FT_Err_Ok
;
703 FT_Int pitch
, width
, height
, line_bits
, h
;
704 FT_UInt bit_height
, bit_width
;
707 FT_UNUSED( recurse_count
);
710 /* check that we can write the glyph into the bitmap */
711 bitmap
= decoder
->bitmap
;
712 bit_width
= bitmap
->width
;
713 bit_height
= bitmap
->rows
;
714 pitch
= bitmap
->pitch
;
715 line
= bitmap
->buffer
;
717 width
= decoder
->metrics
->width
;
718 height
= decoder
->metrics
->height
;
720 line_bits
= width
* decoder
->bit_depth
;
722 if ( x_pos
< 0 || (FT_UInt
)( x_pos
+ width
) > bit_width
||
723 y_pos
< 0 || (FT_UInt
)( y_pos
+ height
) > bit_height
)
725 FT_TRACE1(( "tt_sbit_decoder_load_byte_aligned:"
726 " invalid bitmap dimensions\n" ));
727 error
= FT_THROW( Invalid_File_Format
);
731 if ( p
+ ( ( line_bits
+ 7 ) >> 3 ) * height
> limit
)
733 FT_TRACE1(( "tt_sbit_decoder_load_byte_aligned: broken bitmap\n" ));
734 error
= FT_THROW( Invalid_File_Format
);
738 /* now do the blit */
739 line
+= y_pos
* pitch
+ ( x_pos
>> 3 );
742 if ( x_pos
== 0 ) /* the easy one */
744 for ( h
= height
; h
> 0; h
--, line
+= pitch
)
746 FT_Byte
* pwrite
= line
;
750 for ( w
= line_bits
; w
>= 8; w
-= 8 )
752 pwrite
[0] = (FT_Byte
)( pwrite
[0] | *p
++ );
757 pwrite
[0] = (FT_Byte
)( pwrite
[0] | ( *p
++ & ( 0xFF00U
>> w
) ) );
762 for ( h
= height
; h
> 0; h
--, line
+= pitch
)
764 FT_Byte
* pwrite
= line
;
769 for ( w
= line_bits
; w
>= 8; w
-= 8 )
771 wval
= (FT_UInt
)( wval
| *p
++ );
772 pwrite
[0] = (FT_Byte
)( pwrite
[0] | ( wval
>> x_pos
) );
778 wval
= (FT_UInt
)( wval
| ( *p
++ & ( 0xFF00U
>> w
) ) );
780 /* all bits read and there are `x_pos + w' bits to be written */
782 pwrite
[0] = (FT_Byte
)( pwrite
[0] | ( wval
>> x_pos
) );
788 pwrite
[0] = (FT_Byte
)( pwrite
[0] | ( wval
>> x_pos
) );
795 FT_TRACE3(( "tt_sbit_decoder_load_byte_aligned: loaded\n" ));
801 * Load a bit-aligned bitmap (with pointer `p') into a line-aligned bitmap
802 * (with pointer `pwrite'). In the example below, the width is 3 pixel,
803 * and `x_pos' is 1 pixel.
807 * | 7 6 5 4 3 2 1 0 | 7 6 5 4 3 2 1 0 |...
809 * +-------+ +-------+ +-------+ ...
815 * | 7 6 5 4 3 2 1 0 | .
822 * | 7 6 5 4 3 2 1 0 |
829 * | 7 6 5 4 3 2 1 0 |
836 tt_sbit_decoder_load_bit_aligned( TT_SBitDecoder decoder
,
841 FT_UInt recurse_count
)
843 FT_Error error
= FT_Err_Ok
;
845 FT_Int pitch
, width
, height
, line_bits
, h
, nbits
;
846 FT_UInt bit_height
, bit_width
;
850 FT_UNUSED( recurse_count
);
853 /* check that we can write the glyph into the bitmap */
854 bitmap
= decoder
->bitmap
;
855 bit_width
= bitmap
->width
;
856 bit_height
= bitmap
->rows
;
857 pitch
= bitmap
->pitch
;
858 line
= bitmap
->buffer
;
860 width
= decoder
->metrics
->width
;
861 height
= decoder
->metrics
->height
;
863 line_bits
= width
* decoder
->bit_depth
;
865 if ( x_pos
< 0 || (FT_UInt
)( x_pos
+ width
) > bit_width
||
866 y_pos
< 0 || (FT_UInt
)( y_pos
+ height
) > bit_height
)
868 FT_TRACE1(( "tt_sbit_decoder_load_bit_aligned:"
869 " invalid bitmap dimensions\n" ));
870 error
= FT_THROW( Invalid_File_Format
);
874 if ( p
+ ( ( line_bits
* height
+ 7 ) >> 3 ) > limit
)
876 FT_TRACE1(( "tt_sbit_decoder_load_bit_aligned: broken bitmap\n" ));
877 error
= FT_THROW( Invalid_File_Format
);
881 if ( !line_bits
|| !height
)
887 /* now do the blit */
889 /* adjust `line' to point to the first byte of the bitmap */
890 line
+= y_pos
* pitch
+ ( x_pos
>> 3 );
893 /* the higher byte of `rval' is used as a buffer */
897 for ( h
= height
; h
> 0; h
--, line
+= pitch
)
899 FT_Byte
* pwrite
= line
;
900 FT_Int w
= line_bits
;
903 /* handle initial byte (in target bitmap) specially if necessary */
906 w
= ( line_bits
< 8 - x_pos
) ? line_bits
: 8 - x_pos
;
913 else if ( nbits
< w
)
925 *pwrite
++ |= ( ( rval
>> nbits
) & 0xFF ) &
926 ( ~( 0xFFU
<< w
) << ( 8 - w
- x_pos
) );
932 /* handle medial bytes */
933 for ( ; w
>= 8; w
-= 8 )
936 *pwrite
++ |= ( rval
>> nbits
) & 0xFF;
941 /* handle final byte if necessary */
948 *pwrite
|= ( ( rval
>> nbits
) & 0xFF ) & ( 0xFF00U
>> w
);
955 *pwrite
|= ( ( rval
>> nbits
) & 0xFF ) & ( 0xFF00U
>> w
);
963 FT_TRACE3(( "tt_sbit_decoder_load_bit_aligned: loaded\n" ));
969 tt_sbit_decoder_load_compound( TT_SBitDecoder decoder
,
974 FT_UInt recurse_count
)
976 FT_Error error
= FT_Err_Ok
;
977 FT_UInt num_components
, nn
;
979 FT_Char horiBearingX
= (FT_Char
)decoder
->metrics
->horiBearingX
;
980 FT_Char horiBearingY
= (FT_Char
)decoder
->metrics
->horiBearingY
;
981 FT_Byte horiAdvance
= (FT_Byte
)decoder
->metrics
->horiAdvance
;
982 FT_Char vertBearingX
= (FT_Char
)decoder
->metrics
->vertBearingX
;
983 FT_Char vertBearingY
= (FT_Char
)decoder
->metrics
->vertBearingY
;
984 FT_Byte vertAdvance
= (FT_Byte
)decoder
->metrics
->vertAdvance
;
990 num_components
= FT_NEXT_USHORT( p
);
991 if ( p
+ 4 * num_components
> limit
)
993 FT_TRACE1(( "tt_sbit_decoder_load_compound: broken table\n" ));
997 FT_TRACE3(( "tt_sbit_decoder_load_compound: loading %d components\n",
1000 for ( nn
= 0; nn
< num_components
; nn
++ )
1002 FT_UInt gindex
= FT_NEXT_USHORT( p
);
1003 FT_Byte dx
= FT_NEXT_BYTE( p
);
1004 FT_Byte dy
= FT_NEXT_BYTE( p
);
1007 /* NB: a recursive call */
1008 error
= tt_sbit_decoder_load_image( decoder
,
1013 /* request full bitmap image */
1019 FT_TRACE3(( "tt_sbit_decoder_load_compound: done\n" ));
1021 decoder
->metrics
->horiBearingX
= horiBearingX
;
1022 decoder
->metrics
->horiBearingY
= horiBearingY
;
1023 decoder
->metrics
->horiAdvance
= horiAdvance
;
1024 decoder
->metrics
->vertBearingX
= vertBearingX
;
1025 decoder
->metrics
->vertBearingY
= vertBearingY
;
1026 decoder
->metrics
->vertAdvance
= vertAdvance
;
1027 decoder
->metrics
->width
= (FT_Byte
)decoder
->bitmap
->width
;
1028 decoder
->metrics
->height
= (FT_Byte
)decoder
->bitmap
->rows
;
1034 error
= FT_THROW( Invalid_File_Format
);
1039 #ifdef FT_CONFIG_OPTION_USE_PNG
1042 tt_sbit_decoder_load_png( TT_SBitDecoder decoder
,
1047 FT_UInt recurse_count
)
1049 FT_Error error
= FT_Err_Ok
;
1052 FT_UNUSED( recurse_count
);
1055 if ( limit
- p
< 4 )
1057 FT_TRACE1(( "tt_sbit_decoder_load_png: broken bitmap\n" ));
1058 error
= FT_THROW( Invalid_File_Format
);
1062 png_len
= FT_NEXT_ULONG( p
);
1063 if ( (FT_ULong
)( limit
- p
) < png_len
)
1065 FT_TRACE1(( "tt_sbit_decoder_load_png: broken bitmap\n" ));
1066 error
= FT_THROW( Invalid_File_Format
);
1070 error
= Load_SBit_Png( decoder
->face
->root
.glyph
,
1075 decoder
->stream
->memory
,
1083 FT_TRACE3(( "tt_sbit_decoder_load_png: loaded\n" ));
1087 #endif /* FT_CONFIG_OPTION_USE_PNG */
1091 tt_sbit_decoder_load_bitmap( TT_SBitDecoder decoder
,
1092 FT_UInt glyph_format
,
1093 FT_ULong glyph_start
,
1094 FT_ULong glyph_size
,
1097 FT_UInt recurse_count
,
1098 FT_Bool metrics_only
)
1101 FT_Stream stream
= decoder
->stream
;
1107 /* seek into the EBDT table now */
1109 glyph_start
+ glyph_size
> decoder
->ebdt_size
)
1111 error
= FT_THROW( Invalid_Argument
);
1115 if ( FT_STREAM_SEEK( decoder
->ebdt_start
+ glyph_start
) ||
1116 FT_FRAME_EXTRACT( glyph_size
, data
) )
1120 p_limit
= p
+ glyph_size
;
1122 /* read the data, depending on the glyph format */
1123 switch ( glyph_format
)
1129 error
= tt_sbit_decoder_load_metrics( decoder
, &p
, p_limit
, 0 );
1136 error
= tt_sbit_decoder_load_metrics( decoder
, &p
, p_limit
, 1 );
1147 TT_SBitDecoder_LoadFunc loader
;
1150 switch ( glyph_format
)
1154 loader
= tt_sbit_decoder_load_byte_aligned
;
1160 /* Don't trust `glyph_format'. For example, Apple's main Korean */
1161 /* system font, `AppleMyungJo.ttf' (version 7.0d2e6), uses glyph */
1162 /* format 7, but the data is format 6. We check whether we have */
1163 /* an excessive number of bytes in the image: If it is equal to */
1164 /* the value for a byte-aligned glyph, use the other loading */
1167 /* Note that for some (width,height) combinations, where the */
1168 /* width is not a multiple of 8, the sizes for bit- and */
1169 /* byte-aligned data are equal, for example (7,7) or (15,6). We */
1170 /* then prefer what `glyph_format' specifies. */
1172 FT_UInt width
= decoder
->metrics
->width
;
1173 FT_UInt height
= decoder
->metrics
->height
;
1175 FT_UInt bit_size
= ( width
* height
+ 7 ) >> 3;
1176 FT_UInt byte_size
= height
* ( ( width
+ 7 ) >> 3 );
1179 if ( bit_size
< byte_size
&&
1180 byte_size
== (FT_UInt
)( p_limit
- p
) )
1181 loader
= tt_sbit_decoder_load_byte_aligned
;
1183 loader
= tt_sbit_decoder_load_bit_aligned
;
1188 loader
= tt_sbit_decoder_load_bit_aligned
;
1192 if ( p
+ 1 > p_limit
)
1195 p
+= 1; /* skip padding */
1199 loader
= tt_sbit_decoder_load_compound
;
1202 case 17: /* small metrics, PNG image data */
1203 case 18: /* big metrics, PNG image data */
1204 case 19: /* metrics in EBLC, PNG image data */
1205 #ifdef FT_CONFIG_OPTION_USE_PNG
1206 loader
= tt_sbit_decoder_load_png
;
1209 error
= FT_THROW( Unimplemented_Feature
);
1211 #endif /* FT_CONFIG_OPTION_USE_PNG */
1214 error
= FT_THROW( Invalid_Table
);
1218 if ( !decoder
->bitmap_allocated
)
1220 error
= tt_sbit_decoder_alloc_bitmap( decoder
, metrics_only
);
1227 goto Fail
; /* this is not an error */
1229 error
= loader( decoder
, p
, p_limit
, x_pos
, y_pos
, recurse_count
);
1233 FT_FRAME_RELEASE( data
);
1241 tt_sbit_decoder_load_image( TT_SBitDecoder decoder
,
1242 FT_UInt glyph_index
,
1245 FT_UInt recurse_count
,
1246 FT_Bool metrics_only
)
1248 FT_Byte
* p
= decoder
->eblc_base
+ decoder
->strike_index_array
;
1249 FT_Byte
* p_limit
= decoder
->eblc_limit
;
1250 FT_ULong num_ranges
= decoder
->strike_index_count
;
1251 FT_UInt start
, end
, index_format
, image_format
;
1252 FT_ULong image_start
= 0, image_end
= 0, image_offset
;
1255 /* arbitrary recursion limit */
1256 if ( recurse_count
> 100 )
1258 FT_TRACE4(( "tt_sbit_decoder_load_image:"
1259 " recursion depth exceeded\n" ));
1264 /* First, we find the correct strike range that applies to this */
1266 for ( ; num_ranges
> 0; num_ranges
-- )
1268 start
= FT_NEXT_USHORT( p
);
1269 end
= FT_NEXT_USHORT( p
);
1271 if ( glyph_index
>= start
&& glyph_index
<= end
)
1274 p
+= 4; /* ignore index offset */
1279 image_offset
= FT_NEXT_ULONG( p
);
1281 /* overflow check */
1282 p
= decoder
->eblc_base
+ decoder
->strike_index_array
;
1283 if ( image_offset
> (FT_ULong
)( p_limit
- p
) )
1287 if ( p
+ 8 > p_limit
)
1290 /* now find the glyph's location and extend within the ebdt table */
1291 index_format
= FT_NEXT_USHORT( p
);
1292 image_format
= FT_NEXT_USHORT( p
);
1293 image_offset
= FT_NEXT_ULONG ( p
);
1295 switch ( index_format
)
1297 case 1: /* 4-byte offsets relative to `image_offset' */
1298 p
+= 4 * ( glyph_index
- start
);
1299 if ( p
+ 8 > p_limit
)
1302 image_start
= FT_NEXT_ULONG( p
);
1303 image_end
= FT_NEXT_ULONG( p
);
1305 if ( image_start
== image_end
) /* missing glyph */
1309 case 2: /* big metrics, constant image size */
1311 FT_ULong image_size
;
1314 if ( p
+ 12 > p_limit
)
1317 image_size
= FT_NEXT_ULONG( p
);
1319 if ( tt_sbit_decoder_load_metrics( decoder
, &p
, p_limit
, 1 ) )
1322 image_start
= image_size
* ( glyph_index
- start
);
1323 image_end
= image_start
+ image_size
;
1327 case 3: /* 2-byte offsets relative to 'image_offset' */
1328 p
+= 2 * ( glyph_index
- start
);
1329 if ( p
+ 4 > p_limit
)
1332 image_start
= FT_NEXT_USHORT( p
);
1333 image_end
= FT_NEXT_USHORT( p
);
1335 if ( image_start
== image_end
) /* missing glyph */
1339 case 4: /* sparse glyph array with (glyph,offset) pairs */
1341 FT_ULong mm
, num_glyphs
;
1344 if ( p
+ 4 > p_limit
)
1347 num_glyphs
= FT_NEXT_ULONG( p
);
1349 /* overflow check for p + ( num_glyphs + 1 ) * 4 */
1350 if ( p
+ 4 > p_limit
||
1351 num_glyphs
> (FT_ULong
)( ( ( p_limit
- p
) >> 2 ) - 1 ) )
1354 for ( mm
= 0; mm
< num_glyphs
; mm
++ )
1356 FT_UInt gindex
= FT_NEXT_USHORT( p
);
1359 if ( gindex
== glyph_index
)
1361 image_start
= FT_NEXT_USHORT( p
);
1363 image_end
= FT_PEEK_USHORT( p
);
1369 if ( mm
>= num_glyphs
)
1374 case 5: /* constant metrics with sparse glyph codes */
1377 FT_ULong image_size
, mm
, num_glyphs
;
1380 if ( p
+ 16 > p_limit
)
1383 image_size
= FT_NEXT_ULONG( p
);
1385 if ( tt_sbit_decoder_load_metrics( decoder
, &p
, p_limit
, 1 ) )
1388 num_glyphs
= FT_NEXT_ULONG( p
);
1390 /* overflow check for p + 2 * num_glyphs */
1391 if ( num_glyphs
> (FT_ULong
)( ( p_limit
- p
) >> 1 ) )
1394 for ( mm
= 0; mm
< num_glyphs
; mm
++ )
1396 FT_UInt gindex
= FT_NEXT_USHORT( p
);
1399 if ( gindex
== glyph_index
)
1403 if ( mm
>= num_glyphs
)
1406 image_start
= image_size
* mm
;
1407 image_end
= image_start
+ image_size
;
1415 if ( image_start
> image_end
)
1418 image_end
-= image_start
;
1419 image_start
= image_offset
+ image_start
;
1421 FT_TRACE3(( "tt_sbit_decoder_load_image:"
1422 " found sbit (format %d) for glyph index %d\n",
1423 image_format
, glyph_index
));
1425 return tt_sbit_decoder_load_bitmap( decoder
,
1435 return FT_THROW( Invalid_Table
);
1438 FT_TRACE4(( "tt_sbit_decoder_load_image:"
1439 " no sbit found for glyph index %d\n", glyph_index
));
1441 return FT_THROW( Invalid_Argument
);
1446 tt_face_load_sbix_image( TT_Face face
,
1447 FT_ULong strike_index
,
1448 FT_UInt glyph_index
,
1451 TT_SBit_MetricsRec
*metrics
,
1452 FT_Bool metrics_only
)
1454 FT_UInt strike_offset
, glyph_start
, glyph_end
;
1455 FT_Int originOffsetX
, originOffsetY
;
1457 FT_Int recurse_depth
= 0;
1465 strike_index
= face
->sbit_strike_map
[strike_index
];
1468 metrics
->height
= 0;
1470 p
= face
->sbit_table
+ 8 + 4 * strike_index
;
1471 strike_offset
= FT_NEXT_ULONG( p
);
1474 if ( glyph_index
> (FT_UInt
)face
->root
.num_glyphs
)
1475 return FT_THROW( Invalid_Argument
);
1477 if ( strike_offset
>= face
->ebdt_size
||
1478 face
->ebdt_size
- strike_offset
< 4 + glyph_index
* 4 + 8 )
1479 return FT_THROW( Invalid_File_Format
);
1481 if ( FT_STREAM_SEEK( face
->ebdt_start
+
1483 glyph_index
* 4 ) ||
1484 FT_FRAME_ENTER( 8 ) )
1487 glyph_start
= FT_GET_ULONG();
1488 glyph_end
= FT_GET_ULONG();
1492 if ( glyph_start
== glyph_end
)
1493 return FT_THROW( Invalid_Argument
);
1494 if ( glyph_start
> glyph_end
||
1495 glyph_end
- glyph_start
< 8 ||
1496 face
->ebdt_size
- strike_offset
< glyph_end
)
1497 return FT_THROW( Invalid_File_Format
);
1499 if ( FT_STREAM_SEEK( face
->ebdt_start
+ strike_offset
+ glyph_start
) ||
1500 FT_FRAME_ENTER( glyph_end
- glyph_start
) )
1503 originOffsetX
= FT_GET_SHORT();
1504 originOffsetY
= FT_GET_SHORT();
1506 graphicType
= FT_GET_TAG4();
1508 switch ( graphicType
)
1510 case FT_MAKE_TAG( 'd', 'u', 'p', 'e' ):
1511 if ( recurse_depth
< 4 )
1513 glyph_index
= FT_GET_USHORT();
1518 error
= FT_THROW( Invalid_File_Format
);
1521 case FT_MAKE_TAG( 'p', 'n', 'g', ' ' ):
1522 #ifdef FT_CONFIG_OPTION_USE_PNG
1523 error
= Load_SBit_Png( face
->root
.glyph
,
1530 glyph_end
- glyph_start
- 8,
1534 error
= FT_THROW( Unimplemented_Feature
);
1538 case FT_MAKE_TAG( 'j', 'p', 'g', ' ' ):
1539 case FT_MAKE_TAG( 't', 'i', 'f', 'f' ):
1540 case FT_MAKE_TAG( 'r', 'g', 'b', 'l' ): /* used on iOS 7.1 */
1541 error
= FT_THROW( Unknown_File_Format
);
1545 error
= FT_THROW( Unimplemented_Feature
);
1557 tt_face_get_metrics( face
, FALSE
, glyph_index
, &abearing
, &aadvance
);
1559 metrics
->horiBearingX
= (FT_Short
)originOffsetX
;
1560 metrics
->horiBearingY
= (FT_Short
)( -originOffsetY
+ metrics
->height
);
1561 metrics
->horiAdvance
= (FT_UShort
)( aadvance
*
1562 face
->root
.size
->metrics
.x_ppem
/
1563 face
->header
.Units_Per_EM
);
1569 FT_LOCAL( FT_Error
)
1570 tt_face_load_sbit_image( TT_Face face
,
1571 FT_ULong strike_index
,
1572 FT_UInt glyph_index
,
1576 TT_SBit_MetricsRec
*metrics
)
1578 FT_Error error
= FT_Err_Ok
;
1581 switch ( (FT_UInt
)face
->sbit_table_type
)
1583 case TT_SBIT_TABLE_TYPE_EBLC
:
1584 case TT_SBIT_TABLE_TYPE_CBLC
:
1586 TT_SBitDecoderRec decoder
[1];
1589 error
= tt_sbit_decoder_init( decoder
, face
, strike_index
, metrics
);
1592 error
= tt_sbit_decoder_load_image(
1598 ( load_flags
& FT_LOAD_BITMAP_METRICS_ONLY
) != 0 );
1599 tt_sbit_decoder_done( decoder
);
1604 case TT_SBIT_TABLE_TYPE_SBIX
:
1605 error
= tt_face_load_sbix_image(
1612 ( load_flags
& FT_LOAD_BITMAP_METRICS_ONLY
) != 0 );
1616 error
= FT_THROW( Unknown_File_Format
);
1620 /* Flatten color bitmaps if color was not requested. */
1622 !( load_flags
& FT_LOAD_COLOR
) &&
1623 !( load_flags
& FT_LOAD_BITMAP_METRICS_ONLY
) &&
1624 map
->pixel_mode
== FT_PIXEL_MODE_BGRA
)
1627 FT_Library library
= face
->root
.glyph
->library
;
1630 FT_Bitmap_Init( &new_map
);
1632 /* Convert to 8bit grayscale. */
1633 error
= FT_Bitmap_Convert( library
, map
, &new_map
, 1 );
1635 FT_Bitmap_Done( library
, &new_map
);
1638 map
->pixel_mode
= new_map
.pixel_mode
;
1639 map
->pitch
= new_map
.pitch
;
1640 map
->num_grays
= new_map
.num_grays
;
1642 ft_glyphslot_set_bitmap( face
->root
.glyph
, new_map
.buffer
);
1643 face
->root
.glyph
->internal
->flags
|= FT_GLYPH_OWN_BITMAP
;