ReactOS 0.4.16-dev-2358-g0df3463
ttsbit.c
Go to the documentation of this file.
1/****************************************************************************
2 *
3 * ttsbit.c
4 *
5 * TrueType and OpenType embedded bitmap support (body).
6 *
7 * Copyright (C) 2005-2020 by
8 * David Turner, Robert Wilhelm, and Werner Lemberg.
9 *
10 * Copyright 2013 by Google, Inc.
11 * Google Author(s): Behdad Esfahbod.
12 *
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.
18 *
19 */
20
21
24#include <freetype/tttags.h>
25#include <freetype/ftbitmap.h>
26
27
28#ifdef TT_CONFIG_OPTION_EMBEDDED_BITMAPS
29
30#include "ttsbit.h"
31
32#include "sferrors.h"
33
34#include "ttmtx.h"
35#include "pngshim.h"
36
37
38 /**************************************************************************
39 *
40 * The macro FT_COMPONENT is used in trace mode. It is an implicit
41 * parameter of the FT_TRACE() and FT_ERROR() macros, used to print/log
42 * messages during execution.
43 */
44#undef FT_COMPONENT
45#define FT_COMPONENT ttsbit
46
47
51 {
54 FT_ULong table_start;
55
56
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;
61
62 error = face->goto_table( face, TTAG_CBLC, stream, &table_size );
63 if ( !error )
64 face->sbit_table_type = TT_SBIT_TABLE_TYPE_CBLC;
65 else
66 {
67 error = face->goto_table( face, TTAG_EBLC, stream, &table_size );
68 if ( error )
69 error = face->goto_table( face, TTAG_bloc, stream, &table_size );
70 if ( !error )
71 face->sbit_table_type = TT_SBIT_TABLE_TYPE_EBLC;
72 }
73
74 if ( error )
75 {
76 error = face->goto_table( face, TTAG_sbix, stream, &table_size );
77 if ( !error )
78 face->sbit_table_type = TT_SBIT_TABLE_TYPE_SBIX;
79 }
80 if ( error )
81 goto Exit;
82
83 if ( table_size < 8 )
84 {
85 FT_ERROR(( "tt_face_load_sbit_strikes: table too short\n" ));
86 error = FT_THROW( Invalid_File_Format );
87 goto Exit;
88 }
89
90 table_start = FT_STREAM_POS();
91
92 switch ( (FT_UInt)face->sbit_table_type )
93 {
96 {
97 FT_Byte* p;
99 FT_ULong num_strikes;
101
102
103 if ( FT_FRAME_EXTRACT( table_size, face->sbit_table ) )
104 goto Exit;
105
106 face->sbit_table_size = table_size;
107
108 p = face->sbit_table;
109
111 num_strikes = FT_NEXT_ULONG( p );
112
113 /* there's at least one font (FZShuSong-Z01, version 3) */
114 /* that uses the wrong byte order for the `version' field */
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 )
119 {
120 error = FT_THROW( Unknown_File_Format );
121 goto Exit;
122 }
123
124 if ( num_strikes >= 0x10000UL )
125 {
126 error = FT_THROW( Invalid_File_Format );
127 goto Exit;
128 }
129
130 /*
131 * Count the number of strikes available in the table. We are a bit
132 * paranoid there and don't trust the data.
133 */
134 count = (FT_UInt)num_strikes;
135 if ( 8 + 48UL * count > table_size )
136 count = (FT_UInt)( ( table_size - 8 ) / 48 );
137
138 face->sbit_num_strikes = count;
139 }
140 break;
141
143 {
146 FT_ULong num_strikes;
148
149
150 if ( FT_FRAME_ENTER( 8 ) )
151 goto Exit;
152
155 num_strikes = FT_GET_ULONG();
156
158
159 if ( version < 1 )
160 {
161 error = FT_THROW( Unknown_File_Format );
162 goto Exit;
163 }
164
165 /* Bit 0 must always be `1'. */
166 /* Bit 1 controls the overlay of bitmaps with outlines. */
167 /* All other bits should be zero. */
168 if ( !( flags == 1 || flags == 3 ) ||
169 num_strikes >= 0x10000UL )
170 {
171 error = FT_THROW( Invalid_File_Format );
172 goto Exit;
173 }
174
175 /* we currently don't support bit 1; however, it is better to */
176 /* draw at least something... */
177 if ( flags == 3 )
178 FT_TRACE1(( "tt_face_load_sbit_strikes:"
179 " sbix overlay not supported yet\n"
180 " "
181 " expect bad rendering results\n" ));
182
183 /*
184 * Count the number of strikes available in the table. We are a bit
185 * paranoid there and don't trust the data.
186 */
187 count = (FT_UInt)num_strikes;
188 if ( 8 + 4UL * count > table_size )
189 count = (FT_UInt)( ( table_size - 8 ) / 4 );
190
191 if ( FT_STREAM_SEEK( FT_STREAM_POS() - 8 ) )
192 goto Exit;
193
194 face->sbit_table_size = 8 + count * 4;
195 if ( FT_FRAME_EXTRACT( face->sbit_table_size, face->sbit_table ) )
196 goto Exit;
197
198 face->sbit_num_strikes = count;
199 }
200 break;
201
202 default:
203 /* we ignore unknown table formats */
204 error = FT_THROW( Unknown_File_Format );
205 break;
206 }
207
208 if ( !error )
209 FT_TRACE3(( "tt_face_load_sbit_strikes: found %u strikes\n",
210 face->sbit_num_strikes ));
211
212 face->ebdt_start = 0;
213 face->ebdt_size = 0;
214
215 if ( face->sbit_table_type == TT_SBIT_TABLE_TYPE_SBIX )
216 {
217 /* the `sbix' table is self-contained; */
218 /* it has no associated data table */
219 face->ebdt_start = table_start;
220 face->ebdt_size = table_size;
221 }
222 else if ( face->sbit_table_type != TT_SBIT_TABLE_TYPE_NONE )
223 {
224 FT_ULong ebdt_size;
225
226
227 error = face->goto_table( face, TTAG_CBDT, stream, &ebdt_size );
228 if ( error )
229 error = face->goto_table( face, TTAG_EBDT, stream, &ebdt_size );
230 if ( error )
231 error = face->goto_table( face, TTAG_bdat, stream, &ebdt_size );
232
233 if ( !error )
234 {
235 face->ebdt_start = FT_STREAM_POS();
236 face->ebdt_size = ebdt_size;
237 }
238 }
239
240 if ( !face->ebdt_size )
241 {
242 FT_TRACE2(( "tt_face_load_sbit_strikes:"
243 " no embedded bitmap data table found;\n"
244 " "
245 " resetting number of strikes to zero\n" ));
246 face->sbit_num_strikes = 0;
247 }
248
249 return FT_Err_Ok;
250
251 Exit:
252 if ( error )
253 {
254 if ( face->sbit_table )
255 FT_FRAME_RELEASE( face->sbit_table );
256 face->sbit_table_size = 0;
257 face->sbit_table_type = TT_SBIT_TABLE_TYPE_NONE;
258 }
259
260 return error;
261 }
262
263
264 FT_LOCAL_DEF( void )
266 {
267 FT_Stream stream = face->root.stream;
268
269
270 FT_FRAME_RELEASE( face->sbit_table );
271 face->sbit_table_size = 0;
272 face->sbit_table_type = TT_SBIT_TABLE_TYPE_NONE;
273 face->sbit_num_strikes = 0;
274 }
275
276
279 FT_Size_Request req,
280 FT_ULong* astrike_index )
281 {
282 return FT_Match_Size( (FT_Face)face, req, 0, astrike_index );
283 }
284
285
288 FT_ULong strike_index,
290 {
291 /* we have to test for the existence of `sbit_strike_map' */
292 /* because the function gets also used at the very beginning */
293 /* to construct `sbit_strike_map' itself */
294 if ( face->sbit_strike_map )
295 {
296 if ( strike_index >= (FT_ULong)face->root.num_fixed_sizes )
297 return FT_THROW( Invalid_Argument );
298
299 /* map to real index */
300 strike_index = face->sbit_strike_map[strike_index];
301 }
302 else
303 {
304 if ( strike_index >= (FT_ULong)face->sbit_num_strikes )
305 return FT_THROW( Invalid_Argument );
306 }
307
308 switch ( (FT_UInt)face->sbit_table_type )
309 {
312 {
313 FT_Byte* strike;
314 FT_Char max_before_bl;
315 FT_Char min_after_bl;
316
317
318 strike = face->sbit_table + 8 + strike_index * 48;
319
320 metrics->x_ppem = (FT_UShort)strike[44];
321 metrics->y_ppem = (FT_UShort)strike[45];
322
323 metrics->ascender = (FT_Char)strike[16] * 64; /* hori.ascender */
324 metrics->descender = (FT_Char)strike[17] * 64; /* hori.descender */
325
326 /* Due to fuzzy wording in the EBLC documentation, we find both */
327 /* positive and negative values for `descender'. Additionally, */
328 /* many fonts have both `ascender' and `descender' set to zero */
329 /* (which is definitely wrong). MS Windows simply ignores all */
330 /* those values... For these reasons we apply some heuristics */
331 /* to get a reasonable, non-zero value for the height. */
332
333 max_before_bl = (FT_Char)strike[24];
334 min_after_bl = (FT_Char)strike[25];
335
336 if ( metrics->descender > 0 )
337 {
338 /* compare sign of descender with `min_after_bl' */
339 if ( min_after_bl < 0 )
340 metrics->descender = -metrics->descender;
341 }
342
343 else if ( metrics->descender == 0 )
344 {
345 if ( metrics->ascender == 0 )
346 {
347 FT_TRACE2(( "tt_face_load_strike_metrics:"
348 " sanitizing invalid ascender and descender\n"
349 " "
350 " values for strike %ld (%dppem, %dppem)\n",
351 strike_index,
352 metrics->x_ppem, metrics->y_ppem ));
353
354 /* sanitize buggy ascender and descender values */
355 if ( max_before_bl || min_after_bl )
356 {
357 metrics->ascender = max_before_bl * 64;
358 metrics->descender = min_after_bl * 64;
359 }
360 else
361 {
362 metrics->ascender = metrics->y_ppem * 64;
363 metrics->descender = 0;
364 }
365 }
366 }
367
368#if 0
369 else
370 ; /* if we have a negative descender, simply use it */
371#endif
372
373 metrics->height = metrics->ascender - metrics->descender;
374 if ( metrics->height == 0 )
375 {
376 FT_TRACE2(( "tt_face_load_strike_metrics:"
377 " sanitizing invalid height value\n"
378 " "
379 " for strike (%d, %d)\n",
380 metrics->x_ppem, metrics->y_ppem ));
381 metrics->height = metrics->y_ppem * 64;
382 metrics->descender = metrics->ascender - metrics->height;
383 }
384
385 /* Is this correct? */
386 metrics->max_advance = ( (FT_Char)strike[22] + /* min_origin_SB */
387 strike[18] + /* max_width */
388 (FT_Char)strike[23] /* min_advance_SB */
389 ) * 64;
390
391 /* set the scale values (in 16.16 units) so advances */
392 /* from the hmtx and vmtx table are scaled correctly */
393 metrics->x_scale = FT_MulDiv( metrics->x_ppem,
394 64 * 0x10000,
395 face->header.Units_Per_EM );
396 metrics->y_scale = FT_MulDiv( metrics->y_ppem,
397 64 * 0x10000,
398 face->header.Units_Per_EM );
399
400 return FT_Err_Ok;
401 }
402
404 {
405 FT_Stream stream = face->root.stream;
407 FT_UShort upem, ppem, resolution;
408 TT_HoriHeader *hori;
409 FT_Pos ppem_; /* to reduce casts */
410
412 FT_Byte* p;
413
414
415 p = face->sbit_table + 8 + 4 * strike_index;
417
418 if ( offset + 4 > face->ebdt_size )
419 return FT_THROW( Invalid_File_Format );
420
421 if ( FT_STREAM_SEEK( face->ebdt_start + offset ) ||
422 FT_FRAME_ENTER( 4 ) )
423 return error;
424
425 ppem = FT_GET_USHORT();
426 resolution = FT_GET_USHORT();
427
428 FT_UNUSED( resolution ); /* What to do with this? */
429
431
432 upem = face->header.Units_Per_EM;
433 hori = &face->horizontal;
434
435 metrics->x_ppem = ppem;
436 metrics->y_ppem = ppem;
437
438 ppem_ = (FT_Pos)ppem;
439
440 metrics->ascender =
441 FT_MulDiv( hori->Ascender, ppem_ * 64, upem );
442 metrics->descender =
443 FT_MulDiv( hori->Descender, ppem_ * 64, upem );
444 metrics->height =
445 FT_MulDiv( hori->Ascender - hori->Descender + hori->Line_Gap,
446 ppem_ * 64, upem );
447 metrics->max_advance =
448 FT_MulDiv( hori->advance_Width_Max, ppem_ * 64, upem );
449
450 /* set the scale values (in 16.16 units) so advances */
451 /* from the hmtx and vmtx table are scaled correctly */
452 metrics->x_scale = FT_MulDiv( metrics->x_ppem,
453 64 * 0x10000,
454 face->header.Units_Per_EM );
455 metrics->y_scale = FT_MulDiv( metrics->y_ppem,
456 64 * 0x10000,
457 face->header.Units_Per_EM );
458
459 return error;
460 }
461
462 default:
463 return FT_THROW( Unknown_File_Format );
464 }
465 }
466
467
468 typedef struct TT_SBitDecoderRec_
469 {
474 FT_Bool metrics_loaded;
475 FT_Bool bitmap_allocated;
476 FT_Byte bit_depth;
477
478 FT_ULong ebdt_start;
479 FT_ULong ebdt_size;
480
481 FT_ULong strike_index_array;
482 FT_ULong strike_index_count;
483 FT_Byte* eblc_base;
484 FT_Byte* eblc_limit;
485
486 } TT_SBitDecoderRec, *TT_SBitDecoder;
487
488
489 static FT_Error
490 tt_sbit_decoder_init( TT_SBitDecoder decoder,
492 FT_ULong strike_index,
494 {
495 FT_Error error = FT_ERR( Table_Missing );
496 FT_Stream stream = face->root.stream;
497
498
499 strike_index = face->sbit_strike_map[strike_index];
500
501 if ( !face->ebdt_size )
502 goto Exit;
503 if ( FT_STREAM_SEEK( face->ebdt_start ) )
504 goto Exit;
505
506 decoder->face = face;
507 decoder->stream = stream;
508 decoder->bitmap = &face->root.glyph->bitmap;
509 decoder->metrics = metrics;
510
511 decoder->metrics_loaded = 0;
512 decoder->bitmap_allocated = 0;
513
514 decoder->ebdt_start = face->ebdt_start;
515 decoder->ebdt_size = face->ebdt_size;
516
517 decoder->eblc_base = face->sbit_table;
518 decoder->eblc_limit = face->sbit_table + face->sbit_table_size;
519
520 /* now find the strike corresponding to the index */
521 {
522 FT_Byte* p;
523
524
525 if ( 8 + 48 * strike_index + 3 * 4 + 34 + 1 > face->sbit_table_size )
526 {
527 error = FT_THROW( Invalid_File_Format );
528 goto Exit;
529 }
530
531 p = decoder->eblc_base + 8 + 48 * strike_index;
532
533 decoder->strike_index_array = FT_NEXT_ULONG( p );
534 p += 4;
535 decoder->strike_index_count = FT_NEXT_ULONG( p );
536 p += 34;
537 decoder->bit_depth = *p;
538
539 /* decoder->strike_index_array + */
540 /* 8 * decoder->strike_index_count > face->sbit_table_size ? */
541 if ( decoder->strike_index_array > face->sbit_table_size ||
542 decoder->strike_index_count >
543 ( face->sbit_table_size - decoder->strike_index_array ) / 8 )
544 error = FT_THROW( Invalid_File_Format );
545 }
546
547 Exit:
548 return error;
549 }
550
551
552 static void
553 tt_sbit_decoder_done( TT_SBitDecoder decoder )
554 {
556 }
557
558
559 static FT_Error
560 tt_sbit_decoder_alloc_bitmap( TT_SBitDecoder decoder,
561 FT_Bool metrics_only )
562 {
565 FT_Bitmap* map = decoder->bitmap;
567
568
569 if ( !decoder->metrics_loaded )
570 {
571 error = FT_THROW( Invalid_Argument );
572 goto Exit;
573 }
574
575 width = decoder->metrics->width;
576 height = decoder->metrics->height;
577
578 map->width = width;
579 map->rows = height;
580
581 switch ( decoder->bit_depth )
582 {
583 case 1:
584 map->pixel_mode = FT_PIXEL_MODE_MONO;
585 map->pitch = (int)( ( map->width + 7 ) >> 3 );
586 map->num_grays = 2;
587 break;
588
589 case 2:
590 map->pixel_mode = FT_PIXEL_MODE_GRAY2;
591 map->pitch = (int)( ( map->width + 3 ) >> 2 );
592 map->num_grays = 4;
593 break;
594
595 case 4:
596 map->pixel_mode = FT_PIXEL_MODE_GRAY4;
597 map->pitch = (int)( ( map->width + 1 ) >> 1 );
598 map->num_grays = 16;
599 break;
600
601 case 8:
602 map->pixel_mode = FT_PIXEL_MODE_GRAY;
603 map->pitch = (int)( map->width );
604 map->num_grays = 256;
605 break;
606
607 case 32:
608 map->pixel_mode = FT_PIXEL_MODE_BGRA;
609 map->pitch = (int)( map->width * 4 );
610 map->num_grays = 256;
611 break;
612
613 default:
614 error = FT_THROW( Invalid_File_Format );
615 goto Exit;
616 }
617
618 size = map->rows * (FT_ULong)map->pitch;
619
620 /* check that there is no empty image */
621 if ( size == 0 )
622 goto Exit; /* exit successfully! */
623
624 if ( metrics_only )
625 goto Exit; /* only metrics are requested */
626
627 error = ft_glyphslot_alloc_bitmap( decoder->face->root.glyph, size );
628 if ( error )
629 goto Exit;
630
631 decoder->bitmap_allocated = 1;
632
633 Exit:
634 return error;
635 }
636
637
638 static FT_Error
639 tt_sbit_decoder_load_metrics( TT_SBitDecoder decoder,
640 FT_Byte* *pp,
641 FT_Byte* limit,
642 FT_Bool big )
643 {
644 FT_Byte* p = *pp;
646
647
648 if ( p + 5 > limit )
649 goto Fail;
650
651 metrics->height = p[0];
652 metrics->width = p[1];
653 metrics->horiBearingX = (FT_Char)p[2];
654 metrics->horiBearingY = (FT_Char)p[3];
655 metrics->horiAdvance = p[4];
656
657 p += 5;
658 if ( big )
659 {
660 if ( p + 3 > limit )
661 goto Fail;
662
663 metrics->vertBearingX = (FT_Char)p[0];
664 metrics->vertBearingY = (FT_Char)p[1];
665 metrics->vertAdvance = p[2];
666
667 p += 3;
668 }
669 else
670 {
671 /* avoid uninitialized data in case there is no vertical info -- */
672 metrics->vertBearingX = 0;
673 metrics->vertBearingY = 0;
674 metrics->vertAdvance = 0;
675 }
676
677 decoder->metrics_loaded = 1;
678 *pp = p;
679 return FT_Err_Ok;
680
681 Fail:
682 FT_TRACE1(( "tt_sbit_decoder_load_metrics: broken table\n" ));
683 return FT_THROW( Invalid_Argument );
684 }
685
686
687 /* forward declaration */
688 static FT_Error
689 tt_sbit_decoder_load_image( TT_SBitDecoder decoder,
690 FT_UInt glyph_index,
691 FT_Int x_pos,
692 FT_Int y_pos,
693 FT_UInt recurse_count,
694 FT_Bool metrics_only );
695
696 typedef FT_Error (*TT_SBitDecoder_LoadFunc)(
697 TT_SBitDecoder decoder,
698 FT_Byte* p,
699 FT_Byte* plimit,
700 FT_Int x_pos,
701 FT_Int y_pos,
702 FT_UInt recurse_count );
703
704
705 static FT_Error
706 tt_sbit_decoder_load_byte_aligned( TT_SBitDecoder decoder,
707 FT_Byte* p,
708 FT_Byte* limit,
709 FT_Int x_pos,
710 FT_Int y_pos,
711 FT_UInt recurse_count )
712 {
714 FT_Byte* line;
715 FT_Int pitch, width, height, line_bits, h;
716 FT_UInt bit_height, bit_width;
718
719 FT_UNUSED( recurse_count );
720
721
722 /* check that we can write the glyph into the bitmap */
723 bitmap = decoder->bitmap;
724 bit_width = bitmap->width;
725 bit_height = bitmap->rows;
726 pitch = bitmap->pitch;
727 line = bitmap->buffer;
728
729 width = decoder->metrics->width;
730 height = decoder->metrics->height;
731
732 line_bits = width * decoder->bit_depth;
733
734 if ( x_pos < 0 || (FT_UInt)( x_pos + width ) > bit_width ||
735 y_pos < 0 || (FT_UInt)( y_pos + height ) > bit_height )
736 {
737 FT_TRACE1(( "tt_sbit_decoder_load_byte_aligned:"
738 " invalid bitmap dimensions\n" ));
739 error = FT_THROW( Invalid_File_Format );
740 goto Exit;
741 }
742
743 if ( p + ( ( line_bits + 7 ) >> 3 ) * height > limit )
744 {
745 FT_TRACE1(( "tt_sbit_decoder_load_byte_aligned: broken bitmap\n" ));
746 error = FT_THROW( Invalid_File_Format );
747 goto Exit;
748 }
749
750 /* now do the blit */
751 line += y_pos * pitch + ( x_pos >> 3 );
752 x_pos &= 7;
753
754 if ( x_pos == 0 ) /* the easy one */
755 {
756 for ( h = height; h > 0; h--, line += pitch )
757 {
759 FT_Int w;
760
761
762 for ( w = line_bits; w >= 8; w -= 8 )
763 {
764 pwrite[0] = (FT_Byte)( pwrite[0] | *p++ );
765 pwrite += 1;
766 }
767
768 if ( w > 0 )
769 pwrite[0] = (FT_Byte)( pwrite[0] | ( *p++ & ( 0xFF00U >> w ) ) );
770 }
771 }
772 else /* x_pos > 0 */
773 {
774 for ( h = height; h > 0; h--, line += pitch )
775 {
777 FT_Int w;
778 FT_UInt wval = 0;
779
780
781 for ( w = line_bits; w >= 8; w -= 8 )
782 {
783 wval = (FT_UInt)( wval | *p++ );
784 pwrite[0] = (FT_Byte)( pwrite[0] | ( wval >> x_pos ) );
785 pwrite += 1;
786 wval <<= 8;
787 }
788
789 if ( w > 0 )
790 wval = (FT_UInt)( wval | ( *p++ & ( 0xFF00U >> w ) ) );
791
792 /* all bits read and there are `x_pos + w' bits to be written */
793
794 pwrite[0] = (FT_Byte)( pwrite[0] | ( wval >> x_pos ) );
795
796 if ( x_pos + w > 8 )
797 {
798 pwrite++;
799 wval <<= 8;
800 pwrite[0] = (FT_Byte)( pwrite[0] | ( wval >> x_pos ) );
801 }
802 }
803 }
804
805 Exit:
806 if ( !error )
807 FT_TRACE3(( "tt_sbit_decoder_load_byte_aligned: loaded\n" ));
808 return error;
809 }
810
811
812 /*
813 * Load a bit-aligned bitmap (with pointer `p') into a line-aligned bitmap
814 * (with pointer `pwrite'). In the example below, the width is 3 pixel,
815 * and `x_pos' is 1 pixel.
816 *
817 * p p+1
818 * | | |
819 * | 7 6 5 4 3 2 1 0 | 7 6 5 4 3 2 1 0 |...
820 * | | |
821 * +-------+ +-------+ +-------+ ...
822 * . . .
823 * . . .
824 * v . .
825 * +-------+ . .
826 * | | .
827 * | 7 6 5 4 3 2 1 0 | .
828 * | | .
829 * pwrite . .
830 * . .
831 * v .
832 * +-------+ .
833 * | |
834 * | 7 6 5 4 3 2 1 0 |
835 * | |
836 * pwrite+1 .
837 * .
838 * v
839 * +-------+
840 * | |
841 * | 7 6 5 4 3 2 1 0 |
842 * | |
843 * pwrite+2
844 *
845 */
846
847 static FT_Error
848 tt_sbit_decoder_load_bit_aligned( TT_SBitDecoder decoder,
849 FT_Byte* p,
850 FT_Byte* limit,
851 FT_Int x_pos,
852 FT_Int y_pos,
853 FT_UInt recurse_count )
854 {
856 FT_Byte* line;
857 FT_Int pitch, width, height, line_bits, h, nbits;
858 FT_UInt bit_height, bit_width;
861
862 FT_UNUSED( recurse_count );
863
864
865 /* check that we can write the glyph into the bitmap */
866 bitmap = decoder->bitmap;
867 bit_width = bitmap->width;
868 bit_height = bitmap->rows;
869 pitch = bitmap->pitch;
870 line = bitmap->buffer;
871
872 width = decoder->metrics->width;
873 height = decoder->metrics->height;
874
875 line_bits = width * decoder->bit_depth;
876
877 if ( x_pos < 0 || (FT_UInt)( x_pos + width ) > bit_width ||
878 y_pos < 0 || (FT_UInt)( y_pos + height ) > bit_height )
879 {
880 FT_TRACE1(( "tt_sbit_decoder_load_bit_aligned:"
881 " invalid bitmap dimensions\n" ));
882 error = FT_THROW( Invalid_File_Format );
883 goto Exit;
884 }
885
886 if ( p + ( ( line_bits * height + 7 ) >> 3 ) > limit )
887 {
888 FT_TRACE1(( "tt_sbit_decoder_load_bit_aligned: broken bitmap\n" ));
889 error = FT_THROW( Invalid_File_Format );
890 goto Exit;
891 }
892
893 if ( !line_bits || !height )
894 {
895 /* nothing to do */
896 goto Exit;
897 }
898
899 /* now do the blit */
900
901 /* adjust `line' to point to the first byte of the bitmap */
902 line += y_pos * pitch + ( x_pos >> 3 );
903 x_pos &= 7;
904
905 /* the higher byte of `rval' is used as a buffer */
906 rval = 0;
907 nbits = 0;
908
909 for ( h = height; h > 0; h--, line += pitch )
910 {
912 FT_Int w = line_bits;
913
914
915 /* handle initial byte (in target bitmap) specially if necessary */
916 if ( x_pos )
917 {
918 w = ( line_bits < 8 - x_pos ) ? line_bits : 8 - x_pos;
919
920 if ( h == height )
921 {
922 rval = *p++;
923 nbits = x_pos;
924 }
925 else if ( nbits < w )
926 {
927 if ( p < limit )
928 rval |= *p++;
929 nbits += 8 - w;
930 }
931 else
932 {
933 rval >>= 8;
934 nbits -= w;
935 }
936
937 *pwrite++ |= ( ( rval >> nbits ) & 0xFF ) &
938 ( ~( 0xFFU << w ) << ( 8 - w - x_pos ) );
939 rval <<= 8;
940
941 w = line_bits - w;
942 }
943
944 /* handle medial bytes */
945 for ( ; w >= 8; w -= 8 )
946 {
947 rval |= *p++;
948 *pwrite++ |= ( rval >> nbits ) & 0xFF;
949
950 rval <<= 8;
951 }
952
953 /* handle final byte if necessary */
954 if ( w > 0 )
955 {
956 if ( nbits < w )
957 {
958 if ( p < limit )
959 rval |= *p++;
960 *pwrite |= ( ( rval >> nbits ) & 0xFF ) & ( 0xFF00U >> w );
961 nbits += 8 - w;
962
963 rval <<= 8;
964 }
965 else
966 {
967 *pwrite |= ( ( rval >> nbits ) & 0xFF ) & ( 0xFF00U >> w );
968 nbits -= w;
969 }
970 }
971 }
972
973 Exit:
974 if ( !error )
975 FT_TRACE3(( "tt_sbit_decoder_load_bit_aligned: loaded\n" ));
976 return error;
977 }
978
979
980 static FT_Error
981 tt_sbit_decoder_load_compound( TT_SBitDecoder decoder,
982 FT_Byte* p,
983 FT_Byte* limit,
984 FT_Int x_pos,
985 FT_Int y_pos,
986 FT_UInt recurse_count )
987 {
989 FT_UInt num_components, nn;
990
991 FT_Char horiBearingX = (FT_Char)decoder->metrics->horiBearingX;
992 FT_Char horiBearingY = (FT_Char)decoder->metrics->horiBearingY;
993 FT_Byte horiAdvance = (FT_Byte)decoder->metrics->horiAdvance;
994 FT_Char vertBearingX = (FT_Char)decoder->metrics->vertBearingX;
995 FT_Char vertBearingY = (FT_Char)decoder->metrics->vertBearingY;
996 FT_Byte vertAdvance = (FT_Byte)decoder->metrics->vertAdvance;
997
998
999 if ( p + 2 > limit )
1000 goto Fail;
1001
1002 num_components = FT_NEXT_USHORT( p );
1003 if ( p + 4 * num_components > limit )
1004 {
1005 FT_TRACE1(( "tt_sbit_decoder_load_compound: broken table\n" ));
1006 goto Fail;
1007 }
1008
1009 FT_TRACE3(( "tt_sbit_decoder_load_compound: loading %d component%s\n",
1010 num_components,
1011 num_components == 1 ? "" : "s" ));
1012
1013 for ( nn = 0; nn < num_components; nn++ )
1014 {
1015 FT_UInt gindex = FT_NEXT_USHORT( p );
1016 FT_Char dx = FT_NEXT_CHAR( p );
1017 FT_Char dy = FT_NEXT_CHAR( p );
1018
1019
1020 /* NB: a recursive call */
1021 error = tt_sbit_decoder_load_image( decoder,
1022 gindex,
1023 x_pos + dx,
1024 y_pos + dy,
1025 recurse_count + 1,
1026 /* request full bitmap image */
1027 FALSE );
1028 if ( error )
1029 break;
1030 }
1031
1032 FT_TRACE3(( "tt_sbit_decoder_load_compound: done\n" ));
1033
1034 decoder->metrics->horiBearingX = horiBearingX;
1035 decoder->metrics->horiBearingY = horiBearingY;
1036 decoder->metrics->horiAdvance = horiAdvance;
1037 decoder->metrics->vertBearingX = vertBearingX;
1038 decoder->metrics->vertBearingY = vertBearingY;
1039 decoder->metrics->vertAdvance = vertAdvance;
1040 decoder->metrics->width = (FT_Byte)decoder->bitmap->width;
1041 decoder->metrics->height = (FT_Byte)decoder->bitmap->rows;
1042
1043 Exit:
1044 return error;
1045
1046 Fail:
1047 error = FT_THROW( Invalid_File_Format );
1048 goto Exit;
1049 }
1050
1051
1052#ifdef FT_CONFIG_OPTION_USE_PNG
1053
1054 static FT_Error
1055 tt_sbit_decoder_load_png( TT_SBitDecoder decoder,
1056 FT_Byte* p,
1057 FT_Byte* limit,
1058 FT_Int x_pos,
1059 FT_Int y_pos,
1060 FT_UInt recurse_count )
1061 {
1063 FT_ULong png_len;
1064
1065 FT_UNUSED( recurse_count );
1066
1067
1068 if ( limit - p < 4 )
1069 {
1070 FT_TRACE1(( "tt_sbit_decoder_load_png: broken bitmap\n" ));
1071 error = FT_THROW( Invalid_File_Format );
1072 goto Exit;
1073 }
1074
1075 png_len = FT_NEXT_ULONG( p );
1076 if ( (FT_ULong)( limit - p ) < png_len )
1077 {
1078 FT_TRACE1(( "tt_sbit_decoder_load_png: broken bitmap\n" ));
1079 error = FT_THROW( Invalid_File_Format );
1080 goto Exit;
1081 }
1082
1083 error = Load_SBit_Png( decoder->face->root.glyph,
1084 x_pos,
1085 y_pos,
1086 decoder->bit_depth,
1087 decoder->metrics,
1088 decoder->stream->memory,
1089 p,
1090 png_len,
1091 FALSE,
1092 FALSE );
1093
1094 Exit:
1095 if ( !error )
1096 FT_TRACE3(( "tt_sbit_decoder_load_png: loaded\n" ));
1097 return error;
1098 }
1099
1100#endif /* FT_CONFIG_OPTION_USE_PNG */
1101
1102
1103 static FT_Error
1104 tt_sbit_decoder_load_bitmap( TT_SBitDecoder decoder,
1105 FT_UInt glyph_format,
1106 FT_ULong glyph_start,
1107 FT_ULong glyph_size,
1108 FT_Int x_pos,
1109 FT_Int y_pos,
1110 FT_UInt recurse_count,
1111 FT_Bool metrics_only )
1112 {
1114 FT_Stream stream = decoder->stream;
1115 FT_Byte* p;
1116 FT_Byte* p_limit;
1117 FT_Byte* data;
1118
1119
1120 /* seek into the EBDT table now */
1121 if ( !glyph_size ||
1122 glyph_start + glyph_size > decoder->ebdt_size )
1123 {
1124 error = FT_THROW( Invalid_Argument );
1125 goto Exit;
1126 }
1127
1128 if ( FT_STREAM_SEEK( decoder->ebdt_start + glyph_start ) ||
1129 FT_FRAME_EXTRACT( glyph_size, data ) )
1130 goto Exit;
1131
1132 p = data;
1133 p_limit = p + glyph_size;
1134
1135 /* read the data, depending on the glyph format */
1136 switch ( glyph_format )
1137 {
1138 case 1:
1139 case 2:
1140 case 8:
1141 case 17:
1142 error = tt_sbit_decoder_load_metrics( decoder, &p, p_limit, 0 );
1143 break;
1144
1145 case 6:
1146 case 7:
1147 case 9:
1148 case 18:
1149 error = tt_sbit_decoder_load_metrics( decoder, &p, p_limit, 1 );
1150 break;
1151
1152 default:
1153 error = FT_Err_Ok;
1154 }
1155
1156 if ( error )
1157 goto Fail;
1158
1159 {
1160 TT_SBitDecoder_LoadFunc loader;
1161
1162
1163 switch ( glyph_format )
1164 {
1165 case 1:
1166 case 6:
1167 loader = tt_sbit_decoder_load_byte_aligned;
1168 break;
1169
1170 case 2:
1171 case 7:
1172 {
1173 /* Don't trust `glyph_format'. For example, Apple's main Korean */
1174 /* system font, `AppleMyungJo.ttf' (version 7.0d2e6), uses glyph */
1175 /* format 7, but the data is format 6. We check whether we have */
1176 /* an excessive number of bytes in the image: If it is equal to */
1177 /* the value for a byte-aligned glyph, use the other loading */
1178 /* routine. */
1179 /* */
1180 /* Note that for some (width,height) combinations, where the */
1181 /* width is not a multiple of 8, the sizes for bit- and */
1182 /* byte-aligned data are equal, for example (7,7) or (15,6). We */
1183 /* then prefer what `glyph_format' specifies. */
1184
1185 FT_UInt width = decoder->metrics->width;
1186 FT_UInt height = decoder->metrics->height;
1187
1188 FT_UInt bit_size = ( width * height + 7 ) >> 3;
1189 FT_UInt byte_size = height * ( ( width + 7 ) >> 3 );
1190
1191
1192 if ( bit_size < byte_size &&
1193 byte_size == (FT_UInt)( p_limit - p ) )
1194 loader = tt_sbit_decoder_load_byte_aligned;
1195 else
1196 loader = tt_sbit_decoder_load_bit_aligned;
1197 }
1198 break;
1199
1200 case 5:
1201 loader = tt_sbit_decoder_load_bit_aligned;
1202 break;
1203
1204 case 8:
1205 if ( p + 1 > p_limit )
1206 goto Fail;
1207
1208 p += 1; /* skip padding */
1209 /* fall-through */
1210
1211 case 9:
1212 loader = tt_sbit_decoder_load_compound;
1213 break;
1214
1215 case 17: /* small metrics, PNG image data */
1216 case 18: /* big metrics, PNG image data */
1217 case 19: /* metrics in EBLC, PNG image data */
1218#ifdef FT_CONFIG_OPTION_USE_PNG
1219 loader = tt_sbit_decoder_load_png;
1220 break;
1221#else
1222 error = FT_THROW( Unimplemented_Feature );
1223 goto Fail;
1224#endif /* FT_CONFIG_OPTION_USE_PNG */
1225
1226 default:
1227 error = FT_THROW( Invalid_Table );
1228 goto Fail;
1229 }
1230
1231 if ( !decoder->bitmap_allocated )
1232 {
1233 error = tt_sbit_decoder_alloc_bitmap( decoder, metrics_only );
1234
1235 if ( error )
1236 goto Fail;
1237 }
1238
1239 if ( metrics_only )
1240 goto Fail; /* this is not an error */
1241
1242 error = loader( decoder, p, p_limit, x_pos, y_pos, recurse_count );
1243 }
1244
1245 Fail:
1247
1248 Exit:
1249 return error;
1250 }
1251
1252
1253 static FT_Error
1254 tt_sbit_decoder_load_image( TT_SBitDecoder decoder,
1255 FT_UInt glyph_index,
1256 FT_Int x_pos,
1257 FT_Int y_pos,
1258 FT_UInt recurse_count,
1259 FT_Bool metrics_only )
1260 {
1261 FT_Byte* p = decoder->eblc_base + decoder->strike_index_array;
1262 FT_Byte* p_limit = decoder->eblc_limit;
1263 FT_ULong num_ranges = decoder->strike_index_count;
1264 FT_UInt start, end, index_format, image_format;
1265 FT_ULong image_start = 0, image_end = 0, image_offset;
1266
1267
1268 /* arbitrary recursion limit */
1269 if ( recurse_count > 100 )
1270 {
1271 FT_TRACE4(( "tt_sbit_decoder_load_image:"
1272 " recursion depth exceeded\n" ));
1273 goto Failure;
1274 }
1275
1276
1277 /* First, we find the correct strike range that applies to this */
1278 /* glyph index. */
1279 for ( ; num_ranges > 0; num_ranges-- )
1280 {
1281 start = FT_NEXT_USHORT( p );
1282 end = FT_NEXT_USHORT( p );
1283
1284 if ( glyph_index >= start && glyph_index <= end )
1285 goto FoundRange;
1286
1287 p += 4; /* ignore index offset */
1288 }
1289 goto NoBitmap;
1290
1291 FoundRange:
1292 image_offset = FT_NEXT_ULONG( p );
1293
1294 /* overflow check */
1295 p = decoder->eblc_base + decoder->strike_index_array;
1296 if ( image_offset > (FT_ULong)( p_limit - p ) )
1297 goto Failure;
1298
1299 p += image_offset;
1300 if ( p + 8 > p_limit )
1301 goto NoBitmap;
1302
1303 /* now find the glyph's location and extend within the ebdt table */
1304 index_format = FT_NEXT_USHORT( p );
1305 image_format = FT_NEXT_USHORT( p );
1306 image_offset = FT_NEXT_ULONG ( p );
1307
1308 switch ( index_format )
1309 {
1310 case 1: /* 4-byte offsets relative to `image_offset' */
1311 p += 4 * ( glyph_index - start );
1312 if ( p + 8 > p_limit )
1313 goto NoBitmap;
1314
1315 image_start = FT_NEXT_ULONG( p );
1316 image_end = FT_NEXT_ULONG( p );
1317
1318 if ( image_start == image_end ) /* missing glyph */
1319 goto NoBitmap;
1320 break;
1321
1322 case 2: /* big metrics, constant image size */
1323 {
1325
1326
1327 if ( p + 12 > p_limit )
1328 goto NoBitmap;
1329
1331
1332 if ( tt_sbit_decoder_load_metrics( decoder, &p, p_limit, 1 ) )
1333 goto NoBitmap;
1334
1335 image_start = image_size * ( glyph_index - start );
1336 image_end = image_start + image_size;
1337 }
1338 break;
1339
1340 case 3: /* 2-byte offsets relative to 'image_offset' */
1341 p += 2 * ( glyph_index - start );
1342 if ( p + 4 > p_limit )
1343 goto NoBitmap;
1344
1345 image_start = FT_NEXT_USHORT( p );
1346 image_end = FT_NEXT_USHORT( p );
1347
1348 if ( image_start == image_end ) /* missing glyph */
1349 goto NoBitmap;
1350 break;
1351
1352 case 4: /* sparse glyph array with (glyph,offset) pairs */
1353 {
1354 FT_ULong mm, num_glyphs;
1355
1356
1357 if ( p + 4 > p_limit )
1358 goto NoBitmap;
1359
1360 num_glyphs = FT_NEXT_ULONG( p );
1361
1362 /* overflow check for p + ( num_glyphs + 1 ) * 4 */
1363 if ( p + 4 > p_limit ||
1364 num_glyphs > (FT_ULong)( ( ( p_limit - p ) >> 2 ) - 1 ) )
1365 goto NoBitmap;
1366
1367 for ( mm = 0; mm < num_glyphs; mm++ )
1368 {
1369 FT_UInt gindex = FT_NEXT_USHORT( p );
1370
1371
1372 if ( gindex == glyph_index )
1373 {
1374 image_start = FT_NEXT_USHORT( p );
1375 p += 2;
1376 image_end = FT_PEEK_USHORT( p );
1377 break;
1378 }
1379 p += 2;
1380 }
1381
1382 if ( mm >= num_glyphs )
1383 goto NoBitmap;
1384 }
1385 break;
1386
1387 case 5: /* constant metrics with sparse glyph codes */
1388 case 19:
1389 {
1390 FT_ULong image_size, mm, num_glyphs;
1391
1392
1393 if ( p + 16 > p_limit )
1394 goto NoBitmap;
1395
1397
1398 if ( tt_sbit_decoder_load_metrics( decoder, &p, p_limit, 1 ) )
1399 goto NoBitmap;
1400
1401 num_glyphs = FT_NEXT_ULONG( p );
1402
1403 /* overflow check for p + 2 * num_glyphs */
1404 if ( num_glyphs > (FT_ULong)( ( p_limit - p ) >> 1 ) )
1405 goto NoBitmap;
1406
1407 for ( mm = 0; mm < num_glyphs; mm++ )
1408 {
1409 FT_UInt gindex = FT_NEXT_USHORT( p );
1410
1411
1412 if ( gindex == glyph_index )
1413 break;
1414 }
1415
1416 if ( mm >= num_glyphs )
1417 goto NoBitmap;
1418
1419 image_start = image_size * mm;
1420 image_end = image_start + image_size;
1421 }
1422 break;
1423
1424 default:
1425 goto NoBitmap;
1426 }
1427
1428 if ( image_start > image_end )
1429 goto NoBitmap;
1430
1431 image_end -= image_start;
1432 image_start = image_offset + image_start;
1433
1434 FT_TRACE3(( "tt_sbit_decoder_load_image:"
1435 " found sbit (format %d) for glyph index %d\n",
1436 image_format, glyph_index ));
1437
1438 return tt_sbit_decoder_load_bitmap( decoder,
1439 image_format,
1440 image_start,
1441 image_end,
1442 x_pos,
1443 y_pos,
1444 recurse_count,
1445 metrics_only );
1446
1447 Failure:
1448 return FT_THROW( Invalid_Table );
1449
1450 NoBitmap:
1451 if ( recurse_count )
1452 {
1453 FT_TRACE4(( "tt_sbit_decoder_load_image:"
1454 " missing subglyph sbit with glyph index %d\n",
1455 glyph_index ));
1456 return FT_THROW( Invalid_Composite );
1457 }
1458
1459 FT_TRACE4(( "tt_sbit_decoder_load_image:"
1460 " no sbit found for glyph index %d\n", glyph_index ));
1461 return FT_THROW( Missing_Bitmap );
1462 }
1463
1464
1465 static FT_Error
1466 tt_face_load_sbix_image( TT_Face face,
1467 FT_ULong strike_index,
1468 FT_UInt glyph_index,
1470 FT_Bitmap *map,
1472 FT_Bool metrics_only )
1473 {
1474 FT_UInt strike_offset, glyph_start, glyph_end;
1475 FT_Int originOffsetX, originOffsetY;
1476 FT_Tag graphicType;
1477 FT_Int recurse_depth = 0;
1478
1480 FT_Byte* p;
1481
1482 FT_UNUSED( map );
1483#ifndef FT_CONFIG_OPTION_USE_PNG
1484 FT_UNUSED( metrics_only );
1485#endif
1486
1487
1488 strike_index = face->sbit_strike_map[strike_index];
1489
1490 metrics->width = 0;
1491 metrics->height = 0;
1492
1493 p = face->sbit_table + 8 + 4 * strike_index;
1494 strike_offset = FT_NEXT_ULONG( p );
1495
1496 retry:
1497 if ( glyph_index > (FT_UInt)face->root.num_glyphs )
1498 return FT_THROW( Invalid_Argument );
1499
1500 if ( strike_offset >= face->ebdt_size ||
1501 face->ebdt_size - strike_offset < 4 + glyph_index * 4 + 8 )
1502 return FT_THROW( Invalid_File_Format );
1503
1504 if ( FT_STREAM_SEEK( face->ebdt_start +
1505 strike_offset + 4 +
1506 glyph_index * 4 ) ||
1507 FT_FRAME_ENTER( 8 ) )
1508 return error;
1509
1510 glyph_start = FT_GET_ULONG();
1511 glyph_end = FT_GET_ULONG();
1512
1513 FT_FRAME_EXIT();
1514
1515 if ( glyph_start == glyph_end )
1516 return FT_THROW( Missing_Bitmap );
1517 if ( glyph_start > glyph_end ||
1518 glyph_end - glyph_start < 8 ||
1519 face->ebdt_size - strike_offset < glyph_end )
1520 return FT_THROW( Invalid_File_Format );
1521
1522 if ( FT_STREAM_SEEK( face->ebdt_start + strike_offset + glyph_start ) ||
1523 FT_FRAME_ENTER( glyph_end - glyph_start ) )
1524 return error;
1525
1526 originOffsetX = FT_GET_SHORT();
1527 originOffsetY = FT_GET_SHORT();
1528
1529 graphicType = FT_GET_TAG4();
1530
1531 switch ( graphicType )
1532 {
1533 case FT_MAKE_TAG( 'd', 'u', 'p', 'e' ):
1534 if ( recurse_depth < 4 )
1535 {
1536 glyph_index = FT_GET_USHORT();
1537 FT_FRAME_EXIT();
1538 recurse_depth++;
1539 goto retry;
1540 }
1541 error = FT_THROW( Invalid_File_Format );
1542 break;
1543
1544 case FT_MAKE_TAG( 'p', 'n', 'g', ' ' ):
1545#ifdef FT_CONFIG_OPTION_USE_PNG
1546 error = Load_SBit_Png( face->root.glyph,
1547 0,
1548 0,
1549 32,
1550 metrics,
1551 stream->memory,
1552 stream->cursor,
1553 glyph_end - glyph_start - 8,
1554 TRUE,
1555 metrics_only );
1556#else
1557 error = FT_THROW( Unimplemented_Feature );
1558#endif
1559 break;
1560
1561 case FT_MAKE_TAG( 'j', 'p', 'g', ' ' ):
1562 case FT_MAKE_TAG( 't', 'i', 'f', 'f' ):
1563 case FT_MAKE_TAG( 'r', 'g', 'b', 'l' ): /* used on iOS 7.1 */
1564 error = FT_THROW( Unknown_File_Format );
1565 break;
1566
1567 default:
1568 error = FT_THROW( Unimplemented_Feature );
1569 break;
1570 }
1571
1572 FT_FRAME_EXIT();
1573
1574 if ( !error )
1575 {
1576 FT_Short abearing;
1577 FT_UShort aadvance;
1578
1579
1580 tt_face_get_metrics( face, FALSE, glyph_index, &abearing, &aadvance );
1581
1582 metrics->horiBearingX = (FT_Short)originOffsetX;
1583 metrics->horiBearingY = (FT_Short)( -originOffsetY + metrics->height );
1584 metrics->horiAdvance = (FT_UShort)( aadvance *
1585 face->root.size->metrics.x_ppem /
1586 face->header.Units_Per_EM );
1587 }
1588
1589 return error;
1590 }
1591
1594 FT_ULong strike_index,
1595 FT_UInt glyph_index,
1596 FT_UInt load_flags,
1598 FT_Bitmap *map,
1600 {
1602
1603
1604 switch ( (FT_UInt)face->sbit_table_type )
1605 {
1608 {
1609#ifdef __REACTOS__
1610 TT_SBitDecoderRec *decoder = malloc(sizeof(*decoder));
1611 if (!decoder)
1612 {
1613 error = FT_THROW( Out_Of_Memory );
1614 break;
1615 }
1616#else
1617 TT_SBitDecoderRec decoder[1];
1618#endif
1619
1620 error = tt_sbit_decoder_init( decoder, face, strike_index, metrics );
1621 if ( !error )
1622 {
1623 error = tt_sbit_decoder_load_image(
1624 decoder,
1625 glyph_index,
1626 0,
1627 0,
1628 0,
1629 ( load_flags & FT_LOAD_BITMAP_METRICS_ONLY ) != 0 );
1630 tt_sbit_decoder_done( decoder );
1631 }
1632#ifdef __REACTOS__
1633 free(decoder);
1634#endif
1635 }
1636 break;
1637
1639 error = tt_face_load_sbix_image(
1640 face,
1641 strike_index,
1642 glyph_index,
1643 stream,
1644 map,
1645 metrics,
1646 ( load_flags & FT_LOAD_BITMAP_METRICS_ONLY ) != 0 );
1647 break;
1648
1649 default:
1650 error = FT_THROW( Unknown_File_Format );
1651 break;
1652 }
1653
1654 /* Flatten color bitmaps if color was not requested. */
1655 if ( !error &&
1656 !( load_flags & FT_LOAD_COLOR ) &&
1657 !( load_flags & FT_LOAD_BITMAP_METRICS_ONLY ) &&
1658 map->pixel_mode == FT_PIXEL_MODE_BGRA )
1659 {
1660 FT_Bitmap new_map;
1661 FT_Library library = face->root.glyph->library;
1662
1663
1664 FT_Bitmap_Init( &new_map );
1665
1666 /* Convert to 8bit grayscale. */
1667 error = FT_Bitmap_Convert( library, map, &new_map, 1 );
1668 if ( error )
1669 FT_Bitmap_Done( library, &new_map );
1670 else
1671 {
1672 map->pixel_mode = new_map.pixel_mode;
1673 map->pitch = new_map.pitch;
1674 map->num_grays = new_map.num_grays;
1675
1676 ft_glyphslot_set_bitmap( face->root.glyph, new_map.buffer );
1677 face->root.glyph->internal->flags |= FT_GLYPH_OWN_BITMAP;
1678 }
1679 }
1680
1681 return error;
1682 }
1683
1684#else /* !TT_CONFIG_OPTION_EMBEDDED_BITMAPS */
1685
1686 /* ANSI C doesn't like empty source files */
1687 typedef int _tt_sbit_dummy;
1688
1689#endif /* !TT_CONFIG_OPTION_EMBEDDED_BITMAPS */
1690
1691
1692/* END */
FT_Library library
Definition: cffdrivr.c:660
Definition: _map.h:48
#define FT_LOCAL_DEF(x)
#define FT_LOCAL(x)
float rval
Definition: cylfrac.c:48
#define free
Definition: debug_ros.c:5
#define malloc
Definition: debug_ros.c:4
#define NULL
Definition: types.h:112
#define TRUE
Definition: types.h:120
#define FALSE
Definition: types.h:117
WORD face[3]
Definition: mesh.c:4747
static const WCHAR version[]
Definition: asmname.c:66
unsigned int(__cdecl typeof(jpeg_read_scanlines))(struct jpeg_decompress_struct *
Definition: typeof.h:31
int Fail
Definition: ehthrow.cxx:24
#define FT_LOAD_BITMAP_METRICS_ONLY
Definition: freetype.h:3039
FT_MulDiv(FT_Long a, FT_Long b, FT_Long c)
Definition: ftcalc.c:415
#define FT_LOAD_COLOR
Definition: freetype.h:3037
return FT_Err_Ok
Definition: ftbbox.c:526
FT_Bitmap_Convert(FT_Library library, const FT_Bitmap *source, FT_Bitmap *target, FT_Int alignment)
Definition: ftbitmap.c:523
FT_BEGIN_HEADER FT_Bitmap_Init(FT_Bitmap *abitmap)
Definition: ftbitmap.c:43
FT_Bitmap_Done(FT_Library library, FT_Bitmap *bitmap)
Definition: ftbitmap.c:1197
#define FT_ERROR(varformat)
Definition: ftdebug.h:211
#define FT_TRACE3(varformat)
Definition: ftdebug.h:190
#define FT_THROW(e)
Definition: ftdebug.h:243
#define FT_TRACE2(varformat)
Definition: ftdebug.h:189
#define FT_TRACE1(varformat)
Definition: ftdebug.h:188
#define FT_TRACE4(varformat)
Definition: ftdebug.h:191
@ FT_PIXEL_MODE_GRAY2
Definition: ftimage.h:185
@ FT_PIXEL_MODE_MONO
Definition: ftimage.h:183
@ FT_PIXEL_MODE_GRAY
Definition: ftimage.h:184
@ FT_PIXEL_MODE_BGRA
Definition: ftimage.h:189
@ FT_PIXEL_MODE_GRAY4
Definition: ftimage.h:186
FT_BEGIN_HEADER typedef signed long FT_Pos
Definition: ftimage.h:57
FT_Match_Size(FT_Face face, FT_Size_Request req, FT_Bool ignore_width, FT_ULong *size_index)
Definition: ftobjs.c:2939
#define FT_GLYPH_OWN_BITMAP
Definition: ftobjs.h:421
ft_glyphslot_alloc_bitmap(FT_GlyphSlot slot, FT_ULong size)
Definition: ftobjs.c:514
ft_glyphslot_set_bitmap(FT_GlyphSlot slot, FT_Byte *buffer)
Definition: ftobjs.c:502
#define FT_FRAME_ENTER(size)
Definition: ftstream.h:548
#define FT_GET_ULONG()
Definition: ftstream.h:315
#define FT_FRAME_RELEASE(bytes)
Definition: ftstream.h:562
#define FT_STREAM_SEEK(position)
Definition: ftstream.h:525
#define FT_NEXT_USHORT(buffer)
Definition: ftstream.h:244
#define FT_STREAM_POS()
Definition: ftstream.h:522
#define FT_NEXT_CHAR(buffer)
Definition: ftstream.h:235
#define FT_GET_SHORT()
Definition: ftstream.h:310
#define FT_PEEK_USHORT(p)
Definition: ftstream.h:186
#define FT_NEXT_LONG(buffer)
Definition: ftstream.h:253
#define FT_GET_TAG4()
Definition: ftstream.h:316
#define FT_FRAME_EXIT()
Definition: ftstream.h:553
#define FT_FRAME_EXTRACT(size, bytes)
Definition: ftstream.h:556
#define FT_NEXT_ULONG(buffer)
Definition: ftstream.h:256
#define FT_GET_USHORT()
Definition: ftstream.h:311
signed char FT_Char
Definition: fttypes.h:143
FT_BEGIN_HEADER typedef unsigned char FT_Bool
Definition: fttypes.h:108
FT_UInt32 FT_Tag
Definition: fttypes.h:176
unsigned long FT_ULong
Definition: fttypes.h:253
unsigned char FT_Byte
Definition: fttypes.h:154
signed long FT_Fixed
Definition: fttypes.h:287
int FT_Error
Definition: fttypes.h:299
#define FT_ERR(e)
Definition: fttypes.h:599
unsigned short FT_UShort
Definition: fttypes.h:209
signed short FT_Short
Definition: fttypes.h:198
unsigned int FT_UInt
Definition: fttypes.h:231
#define FT_MAKE_TAG(_x1, _x2, _x3, _x4)
Definition: fttypes.h:488
signed int FT_Int
Definition: fttypes.h:220
GLuint start
Definition: gl.h:1545
GLuint GLuint GLsizei count
Definition: gl.h:1545
GLuint GLuint end
Definition: gl.h:1545
GLint GLenum GLsizei GLsizei GLsizei GLint GLsizei const GLvoid * data
Definition: gl.h:1950
GLint GLint GLsizei GLsizei height
Definition: gl.h:1546
GLint GLint GLsizei width
Definition: gl.h:1546
GLsizeiptr size
Definition: glext.h:5919
GLintptr offset
Definition: glext.h:5920
GLenum GLuint GLint GLenum face
Definition: glext.h:7025
GLsizei GLenum const GLvoid GLuint GLsizei GLfloat * metrics
Definition: glext.h:11745
GLint limit
Definition: glext.h:10326
GLbitfield flags
Definition: glext.h:7161
GLfloat GLfloat p
Definition: glext.h:8902
GLubyte GLubyte GLubyte GLubyte w
Definition: glext.h:6102
GLfloat GLfloat GLfloat GLfloat h
Definition: glext.h:7723
const char cursor[]
Definition: icontest.c:13
GLint dy
Definition: linetemp.h:97
if(dx< 0)
Definition: linetemp.h:194
GLint dx
Definition: linetemp.h:97
static GLint image_size(GLint width, GLint height, GLenum format, GLenum type)
Definition: mipmap.c:4858
#define error(str)
Definition: mkdosfs.c:1605
static char memory[1024 *256]
Definition: process.c:122
ssize_t pwrite(int fd, const void *buf, size_t count, off_t offset)
#define FT_UNUSED(arg)
LOCAL int table_size
Definition: write.c:65
static void Exit(void)
Definition: sock.c:1330
unsigned short num_grays
Definition: ftimage.h:266
unsigned char * buffer
Definition: ftimage.h:265
unsigned char pixel_mode
Definition: ftimage.h:267
int pitch
Definition: ftimage.h:264
FT_UShort advance_Width_Max
Definition: tttables.h:207
FT_Short Line_Gap
Definition: tttables.h:205
FT_Short Ascender
Definition: tttables.h:203
FT_Short Descender
Definition: tttables.h:204
Definition: uimain.c:89
uint32 width
Definition: uimain.c:91
Definition: parser.c:49
Definition: parse.h:23
else
Definition: tritemp.h:161
tt_face_get_metrics(TT_Face face, FT_Bool vertical, FT_UInt gindex, FT_Short *abearing, FT_UShort *aadvance)
Definition: ttmtx.c:228
int _tt_sbit_dummy
Definition: ttsbit.c:1687
tt_face_load_sbit_image(TT_Face face, FT_ULong strike_index, FT_UInt glyph_index, FT_UInt load_flags, FT_Stream stream, FT_Bitmap *map, TT_SBit_MetricsRec *metrics)
tt_face_set_sbit_strike(TT_Face face, FT_Size_Request req, FT_ULong *astrike_index)
tt_face_load_strike_metrics(TT_Face face, FT_ULong strike_index, FT_Size_Metrics *metrics)
FT_BEGIN_HEADER tt_face_load_sbit(TT_Face face, FT_Stream stream)
tt_face_free_sbit(TT_Face face)
#define TTAG_EBLC
Definition: tttags.h:54
#define TTAG_EBDT
Definition: tttags.h:53
#define TTAG_bdat
Definition: tttags.h:37
#define TTAG_CBDT
Definition: tttags.h:42
#define TTAG_CBLC
Definition: tttags.h:43
#define TTAG_sbix
Definition: tttags.h:95
#define TTAG_bloc
Definition: tttags.h:40
@ TT_SBIT_TABLE_TYPE_CBLC
Definition: tttypes.h:1112
@ TT_SBIT_TABLE_TYPE_NONE
Definition: tttypes.h:1109
@ TT_SBIT_TABLE_TYPE_SBIX
Definition: tttypes.h:1113
@ TT_SBIT_TABLE_TYPE_EBLC
Definition: tttypes.h:1110