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