- Create another branch for networking fixes
[reactos.git] / lib / 3rdparty / freetype / src / sfnt / ttsbit0.c
1 /***************************************************************************/
2 /* */
3 /* ttsbit0.c */
4 /* */
5 /* TrueType and OpenType embedded bitmap support (body). */
6 /* This is a heap-optimized version. */
7 /* */
8 /* Copyright 2005, 2006, 2007 by */
9 /* David Turner, Robert Wilhelm, and Werner Lemberg. */
10 /* */
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. */
16 /* */
17 /***************************************************************************/
18
19
20 /* This file is included by ttsbit.c */
21
22
23 #include <ft2build.h>
24 #include FT_INTERNAL_DEBUG_H
25 #include FT_INTERNAL_STREAM_H
26 #include FT_TRUETYPE_TAGS_H
27 #include "ttsbit.h"
28
29 #include "sferrors.h"
30
31
32 /*************************************************************************/
33 /* */
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. */
37 /* */
38 #undef FT_COMPONENT
39 #define FT_COMPONENT trace_ttsbit
40
41
42 static const FT_Frame_Field tt_sbit_line_metrics_fields[] =
43 {
44 #undef FT_STRUCTURE
45 #define FT_STRUCTURE TT_SBit_LineMetricsRec
46
47 /* no FT_FRAME_START */
48 FT_FRAME_CHAR( ascender ),
49 FT_FRAME_CHAR( descender ),
50 FT_FRAME_BYTE( max_width ),
51
52 FT_FRAME_CHAR( caret_slope_numerator ),
53 FT_FRAME_CHAR( caret_slope_denominator ),
54 FT_FRAME_CHAR( caret_offset ),
55
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] ),
62 FT_FRAME_END
63 };
64
65 static const FT_Frame_Field tt_strike_start_fields[] =
66 {
67 #undef FT_STRUCTURE
68 #define FT_STRUCTURE TT_SBit_StrikeRec
69
70 /* no FT_FRAME_START */
71 FT_FRAME_ULONG( ranges_offset ),
72 FT_FRAME_SKIP_LONG,
73 FT_FRAME_ULONG( num_ranges ),
74 FT_FRAME_ULONG( color_ref ),
75 FT_FRAME_END
76 };
77
78 static const FT_Frame_Field tt_strike_end_fields[] =
79 {
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 ),
87 FT_FRAME_END
88 };
89
90
91 FT_LOCAL_DEF( FT_Error )
92 tt_face_load_eblc( TT_Face face,
93 FT_Stream stream )
94 {
95 FT_Error error = SFNT_Err_Ok;
96 FT_Fixed version;
97 FT_ULong num_strikes, table_size;
98 FT_Byte* p;
99 FT_Byte* p_limit;
100 FT_UInt count;
101
102
103 face->sbit_num_strikes = 0;
104
105 /* this table is optional */
106 error = face->goto_table( face, TTAG_EBLC, stream, &table_size );
107 if ( error )
108 error = face->goto_table( face, TTAG_bloc, stream, &table_size );
109 if ( error )
110 goto Exit;
111
112 if ( table_size < 8 )
113 {
114 FT_ERROR(( "%s: table too short!\n", "tt_face_load_sbit_strikes" ));
115 error = SFNT_Err_Invalid_File_Format;
116 goto Exit;
117 }
118
119 if ( FT_FRAME_EXTRACT( table_size, face->sbit_table ) )
120 goto Exit;
121
122 face->sbit_table_size = table_size;
123
124 p = face->sbit_table;
125 p_limit = p + table_size;
126
127 version = FT_NEXT_ULONG( p );
128 num_strikes = FT_NEXT_ULONG( p );
129
130 if ( version != 0x00020000UL || num_strikes >= 0x10000UL )
131 {
132 FT_ERROR(( "%s: invalid table version!\n",
133 "tt_face_load_sbit_strikes" ));
134 error = SFNT_Err_Invalid_File_Format;
135 goto Fail;
136 }
137
138 /*
139 * Count the number of strikes available in the table. We are a bit
140 * paranoid there and don't trust the data.
141 */
142 count = (FT_UInt)num_strikes;
143 if ( 8 + 48UL * count > table_size )
144 count = (FT_UInt)( ( p_limit - p ) / 48 );
145
146 face->sbit_num_strikes = count;
147
148 FT_TRACE3(( "sbit_num_strikes: %u\n", count ));
149 Exit:
150 return error;
151
152 Fail:
153 FT_FRAME_RELEASE( face->sbit_table );
154 face->sbit_table_size = 0;
155 goto Exit;
156 }
157
158
159 FT_LOCAL_DEF( void )
160 tt_face_free_eblc( TT_Face face )
161 {
162 FT_Stream stream = face->root.stream;
163
164
165 FT_FRAME_RELEASE( face->sbit_table );
166 face->sbit_table_size = 0;
167 face->sbit_num_strikes = 0;
168 }
169
170
171 FT_LOCAL_DEF( FT_Error )
172 tt_face_set_sbit_strike( TT_Face face,
173 FT_Size_Request req,
174 FT_ULong* astrike_index )
175 {
176 return FT_Match_Size( (FT_Face)face, req, 0, astrike_index );
177 }
178
179
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 )
184 {
185 FT_Byte* strike;
186
187
188 if ( strike_index >= (FT_ULong)face->sbit_num_strikes )
189 return SFNT_Err_Invalid_Argument;
190
191 strike = face->sbit_table + 8 + strike_index * 48;
192
193 metrics->x_ppem = (FT_UShort)strike[44];
194 metrics->y_ppem = (FT_UShort)strike[45];
195
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;
199
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 */
204 ) << 6;
205
206 return SFNT_Err_Ok;
207 }
208
209
210 typedef struct
211 {
212 TT_Face face;
213 FT_Stream stream;
214 FT_Bitmap* bitmap;
215 TT_SBit_Metrics metrics;
216 FT_Bool metrics_loaded;
217 FT_Bool bitmap_allocated;
218 FT_Byte bit_depth;
219
220 FT_ULong ebdt_start;
221 FT_ULong ebdt_size;
222
223 FT_ULong strike_index_array;
224 FT_ULong strike_index_count;
225 FT_Byte* eblc_base;
226 FT_Byte* eblc_limit;
227
228 } TT_SBitDecoderRec, *TT_SBitDecoder;
229
230
231 static FT_Error
232 tt_sbit_decoder_init( TT_SBitDecoder decoder,
233 TT_Face face,
234 FT_ULong strike_index,
235 TT_SBit_MetricsRec* metrics )
236 {
237 FT_Error error;
238 FT_Stream stream = face->root.stream;
239 FT_ULong ebdt_size;
240
241
242 error = face->goto_table( face, TTAG_EBDT, stream, &ebdt_size );
243 if ( error )
244 error = face->goto_table( face, TTAG_bdat, stream, &ebdt_size );
245 if ( error )
246 goto Exit;
247
248 decoder->face = face;
249 decoder->stream = stream;
250 decoder->bitmap = &face->root.glyph->bitmap;
251 decoder->metrics = metrics;
252
253 decoder->metrics_loaded = 0;
254 decoder->bitmap_allocated = 0;
255
256 decoder->ebdt_start = FT_STREAM_POS();
257 decoder->ebdt_size = ebdt_size;
258
259 decoder->eblc_base = face->sbit_table;
260 decoder->eblc_limit = face->sbit_table + face->sbit_table_size;
261
262 /* now find the strike corresponding to the index */
263 {
264 FT_Byte* p;
265
266
267 if ( 8 + 48 * strike_index + 3 * 4 + 34 + 1 > face->sbit_table_size )
268 {
269 error = SFNT_Err_Invalid_File_Format;
270 goto Exit;
271 }
272
273 p = decoder->eblc_base + 8 + 48 * strike_index;
274
275 decoder->strike_index_array = FT_NEXT_ULONG( p );
276 p += 4;
277 decoder->strike_index_count = FT_NEXT_ULONG( p );
278 p += 34;
279 decoder->bit_depth = *p;
280
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;
285 }
286
287 Exit:
288 return error;
289 }
290
291
292 static void
293 tt_sbit_decoder_done( TT_SBitDecoder decoder )
294 {
295 FT_UNUSED( decoder );
296 }
297
298
299 static FT_Error
300 tt_sbit_decoder_alloc_bitmap( TT_SBitDecoder decoder )
301 {
302 FT_Error error = SFNT_Err_Ok;
303 FT_UInt width, height;
304 FT_Bitmap* map = decoder->bitmap;
305 FT_Long size;
306
307
308 if ( !decoder->metrics_loaded )
309 {
310 error = SFNT_Err_Invalid_Argument;
311 goto Exit;
312 }
313
314 width = decoder->metrics->width;
315 height = decoder->metrics->height;
316
317 map->width = (int)width;
318 map->rows = (int)height;
319
320 switch ( decoder->bit_depth )
321 {
322 case 1:
323 map->pixel_mode = FT_PIXEL_MODE_MONO;
324 map->pitch = ( map->width + 7 ) >> 3;
325 break;
326
327 case 2:
328 map->pixel_mode = FT_PIXEL_MODE_GRAY2;
329 map->pitch = ( map->width + 3 ) >> 2;
330 break;
331
332 case 4:
333 map->pixel_mode = FT_PIXEL_MODE_GRAY4;
334 map->pitch = ( map->width + 1 ) >> 1;
335 break;
336
337 case 8:
338 map->pixel_mode = FT_PIXEL_MODE_GRAY;
339 map->pitch = map->width;
340 break;
341
342 default:
343 error = SFNT_Err_Invalid_File_Format;
344 goto Exit;
345 }
346
347 size = map->rows * map->pitch;
348
349 /* check that there is no empty image */
350 if ( size == 0 )
351 goto Exit; /* exit successfully! */
352
353 error = ft_glyphslot_alloc_bitmap( decoder->face->root.glyph, size );
354 if ( error )
355 goto Exit;
356
357 decoder->bitmap_allocated = 1;
358
359 Exit:
360 return error;
361 }
362
363
364 static FT_Error
365 tt_sbit_decoder_load_metrics( TT_SBitDecoder decoder,
366 FT_Byte* *pp,
367 FT_Byte* limit,
368 FT_Bool big )
369 {
370 FT_Byte* p = *pp;
371 TT_SBit_Metrics metrics = decoder->metrics;
372
373
374 if ( p + 5 > limit )
375 goto Fail;
376
377 if ( !decoder->metrics_loaded )
378 {
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];
384 }
385
386 p += 5;
387 if ( big )
388 {
389 if ( p + 3 > limit )
390 goto Fail;
391
392 if ( !decoder->metrics_loaded )
393 {
394 metrics->vertBearingX = (FT_Char)p[0];
395 metrics->vertBearingY = (FT_Char)p[1];
396 metrics->vertAdvance = p[2];
397 }
398
399 p += 3;
400 }
401
402 decoder->metrics_loaded = 1;
403 *pp = p;
404 return 0;
405
406 Fail:
407 return SFNT_Err_Invalid_Argument;
408 }
409
410
411 /* forward declaration */
412 static FT_Error
413 tt_sbit_decoder_load_image( TT_SBitDecoder decoder,
414 FT_UInt glyph_index,
415 FT_Int x_pos,
416 FT_Int y_pos );
417
418 typedef FT_Error (*TT_SBitDecoder_LoadFunc)( TT_SBitDecoder decoder,
419 FT_Byte* p,
420 FT_Byte* plimit,
421 FT_Int x_pos,
422 FT_Int y_pos );
423
424
425 static FT_Error
426 tt_sbit_decoder_load_byte_aligned( TT_SBitDecoder decoder,
427 FT_Byte* p,
428 FT_Byte* limit,
429 FT_Int x_pos,
430 FT_Int y_pos )
431 {
432 FT_Error error = SFNT_Err_Ok;
433 FT_Byte* line;
434 FT_Int bit_height, bit_width, pitch, width, height, h;
435 FT_Bitmap* bitmap;
436
437
438 if ( !decoder->bitmap_allocated )
439 {
440 error = tt_sbit_decoder_alloc_bitmap( decoder );
441 if ( error )
442 goto Exit;
443 }
444
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;
451
452 width = decoder->metrics->width;
453 height = decoder->metrics->height;
454
455 if ( x_pos < 0 || x_pos + width > bit_width ||
456 y_pos < 0 || y_pos + height > bit_height )
457 {
458 error = SFNT_Err_Invalid_File_Format;
459 goto Exit;
460 }
461
462 if ( p + ( ( width + 7 ) >> 3 ) * height > limit )
463 {
464 error = SFNT_Err_Invalid_File_Format;
465 goto Exit;
466 }
467
468 /* now do the blit */
469 line += y_pos * pitch + ( x_pos >> 3 );
470 x_pos &= 7;
471
472 if ( x_pos == 0 ) /* the easy one */
473 {
474 for ( h = height; h > 0; h--, line += pitch )
475 {
476 FT_Byte* write = line;
477 FT_Int w;
478
479
480 for ( w = width; w >= 8; w -= 8 )
481 {
482 write[0] = (FT_Byte)( write[0] | *p++ );
483 write += 1;
484 }
485
486 if ( w > 0 )
487 write[0] = (FT_Byte)( write[0] | ( *p++ & ( 0xFF00U >> w ) ) );
488 }
489 }
490 else /* x_pos > 0 */
491 {
492 for ( h = height; h > 0; h--, line += pitch )
493 {
494 FT_Byte* write = line;
495 FT_Int w;
496 FT_UInt wval = 0;
497
498
499 for ( w = width; w >= 8; w -= 8 )
500 {
501 wval = (FT_UInt)( wval | *p++ );
502 write[0] = (FT_Byte)( write[0] | ( wval >> x_pos ) );
503 write += 1;
504 wval <<= 8;
505 }
506
507 if ( w > 0 )
508 wval = (FT_UInt)( wval | ( *p++ & ( 0xFF00U >> w ) ) );
509
510 /* all bits read and there are ( x_pos + w ) bits to be written */
511
512 write[0] = (FT_Byte)( write[0] | ( wval >> x_pos ) );
513
514 if ( x_pos + w > 8 )
515 {
516 write++;
517 wval <<= 8;
518 write[0] = (FT_Byte)( write[0] | ( wval >> x_pos ) );
519 }
520 }
521 }
522
523 Exit:
524 return error;
525 }
526
527
528 static FT_Error
529 tt_sbit_decoder_load_bit_aligned( TT_SBitDecoder decoder,
530 FT_Byte* p,
531 FT_Byte* limit,
532 FT_Int x_pos,
533 FT_Int y_pos )
534 {
535 FT_Error error = SFNT_Err_Ok;
536 FT_Byte* line;
537 FT_Int bit_height, bit_width, pitch, width, height, h, nbits;
538 FT_Bitmap* bitmap;
539 FT_UShort rval;
540
541
542 if ( !decoder->bitmap_allocated )
543 {
544 error = tt_sbit_decoder_alloc_bitmap( decoder );
545 if ( error )
546 goto Exit;
547 }
548
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;
555
556 width = decoder->metrics->width;
557 height = decoder->metrics->height;
558
559 if ( x_pos < 0 || x_pos + width > bit_width ||
560 y_pos < 0 || y_pos + height > bit_height )
561 {
562 error = SFNT_Err_Invalid_File_Format;
563 goto Exit;
564 }
565
566 if ( p + ( ( width * height + 7 ) >> 3 ) > limit )
567 {
568 error = SFNT_Err_Invalid_File_Format;
569 goto Exit;
570 }
571
572 /* now do the blit */
573 line += y_pos * pitch + ( x_pos >> 3 );
574 x_pos &= 7;
575
576 /* the higher byte of `rval' is used as a buffer */
577 rval = 0;
578 nbits = 0;
579
580 for ( h = height; h > 0; h--, line += pitch )
581 {
582 FT_Byte* write = line;
583 FT_Int w = width;
584
585
586 if ( x_pos )
587 {
588 w = ( width < 8 - x_pos ) ? width : 8 - x_pos;
589
590 if ( nbits < w )
591 {
592 rval |= *p++;
593 nbits += 8 - w;
594 }
595 else
596 {
597 rval >>= 8;
598 nbits -= w;
599 }
600
601 *write++ |= ( ( rval >> nbits ) & 0xFF ) & ~( 0xFF << w );
602 rval <<= 8;
603
604 w = width - w;
605 }
606
607 for ( ; w >= 8; w -= 8 )
608 {
609 rval |= *p++;
610 *write++ |= ( rval >> nbits ) & 0xFF;
611
612 rval <<= 8;
613 }
614
615 if ( w > 0 )
616 {
617 if ( nbits < w )
618 {
619 rval |= *p++;
620 *write |= ( ( rval >> nbits ) & 0xFF ) & ( 0xFF00U >> w );
621 nbits += 8 - w;
622
623 rval <<= 8;
624 }
625 else
626 {
627 *write |= ( ( rval >> nbits ) & 0xFF ) & ( 0xFF00U >> w );
628 nbits -= w;
629 }
630 }
631 }
632
633 Exit:
634 return error;
635 }
636
637
638 static FT_Error
639 tt_sbit_decoder_load_compound( TT_SBitDecoder decoder,
640 FT_Byte* p,
641 FT_Byte* limit,
642 FT_Int x_pos,
643 FT_Int y_pos )
644 {
645 FT_Error error = SFNT_Err_Ok;
646 FT_UInt num_components, nn;
647
648
649 if ( p + 2 > limit )
650 goto Fail;
651
652 num_components = FT_NEXT_USHORT( p );
653 if ( p + 4 * num_components > limit )
654 goto Fail;
655
656 for ( nn = 0; nn < num_components; nn++ )
657 {
658 FT_UInt gindex = FT_NEXT_USHORT( p );
659 FT_Byte dx = FT_NEXT_BYTE( p );
660 FT_Byte dy = FT_NEXT_BYTE( p );
661
662
663 /* NB: a recursive call */
664 error = tt_sbit_decoder_load_image( decoder, gindex,
665 x_pos + dx, y_pos + dy );
666 if ( error )
667 break;
668 }
669
670 Exit:
671 return error;
672
673 Fail:
674 error = SFNT_Err_Invalid_File_Format;
675 goto Exit;
676 }
677
678
679 static FT_Error
680 tt_sbit_decoder_load_bitmap( TT_SBitDecoder decoder,
681 FT_UInt glyph_format,
682 FT_ULong glyph_start,
683 FT_ULong glyph_size,
684 FT_Int x_pos,
685 FT_Int y_pos )
686 {
687 FT_Error error;
688 FT_Stream stream = decoder->stream;
689 FT_Byte* p;
690 FT_Byte* p_limit;
691 FT_Byte* data;
692
693
694 /* seek into the EBDT table now */
695 if ( glyph_start + glyph_size > decoder->ebdt_size )
696 {
697 error = SFNT_Err_Invalid_Argument;
698 goto Exit;
699 }
700
701 if ( FT_STREAM_SEEK( decoder->ebdt_start + glyph_start ) ||
702 FT_FRAME_EXTRACT( glyph_size, data ) )
703 goto Exit;
704
705 p = data;
706 p_limit = p + glyph_size;
707
708 /* read the data, depending on the glyph format */
709 switch ( glyph_format )
710 {
711 case 1:
712 case 2:
713 case 8:
714 error = tt_sbit_decoder_load_metrics( decoder, &p, p_limit, 0 );
715 break;
716
717 case 6:
718 case 7:
719 case 9:
720 error = tt_sbit_decoder_load_metrics( decoder, &p, p_limit, 1 );
721 break;
722
723 default:
724 error = SFNT_Err_Ok;
725 }
726
727 if ( error )
728 goto Fail;
729
730 {
731 TT_SBitDecoder_LoadFunc loader;
732
733
734 switch ( glyph_format )
735 {
736 case 1:
737 case 6:
738 loader = tt_sbit_decoder_load_byte_aligned;
739 break;
740
741 case 2:
742 case 5:
743 case 7:
744 loader = tt_sbit_decoder_load_bit_aligned;
745 break;
746
747 case 8:
748 if ( p + 1 > p_limit )
749 goto Fail;
750
751 p += 1; /* skip padding */
752 /* fall-through */
753
754 case 9:
755 loader = tt_sbit_decoder_load_compound;
756 break;
757
758 default:
759 goto Fail;
760 }
761
762 error = loader( decoder, p, p_limit, x_pos, y_pos );
763 }
764
765 Fail:
766 FT_FRAME_RELEASE( data );
767
768 Exit:
769 return error;
770 }
771
772
773 static FT_Error
774 tt_sbit_decoder_load_image( TT_SBitDecoder decoder,
775 FT_UInt glyph_index,
776 FT_Int x_pos,
777 FT_Int y_pos )
778 {
779 /*
780 * First, we find the correct strike range that applies to this
781 * glyph index.
782 */
783
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;
789
790
791 for ( ; num_ranges > 0; num_ranges-- )
792 {
793 start = FT_NEXT_USHORT( p );
794 end = FT_NEXT_USHORT( p );
795
796 if ( glyph_index >= start && glyph_index <= end )
797 goto FoundRange;
798
799 p += 4; /* ignore index offset */
800 }
801 goto NoBitmap;
802
803 FoundRange:
804 image_offset = FT_NEXT_ULONG( p );
805
806 /* overflow check */
807 if ( decoder->eblc_base + decoder->strike_index_array + image_offset <
808 decoder->eblc_base )
809 goto Failure;
810
811 p = decoder->eblc_base + decoder->strike_index_array + image_offset;
812 if ( p + 8 > p_limit )
813 goto NoBitmap;
814
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 );
819
820 switch ( index_format )
821 {
822 case 1: /* 4-byte offsets relative to `image_offset' */
823 {
824 p += 4 * ( glyph_index - start );
825 if ( p + 8 > p_limit )
826 goto NoBitmap;
827
828 image_start = FT_NEXT_ULONG( p );
829 image_end = FT_NEXT_ULONG( p );
830
831 if ( image_start == image_end ) /* missing glyph */
832 goto NoBitmap;
833 }
834 break;
835
836 case 2: /* big metrics, constant image size */
837 {
838 FT_ULong image_size;
839
840
841 if ( p + 12 > p_limit )
842 goto NoBitmap;
843
844 image_size = FT_NEXT_ULONG( p );
845
846 if ( tt_sbit_decoder_load_metrics( decoder, &p, p_limit, 1 ) )
847 goto NoBitmap;
848
849 image_start = image_size * ( glyph_index - start );
850 image_end = image_start + image_size;
851 }
852 break;
853
854 case 3: /* 2-byte offsets relative to 'image_offset' */
855 {
856 p += 2 * ( glyph_index - start );
857 if ( p + 4 > p_limit )
858 goto NoBitmap;
859
860 image_start = FT_NEXT_USHORT( p );
861 image_end = FT_NEXT_USHORT( p );
862
863 if ( image_start == image_end ) /* missing glyph */
864 goto NoBitmap;
865 }
866 break;
867
868 case 4: /* sparse glyph array with (glyph,offset) pairs */
869 {
870 FT_ULong mm, num_glyphs;
871
872
873 if ( p + 4 > p_limit )
874 goto NoBitmap;
875
876 num_glyphs = FT_NEXT_ULONG( p );
877
878 /* overflow check */
879 if ( p + ( num_glyphs + 1 ) * 4 < p )
880 goto Failure;
881
882 if ( p + ( num_glyphs + 1 ) * 4 > p_limit )
883 goto NoBitmap;
884
885 for ( mm = 0; mm < num_glyphs; mm++ )
886 {
887 FT_UInt gindex = FT_NEXT_USHORT( p );
888
889
890 if ( gindex == glyph_index )
891 {
892 image_start = FT_NEXT_USHORT( p );
893 p += 2;
894 image_end = FT_PEEK_USHORT( p );
895 break;
896 }
897 p += 2;
898 }
899
900 if ( mm >= num_glyphs )
901 goto NoBitmap;
902 }
903 break;
904
905 case 5: /* constant metrics with sparse glyph codes */
906 {
907 FT_ULong image_size, mm, num_glyphs;
908
909
910 if ( p + 16 > p_limit )
911 goto NoBitmap;
912
913 image_size = FT_NEXT_ULONG( p );
914
915 if ( tt_sbit_decoder_load_metrics( decoder, &p, p_limit, 1 ) )
916 goto NoBitmap;
917
918 num_glyphs = FT_NEXT_ULONG( p );
919
920 /* overflow check */
921 if ( p + 2 * num_glyphs < p )
922 goto Failure;
923
924 if ( p + 2 * num_glyphs > p_limit )
925 goto NoBitmap;
926
927 for ( mm = 0; mm < num_glyphs; mm++ )
928 {
929 FT_UInt gindex = FT_NEXT_USHORT( p );
930
931
932 if ( gindex == glyph_index )
933 break;
934 }
935
936 if ( mm >= num_glyphs )
937 goto NoBitmap;
938
939 image_start = image_size * mm;
940 image_end = image_start + image_size;
941 }
942 break;
943
944 default:
945 goto NoBitmap;
946 }
947
948 if ( image_start > image_end )
949 goto NoBitmap;
950
951 image_end -= image_start;
952 image_start = image_offset + image_start;
953
954 return tt_sbit_decoder_load_bitmap( decoder,
955 image_format,
956 image_start,
957 image_end,
958 x_pos,
959 y_pos );
960
961 Failure:
962 return SFNT_Err_Invalid_Table;
963
964 NoBitmap:
965 return SFNT_Err_Invalid_Argument;
966 }
967
968
969 FT_LOCAL( FT_Error )
970 tt_face_load_sbit_image( TT_Face face,
971 FT_ULong strike_index,
972 FT_UInt glyph_index,
973 FT_UInt load_flags,
974 FT_Stream stream,
975 FT_Bitmap *map,
976 TT_SBit_MetricsRec *metrics )
977 {
978 TT_SBitDecoderRec decoder[1];
979 FT_Error error;
980
981 FT_UNUSED( load_flags );
982 FT_UNUSED( stream );
983 FT_UNUSED( map );
984
985
986 error = tt_sbit_decoder_init( decoder, face, strike_index, metrics );
987 if ( !error )
988 {
989 error = tt_sbit_decoder_load_image( decoder, glyph_index, 0, 0 );
990 tt_sbit_decoder_done( decoder );
991 }
992
993 return error;
994 }
995
996 /* EOF */