1 /***************************************************************************/
5 /* TrueType and OpenType embedded bitmap support (body). */
7 /* Copyright 2005-2009, 2013, 2014 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
,
53 face
->sbit_table
= NULL
;
54 face
->sbit_table_size
= 0;
55 face
->sbit_table_type
= TT_SBIT_TABLE_TYPE_NONE
;
56 face
->sbit_num_strikes
= 0;
58 error
= face
->goto_table( face
, TTAG_CBLC
, stream
, &table_size
);
60 face
->sbit_table_type
= TT_SBIT_TABLE_TYPE_CBLC
;
63 error
= face
->goto_table( face
, TTAG_EBLC
, stream
, &table_size
);
65 error
= face
->goto_table( face
, TTAG_bloc
, stream
, &table_size
);
67 face
->sbit_table_type
= TT_SBIT_TABLE_TYPE_EBLC
;
72 error
= face
->goto_table( face
, TTAG_sbix
, stream
, &table_size
);
74 face
->sbit_table_type
= TT_SBIT_TABLE_TYPE_SBIX
;
81 FT_ERROR(( "tt_face_load_sbit_strikes: table too short\n" ));
82 error
= FT_THROW( Invalid_File_Format
);
86 switch ( (FT_UInt
)face
->sbit_table_type
)
88 case TT_SBIT_TABLE_TYPE_EBLC
:
89 case TT_SBIT_TABLE_TYPE_CBLC
:
97 if ( FT_FRAME_EXTRACT( table_size
, face
->sbit_table
) )
100 face
->sbit_table_size
= table_size
;
102 p
= face
->sbit_table
;
104 version
= FT_NEXT_ULONG( p
);
105 num_strikes
= FT_NEXT_ULONG( p
);
107 if ( ( version
& 0xFFFF0000UL
) != 0x00020000UL
)
109 error
= FT_THROW( Unknown_File_Format
);
113 if ( num_strikes
>= 0x10000UL
)
115 error
= FT_THROW( Invalid_File_Format
);
120 * Count the number of strikes available in the table. We are a bit
121 * paranoid there and don't trust the data.
123 count
= (FT_UInt
)num_strikes
;
124 if ( 8 + 48UL * count
> table_size
)
125 count
= (FT_UInt
)( ( table_size
- 8 ) / 48 );
127 face
->sbit_num_strikes
= count
;
131 case TT_SBIT_TABLE_TYPE_SBIX
:
135 FT_ULong num_strikes
;
139 if ( FT_FRAME_ENTER( 8 ) )
142 version
= FT_GET_USHORT();
143 flags
= FT_GET_USHORT();
144 num_strikes
= FT_GET_ULONG();
150 error
= FT_THROW( Unknown_File_Format
);
153 if ( flags
!= 0x0001 || num_strikes
>= 0x10000UL
)
155 error
= FT_THROW( Invalid_File_Format
);
160 * Count the number of strikes available in the table. We are a bit
161 * paranoid there and don't trust the data.
163 count
= (FT_UInt
)num_strikes
;
164 if ( 8 + 4UL * count
> table_size
)
165 count
= (FT_UInt
)( ( table_size
- 8 ) / 4 );
167 if ( FT_STREAM_SEEK( FT_STREAM_POS() - 8 ) )
170 face
->sbit_table_size
= 8 + count
* 4;
171 if ( FT_FRAME_EXTRACT( face
->sbit_table_size
, face
->sbit_table
) )
174 face
->sbit_num_strikes
= count
;
179 error
= FT_THROW( Unknown_File_Format
);
184 FT_TRACE3(( "sbit_num_strikes: %u\n", face
->sbit_num_strikes
));
191 if ( face
->sbit_table
)
192 FT_FRAME_RELEASE( face
->sbit_table
);
193 face
->sbit_table_size
= 0;
194 face
->sbit_table_type
= TT_SBIT_TABLE_TYPE_NONE
;
202 tt_face_free_sbit( TT_Face face
)
204 FT_Stream stream
= face
->root
.stream
;
207 FT_FRAME_RELEASE( face
->sbit_table
);
208 face
->sbit_table_size
= 0;
209 face
->sbit_table_type
= TT_SBIT_TABLE_TYPE_NONE
;
210 face
->sbit_num_strikes
= 0;
214 FT_LOCAL_DEF( FT_Error
)
215 tt_face_set_sbit_strike( TT_Face face
,
217 FT_ULong
* astrike_index
)
219 return FT_Match_Size( (FT_Face
)face
, req
, 0, astrike_index
);
223 FT_LOCAL_DEF( FT_Error
)
224 tt_face_load_strike_metrics( TT_Face face
,
225 FT_ULong strike_index
,
226 FT_Size_Metrics
* metrics
)
228 if ( strike_index
>= (FT_ULong
)face
->sbit_num_strikes
)
229 return FT_THROW( Invalid_Argument
);
231 switch ( (FT_UInt
)face
->sbit_table_type
)
233 case TT_SBIT_TABLE_TYPE_EBLC
:
234 case TT_SBIT_TABLE_TYPE_CBLC
:
239 strike
= face
->sbit_table
+ 8 + strike_index
* 48;
241 metrics
->x_ppem
= (FT_UShort
)strike
[44];
242 metrics
->y_ppem
= (FT_UShort
)strike
[45];
244 metrics
->ascender
= (FT_Char
)strike
[16] << 6; /* hori.ascender */
245 metrics
->descender
= (FT_Char
)strike
[17] << 6; /* hori.descender */
246 metrics
->height
= metrics
->ascender
- metrics
->descender
;
248 /* Is this correct? */
249 metrics
->max_advance
= ( (FT_Char
)strike
[22] + /* min_origin_SB */
250 strike
[18] + /* max_width */
251 (FT_Char
)strike
[23] /* min_advance_SB */
256 case TT_SBIT_TABLE_TYPE_SBIX
:
258 FT_Stream stream
= face
->root
.stream
;
259 FT_UInt offset
, ppem
, resolution
, upem
;
267 p
= face
->sbit_table
+ 8 + 4 * strike_index
;
268 offset
= FT_NEXT_ULONG( p
);
270 error
= face
->goto_table( face
, TTAG_sbix
, stream
, &table_size
);
274 if ( offset
+ 4 > table_size
)
275 return FT_THROW( Invalid_File_Format
);
277 if ( FT_STREAM_SEEK( FT_STREAM_POS() + offset
) ||
278 FT_FRAME_ENTER( 4 ) )
281 ppem
= FT_GET_USHORT();
282 resolution
= FT_GET_USHORT();
284 FT_UNUSED( resolution
); /* What to do with this? */
288 upem
= face
->header
.Units_Per_EM
;
289 hori
= &face
->horizontal
;
291 metrics
->x_ppem
= ppem
;
292 metrics
->y_ppem
= ppem
;
294 metrics
->ascender
= ppem
* hori
->Ascender
* 64 / upem
;
295 metrics
->descender
= ppem
* hori
->Descender
* 64 / upem
;
296 metrics
->height
= ppem
* ( hori
->Ascender
-
298 hori
->Line_Gap
) * 64 / upem
;
299 metrics
->max_advance
= ppem
* hori
->advance_Width_Max
* 64 / upem
;
305 return FT_THROW( Unknown_File_Format
);
310 typedef struct TT_SBitDecoderRec_
315 TT_SBit_Metrics metrics
;
316 FT_Bool metrics_loaded
;
317 FT_Bool bitmap_allocated
;
323 FT_ULong strike_index_array
;
324 FT_ULong strike_index_count
;
328 } TT_SBitDecoderRec
, *TT_SBitDecoder
;
332 tt_sbit_decoder_init( TT_SBitDecoder decoder
,
334 FT_ULong strike_index
,
335 TT_SBit_MetricsRec
* metrics
)
338 FT_Stream stream
= face
->root
.stream
;
342 error
= face
->goto_table( face
, TTAG_CBDT
, stream
, &ebdt_size
);
344 error
= face
->goto_table( face
, TTAG_EBDT
, stream
, &ebdt_size
);
346 error
= face
->goto_table( face
, TTAG_bdat
, stream
, &ebdt_size
);
350 decoder
->face
= face
;
351 decoder
->stream
= stream
;
352 decoder
->bitmap
= &face
->root
.glyph
->bitmap
;
353 decoder
->metrics
= metrics
;
355 decoder
->metrics_loaded
= 0;
356 decoder
->bitmap_allocated
= 0;
358 decoder
->ebdt_start
= FT_STREAM_POS();
359 decoder
->ebdt_size
= ebdt_size
;
361 decoder
->eblc_base
= face
->sbit_table
;
362 decoder
->eblc_limit
= face
->sbit_table
+ face
->sbit_table_size
;
364 /* now find the strike corresponding to the index */
369 if ( 8 + 48 * strike_index
+ 3 * 4 + 34 + 1 > face
->sbit_table_size
)
371 error
= FT_THROW( Invalid_File_Format
);
375 p
= decoder
->eblc_base
+ 8 + 48 * strike_index
;
377 decoder
->strike_index_array
= FT_NEXT_ULONG( p
);
379 decoder
->strike_index_count
= FT_NEXT_ULONG( p
);
381 decoder
->bit_depth
= *p
;
383 if ( decoder
->strike_index_array
> face
->sbit_table_size
||
384 decoder
->strike_index_array
+ 8 * decoder
->strike_index_count
>
385 face
->sbit_table_size
)
386 error
= FT_THROW( Invalid_File_Format
);
395 tt_sbit_decoder_done( TT_SBitDecoder decoder
)
397 FT_UNUSED( decoder
);
402 tt_sbit_decoder_alloc_bitmap( TT_SBitDecoder decoder
)
404 FT_Error error
= FT_Err_Ok
;
405 FT_UInt width
, height
;
406 FT_Bitmap
* map
= decoder
->bitmap
;
410 if ( !decoder
->metrics_loaded
)
412 error
= FT_THROW( Invalid_Argument
);
416 width
= decoder
->metrics
->width
;
417 height
= decoder
->metrics
->height
;
419 map
->width
= (int)width
;
420 map
->rows
= (int)height
;
422 switch ( decoder
->bit_depth
)
425 map
->pixel_mode
= FT_PIXEL_MODE_MONO
;
426 map
->pitch
= ( map
->width
+ 7 ) >> 3;
431 map
->pixel_mode
= FT_PIXEL_MODE_GRAY2
;
432 map
->pitch
= ( map
->width
+ 3 ) >> 2;
437 map
->pixel_mode
= FT_PIXEL_MODE_GRAY4
;
438 map
->pitch
= ( map
->width
+ 1 ) >> 1;
443 map
->pixel_mode
= FT_PIXEL_MODE_GRAY
;
444 map
->pitch
= map
->width
;
445 map
->num_grays
= 256;
449 map
->pixel_mode
= FT_PIXEL_MODE_BGRA
;
450 map
->pitch
= map
->width
* 4;
451 map
->num_grays
= 256;
455 error
= FT_THROW( Invalid_File_Format
);
459 size
= map
->rows
* map
->pitch
;
461 /* check that there is no empty image */
463 goto Exit
; /* exit successfully! */
465 error
= ft_glyphslot_alloc_bitmap( decoder
->face
->root
.glyph
, size
);
469 decoder
->bitmap_allocated
= 1;
477 tt_sbit_decoder_load_metrics( TT_SBitDecoder decoder
,
483 TT_SBit_Metrics metrics
= decoder
->metrics
;
489 metrics
->height
= p
[0];
490 metrics
->width
= p
[1];
491 metrics
->horiBearingX
= (FT_Char
)p
[2];
492 metrics
->horiBearingY
= (FT_Char
)p
[3];
493 metrics
->horiAdvance
= p
[4];
501 metrics
->vertBearingX
= (FT_Char
)p
[0];
502 metrics
->vertBearingY
= (FT_Char
)p
[1];
503 metrics
->vertAdvance
= p
[2];
508 decoder
->metrics_loaded
= 1;
513 FT_TRACE1(( "tt_sbit_decoder_load_metrics: broken table" ));
514 return FT_THROW( Invalid_Argument
);
518 /* forward declaration */
520 tt_sbit_decoder_load_image( TT_SBitDecoder decoder
,
525 typedef FT_Error (*TT_SBitDecoder_LoadFunc
)( TT_SBitDecoder decoder
,
533 tt_sbit_decoder_load_byte_aligned( TT_SBitDecoder decoder
,
539 FT_Error error
= FT_Err_Ok
;
541 FT_Int bit_height
, bit_width
, pitch
, width
, height
, line_bits
, h
;
545 /* check that we can write the glyph into the bitmap */
546 bitmap
= decoder
->bitmap
;
547 bit_width
= bitmap
->width
;
548 bit_height
= bitmap
->rows
;
549 pitch
= bitmap
->pitch
;
550 line
= bitmap
->buffer
;
552 width
= decoder
->metrics
->width
;
553 height
= decoder
->metrics
->height
;
555 line_bits
= width
* decoder
->bit_depth
;
557 if ( x_pos
< 0 || x_pos
+ width
> bit_width
||
558 y_pos
< 0 || y_pos
+ height
> bit_height
)
560 FT_TRACE1(( "tt_sbit_decoder_load_byte_aligned:"
561 " invalid bitmap dimensions\n" ));
562 error
= FT_THROW( Invalid_File_Format
);
566 if ( p
+ ( ( line_bits
+ 7 ) >> 3 ) * height
> limit
)
568 FT_TRACE1(( "tt_sbit_decoder_load_byte_aligned: broken bitmap\n" ));
569 error
= FT_THROW( Invalid_File_Format
);
573 /* now do the blit */
574 line
+= y_pos
* pitch
+ ( x_pos
>> 3 );
577 if ( x_pos
== 0 ) /* the easy one */
579 for ( h
= height
; h
> 0; h
--, line
+= pitch
)
581 FT_Byte
* pwrite
= line
;
585 for ( w
= line_bits
; w
>= 8; w
-= 8 )
587 pwrite
[0] = (FT_Byte
)( pwrite
[0] | *p
++ );
592 pwrite
[0] = (FT_Byte
)( pwrite
[0] | ( *p
++ & ( 0xFF00U
>> w
) ) );
597 for ( h
= height
; h
> 0; h
--, line
+= pitch
)
599 FT_Byte
* pwrite
= line
;
604 for ( w
= line_bits
; w
>= 8; w
-= 8 )
606 wval
= (FT_UInt
)( wval
| *p
++ );
607 pwrite
[0] = (FT_Byte
)( pwrite
[0] | ( wval
>> x_pos
) );
613 wval
= (FT_UInt
)( wval
| ( *p
++ & ( 0xFF00U
>> w
) ) );
615 /* all bits read and there are `x_pos + w' bits to be written */
617 pwrite
[0] = (FT_Byte
)( pwrite
[0] | ( wval
>> x_pos
) );
623 pwrite
[0] = (FT_Byte
)( pwrite
[0] | ( wval
>> x_pos
) );
630 FT_TRACE3(( "tt_sbit_decoder_load_byte_aligned: loaded\n" ));
636 * Load a bit-aligned bitmap (with pointer `p') into a line-aligned bitmap
637 * (with pointer `pwrite'). In the example below, the width is 3 pixel,
638 * and `x_pos' is 1 pixel.
642 * | 7 6 5 4 3 2 1 0 | 7 6 5 4 3 2 1 0 |...
644 * +-------+ +-------+ +-------+ ...
650 * | 7 6 5 4 3 2 1 0 | .
657 * | 7 6 5 4 3 2 1 0 |
664 * | 7 6 5 4 3 2 1 0 |
671 tt_sbit_decoder_load_bit_aligned( TT_SBitDecoder decoder
,
677 FT_Error error
= FT_Err_Ok
;
679 FT_Int bit_height
, bit_width
, pitch
, width
, height
, line_bits
, h
, nbits
;
684 /* check that we can write the glyph into the bitmap */
685 bitmap
= decoder
->bitmap
;
686 bit_width
= bitmap
->width
;
687 bit_height
= bitmap
->rows
;
688 pitch
= bitmap
->pitch
;
689 line
= bitmap
->buffer
;
691 width
= decoder
->metrics
->width
;
692 height
= decoder
->metrics
->height
;
694 line_bits
= width
* decoder
->bit_depth
;
696 if ( x_pos
< 0 || x_pos
+ width
> bit_width
||
697 y_pos
< 0 || y_pos
+ height
> bit_height
)
699 FT_TRACE1(( "tt_sbit_decoder_load_bit_aligned:"
700 " invalid bitmap dimensions\n" ));
701 error
= FT_THROW( Invalid_File_Format
);
705 if ( p
+ ( ( line_bits
* height
+ 7 ) >> 3 ) > limit
)
707 FT_TRACE1(( "tt_sbit_decoder_load_bit_aligned: broken bitmap\n" ));
708 error
= FT_THROW( Invalid_File_Format
);
712 /* now do the blit */
714 /* adjust `line' to point to the first byte of the bitmap */
715 line
+= y_pos
* pitch
+ ( x_pos
>> 3 );
718 /* the higher byte of `rval' is used as a buffer */
722 for ( h
= height
; h
> 0; h
--, line
+= pitch
)
724 FT_Byte
* pwrite
= line
;
725 FT_Int w
= line_bits
;
728 /* handle initial byte (in target bitmap) specially if necessary */
731 w
= ( line_bits
< 8 - x_pos
) ? line_bits
: 8 - x_pos
;
738 else if ( nbits
< w
)
750 *pwrite
++ |= ( ( rval
>> nbits
) & 0xFF ) &
751 ( ~( 0xFF << w
) << ( 8 - w
- x_pos
) );
757 /* handle medial bytes */
758 for ( ; w
>= 8; w
-= 8 )
761 *pwrite
++ |= ( rval
>> nbits
) & 0xFF;
766 /* handle final byte if necessary */
773 *pwrite
|= ( ( rval
>> nbits
) & 0xFF ) & ( 0xFF00U
>> w
);
780 *pwrite
|= ( ( rval
>> nbits
) & 0xFF ) & ( 0xFF00U
>> w
);
788 FT_TRACE3(( "tt_sbit_decoder_load_bit_aligned: loaded\n" ));
794 tt_sbit_decoder_load_compound( TT_SBitDecoder decoder
,
800 FT_Error error
= FT_Err_Ok
;
801 FT_UInt num_components
, nn
;
803 FT_Char horiBearingX
= decoder
->metrics
->horiBearingX
;
804 FT_Char horiBearingY
= decoder
->metrics
->horiBearingY
;
805 FT_Byte horiAdvance
= decoder
->metrics
->horiAdvance
;
806 FT_Char vertBearingX
= decoder
->metrics
->vertBearingX
;
807 FT_Char vertBearingY
= decoder
->metrics
->vertBearingY
;
808 FT_Byte vertAdvance
= decoder
->metrics
->vertAdvance
;
814 num_components
= FT_NEXT_USHORT( p
);
815 if ( p
+ 4 * num_components
> limit
)
817 FT_TRACE1(( "tt_sbit_decoder_load_compound: broken table\n" ));
821 FT_TRACE3(( "tt_sbit_decoder_load_compound: loading %d components\n",
824 for ( nn
= 0; nn
< num_components
; nn
++ )
826 FT_UInt gindex
= FT_NEXT_USHORT( p
);
827 FT_Byte dx
= FT_NEXT_BYTE( p
);
828 FT_Byte dy
= FT_NEXT_BYTE( p
);
831 /* NB: a recursive call */
832 error
= tt_sbit_decoder_load_image( decoder
, gindex
,
833 x_pos
+ dx
, y_pos
+ dy
);
838 FT_TRACE3(( "tt_sbit_decoder_load_compound: done\n" ));
840 decoder
->metrics
->horiBearingX
= horiBearingX
;
841 decoder
->metrics
->horiBearingY
= horiBearingY
;
842 decoder
->metrics
->horiAdvance
= horiAdvance
;
843 decoder
->metrics
->vertBearingX
= vertBearingX
;
844 decoder
->metrics
->vertBearingY
= vertBearingY
;
845 decoder
->metrics
->vertAdvance
= vertAdvance
;
846 decoder
->metrics
->width
= (FT_Byte
)decoder
->bitmap
->width
;
847 decoder
->metrics
->height
= (FT_Byte
)decoder
->bitmap
->rows
;
853 error
= FT_THROW( Invalid_File_Format
);
858 #ifdef FT_CONFIG_OPTION_USE_PNG
861 tt_sbit_decoder_load_png( TT_SBitDecoder decoder
,
867 FT_Error error
= FT_Err_Ok
;
873 FT_TRACE1(( "tt_sbit_decoder_load_png: broken bitmap\n" ));
874 error
= FT_THROW( Invalid_File_Format
);
878 png_len
= FT_NEXT_ULONG( p
);
879 if ( (FT_ULong
)( limit
- p
) < png_len
)
881 FT_TRACE1(( "tt_sbit_decoder_load_png: broken bitmap\n" ));
882 error
= FT_THROW( Invalid_File_Format
);
886 error
= Load_SBit_Png( decoder
->face
->root
.glyph
,
891 decoder
->stream
->memory
,
898 FT_TRACE3(( "tt_sbit_decoder_load_png: loaded\n" ));
902 #endif /* FT_CONFIG_OPTION_USE_PNG */
906 tt_sbit_decoder_load_bitmap( TT_SBitDecoder decoder
,
907 FT_UInt glyph_format
,
908 FT_ULong glyph_start
,
914 FT_Stream stream
= decoder
->stream
;
920 /* seek into the EBDT table now */
921 if ( glyph_start
+ glyph_size
> decoder
->ebdt_size
)
923 error
= FT_THROW( Invalid_Argument
);
927 if ( FT_STREAM_SEEK( decoder
->ebdt_start
+ glyph_start
) ||
928 FT_FRAME_EXTRACT( glyph_size
, data
) )
932 p_limit
= p
+ glyph_size
;
934 /* read the data, depending on the glyph format */
935 switch ( glyph_format
)
941 error
= tt_sbit_decoder_load_metrics( decoder
, &p
, p_limit
, 0 );
948 error
= tt_sbit_decoder_load_metrics( decoder
, &p
, p_limit
, 1 );
959 TT_SBitDecoder_LoadFunc loader
;
962 switch ( glyph_format
)
966 loader
= tt_sbit_decoder_load_byte_aligned
;
972 /* Don't trust `glyph_format'. For example, Apple's main Korean */
973 /* system font, `AppleMyungJo.ttf' (version 7.0d2e6), uses glyph */
974 /* format 7, but the data is format 6. We check whether we have */
975 /* an excessive number of bytes in the image: If it is equal to */
976 /* the value for a byte-aligned glyph, use the other loading */
979 /* Note that for some (width,height) combinations, where the */
980 /* width is not a multiple of 8, the sizes for bit- and */
981 /* byte-aligned data are equal, for example (7,7) or (15,6). We */
982 /* then prefer what `glyph_format' specifies. */
984 FT_UInt width
= decoder
->metrics
->width
;
985 FT_UInt height
= decoder
->metrics
->height
;
987 FT_UInt bit_size
= ( width
* height
+ 7 ) >> 3;
988 FT_UInt byte_size
= height
* ( ( width
+ 7 ) >> 3 );
991 if ( bit_size
< byte_size
&&
992 byte_size
== (FT_UInt
)( p_limit
- p
) )
993 loader
= tt_sbit_decoder_load_byte_aligned
;
995 loader
= tt_sbit_decoder_load_bit_aligned
;
1000 loader
= tt_sbit_decoder_load_bit_aligned
;
1004 if ( p
+ 1 > p_limit
)
1007 p
+= 1; /* skip padding */
1011 loader
= tt_sbit_decoder_load_compound
;
1014 case 17: /* small metrics, PNG image data */
1015 case 18: /* big metrics, PNG image data */
1016 case 19: /* metrics in EBLC, PNG image data */
1017 #ifdef FT_CONFIG_OPTION_USE_PNG
1018 loader
= tt_sbit_decoder_load_png
;
1021 error
= FT_THROW( Unimplemented_Feature
);
1023 #endif /* FT_CONFIG_OPTION_USE_PNG */
1026 error
= FT_THROW( Invalid_Table
);
1030 if ( !decoder
->bitmap_allocated
)
1032 error
= tt_sbit_decoder_alloc_bitmap( decoder
);
1037 error
= loader( decoder
, p
, p_limit
, x_pos
, y_pos
);
1041 FT_FRAME_RELEASE( data
);
1049 tt_sbit_decoder_load_image( TT_SBitDecoder decoder
,
1050 FT_UInt glyph_index
,
1055 * First, we find the correct strike range that applies to this
1059 FT_Byte
* p
= decoder
->eblc_base
+ decoder
->strike_index_array
;
1060 FT_Byte
* p_limit
= decoder
->eblc_limit
;
1061 FT_ULong num_ranges
= decoder
->strike_index_count
;
1062 FT_UInt start
, end
, index_format
, image_format
;
1063 FT_ULong image_start
= 0, image_end
= 0, image_offset
;
1066 for ( ; num_ranges
> 0; num_ranges
-- )
1068 start
= FT_NEXT_USHORT( p
);
1069 end
= FT_NEXT_USHORT( p
);
1071 if ( glyph_index
>= start
&& glyph_index
<= end
)
1074 p
+= 4; /* ignore index offset */
1079 image_offset
= FT_NEXT_ULONG( p
);
1081 /* overflow check */
1082 p
= decoder
->eblc_base
+ decoder
->strike_index_array
;
1083 if ( image_offset
> (FT_ULong
)( p_limit
- p
) )
1087 if ( p
+ 8 > p_limit
)
1090 /* now find the glyph's location and extend within the ebdt table */
1091 index_format
= FT_NEXT_USHORT( p
);
1092 image_format
= FT_NEXT_USHORT( p
);
1093 image_offset
= FT_NEXT_ULONG ( p
);
1095 switch ( index_format
)
1097 case 1: /* 4-byte offsets relative to `image_offset' */
1098 p
+= 4 * ( glyph_index
- start
);
1099 if ( p
+ 8 > p_limit
)
1102 image_start
= FT_NEXT_ULONG( p
);
1103 image_end
= FT_NEXT_ULONG( p
);
1105 if ( image_start
== image_end
) /* missing glyph */
1109 case 2: /* big metrics, constant image size */
1111 FT_ULong image_size
;
1114 if ( p
+ 12 > p_limit
)
1117 image_size
= FT_NEXT_ULONG( p
);
1119 if ( tt_sbit_decoder_load_metrics( decoder
, &p
, p_limit
, 1 ) )
1122 image_start
= image_size
* ( glyph_index
- start
);
1123 image_end
= image_start
+ image_size
;
1127 case 3: /* 2-byte offsets relative to 'image_offset' */
1128 p
+= 2 * ( glyph_index
- start
);
1129 if ( p
+ 4 > p_limit
)
1132 image_start
= FT_NEXT_USHORT( p
);
1133 image_end
= FT_NEXT_USHORT( p
);
1135 if ( image_start
== image_end
) /* missing glyph */
1139 case 4: /* sparse glyph array with (glyph,offset) pairs */
1141 FT_ULong mm
, num_glyphs
;
1144 if ( p
+ 4 > p_limit
)
1147 num_glyphs
= FT_NEXT_ULONG( p
);
1149 /* overflow check for p + ( num_glyphs + 1 ) * 4 */
1150 if ( num_glyphs
> (FT_ULong
)( ( ( p_limit
- p
) >> 2 ) - 1 ) )
1153 for ( mm
= 0; mm
< num_glyphs
; mm
++ )
1155 FT_UInt gindex
= FT_NEXT_USHORT( p
);
1158 if ( gindex
== glyph_index
)
1160 image_start
= FT_NEXT_USHORT( p
);
1162 image_end
= FT_PEEK_USHORT( p
);
1168 if ( mm
>= num_glyphs
)
1173 case 5: /* constant metrics with sparse glyph codes */
1176 FT_ULong image_size
, mm
, num_glyphs
;
1179 if ( p
+ 16 > p_limit
)
1182 image_size
= FT_NEXT_ULONG( p
);
1184 if ( tt_sbit_decoder_load_metrics( decoder
, &p
, p_limit
, 1 ) )
1187 num_glyphs
= FT_NEXT_ULONG( p
);
1189 /* overflow check for p + 2 * num_glyphs */
1190 if ( num_glyphs
> (FT_ULong
)( ( p_limit
- p
) >> 1 ) )
1193 for ( mm
= 0; mm
< num_glyphs
; mm
++ )
1195 FT_UInt gindex
= FT_NEXT_USHORT( p
);
1198 if ( gindex
== glyph_index
)
1202 if ( mm
>= num_glyphs
)
1205 image_start
= image_size
* mm
;
1206 image_end
= image_start
+ image_size
;
1214 if ( image_start
> image_end
)
1217 image_end
-= image_start
;
1218 image_start
= image_offset
+ image_start
;
1220 FT_TRACE3(( "tt_sbit_decoder_load_image:"
1221 " found sbit (format %d) for glyph index %d\n",
1222 image_format
, glyph_index
));
1224 return tt_sbit_decoder_load_bitmap( decoder
,
1232 return FT_THROW( Invalid_Table
);
1235 FT_TRACE4(( "tt_sbit_decoder_load_image:"
1236 " no sbit found for glyph index %d\n", glyph_index
));
1238 return FT_THROW( Invalid_Argument
);
1243 tt_face_load_sbix_image( TT_Face face
,
1244 FT_ULong strike_index
,
1245 FT_UInt glyph_index
,
1248 TT_SBit_MetricsRec
*metrics
)
1250 FT_UInt sbix_pos
, strike_offset
, glyph_start
, glyph_end
;
1251 FT_ULong table_size
;
1252 FT_Int originOffsetX
, originOffsetY
;
1254 FT_Int recurse_depth
= 0;
1263 metrics
->height
= 0;
1265 p
= face
->sbit_table
+ 8 + 4 * strike_index
;
1266 strike_offset
= FT_NEXT_ULONG( p
);
1268 error
= face
->goto_table( face
, TTAG_sbix
, stream
, &table_size
);
1271 sbix_pos
= FT_STREAM_POS();
1274 if ( glyph_index
> (FT_UInt
)face
->root
.num_glyphs
)
1275 return FT_THROW( Invalid_Argument
);
1277 if ( strike_offset
>= table_size
||
1278 table_size
- strike_offset
< 4 + glyph_index
* 4 + 8 )
1279 return FT_THROW( Invalid_File_Format
);
1281 if ( FT_STREAM_SEEK( sbix_pos
+ strike_offset
+ 4 + glyph_index
* 4 ) ||
1282 FT_FRAME_ENTER( 8 ) )
1285 glyph_start
= FT_GET_ULONG();
1286 glyph_end
= FT_GET_ULONG();
1290 if ( glyph_start
== glyph_end
)
1291 return FT_THROW( Invalid_Argument
);
1292 if ( glyph_start
> glyph_end
||
1293 glyph_end
- glyph_start
< 8 ||
1294 table_size
- strike_offset
< glyph_end
)
1295 return FT_THROW( Invalid_File_Format
);
1297 if ( FT_STREAM_SEEK( sbix_pos
+ strike_offset
+ glyph_start
) ||
1298 FT_FRAME_ENTER( glyph_end
- glyph_start
) )
1301 originOffsetX
= FT_GET_SHORT();
1302 originOffsetY
= FT_GET_SHORT();
1304 graphicType
= FT_GET_TAG4();
1306 switch ( graphicType
)
1308 case FT_MAKE_TAG( 'd', 'u', 'p', 'e' ):
1309 if ( recurse_depth
< 4 )
1311 glyph_index
= FT_GET_USHORT();
1316 error
= FT_THROW( Invalid_File_Format
);
1319 case FT_MAKE_TAG( 'p', 'n', 'g', ' ' ):
1320 #ifdef FT_CONFIG_OPTION_USE_PNG
1321 error
= Load_SBit_Png( face
->root
.glyph
,
1328 glyph_end
- glyph_start
- 8,
1331 error
= FT_THROW( Unimplemented_Feature
);
1335 case FT_MAKE_TAG( 'j', 'p', 'g', ' ' ):
1336 case FT_MAKE_TAG( 't', 'i', 'f', 'f' ):
1337 error
= FT_THROW( Unknown_File_Format
);
1341 error
= FT_THROW( Unimplemented_Feature
);
1353 tt_face_get_metrics( face
, FALSE
, glyph_index
, &abearing
, &aadvance
);
1355 metrics
->horiBearingX
= originOffsetX
;
1356 metrics
->horiBearingY
= -originOffsetY
+ metrics
->height
;
1357 metrics
->horiAdvance
= aadvance
* face
->root
.size
->metrics
.x_ppem
/
1358 face
->header
.Units_Per_EM
;
1364 FT_LOCAL( FT_Error
)
1365 tt_face_load_sbit_image( TT_Face face
,
1366 FT_ULong strike_index
,
1367 FT_UInt glyph_index
,
1371 TT_SBit_MetricsRec
*metrics
)
1373 FT_Error error
= FT_Err_Ok
;
1376 switch ( (FT_UInt
)face
->sbit_table_type
)
1378 case TT_SBIT_TABLE_TYPE_EBLC
:
1379 case TT_SBIT_TABLE_TYPE_CBLC
:
1381 TT_SBitDecoderRec decoder
[1];
1384 error
= tt_sbit_decoder_init( decoder
, face
, strike_index
, metrics
);
1387 error
= tt_sbit_decoder_load_image( decoder
,
1391 tt_sbit_decoder_done( decoder
);
1396 case TT_SBIT_TABLE_TYPE_SBIX
:
1397 error
= tt_face_load_sbix_image( face
,
1406 error
= FT_THROW( Unknown_File_Format
);
1410 /* Flatten color bitmaps if color was not requested. */
1412 !( load_flags
& FT_LOAD_COLOR
) &&
1413 map
->pixel_mode
== FT_PIXEL_MODE_BGRA
)
1416 FT_Library library
= face
->root
.glyph
->library
;
1419 FT_Bitmap_New( &new_map
);
1421 /* Convert to 8bit grayscale. */
1422 error
= FT_Bitmap_Convert( library
, map
, &new_map
, 1 );
1424 FT_Bitmap_Done( library
, &new_map
);
1427 map
->pixel_mode
= new_map
.pixel_mode
;
1428 map
->pitch
= new_map
.pitch
;
1429 map
->num_grays
= new_map
.num_grays
;
1431 ft_glyphslot_set_bitmap( face
->root
.glyph
, new_map
.buffer
);
1432 face
->root
.glyph
->internal
->flags
|= FT_GLYPH_OWN_BITMAP
;