zenilib  0.5.3.0
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Groups Pages
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 1996-2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, */
8 /* 2010 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 #include <ft2build.h>
20 #include FT_INTERNAL_DEBUG_H
21 #include FT_INTERNAL_STREAM_H
22 #include FT_TRUETYPE_TAGS_H
23 
24  /*
25  * Alas, the memory-optimized sbit loader can't be used when implementing
26  * the `old internals' hack
27  */
28 #ifndef FT_CONFIG_OPTION_OLD_INTERNALS
29 
30 #include "ttsbit0.c"
31 
32 #else /* FT_CONFIG_OPTION_OLD_INTERNALS */
33 
34 #include <ft2build.h>
35 #include FT_INTERNAL_DEBUG_H
36 #include FT_INTERNAL_STREAM_H
37 #include FT_TRUETYPE_TAGS_H
38 #include "ttsbit.h"
39 
40 #include "sferrors.h"
41 
42 
43  /*************************************************************************/
44  /* */
45  /* The macro FT_COMPONENT is used in trace mode. It is an implicit */
46  /* parameter of the FT_TRACE() and FT_ERROR() macros, used to print/log */
47  /* messages during execution. */
48  /* */
49 #undef FT_COMPONENT
50 #define FT_COMPONENT trace_ttsbit
51 
52 
53  /*************************************************************************/
54  /* */
55  /* <Function> */
56  /* blit_sbit */
57  /* */
58  /* <Description> */
59  /* Blits a bitmap from an input stream into a given target. Supports */
60  /* x and y offsets as well as byte padded lines. */
61  /* */
62  /* <Input> */
63  /* target :: The target bitmap/pixmap. */
64  /* */
65  /* source :: The input packed bitmap data. */
66  /* */
67  /* line_bits :: The number of bits per line. */
68  /* */
69  /* byte_padded :: A flag which is true if lines are byte-padded. */
70  /* */
71  /* x_offset :: The horizontal offset. */
72  /* */
73  /* y_offset :: The vertical offset. */
74  /* */
75  /* <Note> */
76  /* IMPORTANT: The x and y offsets are relative to the top corner of */
77  /* the target bitmap (unlike the normal TrueType */
78  /* convention). A positive y offset indicates a downwards */
79  /* direction! */
80  /* */
81  static void
82  blit_sbit( FT_Bitmap* target,
83  FT_Byte* source,
84  FT_Int line_bits,
85  FT_Bool byte_padded,
86  FT_Int x_offset,
87  FT_Int y_offset,
88  FT_Int source_height )
89  {
90  FT_Byte* line_buff;
91  FT_Int line_incr;
92  FT_Int height;
93 
94  FT_UShort acc;
95  FT_UInt loaded;
96 
97 
98  /* first of all, compute starting write position */
99  line_incr = target->pitch;
100  line_buff = target->buffer;
101 
102  if ( line_incr < 0 )
103  line_buff -= line_incr * ( target->rows - 1 );
104 
105  line_buff += ( x_offset >> 3 ) + y_offset * line_incr;
106 
107  /***********************************************************************/
108  /* */
109  /* We use the extra-classic `accumulator' trick to extract the bits */
110  /* from the source byte stream. */
111  /* */
112  /* Namely, the variable `acc' is a 16-bit accumulator containing the */
113  /* last `loaded' bits from the input stream. The bits are shifted to */
114  /* the upmost position in `acc'. */
115  /* */
116  /***********************************************************************/
117 
118  acc = 0; /* clear accumulator */
119  loaded = 0; /* no bits were loaded */
120 
121  for ( height = source_height; height > 0; height-- )
122  {
123  FT_Byte* cur = line_buff; /* current write cursor */
124  FT_Int count = line_bits; /* # of bits to extract per line */
125  FT_Byte shift = (FT_Byte)( x_offset & 7 ); /* current write shift */
126  FT_Byte space = (FT_Byte)( 8 - shift );
127 
128 
129  /* first of all, read individual source bytes */
130  if ( count >= 8 )
131  {
132  count -= 8;
133  {
134  do
135  {
136  FT_Byte val;
137 
138 
139  /* ensure that there are at least 8 bits in the accumulator */
140  if ( loaded < 8 )
141  {
142  acc |= (FT_UShort)((FT_UShort)*source++ << ( 8 - loaded ));
143  loaded += 8;
144  }
145 
146  /* now write one byte */
147  val = (FT_Byte)( acc >> 8 );
148  if ( shift )
149  {
150  cur[0] |= (FT_Byte)( val >> shift );
151  cur[1] |= (FT_Byte)( val << space );
152  }
153  else
154  cur[0] |= val;
155 
156  cur++;
157  acc <<= 8; /* remove bits from accumulator */
158  loaded -= 8;
159  count -= 8;
160 
161  } while ( count >= 0 );
162  }
163 
164  /* restore `count' to correct value */
165  count += 8;
166  }
167 
168  /* now write remaining bits (count < 8) */
169  if ( count > 0 )
170  {
171  FT_Byte val;
172 
173 
174  /* ensure that there are at least `count' bits in the accumulator */
175  if ( (FT_Int)loaded < count )
176  {
177  acc |= (FT_UShort)((FT_UShort)*source++ << ( 8 - loaded ));
178  loaded += 8;
179  }
180 
181  /* now write remaining bits */
182  val = (FT_Byte)( ( (FT_Byte)( acc >> 8 ) ) & ~( 0xFF >> count ) );
183  cur[0] |= (FT_Byte)( val >> shift );
184 
185  if ( count > space )
186  cur[1] |= (FT_Byte)( val << space );
187 
188  acc <<= count;
189  loaded -= count;
190  }
191 
192  /* now, skip to next line */
193  if ( byte_padded )
194  {
195  acc = 0;
196  loaded = 0; /* clear accumulator on byte-padded lines */
197  }
198 
199  line_buff += line_incr;
200  }
201  }
202 
203 
204  static const FT_Frame_Field sbit_metrics_fields[] =
205  {
206 #undef FT_STRUCTURE
207 #define FT_STRUCTURE TT_SBit_MetricsRec
208 
209  FT_FRAME_START( 8 ),
210  FT_FRAME_BYTE( height ),
211  FT_FRAME_BYTE( width ),
212 
213  FT_FRAME_CHAR( horiBearingX ),
214  FT_FRAME_CHAR( horiBearingY ),
215  FT_FRAME_BYTE( horiAdvance ),
216 
217  FT_FRAME_CHAR( vertBearingX ),
218  FT_FRAME_CHAR( vertBearingY ),
219  FT_FRAME_BYTE( vertAdvance ),
221  };
222 
223 
224  /*************************************************************************/
225  /* */
226  /* <Function> */
227  /* Load_SBit_Const_Metrics */
228  /* */
229  /* <Description> */
230  /* Loads the metrics for `EBLC' index tables format 2 and 5. */
231  /* */
232  /* <Input> */
233  /* range :: The target range. */
234  /* */
235  /* stream :: The input stream. */
236  /* */
237  /* <Return> */
238  /* FreeType error code. 0 means success. */
239  /* */
240  static FT_Error
241  Load_SBit_Const_Metrics( TT_SBit_Range range,
242  FT_Stream stream )
243  {
244  FT_Error error;
245 
246 
247  if ( FT_READ_ULONG( range->image_size ) )
248  return error;
249 
250  return FT_STREAM_READ_FIELDS( sbit_metrics_fields, &range->metrics );
251  }
252 
253 
254  /*************************************************************************/
255  /* */
256  /* <Function> */
257  /* Load_SBit_Range_Codes */
258  /* */
259  /* <Description> */
260  /* Loads the range codes for `EBLC' index tables format 4 and 5. */
261  /* */
262  /* <Input> */
263  /* range :: The target range. */
264  /* */
265  /* stream :: The input stream. */
266  /* */
267  /* load_offsets :: A flag whether to load the glyph offset table. */
268  /* */
269  /* <Return> */
270  /* FreeType error code. 0 means success. */
271  /* */
272  static FT_Error
273  Load_SBit_Range_Codes( TT_SBit_Range range,
274  FT_Stream stream,
275  FT_Bool load_offsets )
276  {
277  FT_Error error;
278  FT_ULong count, n, size;
279  FT_Memory memory = stream->memory;
280 
281 
282  if ( FT_READ_ULONG( count ) )
283  goto Exit;
284 
285  range->num_glyphs = count;
286 
287  /* Allocate glyph offsets table if needed */
288  if ( load_offsets )
289  {
290  if ( FT_NEW_ARRAY( range->glyph_offsets, count ) )
291  goto Exit;
292 
293  size = count * 4L;
294  }
295  else
296  size = count * 2L;
297 
298  /* Allocate glyph codes table and access frame */
299  if ( FT_NEW_ARRAY ( range->glyph_codes, count ) ||
300  FT_FRAME_ENTER( size ) )
301  goto Exit;
302 
303  for ( n = 0; n < count; n++ )
304  {
305  range->glyph_codes[n] = FT_GET_USHORT();
306 
307  if ( load_offsets )
308  range->glyph_offsets[n] = (FT_ULong)range->image_offset +
309  FT_GET_USHORT();
310  }
311 
312  FT_FRAME_EXIT();
313 
314  Exit:
315  return error;
316  }
317 
318 
319  /*************************************************************************/
320  /* */
321  /* <Function> */
322  /* Load_SBit_Range */
323  /* */
324  /* <Description> */
325  /* Loads a given `EBLC' index/range table. */
326  /* */
327  /* <Input> */
328  /* range :: The target range. */
329  /* */
330  /* stream :: The input stream. */
331  /* */
332  /* <Return> */
333  /* FreeType error code. 0 means success. */
334  /* */
335  static FT_Error
336  Load_SBit_Range( TT_SBit_Range range,
337  FT_Stream stream )
338  {
339  FT_Error error;
340  FT_Memory memory = stream->memory;
341 
342 
343  switch( range->index_format )
344  {
345  case 1: /* variable metrics with 4-byte offsets */
346  case 3: /* variable metrics with 2-byte offsets */
347  {
348  FT_ULong num_glyphs, n;
349  FT_Int size_elem;
350  FT_Bool large = FT_BOOL( range->index_format == 1 );
351 
352 
353 
354  if ( range->last_glyph < range->first_glyph )
355  {
356  error = SFNT_Err_Invalid_File_Format;
357  goto Exit;
358  }
359 
360  num_glyphs = range->last_glyph - range->first_glyph + 1L;
361  range->num_glyphs = num_glyphs;
362  num_glyphs++; /* XXX: BEWARE - see spec */
363 
364  size_elem = large ? 4 : 2;
365 
366  if ( FT_NEW_ARRAY( range->glyph_offsets, num_glyphs ) ||
367  FT_FRAME_ENTER( num_glyphs * size_elem ) )
368  goto Exit;
369 
370  for ( n = 0; n < num_glyphs; n++ )
371  range->glyph_offsets[n] = (FT_ULong)( range->image_offset +
372  ( large ? FT_GET_ULONG()
373  : FT_GET_USHORT() ) );
374  FT_FRAME_EXIT();
375  }
376  break;
377 
378  case 2: /* all glyphs have identical metrics */
379  error = Load_SBit_Const_Metrics( range, stream );
380  break;
381 
382  case 4:
383  error = Load_SBit_Range_Codes( range, stream, 1 );
384  break;
385 
386  case 5:
387  error = Load_SBit_Const_Metrics( range, stream );
388  if ( !error )
389  error = Load_SBit_Range_Codes( range, stream, 0 );
390  break;
391 
392  default:
393  error = SFNT_Err_Invalid_File_Format;
394  }
395 
396  Exit:
397  return error;
398  }
399 
400 
401  /*************************************************************************/
402  /* */
403  /* <Function> */
404  /* tt_face_load_eblc */
405  /* */
406  /* <Description> */
407  /* Loads the table of embedded bitmap sizes for this face. */
408  /* */
409  /* <Input> */
410  /* face :: The target face object. */
411  /* */
412  /* stream :: The input stream. */
413  /* */
414  /* <Return> */
415  /* FreeType error code. 0 means success. */
416  /* */
419  FT_Stream stream )
420  {
421  FT_Error error = SFNT_Err_Ok;
422  FT_Memory memory = stream->memory;
424  FT_ULong num_strikes;
425  FT_ULong table_base;
426 
427  static const FT_Frame_Field sbit_line_metrics_fields[] =
428  {
429 #undef FT_STRUCTURE
430 #define FT_STRUCTURE TT_SBit_LineMetricsRec
431 
432  /* no FT_FRAME_START */
433  FT_FRAME_CHAR( ascender ),
434  FT_FRAME_CHAR( descender ),
435  FT_FRAME_BYTE( max_width ),
436 
437  FT_FRAME_CHAR( caret_slope_numerator ),
438  FT_FRAME_CHAR( caret_slope_denominator ),
439  FT_FRAME_CHAR( caret_offset ),
440 
441  FT_FRAME_CHAR( min_origin_SB ),
442  FT_FRAME_CHAR( min_advance_SB ),
443  FT_FRAME_CHAR( max_before_BL ),
444  FT_FRAME_CHAR( min_after_BL ),
445  FT_FRAME_CHAR( pads[0] ),
446  FT_FRAME_CHAR( pads[1] ),
448  };
449 
450  static const FT_Frame_Field strike_start_fields[] =
451  {
452 #undef FT_STRUCTURE
453 #define FT_STRUCTURE TT_SBit_StrikeRec
454 
455  /* no FT_FRAME_START */
456  FT_FRAME_ULONG( ranges_offset ),
458  FT_FRAME_ULONG( num_ranges ),
459  FT_FRAME_ULONG( color_ref ),
461  };
462 
463  static const FT_Frame_Field strike_end_fields[] =
464  {
465  /* no FT_FRAME_START */
466  FT_FRAME_USHORT( start_glyph ),
467  FT_FRAME_USHORT( end_glyph ),
468  FT_FRAME_BYTE ( x_ppem ),
469  FT_FRAME_BYTE ( y_ppem ),
470  FT_FRAME_BYTE ( bit_depth ),
471  FT_FRAME_CHAR ( flags ),
473  };
474 
475 
476  face->num_sbit_strikes = 0;
477 
478  /* this table is optional */
479  error = face->goto_table( face, TTAG_EBLC, stream, 0 );
480  if ( error )
481  error = face->goto_table( face, TTAG_bloc, stream, 0 );
482  if ( error )
483  goto Exit;
484 
485  table_base = FT_STREAM_POS();
486  if ( FT_FRAME_ENTER( 8L ) )
487  goto Exit;
488 
489  version = FT_GET_LONG();
490  num_strikes = FT_GET_ULONG();
491 
492  FT_FRAME_EXIT();
493 
494  /* check version number and strike count */
495  if ( version != 0x00020000L ||
496  num_strikes >= 0x10000L )
497  {
498  FT_ERROR(( "tt_face_load_sbit_strikes: invalid table version\n" ));
499  error = SFNT_Err_Invalid_File_Format;
500 
501  goto Exit;
502  }
503 
504  /* allocate the strikes table */
505  if ( FT_NEW_ARRAY( face->sbit_strikes, num_strikes ) )
506  goto Exit;
507 
508  face->num_sbit_strikes = num_strikes;
509 
510  /* now read each strike table separately */
511  {
512  TT_SBit_Strike strike = face->sbit_strikes;
513  FT_ULong count = num_strikes;
514 
515 
516  if ( FT_FRAME_ENTER( 48L * num_strikes ) )
517  goto Exit;
518 
519  while ( count > 0 )
520  {
521  if ( FT_STREAM_READ_FIELDS( strike_start_fields, strike ) ||
522  FT_STREAM_READ_FIELDS( sbit_line_metrics_fields, &strike->hori ) ||
523  FT_STREAM_READ_FIELDS( sbit_line_metrics_fields, &strike->vert ) ||
524  FT_STREAM_READ_FIELDS( strike_end_fields, strike ) )
525  break;
526 
527  count--;
528  strike++;
529  }
530 
531  FT_FRAME_EXIT();
532  }
533 
534  /* allocate the index ranges for each strike table */
535  {
536  TT_SBit_Strike strike = face->sbit_strikes;
537  FT_ULong count = num_strikes;
538 
539 
540  while ( count > 0 )
541  {
543  FT_ULong count2 = strike->num_ranges;
544 
545 
546  /* read each range */
547  if ( FT_STREAM_SEEK( table_base + strike->ranges_offset ) ||
548  FT_FRAME_ENTER( strike->num_ranges * 8L ) )
549  goto Exit;
550 
551  if ( FT_NEW_ARRAY( strike->sbit_ranges, strike->num_ranges ) )
552  goto Exit;
553 
554  range = strike->sbit_ranges;
555  while ( count2 > 0 )
556  {
557  range->first_glyph = FT_GET_USHORT();
558  range->last_glyph = FT_GET_USHORT();
559  range->table_offset = table_base + strike->ranges_offset +
560  FT_GET_ULONG();
561  count2--;
562  range++;
563  }
564 
565  FT_FRAME_EXIT();
566 
567  /* Now, read each index table */
568  count2 = strike->num_ranges;
569  range = strike->sbit_ranges;
570  while ( count2 > 0 )
571  {
572  /* Read the header */
573  if ( FT_STREAM_SEEK( range->table_offset ) ||
574  FT_FRAME_ENTER( 8L ) )
575  goto Exit;
576 
577  range->index_format = FT_GET_USHORT();
578  range->image_format = FT_GET_USHORT();
579  range->image_offset = FT_GET_ULONG();
580 
581  FT_FRAME_EXIT();
582 
583  error = Load_SBit_Range( range, stream );
584  if ( error )
585  goto Exit;
586 
587  count2--;
588  range++;
589  }
590 
591  count--;
592  strike++;
593  }
594  }
595 
596  Exit:
597  return error;
598  }
599 
600 
601  /*************************************************************************/
602  /* */
603  /* <Function> */
604  /* tt_face_free_eblc */
605  /* */
606  /* <Description> */
607  /* Releases the embedded bitmap tables. */
608  /* */
609  /* <Input> */
610  /* face :: The target face object. */
611  /* */
612  FT_LOCAL_DEF( void )
613  tt_face_free_eblc( TT_Face face )
614  {
615  FT_Memory memory = face->root.memory;
616  TT_SBit_Strike strike = face->sbit_strikes;
617  TT_SBit_Strike strike_limit = strike + face->num_sbit_strikes;
618 
619 
620  if ( strike )
621  {
622  for ( ; strike < strike_limit; strike++ )
623  {
624  TT_SBit_Range range = strike->sbit_ranges;
625  TT_SBit_Range range_limit = range + strike->num_ranges;
626 
627 
628  if ( range )
629  {
630  for ( ; range < range_limit; range++ )
631  {
632  /* release the glyph offsets and codes tables */
633  /* where appropriate */
634  FT_FREE( range->glyph_offsets );
635  FT_FREE( range->glyph_codes );
636  }
637  }
638  FT_FREE( strike->sbit_ranges );
639  strike->num_ranges = 0;
640  }
641  FT_FREE( face->sbit_strikes );
642  }
643  face->num_sbit_strikes = 0;
644  }
645 
646 
649  FT_Size_Request req,
650  FT_ULong* astrike_index )
651  {
652  return FT_Match_Size( (FT_Face)face, req, 0, astrike_index );
653  }
654 
655 
658  FT_ULong strike_index,
660  {
661  TT_SBit_Strike strike;
662 
663 
664  if ( strike_index >= face->num_sbit_strikes )
665  return SFNT_Err_Invalid_Argument;
666 
667  strike = face->sbit_strikes + strike_index;
668 
669  metrics->x_ppem = strike->x_ppem;
670  metrics->y_ppem = strike->y_ppem;
671 
672  metrics->ascender = strike->hori.ascender << 6;
673  metrics->descender = strike->hori.descender << 6;
674 
675  /* XXX: Is this correct? */
676  metrics->max_advance = ( strike->hori.min_origin_SB +
677  strike->hori.max_width +
678  strike->hori.min_advance_SB ) << 6;
679 
680  metrics->height = metrics->ascender - metrics->descender;
681 
682  return SFNT_Err_Ok;
683  }
684 
685 
686  /*************************************************************************/
687  /* */
688  /* <Function> */
689  /* find_sbit_range */
690  /* */
691  /* <Description> */
692  /* Scans a given strike's ranges and return, for a given glyph */
693  /* index, the corresponding sbit range, and `EBDT' offset. */
694  /* */
695  /* <Input> */
696  /* glyph_index :: The glyph index. */
697  /* */
698  /* strike :: The source/current sbit strike. */
699  /* */
700  /* <Output> */
701  /* arange :: The sbit range containing the glyph index. */
702  /* */
703  /* aglyph_offset :: The offset of the glyph data in `EBDT' table. */
704  /* */
705  /* <Return> */
706  /* FreeType error code. 0 means the glyph index was found. */
707  /* */
708  static FT_Error
709  find_sbit_range( FT_UInt glyph_index,
710  TT_SBit_Strike strike,
711  TT_SBit_Range *arange,
712  FT_ULong *aglyph_offset )
713  {
714  TT_SBit_RangeRec *range, *range_limit;
715 
716 
717  /* check whether the glyph index is within this strike's */
718  /* glyph range */
719  if ( glyph_index < (FT_UInt)strike->start_glyph ||
720  glyph_index > (FT_UInt)strike->end_glyph )
721  goto Fail;
722 
723  /* scan all ranges in strike */
724  range = strike->sbit_ranges;
725  range_limit = range + strike->num_ranges;
726  if ( !range )
727  goto Fail;
728 
729  for ( ; range < range_limit; range++ )
730  {
731  if ( glyph_index >= (FT_UInt)range->first_glyph &&
732  glyph_index <= (FT_UInt)range->last_glyph )
733  {
734  FT_UShort delta = (FT_UShort)( glyph_index - range->first_glyph );
735 
736 
737  switch ( range->index_format )
738  {
739  case 1:
740  case 3:
741  *aglyph_offset = range->glyph_offsets[delta];
742  break;
743 
744  case 2:
745  *aglyph_offset = range->image_offset +
746  range->image_size * delta;
747  break;
748 
749  case 4:
750  case 5:
751  {
752  FT_ULong n;
753 
754 
755  for ( n = 0; n < range->num_glyphs; n++ )
756  {
757  if ( (FT_UInt)range->glyph_codes[n] == glyph_index )
758  {
759  if ( range->index_format == 4 )
760  *aglyph_offset = range->glyph_offsets[n];
761  else
762  *aglyph_offset = range->image_offset +
763  n * range->image_size;
764  goto Found;
765  }
766  }
767  }
768 
769  /* fall-through */
770  default:
771  goto Fail;
772  }
773 
774  Found:
775  /* return successfully! */
776  *arange = range;
777  return SFNT_Err_Ok;
778  }
779  }
780 
781  Fail:
782  *arange = 0;
783  *aglyph_offset = 0;
784 
785  return SFNT_Err_Invalid_Argument;
786  }
787 
788 
789  /*************************************************************************/
790  /* */
791  /* <Function> */
792  /* tt_find_sbit_image */
793  /* */
794  /* <Description> */
795  /* Checks whether an embedded bitmap (an `sbit') exists for a given */
796  /* glyph, at a given strike. */
797  /* */
798  /* <Input> */
799  /* face :: The target face object. */
800  /* */
801  /* glyph_index :: The glyph index. */
802  /* */
803  /* strike_index :: The current strike index. */
804  /* */
805  /* <Output> */
806  /* arange :: The SBit range containing the glyph index. */
807  /* */
808  /* astrike :: The SBit strike containing the glyph index. */
809  /* */
810  /* aglyph_offset :: The offset of the glyph data in `EBDT' table. */
811  /* */
812  /* <Return> */
813  /* FreeType error code. 0 means success. Returns */
814  /* SFNT_Err_Invalid_Argument if no sbit exists for the requested */
815  /* glyph. */
816  /* */
817  FT_LOCAL( FT_Error )
818  tt_find_sbit_image( TT_Face face,
819  FT_UInt glyph_index,
820  FT_ULong strike_index,
821  TT_SBit_Range *arange,
822  TT_SBit_Strike *astrike,
823  FT_ULong *aglyph_offset )
824  {
825  FT_Error error;
826  TT_SBit_Strike strike;
827 
828 
829  if ( !face->sbit_strikes ||
830  ( face->num_sbit_strikes <= strike_index ) )
831  goto Fail;
832 
833  strike = &face->sbit_strikes[strike_index];
834 
835  error = find_sbit_range( glyph_index, strike,
836  arange, aglyph_offset );
837  if ( error )
838  goto Fail;
839 
840  *astrike = strike;
841 
842  return SFNT_Err_Ok;
843 
844  Fail:
845  /* no embedded bitmap for this glyph in face */
846  *arange = 0;
847  *astrike = 0;
848  *aglyph_offset = 0;
849 
850  return SFNT_Err_Invalid_Argument;
851  }
852 
853 
854  /*************************************************************************/
855  /* */
856  /* <Function> */
857  /* tt_load_sbit_metrics */
858  /* */
859  /* <Description> */
860  /* Gets the big metrics for a given SBit. */
861  /* */
862  /* <Input> */
863  /* stream :: The input stream. */
864  /* */
865  /* range :: The SBit range containing the glyph. */
866  /* */
867  /* <Output> */
868  /* big_metrics :: A big SBit metrics structure for the glyph. */
869  /* */
870  /* <Return> */
871  /* FreeType error code. 0 means success. */
872  /* */
873  /* <Note> */
874  /* The stream cursor must be positioned at the glyph's offset within */
875  /* the `EBDT' table before the call. */
876  /* */
877  /* If the image format uses variable metrics, the stream cursor is */
878  /* positioned just after the metrics header in the `EBDT' table on */
879  /* function exit. */
880  /* */
881  FT_LOCAL( FT_Error )
882  tt_load_sbit_metrics( FT_Stream stream,
883  TT_SBit_Range range,
884  TT_SBit_Metrics metrics )
885  {
886  FT_Error error = SFNT_Err_Ok;
887 
888 
889  switch ( range->image_format )
890  {
891  case 1:
892  case 2:
893  case 8:
894  /* variable small metrics */
895  {
896  TT_SBit_SmallMetricsRec smetrics;
897 
898  static const FT_Frame_Field sbit_small_metrics_fields[] =
899  {
900 #undef FT_STRUCTURE
901 #define FT_STRUCTURE TT_SBit_SmallMetricsRec
902 
903  FT_FRAME_START( 5 ),
904  FT_FRAME_BYTE( height ),
905  FT_FRAME_BYTE( width ),
906  FT_FRAME_CHAR( bearingX ),
907  FT_FRAME_CHAR( bearingY ),
908  FT_FRAME_BYTE( advance ),
910  };
911 
912 
913  /* read small metrics */
914  if ( FT_STREAM_READ_FIELDS( sbit_small_metrics_fields, &smetrics ) )
915  goto Exit;
916 
917  /* convert it to a big metrics */
918  metrics->height = smetrics.height;
919  metrics->width = smetrics.width;
920  metrics->horiBearingX = smetrics.bearingX;
921  metrics->horiBearingY = smetrics.bearingY;
922  metrics->horiAdvance = smetrics.advance;
923 
924  /* these metrics are made up at a higher level when */
925  /* needed. */
926  metrics->vertBearingX = 0;
927  metrics->vertBearingY = 0;
928  metrics->vertAdvance = 0;
929  }
930  break;
931 
932  case 6:
933  case 7:
934  case 9:
935  /* variable big metrics */
936  if ( FT_STREAM_READ_FIELDS( sbit_metrics_fields, metrics ) )
937  goto Exit;
938  break;
939 
940  case 5:
941  default: /* constant metrics */
942  if ( range->index_format == 2 || range->index_format == 5 )
943  *metrics = range->metrics;
944  else
945  return SFNT_Err_Invalid_File_Format;
946  }
947 
948  Exit:
949  return error;
950  }
951 
952 
953  /*************************************************************************/
954  /* */
955  /* <Function> */
956  /* crop_bitmap */
957  /* */
958  /* <Description> */
959  /* Crops a bitmap to its tightest bounding box, and adjusts its */
960  /* metrics. */
961  /* */
962  /* <InOut> */
963  /* map :: The bitmap. */
964  /* */
965  /* metrics :: The corresponding metrics structure. */
966  /* */
967  static void
968  crop_bitmap( FT_Bitmap* map,
969  TT_SBit_Metrics metrics )
970  {
971  /***********************************************************************/
972  /* */
973  /* In this situation, some bounding boxes of embedded bitmaps are too */
974  /* large. We need to crop it to a reasonable size. */
975  /* */
976  /* --------- */
977  /* | | ----- */
978  /* | *** | |***| */
979  /* | * | | * | */
980  /* | * | ------> | * | */
981  /* | * | | * | */
982  /* | * | | * | */
983  /* | *** | |***| */
984  /* --------- ----- */
985  /* */
986  /***********************************************************************/
987 
988  FT_Int rows, count;
989  FT_Long line_len;
990  FT_Byte* line;
991 
992 
993  /***********************************************************************/
994  /* */
995  /* first of all, check the top-most lines of the bitmap, and remove */
996  /* them if they're empty. */
997  /* */
998  {
999  line = (FT_Byte*)map->buffer;
1000  rows = map->rows;
1001  line_len = map->pitch;
1002 
1003 
1004  for ( count = 0; count < rows; count++ )
1005  {
1006  FT_Byte* cur = line;
1007  FT_Byte* limit = line + line_len;
1008 
1009 
1010  for ( ; cur < limit; cur++ )
1011  if ( cur[0] )
1012  goto Found_Top;
1013 
1014  /* the current line was empty - skip to next one */
1015  line = limit;
1016  }
1017 
1018  Found_Top:
1019  /* check that we have at least one filled line */
1020  if ( count >= rows )
1021  goto Empty_Bitmap;
1022 
1023  /* now, crop the empty upper lines */
1024  if ( count > 0 )
1025  {
1026  line = (FT_Byte*)map->buffer;
1027 
1028  FT_MEM_MOVE( line, line + count * line_len,
1029  ( rows - count ) * line_len );
1030 
1031  metrics->height = (FT_Byte)( metrics->height - count );
1032  metrics->horiBearingY = (FT_Char)( metrics->horiBearingY - count );
1033  metrics->vertBearingY = (FT_Char)( metrics->vertBearingY - count );
1034 
1035  map->rows -= count;
1036  rows -= count;
1037  }
1038  }
1039 
1040  /***********************************************************************/
1041  /* */
1042  /* second, crop the lower lines */
1043  /* */
1044  {
1045  line = (FT_Byte*)map->buffer + ( rows - 1 ) * line_len;
1046 
1047  for ( count = 0; count < rows; count++ )
1048  {
1049  FT_Byte* cur = line;
1050  FT_Byte* limit = line + line_len;
1051 
1052 
1053  for ( ; cur < limit; cur++ )
1054  if ( cur[0] )
1055  goto Found_Bottom;
1056 
1057  /* the current line was empty - skip to previous one */
1058  line -= line_len;
1059  }
1060 
1061  Found_Bottom:
1062  if ( count > 0 )
1063  {
1064  metrics->height = (FT_Byte)( metrics->height - count );
1065  rows -= count;
1066  map->rows -= count;
1067  }
1068  }
1069 
1070  /***********************************************************************/
1071  /* */
1072  /* third, get rid of the space on the left side of the glyph */
1073  /* */
1074  do
1075  {
1076  FT_Byte* limit;
1077 
1078 
1079  line = (FT_Byte*)map->buffer;
1080  limit = line + rows * line_len;
1081 
1082  for ( ; line < limit; line += line_len )
1083  if ( line[0] & 0x80 )
1084  goto Found_Left;
1085 
1086  /* shift the whole glyph one pixel to the left */
1087  line = (FT_Byte*)map->buffer;
1088  limit = line + rows * line_len;
1089 
1090  for ( ; line < limit; line += line_len )
1091  {
1092  FT_Int n, width = map->width;
1093  FT_Byte old;
1094  FT_Byte* cur = line;
1095 
1096 
1097  old = (FT_Byte)(cur[0] << 1);
1098  for ( n = 8; n < width; n += 8 )
1099  {
1100  FT_Byte val;
1101 
1102 
1103  val = cur[1];
1104  cur[0] = (FT_Byte)( old | ( val >> 7 ) );
1105  old = (FT_Byte)( val << 1 );
1106  cur++;
1107  }
1108  cur[0] = old;
1109  }
1110 
1111  map->width--;
1112  metrics->horiBearingX++;
1113  metrics->vertBearingX++;
1114  metrics->width--;
1115 
1116  } while ( map->width > 0 );
1117 
1118  Found_Left:
1119 
1120  /***********************************************************************/
1121  /* */
1122  /* finally, crop the bitmap width to get rid of the space on the right */
1123  /* side of the glyph. */
1124  /* */
1125  do
1126  {
1127  FT_Int right = map->width - 1;
1128  FT_Byte* limit;
1129  FT_Byte mask;
1130 
1131 
1132  line = (FT_Byte*)map->buffer + ( right >> 3 );
1133  limit = line + rows * line_len;
1134  mask = (FT_Byte)( 0x80 >> ( right & 7 ) );
1135 
1136  for ( ; line < limit; line += line_len )
1137  if ( line[0] & mask )
1138  goto Found_Right;
1139 
1140  /* crop the whole glyph to the right */
1141  map->width--;
1142  metrics->width--;
1143 
1144  } while ( map->width > 0 );
1145 
1146  Found_Right:
1147  /* all right, the bitmap was cropped */
1148  return;
1149 
1150  Empty_Bitmap:
1151  map->width = 0;
1152  map->rows = 0;
1153  map->pitch = 0;
1155  }
1156 
1157 
1158  static FT_Error
1159  Load_SBit_Single( FT_Bitmap* map,
1160  FT_Int x_offset,
1161  FT_Int y_offset,
1162  FT_Int pix_bits,
1163  FT_UShort image_format,
1164  TT_SBit_Metrics metrics,
1165  FT_Stream stream )
1166  {
1167  FT_Error error;
1168 
1169 
1170  /* check that the source bitmap fits into the target pixmap */
1171  if ( x_offset < 0 || x_offset + metrics->width > map->width ||
1172  y_offset < 0 || y_offset + metrics->height > map->rows )
1173  {
1174  error = SFNT_Err_Invalid_Argument;
1175 
1176  goto Exit;
1177  }
1178 
1179  {
1180  FT_Int glyph_width = metrics->width;
1181  FT_Int glyph_height = metrics->height;
1182  FT_Int glyph_size;
1183  FT_Int line_bits = pix_bits * glyph_width;
1184  FT_Bool pad_bytes = 0;
1185 
1186 
1187  /* compute size of glyph image */
1188  switch ( image_format )
1189  {
1190  case 1: /* byte-padded formats */
1191  case 6:
1192  {
1193  FT_Int line_length;
1194 
1195 
1196  switch ( pix_bits )
1197  {
1198  case 1:
1199  line_length = ( glyph_width + 7 ) >> 3;
1200  break;
1201  case 2:
1202  line_length = ( glyph_width + 3 ) >> 2;
1203  break;
1204  case 4:
1205  line_length = ( glyph_width + 1 ) >> 1;
1206  break;
1207  default:
1208  line_length = glyph_width;
1209  }
1210 
1211  glyph_size = glyph_height * line_length;
1212  pad_bytes = 1;
1213  }
1214  break;
1215 
1216  case 2:
1217  case 5:
1218  case 7:
1219  line_bits = glyph_width * pix_bits;
1220  glyph_size = ( glyph_height * line_bits + 7 ) >> 3;
1221  break;
1222 
1223  default: /* invalid format */
1224  return SFNT_Err_Invalid_File_Format;
1225  }
1226 
1227  /* Now read data and draw glyph into target pixmap */
1228  if ( FT_FRAME_ENTER( glyph_size ) )
1229  goto Exit;
1230 
1231  /* don't forget to multiply `x_offset' by `map->pix_bits' as */
1232  /* the sbit blitter doesn't make a difference between pixmap */
1233  /* depths. */
1234  blit_sbit( map, (FT_Byte*)stream->cursor, line_bits, pad_bytes,
1235  x_offset * pix_bits, y_offset, metrics->height );
1236 
1237  FT_FRAME_EXIT();
1238  }
1239 
1240  Exit:
1241  return error;
1242  }
1243 
1244 
1245  static FT_Error
1246  Load_SBit_Image( TT_SBit_Strike strike,
1247  TT_SBit_Range range,
1248  FT_ULong ebdt_pos,
1249  FT_ULong glyph_offset,
1250  FT_GlyphSlot slot,
1251  FT_Int x_offset,
1252  FT_Int y_offset,
1253  FT_Stream stream,
1254  TT_SBit_Metrics metrics,
1255  FT_Int depth )
1256  {
1257  FT_Memory memory = stream->memory;
1258  FT_Bitmap* map = &slot->bitmap;
1259  FT_Error error;
1260 
1261 
1262  /* place stream at beginning of glyph data and read metrics */
1263  if ( FT_STREAM_SEEK( ebdt_pos + glyph_offset ) )
1264  goto Exit;
1265 
1266  error = tt_load_sbit_metrics( stream, range, metrics );
1267  if ( error )
1268  goto Exit;
1269 
1270  /* This function is recursive. At the top-level call, we */
1271  /* compute the dimensions of the higher-level glyph to */
1272  /* allocate the final pixmap buffer. */
1273  if ( depth == 0 )
1274  {
1275  FT_Long size;
1276 
1277 
1278  map->width = metrics->width;
1279  map->rows = metrics->height;
1280 
1281  switch ( strike->bit_depth )
1282  {
1283  case 1:
1285  map->pitch = ( map->width + 7 ) >> 3;
1286  break;
1287 
1288  case 2:
1290  map->pitch = ( map->width + 3 ) >> 2;
1291  break;
1292 
1293  case 4:
1295  map->pitch = ( map->width + 1 ) >> 1;
1296  break;
1297 
1298  case 8:
1300  map->pitch = map->width;
1301  break;
1302 
1303  default:
1304  return SFNT_Err_Invalid_File_Format;
1305  }
1306 
1307  size = map->rows * map->pitch;
1308 
1309  /* check that there is no empty image */
1310  if ( size == 0 )
1311  goto Exit; /* exit successfully! */
1312 
1313  error = ft_glyphslot_alloc_bitmap( slot, size );
1314  if (error)
1315  goto Exit;
1316  }
1317 
1318  switch ( range->image_format )
1319  {
1320  case 1: /* single sbit image - load it */
1321  case 2:
1322  case 5:
1323  case 6:
1324  case 7:
1325  return Load_SBit_Single( map, x_offset, y_offset, strike->bit_depth,
1326  range->image_format, metrics, stream );
1327 
1328  case 8: /* compound format */
1329  if ( FT_STREAM_SKIP( 1L ) )
1330  {
1331  error = SFNT_Err_Invalid_Stream_Skip;
1332  goto Exit;
1333  }
1334  /* fallthrough */
1335 
1336  case 9:
1337  break;
1338 
1339  default: /* invalid image format */
1340  return SFNT_Err_Invalid_File_Format;
1341  }
1342 
1343  /* All right, we have a compound format. First of all, read */
1344  /* the array of elements. */
1345  {
1348  FT_UShort num_components, count;
1349 
1350 
1351  if ( FT_READ_USHORT( num_components ) ||
1352  FT_NEW_ARRAY( components, num_components ) )
1353  goto Exit;
1354 
1355  count = num_components;
1356 
1357  if ( FT_FRAME_ENTER( 4L * num_components ) )
1358  goto Fail_Memory;
1359 
1360  for ( comp = components; count > 0; count--, comp++ )
1361  {
1362  comp->glyph_code = FT_GET_USHORT();
1363  comp->x_offset = FT_GET_CHAR();
1364  comp->y_offset = FT_GET_CHAR();
1365  }
1366 
1367  FT_FRAME_EXIT();
1368 
1369  /* Now recursively load each element glyph */
1370  count = num_components;
1371  comp = components;
1372  for ( ; count > 0; count--, comp++ )
1373  {
1374  TT_SBit_Range elem_range;
1375  TT_SBit_MetricsRec elem_metrics;
1376  FT_ULong elem_offset;
1377 
1378 
1379  /* find the range for this element */
1380  error = find_sbit_range( comp->glyph_code,
1381  strike,
1382  &elem_range,
1383  &elem_offset );
1384  if ( error )
1385  goto Fail_Memory;
1386 
1387  /* now load the element, recursively */
1388  error = Load_SBit_Image( strike,
1389  elem_range,
1390  ebdt_pos,
1391  elem_offset,
1392  slot,
1393  x_offset + comp->x_offset,
1394  y_offset + comp->y_offset,
1395  stream,
1396  &elem_metrics,
1397  depth + 1 );
1398  if ( error )
1399  goto Fail_Memory;
1400  }
1401 
1402  Fail_Memory:
1403  FT_FREE( components );
1404  }
1405 
1406  Exit:
1407  return error;
1408  }
1409 
1410 
1411  /*************************************************************************/
1412  /* */
1413  /* <Function> */
1414  /* tt_face_load_sbit_image */
1415  /* */
1416  /* <Description> */
1417  /* Loads a given glyph sbit image from the font resource. This also */
1418  /* returns its metrics. */
1419  /* */
1420  /* <Input> */
1421  /* face :: The target face object. */
1422  /* */
1423  /* strike_index :: The current strike index. */
1424  /* */
1425  /* glyph_index :: The current glyph index. */
1426  /* */
1427  /* load_flags :: The glyph load flags (the code checks for the flag */
1428  /* FT_LOAD_CROP_BITMAP). */
1429  /* */
1430  /* stream :: The input stream. */
1431  /* */
1432  /* <Output> */
1433  /* map :: The target pixmap. */
1434  /* */
1435  /* metrics :: A big sbit metrics structure for the glyph image. */
1436  /* */
1437  /* <Return> */
1438  /* FreeType error code. 0 means success. Returns an error if no */
1439  /* glyph sbit exists for the index. */
1440  /* */
1441  /* <Note> */
1442  /* The `map.buffer' field is always freed before the glyph is loaded. */
1443  /* */
1446  FT_ULong strike_index,
1447  FT_UInt glyph_index,
1448  FT_UInt load_flags,
1449  FT_Stream stream,
1450  FT_Bitmap *map,
1451  TT_SBit_MetricsRec *metrics )
1452  {
1453  FT_Error error;
1454  FT_ULong ebdt_pos, glyph_offset;
1455 
1456  TT_SBit_Strike strike;
1458 
1459 
1460  /* Check whether there is a glyph sbit for the current index */
1461  error = tt_find_sbit_image( face, glyph_index, strike_index,
1462  &range, &strike, &glyph_offset );
1463  if ( error )
1464  goto Exit;
1465 
1466  /* now, find the location of the `EBDT' table in */
1467  /* the font file */
1468  error = face->goto_table( face, TTAG_EBDT, stream, 0 );
1469  if ( error )
1470  error = face->goto_table( face, TTAG_bdat, stream, 0 );
1471  if ( error )
1472  goto Exit;
1473 
1474  ebdt_pos = FT_STREAM_POS();
1475 
1476  error = Load_SBit_Image( strike, range, ebdt_pos, glyph_offset,
1477  face->root.glyph, 0, 0, stream, metrics, 0 );
1478  if ( error )
1479  goto Exit;
1480 
1481  /* setup vertical metrics if needed */
1482  if ( strike->flags & 1 )
1483  {
1484  /* in case of a horizontal strike only */
1485  FT_Int advance;
1486 
1487 
1488  advance = strike->hori.ascender - strike->hori.descender;
1489 
1490  /* some heuristic values */
1491 
1492  metrics->vertBearingX = (FT_Char)(-metrics->width / 2 );
1493  metrics->vertBearingY = (FT_Char)( ( advance - metrics->height ) / 2 );
1494  metrics->vertAdvance = (FT_Char)( advance * 12 / 10 );
1495  }
1496 
1497  /* Crop the bitmap now, unless specified otherwise */
1498  if ( load_flags & FT_LOAD_CROP_BITMAP )
1499  crop_bitmap( map, metrics );
1500 
1501  Exit:
1502  return error;
1503  }
1504 
1505 #endif /* FT_CONFIG_OPTION_OLD_INTERNALS */
1506 
1507 
1508 /* END */
int FT_Error
Definition: fttypes.h:296
FT_ULong * glyph_offsets
Definition: tttypes.h:602
GLuint const GLfloat * val
Definition: glew.h:2715
signed long FT_Long
Definition: fttypes.h:238
unsigned long FT_ULong
Definition: fttypes.h:249
FT_Char horiBearingY
Definition: tttypes.h:441
#define NULL
Definition: ftobjs.h:61
signed int FT_Int
Definition: fttypes.h:216
int rows
Definition: ftimage.h:312
unsigned char * cursor
Definition: ftsystem.h:333
GLuint GLuint stream
Definition: glew.h:6573
GLclampd n
Definition: glew.h:7287
FT_Byte y_ppem
Definition: tttypes.h:668
#define FT_GET_CHAR()
Definition: ftstream.h:293
FT_UShort first_glyph
Definition: tttypes.h:591
unsigned char * buffer
Definition: ftimage.h:315
GLuint GLsizei GLsizei GLfloat * metrics
Definition: glew.h:12394
signed char FT_Char
Definition: fttypes.h:139
FT_UShort start_glyph
Definition: tttypes.h:664
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
FT_Byte bit_depth
Definition: tttypes.h:670
#define FT_READ_USHORT(var)
Definition: ftstream.h:316
static int comp(const void *a, const void *b)
Definition: lsp.c:298
#define TTAG_EBLC
Definition: tttags.h:50
TT_SBit_LineMetricsRec hori
Definition: tttypes.h:661
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
FT_UShort last_glyph
Definition: tttypes.h:592
FT_ULong ranges_offset
Definition: tttypes.h:657
FT_ULong num_glyphs
Definition: tttypes.h:600
FT_Byte x_ppem
Definition: tttypes.h:667
#define FT_ERROR(varformat)
Definition: ftdebug.h:181
unsigned char FT_Byte
Definition: fttypes.h:150
TT_SBit_LineMetricsRec vert
Definition: tttypes.h:662
#define FT_LOCAL(x)
Definition: ftconfig.h:466
EGLContext EGLenum target
Definition: eglext.h:87
GLenum GLint * range
Definition: glew.h:3391
FT_Bitmap bitmap
Definition: freetype.h:1620
#define FT_STREAM_READ_FIELDS(fields, object)
Definition: ftstream.h:513
FT_Match_Size(FT_Face face, FT_Size_Request req, FT_Bool ignore_width, FT_ULong *size_index)
Definition: ftobjs.c:2479
FT_Char horiBearingX
Definition: tttypes.h:440
FT_Memory memory
Definition: ftsystem.h:332
#define FT_GET_USHORT()
Definition: ftstream.h:296
#define FT_FREE(ptr)
Definition: ftmemory.h:286
#define FT_FRAME_END
Definition: ftstream.h:118
#define FT_STREAM_SKIP(distance)
Definition: ftstream.h:499
#define FT_FRAME_USHORT(f)
Definition: ftstream.h:123
#define FT_LOCAL_DEF(x)
Definition: ftconfig.h:467
for(;;)
#define FT_LOAD_CROP_BITMAP
Definition: freetype.h:2518
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
#define FT_READ_ULONG(var)
Definition: ftstream.h:320
GLint GLsizei count
Definition: gl2ext.h:1011
GLenum face
Definition: gl2ext.h:1490
TT_SBit_MetricsRec metrics
Definition: tttypes.h:599
#define TTAG_bdat
Definition: tttags.h:38
#define TTAG_bloc
Definition: tttags.h:41
FT_Char vertBearingY
Definition: tttypes.h:445
FT_UShort glyph_code
Definition: tttypes.h:693
GLint limit
Definition: glew.h:11829
GLint GLenum GLsizei GLsizei GLsizei depth
Definition: gl2ext.h:845
FT_UShort end_glyph
Definition: tttypes.h:665
FT_UShort image_format
Definition: tttypes.h:595
FT_Int num_ranges
Definition: tttypes.h:655
FT_BEGIN_HEADER tt_face_load_eblc(TT_Face face, FT_Stream stream)
Definition: ttsbit0.c:43
typedefFT_BEGIN_HEADER struct FT_MemoryRec_ * FT_Memory
Definition: ftsystem.h:66
int width
Definition: ftimage.h:313
#define FT_BOOL(x)
Definition: fttypes.h:581
#define FT_FRAME_EXIT()
Definition: ftstream.h:521
FT_ULong table_offset
Definition: tttypes.h:605
#define FT_NEW_ARRAY(ptr, count)
Definition: ftmemory.h:290
#define FT_STREAM_SEEK(position)
Definition: ftstream.h:496
#define FT_STREAM_POS()
Definition: ftstream.h:493
TT_SBit_Range sbit_ranges
Definition: tttypes.h:656
signed long FT_Fixed
Definition: fttypes.h:284
FT_UShort * glyph_codes
Definition: tttypes.h:603
#define FT_FRAME_ULONG(f)
Definition: ftstream.h:121
GLenum GLsizei GLsizei GLsizei GLsizei GLbitfield flags
Definition: glew.h:2767
unsigned int FT_UInt
Definition: fttypes.h:227
#define FT_FRAME_SKIP_LONG
Definition: ftstream.h:136
#define FT_FRAME_BYTE(f)
Definition: ftstream.h:126
GLint GLint GLint GLint GLint GLint GLint GLbitfield mask
Definition: gl2ext.h:961
#define FT_FRAME_CHAR(f)
Definition: ftstream.h:127
char pixel_mode
Definition: ftimage.h:317
tt_face_free_eblc(TT_Face face)
Definition: ttsbit0.c:110
FT_UShort index_format
Definition: tttypes.h:594
#define FT_GET_ULONG()
Definition: ftstream.h:300
GLenum GLenum GLuint components
Definition: glew.h:10653
#define FT_FRAME_ENTER(size)
Definition: ftstream.h:517
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
GLfloat right
Definition: glew.h:13816
FT_ULong image_offset
Definition: tttypes.h:596
#define FT_GET_LONG()
Definition: ftstream.h:299
unsigned short FT_UShort
Definition: fttypes.h:205
#define FT_MEM_MOVE(dest, source, count)
Definition: ftmemory.h:205
GLsizei GLsizei GLchar * source
Definition: gl2ext.h:994
#define FT_FRAME_START(size)
Definition: ftstream.h:117
FT_ULong image_size
Definition: tttypes.h:598
tt_face_load_strike_metrics(TT_Face face, FT_ULong strike_index, FT_Size_Metrics *metrics)
Definition: ttsbit0.c:131
GLsizei size
Definition: gl2ext.h:1467
#define TTAG_EBDT
Definition: tttags.h:49