Visualization Library 2.0.0-b5

A lightweight C++ OpenGL middleware for 2D/3D graphics

VL     Star     Watch     Fork     Issue

[Download] [Tutorials] [All Classes] [Grouped Classes]
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-2009, 2013 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  {
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 = FT_THROW( 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 = FT_THROW( 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 FT_THROW( 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 FT_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;
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
182  tt_sbit_decoder_init( TT_SBitDecoder decoder,
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 = FT_THROW( 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 = FT_THROW( Invalid_File_Format );
235  }
236 
237  Exit:
238  return error;
239  }
240 
241 
242  static void
243  tt_sbit_decoder_done( TT_SBitDecoder decoder )
244  {
245  FT_UNUSED( decoder );
246  }
247 
248 
249  static FT_Error
250  tt_sbit_decoder_alloc_bitmap( TT_SBitDecoder decoder )
251  {
254  FT_Bitmap* map = decoder->bitmap;
255  FT_Long size;
256 
257 
258  if ( !decoder->metrics_loaded )
259  {
260  error = FT_THROW( 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 = FT_THROW( 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
315  tt_sbit_decoder_load_metrics( TT_SBitDecoder decoder,
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 FT_Err_Ok;
349 
350  Fail:
351  return FT_THROW( Invalid_Argument );
352  }
353 
354 
355  /* forward declaration */
356  static FT_Error
357  tt_sbit_decoder_load_image( TT_SBitDecoder decoder,
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
370  tt_sbit_decoder_load_byte_aligned( TT_SBitDecoder decoder,
371  FT_Byte* p,
372  FT_Byte* limit,
373  FT_Int x_pos,
374  FT_Int y_pos )
375  {
377  FT_Byte* line;
378  FT_Int bit_height, bit_width, pitch, width, height, line_bits, 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  line_bits = width * decoder->bit_depth;
400 
401  if ( x_pos < 0 || x_pos + width > bit_width ||
402  y_pos < 0 || y_pos + height > bit_height )
403  {
404  error = FT_THROW( Invalid_File_Format );
405  goto Exit;
406  }
407 
408  if ( p + ( ( line_bits + 7 ) >> 3 ) * height > limit )
409  {
410  error = FT_THROW( Invalid_File_Format );
411  goto Exit;
412  }
413 
414  /* now do the blit */
415  line += y_pos * pitch + ( x_pos >> 3 );
416  x_pos &= 7;
417 
418  if ( x_pos == 0 ) /* the easy one */
419  {
420  for ( h = height; h > 0; h--, line += pitch )
421  {
422  FT_Byte* write = line;
423  FT_Int w;
424 
425 
426  for ( w = line_bits; w >= 8; w -= 8 )
427  {
428  write[0] = (FT_Byte)( write[0] | *p++ );
429  write += 1;
430  }
431 
432  if ( w > 0 )
433  write[0] = (FT_Byte)( write[0] | ( *p++ & ( 0xFF00U >> w ) ) );
434  }
435  }
436  else /* x_pos > 0 */
437  {
438  for ( h = height; h > 0; h--, line += pitch )
439  {
440  FT_Byte* write = line;
441  FT_Int w;
442  FT_UInt wval = 0;
443 
444 
445  for ( w = line_bits; w >= 8; w -= 8 )
446  {
447  wval = (FT_UInt)( wval | *p++ );
448  write[0] = (FT_Byte)( write[0] | ( wval >> x_pos ) );
449  write += 1;
450  wval <<= 8;
451  }
452 
453  if ( w > 0 )
454  wval = (FT_UInt)( wval | ( *p++ & ( 0xFF00U >> w ) ) );
455 
456  /* all bits read and there are `x_pos + w' bits to be written */
457 
458  write[0] = (FT_Byte)( write[0] | ( wval >> x_pos ) );
459 
460  if ( x_pos + w > 8 )
461  {
462  write++;
463  wval <<= 8;
464  write[0] = (FT_Byte)( write[0] | ( wval >> x_pos ) );
465  }
466  }
467  }
468 
469  Exit:
470  return error;
471  }
472 
473 
474  /*
475  * Load a bit-aligned bitmap (with pointer `p') into a line-aligned bitmap
476  * (with pointer `write'). In the example below, the width is 3 pixel,
477  * and `x_pos' is 1 pixel.
478  *
479  * p p+1
480  * | | |
481  * | 7 6 5 4 3 2 1 0 | 7 6 5 4 3 2 1 0 |...
482  * | | |
483  * +-------+ +-------+ +-------+ ...
484  * . . .
485  * . . .
486  * v . .
487  * +-------+ . .
488  * | | .
489  * | 7 6 5 4 3 2 1 0 | .
490  * | | .
491  * write . .
492  * . .
493  * v .
494  * +-------+ .
495  * | |
496  * | 7 6 5 4 3 2 1 0 |
497  * | |
498  * write+1 .
499  * .
500  * v
501  * +-------+
502  * | |
503  * | 7 6 5 4 3 2 1 0 |
504  * | |
505  * write+2
506  *
507  */
508 
509  static FT_Error
510  tt_sbit_decoder_load_bit_aligned( TT_SBitDecoder decoder,
511  FT_Byte* p,
512  FT_Byte* limit,
513  FT_Int x_pos,
514  FT_Int y_pos )
515  {
517  FT_Byte* line;
518  FT_Int bit_height, bit_width, pitch, width, height, line_bits, h, nbits;
519  FT_Bitmap* bitmap;
520  FT_UShort rval;
521 
522 
523  if ( !decoder->bitmap_allocated )
524  {
525  error = tt_sbit_decoder_alloc_bitmap( decoder );
526  if ( error )
527  goto Exit;
528  }
529 
530  /* check that we can write the glyph into the bitmap */
531  bitmap = decoder->bitmap;
532  bit_width = bitmap->width;
533  bit_height = bitmap->rows;
534  pitch = bitmap->pitch;
535  line = bitmap->buffer;
536 
537  width = decoder->metrics->width;
538  height = decoder->metrics->height;
539 
540  line_bits = width * decoder->bit_depth;
541 
542  if ( x_pos < 0 || x_pos + width > bit_width ||
543  y_pos < 0 || y_pos + height > bit_height )
544  {
545  error = FT_THROW( Invalid_File_Format );
546  goto Exit;
547  }
548 
549  if ( p + ( ( line_bits * height + 7 ) >> 3 ) > limit )
550  {
551  error = FT_THROW( Invalid_File_Format );
552  goto Exit;
553  }
554 
555  /* now do the blit */
556 
557  /* adjust `line' to point to the first byte of the bitmap */
558  line += y_pos * pitch + ( x_pos >> 3 );
559  x_pos &= 7;
560 
561  /* the higher byte of `rval' is used as a buffer */
562  rval = 0;
563  nbits = 0;
564 
565  for ( h = height; h > 0; h--, line += pitch )
566  {
567  FT_Byte* write = line;
568  FT_Int w = line_bits;
569 
570 
571  /* handle initial byte (in target bitmap) specially if necessary */
572  if ( x_pos )
573  {
574  w = ( line_bits < 8 - x_pos ) ? line_bits : 8 - x_pos;
575 
576  if ( h == height )
577  {
578  rval = *p++;
579  nbits = x_pos;
580  }
581  else if ( nbits < w )
582  {
583  if ( p < limit )
584  rval |= *p++;
585  nbits += 8 - w;
586  }
587  else
588  {
589  rval >>= 8;
590  nbits -= w;
591  }
592 
593  *write++ |= ( ( rval >> nbits ) & 0xFF ) &
594  ( ~( 0xFF << w ) << ( 8 - w - x_pos ) );
595  rval <<= 8;
596 
597  w = line_bits - w;
598  }
599 
600  /* handle medial bytes */
601  for ( ; w >= 8; w -= 8 )
602  {
603  rval |= *p++;
604  *write++ |= ( rval >> nbits ) & 0xFF;
605 
606  rval <<= 8;
607  }
608 
609  /* handle final byte if necessary */
610  if ( w > 0 )
611  {
612  if ( nbits < w )
613  {
614  if ( p < limit )
615  rval |= *p++;
616  *write |= ( ( rval >> nbits ) & 0xFF ) & ( 0xFF00U >> w );
617  nbits += 8 - w;
618 
619  rval <<= 8;
620  }
621  else
622  {
623  *write |= ( ( rval >> nbits ) & 0xFF ) & ( 0xFF00U >> w );
624  nbits -= w;
625  }
626  }
627  }
628 
629  Exit:
630  return error;
631  }
632 
633 
634  static FT_Error
635  tt_sbit_decoder_load_compound( TT_SBitDecoder decoder,
636  FT_Byte* p,
637  FT_Byte* limit,
638  FT_Int x_pos,
639  FT_Int y_pos )
640  {
642  FT_UInt num_components, nn;
643 
644  FT_Char horiBearingX = decoder->metrics->horiBearingX;
645  FT_Char horiBearingY = decoder->metrics->horiBearingY;
646  FT_Byte horiAdvance = decoder->metrics->horiAdvance;
647  FT_Char vertBearingX = decoder->metrics->vertBearingX;
648  FT_Char vertBearingY = decoder->metrics->vertBearingY;
649  FT_Byte vertAdvance = decoder->metrics->vertAdvance;
650 
651 
652  if ( p + 2 > limit )
653  goto Fail;
654 
655  num_components = FT_NEXT_USHORT( p );
656  if ( p + 4 * num_components > limit )
657  goto Fail;
658 
659  if ( !decoder->bitmap_allocated )
660  {
661  error = tt_sbit_decoder_alloc_bitmap( decoder );
662  if ( error )
663  goto Exit;
664  }
665 
666  for ( nn = 0; nn < num_components; nn++ )
667  {
668  FT_UInt gindex = FT_NEXT_USHORT( p );
669  FT_Byte dx = FT_NEXT_BYTE( p );
670  FT_Byte dy = FT_NEXT_BYTE( p );
671 
672 
673  /* NB: a recursive call */
674  error = tt_sbit_decoder_load_image( decoder, gindex,
675  x_pos + dx, y_pos + dy );
676  if ( error )
677  break;
678  }
679 
680  decoder->metrics->horiBearingX = horiBearingX;
681  decoder->metrics->horiBearingY = horiBearingY;
682  decoder->metrics->horiAdvance = horiAdvance;
683  decoder->metrics->vertBearingX = vertBearingX;
684  decoder->metrics->vertBearingY = vertBearingY;
685  decoder->metrics->vertAdvance = vertAdvance;
686  decoder->metrics->width = (FT_UInt)decoder->bitmap->width;
687  decoder->metrics->height = (FT_UInt)decoder->bitmap->rows;
688 
689  Exit:
690  return error;
691 
692  Fail:
693  error = FT_THROW( Invalid_File_Format );
694  goto Exit;
695  }
696 
697 
698  static FT_Error
699  tt_sbit_decoder_load_bitmap( TT_SBitDecoder decoder,
700  FT_UInt glyph_format,
701  FT_ULong glyph_start,
702  FT_ULong glyph_size,
703  FT_Int x_pos,
704  FT_Int y_pos )
705  {
706  FT_Error error;
707  FT_Stream stream = decoder->stream;
708  FT_Byte* p;
709  FT_Byte* p_limit;
710  FT_Byte* data;
711 
712 
713  /* seek into the EBDT table now */
714  if ( glyph_start + glyph_size > decoder->ebdt_size )
715  {
716  error = FT_THROW( Invalid_Argument );
717  goto Exit;
718  }
719 
720  if ( FT_STREAM_SEEK( decoder->ebdt_start + glyph_start ) ||
721  FT_FRAME_EXTRACT( glyph_size, data ) )
722  goto Exit;
723 
724  p = data;
725  p_limit = p + glyph_size;
726 
727  /* read the data, depending on the glyph format */
728  switch ( glyph_format )
729  {
730  case 1:
731  case 2:
732  case 8:
733  error = tt_sbit_decoder_load_metrics( decoder, &p, p_limit, 0 );
734  break;
735 
736  case 6:
737  case 7:
738  case 9:
739  error = tt_sbit_decoder_load_metrics( decoder, &p, p_limit, 1 );
740  break;
741 
742  default:
743  error = FT_Err_Ok;
744  }
745 
746  if ( error )
747  goto Fail;
748 
749  {
751 
752 
753  switch ( glyph_format )
754  {
755  case 1:
756  case 6:
757  loader = tt_sbit_decoder_load_byte_aligned;
758  break;
759 
760  case 2:
761  case 5:
762  case 7:
763  loader = tt_sbit_decoder_load_bit_aligned;
764  break;
765 
766  case 8:
767  if ( p + 1 > p_limit )
768  goto Fail;
769 
770  p += 1; /* skip padding */
771  /* fall-through */
772 
773  case 9:
774  loader = tt_sbit_decoder_load_compound;
775  break;
776 
777  default:
778  goto Fail;
779  }
780 
781  error = loader( decoder, p, p_limit, x_pos, y_pos );
782  }
783 
784  Fail:
785  FT_FRAME_RELEASE( data );
786 
787  Exit:
788  return error;
789  }
790 
791 
792  static FT_Error
793  tt_sbit_decoder_load_image( TT_SBitDecoder decoder,
794  FT_UInt glyph_index,
795  FT_Int x_pos,
796  FT_Int y_pos )
797  {
798  /*
799  * First, we find the correct strike range that applies to this
800  * glyph index.
801  */
802 
803  FT_Byte* p = decoder->eblc_base + decoder->strike_index_array;
804  FT_Byte* p_limit = decoder->eblc_limit;
805  FT_ULong num_ranges = decoder->strike_index_count;
806  FT_UInt start, end, index_format, image_format;
807  FT_ULong image_start = 0, image_end = 0, image_offset;
808 
809 
810  for ( ; num_ranges > 0; num_ranges-- )
811  {
812  start = FT_NEXT_USHORT( p );
813  end = FT_NEXT_USHORT( p );
814 
815  if ( glyph_index >= start && glyph_index <= end )
816  goto FoundRange;
817 
818  p += 4; /* ignore index offset */
819  }
820  goto NoBitmap;
821 
822  FoundRange:
823  image_offset = FT_NEXT_ULONG( p );
824 
825  /* overflow check */
826  p = decoder->eblc_base + decoder->strike_index_array;
827  if ( image_offset > (FT_ULong)( p_limit - p ) )
828  goto Failure;
829 
830  p += image_offset;
831  if ( p + 8 > p_limit )
832  goto NoBitmap;
833 
834  /* now find the glyph's location and extend within the ebdt table */
835  index_format = FT_NEXT_USHORT( p );
836  image_format = FT_NEXT_USHORT( p );
837  image_offset = FT_NEXT_ULONG ( p );
838 
839  switch ( index_format )
840  {
841  case 1: /* 4-byte offsets relative to `image_offset' */
842  {
843  p += 4 * ( glyph_index - start );
844  if ( p + 8 > p_limit )
845  goto NoBitmap;
846 
847  image_start = FT_NEXT_ULONG( p );
848  image_end = FT_NEXT_ULONG( p );
849 
850  if ( image_start == image_end ) /* missing glyph */
851  goto NoBitmap;
852  }
853  break;
854 
855  case 2: /* big metrics, constant image size */
856  {
857  FT_ULong image_size;
858 
859 
860  if ( p + 12 > p_limit )
861  goto NoBitmap;
862 
863  image_size = FT_NEXT_ULONG( p );
864 
865  if ( tt_sbit_decoder_load_metrics( decoder, &p, p_limit, 1 ) )
866  goto NoBitmap;
867 
868  image_start = image_size * ( glyph_index - start );
869  image_end = image_start + image_size;
870  }
871  break;
872 
873  case 3: /* 2-byte offsets relative to 'image_offset' */
874  {
875  p += 2 * ( glyph_index - start );
876  if ( p + 4 > p_limit )
877  goto NoBitmap;
878 
879  image_start = FT_NEXT_USHORT( p );
880  image_end = FT_NEXT_USHORT( p );
881 
882  if ( image_start == image_end ) /* missing glyph */
883  goto NoBitmap;
884  }
885  break;
886 
887  case 4: /* sparse glyph array with (glyph,offset) pairs */
888  {
889  FT_ULong mm, num_glyphs;
890 
891 
892  if ( p + 4 > p_limit )
893  goto NoBitmap;
894 
895  num_glyphs = FT_NEXT_ULONG( p );
896 
897  /* overflow check for p + ( num_glyphs + 1 ) * 4 */
898  if ( num_glyphs > (FT_ULong)( ( ( p_limit - p ) >> 2 ) - 1 ) )
899  goto NoBitmap;
900 
901  for ( mm = 0; mm < num_glyphs; mm++ )
902  {
903  FT_UInt gindex = FT_NEXT_USHORT( p );
904 
905 
906  if ( gindex == glyph_index )
907  {
908  image_start = FT_NEXT_USHORT( p );
909  p += 2;
910  image_end = FT_PEEK_USHORT( p );
911  break;
912  }
913  p += 2;
914  }
915 
916  if ( mm >= num_glyphs )
917  goto NoBitmap;
918  }
919  break;
920 
921  case 5: /* constant metrics with sparse glyph codes */
922  {
923  FT_ULong image_size, mm, num_glyphs;
924 
925 
926  if ( p + 16 > p_limit )
927  goto NoBitmap;
928 
929  image_size = FT_NEXT_ULONG( p );
930 
931  if ( tt_sbit_decoder_load_metrics( decoder, &p, p_limit, 1 ) )
932  goto NoBitmap;
933 
934  num_glyphs = FT_NEXT_ULONG( p );
935 
936  /* overflow check for p + 2 * num_glyphs */
937  if ( num_glyphs > (FT_ULong)( ( p_limit - p ) >> 1 ) )
938  goto NoBitmap;
939 
940  for ( mm = 0; mm < num_glyphs; mm++ )
941  {
942  FT_UInt gindex = FT_NEXT_USHORT( p );
943 
944 
945  if ( gindex == glyph_index )
946  break;
947  }
948 
949  if ( mm >= num_glyphs )
950  goto NoBitmap;
951 
952  image_start = image_size * mm;
953  image_end = image_start + image_size;
954  }
955  break;
956 
957  default:
958  goto NoBitmap;
959  }
960 
961  if ( image_start > image_end )
962  goto NoBitmap;
963 
964  image_end -= image_start;
965  image_start = image_offset + image_start;
966 
967  return tt_sbit_decoder_load_bitmap( decoder,
968  image_format,
969  image_start,
970  image_end,
971  x_pos,
972  y_pos );
973 
974  Failure:
975  return FT_THROW( Invalid_Table );
976 
977  NoBitmap:
978  return FT_THROW( Invalid_Argument );
979  }
980 
981 
982  FT_LOCAL( FT_Error )
984  FT_ULong strike_index,
985  FT_UInt glyph_index,
986  FT_UInt load_flags,
987  FT_Stream stream,
988  FT_Bitmap *map,
989  TT_SBit_MetricsRec *metrics )
990  {
991  TT_SBitDecoderRec decoder[1];
992  FT_Error error;
993 
994  FT_UNUSED( load_flags );
995  FT_UNUSED( stream );
996  FT_UNUSED( map );
997 
998 
999  error = tt_sbit_decoder_init( decoder, face, strike_index, metrics );
1000  if ( !error )
1001  {
1002  error = tt_sbit_decoder_load_image( decoder, glyph_index, 0, 0 );
1003  tt_sbit_decoder_done( decoder );
1004  }
1005 
1006  return error;
1007  }
1008 
1009 /* EOF */
GLint GLint GLsizei GLsizei height
int FT_Error
Definition: fttypes.h:296
GLuint GLuint stream
signed long FT_Long
Definition: fttypes.h:238
unsigned long FT_ULong
Definition: fttypes.h:249
GLfloat GLfloat p
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:983
int write(int fd, const char *buf, int nbytes)
Definition: tif_acorn.c:325
FT_Char horiBearingY
Definition: tttypes.h:441
signed int FT_Int
Definition: fttypes.h:216
int rows
Definition: ftimage.h:312
FT_Short ascender
Definition: freetype.h:946
FT_Byte horiAdvance
Definition: tttypes.h:442
GLfloat GLfloat GLfloat GLfloat h
return FT_THROW(Missing_Property)
#define FT_NEXT_BYTE(buffer)
Definition: ftstream.h:220
#define FT_UNUSED(arg)
Definition: ftconfig.h:76
unsigned char * buffer
Definition: ftimage.h:315
signed char FT_Char
Definition: fttypes.h:139
GLuint start
GLint GLint GLsizei width
tt_face_free_eblc(TT_Face face)
Definition: ttsbit0.c:110
int pitch
Definition: ftimage.h:314
return FT_Err_Ok
Definition: ftbbox.c:645
TT_Loader_GotoTableFunc goto_table
Definition: tttypes.h:1288
#define TTAG_EBLC
Definition: tttags.h:50
FT_BEGIN_HEADER typedef unsigned char FT_Bool
Definition: fttypes.h:104
GLenum GLuint GLint GLenum face
#define FT_ERROR(varformat)
Definition: ftdebug.h:181
unsigned char FT_Byte
Definition: fttypes.h:150
struct TT_SBitDecoderRec_ TT_SBitDecoderRec
FT_Bitmap bitmap
Definition: freetype.h:1627
FT_Match_Size(FT_Face face, FT_Size_Request req, FT_Bool ignore_width, FT_ULong *size_index)
Definition: ftobjs.c:2491
FT_Char horiBearingX
Definition: tttypes.h:440
FT_Byte * sbit_table
Definition: tttypes.h:1413
#define FT_LOCAL(x)
Definition: ftconfig.h:235
FT_Error error
Definition: cffdrivr.c:411
FT_Char vertBearingX
Definition: tttypes.h:444
ft_glyphslot_alloc_bitmap(FT_GlyphSlot slot, FT_ULong size)
Definition: ftobjs.c:306
GLsizei GLsizei GLenum GLenum const GLvoid * data
#define TTAG_bdat
Definition: tttags.h:38
#define TTAG_bloc
Definition: tttags.h:41
FT_Char vertBearingY
Definition: tttypes.h:445
register bit_buf_type register int int nbits
Definition: jdhuff.h:155
FT_ULong sbit_table_size
Definition: tttypes.h:1414
int const char * version
Definition: zlib.h:813
#define FT_PEEK_USHORT(p)
Definition: ftstream.h:171
GLuint GLuint end
struct TT_SBitDecoderRec_ * TT_SBitDecoder
int width
Definition: ftimage.h:313
tt_face_load_strike_metrics(TT_Face face, FT_ULong strike_index, FT_Size_Metrics *metrics)
Definition: ttsbit0.c:131
FT_FaceRec root
Definition: tttypes.h:1260
#define FT_STREAM_SEEK(position)
Definition: ftstream.h:489
#define FT_NEXT_USHORT(buffer)
Definition: ftstream.h:226
#define FT_FRAME_RELEASE(bytes)
Definition: ftstream.h:522
#define FT_TRACE3(varformat)
Definition: ftdebug.h:160
typedef int
Definition: png.h:978
#define FT_STREAM_POS()
Definition: ftstream.h:486
GLubyte GLubyte GLubyte GLubyte w
signed long FT_Fixed
Definition: fttypes.h:284
FT_GlyphSlot glyph
Definition: freetype.h:956
unsigned int FT_UInt
Definition: fttypes.h:227
#define FT_NEXT_ULONG(buffer)
Definition: ftstream.h:238
#define FT_FRAME_EXTRACT(size, bytes)
Definition: ftstream.h:517
char pixel_mode
Definition: ftimage.h:317
GLuint GLuint GLsizei count
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
tt_face_load_eblc(TT_Face face, FT_Stream stream)
Definition: ttsbit0.c:43
GLsizei GLenum const GLvoid GLuint GLsizei GLfloat * metrics
unsigned short FT_UShort
Definition: fttypes.h:205
FT_Stream stream
Definition: freetype.h:964
GLsizeiptr size
int bit_depth
Definition: readpng.c:72
GLint limit
tt_face_set_sbit_strike(TT_Face face, FT_Size_Request req, FT_ULong *astrike_index)
Definition: ttsbit0.c:122
FT_Byte vertAdvance
Definition: tttypes.h:446
#define FT_LOCAL_DEF(x)
Definition: ftconfig.h:236
#define TTAG_EBDT
Definition: tttags.h:49