zenilib  0.5.3.0
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Groups Pages
ftobjs.c
Go to the documentation of this file.
1 /***************************************************************************/
2 /* */
3 /* ftobjs.c */
4 /* */
5 /* The FreeType private base classes (body). */
6 /* */
7 /* Copyright 1996-2012 by */
8 /* David Turner, Robert Wilhelm, and Werner Lemberg. */
9 /* */
10 /* This file is part of the FreeType project, and may only be used, */
11 /* modified, and distributed under the terms of the FreeType project */
12 /* license, LICENSE.TXT. By continuing to use, modify, or distribute */
13 /* this file you indicate that you have read the license and */
14 /* understand and accept it fully. */
15 /* */
16 /***************************************************************************/
17 
18 
19 #include <ft2build.h>
20 #include FT_LIST_H
21 #include FT_OUTLINE_H
22 #include FT_INTERNAL_VALIDATE_H
23 #include FT_INTERNAL_OBJECTS_H
24 #include FT_INTERNAL_DEBUG_H
25 #include FT_INTERNAL_RFORK_H
26 #include FT_INTERNAL_STREAM_H
27 #include FT_INTERNAL_SFNT_H /* for SFNT_Load_Table_Func */
28 #include FT_TRUETYPE_TABLES_H
29 #include FT_TRUETYPE_TAGS_H
30 #include FT_TRUETYPE_IDS_H
31 
32 #include FT_SERVICE_SFNT_H
33 #include FT_SERVICE_POSTSCRIPT_NAME_H
34 #include FT_SERVICE_GLYPH_DICT_H
35 #include FT_SERVICE_TT_CMAP_H
36 #include FT_SERVICE_KERNING_H
37 #include FT_SERVICE_TRUETYPE_ENGINE_H
38 
39 #ifdef FT_CONFIG_OPTION_MAC_FONTS
40 #include "ftbase.h"
41 #endif
42 
43 #define GRID_FIT_METRICS
44 
45 
47  ft_service_list_lookup( FT_ServiceDesc service_descriptors,
48  const char* service_id )
49  {
51  FT_ServiceDesc desc = service_descriptors;
52 
53 
54  if ( desc && service_id )
55  {
56  for ( ; desc->serv_id != NULL; desc++ )
57  {
58  if ( ft_strcmp( desc->serv_id, service_id ) == 0 )
59  {
60  result = (FT_Pointer)desc->serv_data;
61  break;
62  }
63  }
64  }
65 
66  return result;
67  }
68 
69 
70  FT_BASE_DEF( void )
72  const FT_Byte* base,
75  {
76  valid->base = base;
77  valid->limit = limit;
78  valid->level = level;
79  valid->error = FT_Err_Ok;
80  }
81 
82 
85  {
86  /* This function doesn't work! None should call it. */
87  FT_UNUSED( valid );
88 
89  return -1;
90  }
91 
92 
93  FT_BASE_DEF( void )
95  FT_Error error )
96  {
97  /* since the cast below also disables the compiler's */
98  /* type check, we introduce a dummy variable, which */
99  /* will be optimized away */
100  volatile ft_jmp_buf* jump_buffer = &valid->jump_buffer;
101 
102 
103  valid->error = error;
104 
105  /* throw away volatileness; use `jump_buffer' or the */
106  /* compiler may warn about an unused local variable */
107  ft_longjmp( *(ft_jmp_buf*) jump_buffer, 1 );
108  }
109 
110 
111  /*************************************************************************/
112  /*************************************************************************/
113  /*************************************************************************/
114  /**** ****/
115  /**** ****/
116  /**** S T R E A M ****/
117  /**** ****/
118  /**** ****/
119  /*************************************************************************/
120  /*************************************************************************/
121  /*************************************************************************/
122 
123 
124  /* create a new input stream from an FT_Open_Args structure */
125  /* */
128  const FT_Open_Args* args,
129  FT_Stream *astream )
130  {
131  FT_Error error;
132  FT_Memory memory;
134 
135 
136  *astream = 0;
137 
138  if ( !library )
139  return FT_Err_Invalid_Library_Handle;
140 
141  if ( !args )
143 
144  memory = library->memory;
145 
146  if ( FT_NEW( stream ) )
147  goto Exit;
148 
149  stream->memory = memory;
150 
151  if ( args->flags & FT_OPEN_MEMORY )
152  {
153  /* create a memory-based stream */
154  FT_Stream_OpenMemory( stream,
155  (const FT_Byte*)args->memory_base,
156  args->memory_size );
157  }
158 
159 #ifndef FT_CONFIG_OPTION_DISABLE_STREAM_SUPPORT
160 
161  else if ( args->flags & FT_OPEN_PATHNAME )
162  {
163  /* create a normal system stream */
164  error = FT_Stream_Open( stream, args->pathname );
165  stream->pathname.pointer = args->pathname;
166  }
167  else if ( ( args->flags & FT_OPEN_STREAM ) && args->stream )
168  {
169  /* use an existing, user-provided stream */
170 
171  /* in this case, we do not need to allocate a new stream object */
172  /* since the caller is responsible for closing it himself */
173  FT_FREE( stream );
174  stream = args->stream;
175  }
176 
177 #endif
178 
179  else
180  error = FT_Err_Invalid_Argument;
181 
182  if ( error )
183  FT_FREE( stream );
184  else
185  stream->memory = memory; /* just to be certain */
186 
187  *astream = stream;
188 
189  Exit:
190  return error;
191  }
192 
193 
194  FT_BASE_DEF( void )
196  FT_Int external )
197  {
198  if ( stream )
199  {
200  FT_Memory memory = stream->memory;
201 
202 
203  FT_Stream_Close( stream );
204 
205  if ( !external )
206  FT_FREE( stream );
207  }
208  }
209 
210 
211  /*************************************************************************/
212  /* */
213  /* The macro FT_COMPONENT is used in trace mode. It is an implicit */
214  /* parameter of the FT_TRACE() and FT_ERROR() macros, used to print/log */
215  /* messages during execution. */
216  /* */
217 #undef FT_COMPONENT
218 #define FT_COMPONENT trace_objs
219 
220 
221  /*************************************************************************/
222  /*************************************************************************/
223  /*************************************************************************/
224  /**** ****/
225  /**** ****/
226  /**** FACE, SIZE & GLYPH SLOT OBJECTS ****/
227  /**** ****/
228  /**** ****/
229  /*************************************************************************/
230  /*************************************************************************/
231  /*************************************************************************/
232 
233 
234  static FT_Error
236  {
237  FT_Driver driver = slot->face->driver;
238  FT_Driver_Class clazz = driver->clazz;
239  FT_Memory memory = driver->root.memory;
241  FT_Slot_Internal internal = NULL;
242 
243 
244  slot->library = driver->root.library;
245 
246  if ( FT_NEW( internal ) )
247  goto Exit;
248 
249  slot->internal = internal;
250 
251  if ( FT_DRIVER_USES_OUTLINES( driver ) )
252  error = FT_GlyphLoader_New( memory, &internal->loader );
253 
254  if ( !error && clazz->init_slot )
255  error = clazz->init_slot( slot );
256 
257  Exit:
258  return error;
259  }
260 
261 
262  FT_BASE_DEF( void )
264  {
265  if ( slot->internal && ( slot->internal->flags & FT_GLYPH_OWN_BITMAP ) )
266  {
267  FT_Memory memory = FT_FACE_MEMORY( slot->face );
268 
269 
270  FT_FREE( slot->bitmap.buffer );
271  slot->internal->flags &= ~FT_GLYPH_OWN_BITMAP;
272  }
273  else
274  {
275  /* assume that the bitmap buffer was stolen or not */
276  /* allocated from the heap */
277  slot->bitmap.buffer = NULL;
278  }
279  }
280 
281 
282  FT_BASE_DEF( void )
284  FT_Byte* buffer )
285  {
286  ft_glyphslot_free_bitmap( slot );
287 
288  slot->bitmap.buffer = buffer;
289 
290  FT_ASSERT( (slot->internal->flags & FT_GLYPH_OWN_BITMAP) == 0 );
291  }
292 
293 
296  FT_ULong size )
297  {
298  FT_Memory memory = FT_FACE_MEMORY( slot->face );
299  FT_Error error;
300 
301 
302  if ( slot->internal->flags & FT_GLYPH_OWN_BITMAP )
303  FT_FREE( slot->bitmap.buffer );
304  else
305  slot->internal->flags |= FT_GLYPH_OWN_BITMAP;
306 
307  (void)FT_ALLOC( slot->bitmap.buffer, size );
308  return error;
309  }
310 
311 
312  static void
314  {
315  /* free bitmap if needed */
316  ft_glyphslot_free_bitmap( slot );
317 
318  /* clear all public fields in the glyph slot */
319  FT_ZERO( &slot->metrics );
320  FT_ZERO( &slot->outline );
321 
322  slot->bitmap.width = 0;
323  slot->bitmap.rows = 0;
324  slot->bitmap.pitch = 0;
325  slot->bitmap.pixel_mode = 0;
326  /* `slot->bitmap.buffer' has been handled by ft_glyphslot_free_bitmap */
327 
328  slot->bitmap_left = 0;
329  slot->bitmap_top = 0;
330  slot->num_subglyphs = 0;
331  slot->subglyphs = 0;
332  slot->control_data = 0;
333  slot->control_len = 0;
334  slot->other = 0;
335  slot->format = FT_GLYPH_FORMAT_NONE;
336 
337  slot->linearHoriAdvance = 0;
338  slot->linearVertAdvance = 0;
339  slot->lsb_delta = 0;
340  slot->rsb_delta = 0;
341  }
342 
343 
344  static void
346  {
347  FT_Driver driver = slot->face->driver;
348  FT_Driver_Class clazz = driver->clazz;
349  FT_Memory memory = driver->root.memory;
350 
351 
352  if ( clazz->done_slot )
353  clazz->done_slot( slot );
354 
355  /* free bitmap buffer if needed */
356  ft_glyphslot_free_bitmap( slot );
357 
358  /* slot->internal might be NULL in out-of-memory situations */
359  if ( slot->internal )
360  {
361  /* free glyph loader */
362  if ( FT_DRIVER_USES_OUTLINES( driver ) )
363  {
365  slot->internal->loader = 0;
366  }
367 
368  FT_FREE( slot->internal );
369  }
370  }
371 
372 
373  /* documentation is in ftobjs.h */
374 
377  FT_GlyphSlot *aslot )
378  {
379  FT_Error error;
380  FT_Driver driver;
381  FT_Driver_Class clazz;
382  FT_Memory memory;
383  FT_GlyphSlot slot = NULL;
384 
385 
386  if ( !face || !face->driver )
388 
389  driver = face->driver;
390  clazz = driver->clazz;
391  memory = driver->root.memory;
392 
393  FT_TRACE4(( "FT_New_GlyphSlot: Creating new slot object\n" ));
394  if ( !FT_ALLOC( slot, clazz->slot_object_size ) )
395  {
396  slot->face = face;
397 
398  error = ft_glyphslot_init( slot );
399  if ( error )
400  {
401  ft_glyphslot_done( slot );
402  FT_FREE( slot );
403  goto Exit;
404  }
405 
406  slot->next = face->glyph;
407  face->glyph = slot;
408 
409  if ( aslot )
410  *aslot = slot;
411  }
412  else if ( aslot )
413  *aslot = 0;
414 
415 
416  Exit:
417  FT_TRACE4(( "FT_New_GlyphSlot: Return %d\n", error ));
418  return error;
419  }
420 
421 
422  /* documentation is in ftobjs.h */
423 
424  FT_BASE_DEF( void )
426  {
427  if ( slot )
428  {
429  FT_Driver driver = slot->face->driver;
430  FT_Memory memory = driver->root.memory;
431  FT_GlyphSlot prev;
432  FT_GlyphSlot cur;
433 
434 
435  /* Remove slot from its parent face's list */
436  prev = NULL;
437  cur = slot->face->glyph;
438 
439  while ( cur )
440  {
441  if ( cur == slot )
442  {
443  if ( !prev )
444  slot->face->glyph = cur->next;
445  else
446  prev->next = cur->next;
447 
448  /* finalize client-specific data */
449  if ( slot->generic.finalizer )
450  slot->generic.finalizer( slot );
451 
452  ft_glyphslot_done( slot );
453  FT_FREE( slot );
454  break;
455  }
456  prev = cur;
457  cur = cur->next;
458  }
459  }
460  }
461 
462 
463  /* documentation is in freetype.h */
464 
465  FT_EXPORT_DEF( void )
467  FT_Matrix* matrix,
468  FT_Vector* delta )
469  {
470  FT_Face_Internal internal;
471 
472 
473  if ( !face )
474  return;
475 
476  internal = face->internal;
477 
478  internal->transform_flags = 0;
479 
480  if ( !matrix )
481  {
482  internal->transform_matrix.xx = 0x10000L;
483  internal->transform_matrix.xy = 0;
484  internal->transform_matrix.yx = 0;
485  internal->transform_matrix.yy = 0x10000L;
486  matrix = &internal->transform_matrix;
487  }
488  else
489  internal->transform_matrix = *matrix;
490 
491  /* set transform_flags bit flag 0 if `matrix' isn't the identity */
492  if ( ( matrix->xy | matrix->yx ) ||
493  matrix->xx != 0x10000L ||
494  matrix->yy != 0x10000L )
495  internal->transform_flags |= 1;
496 
497  if ( !delta )
498  {
499  internal->transform_delta.x = 0;
500  internal->transform_delta.y = 0;
501  delta = &internal->transform_delta;
502  }
503  else
504  internal->transform_delta = *delta;
505 
506  /* set transform_flags bit flag 1 if `delta' isn't the null vector */
507  if ( delta->x | delta->y )
508  internal->transform_flags |= 2;
509  }
510 
511 
512  static FT_Renderer
514 
515 
516 #ifdef GRID_FIT_METRICS
517  static void
519  FT_Bool vertical )
520  {
521  FT_Glyph_Metrics* metrics = &slot->metrics;
523 
524 
525  if ( vertical )
526  {
527  metrics->horiBearingX = FT_PIX_FLOOR( metrics->horiBearingX );
528  metrics->horiBearingY = FT_PIX_CEIL ( metrics->horiBearingY );
529 
530  right = FT_PIX_CEIL( metrics->vertBearingX + metrics->width );
531  bottom = FT_PIX_CEIL( metrics->vertBearingY + metrics->height );
532 
533  metrics->vertBearingX = FT_PIX_FLOOR( metrics->vertBearingX );
534  metrics->vertBearingY = FT_PIX_FLOOR( metrics->vertBearingY );
535 
536  metrics->width = right - metrics->vertBearingX;
537  metrics->height = bottom - metrics->vertBearingY;
538  }
539  else
540  {
541  metrics->vertBearingX = FT_PIX_FLOOR( metrics->vertBearingX );
542  metrics->vertBearingY = FT_PIX_FLOOR( metrics->vertBearingY );
543 
544  right = FT_PIX_CEIL ( metrics->horiBearingX + metrics->width );
545  bottom = FT_PIX_FLOOR( metrics->horiBearingY - metrics->height );
546 
547  metrics->horiBearingX = FT_PIX_FLOOR( metrics->horiBearingX );
548  metrics->horiBearingY = FT_PIX_CEIL ( metrics->horiBearingY );
549 
550  metrics->width = right - metrics->horiBearingX;
551  metrics->height = metrics->horiBearingY - bottom;
552  }
553 
554  metrics->horiAdvance = FT_PIX_ROUND( metrics->horiAdvance );
555  metrics->vertAdvance = FT_PIX_ROUND( metrics->vertAdvance );
556  }
557 #endif /* GRID_FIT_METRICS */
558 
559 
560  /* documentation is in freetype.h */
561 
564  FT_UInt glyph_index,
565  FT_Int32 load_flags )
566  {
567  FT_Error error;
568  FT_Driver driver;
569  FT_GlyphSlot slot;
571  FT_Bool autohint = FALSE;
572  FT_Module hinter;
573  TT_Face ttface = (TT_Face)face;
574 
575 
576  if ( !face || !face->size || !face->glyph )
577  return FT_Err_Invalid_Face_Handle;
578 
579  /* The validity test for `glyph_index' is performed by the */
580  /* font drivers. */
581 
582  slot = face->glyph;
583  ft_glyphslot_clear( slot );
584 
585  driver = face->driver;
586  library = driver->root.library;
587  hinter = library->auto_hinter;
588 
589  /* resolve load flags dependencies */
590 
591  if ( load_flags & FT_LOAD_NO_RECURSE )
592  load_flags |= FT_LOAD_NO_SCALE |
594 
595  if ( load_flags & FT_LOAD_NO_SCALE )
596  {
597  load_flags |= FT_LOAD_NO_HINTING |
599 
600  load_flags &= ~FT_LOAD_RENDER;
601  }
602 
603  /*
604  * Determine whether we need to auto-hint or not.
605  * The general rules are:
606  *
607  * - Do only auto-hinting if we have a hinter module, a scalable font
608  * format dealing with outlines, and no transforms except simple
609  * slants and/or rotations by integer multiples of 90 degrees.
610  *
611  * - Then, auto-hint if FT_LOAD_FORCE_AUTOHINT is set or if we don't
612  * have a native font hinter.
613  *
614  * - Otherwise, auto-hint for LIGHT hinting mode or if there isn't
615  * any hinting bytecode in the TrueType/OpenType font.
616  *
617  * - Exception: The font is `tricky' and requires the native hinter to
618  * load properly.
619  */
620 
621  if ( hinter &&
622  !( load_flags & FT_LOAD_NO_HINTING ) &&
623  !( load_flags & FT_LOAD_NO_AUTOHINT ) &&
624  FT_DRIVER_IS_SCALABLE( driver ) &&
625  FT_DRIVER_USES_OUTLINES( driver ) &&
626  !FT_IS_TRICKY( face ) &&
627  ( ( load_flags & FT_LOAD_IGNORE_TRANSFORM ) ||
628  ( face->internal->transform_matrix.yx == 0 &&
629  face->internal->transform_matrix.xx != 0 ) ||
630  ( face->internal->transform_matrix.xx == 0 &&
631  face->internal->transform_matrix.yx != 0 ) ) )
632  {
633  if ( ( load_flags & FT_LOAD_FORCE_AUTOHINT ) ||
634  !FT_DRIVER_HAS_HINTER( driver ) )
635  autohint = TRUE;
636  else
637  {
638  FT_Render_Mode mode = FT_LOAD_TARGET_MODE( load_flags );
639 
640 
641  /* the check for `num_locations' assures that we actually */
642  /* test for instructions in a TTF and not in a CFF-based OTF */
643  if ( mode == FT_RENDER_MODE_LIGHT ||
644  face->internal->ignore_unpatented_hinter ||
645  ( FT_IS_SFNT( face ) &&
646  ttface->num_locations &&
647  ttface->max_profile.maxSizeOfInstructions == 0 ) )
648  autohint = TRUE;
649  }
650  }
651 
652  if ( autohint )
653  {
654  FT_AutoHinter_Service hinting;
655 
656 
657  /* try to load embedded bitmaps first if available */
658  /* */
659  /* XXX: This is really a temporary hack that should disappear */
660  /* promptly with FreeType 2.1! */
661  /* */
662  if ( FT_HAS_FIXED_SIZES( face ) &&
663  ( load_flags & FT_LOAD_NO_BITMAP ) == 0 )
664  {
665  error = driver->clazz->load_glyph( slot, face->size,
666  glyph_index,
667  load_flags | FT_LOAD_SBITS_ONLY );
668 
669  if ( !error && slot->format == FT_GLYPH_FORMAT_BITMAP )
670  goto Load_Ok;
671  }
672 
673  {
674  FT_Face_Internal internal = face->internal;
675  FT_Int transform_flags = internal->transform_flags;
676 
677 
678  /* since the auto-hinter calls FT_Load_Glyph by itself, */
679  /* make sure that glyphs aren't transformed */
680  internal->transform_flags = 0;
681 
682  /* load auto-hinted outline */
683  hinting = (FT_AutoHinter_Service)hinter->clazz->module_interface;
684 
685  error = hinting->load_glyph( (FT_AutoHinter)hinter,
686  slot, face->size,
687  glyph_index, load_flags );
688 
689  internal->transform_flags = transform_flags;
690  }
691  }
692  else
693  {
694  error = driver->clazz->load_glyph( slot,
695  face->size,
696  glyph_index,
697  load_flags );
698  if ( error )
699  goto Exit;
700 
701  if ( slot->format == FT_GLYPH_FORMAT_OUTLINE )
702  {
703  /* check that the loaded outline is correct */
704  error = FT_Outline_Check( &slot->outline );
705  if ( error )
706  goto Exit;
707 
708 #ifdef GRID_FIT_METRICS
709  if ( !( load_flags & FT_LOAD_NO_HINTING ) )
711  FT_BOOL( load_flags & FT_LOAD_VERTICAL_LAYOUT ) );
712 #endif
713  }
714  }
715 
716  Load_Ok:
717  /* compute the advance */
718  if ( load_flags & FT_LOAD_VERTICAL_LAYOUT )
719  {
720  slot->advance.x = 0;
721  slot->advance.y = slot->metrics.vertAdvance;
722  }
723  else
724  {
725  slot->advance.x = slot->metrics.horiAdvance;
726  slot->advance.y = 0;
727  }
728 
729  /* compute the linear advance in 16.16 pixels */
730  if ( ( load_flags & FT_LOAD_LINEAR_DESIGN ) == 0 &&
731  ( FT_IS_SCALABLE( face ) ) )
732  {
733  FT_Size_Metrics* metrics = &face->size->metrics;
734 
735 
736  /* it's tricky! */
738  metrics->x_scale, 64 );
739 
741  metrics->y_scale, 64 );
742  }
743 
744  if ( ( load_flags & FT_LOAD_IGNORE_TRANSFORM ) == 0 )
745  {
746  FT_Face_Internal internal = face->internal;
747 
748 
749  /* now, transform the glyph image if needed */
750  if ( internal->transform_flags )
751  {
752  /* get renderer */
753  FT_Renderer renderer = ft_lookup_glyph_renderer( slot );
754 
755 
756  if ( renderer )
757  error = renderer->clazz->transform_glyph(
758  renderer, slot,
759  &internal->transform_matrix,
760  &internal->transform_delta );
761  else if ( slot->format == FT_GLYPH_FORMAT_OUTLINE )
762  {
763  /* apply `standard' transformation if no renderer is available */
764  if ( internal->transform_flags & 1 )
766  &internal->transform_matrix );
767 
768  if ( internal->transform_flags & 2 )
770  internal->transform_delta.x,
771  internal->transform_delta.y );
772  }
773 
774  /* transform advance */
775  FT_Vector_Transform( &slot->advance, &internal->transform_matrix );
776  }
777  }
778 
779  FT_TRACE5(( " x advance: %d\n" , slot->advance.x ));
780  FT_TRACE5(( " y advance: %d\n" , slot->advance.y ));
781 
782  FT_TRACE5(( " linear x advance: %d\n" , slot->linearHoriAdvance ));
783  FT_TRACE5(( " linear y advance: %d\n" , slot->linearVertAdvance ));
784 
785  /* do we need to render the image now? */
786  if ( !error &&
787  slot->format != FT_GLYPH_FORMAT_BITMAP &&
788  slot->format != FT_GLYPH_FORMAT_COMPOSITE &&
789  load_flags & FT_LOAD_RENDER )
790  {
791  FT_Render_Mode mode = FT_LOAD_TARGET_MODE( load_flags );
792 
793 
794  if ( mode == FT_RENDER_MODE_NORMAL &&
795  (load_flags & FT_LOAD_MONOCHROME ) )
796  mode = FT_RENDER_MODE_MONO;
797 
798  error = FT_Render_Glyph( slot, mode );
799  }
800 
801  Exit:
802  return error;
803  }
804 
805 
806  /* documentation is in freetype.h */
807 
810  FT_ULong char_code,
811  FT_Int32 load_flags )
812  {
813  FT_UInt glyph_index;
814 
815 
816  if ( !face )
817  return FT_Err_Invalid_Face_Handle;
818 
819  glyph_index = (FT_UInt)char_code;
820  if ( face->charmap )
821  glyph_index = FT_Get_Char_Index( face, char_code );
822 
823  return FT_Load_Glyph( face, glyph_index, load_flags );
824  }
825 
826 
827  /* destructor for sizes list */
828  static void
830  FT_Size size,
831  FT_Driver driver )
832  {
833  /* finalize client-specific data */
834  if ( size->generic.finalizer )
835  size->generic.finalizer( size );
836 
837  /* finalize format-specific stuff */
838  if ( driver->clazz->done_size )
839  driver->clazz->done_size( size );
840 
841  FT_FREE( size->internal );
842  FT_FREE( size );
843  }
844 
845 
846  static void
848 
849 
850  static void
852  FT_Memory memory )
853  {
854  FT_Int n;
855 
856 
857  if ( !face )
858  return;
859 
860  for ( n = 0; n < face->num_charmaps; n++ )
861  {
862  FT_CMap cmap = FT_CMAP( face->charmaps[n] );
863 
864 
865  ft_cmap_done_internal( cmap );
866 
867  face->charmaps[n] = NULL;
868  }
869 
870  FT_FREE( face->charmaps );
871  face->num_charmaps = 0;
872  }
873 
874 
875  /* destructor for faces list */
876  static void
878  FT_Face face,
879  FT_Driver driver )
880  {
881  FT_Driver_Class clazz = driver->clazz;
882 
883 
884  /* discard auto-hinting data */
885  if ( face->autohint.finalizer )
886  face->autohint.finalizer( face->autohint.data );
887 
888  /* Discard glyph slots for this face. */
889  /* Beware! FT_Done_GlyphSlot() changes the field `face->glyph' */
890  while ( face->glyph )
891  FT_Done_GlyphSlot( face->glyph );
892 
893  /* discard all sizes for this face */
896  memory,
897  driver );
898  face->size = 0;
899 
900  /* now discard client data */
901  if ( face->generic.finalizer )
902  face->generic.finalizer( face );
903 
904  /* discard charmaps */
905  destroy_charmaps( face, memory );
906 
907  /* finalize format-specific stuff */
908  if ( clazz->done_face )
909  clazz->done_face( face );
910 
911  /* close the stream for this face if needed */
913  face->stream,
914  ( face->face_flags & FT_FACE_FLAG_EXTERNAL_STREAM ) != 0 );
915 
916  face->stream = 0;
917 
918  /* get rid of it */
919  if ( face->internal )
920  {
921  FT_FREE( face->internal );
922  }
923  FT_FREE( face );
924  }
925 
926 
927  static void
929  {
930  FT_List_Finalize( &driver->faces_list,
932  driver->root.memory,
933  driver );
934 
935  /* check whether we need to drop the driver's glyph loader */
936  if ( FT_DRIVER_USES_OUTLINES( driver ) )
938  }
939 
940 
941  /*************************************************************************/
942  /* */
943  /* <Function> */
944  /* find_unicode_charmap */
945  /* */
946  /* <Description> */
947  /* This function finds a Unicode charmap, if there is one. */
948  /* And if there is more than one, it tries to favour the more */
949  /* extensive one, i.e., one that supports UCS-4 against those which */
950  /* are limited to the BMP (said UCS-2 encoding.) */
951  /* */
952  /* This function is called from open_face() (just below), and also */
953  /* from FT_Select_Charmap( ..., FT_ENCODING_UNICODE ). */
954  /* */
955  static FT_Error
957  {
958  FT_CharMap* first;
959  FT_CharMap* cur;
960 
961 
962  /* caller should have already checked that `face' is valid */
963  FT_ASSERT( face );
964 
965  first = face->charmaps;
966 
967  if ( !first )
968  return FT_Err_Invalid_CharMap_Handle;
969 
970  /*
971  * The original TrueType specification(s) only specified charmap
972  * formats that are capable of mapping 8 or 16 bit character codes to
973  * glyph indices.
974  *
975  * However, recent updates to the Apple and OpenType specifications
976  * introduced new formats that are capable of mapping 32-bit character
977  * codes as well. And these are already used on some fonts, mainly to
978  * map non-BMP Asian ideographs as defined in Unicode.
979  *
980  * For compatibility purposes, these fonts generally come with
981  * *several* Unicode charmaps:
982  *
983  * - One of them in the "old" 16-bit format, that cannot access
984  * all glyphs in the font.
985  *
986  * - Another one in the "new" 32-bit format, that can access all
987  * the glyphs.
988  *
989  * This function has been written to always favor a 32-bit charmap
990  * when found. Otherwise, a 16-bit one is returned when found.
991  */
992 
993  /* Since the `interesting' table, with IDs (3,10), is normally the */
994  /* last one, we loop backwards. This loses with type1 fonts with */
995  /* non-BMP characters (<.0001%), this wins with .ttf with non-BMP */
996  /* chars (.01% ?), and this is the same about 99.99% of the time! */
997 
998  cur = first + face->num_charmaps; /* points after the last one */
999 
1000  for ( ; --cur >= first; )
1001  {
1002  if ( cur[0]->encoding == FT_ENCODING_UNICODE )
1003  {
1004  /* XXX If some new encodings to represent UCS-4 are added, */
1005  /* they should be added here. */
1006  if ( ( cur[0]->platform_id == TT_PLATFORM_MICROSOFT &&
1007  cur[0]->encoding_id == TT_MS_ID_UCS_4 ) ||
1008  ( cur[0]->platform_id == TT_PLATFORM_APPLE_UNICODE &&
1009  cur[0]->encoding_id == TT_APPLE_ID_UNICODE_32 ) )
1010  {
1011 #ifdef FT_MAX_CHARMAP_CACHEABLE
1012  if ( cur - first > FT_MAX_CHARMAP_CACHEABLE )
1013  {
1014  FT_ERROR(( "find_unicode_charmap: UCS-4 cmap is found "
1015  "at too late position (%d)\n", cur - first ));
1016  continue;
1017  }
1018 #endif
1019  face->charmap = cur[0];
1020  return FT_Err_Ok;
1021  }
1022  }
1023  }
1024 
1025  /* We do not have any UCS-4 charmap. */
1026  /* Do the loop again and search for UCS-2 charmaps. */
1027  cur = first + face->num_charmaps;
1028 
1029  for ( ; --cur >= first; )
1030  {
1031  if ( cur[0]->encoding == FT_ENCODING_UNICODE )
1032  {
1033 #ifdef FT_MAX_CHARMAP_CACHEABLE
1034  if ( cur - first > FT_MAX_CHARMAP_CACHEABLE )
1035  {
1036  FT_ERROR(( "find_unicode_charmap: UCS-2 cmap is found "
1037  "at too late position (%d)\n", cur - first ));
1038  continue;
1039  }
1040 #endif
1041  face->charmap = cur[0];
1042  return FT_Err_Ok;
1043  }
1044  }
1045 
1046  return FT_Err_Invalid_CharMap_Handle;
1047  }
1048 
1049 
1050  /*************************************************************************/
1051  /* */
1052  /* <Function> */
1053  /* find_variant_selector_charmap */
1054  /* */
1055  /* <Description> */
1056  /* This function finds the variant selector charmap, if there is one. */
1057  /* There can only be one (platform=0, specific=5, format=14). */
1058  /* */
1059  static FT_CharMap
1061  {
1062  FT_CharMap* first;
1063  FT_CharMap* end;
1064  FT_CharMap* cur;
1065 
1066 
1067  /* caller should have already checked that `face' is valid */
1068  FT_ASSERT( face );
1069 
1070  first = face->charmaps;
1071 
1072  if ( !first )
1073  return NULL;
1074 
1075  end = first + face->num_charmaps; /* points after the last one */
1076 
1077  for ( cur = first; cur < end; ++cur )
1078  {
1079  if ( cur[0]->platform_id == TT_PLATFORM_APPLE_UNICODE &&
1080  cur[0]->encoding_id == TT_APPLE_ID_VARIANT_SELECTOR &&
1081  FT_Get_CMap_Format( cur[0] ) == 14 )
1082  {
1083 #ifdef FT_MAX_CHARMAP_CACHEABLE
1084  if ( cur - first > FT_MAX_CHARMAP_CACHEABLE )
1085  {
1086  FT_ERROR(( "find_unicode_charmap: UVS cmap is found "
1087  "at too late position (%d)\n", cur - first ));
1088  continue;
1089  }
1090 #endif
1091  return cur[0];
1092  }
1093  }
1094 
1095  return NULL;
1096  }
1097 
1098 
1099  /*************************************************************************/
1100  /* */
1101  /* <Function> */
1102  /* open_face */
1103  /* */
1104  /* <Description> */
1105  /* This function does some work for FT_Open_Face(). */
1106  /* */
1107  static FT_Error
1109  FT_Stream stream,
1110  FT_Long face_index,
1111  FT_Int num_params,
1113  FT_Face *aface )
1114  {
1115  FT_Memory memory;
1116  FT_Driver_Class clazz;
1117  FT_Face face = 0;
1118  FT_Error error, error2;
1119  FT_Face_Internal internal = NULL;
1120 
1121 
1122  clazz = driver->clazz;
1123  memory = driver->root.memory;
1124 
1125  /* allocate the face object and perform basic initialization */
1126  if ( FT_ALLOC( face, clazz->face_object_size ) )
1127  goto Fail;
1128 
1129  if ( FT_NEW( internal ) )
1130  goto Fail;
1131 
1132  face->internal = internal;
1133 
1134  face->driver = driver;
1135  face->memory = memory;
1136  face->stream = stream;
1137 
1138 #ifdef FT_CONFIG_OPTION_INCREMENTAL
1139  {
1140  int i;
1141 
1142 
1143  face->internal->incremental_interface = 0;
1144  for ( i = 0; i < num_params && !face->internal->incremental_interface;
1145  i++ )
1146  if ( params[i].tag == FT_PARAM_TAG_INCREMENTAL )
1147  face->internal->incremental_interface =
1148  (FT_Incremental_Interface)params[i].data;
1149  }
1150 #endif
1151 
1152  if ( clazz->init_face )
1153  error = clazz->init_face( stream,
1154  face,
1155  (FT_Int)face_index,
1156  num_params,
1157  params );
1158  if ( error )
1159  goto Fail;
1160 
1161  /* select Unicode charmap by default */
1162  error2 = find_unicode_charmap( face );
1163 
1164  /* if no Unicode charmap can be found, FT_Err_Invalid_CharMap_Handle */
1165  /* is returned. */
1166 
1167  /* no error should happen, but we want to play safe */
1168  if ( error2 && error2 != FT_Err_Invalid_CharMap_Handle )
1169  {
1170  error = error2;
1171  goto Fail;
1172  }
1173 
1174  *aface = face;
1175 
1176  Fail:
1177  if ( error )
1178  {
1179  destroy_charmaps( face, memory );
1180  if ( clazz->done_face )
1181  clazz->done_face( face );
1182  FT_FREE( internal );
1183  FT_FREE( face );
1184  *aface = 0;
1185  }
1186 
1187  return error;
1188  }
1189 
1190 
1191  /* there's a Mac-specific extended implementation of FT_New_Face() */
1192  /* in src/base/ftmac.c */
1193 
1194 #ifndef FT_MACINTOSH
1195 
1196  /* documentation is in freetype.h */
1197 
1200  const char* pathname,
1201  FT_Long face_index,
1202  FT_Face *aface )
1203  {
1204  FT_Open_Args args;
1205 
1206 
1207  /* test for valid `library' and `aface' delayed to FT_Open_Face() */
1208  if ( !pathname )
1209  return FT_Err_Invalid_Argument;
1210 
1211  args.flags = FT_OPEN_PATHNAME;
1212  args.pathname = (char*)pathname;
1213  args.stream = NULL;
1214 
1215  return FT_Open_Face( library, &args, face_index, aface );
1216  }
1217 
1218 #endif
1219 
1220 
1221  /* documentation is in freetype.h */
1222 
1225  const FT_Byte* file_base,
1226  FT_Long file_size,
1227  FT_Long face_index,
1228  FT_Face *aface )
1229  {
1230  FT_Open_Args args;
1231 
1232 
1233  /* test for valid `library' and `face' delayed to FT_Open_Face() */
1234  if ( !file_base )
1235  return FT_Err_Invalid_Argument;
1236 
1237  args.flags = FT_OPEN_MEMORY;
1238  args.memory_base = file_base;
1239  args.memory_size = file_size;
1240  args.stream = NULL;
1241 
1242  return FT_Open_Face( library, &args, face_index, aface );
1243  }
1244 
1245 
1246 #ifdef FT_CONFIG_OPTION_MAC_FONTS
1247 
1248  /* The behavior here is very similar to that in base/ftmac.c, but it */
1249  /* is designed to work on non-mac systems, so no mac specific calls. */
1250  /* */
1251  /* We look at the file and determine if it is a mac dfont file or a mac */
1252  /* resource file, or a macbinary file containing a mac resource file. */
1253  /* */
1254  /* Unlike ftmac I'm not going to look at a `FOND'. I don't really see */
1255  /* the point, especially since there may be multiple `FOND' resources. */
1256  /* Instead I'll just look for `sfnt' and `POST' resources, ordered as */
1257  /* they occur in the file. */
1258  /* */
1259  /* Note that multiple `POST' resources do not mean multiple postscript */
1260  /* fonts; they all get jammed together to make what is essentially a */
1261  /* pfb file. */
1262  /* */
1263  /* We aren't interested in `NFNT' or `FONT' bitmap resources. */
1264  /* */
1265  /* As soon as we get an `sfnt' load it into memory and pass it off to */
1266  /* FT_Open_Face. */
1267  /* */
1268  /* If we have a (set of) `POST' resources, massage them into a (memory) */
1269  /* pfb file and pass that to FT_Open_Face. (As with ftmac.c I'm not */
1270  /* going to try to save the kerning info. After all that lives in the */
1271  /* `FOND' which isn't in the file containing the `POST' resources so */
1272  /* we don't really have access to it. */
1273 
1274 
1275  /* Finalizer for a memory stream; gets called by FT_Done_Face(). */
1276  /* It frees the memory it uses. */
1277  /* From ftmac.c. */
1278  static void
1279  memory_stream_close( FT_Stream stream )
1280  {
1281  FT_Memory memory = stream->memory;
1282 
1283 
1284  FT_FREE( stream->base );
1285 
1286  stream->size = 0;
1287  stream->base = 0;
1288  stream->close = 0;
1289  }
1290 
1291 
1292  /* Create a new memory stream from a buffer and a size. */
1293  /* From ftmac.c. */
1294  static FT_Error
1295  new_memory_stream( FT_Library library,
1296  FT_Byte* base,
1297  FT_ULong size,
1298  FT_Stream_CloseFunc close,
1299  FT_Stream *astream )
1300  {
1301  FT_Error error;
1302  FT_Memory memory;
1303  FT_Stream stream = NULL;
1304 
1305 
1306  if ( !library )
1307  return FT_Err_Invalid_Library_Handle;
1308 
1309  if ( !base )
1310  return FT_Err_Invalid_Argument;
1311 
1312  *astream = 0;
1313  memory = library->memory;
1314  if ( FT_NEW( stream ) )
1315  goto Exit;
1316 
1317  FT_Stream_OpenMemory( stream, base, size );
1318 
1319  stream->close = close;
1320 
1321  *astream = stream;
1322 
1323  Exit:
1324  return error;
1325  }
1326 
1327 
1328  /* Create a new FT_Face given a buffer and a driver name. */
1329  /* from ftmac.c */
1332  FT_Byte* base,
1333  FT_ULong size,
1334  FT_Long face_index,
1335  const char* driver_name,
1336  FT_Face *aface )
1337  {
1338  FT_Open_Args args;
1339  FT_Error error;
1340  FT_Stream stream = NULL;
1341  FT_Memory memory = library->memory;
1342 
1343 
1344  error = new_memory_stream( library,
1345  base,
1346  size,
1347  memory_stream_close,
1348  &stream );
1349  if ( error )
1350  {
1351  FT_FREE( base );
1352  return error;
1353  }
1354 
1355  args.flags = FT_OPEN_STREAM;
1356  args.stream = stream;
1357  if ( driver_name )
1358  {
1359  args.flags = args.flags | FT_OPEN_DRIVER;
1360  args.driver = FT_Get_Module( library, driver_name );
1361  }
1362 
1363 #ifdef FT_MACINTOSH
1364  /* At this point, face_index has served its purpose; */
1365  /* whoever calls this function has already used it to */
1366  /* locate the correct font data. We should not propagate */
1367  /* this index to FT_Open_Face() (unless it is negative). */
1368 
1369  if ( face_index > 0 )
1370  face_index = 0;
1371 #endif
1372 
1373  error = FT_Open_Face( library, &args, face_index, aface );
1374 
1375  if ( error == FT_Err_Ok )
1376  (*aface)->face_flags &= ~FT_FACE_FLAG_EXTERNAL_STREAM;
1377  else
1378 #ifdef FT_MACINTOSH
1379  FT_Stream_Free( stream, 0 );
1380 #else
1381  {
1382  FT_Stream_Close( stream );
1383  FT_FREE( stream );
1384  }
1385 #endif
1386 
1387  return error;
1388  }
1389 
1390 
1391  /* Look up `TYP1' or `CID ' table from sfnt table directory. */
1392  /* `offset' and `length' must exclude the binary header in tables. */
1393 
1394  /* Type 1 and CID-keyed font drivers should recognize sfnt-wrapped */
1395  /* format too. Here, since we can't expect that the TrueType font */
1396  /* driver is loaded unconditially, we must parse the font by */
1397  /* ourselves. We are only interested in the name of the table and */
1398  /* the offset. */
1399 
1400  static FT_Error
1401  ft_lookup_PS_in_sfnt_stream( FT_Stream stream,
1402  FT_Long face_index,
1403  FT_ULong* offset,
1404  FT_ULong* length,
1405  FT_Bool* is_sfnt_cid )
1406  {
1407  FT_Error error;
1408  FT_UShort numTables;
1409  FT_Long pstable_index;
1410  FT_ULong tag;
1411  int i;
1412 
1413 
1414  *offset = 0;
1415  *length = 0;
1416  *is_sfnt_cid = FALSE;
1417 
1418  /* TODO: support for sfnt-wrapped PS/CID in TTC format */
1419 
1420  /* version check for 'typ1' (should be ignored?) */
1421  if ( FT_READ_ULONG( tag ) )
1422  return error;
1423  if ( tag != TTAG_typ1 )
1424  return FT_Err_Unknown_File_Format;
1425 
1426  if ( FT_READ_USHORT( numTables ) )
1427  return error;
1428  if ( FT_STREAM_SKIP( 2 * 3 ) ) /* skip binary search header */
1429  return error;
1430 
1431  pstable_index = -1;
1432  *is_sfnt_cid = FALSE;
1433 
1434  for ( i = 0; i < numTables; i++ )
1435  {
1436  if ( FT_READ_ULONG( tag ) || FT_STREAM_SKIP( 4 ) ||
1437  FT_READ_ULONG( *offset ) || FT_READ_ULONG( *length ) )
1438  return error;
1439 
1440  if ( tag == TTAG_CID )
1441  {
1442  pstable_index++;
1443  *offset += 22;
1444  *length -= 22;
1445  *is_sfnt_cid = TRUE;
1446  if ( face_index < 0 )
1447  return FT_Err_Ok;
1448  }
1449  else if ( tag == TTAG_TYP1 )
1450  {
1451  pstable_index++;
1452  *offset += 24;
1453  *length -= 24;
1454  *is_sfnt_cid = FALSE;
1455  if ( face_index < 0 )
1456  return FT_Err_Ok;
1457  }
1458  if ( face_index >= 0 && pstable_index == face_index )
1459  return FT_Err_Ok;
1460  }
1461  return FT_Err_Table_Missing;
1462  }
1463 
1464 
1467  FT_Stream stream,
1468  FT_Long face_index,
1469  FT_Int num_params,
1471  FT_Face *aface )
1472  {
1473  FT_Error error;
1474  FT_Memory memory = library->memory;
1476  FT_Long pos;
1477  FT_Bool is_sfnt_cid;
1478  FT_Byte* sfnt_ps = NULL;
1479 
1480  FT_UNUSED( num_params );
1481  FT_UNUSED( params );
1482 
1483 
1484  pos = FT_Stream_Pos( stream );
1485 
1486  error = ft_lookup_PS_in_sfnt_stream( stream,
1487  face_index,
1488  &offset,
1489  &length,
1490  &is_sfnt_cid );
1491  if ( error )
1492  goto Exit;
1493 
1494  if ( FT_Stream_Seek( stream, pos + offset ) )
1495  goto Exit;
1496 
1497  if ( FT_ALLOC( sfnt_ps, (FT_Long)length ) )
1498  goto Exit;
1499 
1500  error = FT_Stream_Read( stream, (FT_Byte *)sfnt_ps, length );
1501  if ( error )
1502  goto Exit;
1503 
1504  error = open_face_from_buffer( library,
1505  sfnt_ps,
1506  length,
1507  face_index < 0 ? face_index : 0,
1508  is_sfnt_cid ? "cid" : "type1",
1509  aface );
1510  Exit:
1511  {
1512  FT_Error error1;
1513 
1514 
1515  if ( error == FT_Err_Unknown_File_Format )
1516  {
1517  error1 = FT_Stream_Seek( stream, pos );
1518  if ( error1 )
1519  return error1;
1520  }
1521 
1522  return error;
1523  }
1524  }
1525 
1526 
1527 #ifndef FT_MACINTOSH
1528 
1529  /* The resource header says we've got resource_cnt `POST' (type1) */
1530  /* resources in this file. They all need to be coalesced into */
1531  /* one lump which gets passed on to the type1 driver. */
1532  /* Here can be only one PostScript font in a file so face_index */
1533  /* must be 0 (or -1). */
1534  /* */
1535  static FT_Error
1536  Mac_Read_POST_Resource( FT_Library library,
1537  FT_Stream stream,
1538  FT_Long *offsets,
1539  FT_Long resource_cnt,
1540  FT_Long face_index,
1541  FT_Face *aface )
1542  {
1543  FT_Error error = FT_Err_Cannot_Open_Resource;
1544  FT_Memory memory = library->memory;
1545  FT_Byte* pfb_data = NULL;
1546  int i, type, flags;
1547  FT_Long len;
1548  FT_Long pfb_len, pfb_pos, pfb_lenpos;
1549  FT_Long rlen, temp;
1550 
1551 
1552  if ( face_index == -1 )
1553  face_index = 0;
1554  if ( face_index != 0 )
1555  return error;
1556 
1557  /* Find the length of all the POST resources, concatenated. Assume */
1558  /* worst case (each resource in its own section). */
1559  pfb_len = 0;
1560  for ( i = 0; i < resource_cnt; ++i )
1561  {
1562  error = FT_Stream_Seek( stream, offsets[i] );
1563  if ( error )
1564  goto Exit;
1565  if ( FT_READ_LONG( temp ) )
1566  goto Exit;
1567  pfb_len += temp + 6;
1568  }
1569 
1570  if ( FT_ALLOC( pfb_data, (FT_Long)pfb_len + 2 ) )
1571  goto Exit;
1572 
1573  pfb_data[0] = 0x80;
1574  pfb_data[1] = 1; /* Ascii section */
1575  pfb_data[2] = 0; /* 4-byte length, fill in later */
1576  pfb_data[3] = 0;
1577  pfb_data[4] = 0;
1578  pfb_data[5] = 0;
1579  pfb_pos = 6;
1580  pfb_lenpos = 2;
1581 
1582  len = 0;
1583  type = 1;
1584  for ( i = 0; i < resource_cnt; ++i )
1585  {
1586  error = FT_Stream_Seek( stream, offsets[i] );
1587  if ( error )
1588  goto Exit2;
1589  if ( FT_READ_LONG( rlen ) )
1590  goto Exit;
1591  if ( FT_READ_USHORT( flags ) )
1592  goto Exit;
1593  FT_TRACE3(( "POST fragment[%d]: offsets=0x%08x, rlen=0x%08x, flags=0x%04x\n",
1594  i, offsets[i], rlen, flags ));
1595 
1596  /* postpone the check of rlen longer than buffer until FT_Stream_Read() */
1597  if ( ( flags >> 8 ) == 0 ) /* Comment, should not be loaded */
1598  continue;
1599 
1600  /* the flags are part of the resource, so rlen >= 2. */
1601  /* but some fonts declare rlen = 0 for empty fragment */
1602  if ( rlen > 2 )
1603  rlen -= 2;
1604  else
1605  rlen = 0;
1606 
1607  if ( ( flags >> 8 ) == type )
1608  len += rlen;
1609  else
1610  {
1611  if ( pfb_lenpos + 3 > pfb_len + 2 )
1612  goto Exit2;
1613  pfb_data[pfb_lenpos ] = (FT_Byte)( len );
1614  pfb_data[pfb_lenpos + 1] = (FT_Byte)( len >> 8 );
1615  pfb_data[pfb_lenpos + 2] = (FT_Byte)( len >> 16 );
1616  pfb_data[pfb_lenpos + 3] = (FT_Byte)( len >> 24 );
1617 
1618  if ( ( flags >> 8 ) == 5 ) /* End of font mark */
1619  break;
1620 
1621  if ( pfb_pos + 6 > pfb_len + 2 )
1622  goto Exit2;
1623  pfb_data[pfb_pos++] = 0x80;
1624 
1625  type = flags >> 8;
1626  len = rlen;
1627 
1628  pfb_data[pfb_pos++] = (FT_Byte)type;
1629  pfb_lenpos = pfb_pos;
1630  pfb_data[pfb_pos++] = 0; /* 4-byte length, fill in later */
1631  pfb_data[pfb_pos++] = 0;
1632  pfb_data[pfb_pos++] = 0;
1633  pfb_data[pfb_pos++] = 0;
1634  }
1635 
1636  error = FT_Err_Cannot_Open_Resource;
1637  if ( pfb_pos > pfb_len || pfb_pos + rlen > pfb_len )
1638  goto Exit2;
1639 
1640  error = FT_Stream_Read( stream, (FT_Byte *)pfb_data + pfb_pos, rlen );
1641  if ( error )
1642  goto Exit2;
1643  pfb_pos += rlen;
1644  }
1645 
1646  if ( pfb_pos + 2 > pfb_len + 2 )
1647  goto Exit2;
1648  pfb_data[pfb_pos++] = 0x80;
1649  pfb_data[pfb_pos++] = 3;
1650 
1651  if ( pfb_lenpos + 3 > pfb_len + 2 )
1652  goto Exit2;
1653  pfb_data[pfb_lenpos ] = (FT_Byte)( len );
1654  pfb_data[pfb_lenpos + 1] = (FT_Byte)( len >> 8 );
1655  pfb_data[pfb_lenpos + 2] = (FT_Byte)( len >> 16 );
1656  pfb_data[pfb_lenpos + 3] = (FT_Byte)( len >> 24 );
1657 
1658  return open_face_from_buffer( library,
1659  pfb_data,
1660  pfb_pos,
1661  face_index,
1662  "type1",
1663  aface );
1664 
1665  Exit2:
1666  FT_FREE( pfb_data );
1667 
1668  Exit:
1669  return error;
1670  }
1671 
1672 
1673  /* The resource header says we've got resource_cnt `sfnt' */
1674  /* (TrueType/OpenType) resources in this file. Look through */
1675  /* them for the one indicated by face_index, load it into mem, */
1676  /* pass it on the the truetype driver and return it. */
1677  /* */
1678  static FT_Error
1679  Mac_Read_sfnt_Resource( FT_Library library,
1680  FT_Stream stream,
1681  FT_Long *offsets,
1682  FT_Long resource_cnt,
1683  FT_Long face_index,
1684  FT_Face *aface )
1685  {
1686  FT_Memory memory = library->memory;
1687  FT_Byte* sfnt_data = NULL;
1688  FT_Error error;
1689  FT_Long flag_offset;
1690  FT_Long rlen;
1691  int is_cff;
1692  FT_Long face_index_in_resource = 0;
1693 
1694 
1695  if ( face_index == -1 )
1696  face_index = 0;
1697  if ( face_index >= resource_cnt )
1698  return FT_Err_Cannot_Open_Resource;
1699 
1700  flag_offset = offsets[face_index];
1701  error = FT_Stream_Seek( stream, flag_offset );
1702  if ( error )
1703  goto Exit;
1704 
1705  if ( FT_READ_LONG( rlen ) )
1706  goto Exit;
1707  if ( rlen == -1 )
1708  return FT_Err_Cannot_Open_Resource;
1709 
1710  error = open_face_PS_from_sfnt_stream( library,
1711  stream,
1712  face_index,
1713  0, NULL,
1714  aface );
1715  if ( !error )
1716  goto Exit;
1717 
1718  /* rewind sfnt stream before open_face_PS_from_sfnt_stream() */
1719  if ( FT_Stream_Seek( stream, flag_offset + 4 ) )
1720  goto Exit;
1721 
1722  if ( FT_ALLOC( sfnt_data, (FT_Long)rlen ) )
1723  return error;
1724  error = FT_Stream_Read( stream, (FT_Byte *)sfnt_data, rlen );
1725  if ( error )
1726  goto Exit;
1727 
1728  is_cff = rlen > 4 && !ft_memcmp( sfnt_data, "OTTO", 4 );
1729  error = open_face_from_buffer( library,
1730  sfnt_data,
1731  rlen,
1732  face_index_in_resource,
1733  is_cff ? "cff" : "truetype",
1734  aface );
1735 
1736  Exit:
1737  return error;
1738  }
1739 
1740 
1741  /* Check for a valid resource fork header, or a valid dfont */
1742  /* header. In a resource fork the first 16 bytes are repeated */
1743  /* at the location specified by bytes 4-7. In a dfont bytes */
1744  /* 4-7 point to 16 bytes of zeroes instead. */
1745  /* */
1746  static FT_Error
1747  IsMacResource( FT_Library library,
1748  FT_Stream stream,
1749  FT_Long resource_offset,
1750  FT_Long face_index,
1751  FT_Face *aface )
1752  {
1753  FT_Memory memory = library->memory;
1754  FT_Error error;
1755  FT_Long map_offset, rdara_pos;
1756  FT_Long *data_offsets;
1757  FT_Long count;
1758 
1759 
1760  error = FT_Raccess_Get_HeaderInfo( library, stream, resource_offset,
1761  &map_offset, &rdara_pos );
1762  if ( error )
1763  return error;
1764 
1765  error = FT_Raccess_Get_DataOffsets( library, stream,
1766  map_offset, rdara_pos,
1767  TTAG_POST,
1768  &data_offsets, &count );
1769  if ( !error )
1770  {
1771  error = Mac_Read_POST_Resource( library, stream, data_offsets, count,
1772  face_index, aface );
1773  FT_FREE( data_offsets );
1774  /* POST exists in an LWFN providing a single face */
1775  if ( !error )
1776  (*aface)->num_faces = 1;
1777  return error;
1778  }
1779 
1780  error = FT_Raccess_Get_DataOffsets( library, stream,
1781  map_offset, rdara_pos,
1782  TTAG_sfnt,
1783  &data_offsets, &count );
1784  if ( !error )
1785  {
1786  FT_Long face_index_internal = face_index % count;
1787 
1788 
1789  error = Mac_Read_sfnt_Resource( library, stream, data_offsets, count,
1790  face_index_internal, aface );
1791  FT_FREE( data_offsets );
1792  if ( !error )
1793  (*aface)->num_faces = count;
1794  }
1795 
1796  return error;
1797  }
1798 
1799 
1800  /* Check for a valid macbinary header, and if we find one */
1801  /* check that the (flattened) resource fork in it is valid. */
1802  /* */
1803  static FT_Error
1804  IsMacBinary( FT_Library library,
1805  FT_Stream stream,
1806  FT_Long face_index,
1807  FT_Face *aface )
1808  {
1809  unsigned char header[128];
1810  FT_Error error;
1811  FT_Long dlen, offset;
1812 
1813 
1814  if ( NULL == stream )
1815  return FT_Err_Invalid_Stream_Operation;
1816 
1817  error = FT_Stream_Seek( stream, 0 );
1818  if ( error )
1819  goto Exit;
1820 
1821  error = FT_Stream_Read( stream, (FT_Byte*)header, 128 );
1822  if ( error )
1823  goto Exit;
1824 
1825  if ( header[ 0] != 0 ||
1826  header[74] != 0 ||
1827  header[82] != 0 ||
1828  header[ 1] == 0 ||
1829  header[ 1] > 33 ||
1830  header[63] != 0 ||
1831  header[2 + header[1]] != 0 )
1832  return FT_Err_Unknown_File_Format;
1833 
1834  dlen = ( header[0x53] << 24 ) |
1835  ( header[0x54] << 16 ) |
1836  ( header[0x55] << 8 ) |
1837  header[0x56];
1838 #if 0
1839  rlen = ( header[0x57] << 24 ) |
1840  ( header[0x58] << 16 ) |
1841  ( header[0x59] << 8 ) |
1842  header[0x5a];
1843 #endif /* 0 */
1844  offset = 128 + ( ( dlen + 127 ) & ~127 );
1845 
1846  return IsMacResource( library, stream, offset, face_index, aface );
1847 
1848  Exit:
1849  return error;
1850  }
1851 
1852 
1853  static FT_Error
1854  load_face_in_embedded_rfork( FT_Library library,
1855  FT_Stream stream,
1856  FT_Long face_index,
1857  FT_Face *aface,
1858  const FT_Open_Args *args )
1859  {
1860 
1861 #undef FT_COMPONENT
1862 #define FT_COMPONENT trace_raccess
1863 
1864  FT_Memory memory = library->memory;
1865  FT_Error error = FT_Err_Unknown_File_Format;
1866  int i;
1867 
1868  char * file_names[FT_RACCESS_N_RULES];
1869  FT_Long offsets[FT_RACCESS_N_RULES];
1870  FT_Error errors[FT_RACCESS_N_RULES];
1871  FT_Bool is_darwin_vfs, vfs_rfork_has_no_font = FALSE; /* not tested */
1872 
1873  FT_Open_Args args2;
1874  FT_Stream stream2 = 0;
1875 
1876 
1877  FT_Raccess_Guess( library, stream,
1878  args->pathname, file_names, offsets, errors );
1879 
1880  for ( i = 0; i < FT_RACCESS_N_RULES; i++ )
1881  {
1882  is_darwin_vfs = ft_raccess_rule_by_darwin_vfs( library, i );
1883  if ( is_darwin_vfs && vfs_rfork_has_no_font )
1884  {
1885  FT_TRACE3(( "Skip rule %d: darwin vfs resource fork"
1886  " is already checked and"
1887  " no font is found\n", i ));
1888  continue;
1889  }
1890 
1891  if ( errors[i] )
1892  {
1893  FT_TRACE3(( "Error[%d] has occurred in rule %d\n", errors[i], i ));
1894  continue;
1895  }
1896 
1897  args2.flags = FT_OPEN_PATHNAME;
1898  args2.pathname = file_names[i] ? file_names[i] : args->pathname;
1899 
1900  FT_TRACE3(( "Try rule %d: %s (offset=%d) ...",
1901  i, args2.pathname, offsets[i] ));
1902 
1903  error = FT_Stream_New( library, &args2, &stream2 );
1904  if ( is_darwin_vfs && error == FT_Err_Cannot_Open_Stream )
1905  vfs_rfork_has_no_font = TRUE;
1906 
1907  if ( error )
1908  {
1909  FT_TRACE3(( "failed\n" ));
1910  continue;
1911  }
1912 
1913  error = IsMacResource( library, stream2, offsets[i],
1914  face_index, aface );
1915  FT_Stream_Free( stream2, 0 );
1916 
1917  FT_TRACE3(( "%s\n", error ? "failed": "successful" ));
1918 
1919  if ( !error )
1920  break;
1921  else if ( is_darwin_vfs )
1922  vfs_rfork_has_no_font = TRUE;
1923  }
1924 
1925  for (i = 0; i < FT_RACCESS_N_RULES; i++)
1926  {
1927  if ( file_names[i] )
1928  FT_FREE( file_names[i] );
1929  }
1930 
1931  /* Caller (load_mac_face) requires FT_Err_Unknown_File_Format. */
1932  if ( error )
1933  error = FT_Err_Unknown_File_Format;
1934 
1935  return error;
1936 
1937 #undef FT_COMPONENT
1938 #define FT_COMPONENT trace_objs
1939 
1940  }
1941 
1942 
1943  /* Check for some macintosh formats without Carbon framework. */
1944  /* Is this a macbinary file? If so look at the resource fork. */
1945  /* Is this a mac dfont file? */
1946  /* Is this an old style resource fork? (in data) */
1947  /* Else call load_face_in_embedded_rfork to try extra rules */
1948  /* (defined in `ftrfork.c'). */
1949  /* */
1950  static FT_Error
1951  load_mac_face( FT_Library library,
1952  FT_Stream stream,
1953  FT_Long face_index,
1954  FT_Face *aface,
1955  const FT_Open_Args *args )
1956  {
1957  FT_Error error;
1958  FT_UNUSED( args );
1959 
1960 
1961  error = IsMacBinary( library, stream, face_index, aface );
1962  if ( FT_ERROR_BASE( error ) == FT_Err_Unknown_File_Format )
1963  {
1964 
1965 #undef FT_COMPONENT
1966 #define FT_COMPONENT trace_raccess
1967 
1968  FT_TRACE3(( "Try as dfont: %s ...", args->pathname ));
1969 
1970  error = IsMacResource( library, stream, 0, face_index, aface );
1971 
1972  FT_TRACE3(( "%s\n", error ? "failed" : "successful" ));
1973 
1974 #undef FT_COMPONENT
1975 #define FT_COMPONENT trace_objs
1976 
1977  }
1978 
1979  if ( ( FT_ERROR_BASE( error ) == FT_Err_Unknown_File_Format ||
1980  FT_ERROR_BASE( error ) == FT_Err_Invalid_Stream_Operation ) &&
1981  ( args->flags & FT_OPEN_PATHNAME ) )
1982  error = load_face_in_embedded_rfork( library, stream,
1983  face_index, aface, args );
1984  return error;
1985  }
1986 #endif
1987 
1988 #endif /* !FT_MACINTOSH && FT_CONFIG_OPTION_MAC_FONTS */
1989 
1990 
1991  /* documentation is in freetype.h */
1992 
1995  const FT_Open_Args* args,
1996  FT_Long face_index,
1997  FT_Face *aface )
1998  {
1999  FT_Error error;
2000  FT_Driver driver;
2001  FT_Memory memory;
2002  FT_Stream stream = NULL;
2003  FT_Face face = NULL;
2004  FT_ListNode node = NULL;
2005  FT_Bool external_stream;
2006  FT_Module* cur;
2007  FT_Module* limit;
2008 
2009 
2010  /* test for valid `library' delayed to */
2011  /* FT_Stream_New() */
2012 
2013  if ( ( !aface && face_index >= 0 ) || !args )
2014  return FT_Err_Invalid_Argument;
2015 
2016  external_stream = FT_BOOL( ( args->flags & FT_OPEN_STREAM ) &&
2017  args->stream );
2018 
2019  /* create input stream */
2020  error = FT_Stream_New( library, args, &stream );
2021  if ( error )
2022  goto Fail3;
2023 
2024  memory = library->memory;
2025 
2026  /* If the font driver is specified in the `args' structure, use */
2027  /* it. Otherwise, we scan the list of registered drivers. */
2028  if ( ( args->flags & FT_OPEN_DRIVER ) && args->driver )
2029  {
2030  driver = FT_DRIVER( args->driver );
2031 
2032  /* not all modules are drivers, so check... */
2033  if ( FT_MODULE_IS_DRIVER( driver ) )
2034  {
2035  FT_Int num_params = 0;
2036  FT_Parameter* params = 0;
2037 
2038 
2039  if ( args->flags & FT_OPEN_PARAMS )
2040  {
2041  num_params = args->num_params;
2042  params = args->params;
2043  }
2044 
2045  error = open_face( driver, stream, face_index,
2046  num_params, params, &face );
2047  if ( !error )
2048  goto Success;
2049  }
2050  else
2051  error = FT_Err_Invalid_Handle;
2052 
2053  FT_Stream_Free( stream, external_stream );
2054  goto Fail;
2055  }
2056  else
2057  {
2058  /* check each font driver for an appropriate format */
2059  cur = library->modules;
2060  limit = cur + library->num_modules;
2061 
2062 
2063  for ( ; cur < limit; cur++ )
2064  {
2065  /* not all modules are font drivers, so check... */
2066  if ( FT_MODULE_IS_DRIVER( cur[0] ) )
2067  {
2068  FT_Int num_params = 0;
2069  FT_Parameter* params = 0;
2070 
2071 
2072  driver = FT_DRIVER( cur[0] );
2073 
2074  if ( args->flags & FT_OPEN_PARAMS )
2075  {
2076  num_params = args->num_params;
2077  params = args->params;
2078  }
2079 
2080  error = open_face( driver, stream, face_index,
2081  num_params, params, &face );
2082  if ( !error )
2083  goto Success;
2084 
2085 #ifdef FT_CONFIG_OPTION_MAC_FONTS
2086  if ( ft_strcmp( cur[0]->clazz->module_name, "truetype" ) == 0 &&
2087  FT_ERROR_BASE( error ) == FT_Err_Table_Missing )
2088  {
2089  /* TrueType but essential tables are missing */
2090  if ( FT_Stream_Seek( stream, 0 ) )
2091  break;
2092 
2093  error = open_face_PS_from_sfnt_stream( library,
2094  stream,
2095  face_index,
2096  num_params,
2097  params,
2098  aface );
2099  if ( !error )
2100  {
2101  FT_Stream_Free( stream, external_stream );
2102  return error;
2103  }
2104  }
2105 #endif
2106 
2107  if ( FT_ERROR_BASE( error ) != FT_Err_Unknown_File_Format )
2108  goto Fail3;
2109  }
2110  }
2111 
2112  Fail3:
2113  /* If we are on the mac, and we get an FT_Err_Invalid_Stream_Operation */
2114  /* it may be because we have an empty data fork, so we need to check */
2115  /* the resource fork. */
2116  if ( FT_ERROR_BASE( error ) != FT_Err_Cannot_Open_Stream &&
2117  FT_ERROR_BASE( error ) != FT_Err_Unknown_File_Format &&
2118  FT_ERROR_BASE( error ) != FT_Err_Invalid_Stream_Operation )
2119  goto Fail2;
2120 
2121 #if !defined( FT_MACINTOSH ) && defined( FT_CONFIG_OPTION_MAC_FONTS )
2122  error = load_mac_face( library, stream, face_index, aface, args );
2123  if ( !error )
2124  {
2125  /* We don't want to go to Success here. We've already done that. */
2126  /* On the other hand, if we succeeded we still need to close this */
2127  /* stream (we opened a different stream which extracted the */
2128  /* interesting information out of this stream here. That stream */
2129  /* will still be open and the face will point to it). */
2130  FT_Stream_Free( stream, external_stream );
2131  return error;
2132  }
2133 
2134  if ( FT_ERROR_BASE( error ) != FT_Err_Unknown_File_Format )
2135  goto Fail2;
2136 #endif /* !FT_MACINTOSH && FT_CONFIG_OPTION_MAC_FONTS */
2137 
2138  /* no driver is able to handle this format */
2139  error = FT_Err_Unknown_File_Format;
2140 
2141  Fail2:
2142  FT_Stream_Free( stream, external_stream );
2143  goto Fail;
2144  }
2145 
2146  Success:
2147  FT_TRACE4(( "FT_Open_Face: New face object, adding to list\n" ));
2148 
2149  /* set the FT_FACE_FLAG_EXTERNAL_STREAM bit for FT_Done_Face */
2150  if ( external_stream )
2152 
2153  /* add the face object to its driver's list */
2154  if ( FT_NEW( node ) )
2155  goto Fail;
2156 
2157  node->data = face;
2158  /* don't assume driver is the same as face->driver, so use */
2159  /* face->driver instead. */
2160  FT_List_Add( &face->driver->faces_list, node );
2161 
2162  /* now allocate a glyph slot object for the face */
2163  FT_TRACE4(( "FT_Open_Face: Creating glyph slot\n" ));
2164 
2165  if ( face_index >= 0 )
2166  {
2167  error = FT_New_GlyphSlot( face, NULL );
2168  if ( error )
2169  goto Fail;
2170 
2171  /* finally, allocate a size object for the face */
2172  {
2173  FT_Size size;
2174 
2175 
2176  FT_TRACE4(( "FT_Open_Face: Creating size object\n" ));
2177 
2178  error = FT_New_Size( face, &size );
2179  if ( error )
2180  goto Fail;
2181 
2182  face->size = size;
2183  }
2184  }
2185 
2186  /* some checks */
2187 
2188  if ( FT_IS_SCALABLE( face ) )
2189  {
2190  if ( face->height < 0 )
2191  face->height = (FT_Short)-face->height;
2192 
2193  if ( !FT_HAS_VERTICAL( face ) )
2194  face->max_advance_height = (FT_Short)face->height;
2195  }
2196 
2197  if ( FT_HAS_FIXED_SIZES( face ) )
2198  {
2199  FT_Int i;
2200 
2201 
2202  for ( i = 0; i < face->num_fixed_sizes; i++ )
2203  {
2204  FT_Bitmap_Size* bsize = face->available_sizes + i;
2205 
2206 
2207  if ( bsize->height < 0 )
2208  bsize->height = (FT_Short)-bsize->height;
2209  if ( bsize->x_ppem < 0 )
2210  bsize->x_ppem = (FT_Short)-bsize->x_ppem;
2211  if ( bsize->y_ppem < 0 )
2212  bsize->y_ppem = -bsize->y_ppem;
2213  }
2214  }
2215 
2216  /* initialize internal face data */
2217  {
2218  FT_Face_Internal internal = face->internal;
2219 
2220 
2221  internal->transform_matrix.xx = 0x10000L;
2222  internal->transform_matrix.xy = 0;
2223  internal->transform_matrix.yx = 0;
2224  internal->transform_matrix.yy = 0x10000L;
2225 
2226  internal->transform_delta.x = 0;
2227  internal->transform_delta.y = 0;
2228 
2229  internal->refcount = 1;
2230  }
2231 
2232  if ( aface )
2233  *aface = face;
2234  else
2235  FT_Done_Face( face );
2236 
2237  goto Exit;
2238 
2239  Fail:
2240  FT_Done_Face( face );
2241 
2242  Exit:
2243  FT_TRACE4(( "FT_Open_Face: Return %d\n", error ));
2244 
2245  return error;
2246  }
2247 
2248 
2249  /* documentation is in freetype.h */
2250 
2253  const char* filepathname )
2254  {
2255  FT_Open_Args open;
2256 
2257 
2258  /* test for valid `face' delayed to FT_Attach_Stream() */
2259 
2260  if ( !filepathname )
2261  return FT_Err_Invalid_Argument;
2262 
2263  open.stream = NULL;
2264  open.flags = FT_OPEN_PATHNAME;
2265  open.pathname = (char*)filepathname;
2266 
2267  return FT_Attach_Stream( face, &open );
2268  }
2269 
2270 
2271  /* documentation is in freetype.h */
2272 
2275  FT_Open_Args* parameters )
2276  {
2277  FT_Stream stream;
2278  FT_Error error;
2279  FT_Driver driver;
2280 
2281  FT_Driver_Class clazz;
2282 
2283 
2284  /* test for valid `parameters' delayed to FT_Stream_New() */
2285 
2286  if ( !face )
2287  return FT_Err_Invalid_Face_Handle;
2288 
2289  driver = face->driver;
2290  if ( !driver )
2291  return FT_Err_Invalid_Driver_Handle;
2292 
2293  error = FT_Stream_New( driver->root.library, parameters, &stream );
2294  if ( error )
2295  goto Exit;
2296 
2297  /* we implement FT_Attach_Stream in each driver through the */
2298  /* `attach_file' interface */
2299 
2300  error = FT_Err_Unimplemented_Feature;
2301  clazz = driver->clazz;
2302  if ( clazz->attach_file )
2303  error = clazz->attach_file( face, stream );
2304 
2305  /* close the attached stream */
2306  FT_Stream_Free( stream,
2307  (FT_Bool)( parameters->stream &&
2308  ( parameters->flags & FT_OPEN_STREAM ) ) );
2309 
2310  Exit:
2311  return error;
2312  }
2313 
2314 
2315  /* documentation is in freetype.h */
2316 
2319  {
2320  face->internal->refcount++;
2321 
2322  return FT_Err_Ok;
2323  }
2324 
2325 
2326  /* documentation is in freetype.h */
2327 
2330  {
2331  FT_Error error;
2332  FT_Driver driver;
2333  FT_Memory memory;
2334  FT_ListNode node;
2335 
2336 
2337  error = FT_Err_Invalid_Face_Handle;
2338  if ( face && face->driver )
2339  {
2340  face->internal->refcount--;
2341  if ( face->internal->refcount > 0 )
2342  error = FT_Err_Ok;
2343  else
2344  {
2345  driver = face->driver;
2346  memory = driver->root.memory;
2347 
2348  /* find face in driver's list */
2349  node = FT_List_Find( &driver->faces_list, face );
2350  if ( node )
2351  {
2352  /* remove face object from the driver's list */
2353  FT_List_Remove( &driver->faces_list, node );
2354  FT_FREE( node );
2355 
2356  /* now destroy the object proper */
2357  destroy_face( memory, face, driver );
2358  error = FT_Err_Ok;
2359  }
2360  }
2361  }
2362 
2363  return error;
2364  }
2365 
2366 
2367  /* documentation is in ftobjs.h */
2368 
2371  FT_Size *asize )
2372  {
2373  FT_Error error;
2374  FT_Memory memory;
2375  FT_Driver driver;
2376  FT_Driver_Class clazz;
2377 
2378  FT_Size size = 0;
2379  FT_ListNode node = 0;
2380 
2381 
2382  if ( !face )
2383  return FT_Err_Invalid_Face_Handle;
2384 
2385  if ( !asize )
2386  return FT_Err_Invalid_Size_Handle;
2387 
2388  if ( !face->driver )
2389  return FT_Err_Invalid_Driver_Handle;
2390 
2391  *asize = 0;
2392 
2393  driver = face->driver;
2394  clazz = driver->clazz;
2395  memory = face->memory;
2396 
2397  /* Allocate new size object and perform basic initialisation */
2398  if ( FT_ALLOC( size, clazz->size_object_size ) || FT_NEW( node ) )
2399  goto Exit;
2400 
2401  size->face = face;
2402 
2403  /* for now, do not use any internal fields in size objects */
2404  size->internal = 0;
2405 
2406  if ( clazz->init_size )
2407  error = clazz->init_size( size );
2408 
2409  /* in case of success, add to the face's list */
2410  if ( !error )
2411  {
2412  *asize = size;
2413  node->data = size;
2414  FT_List_Add( &face->sizes_list, node );
2415  }
2416 
2417  Exit:
2418  if ( error )
2419  {
2420  FT_FREE( node );
2421  FT_FREE( size );
2422  }
2423 
2424  return error;
2425  }
2426 
2427 
2428  /* documentation is in ftobjs.h */
2429 
2432  {
2433  FT_Error error;
2434  FT_Driver driver;
2435  FT_Memory memory;
2436  FT_Face face;
2437  FT_ListNode node;
2438 
2439 
2440  if ( !size )
2441  return FT_Err_Invalid_Size_Handle;
2442 
2443  face = size->face;
2444  if ( !face )
2445  return FT_Err_Invalid_Face_Handle;
2446 
2447  driver = face->driver;
2448  if ( !driver )
2449  return FT_Err_Invalid_Driver_Handle;
2450 
2451  memory = driver->root.memory;
2452 
2453  error = FT_Err_Ok;
2454  node = FT_List_Find( &face->sizes_list, size );
2455  if ( node )
2456  {
2457  FT_List_Remove( &face->sizes_list, node );
2458  FT_FREE( node );
2459 
2460  if ( face->size == size )
2461  {
2462  face->size = 0;
2463  if ( face->sizes_list.head )
2464  face->size = (FT_Size)(face->sizes_list.head->data);
2465  }
2466 
2467  destroy_size( memory, size, driver );
2468  }
2469  else
2470  error = FT_Err_Invalid_Size_Handle;
2471 
2472  return error;
2473  }
2474 
2475 
2476  /* documentation is in ftobjs.h */
2477 
2480  FT_Size_Request req,
2481  FT_Bool ignore_width,
2482  FT_ULong* size_index )
2483  {
2484  FT_Int i;
2485  FT_Long w, h;
2486 
2487 
2488  if ( !FT_HAS_FIXED_SIZES( face ) )
2489  return FT_Err_Invalid_Face_Handle;
2490 
2491  /* FT_Bitmap_Size doesn't provide enough info... */
2492  if ( req->type != FT_SIZE_REQUEST_TYPE_NOMINAL )
2493  return FT_Err_Unimplemented_Feature;
2494 
2495  w = FT_REQUEST_WIDTH ( req );
2496  h = FT_REQUEST_HEIGHT( req );
2497 
2498  if ( req->width && !req->height )
2499  h = w;
2500  else if ( !req->width && req->height )
2501  w = h;
2502 
2503  w = FT_PIX_ROUND( w );
2504  h = FT_PIX_ROUND( h );
2505 
2506  for ( i = 0; i < face->num_fixed_sizes; i++ )
2507  {
2508  FT_Bitmap_Size* bsize = face->available_sizes + i;
2509 
2510 
2511  if ( h != FT_PIX_ROUND( bsize->y_ppem ) )
2512  continue;
2513 
2514  if ( w == FT_PIX_ROUND( bsize->x_ppem ) || ignore_width )
2515  {
2516  if ( size_index )
2517  *size_index = (FT_ULong)i;
2518 
2519  return FT_Err_Ok;
2520  }
2521  }
2522 
2523  return FT_Err_Invalid_Pixel_Size;
2524  }
2525 
2526 
2527  /* documentation is in ftobjs.h */
2528 
2529  FT_BASE_DEF( void )
2531  FT_Pos advance )
2532  {
2533  FT_Pos height = metrics->height;
2534 
2535 
2536  /* compensate for glyph with bbox above/below the baseline */
2537  if ( metrics->horiBearingY < 0 )
2538  {
2539  if ( height < metrics->horiBearingY )
2540  height = metrics->horiBearingY;
2541  }
2542  else if ( metrics->horiBearingY > 0 )
2543  height -= metrics->horiBearingY;
2544 
2545  /* the factor 1.2 is a heuristical value */
2546  if ( !advance )
2547  advance = height * 12 / 10;
2548 
2549  metrics->vertBearingX = metrics->horiBearingX - metrics->horiAdvance / 2;
2550  metrics->vertBearingY = ( advance - height ) / 2;
2551  metrics->vertAdvance = advance;
2552  }
2553 
2554 
2555  static void
2558  {
2559  /* Compute root ascender, descender, test height, and max_advance */
2560 
2561 #ifdef GRID_FIT_METRICS
2562  metrics->ascender = FT_PIX_CEIL( FT_MulFix( face->ascender,
2563  metrics->y_scale ) );
2564 
2565  metrics->descender = FT_PIX_FLOOR( FT_MulFix( face->descender,
2566  metrics->y_scale ) );
2567 
2568  metrics->height = FT_PIX_ROUND( FT_MulFix( face->height,
2569  metrics->y_scale ) );
2570 
2572  metrics->x_scale ) );
2573 #else /* !GRID_FIT_METRICS */
2574  metrics->ascender = FT_MulFix( face->ascender,
2575  metrics->y_scale );
2576 
2577  metrics->descender = FT_MulFix( face->descender,
2578  metrics->y_scale );
2579 
2580  metrics->height = FT_MulFix( face->height,
2581  metrics->y_scale );
2582 
2583  metrics->max_advance = FT_MulFix( face->max_advance_width,
2584  metrics->x_scale );
2585 #endif /* !GRID_FIT_METRICS */
2586  }
2587 
2588 
2589  FT_BASE_DEF( void )
2591  FT_ULong strike_index )
2592  {
2594  FT_Bitmap_Size* bsize;
2595 
2596 
2597  metrics = &face->size->metrics;
2598  bsize = face->available_sizes + strike_index;
2599 
2600  metrics->x_ppem = (FT_UShort)( ( bsize->x_ppem + 32 ) >> 6 );
2601  metrics->y_ppem = (FT_UShort)( ( bsize->y_ppem + 32 ) >> 6 );
2602 
2603  if ( FT_IS_SCALABLE( face ) )
2604  {
2605  metrics->x_scale = FT_DivFix( bsize->x_ppem,
2606  face->units_per_EM );
2607  metrics->y_scale = FT_DivFix( bsize->y_ppem,
2608  face->units_per_EM );
2609 
2610  ft_recompute_scaled_metrics( face, metrics );
2611  }
2612  else
2613  {
2614  metrics->x_scale = 1L << 16;
2615  metrics->y_scale = 1L << 16;
2616  metrics->ascender = bsize->y_ppem;
2617  metrics->descender = 0;
2618  metrics->height = bsize->height << 6;
2619  metrics->max_advance = bsize->x_ppem;
2620  }
2621 
2622  FT_TRACE5(( "FT_Select_Metrics:\n" ));
2623  FT_TRACE5(( " x scale: %d (%f)\n",
2624  metrics->x_scale, metrics->x_scale / 65536.0 ));
2625  FT_TRACE5(( " y scale: %d (%f)\n",
2626  metrics->y_scale, metrics->y_scale / 65536.0 ));
2627  FT_TRACE5(( " ascender: %f\n", metrics->ascender / 64.0 ));
2628  FT_TRACE5(( " descender: %f\n", metrics->descender / 64.0 ));
2629  FT_TRACE5(( " height: %f\n", metrics->height / 64.0 ));
2630  FT_TRACE5(( " max advance: %f\n", metrics->max_advance / 64.0 ));
2631  FT_TRACE5(( " x ppem: %d\n", metrics->x_ppem ));
2632  FT_TRACE5(( " y ppem: %d\n", metrics->y_ppem ));
2633  }
2634 
2635 
2636  FT_BASE_DEF( void )
2638  FT_Size_Request req )
2639  {
2641 
2642 
2643  metrics = &face->size->metrics;
2644 
2645  if ( FT_IS_SCALABLE( face ) )
2646  {
2647  FT_Long w = 0, h = 0, scaled_w = 0, scaled_h = 0;
2648 
2649 
2650  switch ( req->type )
2651  {
2653  w = h = face->units_per_EM;
2654  break;
2655 
2657  w = h = face->ascender - face->descender;
2658  break;
2659 
2661  w = face->bbox.xMax - face->bbox.xMin;
2662  h = face->bbox.yMax - face->bbox.yMin;
2663  break;
2664 
2666  w = face->max_advance_width;
2667  h = face->ascender - face->descender;
2668  break;
2669 
2671  metrics->x_scale = (FT_Fixed)req->width;
2672  metrics->y_scale = (FT_Fixed)req->height;
2673  if ( !metrics->x_scale )
2674  metrics->x_scale = metrics->y_scale;
2675  else if ( !metrics->y_scale )
2676  metrics->y_scale = metrics->x_scale;
2677  goto Calculate_Ppem;
2678 
2680  break;
2681  }
2682 
2683  /* to be on the safe side */
2684  if ( w < 0 )
2685  w = -w;
2686 
2687  if ( h < 0 )
2688  h = -h;
2689 
2690  scaled_w = FT_REQUEST_WIDTH ( req );
2691  scaled_h = FT_REQUEST_HEIGHT( req );
2692 
2693  /* determine scales */
2694  if ( req->width )
2695  {
2696  metrics->x_scale = FT_DivFix( scaled_w, w );
2697 
2698  if ( req->height )
2699  {
2700  metrics->y_scale = FT_DivFix( scaled_h, h );
2701 
2702  if ( req->type == FT_SIZE_REQUEST_TYPE_CELL )
2703  {
2704  if ( metrics->y_scale > metrics->x_scale )
2705  metrics->y_scale = metrics->x_scale;
2706  else
2707  metrics->x_scale = metrics->y_scale;
2708  }
2709  }
2710  else
2711  {
2712  metrics->y_scale = metrics->x_scale;
2713  scaled_h = FT_MulDiv( scaled_w, h, w );
2714  }
2715  }
2716  else
2717  {
2718  metrics->x_scale = metrics->y_scale = FT_DivFix( scaled_h, h );
2719  scaled_w = FT_MulDiv( scaled_h, w, h );
2720  }
2721 
2722  Calculate_Ppem:
2723  /* calculate the ppems */
2724  if ( req->type != FT_SIZE_REQUEST_TYPE_NOMINAL )
2725  {
2726  scaled_w = FT_MulFix( face->units_per_EM, metrics->x_scale );
2727  scaled_h = FT_MulFix( face->units_per_EM, metrics->y_scale );
2728  }
2729 
2730  metrics->x_ppem = (FT_UShort)( ( scaled_w + 32 ) >> 6 );
2731  metrics->y_ppem = (FT_UShort)( ( scaled_h + 32 ) >> 6 );
2732 
2733  ft_recompute_scaled_metrics( face, metrics );
2734  }
2735  else
2736  {
2737  FT_ZERO( metrics );
2738  metrics->x_scale = 1L << 16;
2739  metrics->y_scale = 1L << 16;
2740  }
2741 
2742  FT_TRACE5(( "FT_Request_Metrics:\n" ));
2743  FT_TRACE5(( " x scale: %d (%f)\n",
2744  metrics->x_scale, metrics->x_scale / 65536.0 ));
2745  FT_TRACE5(( " y scale: %d (%f)\n",
2746  metrics->y_scale, metrics->y_scale / 65536.0 ));
2747  FT_TRACE5(( " ascender: %f\n", metrics->ascender / 64.0 ));
2748  FT_TRACE5(( " descender: %f\n", metrics->descender / 64.0 ));
2749  FT_TRACE5(( " height: %f\n", metrics->height / 64.0 ));
2750  FT_TRACE5(( " max advance: %f\n", metrics->max_advance / 64.0 ));
2751  FT_TRACE5(( " x ppem: %d\n", metrics->x_ppem ));
2752  FT_TRACE5(( " y ppem: %d\n", metrics->y_ppem ));
2753  }
2754 
2755 
2756  /* documentation is in freetype.h */
2757 
2760  FT_Int strike_index )
2761  {
2762  FT_Driver_Class clazz;
2763 
2764 
2765  if ( !face || !FT_HAS_FIXED_SIZES( face ) )
2766  return FT_Err_Invalid_Face_Handle;
2767 
2768  if ( strike_index < 0 || strike_index >= face->num_fixed_sizes )
2769  return FT_Err_Invalid_Argument;
2770 
2771  clazz = face->driver->clazz;
2772 
2773  if ( clazz->select_size )
2774  {
2775  FT_Error error;
2776 
2777 
2778  error = clazz->select_size( face->size, (FT_ULong)strike_index );
2779 
2780 #ifdef FT_DEBUG_LEVEL_TRACE
2781  {
2782  FT_Size_Metrics* metrics = &face->size->metrics;
2783 
2784 
2785  FT_TRACE5(( "FT_Select_Size (font driver's `select_size'):\n" ));
2786  FT_TRACE5(( " x scale: %d (%f)\n",
2787  metrics->x_scale, metrics->x_scale / 65536.0 ));
2788  FT_TRACE5(( " y scale: %d (%f)\n",
2789  metrics->y_scale, metrics->y_scale / 65536.0 ));
2790  FT_TRACE5(( " ascender: %f\n", metrics->ascender / 64.0 ));
2791  FT_TRACE5(( " descender: %f\n", metrics->descender / 64.0 ));
2792  FT_TRACE5(( " height: %f\n", metrics->height / 64.0 ));
2793  FT_TRACE5(( " max advance: %f\n", metrics->max_advance / 64.0 ));
2794  FT_TRACE5(( " x ppem: %d\n", metrics->x_ppem ));
2795  FT_TRACE5(( " y ppem: %d\n", metrics->y_ppem ));
2796  }
2797 #endif
2798 
2799  return error;
2800  }
2801 
2802  FT_Select_Metrics( face, (FT_ULong)strike_index );
2803 
2804  return FT_Err_Ok;
2805  }
2806 
2807 
2808  /* documentation is in freetype.h */
2809 
2812  FT_Size_Request req )
2813  {
2814  FT_Driver_Class clazz;
2815  FT_ULong strike_index;
2816 
2817 
2818  if ( !face )
2819  return FT_Err_Invalid_Face_Handle;
2820 
2821  if ( !req || req->width < 0 || req->height < 0 ||
2822  req->type >= FT_SIZE_REQUEST_TYPE_MAX )
2823  return FT_Err_Invalid_Argument;
2824 
2825  clazz = face->driver->clazz;
2826 
2827  if ( clazz->request_size )
2828  {
2829  FT_Error error;
2830 
2831 
2832  error = clazz->request_size( face->size, req );
2833 
2834 #ifdef FT_DEBUG_LEVEL_TRACE
2835  {
2836  FT_Size_Metrics* metrics = &face->size->metrics;
2837 
2838 
2839  FT_TRACE5(( "FT_Request_Size (font driver's `request_size'):\n" ));
2840  FT_TRACE5(( " x scale: %d (%f)\n",
2841  metrics->x_scale, metrics->x_scale / 65536.0 ));
2842  FT_TRACE5(( " y scale: %d (%f)\n",
2843  metrics->y_scale, metrics->y_scale / 65536.0 ));
2844  FT_TRACE5(( " ascender: %f\n", metrics->ascender / 64.0 ));
2845  FT_TRACE5(( " descender: %f\n", metrics->descender / 64.0 ));
2846  FT_TRACE5(( " height: %f\n", metrics->height / 64.0 ));
2847  FT_TRACE5(( " max advance: %f\n", metrics->max_advance / 64.0 ));
2848  FT_TRACE5(( " x ppem: %d\n", metrics->x_ppem ));
2849  FT_TRACE5(( " y ppem: %d\n", metrics->y_ppem ));
2850  }
2851 #endif
2852 
2853  return error;
2854  }
2855 
2856  /*
2857  * The reason that a driver doesn't have `request_size' defined is
2858  * either that the scaling here suffices or that the supported formats
2859  * are bitmap-only and size matching is not implemented.
2860  *
2861  * In the latter case, a simple size matching is done.
2862  */
2863  if ( !FT_IS_SCALABLE( face ) && FT_HAS_FIXED_SIZES( face ) )
2864  {
2865  FT_Error error;
2866 
2867 
2868  error = FT_Match_Size( face, req, 0, &strike_index );
2869  if ( error )
2870  return error;
2871 
2872  FT_TRACE3(( "FT_Request_Size: bitmap strike %lu matched\n",
2873  strike_index ));
2874 
2875  return FT_Select_Size( face, (FT_Int)strike_index );
2876  }
2877 
2878  FT_Request_Metrics( face, req );
2879 
2880  return FT_Err_Ok;
2881  }
2882 
2883 
2884  /* documentation is in freetype.h */
2885 
2888  FT_F26Dot6 char_width,
2889  FT_F26Dot6 char_height,
2890  FT_UInt horz_resolution,
2891  FT_UInt vert_resolution )
2892  {
2893  FT_Size_RequestRec req;
2894 
2895 
2896  if ( !char_width )
2897  char_width = char_height;
2898  else if ( !char_height )
2899  char_height = char_width;
2900 
2901  if ( !horz_resolution )
2902  horz_resolution = vert_resolution;
2903  else if ( !vert_resolution )
2904  vert_resolution = horz_resolution;
2905 
2906  if ( char_width < 1 * 64 )
2907  char_width = 1 * 64;
2908  if ( char_height < 1 * 64 )
2909  char_height = 1 * 64;
2910 
2911  if ( !horz_resolution )
2912  horz_resolution = vert_resolution = 72;
2913 
2915  req.width = char_width;
2916  req.height = char_height;
2917  req.horiResolution = horz_resolution;
2918  req.vertResolution = vert_resolution;
2919 
2920  return FT_Request_Size( face, &req );
2921  }
2922 
2923 
2924  /* documentation is in freetype.h */
2925 
2928  FT_UInt pixel_width,
2929  FT_UInt pixel_height )
2930  {
2931  FT_Size_RequestRec req;
2932 
2933 
2934  if ( pixel_width == 0 )
2935  pixel_width = pixel_height;
2936  else if ( pixel_height == 0 )
2937  pixel_height = pixel_width;
2938 
2939  if ( pixel_width < 1 )
2940  pixel_width = 1;
2941  if ( pixel_height < 1 )
2942  pixel_height = 1;
2943 
2944  /* use `>=' to avoid potential compiler warning on 16bit platforms */
2945  if ( pixel_width >= 0xFFFFU )
2946  pixel_width = 0xFFFFU;
2947  if ( pixel_height >= 0xFFFFU )
2948  pixel_height = 0xFFFFU;
2949 
2951  req.width = pixel_width << 6;
2952  req.height = pixel_height << 6;
2953  req.horiResolution = 0;
2954  req.vertResolution = 0;
2955 
2956  return FT_Request_Size( face, &req );
2957  }
2958 
2959 
2960  /* documentation is in freetype.h */
2961 
2964  FT_UInt left_glyph,
2965  FT_UInt right_glyph,
2966  FT_UInt kern_mode,
2967  FT_Vector *akerning )
2968  {
2969  FT_Error error = FT_Err_Ok;
2970  FT_Driver driver;
2971 
2972 
2973  if ( !face )
2974  return FT_Err_Invalid_Face_Handle;
2975 
2976  if ( !akerning )
2977  return FT_Err_Invalid_Argument;
2978 
2979  driver = face->driver;
2980 
2981  akerning->x = 0;
2982  akerning->y = 0;
2983 
2984  if ( driver->clazz->get_kerning )
2985  {
2986  error = driver->clazz->get_kerning( face,
2987  left_glyph,
2988  right_glyph,
2989  akerning );
2990  if ( !error )
2991  {
2992  if ( kern_mode != FT_KERNING_UNSCALED )
2993  {
2994  akerning->x = FT_MulFix( akerning->x, face->size->metrics.x_scale );
2995  akerning->y = FT_MulFix( akerning->y, face->size->metrics.y_scale );
2996 
2997  if ( kern_mode != FT_KERNING_UNFITTED )
2998  {
2999  /* we scale down kerning values for small ppem values */
3000  /* to avoid that rounding makes them too big. */
3001  /* `25' has been determined heuristically. */
3002  if ( face->size->metrics.x_ppem < 25 )
3003  akerning->x = FT_MulDiv( akerning->x,
3004  face->size->metrics.x_ppem, 25 );
3005  if ( face->size->metrics.y_ppem < 25 )
3006  akerning->y = FT_MulDiv( akerning->y,
3007  face->size->metrics.y_ppem, 25 );
3008 
3009  akerning->x = FT_PIX_ROUND( akerning->x );
3010  akerning->y = FT_PIX_ROUND( akerning->y );
3011  }
3012  }
3013  }
3014  }
3015 
3016  return error;
3017  }
3018 
3019 
3020  /* documentation is in freetype.h */
3021 
3024  FT_Fixed point_size,
3025  FT_Int degree,
3026  FT_Fixed* akerning )
3027  {
3028  FT_Service_Kerning service;
3029  FT_Error error = FT_Err_Ok;
3030 
3031 
3032  if ( !face )
3033  return FT_Err_Invalid_Face_Handle;
3034 
3035  if ( !akerning )
3036  return FT_Err_Invalid_Argument;
3037 
3038  FT_FACE_FIND_SERVICE( face, service, KERNING );
3039  if ( !service )
3040  return FT_Err_Unimplemented_Feature;
3041 
3042  error = service->get_track( face,
3043  point_size,
3044  degree,
3045  akerning );
3046 
3047  return error;
3048  }
3049 
3050 
3051  /* documentation is in freetype.h */
3052 
3055  FT_Encoding encoding )
3056  {
3057  FT_CharMap* cur;
3058  FT_CharMap* limit;
3059 
3060 
3061  if ( !face )
3062  return FT_Err_Invalid_Face_Handle;
3063 
3064  if ( encoding == FT_ENCODING_NONE )
3065  return FT_Err_Invalid_Argument;
3066 
3067  /* FT_ENCODING_UNICODE is special. We try to find the `best' Unicode */
3068  /* charmap available, i.e., one with UCS-4 characters, if possible. */
3069  /* */
3070  /* This is done by find_unicode_charmap() above, to share code. */
3071  if ( encoding == FT_ENCODING_UNICODE )
3072  return find_unicode_charmap( face );
3073 
3074  cur = face->charmaps;
3075  if ( !cur )
3076  return FT_Err_Invalid_CharMap_Handle;
3077 
3078  limit = cur + face->num_charmaps;
3079 
3080  for ( ; cur < limit; cur++ )
3081  {
3082  if ( cur[0]->encoding == encoding )
3083  {
3084 #ifdef FT_MAX_CHARMAP_CACHEABLE
3085  if ( cur - face->charmaps > FT_MAX_CHARMAP_CACHEABLE )
3086  {
3087  FT_ERROR(( "FT_Select_Charmap: requested charmap is found (%d), "
3088  "but in too late position to cache\n",
3089  cur - face->charmaps ));
3090  continue;
3091  }
3092 #endif
3093  face->charmap = cur[0];
3094  return 0;
3095  }
3096  }
3097 
3098  return FT_Err_Invalid_Argument;
3099  }
3100 
3101 
3102  /* documentation is in freetype.h */
3103 
3106  FT_CharMap charmap )
3107  {
3108  FT_CharMap* cur;
3109  FT_CharMap* limit;
3110 
3111 
3112  if ( !face )
3113  return FT_Err_Invalid_Face_Handle;
3114 
3115  cur = face->charmaps;
3116  if ( !cur )
3117  return FT_Err_Invalid_CharMap_Handle;
3118  if ( FT_Get_CMap_Format( charmap ) == 14 )
3119  return FT_Err_Invalid_Argument;
3120 
3121  limit = cur + face->num_charmaps;
3122 
3123  for ( ; cur < limit; cur++ )
3124  {
3125  if ( cur[0] == charmap )
3126  {
3127 #ifdef FT_MAX_CHARMAP_CACHEABLE
3128  if ( cur - face->charmaps > FT_MAX_CHARMAP_CACHEABLE )
3129  {
3130  FT_ERROR(( "FT_Set_Charmap: requested charmap is found (%d), "
3131  "but in too late position to cache\n",
3132  cur - face->charmaps ));
3133  continue;
3134  }
3135 #endif
3136  face->charmap = cur[0];
3137  return 0;
3138  }
3139  }
3140  return FT_Err_Invalid_Argument;
3141  }
3142 
3143 
3144  /* documentation is in freetype.h */
3145 
3148  {
3149  FT_Int i;
3150 
3151 
3152  if ( !charmap || !charmap->face )
3153  return -1;
3154 
3155  for ( i = 0; i < charmap->face->num_charmaps; i++ )
3156  if ( charmap->face->charmaps[i] == charmap )
3157  break;
3158 
3159  FT_ASSERT( i < charmap->face->num_charmaps );
3160 
3161 #ifdef FT_MAX_CHARMAP_CACHEABLE
3162  if ( i > FT_MAX_CHARMAP_CACHEABLE )
3163  {
3164  FT_ERROR(( "FT_Get_Charmap_Index: requested charmap is found (%d), "
3165  "but in too late position to cache\n",
3166  i ));
3167  return -i;
3168  }
3169 #endif
3170  return i;
3171  }
3172 
3173 
3174  static void
3176  {
3177  FT_CMap_Class clazz = cmap->clazz;
3178  FT_Face face = cmap->charmap.face;
3179  FT_Memory memory = FT_FACE_MEMORY(face);
3180 
3181 
3182  if ( clazz->done )
3183  clazz->done( cmap );
3184 
3185  FT_FREE( cmap );
3186  }
3187 
3188 
3189  FT_BASE_DEF( void )
3191  {
3192  if ( cmap )
3193  {
3194  FT_Face face = cmap->charmap.face;
3195  FT_Memory memory = FT_FACE_MEMORY( face );
3196  FT_Error error;
3197  FT_Int i, j;
3198 
3199 
3200  for ( i = 0; i < face->num_charmaps; i++ )
3201  {
3202  if ( (FT_CMap)face->charmaps[i] == cmap )
3203  {
3204  FT_CharMap last_charmap = face->charmaps[face->num_charmaps - 1];
3205 
3206 
3207  if ( FT_RENEW_ARRAY( face->charmaps,
3208  face->num_charmaps,
3209  face->num_charmaps - 1 ) )
3210  return;
3211 
3212  /* remove it from our list of charmaps */
3213  for ( j = i + 1; j < face->num_charmaps; j++ )
3214  {
3215  if ( j == face->num_charmaps - 1 )
3216  face->charmaps[j - 1] = last_charmap;
3217  else
3218  face->charmaps[j - 1] = face->charmaps[j];
3219  }
3220 
3221  face->num_charmaps--;
3222 
3223  if ( (FT_CMap)face->charmap == cmap )
3224  face->charmap = NULL;
3225 
3226  ft_cmap_done_internal( cmap );
3227 
3228  break;
3229  }
3230  }
3231  }
3232  }
3233 
3234 
3237  FT_Pointer init_data,
3238  FT_CharMap charmap,
3239  FT_CMap *acmap )
3240  {
3241  FT_Error error = FT_Err_Ok;
3242  FT_Face face;
3243  FT_Memory memory;
3244  FT_CMap cmap = NULL;
3245 
3246 
3247  if ( clazz == NULL || charmap == NULL || charmap->face == NULL )
3248  return FT_Err_Invalid_Argument;
3249 
3250  face = charmap->face;
3251  memory = FT_FACE_MEMORY( face );
3252 
3253  if ( !FT_ALLOC( cmap, clazz->size ) )
3254  {
3255  cmap->charmap = *charmap;
3256  cmap->clazz = clazz;
3257 
3258  if ( clazz->init )
3259  {
3260  error = clazz->init( cmap, init_data );
3261  if ( error )
3262  goto Fail;
3263  }
3264 
3265  /* add it to our list of charmaps */
3266  if ( FT_RENEW_ARRAY( face->charmaps,
3267  face->num_charmaps,
3268  face->num_charmaps + 1 ) )
3269  goto Fail;
3270 
3271  face->charmaps[face->num_charmaps++] = (FT_CharMap)cmap;
3272  }
3273 
3274  Exit:
3275  if ( acmap )
3276  *acmap = cmap;
3277 
3278  return error;
3279 
3280  Fail:
3281  ft_cmap_done_internal( cmap );
3282  cmap = NULL;
3283  goto Exit;
3284  }
3285 
3286 
3287  /* documentation is in freetype.h */
3288 
3291  FT_ULong charcode )
3292  {
3293  FT_UInt result = 0;
3294 
3295 
3296  if ( face && face->charmap )
3297  {
3298  FT_CMap cmap = FT_CMAP( face->charmap );
3299 
3300 
3301  if ( charcode > 0xFFFFFFFFUL )
3302  {
3303  FT_TRACE1(( "FT_Get_Char_Index: too large charcode" ));
3304  FT_TRACE1(( " 0x%x is truncated\n", charcode ));
3305  }
3306  result = cmap->clazz->char_index( cmap, (FT_UInt32)charcode );
3307  }
3308  return result;
3309  }
3310 
3311 
3312  /* documentation is in freetype.h */
3313 
3316  FT_UInt *agindex )
3317  {
3318  FT_ULong result = 0;
3319  FT_UInt gindex = 0;
3320 
3321 
3322  if ( face && face->charmap && face->num_glyphs )
3323  {
3324  gindex = FT_Get_Char_Index( face, 0 );
3325  if ( gindex == 0 || gindex >= (FT_UInt)face->num_glyphs )
3326  result = FT_Get_Next_Char( face, 0, &gindex );
3327  }
3328 
3329  if ( agindex )
3330  *agindex = gindex;
3331 
3332  return result;
3333  }
3334 
3335 
3336  /* documentation is in freetype.h */
3337 
3340  FT_ULong charcode,
3341  FT_UInt *agindex )
3342  {
3343  FT_ULong result = 0;
3344  FT_UInt gindex = 0;
3345 
3346 
3347  if ( face && face->charmap && face->num_glyphs )
3348  {
3349  FT_UInt32 code = (FT_UInt32)charcode;
3350  FT_CMap cmap = FT_CMAP( face->charmap );
3351 
3352 
3353  do {
3354  gindex = cmap->clazz->char_next( cmap, &code );
3355  } while ( gindex >= (FT_UInt)face->num_glyphs );
3356 
3357  result = ( gindex == 0 ) ? 0 : code;
3358  }
3359 
3360  if ( agindex )
3361  *agindex = gindex;
3362 
3363  return result;
3364  }
3365 
3366 
3367  /* documentation is in freetype.h */
3368 
3371  FT_ULong charcode,
3372  FT_ULong variantSelector )
3373  {
3374  FT_UInt result = 0;
3375 
3376 
3377  if ( face && face->charmap &&
3378  face->charmap->encoding == FT_ENCODING_UNICODE )
3379  {
3380  FT_CharMap charmap = find_variant_selector_charmap( face );
3381  FT_CMap ucmap = FT_CMAP( face->charmap );
3382 
3383 
3384  if ( charmap != NULL )
3385  {
3386  FT_CMap vcmap = FT_CMAP( charmap );
3387 
3388 
3389  if ( charcode > 0xFFFFFFFFUL )
3390  {
3391  FT_TRACE1(( "FT_Get_Char_Index: too large charcode" ));
3392  FT_TRACE1(( " 0x%x is truncated\n", charcode ));
3393  }
3394  if ( variantSelector > 0xFFFFFFFFUL )
3395  {
3396  FT_TRACE1(( "FT_Get_Char_Index: too large variantSelector" ));
3397  FT_TRACE1(( " 0x%x is truncated\n", variantSelector ));
3398  }
3399 
3400  result = vcmap->clazz->char_var_index( vcmap, ucmap,
3401  (FT_UInt32)charcode,
3402  (FT_UInt32)variantSelector );
3403  }
3404  }
3405 
3406  return result;
3407  }
3408 
3409 
3410  /* documentation is in freetype.h */
3411 
3414  FT_ULong charcode,
3415  FT_ULong variantSelector )
3416  {
3417  FT_Int result = -1;
3418 
3419 
3420  if ( face )
3421  {
3422  FT_CharMap charmap = find_variant_selector_charmap( face );
3423 
3424 
3425  if ( charmap != NULL )
3426  {
3427  FT_CMap vcmap = FT_CMAP( charmap );
3428 
3429 
3430  if ( charcode > 0xFFFFFFFFUL )
3431  {
3432  FT_TRACE1(( "FT_Get_Char_Index: too large charcode" ));
3433  FT_TRACE1(( " 0x%x is truncated\n", charcode ));
3434  }
3435  if ( variantSelector > 0xFFFFFFFFUL )
3436  {
3437  FT_TRACE1(( "FT_Get_Char_Index: too large variantSelector" ));
3438  FT_TRACE1(( " 0x%x is truncated\n", variantSelector ));
3439  }
3440 
3441  result = vcmap->clazz->char_var_default( vcmap,
3442  (FT_UInt32)charcode,
3443  (FT_UInt32)variantSelector );
3444  }
3445  }
3446 
3447  return result;
3448  }
3449 
3450 
3451  /* documentation is in freetype.h */
3452 
3453  FT_EXPORT_DEF( FT_UInt32* )
3455  {
3456  FT_UInt32 *result = NULL;
3457 
3458 
3459  if ( face )
3460  {
3461  FT_CharMap charmap = find_variant_selector_charmap( face );
3462 
3463 
3464  if ( charmap != NULL )
3465  {
3466  FT_CMap vcmap = FT_CMAP( charmap );
3467  FT_Memory memory = FT_FACE_MEMORY( face );
3468 
3469 
3470  result = vcmap->clazz->variant_list( vcmap, memory );
3471  }
3472  }
3473 
3474  return result;
3475  }
3476 
3477 
3478  /* documentation is in freetype.h */
3479 
3480  FT_EXPORT_DEF( FT_UInt32* )
3482  FT_ULong charcode )
3483  {
3484  FT_UInt32 *result = NULL;
3485 
3486 
3487  if ( face )
3488  {
3489  FT_CharMap charmap = find_variant_selector_charmap( face );
3490 
3491 
3492  if ( charmap != NULL )
3493  {
3494  FT_CMap vcmap = FT_CMAP( charmap );
3495  FT_Memory memory = FT_FACE_MEMORY( face );
3496 
3497 
3498  if ( charcode > 0xFFFFFFFFUL )
3499  {
3500  FT_TRACE1(( "FT_Get_Char_Index: too large charcode" ));
3501  FT_TRACE1(( " 0x%x is truncated\n", charcode ));
3502  }
3503 
3504  result = vcmap->clazz->charvariant_list( vcmap, memory,
3505  (FT_UInt32)charcode );
3506  }
3507  }
3508  return result;
3509  }
3510 
3511 
3512  /* documentation is in freetype.h */
3513 
3514  FT_EXPORT_DEF( FT_UInt32* )
3516  FT_ULong variantSelector )
3517  {
3518  FT_UInt32 *result = NULL;
3519 
3520 
3521  if ( face )
3522  {
3523  FT_CharMap charmap = find_variant_selector_charmap( face );
3524 
3525 
3526  if ( charmap != NULL )
3527  {
3528  FT_CMap vcmap = FT_CMAP( charmap );
3529  FT_Memory memory = FT_FACE_MEMORY( face );
3530 
3531 
3532  if ( variantSelector > 0xFFFFFFFFUL )
3533  {
3534  FT_TRACE1(( "FT_Get_Char_Index: too large variantSelector" ));
3535  FT_TRACE1(( " 0x%x is truncated\n", variantSelector ));
3536  }
3537 
3538  result = vcmap->clazz->variantchar_list( vcmap, memory,
3539  (FT_UInt32)variantSelector );
3540  }
3541  }
3542 
3543  return result;
3544  }
3545 
3546 
3547  /* documentation is in freetype.h */
3548 
3551  FT_String* glyph_name )
3552  {
3553  FT_UInt result = 0;
3554 
3555 
3556  if ( face && FT_HAS_GLYPH_NAMES( face ) )
3557  {
3558  FT_Service_GlyphDict service;
3559 
3560 
3561  FT_FACE_LOOKUP_SERVICE( face,
3562  service,
3563  GLYPH_DICT );
3564 
3565  if ( service && service->name_index )
3566  result = service->name_index( face, glyph_name );
3567  }
3568 
3569  return result;
3570  }
3571 
3572 
3573  /* documentation is in freetype.h */
3574 
3577  FT_UInt glyph_index,
3579  FT_UInt buffer_max )
3580  {
3582 
3583 
3584  /* clean up buffer */
3585  if ( buffer && buffer_max > 0 )
3586  ((FT_Byte*)buffer)[0] = 0;
3587 
3588  if ( face &&
3589  (FT_Long)glyph_index <= face->num_glyphs &&
3590  FT_HAS_GLYPH_NAMES( face ) )
3591  {
3592  FT_Service_GlyphDict service;
3593 
3594 
3595  FT_FACE_LOOKUP_SERVICE( face,
3596  service,
3597  GLYPH_DICT );
3598 
3599  if ( service && service->get_name )
3600  error = service->get_name( face, glyph_index, buffer, buffer_max );
3601  }
3602 
3603  return error;
3604  }
3605 
3606 
3607  /* documentation is in freetype.h */
3608 
3609  FT_EXPORT_DEF( const char* )
3611  {
3612  const char* result = NULL;
3613 
3614 
3615  if ( !face )
3616  goto Exit;
3617 
3618  if ( !result )
3619  {
3620  FT_Service_PsFontName service;
3621 
3622 
3623  FT_FACE_LOOKUP_SERVICE( face,
3624  service,
3625  POSTSCRIPT_FONT_NAME );
3626 
3627  if ( service && service->get_ps_font_name )
3628  result = service->get_ps_font_name( face );
3629  }
3630 
3631  Exit:
3632  return result;
3633  }
3634 
3635 
3636  /* documentation is in tttables.h */
3637 
3638  FT_EXPORT_DEF( void* )
3640  FT_Sfnt_Tag tag )
3641  {
3642  void* table = 0;
3643  FT_Service_SFNT_Table service;
3644 
3645 
3646  if ( face && FT_IS_SFNT( face ) )
3647  {
3648  FT_FACE_FIND_SERVICE( face, service, SFNT_TABLE );
3649  if ( service != NULL )
3650  table = service->get_table( face, tag );
3651  }
3652 
3653  return table;
3654  }
3655 
3656 
3657  /* documentation is in tttables.h */
3658 
3661  FT_ULong tag,
3662  FT_Long offset,
3663  FT_Byte* buffer,
3664  FT_ULong* length )
3665  {
3666  FT_Service_SFNT_Table service;
3667 
3668 
3669  if ( !face || !FT_IS_SFNT( face ) )
3670  return FT_Err_Invalid_Face_Handle;
3671 
3672  FT_FACE_FIND_SERVICE( face, service, SFNT_TABLE );
3673  if ( service == NULL )
3674  return FT_Err_Unimplemented_Feature;
3675 
3676  return service->load_table( face, tag, offset, buffer, length );
3677  }
3678 
3679 
3680  /* documentation is in tttables.h */
3681 
3684  FT_UInt table_index,
3685  FT_ULong *tag,
3686  FT_ULong *length )
3687  {
3688  FT_Service_SFNT_Table service;
3689  FT_ULong offset;
3690 
3691 
3692  if ( !face || !FT_IS_SFNT( face ) )
3693  return FT_Err_Invalid_Face_Handle;
3694 
3695  FT_FACE_FIND_SERVICE( face, service, SFNT_TABLE );
3696  if ( service == NULL )
3697  return FT_Err_Unimplemented_Feature;
3698 
3699  return service->table_info( face, table_index, tag, &offset, length );
3700  }
3701 
3702 
3703  /* documentation is in tttables.h */
3704 
3707  {
3708  FT_Service_TTCMaps service;
3709  FT_Face face;
3711 
3712 
3713  if ( !charmap || !charmap->face )
3714  return 0;
3715 
3716  face = charmap->face;
3717  FT_FACE_FIND_SERVICE( face, service, TT_CMAP );
3718  if ( service == NULL )
3719  return 0;
3720  if ( service->get_cmap_info( charmap, &cmap_info ))
3721  return 0;
3722 
3723  return cmap_info.language;
3724  }
3725 
3726 
3727  /* documentation is in tttables.h */
3728 
3731  {
3732  FT_Service_TTCMaps service;
3733  FT_Face face;
3735 
3736 
3737  if ( !charmap || !charmap->face )
3738  return -1;
3739 
3740  face = charmap->face;
3741  FT_FACE_FIND_SERVICE( face, service, TT_CMAP );
3742  if ( service == NULL )
3743  return -1;
3744  if ( service->get_cmap_info( charmap, &cmap_info ))
3745  return -1;
3746 
3747  return cmap_info.format;
3748  }
3749 
3750 
3751  /* documentation is in ftsizes.h */
3752 
3755  {
3756  FT_Face face;
3757 
3758 
3759  if ( size == NULL )
3760  return FT_Err_Invalid_Argument;
3761 
3762  face = size->face;
3763  if ( face == NULL || face->driver == NULL )
3764  return FT_Err_Invalid_Argument;
3765 
3766  /* we don't need anything more complex than that; all size objects */
3767  /* are already listed by the face */
3768  face->size = size;
3769 
3770  return FT_Err_Ok;
3771  }
3772 
3773 
3774  /*************************************************************************/
3775  /*************************************************************************/
3776  /*************************************************************************/
3777  /**** ****/
3778  /**** ****/
3779  /**** R E N D E R E R S ****/
3780  /**** ****/
3781  /**** ****/
3782  /*************************************************************************/
3783  /*************************************************************************/
3784  /*************************************************************************/
3785 
3786  /* lookup a renderer by glyph format in the library's list */
3790  FT_ListNode* node )
3791  {
3792  FT_ListNode cur;
3793  FT_Renderer result = 0;
3794 
3795 
3796  if ( !library )
3797  goto Exit;
3798 
3799  cur = library->renderers.head;
3800 
3801  if ( node )
3802  {
3803  if ( *node )
3804  cur = (*node)->next;
3805  *node = 0;
3806  }
3807 
3808  while ( cur )
3809  {
3810  FT_Renderer renderer = FT_RENDERER( cur->data );
3811 
3812 
3813  if ( renderer->glyph_format == format )
3814  {
3815  if ( node )
3816  *node = cur;
3817 
3818  result = renderer;
3819  break;
3820  }
3821  cur = cur->next;
3822  }
3823 
3824  Exit:
3825  return result;
3826  }
3827 
3828 
3829  static FT_Renderer
3831  {
3832  FT_Face face = slot->face;
3833  FT_Library library = FT_FACE_LIBRARY( face );
3834  FT_Renderer result = library->cur_renderer;
3835 
3836 
3837  if ( !result || result->glyph_format != slot->format )
3838  result = FT_Lookup_Renderer( library, slot->format, 0 );
3839 
3840  return result;
3841  }
3842 
3843 
3844  static void
3846  {
3847  FT_Renderer renderer;
3848 
3849 
3850  renderer = FT_Lookup_Renderer( library, FT_GLYPH_FORMAT_OUTLINE, 0 );
3851  library->cur_renderer = renderer;
3852  }
3853 
3854 
3855  static FT_Error
3857  {
3858  FT_Library library = module->library;
3859  FT_Memory memory = library->memory;
3860  FT_Error error;
3861  FT_ListNode node = NULL;
3862 
3863 
3864  if ( FT_NEW( node ) )
3865  goto Exit;
3866 
3867  {
3868  FT_Renderer render = FT_RENDERER( module );
3869  FT_Renderer_Class* clazz = (FT_Renderer_Class*)module->clazz;
3870 
3871 
3872  render->clazz = clazz;
3873  render->glyph_format = clazz->glyph_format;
3874 
3875  /* allocate raster object if needed */
3876  if ( clazz->glyph_format == FT_GLYPH_FORMAT_OUTLINE &&
3877  clazz->raster_class->raster_new )
3878  {
3879  error = clazz->raster_class->raster_new( memory, &render->raster );
3880  if ( error )
3881  goto Fail;
3882 
3883  render->raster_render = clazz->raster_class->raster_render;
3884  render->render = clazz->render_glyph;
3885  }
3886 
3887  /* add to list */
3888  node->data = module;
3889  FT_List_Add( &library->renderers, node );
3890 
3891  ft_set_current_renderer( library );
3892  }
3893 
3894  Fail:
3895  if ( error )
3896  FT_FREE( node );
3897 
3898  Exit:
3899  return error;
3900  }
3901 
3902 
3903  static void
3905  {
3906  FT_Library library = module->library;
3907  FT_Memory memory = library->memory;
3908  FT_ListNode node;
3909 
3910 
3911  node = FT_List_Find( &library->renderers, module );
3912  if ( node )
3913  {
3914  FT_Renderer render = FT_RENDERER( module );
3915 
3916 
3917  /* release raster object, if any */
3918  if ( render->clazz->glyph_format == FT_GLYPH_FORMAT_OUTLINE &&
3919  render->raster )
3920  render->clazz->raster_class->raster_done( render->raster );
3921 
3922  /* remove from list */
3923  FT_List_Remove( &library->renderers, node );
3924  FT_FREE( node );
3925 
3926  ft_set_current_renderer( library );
3927  }
3928  }
3929 
3930 
3931  /* documentation is in ftrender.h */
3932 
3936  {
3937  /* test for valid `library' delayed to FT_Lookup_Renderer() */
3938 
3939  return FT_Lookup_Renderer( library, format, 0 );
3940  }
3941 
3942 
3943  /* documentation is in ftrender.h */
3944 
3947  FT_Renderer renderer,
3948  FT_UInt num_params,
3949  FT_Parameter* parameters )
3950  {
3951  FT_ListNode node;
3952  FT_Error error = FT_Err_Ok;
3953 
3954 
3955  if ( !library )
3956  return FT_Err_Invalid_Library_Handle;
3957 
3958  if ( !renderer )
3959  return FT_Err_Invalid_Argument;
3960 
3961  node = FT_List_Find( &library->renderers, renderer );
3962  if ( !node )
3963  {
3964  error = FT_Err_Invalid_Argument;
3965  goto Exit;
3966  }
3967 
3968  FT_List_Up( &library->renderers, node );
3969 
3970  if ( renderer->glyph_format == FT_GLYPH_FORMAT_OUTLINE )
3971  library->cur_renderer = renderer;
3972 
3973  if ( num_params > 0 )
3974  {
3975  FT_Renderer_SetModeFunc set_mode = renderer->clazz->set_mode;
3976 
3977 
3978  for ( ; num_params > 0; num_params-- )
3979  {
3980  error = set_mode( renderer, parameters->tag, parameters->data );
3981  if ( error )
3982  break;
3983  parameters++;
3984  }
3985  }
3986 
3987  Exit:
3988  return error;
3989  }
3990 
3991 
3994  FT_GlyphSlot slot,
3995  FT_Render_Mode render_mode )
3996  {
3997  FT_Error error = FT_Err_Ok;
3998  FT_Renderer renderer;
3999 
4000 
4001  /* if it is already a bitmap, no need to do anything */
4002  switch ( slot->format )
4003  {
4004  case FT_GLYPH_FORMAT_BITMAP: /* already a bitmap, don't do anything */
4005  break;
4006 
4007  default:
4008  {
4009  FT_ListNode node = 0;
4010  FT_Bool update = 0;
4011 
4012 
4013  /* small shortcut for the very common case */
4014  if ( slot->format == FT_GLYPH_FORMAT_OUTLINE )
4015  {
4016  renderer = library->cur_renderer;
4017  node = library->renderers.head;
4018  }
4019  else
4020  renderer = FT_Lookup_Renderer( library, slot->format, &node );
4021 
4022  error = FT_Err_Unimplemented_Feature;
4023  while ( renderer )
4024  {
4025  error = renderer->render( renderer, slot, render_mode, NULL );
4026  if ( !error ||
4027  FT_ERROR_BASE( error ) != FT_Err_Cannot_Render_Glyph )
4028  break;
4029 
4030  /* FT_Err_Cannot_Render_Glyph is returned if the render mode */
4031  /* is unsupported by the current renderer for this glyph image */
4032  /* format. */
4033 
4034  /* now, look for another renderer that supports the same */
4035  /* format. */
4036  renderer = FT_Lookup_Renderer( library, slot->format, &node );
4037  update = 1;
4038  }
4039 
4040  /* if we changed the current renderer for the glyph image format */
4041  /* we need to select it as the next current one */
4042  if ( !error && update && renderer )
4043  FT_Set_Renderer( library, renderer, 0, 0 );
4044  }
4045  }
4046 
4047  return error;
4048  }
4049 
4050 
4051  /* documentation is in freetype.h */
4052 
4055  FT_Render_Mode render_mode )
4056  {
4058 
4059 
4060  if ( !slot || !slot->face )
4061  return FT_Err_Invalid_Argument;
4062 
4063  library = FT_FACE_LIBRARY( slot->face );
4064 
4065  return FT_Render_Glyph_Internal( library, slot, render_mode );
4066  }
4067 
4068 
4069  /*************************************************************************/
4070  /*************************************************************************/
4071  /*************************************************************************/
4072  /**** ****/
4073  /**** ****/
4074  /**** M O D U L E S ****/
4075  /**** ****/
4076  /**** ****/
4077  /*************************************************************************/
4078  /*************************************************************************/
4079  /*************************************************************************/
4080 
4081 
4082  /*************************************************************************/
4083  /* */
4084  /* <Function> */
4085  /* Destroy_Module */
4086  /* */
4087  /* <Description> */
4088  /* Destroys a given module object. For drivers, this also destroys */
4089  /* all child faces. */
4090  /* */
4091  /* <InOut> */
4092  /* module :: A handle to the target driver object. */
4093  /* */
4094  /* <Note> */
4095  /* The driver _must_ be LOCKED! */
4096  /* */
4097  static void
4099  {
4100  FT_Memory memory = module->memory;
4101  FT_Module_Class* clazz = module->clazz;
4102  FT_Library library = module->library;
4103 
4104 
4105  if ( library && library->auto_hinter == module )
4106  library->auto_hinter = 0;
4107 
4108  /* if the module is a renderer */
4109  if ( FT_MODULE_IS_RENDERER( module ) )
4110  ft_remove_renderer( module );
4111 
4112  /* if the module is a font driver, add some steps */
4113  if ( FT_MODULE_IS_DRIVER( module ) )
4114  Destroy_Driver( FT_DRIVER( module ) );
4115 
4116  /* finalize the module object */
4117  if ( clazz->module_done )
4118  clazz->module_done( module );
4119 
4120  /* discard it */
4121  FT_FREE( module );
4122  }
4123 
4124 
4125  /* documentation is in ftmodapi.h */
4126 
4129  const FT_Module_Class* clazz )
4130  {
4131  FT_Error error;
4132  FT_Memory memory;
4133  FT_Module module;
4134  FT_UInt nn;
4135 
4136 
4137 #define FREETYPE_VER_FIXED ( ( (FT_Long)FREETYPE_MAJOR << 16 ) | \
4138  FREETYPE_MINOR )
4139 
4140  if ( !library )
4141  return FT_Err_Invalid_Library_Handle;
4142 
4143  if ( !clazz )
4144  return FT_Err_Invalid_Argument;
4145 
4146  /* check freetype version */
4147  if ( clazz->module_requires > FREETYPE_VER_FIXED )
4148  return FT_Err_Invalid_Version;
4149 
4150  /* look for a module with the same name in the library's table */
4151  for ( nn = 0; nn < library->num_modules; nn++ )
4152  {
4153  module = library->modules[nn];
4154  if ( ft_strcmp( module->clazz->module_name, clazz->module_name ) == 0 )
4155  {
4156  /* this installed module has the same name, compare their versions */
4157  if ( clazz->module_version <= module->clazz->module_version )
4158  return FT_Err_Lower_Module_Version;
4159 
4160  /* remove the module from our list, then exit the loop to replace */
4161  /* it by our new version.. */
4162  FT_Remove_Module( library, module );
4163  break;
4164  }
4165  }
4166 
4167  memory = library->memory;
4168  error = FT_Err_Ok;
4169 
4170  if ( library->num_modules >= FT_MAX_MODULES )
4171  {
4172  error = FT_Err_Too_Many_Drivers;
4173  goto Exit;
4174  }
4175 
4176  /* allocate module object */
4177  if ( FT_ALLOC( module, clazz->module_size ) )
4178  goto Exit;
4179 
4180  /* base initialization */
4181  module->library = library;
4182  module->memory = memory;
4183  module->clazz = (FT_Module_Class*)clazz;
4184 
4185  /* check whether the module is a renderer - this must be performed */
4186  /* before the normal module initialization */
4187  if ( FT_MODULE_IS_RENDERER( module ) )
4188  {
4189  /* add to the renderers list */
4190  error = ft_add_renderer( module );
4191  if ( error )
4192  goto Fail;
4193  }
4194 
4195  /* is the module a auto-hinter? */
4196  if ( FT_MODULE_IS_HINTER( module ) )
4197  library->auto_hinter = module;
4198 
4199  /* if the module is a font driver */
4200  if ( FT_MODULE_IS_DRIVER( module ) )
4201  {
4202  /* allocate glyph loader if needed */
4203  FT_Driver driver = FT_DRIVER( module );
4204 
4205 
4206  driver->clazz = (FT_Driver_Class)module->clazz;
4207  if ( FT_DRIVER_USES_OUTLINES( driver ) )
4208  {
4209  error = FT_GlyphLoader_New( memory, &driver->glyph_loader );
4210  if ( error )
4211  goto Fail;
4212  }
4213  }
4214 
4215  if ( clazz->module_init )
4216  {
4217  error = clazz->module_init( module );
4218  if ( error )
4219  goto Fail;
4220  }
4221 
4222  /* add module to the library's table */
4223  library->modules[library->num_modules++] = module;
4224 
4225  Exit:
4226  return error;
4227 
4228  Fail:
4229  if ( FT_MODULE_IS_DRIVER( module ) )
4230  {
4231  FT_Driver driver = FT_DRIVER( module );
4232 
4233 
4234  if ( FT_DRIVER_USES_OUTLINES( driver ) )
4235  FT_GlyphLoader_Done( driver->glyph_loader );
4236  }
4237 
4238  if ( FT_MODULE_IS_RENDERER( module ) )
4239  {
4240  FT_Renderer renderer = FT_RENDERER( module );
4241 
4242 
4243  if ( renderer->clazz->glyph_format == FT_GLYPH_FORMAT_OUTLINE &&
4244  renderer->raster )
4245  renderer->clazz->raster_class->raster_done( renderer->raster );
4246  }
4247 
4248  FT_FREE( module );
4249  goto Exit;
4250  }
4251 
4252 
4253  /* documentation is in ftmodapi.h */
4254 
4257  const char* module_name )
4258  {
4259  FT_Module result = 0;
4260  FT_Module* cur;
4261  FT_Module* limit;
4262 
4263 
4264  if ( !library || !module_name )
4265  return result;
4266 
4267  cur = library->modules;
4268  limit = cur + library->num_modules;
4269 
4270  for ( ; cur < limit; cur++ )
4271  if ( ft_strcmp( cur[0]->clazz->module_name, module_name ) == 0 )
4272  {
4273  result = cur[0];
4274  break;
4275  }
4276 
4277  return result;
4278  }
4279 
4280 
4281  /* documentation is in ftobjs.h */
4282 
4283  FT_BASE_DEF( const void* )
4285  const char* mod_name )
4286  {
4287  FT_Module module;
4288 
4289 
4290  /* test for valid `library' delayed to FT_Get_Module() */
4291 
4292  module = FT_Get_Module( library, mod_name );
4293 
4294  return module ? module->clazz->module_interface : 0;
4295  }
4296 
4297 
4300  const char* service_id )
4301  {
4303 
4304  if ( module )
4305  {
4306  FT_ASSERT( module->clazz && module->clazz->get_interface );
4307 
4308  /* first, look for the service in the module
4309  */
4310  if ( module->clazz->get_interface )
4311  result = module->clazz->get_interface( module, service_id );
4312 
4313  if ( result == NULL )
4314  {
4315  /* we didn't find it, look in all other modules then
4316  */
4317  FT_Library library = module->library;
4318  FT_Module* cur = library->modules;
4319  FT_Module* limit = cur + library->num_modules;
4320 
4321 
4322  for ( ; cur < limit; cur++ )
4323  {
4324  if ( cur[0] != module )
4325  {
4326  FT_ASSERT( cur[0]->clazz );
4327 
4328  if ( cur[0]->clazz->get_interface )
4329  {
4330  result = cur[0]->clazz->get_interface( cur[0], service_id );
4331  if ( result != NULL )
4332  break;
4333  }
4334  }
4335  }
4336  }
4337  }
4338 
4339  return result;
4340  }
4341 
4342 
4343  /* documentation is in ftmodapi.h */
4344 
4347  FT_Module module )
4348  {
4349  /* try to find the module from the table, then remove it from there */
4350 
4351  if ( !library )
4352  return FT_Err_Invalid_Library_Handle;
4353 
4354  if ( module )
4355  {
4356  FT_Module* cur = library->modules;
4357  FT_Module* limit = cur + library->num_modules;
4358 
4359 
4360  for ( ; cur < limit; cur++ )
4361  {
4362  if ( cur[0] == module )
4363  {
4364  /* remove it from the table */
4365  library->num_modules--;
4366  limit--;
4367  while ( cur < limit )
4368  {
4369  cur[0] = cur[1];
4370  cur++;
4371  }
4372  limit[0] = 0;
4373 
4374  /* destroy the module */
4375  Destroy_Module( module );
4376 
4377  return FT_Err_Ok;
4378  }
4379  }
4380  }
4381  return FT_Err_Invalid_Driver_Handle;
4382  }
4383 
4384 
4385  /*************************************************************************/
4386  /*************************************************************************/
4387  /*************************************************************************/
4388  /**** ****/
4389  /**** ****/
4390  /**** L I B R A R Y ****/
4391  /**** ****/
4392  /**** ****/
4393  /*************************************************************************/
4394  /*************************************************************************/
4395  /*************************************************************************/
4396 
4397 
4398  /* documentation is in ftmodapi.h */
4399 
4402  {
4403  library->refcount++;
4404 
4405  return FT_Err_Ok;
4406  }
4407 
4408 
4409  /* documentation is in ftmodapi.h */
4410 
4413  FT_Library *alibrary )
4414  {
4415  FT_Library library = NULL;
4416  FT_Error error;
4417 
4418 
4419  if ( !memory )
4420  return FT_Err_Invalid_Argument;
4421 
4422 #ifdef FT_DEBUG_LEVEL_ERROR
4423  /* init debugging support */
4424  ft_debug_init();
4425 #endif
4426 
4427  /* first of all, allocate the library object */
4428  if ( FT_NEW( library ) )
4429  return error;
4430 
4431  library->memory = memory;
4432 
4433 #ifdef FT_CONFIG_OPTION_PIC
4434  /* initialize position independent code containers */
4435  error = ft_pic_container_init( library );
4436  if ( error )
4437  goto Fail;
4438 #endif
4439 
4440  /* allocate the render pool */
4442 #if FT_RENDER_POOL_SIZE > 0
4443  if ( FT_ALLOC( library->raster_pool, FT_RENDER_POOL_SIZE ) )
4444  goto Fail;
4445 #endif
4446 
4447  library->version_major = FREETYPE_MAJOR;
4448  library->version_minor = FREETYPE_MINOR;
4449  library->version_patch = FREETYPE_PATCH;
4450 
4451  library->refcount = 1;
4452 
4453  /* That's ok now */
4454  *alibrary = library;
4455 
4456  return FT_Err_Ok;
4457 
4458  Fail:
4459 #ifdef FT_CONFIG_OPTION_PIC
4460  ft_pic_container_destroy( library );
4461 #endif
4462  FT_FREE( library );
4463  return error;
4464  }
4465 
4466 
4467  /* documentation is in freetype.h */
4468 
4469  FT_EXPORT_DEF( void )
4471  FT_Int *amajor,
4472  FT_Int *aminor,
4473  FT_Int *apatch )
4474  {
4475  FT_Int major = 0;
4476  FT_Int minor = 0;
4477  FT_Int patch = 0;
4478 
4479 
4480  if ( library )
4481  {
4482  major = library->version_major;
4483  minor = library->version_minor;
4484  patch = library->version_patch;
4485  }
4486 
4487  if ( amajor )
4488  *amajor = major;
4489 
4490  if ( aminor )
4491  *aminor = minor;
4492 
4493  if ( apatch )
4494  *apatch = patch;
4495  }
4496 
4497 
4498  /* documentation is in ftmodapi.h */
4499 
4502  {
4503  FT_Memory memory;
4504 
4505 
4506  if ( !library )
4507  return FT_Err_Invalid_Library_Handle;
4508 
4509  library->refcount--;
4510  if ( library->refcount > 0 )
4511  goto Exit;
4512 
4513  memory = library->memory;
4514 
4515  /*
4516  * Close all faces in the library. If we don't do this, we can have
4517  * some subtle memory leaks.
4518  *
4519  * Example:
4520  *
4521  * - the cff font driver uses the pshinter module in cff_size_done
4522  * - if the pshinter module is destroyed before the cff font driver,
4523  * opened FT_Face objects managed by the driver are not properly
4524  * destroyed, resulting in a memory leak
4525  *
4526  * Some faces are dependent on other faces, like Type42 faces that
4527  * depend on TrueType faces synthesized internally.
4528  *
4529  * The order of drivers should be specified in driver_name[].
4530  */
4531  {
4532  FT_UInt m, n;
4533  const char* driver_name[] = { "type42", NULL };
4534 
4535 
4536  for ( m = 0;
4537  m < sizeof ( driver_name ) / sizeof ( driver_name[0] );
4538  m++ )
4539  {
4540  for ( n = 0; n < library->num_modules; n++ )
4541  {
4542  FT_Module module = library->modules[n];
4543  const char* module_name = module->clazz->module_name;
4544  FT_List faces;
4545 
4546 
4547  if ( driver_name[m] &&
4548  ft_strcmp( module_name, driver_name[m] ) != 0 )
4549  continue;
4550 
4551  if ( ( module->clazz->module_flags & FT_MODULE_FONT_DRIVER ) == 0 )
4552  continue;
4553 
4554  FT_TRACE7(( "FT_Done_Library: close faces for %s\n", module_name ));
4555 
4556  faces = &FT_DRIVER( module )->faces_list;
4557  while ( faces->head )
4558  {
4559  FT_Done_Face( FT_FACE( faces->head->data ) );
4560  if ( faces->head )
4561  FT_TRACE0(( "FT_Done_Library: failed to free some faces\n" ));
4562  }
4563  }
4564  }
4565  }
4566 
4567  /* Close all other modules in the library */
4568 #if 1
4569  /* XXX Modules are removed in the reversed order so that */
4570  /* type42 module is removed before truetype module. This */
4571  /* avoids double free in some occasions. It is a hack. */
4572  while ( library->num_modules > 0 )
4573  FT_Remove_Module( library,
4574  library->modules[library->num_modules - 1] );
4575 #else
4576  {
4577  FT_UInt n;
4578 
4579 
4580  for ( n = 0; n < library->num_modules; n++ )
4581  {
4582  FT_Module module = library->modules[n];
4583 
4584 
4585  if ( module )
4586  {
4587  Destroy_Module( module );
4588  library->modules[n] = 0;
4589  }
4590  }
4591  }
4592 #endif
4593 
4594  /* Destroy raster objects */
4595  FT_FREE( library->raster_pool );
4596  library->raster_pool_size = 0;
4597 
4598 #ifdef FT_CONFIG_OPTION_PIC
4599  /* Destroy pic container contents */
4600  ft_pic_container_destroy( library );
4601 #endif
4602 
4603  FT_FREE( library );
4604 
4605  Exit:
4606  return FT_Err_Ok;
4607  }
4608 
4609 
4610  /* documentation is in ftmodapi.h */
4611 
4612  FT_EXPORT_DEF( void )
4614  FT_UInt hook_index,
4615  FT_DebugHook_Func debug_hook )
4616  {
4617  if ( library && debug_hook &&
4618  hook_index <
4619  ( sizeof ( library->debug_hooks ) / sizeof ( void* ) ) )
4620  library->debug_hooks[hook_index] = debug_hook;
4621  }
4622 
4623 
4624  /* documentation is in ftmodapi.h */
4625 
4628  {
4630 
4631 
4632  if ( library )
4633  {
4634  FT_Module module = FT_Get_Module( library, "truetype" );
4635 
4636 
4637  if ( module )
4638  {
4639  FT_Service_TrueTypeEngine service;
4640 
4641 
4642  service = (FT_Service_TrueTypeEngine)
4643  ft_module_get_service( module,
4645  if ( service )
4646  result = service->engine_type;
4647  }
4648  }
4649 
4650  return result;
4651  }
4652 
4653 
4654 #ifdef FT_CONFIG_OPTION_OLD_INTERNALS
4655 
4657  ft_stub_set_char_sizes( FT_Size size,
4658  FT_F26Dot6 width,
4660  FT_UInt horz_res,
4661  FT_UInt vert_res )
4662  {
4663  FT_Size_RequestRec req;
4664  FT_Driver driver = size->face->driver;
4665 
4666 
4667  if ( driver->clazz->request_size )
4668  {
4670  req.width = width;
4671  req.height = height;
4672 
4673  if ( horz_res == 0 )
4674  horz_res = vert_res;
4675 
4676  if ( vert_res == 0 )
4677  vert_res = horz_res;
4678 
4679  if ( horz_res == 0 )
4680  horz_res = vert_res = 72;
4681 
4682  req.horiResolution = horz_res;
4683  req.vertResolution = vert_res;
4684 
4685  return driver->clazz->request_size( size, &req );
4686  }
4687 
4688  return 0;
4689  }
4690 
4691 
4693  ft_stub_set_pixel_sizes( FT_Size size,
4694  FT_UInt width,
4695  FT_UInt height )
4696  {
4697  FT_Size_RequestRec req;
4698  FT_Driver driver = size->face->driver;
4699 
4700 
4701  if ( driver->clazz->request_size )
4702  {
4704  req.width = width << 6;
4705  req.height = height << 6;
4706  req.horiResolution = 0;
4707  req.vertResolution = 0;
4708 
4709  return driver->clazz->request_size( size, &req );
4710  }
4711 
4712  return 0;
4713  }
4714 
4715 #endif /* FT_CONFIG_OPTION_OLD_INTERNALS */
4716 
4717 
4718  /* documentation is in freetype.h */
4719 
4722  FT_UInt sub_index,
4723  FT_Int *p_index,
4724  FT_UInt *p_flags,
4725  FT_Int *p_arg1,
4726  FT_Int *p_arg2,
4727  FT_Matrix *p_transform )
4728  {
4730 
4731 
4732  if ( glyph &&
4733  glyph->subglyphs &&
4734  glyph->format == FT_GLYPH_FORMAT_COMPOSITE &&
4735  sub_index < glyph->num_subglyphs )
4736  {
4737  FT_SubGlyph subg = glyph->subglyphs + sub_index;
4738 
4739 
4740  *p_index = subg->index;
4741  *p_flags = subg->flags;
4742  *p_arg1 = subg->arg1;
4743  *p_arg2 = subg->arg2;
4744  *p_transform = subg->transform;
4745  }
4746 
4747  return error;
4748  }
4749 
4750 
4751 /* END */
unsigned char * base
Definition: ftsystem.h:323
#define ft_jmp_buf
Definition: ftstdlib.h:157
const FT_Byte * memory_base
Definition: freetype.h:1832
#define FT_ALLOC(ptr, size)
Definition: ftmemory.h:260
GLenum GLsizei GLenum GLenum const GLvoid * table
Definition: glew.h:4422
ft_glyphslot_set_bitmap(FT_GlyphSlot slot, FT_Byte *buffer)
Definition: ftobjs.c:283
#define FT_PIX_CEIL(x)
Definition: ftobjs.h:82
FT_Face face
Definition: freetype.h:1397
FT_Get_Kerning(FT_Face face, FT_UInt left_glyph, FT_UInt right_glyph, FT_UInt kern_mode, FT_Vector *akerning)
Definition: ftobjs.c:2963
#define FREETYPE_VER_FIXED
static void ft_remove_renderer(FT_Module module)
Definition: ftobjs.c:3904
ft_service_list_lookup(FT_ServiceDesc service_descriptors, const char *service_id)
Definition: ftobjs.c:47
#define FREETYPE_MINOR
Definition: freetype.h:3836
int FT_Error
Definition: fttypes.h:296
FT_Module_Destructor module_done
Definition: ftmodapi.h:170
#define FT_DRIVER(x)
Definition: ftobjs.h:686
#define FT_LOAD_VERTICAL_LAYOUT
Definition: freetype.h:2516
FT_DivFix(FT_Long a, FT_Long b)
Definition: ftcalc.c:536
FT_Get_CMap_Format(FT_CharMap charmap)
Definition: ftobjs.c:3730
GLint GLint bottom
Definition: glew.h:7291
FT_ULong raster_pool_size
Definition: ftobjs.h:841
FT_Raster_Render_Func raster_render
Definition: ftobjs.h:666
FT_Raccess_Get_DataOffsets(FT_Library library, FT_Stream stream, FT_Long map_offset, FT_Long rdata_pos, FT_Long tag, FT_Long **offsets, FT_Long *count)
Definition: ftrfork.c:149
FT_Int num_fixed_sizes
Definition: freetype.h:925
signed long FT_Long
Definition: fttypes.h:238
FT_Pos x_ppem
Definition: freetype.h:301
static FT_CharMap find_variant_selector_charmap(FT_Face face)
Definition: ftobjs.c:1060
FT_Stream_Seek(FT_Stream stream, FT_ULong pos)
Definition: ftstream.c:57
cannot open resource broken file module version is too low unimplemented feature broken offset within table missing module invalid character code cannot render this glyph format invalid composite glyph invalid pixel size invalid library handle invalid face handle invalid glyph slot handle invalid cache manager handle too many modules out of memory cannot open stream invalid stream skip invalid stream operation nested frame access raster uninitialized raster overflow too many registered caches too few arguments code overflow division by zero found debug opcode nested DEFS execution context too long too many instruction definitions horizontal header(hhea) table missing" ) FT_ERRORDEF_( Locations_Missing
unsigned long FT_ULong
Definition: fttypes.h:249
unsigned long size
Definition: ftsystem.h:324
static void ft_glyphslot_done(FT_GlyphSlot slot)
Definition: ftobjs.c:345
FT_Select_Size(FT_Face face, FT_Int strike_index)
Definition: ftobjs.c:2759
#define FT_OPEN_PATHNAME
Definition: freetype.h:1734
#define FT_LOAD_SBITS_ONLY
Definition: freetype.h:2531
FT_Size_InitFunc init_size
Definition: ftdriver.h:193
FT_BEGIN_HEADER typedef signed long FT_Pos
Definition: ftimage.h:59
FT_Renderer_RenderFunc render
Definition: ftobjs.h:667
FT_ListNode head
Definition: fttypes.h:565
FT_CMap_CharVarIndexFunc char_var_index
Definition: ftobjs.h:201
ft_synthesize_vertical_metrics(FT_Glyph_Metrics *metrics, FT_Pos advance)
Definition: ftobjs.c:2530
GLfloat GLfloat GLfloat GLfloat h
Definition: glew.h:7294
GLint GLenum GLsizei GLsizei GLsizei GLint GLenum GLenum type
Definition: gl2ext.h:845
FT_Generic_Finalizer finalizer
Definition: fttypes.h:458
FT_Generic generic
Definition: freetype.h:1398
GLvoid **typedef void(GLAPIENTRY *PFNGLGETVERTEXATTRIBDVPROC)(GLuint
Definition: glew.h:1824
FT_SERVICE_ID_TRUETYPE_ENGINE
Definition: ttdriver.c:395
FT_Driver_Class clazz
Definition: ftobjs.h:718
FT_Select_Metrics(FT_Face face, FT_ULong strike_index)
Definition: ftobjs.c:2590
FT_CharMap charmap
Definition: freetype.h:951
FT_Set_Transform(FT_Face face, FT_Matrix *matrix, FT_Vector *delta)
Definition: ftobjs.c:466
FT_UInt flags
Definition: freetype.h:1831
FT_Glyph_Format glyph_format
Definition: ftrender.h:148
#define NULL
Definition: ftobjs.h:61
signed int FT_Int
Definition: fttypes.h:216
void(* FT_Stream_CloseFunc)(FT_Stream stream)
Definition: ftsystem.h:268
int rows
Definition: ftimage.h:312
FT_Short ascender
Definition: freetype.h:939
#define FT_REQUEST_HEIGHT(req)
Definition: ftobjs.h:587
FT_String * pathname
Definition: freetype.h:1834
FT_Slot_DoneFunc done_slot
Definition: ftdriver.h:197
enum FT_Render_Mode_ FT_Render_Mode
return FT_Err_Invalid_Argument
Definition: ftbbox.c:584
enum FT_ValidationLevel_ FT_ValidationLevel
FT_Module_Class * clazz
Definition: ftobjs.h:441
GLuint GLuint stream
Definition: glew.h:6573
GLclampd n
Definition: glew.h:7287
FT_Generic generic
Definition: freetype.h:1611
FT_Get_Next_Char(FT_Face face, FT_ULong char_code, FT_UInt *agindex)
Definition: ftobjs.c:3339
FT_Short height
Definition: freetype.h:296
#define FT_LOAD_NO_HINTING
Definition: freetype.h:2513
static void destroy_face(FT_Memory memory, FT_Face face, FT_Driver driver)
Definition: ftobjs.c:877
FT_List_Finalize(FT_List list, FT_List_Destructor destroy, FT_Memory memory, void *user)
Definition: ftutil.c:386
FT_Done_Library(FT_Library library)
Definition: ftobjs.c:4501
FT_Int arg1
Definition: ftgloadr.h:61
#define FT_OPEN_PARAMS
Definition: freetype.h:1736
FT_Library library
Definition: ftobjs.h:442
#define FT_DRIVER_HAS_HINTER(x)
Definition: ftobjs.h:473
GLuint GLsizei GLsizei GLfloat * metrics
Definition: glew.h:12394
GLuint GLsizei const GLuint const GLintptr * offsets
Definition: glew.h:4750
FT_Short descender
Definition: freetype.h:940
FT_List_Remove(FT_List list, FT_ListNode node)
Definition: ftutil.c:305
#define FT_LOAD_NO_RECURSE
Definition: freetype.h:2521
static void render(const Vertex_Buffer_Macrorenderer &macrorenderer, std::vector< Vertex_Buffer::Vertex_Buffer_Range * > &descriptors)
FT_New_GlyphSlot(FT_Face face, FT_GlyphSlot *aslot)
Definition: ftobjs.c:376
FT_Reference_Face(FT_Face face)
Definition: ftobjs.c:2318
#define ft_longjmp
Definition: ftstdlib.h:161
static FT_Renderer ft_lookup_glyph_renderer(FT_GlyphSlot slot)
Definition: ftobjs.c:3830
FT_Bitmap_Size * available_sizes
Definition: freetype.h:926
int32_t j
Definition: e_log.c:102
FT_ListRec faces_list
Definition: ftobjs.h:719
FT_Stream_Pos(FT_Stream stream)
Definition: ftstream.c:103
EGLSurface EGLint EGLint EGLint EGLint height
Definition: eglext.h:293
#define FT_OPEN_MEMORY
Definition: freetype.h:1732
FT_Fixed linearHoriAdvance
Definition: freetype.h:1614
FT_Int bitmap_top
Definition: freetype.h:1622
FT_GlyphLoader_New(FT_Memory memory, FT_GlyphLoader *aloader)
Definition: ftgloadr.c:69
FT_Remove_Module(FT_Library library, FT_Module module)
Definition: ftobjs.c:4346
static void ft_glyphslot_grid_fit_metrics(FT_GlyphSlot slot, FT_Bool vertical)
Definition: ftobjs.c:518
FT_Library library
Definition: cffdrivr.c:409
ft_validator_run(FT_Validator valid)
Definition: ftobjs.c:84
int pitch
Definition: ftimage.h:314
#define FT_OPEN_STREAM
Definition: freetype.h:1733
FT_Vector advance
Definition: freetype.h:1616
FT_Library library
Definition: freetype.h:1607
return FT_Err_Ok
Definition: ftbbox.c:658
FT_Raster raster
Definition: ftobjs.h:665
#define FT_PARAM_TAG_INCREMENTAL
Definition: ftincrem.h:344
#define FT_READ_USHORT(var)
Definition: ftstream.h:316
#define FT_MAX_CHARMAP_CACHEABLE
Definition: ftoption.h:784
FT_Stream_Close(FT_Stream stream)
Definition: ftstream.c:49
FT_Done_GlyphSlot(FT_GlyphSlot slot)
Definition: ftobjs.c:425
FT_Render_Glyph_Internal(FT_Library library, FT_GlyphSlot slot, FT_Render_Mode render_mode)
Definition: ftobjs.c:3993
FT_Int index
Definition: ftgloadr.h:59
#define TT_PLATFORM_MICROSOFT
Definition: ttnameid.h:89
struct FT_AutoHinter_ServiceRec_ * FT_AutoHinter_Service
GLenum GLsizei len
Definition: glew.h:7035
FT_New_Memory_Face(FT_Library library, const FT_Byte *file_base, FT_Long file_size, FT_Long face_index, FT_Face *aface)
Definition: ftobjs.c:1224
#define FT_DRIVER_USES_OUTLINES(x)
Definition: ftobjs.h:470
static void ft_recompute_scaled_metrics(FT_Face face, FT_Size_Metrics *metrics)
Definition: ftobjs.c:2556
#define FT_GLYPH_OWN_BITMAP
Definition: ftobjs.h:376
FT_Face_GetCharVariantIsDefault(FT_Face face, FT_ULong charcode, FT_ULong variantSelector)
Definition: ftobjs.c:3413
FT_BEGIN_HEADER open_face_PS_from_sfnt_stream(FT_Library library, FT_Stream stream, FT_Long face_index, FT_Int num_params, FT_Parameter *params, FT_Face *aface)
#define TTAG_TYP1
Definition: tttags.h:95
void * data
Definition: fttypes.h:544
FT_UShort flags
Definition: ftgloadr.h:60
#define FT_OPEN_DRIVER
Definition: freetype.h:1735
if(!yyg->yy_init)
FT_Generic autohint
Definition: freetype.h:961
#define FT_CMAP(x)
Definition: ftobjs.h:139
FT_Pos max_advance
Definition: freetype.h:1371
FT_Lookup_Renderer(FT_Library library, FT_Glyph_Format format, FT_ListNode *node)
Definition: ftobjs.c:3788
FT_BEGIN_HEADER typedef unsigned char FT_Bool
Definition: fttypes.h:104
FT_Face face
Definition: freetype.h:738
#define FT_LOAD_LINEAR_DESIGN
Definition: freetype.h:2524
FT_Set_Pixel_Sizes(FT_Face face, FT_UInt pixel_width, FT_UInt pixel_height)
Definition: ftobjs.c:2927
#define FT_LOAD_NO_SCALE
Definition: freetype.h:2512
FT_Face_Internal internal
Definition: freetype.h:964
FT_ListNode next
Definition: fttypes.h:543
FT_Get_CMap_Language_ID(FT_CharMap charmap)
Definition: ftobjs.c:3706
FT_Short max_advance_height
Definition: freetype.h:944
#define FT_TRACE1(varformat)
Definition: ftdebug.h:158
open_face_from_buffer(FT_Library library, FT_Byte *base, FT_ULong size, FT_Long face_index, const char *driver_name, FT_Face *aface)
FT_Size_SelectFunc select_size
Definition: ftdriver.h:214
TT_CMapInfo * cmap_info
Definition: cffdrivr.c:405
FT_Outline outline
Definition: freetype.h:1624
FT_Module auto_hinter
Definition: ftobjs.h:837
FT_Get_Charmap_Index(FT_CharMap charmap)
Definition: ftobjs.c:3147
#define FT_ERROR(varformat)
Definition: ftdebug.h:181
FT_Int version_patch
Definition: ftobjs.h:830
unsigned char FT_Byte
Definition: fttypes.h:150
FT_Renderer_RenderFunc render_glyph
Definition: ftrender.h:150
#define FT_ASSERT(condition)
Definition: ftdebug.h:204
FT_CMap_CharIndexFunc char_index
Definition: ftobjs.h:195
enum FT_Sfnt_Tag_ FT_Sfnt_Tag
#define FT_LOAD_RENDER
Definition: freetype.h:2514
GLenum GLvoid ** params
Definition: gl2ext.h:806
FT_Load_Glyph(FT_Face face, FT_UInt glyph_index, FT_Int32 load_flags)
Definition: ftobjs.c:563
FT_Long size_object_size
Definition: ftdriver.h:187
FT_Matrix transform
Definition: ftgloadr.h:63
FT_CMap_VariantListFunc variant_list
Definition: ftobjs.h:203
static FT_Error find_unicode_charmap(FT_Face face)
Definition: ftobjs.c:956
FT_Size_Internal internal
Definition: freetype.h:1400
FT_Add_Module(FT_Library library, const FT_Module_Class *clazz)
Definition: ftobjs.c:4128
#define FT_TRACE4(varformat)
Definition: ftdebug.h:161
FT_Get_Sfnt_Table(FT_Face face, FT_Sfnt_Tag tag)
Definition: ftobjs.c:3639
#define FT_RACCESS_N_RULES
Definition: ftrfork.h:37
FT_Slot_InitFunc init_slot
Definition: ftdriver.h:196
FT_Attach_Stream(FT_Face face, FT_Open_Args *parameters)
Definition: ftobjs.c:2274
FT_Face_GetCharVariantIndex(FT_Face face, FT_ULong charcode, FT_ULong variantSelector)
Definition: ftobjs.c:3370
FT_CMap_CharVariantListFunc charvariant_list
Definition: ftobjs.h:204
EGLContext EGLenum EGLClientBuffer buffer
Definition: eglext.h:87
FT_Bitmap bitmap
Definition: freetype.h:1620
#define FT_FACE_LOOKUP_SERVICE(face, ptr, id)
Definition: ftserv.h:625
FT_Memory memory
Definition: ftobjs.h:826
FT_Match_Size(FT_Face face, FT_Size_Request req, FT_Bool ignore_width, FT_ULong *size_index)
Definition: ftobjs.c:2479
FT_ListRec renderers
Definition: ftobjs.h:835
#define FT_PIX_FLOOR(x)
Definition: ftobjs.h:80
#define FT_LOAD_FORCE_AUTOHINT
Definition: freetype.h:2517
FT_GlyphSlot next
Definition: freetype.h:1609
#define FT_MODULE_IS_DRIVER(x)
Definition: ftobjs.h:455
#define TT_APPLE_ID_VARIANT_SELECTOR
Definition: ttnameid.h:129
const char * serv_id
Definition: ftserv.h:159
FT_Memory memory
Definition: ftsystem.h:332
FT_Int num_charmaps
Definition: freetype.h:928
#define FT_REQUEST_WIDTH(req)
Definition: ftobjs.h:582
#define FT_FREE(ptr)
Definition: ftmemory.h:286
ft_module_get_service(FT_Module module, const char *service_id)
Definition: ftobjs.c:4299
FT_Outline_Transform(const FT_Outline *outline, const FT_Matrix *matrix)
Definition: ftoutln.c:695
FT_Face_GetVariantsOfChar(FT_Face face, FT_ULong charcode)
Definition: ftobjs.c:3481
FT_Pos rsb_delta
Definition: freetype.h:1633
#define TTAG_POST
Definition: tttags.h:85
#define FT_STREAM_SKIP(distance)
Definition: ftstream.h:499
FT_List_Up(FT_List list, FT_ListNode node)
Definition: ftutil.c:329
FT_Long slot_object_size
Definition: ftdriver.h:188
GLint first
Definition: gl2ext.h:1011
FT_Raster_Funcs * raster_class
Definition: ftrender.h:155
FT_Module driver
Definition: freetype.h:1836
FT_GlyphLoader_Done(FT_GlyphLoader loader)
Definition: ftgloadr.c:127
GLuint64EXT * result
Definition: glew.h:12708
#define FT_LOCAL_DEF(x)
Definition: ftconfig.h:467
FT_Int transform_flags
Definition: ftobjs.h:328
FT_ModuleRec root
Definition: ftobjs.h:717
struct TT_FaceRec_ * TT_Face
Definition: tttypes.h:951
FT_Request_Size(FT_Face face, FT_Size_Request req)
Definition: ftobjs.c:2811
FT_Get_Char_Index(FT_Face face, FT_ULong charcode)
Definition: ftobjs.c:3290
FT_Stream_Read(FT_Stream stream, FT_Byte *buffer, FT_ULong count)
Definition: ftstream.c:110
FT_Request_Metrics(FT_Face face, FT_Size_Request req)
Definition: ftobjs.c:2637
TT_MaxProfile max_profile
Definition: tttypes.h:1271
FT_Set_Char_Size(FT_Face face, FT_F26Dot6 char_width, FT_F26Dot6 char_height, FT_UInt horz_resolution, FT_UInt vert_resolution)
Definition: ftobjs.c:2887
FT_Raster_DoneFunc raster_done
Definition: ftimage.h:1295
GLsizei GLsizei * length
Definition: gl2ext.h:792
#define FT_DRIVER_IS_SCALABLE(x)
Definition: ftobjs.h:467
FT_MulDiv(FT_Long a, FT_Long b, FT_Long c)
Definition: ftcalc.c:358
FT_Load_Sfnt_Table(FT_Face face, FT_ULong tag, FT_Long offset, FT_Byte *buffer, FT_ULong *length)
Definition: ftobjs.c:3660
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
static void Destroy_Module(FT_Module module)
Definition: ftobjs.c:4098
#define FREETYPE_PATCH
Definition: freetype.h:3837
FT_UInt num_subglyphs
Definition: freetype.h:1626
Colormap cmap
FT_Incremental_InterfaceRec * FT_Incremental_Interface
Definition: ftincrem.h:331
FT_Get_Postscript_Name(FT_Face face)
Definition: ftobjs.c:3610
FT_Pos x
Definition: ftimage.h:77
ft_glyphslot_alloc_bitmap(FT_GlyphSlot slot, FT_ULong size)
Definition: ftobjs.c:295
#define FT_READ_ULONG(var)
Definition: ftstream.h:320
#define FT_TRACE0(varformat)
Definition: ftdebug.h:157
FT_Int version_minor
Definition: ftobjs.h:829
FT_Renderer_TransformFunc transform_glyph
Definition: ftrender.h:151
char FT_String
Definition: fttypes.h:183
FT_Get_Track_Kerning(FT_Face face, FT_Fixed point_size, FT_Int degree, FT_Fixed *akerning)
Definition: ftobjs.c:3023
void * FT_Pointer
Definition: fttypes.h:307
#define FT_ZERO(p)
Definition: ftmemory.h:210
FT_ULong num_locations
Definition: tttypes.h:1404
GLint GLsizei count
Definition: gl2ext.h:1011
#define FT_HAS_FIXED_SIZES(face)
Definition: freetype.h:1190
FT_BEGIN_HEADER FT_List_Find(FT_List list, void *data)
Definition: ftutil.c:241
FT_Select_Charmap(FT_Face face, FT_Encoding encoding)
Definition: ftobjs.c:3054
static void destroy_charmaps(FT_Face face, FT_Memory memory)
Definition: ftobjs.c:851
GLenum face
Definition: gl2ext.h:1490
FT_StreamDesc pathname
Definition: ftsystem.h:328
FT_GlyphLoader glyph_loader
Definition: ftobjs.h:720
#define FT_IS_TRICKY(face)
Definition: freetype.h:1263
FT_Pos y
Definition: ftimage.h:78
FT_Face_GetKerningFunc get_kerning
Definition: ftdriver.h:208
typedefFT_BEGIN_HEADER struct FT_ValidatorRec_ volatile * FT_Validator
Definition: ftvalid.h:42
FT_Size_DoneFunc done_size
Definition: ftdriver.h:194
FT_Activate_Size(FT_Size size)
Definition: ftobjs.c:3754
FT_Done_Size(FT_Size size)
Definition: ftobjs.c:2431
FT_UShort maxSizeOfInstructions
Definition: tttables.h:542
const void * module_interface
Definition: ftmodapi.h:167
FT_Renderer cur_renderer
Definition: ftobjs.h:836
FT_Stream_CloseFunc close
Definition: ftsystem.h:330
FT_Int version_major
Definition: ftobjs.h:828
FT_Render_Glyph(FT_GlyphSlot slot, FT_Render_Mode render_mode)
Definition: ftobjs.c:4054
GLint GLenum GLsizei GLsizei GLsizei GLint GLenum format
Definition: gl2ext.h:845
FT_Get_SubGlyph_Info(FT_GlyphSlot glyph, FT_UInt sub_index, FT_Int *p_index, FT_UInt *p_flags, FT_Int *p_arg1, FT_Int *p_arg2, FT_Matrix *p_transform)
Definition: ftobjs.c:4721
GLint limit
Definition: glew.h:11829
#define FT_TRACE7(varformat)
Definition: ftdebug.h:164
#define FT_RENEW_ARRAY(ptr, curcnt, newcnt)
Definition: ftmemory.h:293
#define FT_IS_SFNT(face)
Definition: freetype.h:1160
FT_GlyphLoader loader
Definition: ftobjs.h:380
FT_Load_Char(FT_Face face, FT_ULong char_code, FT_Int32 load_flags)
Definition: ftobjs.c:809
ft_validator_error(FT_Validator valid, FT_Error error)
Definition: ftobjs.c:94
#define FREETYPE_MAJOR
Definition: freetype.h:3835
static FT_Error open_face(FT_Driver driver, FT_Stream stream, FT_Long face_index, FT_Int num_params, FT_Parameter *params, FT_Face *aface)
Definition: ftobjs.c:1108
#define FT_FACE_FLAG_EXTERNAL_STREAM
Definition: freetype.h:1079
FT_Pos descender
Definition: freetype.h:1369
const void * serv_data
Definition: ftserv.h:160
#define TTAG_CID
Definition: tttags.h:44
FT_Get_TrueType_Engine_Type(FT_Library library)
Definition: ftobjs.c:4627
FT_Long format
Definition: svttcmap.h:62
FT_SubGlyph subglyphs
Definition: freetype.h:1627
FT_UShort x_ppem
Definition: freetype.h:1362
#define FT_READ_LONG(var)
Definition: ftstream.h:319
#define TT_MS_ID_UCS_4
Definition: ttnameid.h:286
FT_Get_First_Char(FT_Face face, FT_UInt *agindex)
Definition: ftobjs.c:3315
#define FT_MODULE_FONT_DRIVER
Definition: ftmodapi.h:55
#define TT_APPLE_ID_UNICODE_32
Definition: ttnameid.h:128
enum FT_TrueTypeEngineType_ FT_TrueTypeEngineType
#define FALSE
Definition: ftobjs.h:57
FT_Sfnt_Table_Info(FT_Face face, FT_UInt table_index, FT_ULong *tag, FT_ULong *length)
Definition: ftobjs.c:3683
FT_CharMap * charmaps
Definition: freetype.h:929
enum FT_Encoding_ FT_Encoding
#define FT_LOAD_MONOCHROME
Definition: freetype.h:2523
FT_Pos lsb_delta
Definition: freetype.h:1632
GLuint GLenum matrix
Definition: glew.h:13408
FT_Slot_LoadFunc load_glyph
Definition: ftdriver.h:206
FT_Set_Charmap(FT_Face face, FT_CharMap charmap)
Definition: ftobjs.c:3105
FT_Size size
Definition: freetype.h:950
static FT_Error ft_glyphslot_init(FT_GlyphSlot slot)
Definition: ftobjs.c:235
signed short FT_Short
Definition: fttypes.h:194
FT_Long face_flags
Definition: freetype.h:917
#define TTAG_sfnt
Definition: tttags.h:89
#define FT_HAS_GLYPH_NAMES(face)
Definition: freetype.h:1216
typedefFT_BEGIN_HEADER struct FT_MemoryRec_ * FT_Memory
Definition: ftsystem.h:66
static void Destroy_Driver(FT_Driver driver)
Definition: ftobjs.c:928
FT_List_Add(FT_List list, FT_ListNode node)
Definition: ftutil.c:263
int width
Definition: ftimage.h:313
FT_Glyph_Format glyph_format
Definition: ftobjs.h:662
FT_CMap_DoneFunc done
Definition: ftobjs.h:194
FT_Stream stream
Definition: freetype.h:1835
FT_Fixed xx
Definition: fttypes.h:383
#define FT_BOOL(x)
Definition: fttypes.h:581
FT_Size_RequestFunc request_size
Definition: ftdriver.h:213
FT_Error(* FT_Renderer_SetModeFunc)(FT_Renderer renderer, FT_ULong mode_tag, FT_Pointer mode_ptr)
Definition: ftrender.h:107
Definition: inftrees.h:24
#define TTAG_typ1
Definition: tttags.h:96
sizeof(FT_AutofitterRec)
FT_Generic generic
Definition: freetype.h:931
FT_Face_DoneFunc done_face
Definition: ftdriver.h:191
FT_Size_Request_Type type
Definition: freetype.h:2187
FT_MulFix(FT_Long a, FT_Long b)
Definition: ftcalc.c:435
void * data
Definition: fttypes.h:457
ft_glyphslot_free_bitmap(FT_GlyphSlot slot)
Definition: ftobjs.c:263
signed long FT_F26Dot6
Definition: fttypes.h:272
FT_Outline_Check(FT_Outline *outline)
Definition: ftoutln.c:345
#define FT_HAS_VERTICAL(face)
Definition: freetype.h:1112
FT_Stream_New(FT_Library library, const FT_Open_Args *args, FT_Stream *astream)
Definition: ftobjs.c:127
#define FT_TRACE3(varformat)
Definition: ftdebug.h:160
#define FT_FACE_MEMORY(x)
Definition: ftobjs.h:529
FT_UInt horiResolution
Definition: freetype.h:2190
FT_CMap_New(FT_CMap_Class clazz, FT_Pointer init_data, FT_CharMap charmap, FT_CMap *acmap)
Definition: ftobjs.c:3236
FT_CMap_Done(FT_CMap cmap)
Definition: ftobjs.c:3190
void * pointer
Definition: ftsystem.h:212
#define const
Definition: zconf.h:91
FT_ListRec sizes_list
Definition: freetype.h:959
const FT_String * module_name
Definition: ftmodapi.h:163
FT_Fixed y_scale
Definition: freetype.h:1366
FT_UInt refcount
Definition: ftobjs.h:856
GLintptr offset
Definition: glew.h:1668
FT_Vector_Transform(FT_Vector *vec, const FT_Matrix *matrix)
Definition: ftoutln.c:672
signed long FT_Fixed
Definition: fttypes.h:284
FT_Byte * raster_pool
Definition: ftobjs.h:839
FT_Int bitmap_left
Definition: freetype.h:1621
FT_BEGIN_HEADER struct FT_Glyph_Metrics_ FT_Glyph_Metrics
FT_Glyph_Format format
Definition: freetype.h:1618
FT_Face_AttachFunc attach_file
Definition: ftdriver.h:209
FT_New_Library(FT_Memory memory, FT_Library *alibrary)
Definition: ftobjs.c:4412
#define FT_FACE(x)
Definition: ftobjs.h:523
GLenum GLsizei GLsizei GLsizei GLsizei GLbitfield flags
Definition: glew.h:2767
FT_Memory memory
Definition: ftobjs.h:443
#define ft_memcmp
Definition: ftstdlib.h:80
static void destroy_size(FT_Memory memory, FT_Size size, FT_Driver driver)
Definition: ftobjs.c:829
static FT_Error ft_add_renderer(FT_Module module)
Definition: ftobjs.c:3856
FT_Stream_Free(FT_Stream stream, FT_Int external)
Definition: ftobjs.c:195
FT_GlyphSlot glyph
Definition: freetype.h:949
#define FT_EXPORT_DEF(x)
Definition: ftconfig.h:511
struct FT_SizeRec_ * FT_Size
Definition: freetype.h:429
unsigned int FT_UInt
Definition: fttypes.h:227
#define FT_RENDERER(x)
Definition: ftobjs.h:652
FT_Reference_Library(FT_Library library)
Definition: ftobjs.c:4401
#define FT_MODULE_IS_RENDERER(x)
Definition: ftobjs.h:458
enum FT_Glyph_Format_ FT_Glyph_Format
FT_ULong language
Definition: svttcmap.h:61
FT_Slot_Internal internal
Definition: freetype.h:1637
FT_Short height
Definition: freetype.h:941
GLint level
Definition: gl2ext.h:845
struct FT_Driver_ClassRec_ * FT_Driver_Class
void * control_data
Definition: freetype.h:1629
FT_Open_Face(FT_Library library, const FT_Open_Args *args, FT_Long face_index, FT_Face *aface)
Definition: ftobjs.c:1994
FT_Raster_RenderFunc raster_render
Definition: ftimage.h:1294
#define FT_TRACE5(varformat)
Definition: ftdebug.h:162
typedefFT_BEGIN_HEADER struct FT_AutoHinterRec_ * FT_AutoHinter
Definition: autohint.h:80
#define FT_LOAD_NO_AUTOHINT
Definition: freetype.h:2525
static void ft_cmap_done_internal(FT_CMap cmap)
Definition: ftobjs.c:3175
FT_Long face_object_size
Definition: ftdriver.h:186
FT_Int arg2
Definition: ftgloadr.h:62
#define FT_BASE_DEF(x)
Definition: ftconfig.h:489
ft_debug_init(void)
Definition: ftdebug.c:221
#define FT_RENDER_POOL_SIZE
Definition: ftoption.h:358
char pixel_mode
Definition: ftimage.h:317
FT_New_Face(FT_Library library, const char *filepathname, FT_Long face_index, FT_Face *aface)
Definition: ftobjs.c:1199
FT_ULong module_flags
Definition: ftmodapi.h:161
GLuint GLuint end
Definition: glew.h:1239
#define FT_MODULE_IS_HINTER(x)
Definition: ftobjs.h:461
ft_validator_init(FT_Validator valid, const FT_Byte *base, const FT_Byte *limit, FT_ValidationLevel level)
Definition: ftobjs.c:71
FT_Fixed x_scale
Definition: freetype.h:1365
FT_AutoHinter_GlyphLoadFunc load_glyph
Definition: autohint.h:195
FT_Fixed linearVertAdvance
Definition: freetype.h:1615
FT_Glyph_Metrics metrics
Definition: freetype.h:1613
GLint GLint GLint GLint GLint w
Definition: gl2ext.h:1215
FT_Face_InitFunc init_face
Definition: ftdriver.h:190
FT_Stream_Open(FT_Stream stream, const char *filepathname)
Definition: ftsystem.c:224
FT_Get_Module(FT_Library library, const char *module_name)
Definition: ftobjs.c:4256
FT_Outline_Translate(const FT_Outline *outline, FT_Pos xOffset, FT_Pos yOffset)
Definition: ftoutln.c:510
FT_Stream_OpenMemory(FT_Stream stream, const FT_Byte *base, FT_ULong size)
Definition: ftstream.c:35
#define TT_PLATFORM_APPLE_UNICODE
Definition: ttnameid.h:86
#define FT_ERROR_BASE(x)
Definition: fttypes.h:576
#define FT_MAX_MODULES
Definition: ftoption.h:368
FT_Pos y_ppem
Definition: freetype.h:302
FT_Driver driver
Definition: freetype.h:955
FT_Get_Module_Interface(FT_Library library, const char *mod_name)
Definition: ftobjs.c:4284
FT_Done_Face(FT_Face face)
Definition: ftobjs.c:2329
FT_Raster_NewFunc raster_new
Definition: ftimage.h:1291
FT_Matrix transform_matrix
Definition: ftobjs.h:326
#define FT_NEW(ptr)
Definition: ftmemory.h:288
int i
Definition: pngrutil.c:1377
FT_Set_Debug_Hook(FT_Library library, FT_UInt hook_index, FT_DebugHook_Func debug_hook)
Definition: ftobjs.c:4613
GLfloat right
Definition: glew.h:13816
FT_Renderer_Class * clazz
Definition: ftobjs.h:661
#define FT_LOAD_NO_BITMAP
Definition: freetype.h:2515
FT_CharMapRec charmap
Definition: ftobjs.h:133
FT_CMap_Class clazz
Definition: ftobjs.h:134
FT_Fixed module_version
Definition: ftmodapi.h:164
FT_CMap_CharNextFunc char_next
Definition: ftobjs.h:196
void(* FT_DebugHook_Func)(void *arg)
Definition: ftmodapi.h:339
#define FT_FACE_FIND_SERVICE(face, ptr, id)
Definition: ftserv.h:83
static void ft_set_current_renderer(FT_Library library)
Definition: ftobjs.c:3845
#define FT_LOAD_IGNORE_TRANSFORM
Definition: freetype.h:2522
FT_CMap_InitFunc init
Definition: ftobjs.h:193
#define FT_FACE_LIBRARY(x)
Definition: ftobjs.h:528
unsigned short FT_UShort
Definition: fttypes.h:205
FT_CMap_VariantCharListFunc variantchar_list
Definition: ftobjs.h:205
struct FT_CharMapRec_ * FT_CharMap
Definition: freetype.h:482
FT_Stream stream
Definition: freetype.h:957
FT_UInt vertResolution
Definition: freetype.h:2191
#define FT_IS_SCALABLE(face)
Definition: freetype.h:1141
FT_Module_Requester get_interface
Definition: ftmodapi.h:171
void(* FT_List_Destructor)(FT_Memory memory, void *data, void *user)
Definition: ftlist.h:234
FT_Short max_advance_width
Definition: freetype.h:943
FT_Get_Glyph_Name(FT_Face face, FT_UInt glyph_index, FT_Pointer buffer, FT_UInt buffer_max)
Definition: ftobjs.c:3576
#define m(i, j)
FT_UInt num_modules
Definition: ftobjs.h:832
#define FT_UNUSED(arg)
Definition: ftconfig.h:101
FT_Library_Version(FT_Library library, FT_Int *amajor, FT_Int *aminor, FT_Int *apatch)
Definition: ftobjs.c:4470
GLenum mode
Definition: glew.h:2394
#define TRUE
Definition: ftobjs.h:53
FT_Face_GetVariantSelectors(FT_Face face)
Definition: ftobjs.c:3454
FT_Get_Renderer(FT_Library library, FT_Glyph_Format format)
Definition: ftobjs.c:3934
static void ft_glyphslot_clear(FT_GlyphSlot slot)
Definition: ftobjs.c:313
FT_Face_GetCharsOfVariant(FT_Face face, FT_ULong variantSelector)
Definition: ftobjs.c:3515
#define FT_PIX_ROUND(x)
Definition: ftobjs.h:81
FT_Module_Constructor FT_GLYPH_FORMAT_OUTLINE
Definition: ftrend1.c:283
FT_Module modules[FT_MAX_MODULES]
Definition: ftobjs.h:833
FT_CMap_CharVarIsDefaultFunc char_var_default
Definition: ftobjs.h:202
FT_Raccess_Guess(FT_Library library, FT_Stream stream, char *base_name, char **new_names, FT_Long *offsets, FT_Error *errors)
Definition: ftrfork.c:823
FT_BEGIN_HEADER FT_New_Size(FT_Face face, FT_Size *size)
Definition: ftobjs.c:2370
FT_Get_Name_Index(FT_Face face, FT_String *glyph_name)
Definition: ftobjs.c:3550
FT_Memory memory
Definition: freetype.h:956
FT_Long memory_size
Definition: freetype.h:1833
#define ft_strcmp
Definition: ftstdlib.h:85
FT_Raccess_Get_HeaderInfo(FT_Library library, FT_Stream stream, FT_Long rfork_offset, FT_Long *map_offset, FT_Long *rdata_pos)
Definition: ftrfork.c:50
FT_UShort y_ppem
Definition: freetype.h:1363
#define FT_LOAD_TARGET_MODE(x)
Definition: freetype.h:2617
GLsizei size
Definition: gl2ext.h:1467
FT_Attach_File(FT_Face face, const char *filepathname)
Definition: ftobjs.c:2252
FT_Set_Renderer(FT_Library library, FT_Renderer renderer, FT_UInt num_params, FT_Parameter *parameters)
Definition: ftobjs.c:3946