28#ifdef TT_CONFIG_OPTION_EMBEDDED_BITMAPS
45#define FT_COMPONENT ttsbit
48 FT_LOCAL_DEF( FT_Error )
49 tt_face_load_sbit( TT_Face face,
57 face->sbit_table = NULL;
58 face->sbit_table_size = 0;
59 face->sbit_table_type = TT_SBIT_TABLE_TYPE_NONE;
60 face->sbit_num_strikes = 0;
62 error = face->goto_table( face, TTAG_CBLC, stream, &table_size );
64 face->sbit_table_type = TT_SBIT_TABLE_TYPE_CBLC;
67 error = face->goto_table( face, TTAG_EBLC, stream, &table_size );
69 error = face->goto_table( face, TTAG_bloc, stream, &table_size );
71 face->sbit_table_type = TT_SBIT_TABLE_TYPE_EBLC;
76 error = face->goto_table( face, TTAG_sbix, stream, &table_size );
78 face->sbit_table_type = TT_SBIT_TABLE_TYPE_SBIX;
85 FT_ERROR((
"tt_face_load_sbit_strikes: table too short\n" ));
86 error = FT_THROW( Invalid_File_Format );
90 table_start = FT_STREAM_POS();
92 switch ( (FT_UInt)face->sbit_table_type )
94 case TT_SBIT_TABLE_TYPE_EBLC:
95 case TT_SBIT_TABLE_TYPE_CBLC:
103 if ( FT_FRAME_EXTRACT( table_size, face->sbit_table ) )
106 face->sbit_table_size = table_size;
108 p = face->sbit_table;
110 version = FT_NEXT_LONG( p );
111 num_strikes = FT_NEXT_ULONG( p );
115 if ( ( (FT_ULong)version & 0xFFFF0000UL ) != 0x00020000UL &&
116 ( (FT_ULong)version & 0x0000FFFFUL ) != 0x00000200UL &&
117 ( (FT_ULong)version & 0xFFFF0000UL ) != 0x00030000UL &&
118 ( (FT_ULong)version & 0x0000FFFFUL ) != 0x00000300UL )
120 error = FT_THROW( Unknown_File_Format );
124 if ( num_strikes >= 0x10000UL )
126 error = FT_THROW( Invalid_File_Format );
134 count = (FT_UInt)num_strikes;
135 if ( 8 + 48UL * count > table_size )
136 count = (FT_UInt)( ( table_size - 8 ) / 48 );
138 face->sbit_num_strikes = count;
142 case TT_SBIT_TABLE_TYPE_SBIX:
146 FT_ULong num_strikes;
150 if ( FT_FRAME_ENTER( 8 ) )
153 version = FT_GET_USHORT();
154 flags = FT_GET_USHORT();
155 num_strikes = FT_GET_ULONG();
161 error = FT_THROW( Unknown_File_Format );
168 if ( !( flags == 1 || flags == 3 ) ||
169 num_strikes >= 0x10000UL )
171 error = FT_THROW( Invalid_File_Format );
176 face->root.face_flags |= FT_FACE_FLAG_SBIX_OVERLAY;
182 count = (FT_UInt)num_strikes;
183 if ( 8 + 4UL * count > table_size )
184 count = (FT_UInt)( ( table_size - 8 ) / 4 );
186 if ( FT_STREAM_SEEK( FT_STREAM_POS() - 8 ) )
189 face->sbit_table_size = 8 + count * 4;
190 if ( FT_FRAME_EXTRACT( face->sbit_table_size, face->sbit_table ) )
193 face->sbit_num_strikes = count;
199 error = FT_THROW( Unknown_File_Format );
204 FT_TRACE3((
"tt_face_load_sbit_strikes: found %u strikes\n",
205 face->sbit_num_strikes ));
207 face->ebdt_start = 0;
210 if ( face->sbit_table_type == TT_SBIT_TABLE_TYPE_SBIX )
214 face->ebdt_start = table_start;
215 face->ebdt_size = table_size;
217 else if ( face->sbit_table_type != TT_SBIT_TABLE_TYPE_NONE )
222 error = face->goto_table( face, TTAG_CBDT, stream, &ebdt_size );
224 error = face->goto_table( face, TTAG_EBDT, stream, &ebdt_size );
226 error = face->goto_table( face, TTAG_bdat, stream, &ebdt_size );
230 face->ebdt_start = FT_STREAM_POS();
231 face->ebdt_size = ebdt_size;
235 if ( !face->ebdt_size )
237 FT_TRACE2((
"tt_face_load_sbit_strikes:"
238 " no embedded bitmap data table found;\n" ));
240 " resetting number of strikes to zero\n" ));
241 face->sbit_num_strikes = 0;
249 if ( face->sbit_table )
250 FT_FRAME_RELEASE( face->sbit_table );
251 face->sbit_table_size = 0;
252 face->sbit_table_type = TT_SBIT_TABLE_TYPE_NONE;
260 tt_face_free_sbit( TT_Face face )
262 FT_Stream stream = face->root.stream;
265 FT_FRAME_RELEASE( face->sbit_table );
266 face->sbit_table_size = 0;
267 face->sbit_table_type = TT_SBIT_TABLE_TYPE_NONE;
268 face->sbit_num_strikes = 0;
272 FT_LOCAL_DEF( FT_Error )
273 tt_face_set_sbit_strike( TT_Face face,
275 FT_ULong* astrike_index )
277 return FT_Match_Size( (FT_Face)face, req, 0, astrike_index );
281 FT_LOCAL_DEF( FT_Error )
282 tt_face_load_strike_metrics( TT_Face face,
283 FT_ULong strike_index,
284 FT_Size_Metrics* metrics )
289 if ( face->sbit_strike_map )
291 if ( strike_index >= (FT_ULong)face->root.num_fixed_sizes )
292 return FT_THROW( Invalid_Argument );
295 strike_index = face->sbit_strike_map[strike_index];
299 if ( strike_index >= (FT_ULong)face->sbit_num_strikes )
300 return FT_THROW( Invalid_Argument );
303 switch ( (FT_UInt)face->sbit_table_type )
305 case TT_SBIT_TABLE_TYPE_EBLC:
306 case TT_SBIT_TABLE_TYPE_CBLC:
309 FT_Char max_before_bl;
310 FT_Char min_after_bl;
313 strike = face->sbit_table + 8 + strike_index * 48;
315 metrics->x_ppem = (FT_UShort)strike[44];
316 metrics->y_ppem = (FT_UShort)strike[45];
318 metrics->ascender = (FT_Char)strike[16] * 64;
319 metrics->descender = (FT_Char)strike[17] * 64;
328 max_before_bl = (FT_Char)strike[24];
329 min_after_bl = (FT_Char)strike[25];
331 if ( metrics->descender > 0 )
334 if ( min_after_bl < 0 )
335 metrics->descender = -metrics->descender;
338 else if ( metrics->descender == 0 )
340 if ( metrics->ascender == 0 )
342 FT_TRACE2((
"tt_face_load_strike_metrics:"
343 " sanitizing invalid ascender and descender\n" ));
345 " values for strike %lu (%dppem, %dppem)\n",
347 metrics->x_ppem, metrics->y_ppem ));
350 if ( max_before_bl || min_after_bl )
352 metrics->ascender = max_before_bl * 64;
353 metrics->descender = min_after_bl * 64;
357 metrics->ascender = metrics->y_ppem * 64;
358 metrics->descender = 0;
368 metrics->height = metrics->ascender - metrics->descender;
369 if ( metrics->height == 0 )
371 FT_TRACE2((
"tt_face_load_strike_metrics:"
372 " sanitizing invalid height value\n" ));
374 " for strike (%d, %d)\n",
375 metrics->x_ppem, metrics->y_ppem ));
376 metrics->height = metrics->y_ppem * 64;
377 metrics->descender = metrics->ascender - metrics->height;
381 metrics->max_advance = ( (FT_Char)strike[22] +
388 metrics->x_scale = FT_DivFix( metrics->x_ppem * 64,
389 face->header.Units_Per_EM );
390 metrics->y_scale = FT_DivFix( metrics->y_ppem * 64,
391 face->header.Units_Per_EM );
396 case TT_SBIT_TABLE_TYPE_SBIX:
398 FT_Stream stream = face->root.stream;
400 FT_UShort ppem, resolution;
408 p = face->sbit_table + 8 + 4 * strike_index;
409 offset = FT_NEXT_ULONG( p );
411 if ( offset + 4 > face->ebdt_size )
412 return FT_THROW( Invalid_File_Format );
414 if ( FT_STREAM_SEEK( face->ebdt_start + offset ) ||
415 FT_FRAME_ENTER( 4 ) )
418 ppem = FT_GET_USHORT();
419 resolution = FT_GET_USHORT();
421 FT_UNUSED( resolution );
425 metrics->x_ppem = ppem;
426 metrics->y_ppem = ppem;
428 scale = FT_DivFix( ppem * 64, face->header.Units_Per_EM );
429 hori = &face->horizontal;
431 metrics->ascender = FT_MulFix( hori->Ascender, scale );
432 metrics->descender = FT_MulFix( hori->Descender, scale );
434 FT_MulFix( hori->Ascender - hori->Descender + hori->Line_Gap,
436 metrics->max_advance = FT_MulFix( hori->advance_Width_Max, scale );
440 metrics->x_scale = scale;
441 metrics->y_scale = scale;
447 return FT_THROW( Unknown_File_Format );
452 typedef struct TT_SBitDecoderRec_
457 TT_SBit_Metrics metrics;
458 FT_Bool metrics_loaded;
459 FT_Bool bitmap_allocated;
465 FT_ULong strike_index_array;
466 FT_ULong strike_index_count;
470 } TT_SBitDecoderRec, *TT_SBitDecoder;
474 tt_sbit_decoder_init( TT_SBitDecoder decoder,
476 FT_ULong strike_index,
477 TT_SBit_MetricsRec* metrics )
479 FT_Error error = FT_ERR( Table_Missing );
480 FT_Stream stream = face->root.stream;
483 strike_index = face->sbit_strike_map[strike_index];
485 if ( !face->ebdt_size )
487 if ( FT_STREAM_SEEK( face->ebdt_start ) )
490 decoder->face = face;
491 decoder->stream = stream;
492 decoder->bitmap = &face->root.glyph->bitmap;
493 decoder->metrics = metrics;
495 decoder->metrics_loaded = 0;
496 decoder->bitmap_allocated = 0;
498 decoder->ebdt_start = face->ebdt_start;
499 decoder->ebdt_size = face->ebdt_size;
501 decoder->eblc_base = face->sbit_table;
502 decoder->eblc_limit = face->sbit_table + face->sbit_table_size;
509 if ( 8 + 48 * strike_index + 3 * 4 + 34 + 1 > face->sbit_table_size )
511 error = FT_THROW( Invalid_File_Format );
515 p = decoder->eblc_base + 8 + 48 * strike_index;
517 decoder->strike_index_array = FT_NEXT_ULONG( p );
519 decoder->strike_index_count = FT_NEXT_ULONG( p );
521 decoder->bit_depth = *p;
525 if ( decoder->strike_index_array > face->sbit_table_size ||
526 decoder->strike_index_count >
527 ( face->sbit_table_size - decoder->strike_index_array ) / 8 )
528 error = FT_THROW( Invalid_File_Format );
537 tt_sbit_decoder_done( TT_SBitDecoder decoder )
539 FT_UNUSED( decoder );
544 tt_sbit_decoder_alloc_bitmap( TT_SBitDecoder decoder,
545 FT_Bool metrics_only )
547 FT_Error error = FT_Err_Ok;
548 FT_UInt width, height;
549 FT_Bitmap* map = decoder->bitmap;
553 if ( !decoder->metrics_loaded )
555 error = FT_THROW( Invalid_Argument );
559 width = decoder->metrics->width;
560 height = decoder->metrics->height;
565 switch ( decoder->bit_depth )
568 map->pixel_mode = FT_PIXEL_MODE_MONO;
569 map->pitch = (int)( ( map->width + 7 ) >> 3 );
574 map->pixel_mode = FT_PIXEL_MODE_GRAY2;
575 map->pitch = (int)( ( map->width + 3 ) >> 2 );
580 map->pixel_mode = FT_PIXEL_MODE_GRAY4;
581 map->pitch = (int)( ( map->width + 1 ) >> 1 );
586 map->pixel_mode = FT_PIXEL_MODE_GRAY;
587 map->pitch = (int)( map->width );
588 map->num_grays = 256;
592 map->pixel_mode = FT_PIXEL_MODE_BGRA;
593 map->pitch = (int)( map->width * 4 );
594 map->num_grays = 256;
598 error = FT_THROW( Invalid_File_Format );
602 size = map->rows * (FT_ULong)map->pitch;
611 error = ft_glyphslot_alloc_bitmap( decoder->face->root.glyph, size );
615 decoder->bitmap_allocated = 1;
623 tt_sbit_decoder_load_metrics( TT_SBitDecoder decoder,
629 TT_SBit_Metrics metrics = decoder->metrics;
635 metrics->height = p[0];
636 metrics->width = p[1];
637 metrics->horiBearingX = (FT_Char)p[2];
638 metrics->horiBearingY = (FT_Char)p[3];
639 metrics->horiAdvance = p[4];
647 metrics->vertBearingX = (FT_Char)p[0];
648 metrics->vertBearingY = (FT_Char)p[1];
649 metrics->vertAdvance = p[2];
656 metrics->vertBearingX = 0;
657 metrics->vertBearingY = 0;
658 metrics->vertAdvance = 0;
661 decoder->metrics_loaded = 1;
666 FT_TRACE1((
"tt_sbit_decoder_load_metrics: broken table\n" ));
667 return FT_THROW( Invalid_Argument );
673 tt_sbit_decoder_load_image( TT_SBitDecoder decoder,
677 FT_UInt recurse_count,
678 FT_Bool metrics_only );
680 typedef FT_Error (*TT_SBitDecoder_LoadFunc)(
681 TT_SBitDecoder decoder,
686 FT_UInt recurse_count );
690 tt_sbit_decoder_load_byte_aligned( TT_SBitDecoder decoder,
695 FT_UInt recurse_count )
697 FT_Error error = FT_Err_Ok;
699 FT_Int pitch, width, height, line_bits, h;
700 FT_UInt bit_height, bit_width;
703 FT_UNUSED( recurse_count );
707 bitmap = decoder->bitmap;
708 bit_width = bitmap->width;
709 bit_height = bitmap->rows;
710 pitch = bitmap->pitch;
711 line = bitmap->buffer;
716 width = decoder->metrics->width;
717 height = decoder->metrics->height;
719 line_bits = width * decoder->bit_depth;
721 if ( x_pos < 0 || (FT_UInt)( x_pos + width ) > bit_width ||
722 y_pos < 0 || (FT_UInt)( y_pos + height ) > bit_height )
724 FT_TRACE1((
"tt_sbit_decoder_load_byte_aligned:"
725 " invalid bitmap dimensions\n" ));
726 error = FT_THROW( Invalid_File_Format );
730 if ( p + ( ( line_bits + 7 ) >> 3 ) * height > limit )
732 FT_TRACE1((
"tt_sbit_decoder_load_byte_aligned: broken bitmap\n" ));
733 error = FT_THROW( Invalid_File_Format );
738 line += y_pos * pitch + ( x_pos >> 3 );
743 for ( h = height; h > 0; h--, line += pitch )
745 FT_Byte* pwrite = line;
749 for ( w = line_bits; w >= 8; w -= 8 )
751 pwrite[0] = (FT_Byte)( pwrite[0] | *p++ );
756 pwrite[0] = (FT_Byte)( pwrite[0] | ( *p++ & ( 0xFF00U >> w ) ) );
761 for ( h = height; h > 0; h--, line += pitch )
763 FT_Byte* pwrite = line;
768 for ( w = line_bits; w >= 8; w -= 8 )
770 wval = (FT_UInt)( wval | *p++ );
771 pwrite[0] = (FT_Byte)( pwrite[0] | ( wval >> x_pos ) );
777 wval = (FT_UInt)( wval | ( *p++ & ( 0xFF00U >> w ) ) );
781 pwrite[0] = (FT_Byte)( pwrite[0] | ( wval >> x_pos ) );
787 pwrite[0] = (FT_Byte)( pwrite[0] | ( wval >> x_pos ) );
794 FT_TRACE3((
"tt_sbit_decoder_load_byte_aligned: loaded\n" ));
835 tt_sbit_decoder_load_bit_aligned( TT_SBitDecoder decoder,
840 FT_UInt recurse_count )
842 FT_Error error = FT_Err_Ok;
844 FT_Int pitch, width, height, line_bits, h, nbits;
845 FT_UInt bit_height, bit_width;
849 FT_UNUSED( recurse_count );
853 bitmap = decoder->bitmap;
854 bit_width = bitmap->width;
855 bit_height = bitmap->rows;
856 pitch = bitmap->pitch;
857 line = bitmap->buffer;
859 width = decoder->metrics->width;
860 height = decoder->metrics->height;
862 line_bits = width * decoder->bit_depth;
864 if ( x_pos < 0 || (FT_UInt)( x_pos + width ) > bit_width ||
865 y_pos < 0 || (FT_UInt)( y_pos + height ) > bit_height )
867 FT_TRACE1((
"tt_sbit_decoder_load_bit_aligned:"
868 " invalid bitmap dimensions\n" ));
869 error = FT_THROW( Invalid_File_Format );
873 if ( p + ( ( line_bits * height + 7 ) >> 3 ) > limit )
875 FT_TRACE1((
"tt_sbit_decoder_load_bit_aligned: broken bitmap\n" ));
876 error = FT_THROW( Invalid_File_Format );
880 if ( !line_bits || !height )
889 line += y_pos * pitch + ( x_pos >> 3 );
896 for ( h = height; h > 0; h--, line += pitch )
898 FT_Byte* pwrite = line;
899 FT_Int w = line_bits;
905 w = ( line_bits < 8 - x_pos ) ? line_bits : 8 - x_pos;
912 else if ( nbits < w )
924 *pwrite++ |= ( ( rval >> nbits ) & 0xFF ) &
925 ( ~( 0xFFU << w ) << ( 8 - w - x_pos ) );
932 for ( ; w >= 8; w -= 8 )
935 *pwrite++ |= ( rval >> nbits ) & 0xFF;
947 *pwrite |= ( ( rval >> nbits ) & 0xFF ) & ( 0xFF00U >> w );
954 *pwrite |= ( ( rval >> nbits ) & 0xFF ) & ( 0xFF00U >> w );
962 FT_TRACE3((
"tt_sbit_decoder_load_bit_aligned: loaded\n" ));
968 tt_sbit_decoder_load_compound( TT_SBitDecoder decoder,
973 FT_UInt recurse_count )
975 FT_Error error = FT_Err_Ok;
976 FT_UInt num_components, nn;
978 FT_Char horiBearingX = (FT_Char)decoder->metrics->horiBearingX;
979 FT_Char horiBearingY = (FT_Char)decoder->metrics->horiBearingY;
980 FT_Byte horiAdvance = (FT_Byte)decoder->metrics->horiAdvance;
981 FT_Char vertBearingX = (FT_Char)decoder->metrics->vertBearingX;
982 FT_Char vertBearingY = (FT_Char)decoder->metrics->vertBearingY;
983 FT_Byte vertAdvance = (FT_Byte)decoder->metrics->vertAdvance;
989 num_components = FT_NEXT_USHORT( p );
990 if ( p + 4 * num_components > limit )
992 FT_TRACE1((
"tt_sbit_decoder_load_compound: broken table\n" ));
996 FT_TRACE3((
"tt_sbit_decoder_load_compound: loading %u component%s\n",
998 num_components == 1 ?
"" :
"s" ));
1000 for ( nn = 0; nn < num_components; nn++ )
1002 FT_UInt gindex = FT_NEXT_USHORT( p );
1003 FT_Char dx = FT_NEXT_CHAR( p );
1004 FT_Char dy = FT_NEXT_CHAR( p );
1008 error = tt_sbit_decoder_load_image( decoder,
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" ));
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;
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;
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;
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 )
1199 loader = tt_sbit_decoder_load_compound;
1205#ifdef FT_CONFIG_OPTION_USE_PNG
1206 loader = tt_sbit_decoder_load_png;
1209 error = FT_THROW( Unimplemented_Feature );
1214 error = FT_THROW( Invalid_Table );
1218 if ( !decoder->bitmap_allocated )
1220 error = tt_sbit_decoder_alloc_bitmap( decoder, metrics_only );
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;
1256 if ( recurse_count > 100 )
1258 FT_TRACE4((
"tt_sbit_decoder_load_image:"
1259 " recursion depth exceeded\n" ));
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 )
1279 image_offset = FT_NEXT_ULONG( p );
1282 p = decoder->eblc_base + decoder->strike_index_array;
1283 if ( image_offset > (FT_ULong)( p_limit - p ) )
1287 if ( p + 8 > p_limit )
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 )
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 )
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;
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 )
1341 FT_ULong mm, num_glyphs;
1344 if ( p + 4 > p_limit )
1347 num_glyphs = FT_NEXT_ULONG( p );
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 )
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 );
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 %u) for glyph index %u\n",
1423 image_format, glyph_index ));
1425 return tt_sbit_decoder_load_bitmap( decoder,
1435 return FT_THROW( Invalid_Table );
1438 if ( recurse_count )
1440 FT_TRACE4((
"tt_sbit_decoder_load_image:"
1441 " missing subglyph sbit with glyph index %u\n",
1443 return FT_THROW( Invalid_Composite );
1446 FT_TRACE4((
"tt_sbit_decoder_load_image:"
1447 " no sbit found for glyph index %u\n", glyph_index ));
1448 return FT_THROW( Missing_Bitmap );
1453 tt_face_load_sbix_image( TT_Face face,
1454 FT_ULong strike_index,
1455 FT_UInt glyph_index,
1458 TT_SBit_MetricsRec *metrics,
1459 FT_Bool metrics_only )
1461 FT_UInt strike_offset, glyph_start, glyph_end;
1462 FT_Int originOffsetX, originOffsetY;
1464 FT_Int recurse_depth = 0;
1465 FT_Bool flipped = FALSE;
1470#ifndef FT_CONFIG_OPTION_USE_PNG
1472 FT_UNUSED( metrics_only );
1476 strike_index = face->sbit_strike_map[strike_index];
1479 metrics->height = 0;
1481 p = face->sbit_table + 8 + 4 * strike_index;
1482 strike_offset = FT_NEXT_ULONG( p );
1485 if ( glyph_index > (FT_UInt)face->root.num_glyphs )
1486 return FT_THROW( Invalid_Argument );
1488 if ( strike_offset >= face->ebdt_size ||
1489 face->ebdt_size - strike_offset < 4 + glyph_index * 4 + 8 )
1490 return FT_THROW( Invalid_File_Format );
1492 if ( FT_STREAM_SEEK( face->ebdt_start +
1494 glyph_index * 4 ) ||
1495 FT_FRAME_ENTER( 8 ) )
1498 glyph_start = FT_GET_ULONG();
1499 glyph_end = FT_GET_ULONG();
1503 if ( glyph_start == glyph_end )
1504 return FT_THROW( Missing_Bitmap );
1505 if ( glyph_start > glyph_end ||
1506 glyph_end - glyph_start < 8 ||
1507 face->ebdt_size - strike_offset < glyph_end )
1508 return FT_THROW( Invalid_File_Format );
1510 if ( FT_STREAM_SEEK( face->ebdt_start + strike_offset + glyph_start ) ||
1511 FT_FRAME_ENTER( glyph_end - glyph_start ) )
1514 originOffsetX = FT_GET_SHORT();
1515 originOffsetY = FT_GET_SHORT();
1517 graphicType = FT_GET_TAG4();
1519 switch ( graphicType )
1521 case FT_MAKE_TAG(
'f',
'l',
'i',
'p' ):
1525 case FT_MAKE_TAG(
'd',
'u',
'p',
'e' ):
1526 if ( recurse_depth++ < 4 )
1528 glyph_index = FT_GET_USHORT();
1533 error = FT_THROW( Invalid_File_Format );
1536 case FT_MAKE_TAG(
'p',
'n',
'g',
' ' ):
1537#ifdef FT_CONFIG_OPTION_USE_PNG
1538 error = Load_SBit_Png( face->root.glyph,
1545 glyph_end - glyph_start - 8,
1548 if ( flipped && !metrics_only && !error )
1550 FT_UInt32* curr_pos = (FT_UInt32*)map->buffer;
1554 FT_UInt width = map->width;
1558 for ( y = 0; y < map->rows; y++ )
1560 FT_UInt32* left = curr_pos;
1561 FT_UInt32* right = curr_pos + width - 1;
1564 while ( left < right )
1581 error = FT_THROW( Unimplemented_Feature );
1585 case FT_MAKE_TAG(
'j',
'p',
'g',
' ' ):
1586 case FT_MAKE_TAG(
't',
'i',
'f',
'f' ):
1587 case FT_MAKE_TAG(
'r',
'g',
'b',
'l' ):
1588 error = FT_THROW( Unknown_File_Format );
1592 error = FT_THROW( Unimplemented_Feature );
1604 tt_face_get_metrics( face, FALSE, glyph_index, &abearing, &aadvance );
1606 metrics->horiBearingX = (FT_Short)originOffsetX;
1607 metrics->vertBearingX = (FT_Short)originOffsetX;
1609 metrics->horiBearingY = (FT_Short)( originOffsetY + metrics->height );
1610 metrics->vertBearingY = (FT_Short)originOffsetY;
1612 metrics->horiAdvance = (FT_UShort)( aadvance *
1613 face->root.size->metrics.x_ppem /
1614 face->header.Units_Per_EM );
1616 if ( face->vertical_info )
1617 tt_face_get_metrics( face, TRUE, glyph_index, &abearing, &aadvance );
1618 else if ( face->os2.version != 0xFFFFU )
1619 aadvance = (FT_UShort)FT_ABS( face->os2.sTypoAscender -
1620 face->os2.sTypoDescender );
1622 aadvance = (FT_UShort)FT_ABS( face->horizontal.Ascender -
1623 face->horizontal.Descender );
1625 metrics->vertAdvance = (FT_UShort)( aadvance *
1626 face->root.size->metrics.x_ppem /
1627 face->header.Units_Per_EM );
1633 FT_LOCAL_DEF( FT_Error )
1634 tt_face_load_sbit_image( TT_Face face,
1635 FT_ULong strike_index,
1636 FT_UInt glyph_index,
1640 TT_SBit_MetricsRec *metrics )
1642 FT_Error error = FT_Err_Ok;
1645 switch ( (FT_UInt)face->sbit_table_type )
1647 case TT_SBIT_TABLE_TYPE_EBLC:
1648 case TT_SBIT_TABLE_TYPE_CBLC:
1650 TT_SBitDecoderRec decoder[1];
1653 error = tt_sbit_decoder_init( decoder, face, strike_index, metrics );
1656 error = tt_sbit_decoder_load_image(
1662 ( load_flags & FT_LOAD_BITMAP_METRICS_ONLY ) != 0 );
1663 tt_sbit_decoder_done( decoder );
1668 case TT_SBIT_TABLE_TYPE_SBIX:
1669 error = tt_face_load_sbix_image(
1676 ( load_flags & FT_LOAD_BITMAP_METRICS_ONLY ) != 0 );
1680 error = FT_THROW( Unknown_File_Format );
1686 !( load_flags & FT_LOAD_COLOR ) &&
1687 !( load_flags & FT_LOAD_BITMAP_METRICS_ONLY ) &&
1688 map->pixel_mode == FT_PIXEL_MODE_BGRA )
1691 FT_Library library = face->root.glyph->library;
1694 FT_Bitmap_Init( &new_map );
1697 error = FT_Bitmap_Convert( library, map, &new_map, 1 );
1699 FT_Bitmap_Done( library, &new_map );
1702 map->pixel_mode = new_map.pixel_mode;
1703 map->pitch = new_map.pitch;
1704 map->num_grays = new_map.num_grays;
1706 ft_glyphslot_set_bitmap( face->root.glyph, new_map.buffer );
1707 face->root.glyph->internal->flags |= FT_GLYPH_OWN_BITMAP;
1717 typedef int tt_sbit_dummy_;