ReactOS 0.4.15-dev-7958-gcd0bb1a
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-2018 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_FONT_FORMATS_H
23
24#include FT_INTERNAL_VALIDATE_H
25#include FT_INTERNAL_OBJECTS_H
26#include FT_INTERNAL_DEBUG_H
27#include FT_INTERNAL_RFORK_H
28#include FT_INTERNAL_STREAM_H
29#include FT_INTERNAL_SFNT_H /* for SFNT_Load_Table_Func */
30#include FT_INTERNAL_POSTSCRIPT_AUX_H /* for PS_Driver */
31
32#include FT_TRUETYPE_TABLES_H
33#include FT_TRUETYPE_TAGS_H
34#include FT_TRUETYPE_IDS_H
35
36#include FT_SERVICE_PROPERTIES_H
37#include FT_SERVICE_SFNT_H
38#include FT_SERVICE_POSTSCRIPT_NAME_H
39#include FT_SERVICE_GLYPH_DICT_H
40#include FT_SERVICE_TT_CMAP_H
41#include FT_SERVICE_KERNING_H
42#include FT_SERVICE_TRUETYPE_ENGINE_H
43
44#include FT_DRIVER_H
45
46#ifdef FT_CONFIG_OPTION_MAC_FONTS
47#include "ftbase.h"
48#endif
49
50
51#ifdef FT_DEBUG_LEVEL_TRACE
52
53#include FT_BITMAP_H
54
55#if defined( _MSC_VER ) /* Visual C++ (and Intel C++) */
56 /* We disable the warning `conversion from XXX to YYY, */
57 /* possible loss of data' in order to compile cleanly with */
58 /* the maximum level of warnings: `md5.c' is non-FreeType */
59 /* code, and it gets used during development builds only. */
60#pragma warning( push )
61#pragma warning( disable : 4244 )
62#endif /* _MSC_VER */
63
64 /* It's easiest to include `md5.c' directly. However, since OpenSSL */
65 /* also provides the same functions, there might be conflicts if */
66 /* both FreeType and OpenSSL are built as static libraries. For */
67 /* this reason, we put the MD5 stuff into the `FT_' namespace. */
68#define MD5_u32plus FT_MD5_u32plus
69#define MD5_CTX FT_MD5_CTX
70#define MD5_Init FT_MD5_Init
71#define MD5_Update FT_MD5_Update
72#define MD5_Final FT_MD5_Final
73
74#undef HAVE_OPENSSL
75
76#include "md5.c"
77
78#if defined( _MSC_VER )
79#pragma warning( pop )
80#endif
81
82#endif /* FT_DEBUG_LEVEL_TRACE */
83
84
85#define GRID_FIT_METRICS
86
87
88 /* forward declaration */
89 static FT_Error
91 const FT_Open_Args* args,
92 FT_Long face_index,
93 FT_Face *aface,
94 FT_Bool test_mac_fonts );
95
96
99 const char* service_id )
100 {
102 FT_ServiceDesc desc = service_descriptors;
103
104
105 if ( desc && service_id )
106 {
107 for ( ; desc->serv_id != NULL; desc++ )
108 {
109 if ( ft_strcmp( desc->serv_id, service_id ) == 0 )
110 {
111 result = (FT_Pointer)desc->serv_data;
112 break;
113 }
114 }
115 }
116
117 return result;
118 }
119
120
121 FT_BASE_DEF( void )
126 {
127 valid->base = base;
128 valid->limit = limit;
129 valid->level = level;
130 valid->error = FT_Err_Ok;
131 }
132
133
136 {
137 /* This function doesn't work! None should call it. */
138 FT_UNUSED( valid );
139
140 return -1;
141 }
142
143
144 FT_BASE_DEF( void )
147 {
148 /* since the cast below also disables the compiler's */
149 /* type check, we introduce a dummy variable, which */
150 /* will be optimized away */
151 volatile ft_jmp_buf* jump_buffer = &valid->jump_buffer;
152
153
154 valid->error = error;
155
156 /* throw away volatileness; use `jump_buffer' or the */
157 /* compiler may warn about an unused local variable */
158 ft_longjmp( *(ft_jmp_buf*) jump_buffer, 1 );
159 }
160
161
162 /*************************************************************************/
163 /*************************************************************************/
164 /*************************************************************************/
165 /**** ****/
166 /**** ****/
167 /**** S T R E A M ****/
168 /**** ****/
169 /**** ****/
170 /*************************************************************************/
171 /*************************************************************************/
172 /*************************************************************************/
173
174
175 /* create a new input stream from an FT_Open_Args structure */
176 /* */
180 FT_Stream *astream )
181 {
185
186
187 *astream = NULL;
188
189 if ( !library )
190 return FT_THROW( Invalid_Library_Handle );
191
192 if ( !args )
193 return FT_THROW( Invalid_Argument );
194
196
197 if ( FT_NEW( stream ) )
198 goto Exit;
199
200 stream->memory = memory;
201
202 if ( args->flags & FT_OPEN_MEMORY )
203 {
204 /* create a memory-based stream */
206 (const FT_Byte*)args->memory_base,
207 (FT_ULong)args->memory_size );
208 }
209
210#ifndef FT_CONFIG_OPTION_DISABLE_STREAM_SUPPORT
211
212 else if ( args->flags & FT_OPEN_PATHNAME )
213 {
214 /* create a normal system stream */
215 error = FT_Stream_Open( stream, args->pathname );
216 stream->pathname.pointer = args->pathname;
217 }
218 else if ( ( args->flags & FT_OPEN_STREAM ) && args->stream )
219 {
220 /* use an existing, user-provided stream */
221
222 /* in this case, we do not need to allocate a new stream object */
223 /* since the caller is responsible for closing it himself */
224 FT_FREE( stream );
225 stream = args->stream;
226 }
227
228#endif
229
230 else
231 error = FT_THROW( Invalid_Argument );
232
233 if ( error )
234 FT_FREE( stream );
235 else
236 stream->memory = memory; /* just to be certain */
237
238 *astream = stream;
239
240 Exit:
241 return error;
242 }
243
244
245 FT_BASE_DEF( void )
247 FT_Int external )
248 {
249 if ( stream )
250 {
251 FT_Memory memory = stream->memory;
252
253
255
256 if ( !external )
257 FT_FREE( stream );
258 }
259 }
260
261
262 /*************************************************************************/
263 /* */
264 /* The macro FT_COMPONENT is used in trace mode. It is an implicit */
265 /* parameter of the FT_TRACE() and FT_ERROR() macros, used to print/log */
266 /* messages during execution. */
267 /* */
268#undef FT_COMPONENT
269#define FT_COMPONENT trace_objs
270
271
272 /*************************************************************************/
273 /*************************************************************************/
274 /*************************************************************************/
275 /**** ****/
276 /**** ****/
277 /**** FACE, SIZE & GLYPH SLOT OBJECTS ****/
278 /**** ****/
279 /**** ****/
280 /*************************************************************************/
281 /*************************************************************************/
282 /*************************************************************************/
283
284
285 static FT_Error
287 {
288 FT_Driver driver = slot->face->driver;
289 FT_Driver_Class clazz = driver->clazz;
290 FT_Memory memory = driver->root.memory;
293
294
295 slot->library = driver->root.library;
296
297 if ( FT_NEW( internal ) )
298 goto Exit;
299
300 slot->internal = internal;
301
304
305 if ( !error && clazz->init_slot )
306 error = clazz->init_slot( slot );
307
308 Exit:
309 return error;
310 }
311
312
313 FT_BASE_DEF( void )
315 {
316 if ( slot->internal && ( slot->internal->flags & FT_GLYPH_OWN_BITMAP ) )
317 {
319
320
321 FT_FREE( slot->bitmap.buffer );
322 slot->internal->flags &= ~FT_GLYPH_OWN_BITMAP;
323 }
324 else
325 {
326 /* assume that the bitmap buffer was stolen or not */
327 /* allocated from the heap */
328 slot->bitmap.buffer = NULL;
329 }
330 }
331
332
333 FT_BASE_DEF( void )
337 {
338 FT_Outline* outline = &slot->outline;
339 FT_Bitmap* bitmap = &slot->bitmap;
340
341 FT_Pixel_Mode pixel_mode;
342
343 FT_BBox cbox;
344 FT_Pos x_shift = 0;
345 FT_Pos y_shift = 0;
346 FT_Pos x_left, y_top;
347 FT_Pos width, height, pitch;
348
349
350 if ( slot->internal && ( slot->internal->flags & FT_GLYPH_OWN_BITMAP ) )
351 return;
352
353 if ( origin )
354 {
355 x_shift = origin->x;
356 y_shift = origin->y;
357 }
358
359 /* compute the control box, and grid-fit it, */
360 /* taking into account the origin shift */
362
363 cbox.xMin += x_shift;
364 cbox.yMin += y_shift;
365 cbox.xMax += x_shift;
366 cbox.yMax += y_shift;
367
368 switch ( mode )
369 {
371 pixel_mode = FT_PIXEL_MODE_MONO;
372#if 1
373 /* undocumented but confirmed: bbox values get rounded */
374 /* unless the rounded box can collapse for a narrow glyph */
375 if ( cbox.xMax - cbox.xMin < 64 )
376 {
377 cbox.xMin = FT_PIX_FLOOR( cbox.xMin );
378 cbox.xMax = FT_PIX_CEIL_LONG( cbox.xMax );
379 }
380 else
381 {
382 cbox.xMin = FT_PIX_ROUND_LONG( cbox.xMin );
383 cbox.xMax = FT_PIX_ROUND_LONG( cbox.xMax );
384 }
385
386 if ( cbox.yMax - cbox.yMin < 64 )
387 {
388 cbox.yMin = FT_PIX_FLOOR( cbox.yMin );
389 cbox.yMax = FT_PIX_CEIL_LONG( cbox.yMax );
390 }
391 else
392 {
393 cbox.yMin = FT_PIX_ROUND_LONG( cbox.yMin );
394 cbox.yMax = FT_PIX_ROUND_LONG( cbox.yMax );
395 }
396#else
397 cbox.xMin = FT_PIX_FLOOR( cbox.xMin );
398 cbox.yMin = FT_PIX_FLOOR( cbox.yMin );
399 cbox.xMax = FT_PIX_CEIL_LONG( cbox.xMax );
400 cbox.yMax = FT_PIX_CEIL_LONG( cbox.yMax );
401#endif
402 break;
403
405 pixel_mode = FT_PIXEL_MODE_LCD;
406 ft_lcd_padding( &cbox.xMin, &cbox.xMax, slot );
407 goto Round;
408
410 pixel_mode = FT_PIXEL_MODE_LCD_V;
411 ft_lcd_padding( &cbox.yMin, &cbox.yMax, slot );
412 goto Round;
413
416 default:
417 pixel_mode = FT_PIXEL_MODE_GRAY;
418 Round:
419 cbox.xMin = FT_PIX_FLOOR( cbox.xMin );
420 cbox.yMin = FT_PIX_FLOOR( cbox.yMin );
421 cbox.xMax = FT_PIX_CEIL_LONG( cbox.xMax );
422 cbox.yMax = FT_PIX_CEIL_LONG( cbox.yMax );
423 }
424
425 x_shift = SUB_LONG( x_shift, cbox.xMin );
426 y_shift = SUB_LONG( y_shift, cbox.yMin );
427
428 x_left = cbox.xMin >> 6;
429 y_top = cbox.yMax >> 6;
430
431 width = ( (FT_ULong)cbox.xMax - (FT_ULong)cbox.xMin ) >> 6;
432 height = ( (FT_ULong)cbox.yMax - (FT_ULong)cbox.yMin ) >> 6;
433
434 switch ( pixel_mode )
435 {
437 pitch = ( ( width + 15 ) >> 4 ) << 1;
438 break;
439
441 width *= 3;
442 pitch = FT_PAD_CEIL( width, 4 );
443 break;
444
446 height *= 3;
447 /* fall through */
448
450 default:
451 pitch = width;
452 }
453
454 slot->bitmap_left = (FT_Int)x_left;
455 slot->bitmap_top = (FT_Int)y_top;
456
457 bitmap->pixel_mode = (unsigned char)pixel_mode;
458 bitmap->num_grays = 256;
459 bitmap->width = (unsigned int)width;
460 bitmap->rows = (unsigned int)height;
461 bitmap->pitch = pitch;
462 }
463
464
465 FT_BASE_DEF( void )
467 FT_Byte* buffer )
468 {
470
471 slot->bitmap.buffer = buffer;
472
473 FT_ASSERT( (slot->internal->flags & FT_GLYPH_OWN_BITMAP) == 0 );
474 }
475
476
479 FT_ULong size )
480 {
483
484
485 if ( slot->internal->flags & FT_GLYPH_OWN_BITMAP )
486 FT_FREE( slot->bitmap.buffer );
487 else
488 slot->internal->flags |= FT_GLYPH_OWN_BITMAP;
489
490 (void)FT_ALLOC( slot->bitmap.buffer, size );
491 return error;
492 }
493
494
495 static void
497 {
498 /* free bitmap if needed */
500
501 /* clear all public fields in the glyph slot */
502 FT_ZERO( &slot->metrics );
503 FT_ZERO( &slot->outline );
504
505 slot->bitmap.width = 0;
506 slot->bitmap.rows = 0;
507 slot->bitmap.pitch = 0;
508 slot->bitmap.pixel_mode = 0;
509 /* `slot->bitmap.buffer' has been handled by ft_glyphslot_free_bitmap */
510
511 slot->bitmap_left = 0;
512 slot->bitmap_top = 0;
513 slot->num_subglyphs = 0;
514 slot->subglyphs = NULL;
515 slot->control_data = NULL;
516 slot->control_len = 0;
517 slot->other = NULL;
518 slot->format = FT_GLYPH_FORMAT_NONE;
519
520 slot->linearHoriAdvance = 0;
521 slot->linearVertAdvance = 0;
522 slot->lsb_delta = 0;
523 slot->rsb_delta = 0;
524 }
525
526
527 static void
529 {
530 FT_Driver driver = slot->face->driver;
531 FT_Driver_Class clazz = driver->clazz;
532 FT_Memory memory = driver->root.memory;
533
534
535 if ( clazz->done_slot )
536 clazz->done_slot( slot );
537
538 /* free bitmap buffer if needed */
540
541 /* slot->internal might be NULL in out-of-memory situations */
542 if ( slot->internal )
543 {
544 /* free glyph loader */
546 {
547 FT_GlyphLoader_Done( slot->internal->loader );
548 slot->internal->loader = NULL;
549 }
550
551 FT_FREE( slot->internal );
552 }
553 }
554
555
556 /* documentation is in ftobjs.h */
557
560 FT_GlyphSlot *aslot )
561 {
564 FT_Driver_Class clazz;
567
568
569 if ( !face )
570 return FT_THROW( Invalid_Face_Handle );
571
572 if ( !face->driver )
573 return FT_THROW( Invalid_Argument );
574
575 driver = face->driver;
576 clazz = driver->clazz;
577 memory = driver->root.memory;
578
579 FT_TRACE4(( "FT_New_GlyphSlot: Creating new slot object\n" ));
580 if ( !FT_ALLOC( slot, clazz->slot_object_size ) )
581 {
582 slot->face = face;
583
585 if ( error )
586 {
588 FT_FREE( slot );
589 goto Exit;
590 }
591
592 slot->next = face->glyph;
593 face->glyph = slot;
594
595 if ( aslot )
596 *aslot = slot;
597 }
598 else if ( aslot )
599 *aslot = NULL;
600
601
602 Exit:
603 FT_TRACE4(( "FT_New_GlyphSlot: Return 0x%x\n", error ));
604
605 return error;
606 }
607
608
609 /* documentation is in ftobjs.h */
610
611 FT_BASE_DEF( void )
613 {
614 if ( slot )
615 {
616 FT_Driver driver = slot->face->driver;
617 FT_Memory memory = driver->root.memory;
618 FT_GlyphSlot prev;
620
621
622 /* Remove slot from its parent face's list */
623 prev = NULL;
624 cur = slot->face->glyph;
625
626 while ( cur )
627 {
628 if ( cur == slot )
629 {
630 if ( !prev )
631 slot->face->glyph = cur->next;
632 else
633 prev->next = cur->next;
634
635 /* finalize client-specific data */
636 if ( slot->generic.finalizer )
637 slot->generic.finalizer( slot );
638
640 FT_FREE( slot );
641 break;
642 }
643 prev = cur;
644 cur = cur->next;
645 }
646 }
647 }
648
649
650 /* documentation is in freetype.h */
651
652 FT_EXPORT_DEF( void )
655 FT_Vector* delta )
656 {
658
659
660 if ( !face )
661 return;
662
663 internal = face->internal;
664
665 internal->transform_flags = 0;
666
667 if ( !matrix )
668 {
669 internal->transform_matrix.xx = 0x10000L;
670 internal->transform_matrix.xy = 0;
671 internal->transform_matrix.yx = 0;
672 internal->transform_matrix.yy = 0x10000L;
673
674 matrix = &internal->transform_matrix;
675 }
676 else
677 internal->transform_matrix = *matrix;
678
679 /* set transform_flags bit flag 0 if `matrix' isn't the identity */
680 if ( ( matrix->xy | matrix->yx ) ||
681 matrix->xx != 0x10000L ||
682 matrix->yy != 0x10000L )
683 internal->transform_flags |= 1;
684
685 if ( !delta )
686 {
687 internal->transform_delta.x = 0;
688 internal->transform_delta.y = 0;
689
690 delta = &internal->transform_delta;
691 }
692 else
693 internal->transform_delta = *delta;
694
695 /* set transform_flags bit flag 1 if `delta' isn't the null vector */
696 if ( delta->x | delta->y )
697 internal->transform_flags |= 2;
698 }
699
700
701 static FT_Renderer
703
704
705#ifdef GRID_FIT_METRICS
706 static void
708 FT_Bool vertical )
709 {
710 FT_Glyph_Metrics* metrics = &slot->metrics;
712
713
714 if ( vertical )
715 {
716 metrics->horiBearingX = FT_PIX_FLOOR( metrics->horiBearingX );
717 metrics->horiBearingY = FT_PIX_CEIL_LONG( metrics->horiBearingY );
718
719 right = FT_PIX_CEIL_LONG( ADD_LONG( metrics->vertBearingX,
720 metrics->width ) );
721 bottom = FT_PIX_CEIL_LONG( ADD_LONG( metrics->vertBearingY,
722 metrics->height ) );
723
724 metrics->vertBearingX = FT_PIX_FLOOR( metrics->vertBearingX );
725 metrics->vertBearingY = FT_PIX_FLOOR( metrics->vertBearingY );
726
727 metrics->width = SUB_LONG( right,
728 metrics->vertBearingX );
729 metrics->height = SUB_LONG( bottom,
730 metrics->vertBearingY );
731 }
732 else
733 {
734 metrics->vertBearingX = FT_PIX_FLOOR( metrics->vertBearingX );
735 metrics->vertBearingY = FT_PIX_FLOOR( metrics->vertBearingY );
736
737 right = FT_PIX_CEIL_LONG( ADD_LONG( metrics->horiBearingX,
738 metrics->width ) );
739 bottom = FT_PIX_FLOOR( SUB_LONG( metrics->horiBearingY,
740 metrics->height ) );
741
742 metrics->horiBearingX = FT_PIX_FLOOR( metrics->horiBearingX );
743 metrics->horiBearingY = FT_PIX_CEIL_LONG( metrics->horiBearingY );
744
745 metrics->width = SUB_LONG( right,
746 metrics->horiBearingX );
747 metrics->height = SUB_LONG( metrics->horiBearingY,
748 bottom );
749 }
750
751 metrics->horiAdvance = FT_PIX_ROUND_LONG( metrics->horiAdvance );
752 metrics->vertAdvance = FT_PIX_ROUND_LONG( metrics->vertAdvance );
753 }
754#endif /* GRID_FIT_METRICS */
755
756
757 /* documentation is in freetype.h */
758
761 FT_UInt glyph_index,
762 FT_Int32 load_flags )
763 {
768 FT_Bool autohint = FALSE;
769 FT_Module hinter;
770 TT_Face ttface = (TT_Face)face;
771
772
773 if ( !face || !face->size || !face->glyph )
774 return FT_THROW( Invalid_Face_Handle );
775
776 /* The validity test for `glyph_index' is performed by the */
777 /* font drivers. */
778
779 slot = face->glyph;
781
782 driver = face->driver;
783 library = driver->root.library;
784 hinter = library->auto_hinter;
785
786 /* resolve load flags dependencies */
787
788 if ( load_flags & FT_LOAD_NO_RECURSE )
789 load_flags |= FT_LOAD_NO_SCALE |
791
792 if ( load_flags & FT_LOAD_NO_SCALE )
793 {
794 load_flags |= FT_LOAD_NO_HINTING |
796
797 load_flags &= ~FT_LOAD_RENDER;
798 }
799
800 if ( load_flags & FT_LOAD_BITMAP_METRICS_ONLY )
801 load_flags &= ~FT_LOAD_RENDER;
802
803 /*
804 * Determine whether we need to auto-hint or not.
805 * The general rules are:
806 *
807 * - Do only auto-hinting if we have
808 *
809 * - a hinter module,
810 * - a scalable font format dealing with outlines,
811 * - not a tricky font, and
812 * - no transforms except simple slants and/or rotations by
813 * integer multiples of 90 degrees.
814 *
815 * - Then, auto-hint if FT_LOAD_FORCE_AUTOHINT is set or if we don't
816 * have a native font hinter.
817 *
818 * - Otherwise, auto-hint for LIGHT hinting mode or if there isn't
819 * any hinting bytecode in the TrueType/OpenType font.
820 *
821 * - Exception: The font is `tricky' and requires the native hinter to
822 * load properly.
823 */
824
825 if ( hinter &&
826 !( load_flags & FT_LOAD_NO_HINTING ) &&
827 !( load_flags & FT_LOAD_NO_AUTOHINT ) &&
830 !FT_IS_TRICKY( face ) &&
831 ( ( load_flags & FT_LOAD_IGNORE_TRANSFORM ) ||
832 ( face->internal->transform_matrix.yx == 0 &&
833 face->internal->transform_matrix.xx != 0 ) ||
834 ( face->internal->transform_matrix.xx == 0 &&
835 face->internal->transform_matrix.yx != 0 ) ) )
836 {
837 if ( ( load_flags & FT_LOAD_FORCE_AUTOHINT ) ||
839 autohint = TRUE;
840 else
841 {
843 FT_Bool is_light_type1;
844
845
846 /* only the new Adobe engine (for both CFF and Type 1) is `light'; */
847 /* we use `strstr' to catch both `Type 1' and `CID Type 1' */
848 is_light_type1 =
849 ft_strstr( FT_Get_Font_Format( face ), "Type 1" ) != NULL &&
850 ((PS_Driver)driver)->hinting_engine == FT_HINTING_ADOBE;
851
852 /* the check for `num_locations' assures that we actually */
853 /* test for instructions in a TTF and not in a CFF-based OTF */
854 /* */
855 /* since `maxSizeOfInstructions' might be unreliable, we */
856 /* check the size of the `fpgm' and `prep' tables, too -- */
857 /* the assumption is that there don't exist real TTFs where */
858 /* both `fpgm' and `prep' tables are missing */
859 if ( ( mode == FT_RENDER_MODE_LIGHT &&
861 !is_light_type1 ) ) ||
862 ( FT_IS_SFNT( face ) &&
863 ttface->num_locations &&
864 ttface->max_profile.maxSizeOfInstructions == 0 &&
865 ttface->font_program_size == 0 &&
866 ttface->cvt_program_size == 0 ) )
867 autohint = TRUE;
868 }
869 }
870
871 if ( autohint )
872 {
874
875
876 /* try to load embedded bitmaps first if available */
877 /* */
878 /* XXX: This is really a temporary hack that should disappear */
879 /* promptly with FreeType 2.1! */
880 /* */
881 if ( FT_HAS_FIXED_SIZES( face ) &&
882 ( load_flags & FT_LOAD_NO_BITMAP ) == 0 )
883 {
884 error = driver->clazz->load_glyph( slot, face->size,
885 glyph_index,
886 load_flags | FT_LOAD_SBITS_ONLY );
887
888 if ( !error && slot->format == FT_GLYPH_FORMAT_BITMAP )
889 goto Load_Ok;
890 }
891
892 {
893 FT_Face_Internal internal = face->internal;
894 FT_Int transform_flags = internal->transform_flags;
895
896
897 /* since the auto-hinter calls FT_Load_Glyph by itself, */
898 /* make sure that glyphs aren't transformed */
899 internal->transform_flags = 0;
900
901 /* load auto-hinted outline */
903
904 error = hinting->load_glyph( (FT_AutoHinter)hinter,
905 slot, face->size,
906 glyph_index, load_flags );
907
908 internal->transform_flags = transform_flags;
909 }
910 }
911 else
912 {
913 error = driver->clazz->load_glyph( slot,
914 face->size,
915 glyph_index,
916 load_flags );
917 if ( error )
918 goto Exit;
919
920 if ( slot->format == FT_GLYPH_FORMAT_OUTLINE )
921 {
922 /* check that the loaded outline is correct */
923 error = FT_Outline_Check( &slot->outline );
924 if ( error )
925 goto Exit;
926
927#ifdef GRID_FIT_METRICS
928 if ( !( load_flags & FT_LOAD_NO_HINTING ) )
930 FT_BOOL( load_flags & FT_LOAD_VERTICAL_LAYOUT ) );
931#endif
932 }
933 }
934
935 Load_Ok:
936 /* compute the advance */
937 if ( load_flags & FT_LOAD_VERTICAL_LAYOUT )
938 {
939 slot->advance.x = 0;
940 slot->advance.y = slot->metrics.vertAdvance;
941 }
942 else
943 {
944 slot->advance.x = slot->metrics.horiAdvance;
945 slot->advance.y = 0;
946 }
947
948 /* compute the linear advance in 16.16 pixels */
949 if ( ( load_flags & FT_LOAD_LINEAR_DESIGN ) == 0 &&
951 {
952 FT_Size_Metrics* metrics = &face->size->metrics;
953
954
955 /* it's tricky! */
956 slot->linearHoriAdvance = FT_MulDiv( slot->linearHoriAdvance,
957 metrics->x_scale, 64 );
958
959 slot->linearVertAdvance = FT_MulDiv( slot->linearVertAdvance,
960 metrics->y_scale, 64 );
961 }
962
963 if ( ( load_flags & FT_LOAD_IGNORE_TRANSFORM ) == 0 )
964 {
965 FT_Face_Internal internal = face->internal;
966
967
968 /* now, transform the glyph image if needed */
969 if ( internal->transform_flags )
970 {
971 /* get renderer */
973
974
975 if ( renderer )
976 error = renderer->clazz->transform_glyph(
977 renderer, slot,
978 &internal->transform_matrix,
979 &internal->transform_delta );
980 else if ( slot->format == FT_GLYPH_FORMAT_OUTLINE )
981 {
982 /* apply `standard' transformation if no renderer is available */
983 if ( internal->transform_flags & 1 )
984 FT_Outline_Transform( &slot->outline,
985 &internal->transform_matrix );
986
987 if ( internal->transform_flags & 2 )
988 FT_Outline_Translate( &slot->outline,
989 internal->transform_delta.x,
990 internal->transform_delta.y );
991 }
992
993 /* transform advance */
994 FT_Vector_Transform( &slot->advance, &internal->transform_matrix );
995 }
996 }
997
998 /* do we need to render the image or preset the bitmap now? */
999 if ( !error &&
1000 ( load_flags & FT_LOAD_NO_SCALE ) == 0 &&
1001 slot->format != FT_GLYPH_FORMAT_BITMAP &&
1002 slot->format != FT_GLYPH_FORMAT_COMPOSITE )
1003 {
1004 FT_Render_Mode mode = FT_LOAD_TARGET_MODE( load_flags );
1005
1006
1007 if ( mode == FT_RENDER_MODE_NORMAL &&
1008 load_flags & FT_LOAD_MONOCHROME )
1010
1011 if ( load_flags & FT_LOAD_RENDER )
1013 else
1015 }
1016
1017 FT_TRACE5(( "FT_Load_Glyph: index %d, flags %x\n",
1018 glyph_index, load_flags ));
1019 FT_TRACE5(( " x advance: %f\n", slot->advance.x / 64.0 ));
1020 FT_TRACE5(( " y advance: %f\n", slot->advance.y / 64.0 ));
1021 FT_TRACE5(( " linear x advance: %f\n",
1022 slot->linearHoriAdvance / 65536.0 ));
1023 FT_TRACE5(( " linear y advance: %f\n",
1024 slot->linearVertAdvance / 65536.0 ));
1025 FT_TRACE5(( " bitmap %dx%d, mode %d\n",
1026 slot->bitmap.width, slot->bitmap.rows,
1027 slot->bitmap.pixel_mode ));
1028
1029 Exit:
1030 return error;
1031 }
1032
1033
1034 /* documentation is in freetype.h */
1035
1038 FT_ULong char_code,
1039 FT_Int32 load_flags )
1040 {
1041 FT_UInt glyph_index;
1042
1043
1044 if ( !face )
1045 return FT_THROW( Invalid_Face_Handle );
1046
1047 glyph_index = (FT_UInt)char_code;
1048 if ( face->charmap )
1049 glyph_index = FT_Get_Char_Index( face, char_code );
1050
1051 return FT_Load_Glyph( face, glyph_index, load_flags );
1052 }
1053
1054
1055 /* destructor for sizes list */
1056 static void
1058 FT_Size size,
1060 {
1061 /* finalize client-specific data */
1062 if ( size->generic.finalizer )
1063 size->generic.finalizer( size );
1064
1065 /* finalize format-specific stuff */
1066 if ( driver->clazz->done_size )
1067 driver->clazz->done_size( size );
1068
1069 FT_FREE( size->internal );
1070 FT_FREE( size );
1071 }
1072
1073
1074 static void
1076
1077
1078 static void
1081 {
1082 FT_Int n;
1083
1084
1085 if ( !face )
1086 return;
1087
1088 for ( n = 0; n < face->num_charmaps; n++ )
1089 {
1090 FT_CMap cmap = FT_CMAP( face->charmaps[n] );
1091
1092
1093 ft_cmap_done_internal( cmap );
1094
1095 face->charmaps[n] = NULL;
1096 }
1097
1098 FT_FREE( face->charmaps );
1099 face->num_charmaps = 0;
1100 }
1101
1102
1103 /* destructor for faces list */
1104 static void
1106 FT_Face face,
1108 {
1109 FT_Driver_Class clazz = driver->clazz;
1110
1111
1112 /* discard auto-hinting data */
1113 if ( face->autohint.finalizer )
1114 face->autohint.finalizer( face->autohint.data );
1115
1116 /* Discard glyph slots for this face. */
1117 /* Beware! FT_Done_GlyphSlot() changes the field `face->glyph' */
1118 while ( face->glyph )
1119 FT_Done_GlyphSlot( face->glyph );
1120
1121 /* discard all sizes for this face */
1122 FT_List_Finalize( &face->sizes_list,
1124 memory,
1125 driver );
1126 face->size = NULL;
1127
1128 /* now discard client data */
1129 if ( face->generic.finalizer )
1130 face->generic.finalizer( face );
1131
1132 /* discard charmaps */
1134
1135 /* finalize format-specific stuff */
1136 if ( clazz->done_face )
1137 clazz->done_face( face );
1138
1139 /* close the stream for this face if needed */
1141 face->stream,
1142 ( face->face_flags & FT_FACE_FLAG_EXTERNAL_STREAM ) != 0 );
1143
1144 face->stream = NULL;
1145
1146 /* get rid of it */
1147 if ( face->internal )
1148 {
1149 FT_FREE( face->internal );
1150 }
1151 FT_FREE( face );
1152 }
1153
1154
1155 static void
1157 {
1158 FT_List_Finalize( &driver->faces_list,
1160 driver->root.memory,
1161 driver );
1162 }
1163
1164
1165 /*************************************************************************/
1166 /* */
1167 /* <Function> */
1168 /* find_unicode_charmap */
1169 /* */
1170 /* <Description> */
1171 /* This function finds a Unicode charmap, if there is one. */
1172 /* And if there is more than one, it tries to favour the more */
1173 /* extensive one, i.e., one that supports UCS-4 against those which */
1174 /* are limited to the BMP (said UCS-2 encoding.) */
1175 /* */
1176 /* This function is called from open_face() (just below), and also */
1177 /* from FT_Select_Charmap( ..., FT_ENCODING_UNICODE ). */
1178 /* */
1179 static FT_Error
1181 {
1183 FT_CharMap* cur;
1184
1185
1186 /* caller should have already checked that `face' is valid */
1187 FT_ASSERT( face );
1188
1189 first = face->charmaps;
1190
1191 if ( !first )
1192 return FT_THROW( Invalid_CharMap_Handle );
1193
1194 /*
1195 * The original TrueType specification(s) only specified charmap
1196 * formats that are capable of mapping 8 or 16 bit character codes to
1197 * glyph indices.
1198 *
1199 * However, recent updates to the Apple and OpenType specifications
1200 * introduced new formats that are capable of mapping 32-bit character
1201 * codes as well. And these are already used on some fonts, mainly to
1202 * map non-BMP Asian ideographs as defined in Unicode.
1203 *
1204 * For compatibility purposes, these fonts generally come with
1205 * *several* Unicode charmaps:
1206 *
1207 * - One of them in the "old" 16-bit format, that cannot access
1208 * all glyphs in the font.
1209 *
1210 * - Another one in the "new" 32-bit format, that can access all
1211 * the glyphs.
1212 *
1213 * This function has been written to always favor a 32-bit charmap
1214 * when found. Otherwise, a 16-bit one is returned when found.
1215 */
1216
1217 /* Since the `interesting' table, with IDs (3,10), is normally the */
1218 /* last one, we loop backwards. This loses with type1 fonts with */
1219 /* non-BMP characters (<.0001%), this wins with .ttf with non-BMP */
1220 /* chars (.01% ?), and this is the same about 99.99% of the time! */
1221
1222 cur = first + face->num_charmaps; /* points after the last one */
1223
1224 for ( ; --cur >= first; )
1225 {
1226 if ( cur[0]->encoding == FT_ENCODING_UNICODE )
1227 {
1228 /* XXX If some new encodings to represent UCS-4 are added, */
1229 /* they should be added here. */
1230 if ( ( cur[0]->platform_id == TT_PLATFORM_MICROSOFT &&
1231 cur[0]->encoding_id == TT_MS_ID_UCS_4 ) ||
1232 ( cur[0]->platform_id == TT_PLATFORM_APPLE_UNICODE &&
1233 cur[0]->encoding_id == TT_APPLE_ID_UNICODE_32 ) )
1234 {
1235 face->charmap = cur[0];
1236 return FT_Err_Ok;
1237 }
1238 }
1239 }
1240
1241 /* We do not have any UCS-4 charmap. */
1242 /* Do the loop again and search for UCS-2 charmaps. */
1243 cur = first + face->num_charmaps;
1244
1245 for ( ; --cur >= first; )
1246 {
1247 if ( cur[0]->encoding == FT_ENCODING_UNICODE )
1248 {
1249 face->charmap = cur[0];
1250 return FT_Err_Ok;
1251 }
1252 }
1253
1254 return FT_THROW( Invalid_CharMap_Handle );
1255 }
1256
1257
1258 /*************************************************************************/
1259 /* */
1260 /* <Function> */
1261 /* find_variant_selector_charmap */
1262 /* */
1263 /* <Description> */
1264 /* This function finds the variant selector charmap, if there is one. */
1265 /* There can only be one (platform=0, specific=5, format=14). */
1266 /* */
1267 static FT_CharMap
1269 {
1271 FT_CharMap* end;
1272 FT_CharMap* cur;
1273
1274
1275 /* caller should have already checked that `face' is valid */
1276 FT_ASSERT( face );
1277
1278 first = face->charmaps;
1279
1280 if ( !first )
1281 return NULL;
1282
1283 end = first + face->num_charmaps; /* points after the last one */
1284
1285 for ( cur = first; cur < end; cur++ )
1286 {
1287 if ( cur[0]->platform_id == TT_PLATFORM_APPLE_UNICODE &&
1288 cur[0]->encoding_id == TT_APPLE_ID_VARIANT_SELECTOR &&
1289 FT_Get_CMap_Format( cur[0] ) == 14 )
1290 return cur[0];
1291 }
1292
1293 return NULL;
1294 }
1295
1296
1297 /*************************************************************************/
1298 /* */
1299 /* <Function> */
1300 /* open_face */
1301 /* */
1302 /* <Description> */
1303 /* This function does some work for FT_Open_Face(). */
1304 /* */
1305 static FT_Error
1307 FT_Stream *astream,
1308 FT_Bool external_stream,
1309 FT_Long face_index,
1310 FT_Int num_params,
1312 FT_Face *aface )
1313 {
1315 FT_Driver_Class clazz;
1316 FT_Face face = NULL;
1318
1320
1321
1322 clazz = driver->clazz;
1323 memory = driver->root.memory;
1324
1325 /* allocate the face object and perform basic initialization */
1326 if ( FT_ALLOC( face, clazz->face_object_size ) )
1327 goto Fail;
1328
1329 face->driver = driver;
1330 face->memory = memory;
1331 face->stream = *astream;
1332
1333 /* set the FT_FACE_FLAG_EXTERNAL_STREAM bit for FT_Done_Face */
1334 if ( external_stream )
1335 face->face_flags |= FT_FACE_FLAG_EXTERNAL_STREAM;
1336
1337 if ( FT_NEW( internal ) )
1338 goto Fail;
1339
1340 face->internal = internal;
1341
1342#ifdef FT_CONFIG_OPTION_INCREMENTAL
1343 {
1344 int i;
1345
1346
1347 face->internal->incremental_interface = NULL;
1348 for ( i = 0; i < num_params && !face->internal->incremental_interface;
1349 i++ )
1351 face->internal->incremental_interface =
1353 }
1354#endif
1355
1356 face->internal->random_seed = -1;
1357
1358 if ( clazz->init_face )
1359 error = clazz->init_face( *astream,
1360 face,
1361 (FT_Int)face_index,
1362 num_params,
1363 params );
1364 *astream = face->stream; /* Stream may have been changed. */
1365 if ( error )
1366 goto Fail;
1367
1368 /* select Unicode charmap by default */
1370
1371 /* if no Unicode charmap can be found, FT_Err_Invalid_CharMap_Handle */
1372 /* is returned. */
1373
1374 /* no error should happen, but we want to play safe */
1375 if ( error2 && FT_ERR_NEQ( error2, Invalid_CharMap_Handle ) )
1376 {
1377 error = error2;
1378 goto Fail;
1379 }
1380
1381 *aface = face;
1382
1383 Fail:
1384 if ( error )
1385 {
1387 if ( clazz->done_face )
1388 clazz->done_face( face );
1389 FT_FREE( internal );
1390 FT_FREE( face );
1391 *aface = NULL;
1392 }
1393
1394 return error;
1395 }
1396
1397
1398 /* there's a Mac-specific extended implementation of FT_New_Face() */
1399 /* in src/base/ftmac.c */
1400
1401#ifndef FT_MACINTOSH
1402
1403 /* documentation is in freetype.h */
1404
1407 const char* pathname,
1408 FT_Long face_index,
1409 FT_Face *aface )
1410 {
1412
1413
1414 /* test for valid `library' and `aface' delayed to `FT_Open_Face' */
1415 if ( !pathname )
1416 return FT_THROW( Invalid_Argument );
1417
1418 args.flags = FT_OPEN_PATHNAME;
1419 args.pathname = (char*)pathname;
1420 args.stream = NULL;
1421
1422 return ft_open_face_internal( library, &args, face_index, aface, 1 );
1423 }
1424
1425#endif
1426
1427
1428 /* documentation is in freetype.h */
1429
1432 const FT_Byte* file_base,
1434 FT_Long face_index,
1435 FT_Face *aface )
1436 {
1438
1439
1440 /* test for valid `library' and `face' delayed to `FT_Open_Face' */
1441 if ( !file_base )
1442 return FT_THROW( Invalid_Argument );
1443
1444 args.flags = FT_OPEN_MEMORY;
1445 args.memory_base = file_base;
1446 args.memory_size = file_size;
1447 args.stream = NULL;
1448
1449 return ft_open_face_internal( library, &args, face_index, aface, 1 );
1450 }
1451
1452
1453#ifdef FT_CONFIG_OPTION_MAC_FONTS
1454
1455 /* The behavior here is very similar to that in base/ftmac.c, but it */
1456 /* is designed to work on non-mac systems, so no mac specific calls. */
1457 /* */
1458 /* We look at the file and determine if it is a mac dfont file or a mac */
1459 /* resource file, or a macbinary file containing a mac resource file. */
1460 /* */
1461 /* Unlike ftmac I'm not going to look at a `FOND'. I don't really see */
1462 /* the point, especially since there may be multiple `FOND' resources. */
1463 /* Instead I'll just look for `sfnt' and `POST' resources, ordered as */
1464 /* they occur in the file. */
1465 /* */
1466 /* Note that multiple `POST' resources do not mean multiple postscript */
1467 /* fonts; they all get jammed together to make what is essentially a */
1468 /* pfb file. */
1469 /* */
1470 /* We aren't interested in `NFNT' or `FONT' bitmap resources. */
1471 /* */
1472 /* As soon as we get an `sfnt' load it into memory and pass it off to */
1473 /* FT_Open_Face. */
1474 /* */
1475 /* If we have a (set of) `POST' resources, massage them into a (memory) */
1476 /* pfb file and pass that to FT_Open_Face. (As with ftmac.c I'm not */
1477 /* going to try to save the kerning info. After all that lives in the */
1478 /* `FOND' which isn't in the file containing the `POST' resources so */
1479 /* we don't really have access to it. */
1480
1481
1482 /* Finalizer for a memory stream; gets called by FT_Done_Face(). */
1483 /* It frees the memory it uses. */
1484 /* From `ftmac.c'. */
1485 static void
1486 memory_stream_close( FT_Stream stream )
1487 {
1488 FT_Memory memory = stream->memory;
1489
1490
1491 FT_FREE( stream->base );
1492
1493 stream->size = 0;
1494 stream->base = NULL;
1495 stream->close = NULL;
1496 }
1497
1498
1499 /* Create a new memory stream from a buffer and a size. */
1500 /* From `ftmac.c'. */
1501 static FT_Error
1502 new_memory_stream( FT_Library library,
1503 FT_Byte* base,
1504 FT_ULong size,
1506 FT_Stream *astream )
1507 {
1511
1512
1513 if ( !library )
1514 return FT_THROW( Invalid_Library_Handle );
1515
1516 if ( !base )
1517 return FT_THROW( Invalid_Argument );
1518
1519 *astream = NULL;
1521 if ( FT_NEW( stream ) )
1522 goto Exit;
1523
1525
1526 stream->close = close;
1527
1528 *astream = stream;
1529
1530 Exit:
1531 return error;
1532 }
1533
1534
1535 /* Create a new FT_Face given a buffer and a driver name. */
1536 /* From `ftmac.c'. */
1538 open_face_from_buffer( FT_Library library,
1539 FT_Byte* base,
1540 FT_ULong size,
1541 FT_Long face_index,
1542 const char* driver_name,
1543 FT_Face *aface )
1544 {
1549
1550
1551 error = new_memory_stream( library,
1552 base,
1553 size,
1554 memory_stream_close,
1555 &stream );
1556 if ( error )
1557 {
1558 FT_FREE( base );
1559 return error;
1560 }
1561
1562 args.flags = FT_OPEN_STREAM;
1563 args.stream = stream;
1564 if ( driver_name )
1565 {
1566 args.flags = args.flags | FT_OPEN_DRIVER;
1567 args.driver = FT_Get_Module( library, driver_name );
1568 }
1569
1570#ifdef FT_MACINTOSH
1571 /* At this point, the face index has served its purpose; */
1572 /* whoever calls this function has already used it to */
1573 /* locate the correct font data. We should not propagate */
1574 /* this index to FT_Open_Face() (unless it is negative). */
1575
1576 if ( face_index > 0 )
1577 face_index &= 0x7FFF0000L; /* retain GX data */
1578#endif
1579
1580 error = ft_open_face_internal( library, &args, face_index, aface, 0 );
1581
1582 if ( !error )
1583 (*aface)->face_flags &= ~FT_FACE_FLAG_EXTERNAL_STREAM;
1584 else
1585#ifdef FT_MACINTOSH
1586 FT_Stream_Free( stream, 0 );
1587#else
1588 {
1590 FT_FREE( stream );
1591 }
1592#endif
1593
1594 return error;
1595 }
1596
1597
1598 /* Look up `TYP1' or `CID ' table from sfnt table directory. */
1599 /* `offset' and `length' must exclude the binary header in tables. */
1600
1601 /* Type 1 and CID-keyed font drivers should recognize sfnt-wrapped */
1602 /* format too. Here, since we can't expect that the TrueType font */
1603 /* driver is loaded unconditionally, we must parse the font by */
1604 /* ourselves. We are only interested in the name of the table and */
1605 /* the offset. */
1606
1607 static FT_Error
1608 ft_lookup_PS_in_sfnt_stream( FT_Stream stream,
1609 FT_Long face_index,
1612 FT_Bool* is_sfnt_cid )
1613 {
1615 FT_UShort numTables;
1616 FT_Long pstable_index;
1617 FT_ULong tag;
1618 int i;
1619
1620
1621 *offset = 0;
1622 *length = 0;
1623 *is_sfnt_cid = FALSE;
1624
1625 /* TODO: support for sfnt-wrapped PS/CID in TTC format */
1626
1627 /* version check for 'typ1' (should be ignored?) */
1628 if ( FT_READ_ULONG( tag ) )
1629 return error;
1630 if ( tag != TTAG_typ1 )
1631 return FT_THROW( Unknown_File_Format );
1632
1633 if ( FT_READ_USHORT( numTables ) )
1634 return error;
1635 if ( FT_STREAM_SKIP( 2 * 3 ) ) /* skip binary search header */
1636 return error;
1637
1638 pstable_index = -1;
1639 *is_sfnt_cid = FALSE;
1640
1641 for ( i = 0; i < numTables; i++ )
1642 {
1643 if ( FT_READ_ULONG( tag ) || FT_STREAM_SKIP( 4 ) ||
1645 return error;
1646
1647 if ( tag == TTAG_CID )
1648 {
1649 pstable_index++;
1650 *offset += 22;
1651 *length -= 22;
1652 *is_sfnt_cid = TRUE;
1653 if ( face_index < 0 )
1654 return FT_Err_Ok;
1655 }
1656 else if ( tag == TTAG_TYP1 )
1657 {
1658 pstable_index++;
1659 *offset += 24;
1660 *length -= 24;
1661 *is_sfnt_cid = FALSE;
1662 if ( face_index < 0 )
1663 return FT_Err_Ok;
1664 }
1665 if ( face_index >= 0 && pstable_index == face_index )
1666 return FT_Err_Ok;
1667 }
1668
1669 return FT_THROW( Table_Missing );
1670 }
1671
1672
1674 open_face_PS_from_sfnt_stream( FT_Library library,
1676 FT_Long face_index,
1677 FT_Int num_params,
1679 FT_Face *aface )
1680 {
1684 FT_ULong pos;
1685 FT_Bool is_sfnt_cid;
1686 FT_Byte* sfnt_ps = NULL;
1687
1688 FT_UNUSED( num_params );
1689 FT_UNUSED( params );
1690
1691
1692 /* ignore GX stuff */
1693 if ( face_index > 0 )
1694 face_index &= 0xFFFFL;
1695
1696 pos = FT_STREAM_POS();
1697
1698 error = ft_lookup_PS_in_sfnt_stream( stream,
1699 face_index,
1700 &offset,
1701 &length,
1702 &is_sfnt_cid );
1703 if ( error )
1704 goto Exit;
1705
1706 if ( offset > stream->size )
1707 {
1708 FT_TRACE2(( "open_face_PS_from_sfnt_stream: invalid table offset\n" ));
1709 error = FT_THROW( Invalid_Table );
1710 goto Exit;
1711 }
1712 else if ( length > stream->size - offset )
1713 {
1714 FT_TRACE2(( "open_face_PS_from_sfnt_stream: invalid table length\n" ));
1715 error = FT_THROW( Invalid_Table );
1716 goto Exit;
1717 }
1718
1720 if ( error )
1721 goto Exit;
1722
1723 if ( FT_ALLOC( sfnt_ps, (FT_Long)length ) )
1724 goto Exit;
1725
1726 error = FT_Stream_Read( stream, (FT_Byte *)sfnt_ps, length );
1727 if ( error )
1728 {
1729 FT_FREE( sfnt_ps );
1730 goto Exit;
1731 }
1732
1733 error = open_face_from_buffer( library,
1734 sfnt_ps,
1735 length,
1736 FT_MIN( face_index, 0 ),
1737 is_sfnt_cid ? "cid" : "type1",
1738 aface );
1739 Exit:
1740 {
1742
1743
1744 if ( FT_ERR_EQ( error, Unknown_File_Format ) )
1745 {
1747 if ( error1 )
1748 return error1;
1749 }
1750
1751 return error;
1752 }
1753 }
1754
1755
1756#ifndef FT_MACINTOSH
1757
1758 /* The resource header says we've got resource_cnt `POST' (type1) */
1759 /* resources in this file. They all need to be coalesced into */
1760 /* one lump which gets passed on to the type1 driver. */
1761 /* Here can be only one PostScript font in a file so face_index */
1762 /* must be 0 (or -1). */
1763 /* */
1764 static FT_Error
1765 Mac_Read_POST_Resource( FT_Library library,
1768 FT_Long resource_cnt,
1769 FT_Long face_index,
1770 FT_Face *aface )
1771 {
1772 FT_Error error = FT_ERR( Cannot_Open_Resource );
1774
1775 FT_Byte* pfb_data = NULL;
1776 int i, type, flags;
1777 FT_ULong len;
1778 FT_ULong pfb_len, pfb_pos, pfb_lenpos;
1779 FT_ULong rlen, temp;
1780
1781
1782 if ( face_index == -1 )
1783 face_index = 0;
1784 if ( face_index != 0 )
1785 return error;
1786
1787 /* Find the length of all the POST resources, concatenated. Assume */
1788 /* worst case (each resource in its own section). */
1789 pfb_len = 0;
1790 for ( i = 0; i < resource_cnt; i++ )
1791 {
1793 if ( error )
1794 goto Exit;
1795 if ( FT_READ_ULONG( temp ) ) /* actually LONG */
1796 goto Exit;
1797
1798 /* FT2 allocator takes signed long buffer length,
1799 * too large value causing overflow should be checked
1800 */
1801 FT_TRACE4(( " POST fragment #%d: length=0x%08x"
1802 " total pfb_len=0x%08x\n",
1803 i, temp, pfb_len + temp + 6 ));
1804
1805 if ( FT_MAC_RFORK_MAX_LEN < temp ||
1806 FT_MAC_RFORK_MAX_LEN - temp < pfb_len + 6 )
1807 {
1808 FT_TRACE2(( " MacOS resource length cannot exceed"
1809 " 0x%08x\n",
1810 FT_MAC_RFORK_MAX_LEN ));
1811
1812 error = FT_THROW( Invalid_Offset );
1813 goto Exit;
1814 }
1815
1816 pfb_len += temp + 6;
1817 }
1818
1819 FT_TRACE2(( " total buffer size to concatenate"
1820 " %d POST fragments: 0x%08x\n",
1821 resource_cnt, pfb_len + 2 ));
1822
1823 if ( pfb_len + 2 < 6 )
1824 {
1825 FT_TRACE2(( " too long fragment length makes"
1826 " pfb_len confused: pfb_len=0x%08x\n",
1827 pfb_len ));
1828
1829 error = FT_THROW( Array_Too_Large );
1830 goto Exit;
1831 }
1832
1833 if ( FT_ALLOC( pfb_data, (FT_Long)pfb_len + 2 ) )
1834 goto Exit;
1835
1836 pfb_data[0] = 0x80;
1837 pfb_data[1] = 1; /* Ascii section */
1838 pfb_data[2] = 0; /* 4-byte length, fill in later */
1839 pfb_data[3] = 0;
1840 pfb_data[4] = 0;
1841 pfb_data[5] = 0;
1842 pfb_pos = 6;
1843 pfb_lenpos = 2;
1844
1845 len = 0;
1846 type = 1;
1847
1848 for ( i = 0; i < resource_cnt; i++ )
1849 {
1851 if ( error )
1852 goto Exit2;
1853 if ( FT_READ_ULONG( rlen ) )
1854 goto Exit2;
1855
1856 /* FT2 allocator takes signed long buffer length,
1857 * too large fragment length causing overflow should be checked
1858 */
1859 if ( 0x7FFFFFFFUL < rlen )
1860 {
1861 error = FT_THROW( Invalid_Offset );
1862 goto Exit2;
1863 }
1864
1865 if ( FT_READ_USHORT( flags ) )
1866 goto Exit2;
1867
1868 FT_TRACE3(( "POST fragment[%d]:"
1869 " offsets=0x%08x, rlen=0x%08x, flags=0x%04x\n",
1870 i, offsets[i], rlen, flags ));
1871
1872 error = FT_ERR( Array_Too_Large );
1873
1874 /* postpone the check of `rlen longer than buffer' */
1875 /* until `FT_Stream_Read' */
1876
1877 if ( ( flags >> 8 ) == 0 ) /* Comment, should not be loaded */
1878 {
1879 FT_TRACE3(( " Skip POST fragment #%d because it is a comment\n",
1880 i ));
1881 continue;
1882 }
1883
1884 /* the flags are part of the resource, so rlen >= 2, */
1885 /* but some fonts declare rlen = 0 for empty fragment */
1886 if ( rlen > 2 )
1887 rlen -= 2;
1888 else
1889 rlen = 0;
1890
1891 if ( ( flags >> 8 ) == type )
1892 len += rlen;
1893 else
1894 {
1895 FT_TRACE3(( " Write POST fragment #%d header (4-byte) to buffer"
1896 " %p + 0x%08x\n",
1897 i, pfb_data, pfb_lenpos ));
1898
1899 if ( pfb_lenpos + 3 > pfb_len + 2 )
1900 goto Exit2;
1901
1902 pfb_data[pfb_lenpos ] = (FT_Byte)( len );
1903 pfb_data[pfb_lenpos + 1] = (FT_Byte)( len >> 8 );
1904 pfb_data[pfb_lenpos + 2] = (FT_Byte)( len >> 16 );
1905 pfb_data[pfb_lenpos + 3] = (FT_Byte)( len >> 24 );
1906
1907 if ( ( flags >> 8 ) == 5 ) /* End of font mark */
1908 break;
1909
1910 FT_TRACE3(( " Write POST fragment #%d header (6-byte) to buffer"
1911 " %p + 0x%08x\n",
1912 i, pfb_data, pfb_pos ));
1913
1914 if ( pfb_pos + 6 > pfb_len + 2 )
1915 goto Exit2;
1916
1917 pfb_data[pfb_pos++] = 0x80;
1918
1919 type = flags >> 8;
1920 len = rlen;
1921
1922 pfb_data[pfb_pos++] = (FT_Byte)type;
1923 pfb_lenpos = pfb_pos;
1924 pfb_data[pfb_pos++] = 0; /* 4-byte length, fill in later */
1925 pfb_data[pfb_pos++] = 0;
1926 pfb_data[pfb_pos++] = 0;
1927 pfb_data[pfb_pos++] = 0;
1928 }
1929
1930 if ( pfb_pos > pfb_len || pfb_pos + rlen > pfb_len )
1931 goto Exit2;
1932
1933 FT_TRACE3(( " Load POST fragment #%d (%d byte) to buffer"
1934 " %p + 0x%08x\n",
1935 i, rlen, pfb_data, pfb_pos ));
1936
1937 error = FT_Stream_Read( stream, (FT_Byte *)pfb_data + pfb_pos, rlen );
1938 if ( error )
1939 goto Exit2;
1940
1941 pfb_pos += rlen;
1942 }
1943
1944 error = FT_ERR( Array_Too_Large );
1945
1946 if ( pfb_pos + 2 > pfb_len + 2 )
1947 goto Exit2;
1948 pfb_data[pfb_pos++] = 0x80;
1949 pfb_data[pfb_pos++] = 3;
1950
1951 if ( pfb_lenpos + 3 > pfb_len + 2 )
1952 goto Exit2;
1953 pfb_data[pfb_lenpos ] = (FT_Byte)( len );
1954 pfb_data[pfb_lenpos + 1] = (FT_Byte)( len >> 8 );
1955 pfb_data[pfb_lenpos + 2] = (FT_Byte)( len >> 16 );
1956 pfb_data[pfb_lenpos + 3] = (FT_Byte)( len >> 24 );
1957
1958 return open_face_from_buffer( library,
1959 pfb_data,
1960 pfb_pos,
1961 face_index,
1962 "type1",
1963 aface );
1964
1965 Exit2:
1966 if ( FT_ERR_EQ( error, Array_Too_Large ) )
1967 FT_TRACE2(( " Abort due to too-short buffer to store"
1968 " all POST fragments\n" ));
1969 else if ( FT_ERR_EQ( error, Invalid_Offset ) )
1970 FT_TRACE2(( " Abort due to invalid offset in a POST fragment\n" ));
1971
1972 if ( error )
1973 error = FT_ERR( Cannot_Open_Resource );
1974 FT_FREE( pfb_data );
1975
1976 Exit:
1977 return error;
1978 }
1979
1980
1981 /* The resource header says we've got resource_cnt `sfnt' */
1982 /* (TrueType/OpenType) resources in this file. Look through */
1983 /* them for the one indicated by face_index, load it into mem, */
1984 /* pass it on to the truetype driver, and return it. */
1985 /* */
1986 static FT_Error
1987 Mac_Read_sfnt_Resource( FT_Library library,
1990 FT_Long resource_cnt,
1991 FT_Long face_index,
1992 FT_Face *aface )
1993 {
1995 FT_Byte* sfnt_data = NULL;
1997 FT_ULong flag_offset;
1998 FT_Long rlen;
1999 int is_cff;
2000 FT_Long face_index_in_resource = 0;
2001
2002
2003 if ( face_index < 0 )
2004 face_index = -face_index - 1;
2005 if ( face_index >= resource_cnt )
2006 return FT_THROW( Cannot_Open_Resource );
2007
2008 flag_offset = (FT_ULong)offsets[face_index];
2009 error = FT_Stream_Seek( stream, flag_offset );
2010 if ( error )
2011 goto Exit;
2012
2013 if ( FT_READ_LONG( rlen ) )
2014 goto Exit;
2015 if ( rlen < 1 )
2016 return FT_THROW( Cannot_Open_Resource );
2017 if ( (FT_ULong)rlen > FT_MAC_RFORK_MAX_LEN )
2018 return FT_THROW( Invalid_Offset );
2019
2020 error = open_face_PS_from_sfnt_stream( library,
2021 stream,
2022 face_index,
2023 0, NULL,
2024 aface );
2025 if ( !error )
2026 goto Exit;
2027
2028 /* rewind sfnt stream before open_face_PS_from_sfnt_stream() */
2029 error = FT_Stream_Seek( stream, flag_offset + 4 );
2030 if ( error )
2031 goto Exit;
2032
2033 if ( FT_ALLOC( sfnt_data, rlen ) )
2034 return error;
2035 error = FT_Stream_Read( stream, (FT_Byte *)sfnt_data, (FT_ULong)rlen );
2036 if ( error ) {
2037 FT_FREE( sfnt_data );
2038 goto Exit;
2039 }
2040
2041 is_cff = rlen > 4 && !ft_memcmp( sfnt_data, "OTTO", 4 );
2042 error = open_face_from_buffer( library,
2043 sfnt_data,
2044 (FT_ULong)rlen,
2045 face_index_in_resource,
2046 is_cff ? "cff" : "truetype",
2047 aface );
2048
2049 Exit:
2050 return error;
2051 }
2052
2053
2054 /* Check for a valid resource fork header, or a valid dfont */
2055 /* header. In a resource fork the first 16 bytes are repeated */
2056 /* at the location specified by bytes 4-7. In a dfont bytes */
2057 /* 4-7 point to 16 bytes of zeroes instead. */
2058 /* */
2059 static FT_Error
2060 IsMacResource( FT_Library library,
2062 FT_Long resource_offset,
2063 FT_Long face_index,
2064 FT_Face *aface )
2065 {
2068 FT_Long map_offset, rdata_pos;
2069 FT_Long *data_offsets;
2070 FT_Long count;
2071
2072
2073 error = FT_Raccess_Get_HeaderInfo( library, stream, resource_offset,
2074 &map_offset, &rdata_pos );
2075 if ( error )
2076 return error;
2077
2078 /* POST resources must be sorted to concatenate properly */
2080 map_offset, rdata_pos,
2081 TTAG_POST, TRUE,
2082 &data_offsets, &count );
2083 if ( !error )
2084 {
2085 error = Mac_Read_POST_Resource( library, stream, data_offsets, count,
2086 face_index, aface );
2087 FT_FREE( data_offsets );
2088 /* POST exists in an LWFN providing a single face */
2089 if ( !error )
2090 (*aface)->num_faces = 1;
2091 return error;
2092 }
2093
2094 /* sfnt resources should not be sorted to preserve the face order by
2095 QuickDraw API */
2097 map_offset, rdata_pos,
2099 &data_offsets, &count );
2100 if ( !error )
2101 {
2102 FT_Long face_index_internal = face_index % count;
2103
2104
2105 error = Mac_Read_sfnt_Resource( library, stream, data_offsets, count,
2106 face_index_internal, aface );
2107 FT_FREE( data_offsets );
2108 if ( !error )
2109 (*aface)->num_faces = count;
2110 }
2111
2112 return error;
2113 }
2114
2115
2116 /* Check for a valid macbinary header, and if we find one */
2117 /* check that the (flattened) resource fork in it is valid. */
2118 /* */
2119 static FT_Error
2120 IsMacBinary( FT_Library library,
2122 FT_Long face_index,
2123 FT_Face *aface )
2124 {
2125 unsigned char header[128];
2127 FT_Long dlen, offset;
2128
2129
2130 if ( !stream )
2131 return FT_THROW( Invalid_Stream_Operation );
2132
2133 error = FT_Stream_Seek( stream, 0 );
2134 if ( error )
2135 goto Exit;
2136
2138 if ( error )
2139 goto Exit;
2140
2141 if ( header[ 0] != 0 ||
2142 header[74] != 0 ||
2143 header[82] != 0 ||
2144 header[ 1] == 0 ||
2145 header[ 1] > 33 ||
2146 header[63] != 0 ||
2147 header[2 + header[1]] != 0 ||
2148 header[0x53] > 0x7F )
2149 return FT_THROW( Unknown_File_Format );
2150
2151 dlen = ( header[0x53] << 24 ) |
2152 ( header[0x54] << 16 ) |
2153 ( header[0x55] << 8 ) |
2154 header[0x56];
2155#if 0
2156 rlen = ( header[0x57] << 24 ) |
2157 ( header[0x58] << 16 ) |
2158 ( header[0x59] << 8 ) |
2159 header[0x5A];
2160#endif /* 0 */
2161 offset = 128 + ( ( dlen + 127 ) & ~127 );
2162
2163 return IsMacResource( library, stream, offset, face_index, aface );
2164
2165 Exit:
2166 return error;
2167 }
2168
2169
2170 static FT_Error
2171 load_face_in_embedded_rfork( FT_Library library,
2173 FT_Long face_index,
2174 FT_Face *aface,
2175 const FT_Open_Args *args )
2176 {
2177
2178#undef FT_COMPONENT
2179#define FT_COMPONENT trace_raccess
2180
2182 FT_Error error = FT_ERR( Unknown_File_Format );
2183 FT_UInt i;
2184
2185 char * file_names[FT_RACCESS_N_RULES];
2188 FT_Bool is_darwin_vfs, vfs_rfork_has_no_font = FALSE; /* not tested */
2189
2190 FT_Open_Args args2;
2191 FT_Stream stream2 = NULL;
2192
2193
2195 args->pathname, file_names, offsets, errors );
2196
2197 for ( i = 0; i < FT_RACCESS_N_RULES; i++ )
2198 {
2199 is_darwin_vfs = ft_raccess_rule_by_darwin_vfs( library, i );
2200 if ( is_darwin_vfs && vfs_rfork_has_no_font )
2201 {
2202 FT_TRACE3(( "Skip rule %d: darwin vfs resource fork"
2203 " is already checked and"
2204 " no font is found\n",
2205 i ));
2206 continue;
2207 }
2208
2209 if ( errors[i] )
2210 {
2211 FT_TRACE3(( "Error 0x%x has occurred in rule %d\n",
2212 errors[i], i ));
2213 continue;
2214 }
2215
2216 args2.flags = FT_OPEN_PATHNAME;
2217 args2.pathname = file_names[i] ? file_names[i] : args->pathname;
2218
2219 FT_TRACE3(( "Try rule %d: %s (offset=%d) ...",
2220 i, args2.pathname, offsets[i] ));
2221
2222 error = FT_Stream_New( library, &args2, &stream2 );
2223 if ( is_darwin_vfs && FT_ERR_EQ( error, Cannot_Open_Stream ) )
2224 vfs_rfork_has_no_font = TRUE;
2225
2226 if ( error )
2227 {
2228 FT_TRACE3(( "failed\n" ));
2229 continue;
2230 }
2231
2232 error = IsMacResource( library, stream2, offsets[i],
2233 face_index, aface );
2234 FT_Stream_Free( stream2, 0 );
2235
2236 FT_TRACE3(( "%s\n", error ? "failed": "successful" ));
2237
2238 if ( !error )
2239 break;
2240 else if ( is_darwin_vfs )
2241 vfs_rfork_has_no_font = TRUE;
2242 }
2243
2244 for (i = 0; i < FT_RACCESS_N_RULES; i++)
2245 {
2246 if ( file_names[i] )
2247 FT_FREE( file_names[i] );
2248 }
2249
2250 /* Caller (load_mac_face) requires FT_Err_Unknown_File_Format. */
2251 if ( error )
2252 error = FT_ERR( Unknown_File_Format );
2253
2254 return error;
2255
2256#undef FT_COMPONENT
2257#define FT_COMPONENT trace_objs
2258
2259 }
2260
2261
2262 /* Check for some macintosh formats without Carbon framework. */
2263 /* Is this a macbinary file? If so look at the resource fork. */
2264 /* Is this a mac dfont file? */
2265 /* Is this an old style resource fork? (in data) */
2266 /* Else call load_face_in_embedded_rfork to try extra rules */
2267 /* (defined in `ftrfork.c'). */
2268 /* */
2269 static FT_Error
2270 load_mac_face( FT_Library library,
2272 FT_Long face_index,
2273 FT_Face *aface,
2274 const FT_Open_Args *args )
2275 {
2277 FT_UNUSED( args );
2278
2279
2280 error = IsMacBinary( library, stream, face_index, aface );
2281 if ( FT_ERR_EQ( error, Unknown_File_Format ) )
2282 {
2283
2284#undef FT_COMPONENT
2285#define FT_COMPONENT trace_raccess
2286
2287#ifdef FT_DEBUG_LEVEL_TRACE
2288 FT_TRACE3(( "Try as dfont: " ));
2289 if ( !( args->flags & FT_OPEN_MEMORY ) )
2290 FT_TRACE3(( "%s ...", args->pathname ));
2291#endif
2292
2293 error = IsMacResource( library, stream, 0, face_index, aface );
2294
2295 FT_TRACE3(( "%s\n", error ? "failed" : "successful" ));
2296
2297#undef FT_COMPONENT
2298#define FT_COMPONENT trace_objs
2299
2300 }
2301
2302 if ( ( FT_ERR_EQ( error, Unknown_File_Format ) ||
2303 FT_ERR_EQ( error, Invalid_Stream_Operation ) ) &&
2304 ( args->flags & FT_OPEN_PATHNAME ) )
2305 error = load_face_in_embedded_rfork( library, stream,
2306 face_index, aface, args );
2307 return error;
2308 }
2309#endif
2310
2311#endif /* !FT_MACINTOSH && FT_CONFIG_OPTION_MAC_FONTS */
2312
2313
2314 /* documentation is in freetype.h */
2315
2319 FT_Long face_index,
2320 FT_Face *aface )
2321 {
2322 return ft_open_face_internal( library, args, face_index, aface, 1 );
2323 }
2324
2325
2326 static FT_Error
2328 const FT_Open_Args* args,
2329 FT_Long face_index,
2330 FT_Face *aface,
2331 FT_Bool test_mac_fonts )
2332 {
2337 FT_Face face = NULL;
2339 FT_Bool external_stream;
2340 FT_Module* cur;
2342
2343#ifndef FT_CONFIG_OPTION_MAC_FONTS
2344 FT_UNUSED( test_mac_fonts );
2345#endif
2346
2347
2348#ifdef FT_DEBUG_LEVEL_TRACE
2349 FT_TRACE3(( "FT_Open_Face: " ));
2350 if ( face_index < 0 )
2351 FT_TRACE3(( "Requesting number of faces and named instances\n"));
2352 else
2353 {
2354 FT_TRACE3(( "Requesting face %ld", face_index & 0xFFFFL ));
2355 if ( face_index & 0x7FFF0000L )
2356 FT_TRACE3(( ", named instance %ld", face_index >> 16 ));
2357 FT_TRACE3(( "\n" ));
2358 }
2359#endif
2360
2361 /* test for valid `library' delayed to `FT_Stream_New' */
2362
2363 if ( ( !aface && face_index >= 0 ) || !args )
2364 return FT_THROW( Invalid_Argument );
2365
2366 external_stream = FT_BOOL( ( args->flags & FT_OPEN_STREAM ) &&
2367 args->stream );
2368
2369 /* create input stream */
2371 if ( error )
2372 goto Fail3;
2373
2375
2376 /* If the font driver is specified in the `args' structure, use */
2377 /* it. Otherwise, we scan the list of registered drivers. */
2378 if ( ( args->flags & FT_OPEN_DRIVER ) && args->driver )
2379 {
2380 driver = FT_DRIVER( args->driver );
2381
2382 /* not all modules are drivers, so check... */
2383 if ( FT_MODULE_IS_DRIVER( driver ) )
2384 {
2385 FT_Int num_params = 0;
2387
2388
2389 if ( args->flags & FT_OPEN_PARAMS )
2390 {
2391 num_params = args->num_params;
2392 params = args->params;
2393 }
2394
2395 error = open_face( driver, &stream, external_stream, face_index,
2396 num_params, params, &face );
2397 if ( !error )
2398 goto Success;
2399 }
2400 else
2401 error = FT_THROW( Invalid_Handle );
2402
2403 FT_Stream_Free( stream, external_stream );
2404 goto Fail;
2405 }
2406 else
2407 {
2408 error = FT_ERR( Missing_Module );
2409
2410 /* check each font driver for an appropriate format */
2411 cur = library->modules;
2413
2414 for ( ; cur < limit; cur++ )
2415 {
2416 /* not all modules are font drivers, so check... */
2417 if ( FT_MODULE_IS_DRIVER( cur[0] ) )
2418 {
2419 FT_Int num_params = 0;
2421
2422
2423 driver = FT_DRIVER( cur[0] );
2424
2425 if ( args->flags & FT_OPEN_PARAMS )
2426 {
2427 num_params = args->num_params;
2428 params = args->params;
2429 }
2430
2431 error = open_face( driver, &stream, external_stream, face_index,
2432 num_params, params, &face );
2433 if ( !error )
2434 goto Success;
2435
2436#ifdef FT_CONFIG_OPTION_MAC_FONTS
2437 if ( test_mac_fonts &&
2438 ft_strcmp( cur[0]->clazz->module_name, "truetype" ) == 0 &&
2439 FT_ERR_EQ( error, Table_Missing ) )
2440 {
2441 /* TrueType but essential tables are missing */
2442 error = FT_Stream_Seek( stream, 0 );
2443 if ( error )
2444 break;
2445
2446 error = open_face_PS_from_sfnt_stream( library,
2447 stream,
2448 face_index,
2449 num_params,
2450 params,
2451 aface );
2452 if ( !error )
2453 {
2454 FT_Stream_Free( stream, external_stream );
2455 return error;
2456 }
2457 }
2458#endif
2459
2460 if ( FT_ERR_NEQ( error, Unknown_File_Format ) )
2461 goto Fail3;
2462 }
2463 }
2464
2465 Fail3:
2466 /* If we are on the mac, and we get an */
2467 /* FT_Err_Invalid_Stream_Operation it may be because we have an */
2468 /* empty data fork, so we need to check the resource fork. */
2469 if ( FT_ERR_NEQ( error, Cannot_Open_Stream ) &&
2470 FT_ERR_NEQ( error, Unknown_File_Format ) &&
2471 FT_ERR_NEQ( error, Invalid_Stream_Operation ) )
2472 goto Fail2;
2473
2474#if !defined( FT_MACINTOSH ) && defined( FT_CONFIG_OPTION_MAC_FONTS )
2475 if ( test_mac_fonts )
2476 {
2477 error = load_mac_face( library, stream, face_index, aface, args );
2478 if ( !error )
2479 {
2480 /* We don't want to go to Success here. We've already done */
2481 /* that. On the other hand, if we succeeded we still need to */
2482 /* close this stream (we opened a different stream which */
2483 /* extracted the interesting information out of this stream */
2484 /* here. That stream will still be open and the face will */
2485 /* point to it). */
2486 FT_Stream_Free( stream, external_stream );
2487 return error;
2488 }
2489 }
2490
2491 if ( FT_ERR_NEQ( error, Unknown_File_Format ) )
2492 goto Fail2;
2493#endif /* !FT_MACINTOSH && FT_CONFIG_OPTION_MAC_FONTS */
2494
2495 /* no driver is able to handle this format */
2496 error = FT_THROW( Unknown_File_Format );
2497
2498 Fail2:
2499 FT_Stream_Free( stream, external_stream );
2500 goto Fail;
2501 }
2502
2503 Success:
2504 FT_TRACE4(( "FT_Open_Face: New face object, adding to list\n" ));
2505
2506 /* add the face object to its driver's list */
2507 if ( FT_NEW( node ) )
2508 goto Fail;
2509
2510 node->data = face;
2511 /* don't assume driver is the same as face->driver, so use */
2512 /* face->driver instead. */
2513 FT_List_Add( &face->driver->faces_list, node );
2514
2515 /* now allocate a glyph slot object for the face */
2516 FT_TRACE4(( "FT_Open_Face: Creating glyph slot\n" ));
2517
2518 if ( face_index >= 0 )
2519 {
2521 if ( error )
2522 goto Fail;
2523
2524 /* finally, allocate a size object for the face */
2525 {
2526 FT_Size size;
2527
2528
2529 FT_TRACE4(( "FT_Open_Face: Creating size object\n" ));
2530
2531 error = FT_New_Size( face, &size );
2532 if ( error )
2533 goto Fail;
2534
2535 face->size = size;
2536 }
2537 }
2538
2539 /* some checks */
2540
2541 if ( FT_IS_SCALABLE( face ) )
2542 {
2543 if ( face->height < 0 )
2544 face->height = (FT_Short)-face->height;
2545
2546 if ( !FT_HAS_VERTICAL( face ) )
2547 face->max_advance_height = (FT_Short)face->height;
2548 }
2549
2550 if ( FT_HAS_FIXED_SIZES( face ) )
2551 {
2552 FT_Int i;
2553
2554
2555 for ( i = 0; i < face->num_fixed_sizes; i++ )
2556 {
2557 FT_Bitmap_Size* bsize = face->available_sizes + i;
2558
2559
2560 if ( bsize->height < 0 )
2561 bsize->height = -bsize->height;
2562 if ( bsize->x_ppem < 0 )
2563 bsize->x_ppem = -bsize->x_ppem;
2564 if ( bsize->y_ppem < 0 )
2565 bsize->y_ppem = -bsize->y_ppem;
2566
2567 /* check whether negation actually has worked */
2568 if ( bsize->height < 0 || bsize->x_ppem < 0 || bsize->y_ppem < 0 )
2569 {
2570 FT_TRACE0(( "FT_Open_Face:"
2571 " Invalid bitmap dimensions for strike %d,"
2572 " now disabled\n", i ));
2573 bsize->width = 0;
2574 bsize->height = 0;
2575 bsize->size = 0;
2576 bsize->x_ppem = 0;
2577 bsize->y_ppem = 0;
2578 }
2579 }
2580 }
2581
2582 /* initialize internal face data */
2583 {
2584 FT_Face_Internal internal = face->internal;
2585
2586
2587 internal->transform_matrix.xx = 0x10000L;
2588 internal->transform_matrix.xy = 0;
2589 internal->transform_matrix.yx = 0;
2590 internal->transform_matrix.yy = 0x10000L;
2591
2592 internal->transform_delta.x = 0;
2593 internal->transform_delta.y = 0;
2594
2595 internal->refcount = 1;
2596
2597 internal->no_stem_darkening = -1;
2598
2599#ifdef FT_CONFIG_OPTION_SUBPIXEL_RENDERING
2600 /* Per-face filtering can only be set up by FT_Face_Properties */
2601 internal->lcd_filter_func = NULL;
2602#endif
2603 }
2604
2605 if ( aface )
2606 *aface = face;
2607 else
2608 FT_Done_Face( face );
2609
2610 goto Exit;
2611
2612 Fail:
2613 if ( node )
2614 FT_Done_Face( face ); /* face must be in the driver's list */
2615 else if ( face )
2617
2618 Exit:
2619#ifdef FT_DEBUG_LEVEL_TRACE
2620 if ( !error && face_index < 0 )
2621 {
2622 FT_TRACE3(( "FT_Open_Face: The font has %ld face%s\n"
2623 " and %ld named instance%s for face %ld\n",
2624 face->num_faces,
2625 face->num_faces == 1 ? "" : "s",
2626 face->style_flags >> 16,
2627 ( face->style_flags >> 16 ) == 1 ? "" : "s",
2628 -face_index - 1 ));
2629 }
2630#endif
2631
2632 FT_TRACE4(( "FT_Open_Face: Return 0x%x\n", error ));
2633
2634 return error;
2635 }
2636
2637
2638 /* documentation is in freetype.h */
2639
2642 const char* filepathname )
2643 {
2645
2646
2647 /* test for valid `face' delayed to `FT_Attach_Stream' */
2648
2649 if ( !filepathname )
2650 return FT_THROW( Invalid_Argument );
2651
2652 open.stream = NULL;
2653 open.flags = FT_OPEN_PATHNAME;
2654 open.pathname = (char*)filepathname;
2655
2656 return FT_Attach_Stream( face, &open );
2657 }
2658
2659
2660 /* documentation is in freetype.h */
2661
2664 FT_Open_Args* parameters )
2665 {
2669
2670 FT_Driver_Class clazz;
2671
2672
2673 /* test for valid `parameters' delayed to `FT_Stream_New' */
2674
2675 if ( !face )
2676 return FT_THROW( Invalid_Face_Handle );
2677
2678 driver = face->driver;
2679 if ( !driver )
2680 return FT_THROW( Invalid_Driver_Handle );
2681
2682 error = FT_Stream_New( driver->root.library, parameters, &stream );
2683 if ( error )
2684 goto Exit;
2685
2686 /* we implement FT_Attach_Stream in each driver through the */
2687 /* `attach_file' interface */
2688
2689 error = FT_ERR( Unimplemented_Feature );
2690 clazz = driver->clazz;
2691 if ( clazz->attach_file )
2692 error = clazz->attach_file( face, stream );
2693
2694 /* close the attached stream */
2696 (FT_Bool)( parameters->stream &&
2697 ( parameters->flags & FT_OPEN_STREAM ) ) );
2698
2699 Exit:
2700 return error;
2701 }
2702
2703
2704 /* documentation is in freetype.h */
2705
2708 {
2709 if ( !face )
2710 return FT_THROW( Invalid_Face_Handle );
2711
2712 face->internal->refcount++;
2713
2714 return FT_Err_Ok;
2715 }
2716
2717
2718 /* documentation is in freetype.h */
2719
2722 {
2727
2728
2729 error = FT_ERR( Invalid_Face_Handle );
2730 if ( face && face->driver )
2731 {
2732 face->internal->refcount--;
2733 if ( face->internal->refcount > 0 )
2734 error = FT_Err_Ok;
2735 else
2736 {
2737 driver = face->driver;
2738 memory = driver->root.memory;
2739
2740 /* find face in driver's list */
2741 node = FT_List_Find( &driver->faces_list, face );
2742 if ( node )
2743 {
2744 /* remove face object from the driver's list */
2745 FT_List_Remove( &driver->faces_list, node );
2746 FT_FREE( node );
2747
2748 /* now destroy the object proper */
2750 error = FT_Err_Ok;
2751 }
2752 }
2753 }
2754
2755 return error;
2756 }
2757
2758
2759 /* documentation is in ftobjs.h */
2760
2763 FT_Size *asize )
2764 {
2768 FT_Driver_Class clazz;
2769
2770 FT_Size size = NULL;
2772
2774
2775
2776 if ( !face )
2777 return FT_THROW( Invalid_Face_Handle );
2778
2779 if ( !asize )
2780 return FT_THROW( Invalid_Argument );
2781
2782 if ( !face->driver )
2783 return FT_THROW( Invalid_Driver_Handle );
2784
2785 *asize = NULL;
2786
2787 driver = face->driver;
2788 clazz = driver->clazz;
2789 memory = face->memory;
2790
2791 /* Allocate new size object and perform basic initialisation */
2792 if ( FT_ALLOC( size, clazz->size_object_size ) || FT_NEW( node ) )
2793 goto Exit;
2794
2795 size->face = face;
2796
2797 if ( FT_NEW( internal ) )
2798 goto Exit;
2799
2800 size->internal = internal;
2801
2802 if ( clazz->init_size )
2803 error = clazz->init_size( size );
2804
2805 /* in case of success, add to the face's list */
2806 if ( !error )
2807 {
2808 *asize = size;
2809 node->data = size;
2810 FT_List_Add( &face->sizes_list, node );
2811 }
2812
2813 Exit:
2814 if ( error )
2815 {
2816 FT_FREE( node );
2817 FT_FREE( size );
2818 }
2819
2820 return error;
2821 }
2822
2823
2824 /* documentation is in ftobjs.h */
2825
2828 {
2832 FT_Face face;
2834
2835
2836 if ( !size )
2837 return FT_THROW( Invalid_Size_Handle );
2838
2839 face = size->face;
2840 if ( !face )
2841 return FT_THROW( Invalid_Face_Handle );
2842
2843 driver = face->driver;
2844 if ( !driver )
2845 return FT_THROW( Invalid_Driver_Handle );
2846
2847 memory = driver->root.memory;
2848
2849 error = FT_Err_Ok;
2850 node = FT_List_Find( &face->sizes_list, size );
2851 if ( node )
2852 {
2853 FT_List_Remove( &face->sizes_list, node );
2854 FT_FREE( node );
2855
2856 if ( face->size == size )
2857 {
2858 face->size = NULL;
2859 if ( face->sizes_list.head )
2860 face->size = (FT_Size)(face->sizes_list.head->data);
2861 }
2862
2864 }
2865 else
2866 error = FT_THROW( Invalid_Size_Handle );
2867
2868 return error;
2869 }
2870
2871
2872 /* documentation is in ftobjs.h */
2873
2876 FT_Size_Request req,
2877 FT_Bool ignore_width,
2878 FT_ULong* size_index )
2879 {
2880 FT_Int i;
2881 FT_Long w, h;
2882
2883
2884 if ( !FT_HAS_FIXED_SIZES( face ) )
2885 return FT_THROW( Invalid_Face_Handle );
2886
2887 /* FT_Bitmap_Size doesn't provide enough info... */
2888 if ( req->type != FT_SIZE_REQUEST_TYPE_NOMINAL )
2889 return FT_THROW( Unimplemented_Feature );
2890
2891 w = FT_REQUEST_WIDTH ( req );
2892 h = FT_REQUEST_HEIGHT( req );
2893
2894 if ( req->width && !req->height )
2895 h = w;
2896 else if ( !req->width && req->height )
2897 w = h;
2898
2899 w = FT_PIX_ROUND( w );
2900 h = FT_PIX_ROUND( h );
2901
2902 if ( !w || !h )
2903 return FT_THROW( Invalid_Pixel_Size );
2904
2905 for ( i = 0; i < face->num_fixed_sizes; i++ )
2906 {
2907 FT_Bitmap_Size* bsize = face->available_sizes + i;
2908
2909
2910 if ( h != FT_PIX_ROUND( bsize->y_ppem ) )
2911 continue;
2912
2913 if ( w == FT_PIX_ROUND( bsize->x_ppem ) || ignore_width )
2914 {
2915 FT_TRACE3(( "FT_Match_Size: bitmap strike %d matches\n", i ));
2916
2917 if ( size_index )
2918 *size_index = (FT_ULong)i;
2919
2920 return FT_Err_Ok;
2921 }
2922 }
2923
2924 FT_TRACE3(( "FT_Match_Size: no matching bitmap strike\n" ));
2925
2926 return FT_THROW( Invalid_Pixel_Size );
2927 }
2928
2929
2930 /* documentation is in ftobjs.h */
2931
2932 FT_BASE_DEF( void )
2934 FT_Pos advance )
2935 {
2936 FT_Pos height = metrics->height;
2937
2938
2939 /* compensate for glyph with bbox above/below the baseline */
2940 if ( metrics->horiBearingY < 0 )
2941 {
2942 if ( height < metrics->horiBearingY )
2943 height = metrics->horiBearingY;
2944 }
2945 else if ( metrics->horiBearingY > 0 )
2946 height -= metrics->horiBearingY;
2947
2948 /* the factor 1.2 is a heuristical value */
2949 if ( !advance )
2950 advance = height * 12 / 10;
2951
2952 metrics->vertBearingX = metrics->horiBearingX - metrics->horiAdvance / 2;
2953 metrics->vertBearingY = ( advance - height ) / 2;
2954 metrics->vertAdvance = advance;
2955 }
2956
2957
2958 static void
2961 {
2962 /* Compute root ascender, descender, test height, and max_advance */
2963
2964#ifdef GRID_FIT_METRICS
2965 metrics->ascender = FT_PIX_CEIL( FT_MulFix( face->ascender,
2966 metrics->y_scale ) );
2967
2968 metrics->descender = FT_PIX_FLOOR( FT_MulFix( face->descender,
2969 metrics->y_scale ) );
2970
2971 metrics->height = FT_PIX_ROUND( FT_MulFix( face->height,
2972 metrics->y_scale ) );
2973
2974 metrics->max_advance = FT_PIX_ROUND( FT_MulFix( face->max_advance_width,
2975 metrics->x_scale ) );
2976#else /* !GRID_FIT_METRICS */
2977 metrics->ascender = FT_MulFix( face->ascender,
2978 metrics->y_scale );
2979
2980 metrics->descender = FT_MulFix( face->descender,
2981 metrics->y_scale );
2982
2983 metrics->height = FT_MulFix( face->height,
2984 metrics->y_scale );
2985
2986 metrics->max_advance = FT_MulFix( face->max_advance_width,
2987 metrics->x_scale );
2988#endif /* !GRID_FIT_METRICS */
2989 }
2990
2991
2992 FT_BASE_DEF( void )
2994 FT_ULong strike_index )
2995 {
2997 FT_Bitmap_Size* bsize;
2998
2999
3000 metrics = &face->size->metrics;
3001 bsize = face->available_sizes + strike_index;
3002
3003 metrics->x_ppem = (FT_UShort)( ( bsize->x_ppem + 32 ) >> 6 );
3004 metrics->y_ppem = (FT_UShort)( ( bsize->y_ppem + 32 ) >> 6 );
3005
3006 if ( FT_IS_SCALABLE( face ) )
3007 {
3008 metrics->x_scale = FT_DivFix( bsize->x_ppem,
3009 face->units_per_EM );
3010 metrics->y_scale = FT_DivFix( bsize->y_ppem,
3011 face->units_per_EM );
3012
3014 }
3015 else
3016 {
3017 metrics->x_scale = 1L << 16;
3018 metrics->y_scale = 1L << 16;
3019 metrics->ascender = bsize->y_ppem;
3020 metrics->descender = 0;
3021 metrics->height = bsize->height << 6;
3022 metrics->max_advance = bsize->x_ppem;
3023 }
3024 }
3025
3026
3027 FT_BASE_DEF( void )
3029 FT_Size_Request req )
3030 {
3032
3033
3034 metrics = &face->size->metrics;
3035
3036 if ( FT_IS_SCALABLE( face ) )
3037 {
3038 FT_Long w = 0, h = 0, scaled_w = 0, scaled_h = 0;
3039
3040
3041 switch ( req->type )
3042 {
3044 w = h = face->units_per_EM;
3045 break;
3046
3048 w = h = face->ascender - face->descender;
3049 break;
3050
3052 w = face->bbox.xMax - face->bbox.xMin;
3053 h = face->bbox.yMax - face->bbox.yMin;
3054 break;
3055
3057 w = face->max_advance_width;
3058 h = face->ascender - face->descender;
3059 break;
3060
3062 metrics->x_scale = (FT_Fixed)req->width;
3063 metrics->y_scale = (FT_Fixed)req->height;
3064 if ( !metrics->x_scale )
3065 metrics->x_scale = metrics->y_scale;
3066 else if ( !metrics->y_scale )
3067 metrics->y_scale = metrics->x_scale;
3068 goto Calculate_Ppem;
3069
3071 break;
3072 }
3073
3074 /* to be on the safe side */
3075 if ( w < 0 )
3076 w = -w;
3077
3078 if ( h < 0 )
3079 h = -h;
3080
3081 scaled_w = FT_REQUEST_WIDTH ( req );
3082 scaled_h = FT_REQUEST_HEIGHT( req );
3083
3084 /* determine scales */
3085 if ( req->width )
3086 {
3087 metrics->x_scale = FT_DivFix( scaled_w, w );
3088
3089 if ( req->height )
3090 {
3091 metrics->y_scale = FT_DivFix( scaled_h, h );
3092
3093 if ( req->type == FT_SIZE_REQUEST_TYPE_CELL )
3094 {
3095 if ( metrics->y_scale > metrics->x_scale )
3096 metrics->y_scale = metrics->x_scale;
3097 else
3098 metrics->x_scale = metrics->y_scale;
3099 }
3100 }
3101 else
3102 {
3103 metrics->y_scale = metrics->x_scale;
3104 scaled_h = FT_MulDiv( scaled_w, h, w );
3105 }
3106 }
3107 else
3108 {
3109 metrics->x_scale = metrics->y_scale = FT_DivFix( scaled_h, h );
3110 scaled_w = FT_MulDiv( scaled_h, w, h );
3111 }
3112
3113 Calculate_Ppem:
3114 /* calculate the ppems */
3115 if ( req->type != FT_SIZE_REQUEST_TYPE_NOMINAL )
3116 {
3117 scaled_w = FT_MulFix( face->units_per_EM, metrics->x_scale );
3118 scaled_h = FT_MulFix( face->units_per_EM, metrics->y_scale );
3119 }
3120
3121 metrics->x_ppem = (FT_UShort)( ( scaled_w + 32 ) >> 6 );
3122 metrics->y_ppem = (FT_UShort)( ( scaled_h + 32 ) >> 6 );
3123
3125 }
3126 else
3127 {
3128 FT_ZERO( metrics );
3129 metrics->x_scale = 1L << 16;
3130 metrics->y_scale = 1L << 16;
3131 }
3132 }
3133
3134
3135 /* documentation is in freetype.h */
3136
3139 FT_Int strike_index )
3140 {
3142 FT_Driver_Class clazz;
3143
3144
3145 if ( !face || !FT_HAS_FIXED_SIZES( face ) )
3146 return FT_THROW( Invalid_Face_Handle );
3147
3148 if ( strike_index < 0 || strike_index >= face->num_fixed_sizes )
3149 return FT_THROW( Invalid_Argument );
3150
3151 clazz = face->driver->clazz;
3152
3153 if ( clazz->select_size )
3154 {
3155 error = clazz->select_size( face->size, (FT_ULong)strike_index );
3156
3157 FT_TRACE5(( "FT_Select_Size (%s driver):\n",
3158 face->driver->root.clazz->module_name ));
3159 }
3160 else
3161 {
3162 FT_Select_Metrics( face, (FT_ULong)strike_index );
3163
3164 FT_TRACE5(( "FT_Select_Size:\n" ));
3165 }
3166
3167#ifdef FT_DEBUG_LEVEL_TRACE
3168 {
3169 FT_Size_Metrics* metrics = &face->size->metrics;
3170
3171
3172 FT_TRACE5(( " x scale: %d (%f)\n",
3173 metrics->x_scale, metrics->x_scale / 65536.0 ));
3174 FT_TRACE5(( " y scale: %d (%f)\n",
3175 metrics->y_scale, metrics->y_scale / 65536.0 ));
3176 FT_TRACE5(( " ascender: %f\n", metrics->ascender / 64.0 ));
3177 FT_TRACE5(( " descender: %f\n", metrics->descender / 64.0 ));
3178 FT_TRACE5(( " height: %f\n", metrics->height / 64.0 ));
3179 FT_TRACE5(( " max advance: %f\n", metrics->max_advance / 64.0 ));
3180 FT_TRACE5(( " x ppem: %d\n", metrics->x_ppem ));
3181 FT_TRACE5(( " y ppem: %d\n", metrics->y_ppem ));
3182 }
3183#endif
3184
3185 return error;
3186 }
3187
3188
3189 /* documentation is in freetype.h */
3190
3193 FT_Size_Request req )
3194 {
3196 FT_Driver_Class clazz;
3197 FT_ULong strike_index;
3198
3199
3200 if ( !face )
3201 return FT_THROW( Invalid_Face_Handle );
3202
3203 if ( !req || req->width < 0 || req->height < 0 ||
3204 req->type >= FT_SIZE_REQUEST_TYPE_MAX )
3205 return FT_THROW( Invalid_Argument );
3206
3207 /* signal the auto-hinter to recompute its size metrics */
3208 /* (if requested) */
3209 face->size->internal->autohint_metrics.x_scale = 0;
3210
3211 clazz = face->driver->clazz;
3212
3213 if ( clazz->request_size )
3214 {
3215 error = clazz->request_size( face->size, req );
3216
3217 FT_TRACE5(( "FT_Request_Size (%s driver):\n",
3218 face->driver->root.clazz->module_name ));
3219 }
3220 else if ( !FT_IS_SCALABLE( face ) && FT_HAS_FIXED_SIZES( face ) )
3221 {
3222 /*
3223 * The reason that a driver doesn't have `request_size' defined is
3224 * either that the scaling here suffices or that the supported formats
3225 * are bitmap-only and size matching is not implemented.
3226 *
3227 * In the latter case, a simple size matching is done.
3228 */
3229 error = FT_Match_Size( face, req, 0, &strike_index );
3230 if ( error )
3231 return error;
3232
3233 return FT_Select_Size( face, (FT_Int)strike_index );
3234 }
3235 else
3236 {
3237 FT_Request_Metrics( face, req );
3238
3239 FT_TRACE5(( "FT_Request_Size:\n" ));
3240 }
3241
3242#ifdef FT_DEBUG_LEVEL_TRACE
3243 {
3244 FT_Size_Metrics* metrics = &face->size->metrics;
3245
3246
3247 FT_TRACE5(( " x scale: %d (%f)\n",
3248 metrics->x_scale, metrics->x_scale / 65536.0 ));
3249 FT_TRACE5(( " y scale: %d (%f)\n",
3250 metrics->y_scale, metrics->y_scale / 65536.0 ));
3251 FT_TRACE5(( " ascender: %f\n", metrics->ascender / 64.0 ));
3252 FT_TRACE5(( " descender: %f\n", metrics->descender / 64.0 ));
3253 FT_TRACE5(( " height: %f\n", metrics->height / 64.0 ));
3254 FT_TRACE5(( " max advance: %f\n", metrics->max_advance / 64.0 ));
3255 FT_TRACE5(( " x ppem: %d\n", metrics->x_ppem ));
3256 FT_TRACE5(( " y ppem: %d\n", metrics->y_ppem ));
3257 }
3258#endif
3259
3260 return error;
3261 }
3262
3263
3264 /* documentation is in freetype.h */
3265
3268 FT_F26Dot6 char_width,
3269 FT_F26Dot6 char_height,
3270 FT_UInt horz_resolution,
3271 FT_UInt vert_resolution )
3272 {
3274
3275
3276 /* check of `face' delayed to `FT_Request_Size' */
3277
3278 if ( !char_width )
3279 char_width = char_height;
3280 else if ( !char_height )
3281 char_height = char_width;
3282
3283 if ( !horz_resolution )
3284 horz_resolution = vert_resolution;
3285 else if ( !vert_resolution )
3286 vert_resolution = horz_resolution;
3287
3288 if ( char_width < 1 * 64 )
3289 char_width = 1 * 64;
3290 if ( char_height < 1 * 64 )
3291 char_height = 1 * 64;
3292
3293 if ( !horz_resolution )
3294 horz_resolution = vert_resolution = 72;
3295
3297 req.width = char_width;
3298 req.height = char_height;
3299 req.horiResolution = horz_resolution;
3300 req.vertResolution = vert_resolution;
3301
3302 return FT_Request_Size( face, &req );
3303 }
3304
3305
3306 /* documentation is in freetype.h */
3307
3310 FT_UInt pixel_width,
3311 FT_UInt pixel_height )
3312 {
3314
3315
3316 /* check of `face' delayed to `FT_Request_Size' */
3317
3318 if ( pixel_width == 0 )
3319 pixel_width = pixel_height;
3320 else if ( pixel_height == 0 )
3321 pixel_height = pixel_width;
3322
3323 if ( pixel_width < 1 )
3324 pixel_width = 1;
3325 if ( pixel_height < 1 )
3326 pixel_height = 1;
3327
3328 /* use `>=' to avoid potential compiler warning on 16bit platforms */
3329 if ( pixel_width >= 0xFFFFU )
3330 pixel_width = 0xFFFFU;
3331 if ( pixel_height >= 0xFFFFU )
3332 pixel_height = 0xFFFFU;
3333
3335 req.width = (FT_Long)( pixel_width << 6 );
3336 req.height = (FT_Long)( pixel_height << 6 );
3337 req.horiResolution = 0;
3338 req.vertResolution = 0;
3339
3340 return FT_Request_Size( face, &req );
3341 }
3342
3343
3344 /* documentation is in freetype.h */
3345
3350 FT_UInt kern_mode,
3351 FT_Vector *akerning )
3352 {
3355
3356
3357 if ( !face )
3358 return FT_THROW( Invalid_Face_Handle );
3359
3360 if ( !akerning )
3361 return FT_THROW( Invalid_Argument );
3362
3363 driver = face->driver;
3364
3365 akerning->x = 0;
3366 akerning->y = 0;
3367
3368 if ( driver->clazz->get_kerning )
3369 {
3370 error = driver->clazz->get_kerning( face,
3371 left_glyph,
3373 akerning );
3374 if ( !error )
3375 {
3376 if ( kern_mode != FT_KERNING_UNSCALED )
3377 {
3378 akerning->x = FT_MulFix( akerning->x, face->size->metrics.x_scale );
3379 akerning->y = FT_MulFix( akerning->y, face->size->metrics.y_scale );
3380
3381 if ( kern_mode != FT_KERNING_UNFITTED )
3382 {
3383 FT_Pos orig_x = akerning->x;
3384 FT_Pos orig_y = akerning->y;
3385
3386
3387 /* we scale down kerning values for small ppem values */
3388 /* to avoid that rounding makes them too big. */
3389 /* `25' has been determined heuristically. */
3390 if ( face->size->metrics.x_ppem < 25 )
3391 akerning->x = FT_MulDiv( orig_x,
3392 face->size->metrics.x_ppem, 25 );
3393 if ( face->size->metrics.y_ppem < 25 )
3394 akerning->y = FT_MulDiv( orig_y,
3395 face->size->metrics.y_ppem, 25 );
3396
3397 akerning->x = FT_PIX_ROUND( akerning->x );
3398 akerning->y = FT_PIX_ROUND( akerning->y );
3399
3400#ifdef FT_DEBUG_LEVEL_TRACE
3401 {
3402 FT_Pos orig_x_rounded = FT_PIX_ROUND( orig_x );
3403 FT_Pos orig_y_rounded = FT_PIX_ROUND( orig_y );
3404
3405
3406 if ( akerning->x != orig_x_rounded ||
3407 akerning->y != orig_y_rounded )
3408 FT_TRACE5(( "FT_Get_Kerning: horizontal kerning"
3409 " (%d, %d) scaled down to (%d, %d) pixels\n",
3410 orig_x_rounded / 64, orig_y_rounded / 64,
3411 akerning->x / 64, akerning->y / 64 ));
3412 }
3413#endif
3414 }
3415 }
3416 }
3417 }
3418
3419 return error;
3420 }
3421
3422
3423 /* documentation is in freetype.h */
3424
3427 FT_Fixed point_size,
3428 FT_Int degree,
3429 FT_Fixed* akerning )
3430 {
3431 FT_Service_Kerning service;
3433
3434
3435 if ( !face )
3436 return FT_THROW( Invalid_Face_Handle );
3437
3438 if ( !akerning )
3439 return FT_THROW( Invalid_Argument );
3440
3441 FT_FACE_FIND_SERVICE( face, service, KERNING );
3442 if ( !service )
3443 return FT_THROW( Unimplemented_Feature );
3444
3445 error = service->get_track( face,
3446 point_size,
3447 degree,
3448 akerning );
3449
3450 return error;
3451 }
3452
3453
3454 /* documentation is in freetype.h */
3455
3459 {
3460 FT_CharMap* cur;
3462
3463
3464 if ( !face )
3465 return FT_THROW( Invalid_Face_Handle );
3466
3467 if ( encoding == FT_ENCODING_NONE )
3468 return FT_THROW( Invalid_Argument );
3469
3470 /* FT_ENCODING_UNICODE is special. We try to find the `best' Unicode */
3471 /* charmap available, i.e., one with UCS-4 characters, if possible. */
3472 /* */
3473 /* This is done by find_unicode_charmap() above, to share code. */
3474 if ( encoding == FT_ENCODING_UNICODE )
3475 return find_unicode_charmap( face );
3476
3477 cur = face->charmaps;
3478 if ( !cur )
3479 return FT_THROW( Invalid_CharMap_Handle );
3480
3481 limit = cur + face->num_charmaps;
3482
3483 for ( ; cur < limit; cur++ )
3484 {
3485 if ( cur[0]->encoding == encoding )
3486 {
3487 face->charmap = cur[0];
3488 return 0;
3489 }
3490 }
3491
3492 return FT_THROW( Invalid_Argument );
3493 }
3494
3495
3496 /* documentation is in freetype.h */
3497
3500 FT_CharMap charmap )
3501 {
3502 FT_CharMap* cur;
3504
3505
3506 if ( !face )
3507 return FT_THROW( Invalid_Face_Handle );
3508
3509 cur = face->charmaps;
3510 if ( !cur || !charmap )
3511 return FT_THROW( Invalid_CharMap_Handle );
3512
3513 if ( FT_Get_CMap_Format( charmap ) == 14 )
3514 return FT_THROW( Invalid_Argument );
3515
3516 limit = cur + face->num_charmaps;
3517
3518 for ( ; cur < limit; cur++ )
3519 {
3520 if ( cur[0] == charmap )
3521 {
3522 face->charmap = cur[0];
3523 return FT_Err_Ok;
3524 }
3525 }
3526
3527 return FT_THROW( Invalid_Argument );
3528 }
3529
3530
3531 /* documentation is in freetype.h */
3532
3535 {
3536 FT_Int i;
3537
3538
3539 if ( !charmap || !charmap->face )
3540 return -1;
3541
3542 for ( i = 0; i < charmap->face->num_charmaps; i++ )
3543 if ( charmap->face->charmaps[i] == charmap )
3544 break;
3545
3546 FT_ASSERT( i < charmap->face->num_charmaps );
3547
3548 return i;
3549 }
3550
3551
3552 static void
3554 {
3555 FT_CMap_Class clazz = cmap->clazz;
3556 FT_Face face = cmap->charmap.face;
3558
3559
3560 if ( clazz->done )
3561 clazz->done( cmap );
3562
3563 FT_FREE( cmap );
3564 }
3565
3566
3567 FT_BASE_DEF( void )
3569 {
3570 if ( cmap )
3571 {
3572 FT_Face face = cmap->charmap.face;
3575 FT_Int i, j;
3576
3577
3578 for ( i = 0; i < face->num_charmaps; i++ )
3579 {
3580 if ( (FT_CMap)face->charmaps[i] == cmap )
3581 {
3582 FT_CharMap last_charmap = face->charmaps[face->num_charmaps - 1];
3583
3584
3585 if ( FT_RENEW_ARRAY( face->charmaps,
3586 face->num_charmaps,
3587 face->num_charmaps - 1 ) )
3588 return;
3589
3590 /* remove it from our list of charmaps */
3591 for ( j = i + 1; j < face->num_charmaps; j++ )
3592 {
3593 if ( j == face->num_charmaps - 1 )
3594 face->charmaps[j - 1] = last_charmap;
3595 else
3596 face->charmaps[j - 1] = face->charmaps[j];
3597 }
3598
3599 face->num_charmaps--;
3600
3601 if ( (FT_CMap)face->charmap == cmap )
3602 face->charmap = NULL;
3603
3604 ft_cmap_done_internal( cmap );
3605
3606 break;
3607 }
3608 }
3609 }
3610 }
3611
3612
3615 FT_Pointer init_data,
3616 FT_CharMap charmap,
3617 FT_CMap *acmap )
3618 {
3620 FT_Face face;
3622 FT_CMap cmap = NULL;
3623
3624
3625 if ( !clazz || !charmap || !charmap->face )
3626 return FT_THROW( Invalid_Argument );
3627
3628 face = charmap->face;
3630
3631 if ( !FT_ALLOC( cmap, clazz->size ) )
3632 {
3633 cmap->charmap = *charmap;
3634 cmap->clazz = clazz;
3635
3636 if ( clazz->init )
3637 {
3638 error = clazz->init( cmap, init_data );
3639 if ( error )
3640 goto Fail;
3641 }
3642
3643 /* add it to our list of charmaps */
3644 if ( FT_RENEW_ARRAY( face->charmaps,
3645 face->num_charmaps,
3646 face->num_charmaps + 1 ) )
3647 goto Fail;
3648
3649 face->charmaps[face->num_charmaps++] = (FT_CharMap)cmap;
3650 }
3651
3652 Exit:
3653 if ( acmap )
3654 *acmap = cmap;
3655
3656 return error;
3657
3658 Fail:
3659 ft_cmap_done_internal( cmap );
3660 cmap = NULL;
3661 goto Exit;
3662 }
3663
3664
3665 /* documentation is in freetype.h */
3666
3669 FT_ULong charcode )
3670 {
3671 FT_UInt result = 0;
3672
3673
3674 if ( face && face->charmap )
3675 {
3676 FT_CMap cmap = FT_CMAP( face->charmap );
3677
3678
3679 if ( charcode > 0xFFFFFFFFUL )
3680 {
3681 FT_TRACE1(( "FT_Get_Char_Index: too large charcode" ));
3682 FT_TRACE1(( " 0x%x is truncated\n", charcode ));
3683 }
3684
3685 result = cmap->clazz->char_index( cmap, (FT_UInt32)charcode );
3686 if ( result >= (FT_UInt)face->num_glyphs )
3687 result = 0;
3688 }
3689
3690 return result;
3691 }
3692
3693
3694 /* documentation is in freetype.h */
3695
3698 FT_UInt *agindex )
3699 {
3700 FT_ULong result = 0;
3701 FT_UInt gindex = 0;
3702
3703
3704 /* only do something if we have a charmap, and we have glyphs at all */
3705 if ( face && face->charmap && face->num_glyphs )
3706 {
3707 gindex = FT_Get_Char_Index( face, 0 );
3708 if ( gindex == 0 )
3709 result = FT_Get_Next_Char( face, 0, &gindex );
3710 }
3711
3712 if ( agindex )
3713 *agindex = gindex;
3714
3715 return result;
3716 }
3717
3718
3719 /* documentation is in freetype.h */
3720
3723 FT_ULong charcode,
3724 FT_UInt *agindex )
3725 {
3726 FT_ULong result = 0;
3727 FT_UInt gindex = 0;
3728
3729
3730 if ( face && face->charmap && face->num_glyphs )
3731 {
3732 FT_UInt32 code = (FT_UInt32)charcode;
3733 FT_CMap cmap = FT_CMAP( face->charmap );
3734
3735
3736 do
3737 {
3738 gindex = cmap->clazz->char_next( cmap, &code );
3739
3740 } while ( gindex >= (FT_UInt)face->num_glyphs );
3741
3742 result = ( gindex == 0 ) ? 0 : code;
3743 }
3744
3745 if ( agindex )
3746 *agindex = gindex;
3747
3748 return result;
3749 }
3750
3751
3752 /* documentation is in freetype.h */
3753
3756 FT_UInt num_properties,
3757 FT_Parameter* properties )
3758 {
3760
3761
3762 if ( num_properties > 0 && !properties )
3763 {
3764 error = FT_THROW( Invalid_Argument );
3765 goto Exit;
3766 }
3767
3768 for ( ; num_properties > 0; num_properties-- )
3769 {
3770 if ( properties->tag == FT_PARAM_TAG_STEM_DARKENING )
3771 {
3772 if ( properties->data )
3773 {
3774 if ( *( (FT_Bool*)properties->data ) == TRUE )
3775 face->internal->no_stem_darkening = FALSE;
3776 else
3777 face->internal->no_stem_darkening = TRUE;
3778 }
3779 else
3780 {
3781 /* use module default */
3782 face->internal->no_stem_darkening = -1;
3783 }
3784 }
3785 else if ( properties->tag == FT_PARAM_TAG_LCD_FILTER_WEIGHTS )
3786 {
3787#ifdef FT_CONFIG_OPTION_SUBPIXEL_RENDERING
3788 if ( properties->data )
3789 {
3790 ft_memcpy( face->internal->lcd_weights,
3791 properties->data,
3793 face->internal->lcd_filter_func = ft_lcd_filter_fir;
3794 }
3795#else
3796 error = FT_THROW( Unimplemented_Feature );
3797 goto Exit;
3798#endif
3799 }
3800 else if ( properties->tag == FT_PARAM_TAG_RANDOM_SEED )
3801 {
3802 if ( properties->data )
3803 {
3804 face->internal->random_seed = *( (FT_Int32*)properties->data );
3805 if ( face->internal->random_seed < 0 )
3806 face->internal->random_seed = 0;
3807 }
3808 else
3809 {
3810 /* use module default */
3811 face->internal->random_seed = -1;
3812 }
3813 }
3814 else
3815 {
3816 error = FT_THROW( Invalid_Argument );
3817 goto Exit;
3818 }
3819
3820 if ( error )
3821 break;
3822
3823 properties++;
3824 }
3825
3826 Exit:
3827 return error;
3828 }
3829
3830
3831 /* documentation is in freetype.h */
3832
3835 FT_ULong charcode,
3836 FT_ULong variantSelector )
3837 {
3838 FT_UInt result = 0;
3839
3840
3841 if ( face &&
3842 face->charmap &&
3843 face->charmap->encoding == FT_ENCODING_UNICODE )
3844 {
3846 FT_CMap ucmap = FT_CMAP( face->charmap );
3847
3848
3849 if ( charmap )
3850 {
3851 FT_CMap vcmap = FT_CMAP( charmap );
3852
3853
3854 if ( charcode > 0xFFFFFFFFUL )
3855 {
3856 FT_TRACE1(( "FT_Face_GetCharVariantIndex:"
3857 " too large charcode" ));
3858 FT_TRACE1(( " 0x%x is truncated\n", charcode ));
3859 }
3860 if ( variantSelector > 0xFFFFFFFFUL )
3861 {
3862 FT_TRACE1(( "FT_Face_GetCharVariantIndex:"
3863 " too large variantSelector" ));
3864 FT_TRACE1(( " 0x%x is truncated\n", variantSelector ));
3865 }
3866
3867 result = vcmap->clazz->char_var_index( vcmap, ucmap,
3868 (FT_UInt32)charcode,
3869 (FT_UInt32)variantSelector );
3870 }
3871 }
3872
3873 return result;
3874 }
3875
3876
3877 /* documentation is in freetype.h */
3878
3881 FT_ULong charcode,
3882 FT_ULong variantSelector )
3883 {
3884 FT_Int result = -1;
3885
3886
3887 if ( face )
3888 {
3890
3891
3892 if ( charmap )
3893 {
3894 FT_CMap vcmap = FT_CMAP( charmap );
3895
3896
3897 if ( charcode > 0xFFFFFFFFUL )
3898 {
3899 FT_TRACE1(( "FT_Face_GetCharVariantIsDefault:"
3900 " too large charcode" ));
3901 FT_TRACE1(( " 0x%x is truncated\n", charcode ));
3902 }
3903 if ( variantSelector > 0xFFFFFFFFUL )
3904 {
3905 FT_TRACE1(( "FT_Face_GetCharVariantIsDefault:"
3906 " too large variantSelector" ));
3907 FT_TRACE1(( " 0x%x is truncated\n", variantSelector ));
3908 }
3909
3910 result = vcmap->clazz->char_var_default( vcmap,
3911 (FT_UInt32)charcode,
3912 (FT_UInt32)variantSelector );
3913 }
3914 }
3915
3916 return result;
3917 }
3918
3919
3920 /* documentation is in freetype.h */
3921
3922 FT_EXPORT_DEF( FT_UInt32* )
3924 {
3925 FT_UInt32 *result = NULL;
3926
3927
3928 if ( face )
3929 {
3931
3932
3933 if ( charmap )
3934 {
3935 FT_CMap vcmap = FT_CMAP( charmap );
3937
3938
3939 result = vcmap->clazz->variant_list( vcmap, memory );
3940 }
3941 }
3942
3943 return result;
3944 }
3945
3946
3947 /* documentation is in freetype.h */
3948
3949 FT_EXPORT_DEF( FT_UInt32* )
3951 FT_ULong charcode )
3952 {
3953 FT_UInt32 *result = NULL;
3954
3955
3956 if ( face )
3957 {
3959
3960
3961 if ( charmap )
3962 {
3963 FT_CMap vcmap = FT_CMAP( charmap );
3965
3966
3967 if ( charcode > 0xFFFFFFFFUL )
3968 {
3969 FT_TRACE1(( "FT_Face_GetVariantsOfChar: too large charcode" ));
3970 FT_TRACE1(( " 0x%x is truncated\n", charcode ));
3971 }
3972
3973 result = vcmap->clazz->charvariant_list( vcmap, memory,
3974 (FT_UInt32)charcode );
3975 }
3976 }
3977 return result;
3978 }
3979
3980
3981 /* documentation is in freetype.h */
3982
3983 FT_EXPORT_DEF( FT_UInt32* )
3985 FT_ULong variantSelector )
3986 {
3987 FT_UInt32 *result = NULL;
3988
3989
3990 if ( face )
3991 {
3993
3994
3995 if ( charmap )
3996 {
3997 FT_CMap vcmap = FT_CMAP( charmap );
3999
4000
4001 if ( variantSelector > 0xFFFFFFFFUL )
4002 {
4003 FT_TRACE1(( "FT_Get_Char_Index: too large variantSelector" ));
4004 FT_TRACE1(( " 0x%x is truncated\n", variantSelector ));
4005 }
4006
4007 result = vcmap->clazz->variantchar_list( vcmap, memory,
4008 (FT_UInt32)variantSelector );
4009 }
4010 }
4011
4012 return result;
4013 }
4014
4015
4016 /* documentation is in freetype.h */
4017
4020 FT_String* glyph_name )
4021 {
4022 FT_UInt result = 0;
4023
4024
4025 if ( face &&
4027 glyph_name )
4028 {
4029 FT_Service_GlyphDict service;
4030
4031
4033 service,
4034 GLYPH_DICT );
4035
4036 if ( service && service->name_index )
4037 result = service->name_index( face, glyph_name );
4038 }
4039
4040 return result;
4041 }
4042
4043
4044 /* documentation is in freetype.h */
4045
4048 FT_UInt glyph_index,
4050 FT_UInt buffer_max )
4051 {
4053 FT_Service_GlyphDict service;
4054
4055
4056 if ( !face )
4057 return FT_THROW( Invalid_Face_Handle );
4058
4059 if ( !buffer || buffer_max == 0 )
4060 return FT_THROW( Invalid_Argument );
4061
4062 /* clean up buffer */
4063 ((FT_Byte*)buffer)[0] = '\0';
4064
4065 if ( (FT_Long)glyph_index >= face->num_glyphs )
4066 return FT_THROW( Invalid_Glyph_Index );
4067
4068 if ( !FT_HAS_GLYPH_NAMES( face ) )
4069 return FT_THROW( Invalid_Argument );
4070
4071 FT_FACE_LOOKUP_SERVICE( face, service, GLYPH_DICT );
4072 if ( service && service->get_name )
4073 error = service->get_name( face, glyph_index, buffer, buffer_max );
4074 else
4075 error = FT_THROW( Invalid_Argument );
4076
4077 return error;
4078 }
4079
4080
4081 /* documentation is in freetype.h */
4082
4083 FT_EXPORT_DEF( const char* )
4085 {
4086 const char* result = NULL;
4087
4088
4089 if ( !face )
4090 goto Exit;
4091
4092 if ( !result )
4093 {
4094 FT_Service_PsFontName service;
4095
4096
4098 service,
4099 POSTSCRIPT_FONT_NAME );
4100
4101 if ( service && service->get_ps_font_name )
4102 result = service->get_ps_font_name( face );
4103 }
4104
4105 Exit:
4106 return result;
4107 }
4108
4109
4110 /* documentation is in tttables.h */
4111
4112 FT_EXPORT_DEF( void* )
4115 {
4116 void* table = NULL;
4117 FT_Service_SFNT_Table service;
4118
4119
4120 if ( face && FT_IS_SFNT( face ) )
4121 {
4122 FT_FACE_FIND_SERVICE( face, service, SFNT_TABLE );
4123 if ( service )
4124 table = service->get_table( face, tag );
4125 }
4126
4127 return table;
4128 }
4129
4130
4131 /* documentation is in tttables.h */
4132
4135 FT_ULong tag,
4137 FT_Byte* buffer,
4138 FT_ULong* length )
4139 {
4140 FT_Service_SFNT_Table service;
4141
4142
4143 if ( !face || !FT_IS_SFNT( face ) )
4144 return FT_THROW( Invalid_Face_Handle );
4145
4146 FT_FACE_FIND_SERVICE( face, service, SFNT_TABLE );
4147 if ( !service )
4148 return FT_THROW( Unimplemented_Feature );
4149
4150 return service->load_table( face, tag, offset, buffer, length );
4151 }
4152
4153
4154 /* documentation is in tttables.h */
4155
4158 FT_UInt table_index,
4159 FT_ULong *tag,
4160 FT_ULong *length )
4161 {
4162 FT_Service_SFNT_Table service;
4164
4165
4166 /* test for valid `length' delayed to `service->table_info' */
4167
4168 if ( !face || !FT_IS_SFNT( face ) )
4169 return FT_THROW( Invalid_Face_Handle );
4170
4171 FT_FACE_FIND_SERVICE( face, service, SFNT_TABLE );
4172 if ( !service )
4173 return FT_THROW( Unimplemented_Feature );
4174
4175 return service->table_info( face, table_index, tag, &offset, length );
4176 }
4177
4178
4179 /* documentation is in tttables.h */
4180
4183 {
4184 FT_Service_TTCMaps service;
4185 FT_Face face;
4187
4188
4189 if ( !charmap || !charmap->face )
4190 return 0;
4191
4192 face = charmap->face;
4193 FT_FACE_FIND_SERVICE( face, service, TT_CMAP );
4194 if ( !service )
4195 return 0;
4196 if ( service->get_cmap_info( charmap, &cmap_info ))
4197 return 0;
4198
4199 return cmap_info.language;
4200 }
4201
4202
4203 /* documentation is in tttables.h */
4204
4207 {
4208 FT_Service_TTCMaps service;
4209 FT_Face face;
4211
4212
4213 if ( !charmap || !charmap->face )
4214 return -1;
4215
4216 face = charmap->face;
4217 FT_FACE_FIND_SERVICE( face, service, TT_CMAP );
4218 if ( !service )
4219 return -1;
4220 if ( service->get_cmap_info( charmap, &cmap_info ))
4221 return -1;
4222
4223 return cmap_info.format;
4224 }
4225
4226
4227 /* documentation is in ftsizes.h */
4228
4231 {
4232 FT_Face face;
4233
4234
4235 if ( !size )
4236 return FT_THROW( Invalid_Size_Handle );
4237
4238 face = size->face;
4239 if ( !face || !face->driver )
4240 return FT_THROW( Invalid_Face_Handle );
4241
4242 /* we don't need anything more complex than that; all size objects */
4243 /* are already listed by the face */
4244 face->size = size;
4245
4246 return FT_Err_Ok;
4247 }
4248
4249
4250 /*************************************************************************/
4251 /*************************************************************************/
4252 /*************************************************************************/
4253 /**** ****/
4254 /**** ****/
4255 /**** R E N D E R E R S ****/
4256 /**** ****/
4257 /**** ****/
4258 /*************************************************************************/
4259 /*************************************************************************/
4260 /*************************************************************************/
4261
4262 /* lookup a renderer by glyph format in the library's list */
4266 FT_ListNode* node )
4267 {
4270
4271
4272 if ( !library )
4273 goto Exit;
4274
4276
4277 if ( node )
4278 {
4279 if ( *node )
4280 cur = (*node)->next;
4281 *node = NULL;
4282 }
4283
4284 while ( cur )
4285 {
4286 FT_Renderer renderer = FT_RENDERER( cur->data );
4287
4288
4289 if ( renderer->glyph_format == format )
4290 {
4291 if ( node )
4292 *node = cur;
4293
4294 result = renderer;
4295 break;
4296 }
4297 cur = cur->next;
4298 }
4299
4300 Exit:
4301 return result;
4302 }
4303
4304
4305 static FT_Renderer
4307 {
4308 FT_Face face = slot->face;
4311
4312
4313 if ( !result || result->glyph_format != slot->format )
4314 result = FT_Lookup_Renderer( library, slot->format, 0 );
4315
4316 return result;
4317 }
4318
4319
4320 static void
4322 {
4323 FT_Renderer renderer;
4324
4325
4327 library->cur_renderer = renderer;
4328 }
4329
4330
4331 static FT_Error
4333 {
4334 FT_Library library = module->library;
4338
4339
4340 if ( FT_NEW( node ) )
4341 goto Exit;
4342
4343 {
4345 FT_Renderer_Class* clazz = (FT_Renderer_Class*)module->clazz;
4346
4347
4348 render->clazz = clazz;
4349 render->glyph_format = clazz->glyph_format;
4350
4351 /* allocate raster object if needed */
4353 clazz->raster_class->raster_new )
4354 {
4355 error = clazz->raster_class->raster_new( memory, &render->raster );
4356 if ( error )
4357 goto Fail;
4358
4359 render->raster_render = clazz->raster_class->raster_render;
4360 render->render = clazz->render_glyph;
4361 }
4362
4363 /* add to list */
4364 node->data = module;
4366
4368 }
4369
4370 Fail:
4371 if ( error )
4372 FT_FREE( node );
4373
4374 Exit:
4375 return error;
4376 }
4377
4378
4379 static void
4381 {
4385
4386
4387 library = module->library;
4388 if ( !library )
4389 return;
4390
4392
4394 if ( node )
4395 {
4397
4398
4399 /* release raster object, if any */
4400 if ( render->clazz->glyph_format == FT_GLYPH_FORMAT_OUTLINE &&
4401 render->raster )
4402 render->clazz->raster_class->raster_done( render->raster );
4403
4404 /* remove from list */
4406 FT_FREE( node );
4407
4409 }
4410 }
4411
4412
4413 /* documentation is in ftrender.h */
4414
4418 {
4419 /* test for valid `library' delayed to `FT_Lookup_Renderer' */
4420
4421 return FT_Lookup_Renderer( library, format, 0 );
4422 }
4423
4424
4425 /* documentation is in ftrender.h */
4426
4429 FT_Renderer renderer,
4430 FT_UInt num_params,
4431 FT_Parameter* parameters )
4432 {
4435
4436 FT_Renderer_SetModeFunc set_mode;
4437
4438
4439 if ( !library )
4440 {
4441 error = FT_THROW( Invalid_Library_Handle );
4442 goto Exit;
4443 }
4444
4445 if ( !renderer )
4446 {
4447 error = FT_THROW( Invalid_Argument );
4448 goto Exit;
4449 }
4450
4451 if ( num_params > 0 && !parameters )
4452 {
4453 error = FT_THROW( Invalid_Argument );
4454 goto Exit;
4455 }
4456
4457 node = FT_List_Find( &library->renderers, renderer );
4458 if ( !node )
4459 {
4460 error = FT_THROW( Invalid_Argument );
4461 goto Exit;
4462 }
4463
4465
4466 if ( renderer->glyph_format == FT_GLYPH_FORMAT_OUTLINE )
4467 library->cur_renderer = renderer;
4468
4469 set_mode = renderer->clazz->set_mode;
4470
4471 for ( ; num_params > 0; num_params-- )
4472 {
4473 error = set_mode( renderer, parameters->tag, parameters->data );
4474 if ( error )
4475 break;
4476 parameters++;
4477 }
4478
4479 Exit:
4480 return error;
4481 }
4482
4483
4487 FT_Render_Mode render_mode )
4488 {
4490 FT_Renderer renderer;
4491
4492
4493 /* if it is already a bitmap, no need to do anything */
4494 switch ( slot->format )
4495 {
4496 case FT_GLYPH_FORMAT_BITMAP: /* already a bitmap, don't do anything */
4497 break;
4498
4499 default:
4500 {
4502
4503
4504 /* small shortcut for the very common case */
4505 if ( slot->format == FT_GLYPH_FORMAT_OUTLINE )
4506 {
4507 renderer = library->cur_renderer;
4509 }
4510 else
4511 renderer = FT_Lookup_Renderer( library, slot->format, &node );
4512
4513 error = FT_ERR( Unimplemented_Feature );
4514 while ( renderer )
4515 {
4516 error = renderer->render( renderer, slot, render_mode, NULL );
4517 if ( !error ||
4518 FT_ERR_NEQ( error, Cannot_Render_Glyph ) )
4519 break;
4520
4521 /* FT_Err_Cannot_Render_Glyph is returned if the render mode */
4522 /* is unsupported by the current renderer for this glyph image */
4523 /* format. */
4524
4525 /* now, look for another renderer that supports the same */
4526 /* format. */
4527 renderer = FT_Lookup_Renderer( library, slot->format, &node );
4528 }
4529 }
4530 }
4531
4532#ifdef FT_DEBUG_LEVEL_TRACE
4533
4534#undef FT_COMPONENT
4535#define FT_COMPONENT trace_bitmap
4536
4537 /*
4538 * Computing the MD5 checksum is expensive, unnecessarily distorting a
4539 * possible profiling of FreeType if compiled with tracing support. For
4540 * this reason, we execute the following code only if explicitly
4541 * requested.
4542 */
4543
4544 /* we use FT_TRACE3 in this block */
4545 if ( !error &&
4546 ft_trace_levels[trace_bitmap] >= 3 &&
4547 slot->bitmap.buffer )
4548 {
4550 FT_Error err;
4551
4552
4554
4555 /* we convert to a single bitmap format for computing the checksum */
4556 /* this also converts the bitmap flow to `down' (i.e., pitch > 0) */
4557 err = FT_Bitmap_Convert( library, &slot->bitmap, &bitmap, 1 );
4558 if ( !err )
4559 {
4560 MD5_CTX ctx;
4561 unsigned char md5[16];
4562 unsigned long coverage = 0;
4563 int i, j;
4564 int rows = (int)bitmap.rows;
4565 int pitch = bitmap.pitch;
4566
4567
4568 FT_TRACE3(( "FT_Render_Glyph: bitmap %dx%d, mode %d\n",
4569 rows, pitch, slot->bitmap.pixel_mode ));
4570
4571 for ( i = 0; i < rows; i++ )
4572 for ( j = 0; j < pitch; j++ )
4573 coverage += bitmap.buffer[i * pitch + j];
4574
4575 FT_TRACE3(( " Total coverage: %lu\n", coverage ));
4576
4577 MD5_Init( &ctx );
4578 if ( bitmap.buffer )
4579 MD5_Update( &ctx, bitmap.buffer,
4580 (unsigned long)rows * (unsigned long)pitch );
4581 MD5_Final( md5, &ctx );
4582
4583 FT_TRACE3(( " MD5 checksum: " ));
4584 for ( i = 0; i < 16; i++ )
4585 FT_TRACE3(( "%02X", md5[i] ));
4586 FT_TRACE3(( "\n" ));
4587 }
4588
4590 }
4591
4592 /*
4593 * Dump bitmap in Netpbm format (PBM or PGM).
4594 */
4595
4596 /* we use FT_TRACE7 in this block */
4597 if ( !error &&
4598 ft_trace_levels[trace_bitmap] >= 7 &&
4599 slot->bitmap.rows < 128U &&
4600 slot->bitmap.width < 128U &&
4601 slot->bitmap.buffer )
4602 {
4603 int rows = (int)slot->bitmap.rows;
4604 int width = (int)slot->bitmap.width;
4605 int pitch = slot->bitmap.pitch;
4606 int i, j, m;
4607 unsigned char* topleft = slot->bitmap.buffer;
4608
4609 if ( pitch < 0 )
4610 topleft -= pitch * ( rows - 1 );
4611
4612 FT_TRACE7(( "Netpbm image: start\n" ));
4613 switch ( slot->bitmap.pixel_mode )
4614 {
4615 case FT_PIXEL_MODE_MONO:
4616 FT_TRACE7(( "P1 %d %d\n", width, rows ));
4617 for ( i = 0; i < rows; i++ )
4618 {
4619 for ( j = 0; j < width; )
4620 for ( m = 128; m > 0 && j < width; m >>= 1, j++ )
4621 FT_TRACE7(( " %d", ( topleft[i * pitch + j / 8] & m ) != 0 ));
4622 FT_TRACE7(( "\n" ));
4623 }
4624 break;
4625
4626 default:
4627 FT_TRACE7(( "P2 %d %d 255\n", width, rows ));
4628 for ( i = 0; i < rows; i++ )
4629 {
4630 for ( j = 0; j < width; j += 1 )
4631 FT_TRACE7(( " %3u", topleft[i * pitch + j] ));
4632 FT_TRACE7(( "\n" ));
4633 }
4634 }
4635 FT_TRACE7(( "Netpbm image: end\n" ));
4636 }
4637
4638#undef FT_COMPONENT
4639#define FT_COMPONENT trace_objs
4640
4641#endif /* FT_DEBUG_LEVEL_TRACE */
4642
4643 return error;
4644 }
4645
4646
4647 /* documentation is in freetype.h */
4648
4651 FT_Render_Mode render_mode )
4652 {
4654
4655
4656 if ( !slot || !slot->face )
4657 return FT_THROW( Invalid_Argument );
4658
4659 library = FT_FACE_LIBRARY( slot->face );
4660
4661 return FT_Render_Glyph_Internal( library, slot, render_mode );
4662 }
4663
4664
4665 /*************************************************************************/
4666 /*************************************************************************/
4667 /*************************************************************************/
4668 /**** ****/
4669 /**** ****/
4670 /**** M O D U L E S ****/
4671 /**** ****/
4672 /**** ****/
4673 /*************************************************************************/
4674 /*************************************************************************/
4675 /*************************************************************************/
4676
4677
4678 /*************************************************************************/
4679 /* */
4680 /* <Function> */
4681 /* Destroy_Module */
4682 /* */
4683 /* <Description> */
4684 /* Destroys a given module object. For drivers, this also destroys */
4685 /* all child faces. */
4686 /* */
4687 /* <InOut> */
4688 /* module :: A handle to the target driver object. */
4689 /* */
4690 /* <Note> */
4691 /* The driver _must_ be LOCKED! */
4692 /* */
4693 static void
4695 {
4696 FT_Memory memory = module->memory;
4697 FT_Module_Class* clazz = module->clazz;
4698 FT_Library library = module->library;
4699
4700
4701 if ( library && library->auto_hinter == module )
4703
4704 /* if the module is a renderer */
4707
4708 /* if the module is a font driver, add some steps */
4709 if ( FT_MODULE_IS_DRIVER( module ) )
4711
4712 /* finalize the module object */
4713 if ( clazz->module_done )
4714 clazz->module_done( module );
4715
4716 /* discard it */
4717 FT_FREE( module );
4718 }
4719
4720
4721 /* documentation is in ftmodapi.h */
4722
4725 const FT_Module_Class* clazz )
4726 {
4730 FT_UInt nn;
4731
4732
4733#define FREETYPE_VER_FIXED ( ( (FT_Long)FREETYPE_MAJOR << 16 ) | \
4734 FREETYPE_MINOR )
4735
4736 if ( !library )
4737 return FT_THROW( Invalid_Library_Handle );
4738
4739 if ( !clazz )
4740 return FT_THROW( Invalid_Argument );
4741
4742 /* check FreeType version */
4743 if ( clazz->module_requires > FREETYPE_VER_FIXED )
4744 return FT_THROW( Invalid_Version );
4745
4746 /* look for a module with the same name in the library's table */
4747 for ( nn = 0; nn < library->num_modules; nn++ )
4748 {
4749 module = library->modules[nn];
4750 if ( ft_strcmp( module->clazz->module_name, clazz->module_name ) == 0 )
4751 {
4752 /* this installed module has the same name, compare their versions */
4753 if ( clazz->module_version <= module->clazz->module_version )
4754 return FT_THROW( Lower_Module_Version );
4755
4756 /* remove the module from our list, then exit the loop to replace */
4757 /* it by our new version.. */
4759 break;
4760 }
4761 }
4762
4764 error = FT_Err_Ok;
4765
4767 {
4768 error = FT_THROW( Too_Many_Drivers );
4769 goto Exit;
4770 }
4771
4772 /* allocate module object */
4773 if ( FT_ALLOC( module, clazz->module_size ) )
4774 goto Exit;
4775
4776 /* base initialization */
4777 module->library = library;
4778 module->memory = memory;
4779 module->clazz = (FT_Module_Class*)clazz;
4780
4781 /* check whether the module is a renderer - this must be performed */
4782 /* before the normal module initialization */
4784 {
4785 /* add to the renderers list */
4787 if ( error )
4788 goto Fail;
4789 }
4790
4791 /* is the module a auto-hinter? */
4792 if ( FT_MODULE_IS_HINTER( module ) )
4794
4795 /* if the module is a font driver */
4796 if ( FT_MODULE_IS_DRIVER( module ) )
4797 {
4799
4800
4801 driver->clazz = (FT_Driver_Class)module->clazz;
4802 }
4803
4804 if ( clazz->module_init )
4805 {
4806 error = clazz->module_init( module );
4807 if ( error )
4808 goto Fail;
4809 }
4810
4811 /* add module to the library's table */
4813
4814 Exit:
4815 return error;
4816
4817 Fail:
4819 {
4820 FT_Renderer renderer = FT_RENDERER( module );
4821
4822
4823 if ( renderer->clazz &&
4825 renderer->raster )
4826 renderer->clazz->raster_class->raster_done( renderer->raster );
4827 }
4828
4829 FT_FREE( module );
4830 goto Exit;
4831 }
4832
4833
4834 /* documentation is in ftmodapi.h */
4835
4838 const char* module_name )
4839 {
4841 FT_Module* cur;
4843
4844
4845 if ( !library || !module_name )
4846 return result;
4847
4848 cur = library->modules;
4850
4851 for ( ; cur < limit; cur++ )
4852 if ( ft_strcmp( cur[0]->clazz->module_name, module_name ) == 0 )
4853 {
4854 result = cur[0];
4855 break;
4856 }
4857
4858 return result;
4859 }
4860
4861
4862 /* documentation is in ftobjs.h */
4863
4864 FT_BASE_DEF( const void* )
4866 const char* mod_name )
4867 {
4869
4870
4871 /* test for valid `library' delayed to FT_Get_Module() */
4872
4873 module = FT_Get_Module( library, mod_name );
4874
4875 return module ? module->clazz->module_interface : 0;
4876 }
4877
4878
4881 const char* service_id,
4882 FT_Bool global )
4883 {
4885
4886
4887 if ( module )
4888 {
4889 FT_ASSERT( module->clazz && module->clazz->get_interface );
4890
4891 /* first, look for the service in the module */
4892 if ( module->clazz->get_interface )
4893 result = module->clazz->get_interface( module, service_id );
4894
4895 if ( global && !result )
4896 {
4897 /* we didn't find it, look in all other modules then */
4898 FT_Library library = module->library;
4901
4902
4903 for ( ; cur < limit; cur++ )
4904 {
4905 if ( cur[0] != module )
4906 {
4907 FT_ASSERT( cur[0]->clazz );
4908
4909 if ( cur[0]->clazz->get_interface )
4910 {
4911 result = cur[0]->clazz->get_interface( cur[0], service_id );
4912 if ( result )
4913 break;
4914 }
4915 }
4916 }
4917 }
4918 }
4919
4920 return result;
4921 }
4922
4923
4924 /* documentation is in ftmodapi.h */
4925
4929 {
4930 /* try to find the module from the table, then remove it from there */
4931
4932 if ( !library )
4933 return FT_THROW( Invalid_Library_Handle );
4934
4935 if ( module )
4936 {
4939
4940
4941 for ( ; cur < limit; cur++ )
4942 {
4943 if ( cur[0] == module )
4944 {
4945 /* remove it from the table */
4947 limit--;
4948 while ( cur < limit )
4949 {
4950 cur[0] = cur[1];
4951 cur++;
4952 }
4953 limit[0] = NULL;
4954
4955 /* destroy the module */
4957
4958 return FT_Err_Ok;
4959 }
4960 }
4961 }
4962 return FT_THROW( Invalid_Driver_Handle );
4963 }
4964
4965
4966 static FT_Error
4968 const FT_String* module_name,
4969 const FT_String* property_name,
4970 void* value,
4971 FT_Bool set,
4972 FT_Bool value_is_string )
4973 {
4974 FT_Module* cur;
4977
4978 FT_Service_Properties service;
4979
4980#ifdef FT_DEBUG_LEVEL_ERROR
4981 const FT_String* set_name = "FT_Property_Set";
4982 const FT_String* get_name = "FT_Property_Get";
4984#endif
4985
4986 FT_Bool missing_func;
4987
4988
4989 if ( !library )
4990 return FT_THROW( Invalid_Library_Handle );
4991
4992 if ( !module_name || !property_name || !value )
4993 return FT_THROW( Invalid_Argument );
4994
4995 cur = library->modules;
4997
4998 /* search module */
4999 for ( ; cur < limit; cur++ )
5000 if ( !ft_strcmp( cur[0]->clazz->module_name, module_name ) )
5001 break;
5002
5003 if ( cur == limit )
5004 {
5005 FT_ERROR(( "%s: can't find module `%s'\n",
5007 return FT_THROW( Missing_Module );
5008 }
5009
5010 /* check whether we have a service interface */
5011 if ( !cur[0]->clazz->get_interface )
5012 {
5013 FT_ERROR(( "%s: module `%s' doesn't support properties\n",
5015 return FT_THROW( Unimplemented_Feature );
5016 }
5017
5018 /* search property service */
5019 interface = cur[0]->clazz->get_interface( cur[0],
5021 if ( !interface )
5022 {
5023 FT_ERROR(( "%s: module `%s' doesn't support properties\n",
5025 return FT_THROW( Unimplemented_Feature );
5026 }
5027
5028 service = (FT_Service_Properties)interface;
5029
5030 if ( set )
5031 missing_func = (FT_Bool)( !service->set_property );
5032 else
5033 missing_func = (FT_Bool)( !service->get_property );
5034
5035 if ( missing_func )
5036 {
5037 FT_ERROR(( "%s: property service of module `%s' is broken\n",
5039 return FT_THROW( Unimplemented_Feature );
5040 }
5041
5042 return set ? service->set_property( cur[0],
5043 property_name,
5044 value,
5045 value_is_string )
5046 : service->get_property( cur[0],
5047 property_name,
5048 value );
5049 }
5050
5051
5052 /* documentation is in ftmodapi.h */
5053
5057 const FT_String* property_name,
5058 const void* value )
5059 {
5060 return ft_property_do( library,
5062 property_name,
5063 (void*)value,
5064 TRUE,
5065 FALSE );
5066 }
5067
5068
5069 /* documentation is in ftmodapi.h */
5070
5074 const FT_String* property_name,
5075 void* value )
5076 {
5077 return ft_property_do( library,
5079 property_name,
5080 value,
5081 FALSE,
5082 FALSE );
5083 }
5084
5085
5086#ifdef FT_CONFIG_OPTION_ENVIRONMENT_PROPERTIES
5087
5088 /* this variant is used for handling the FREETYPE_PROPERTIES */
5089 /* environment variable */
5090
5092 ft_property_string_set( FT_Library library,
5093 const FT_String* module_name,
5094 const FT_String* property_name,
5095 FT_String* value )
5096 {
5097 return ft_property_do( library,
5099 property_name,
5100 (void*)value,
5101 TRUE,
5102 TRUE );
5103 }
5104
5105#endif
5106
5107
5108 /*************************************************************************/
5109 /*************************************************************************/
5110 /*************************************************************************/
5111 /**** ****/
5112 /**** ****/
5113 /**** L I B R A R Y ****/
5114 /**** ****/
5115 /**** ****/
5116 /*************************************************************************/
5117 /*************************************************************************/
5118 /*************************************************************************/
5119
5120
5121 /* documentation is in ftmodapi.h */
5122
5125 {
5126 if ( !library )
5127 return FT_THROW( Invalid_Library_Handle );
5128
5129 library->refcount++;
5130
5131 return FT_Err_Ok;
5132 }
5133
5134
5135 /* documentation is in ftmodapi.h */
5136
5139 FT_Library *alibrary )
5140 {
5143
5144
5145 if ( !memory || !alibrary )
5146 return FT_THROW( Invalid_Argument );
5147
5148#ifdef FT_DEBUG_LEVEL_ERROR
5149 /* init debugging support */
5150 ft_debug_init();
5151#endif
5152
5153 /* first of all, allocate the library object */
5154 if ( FT_NEW( library ) )
5155 return error;
5156
5158
5159#ifdef FT_CONFIG_OPTION_PIC
5160 /* initialize position independent code containers */
5161 error = ft_pic_container_init( library );
5162 if ( error )
5163 goto Fail;
5164#endif
5165
5169
5170 library->refcount = 1;
5171
5172 /* That's ok now */
5173 *alibrary = library;
5174
5175 return FT_Err_Ok;
5176
5177#ifdef FT_CONFIG_OPTION_PIC
5178 Fail:
5179 ft_pic_container_destroy( library );
5180 FT_FREE( library );
5181 return error;
5182#endif
5183 }
5184
5185
5186 /* documentation is in freetype.h */
5187
5188 FT_EXPORT_DEF( void )
5190 FT_Int *amajor,
5191 FT_Int *aminor,
5192 FT_Int *apatch )
5193 {
5194 FT_Int major = 0;
5195 FT_Int minor = 0;
5196 FT_Int patch = 0;
5197
5198
5199 if ( library )
5200 {
5203 patch = library->version_patch;
5204 }
5205
5206 if ( amajor )
5207 *amajor = major;
5208
5209 if ( aminor )
5210 *aminor = minor;
5211
5212 if ( apatch )
5213 *apatch = patch;
5214 }
5215
5216
5217 /* documentation is in ftmodapi.h */
5218
5221 {
5223
5224
5225 if ( !library )
5226 return FT_THROW( Invalid_Library_Handle );
5227
5228 library->refcount--;
5229 if ( library->refcount > 0 )
5230 goto Exit;
5231
5233
5234 /*
5235 * Close all faces in the library. If we don't do this, we can have
5236 * some subtle memory leaks.
5237 *
5238 * Example:
5239 *
5240 * - the cff font driver uses the pshinter module in cff_size_done
5241 * - if the pshinter module is destroyed before the cff font driver,
5242 * opened FT_Face objects managed by the driver are not properly
5243 * destroyed, resulting in a memory leak
5244 *
5245 * Some faces are dependent on other faces, like Type42 faces that
5246 * depend on TrueType faces synthesized internally.
5247 *
5248 * The order of drivers should be specified in driver_name[].
5249 */
5250 {
5251 FT_UInt m, n;
5252 const char* driver_name[] = { "type42", NULL };
5253
5254
5255 for ( m = 0;
5256 m < sizeof ( driver_name ) / sizeof ( driver_name[0] );
5257 m++ )
5258 {
5259 for ( n = 0; n < library->num_modules; n++ )
5260 {
5262 const char* module_name = module->clazz->module_name;
5263 FT_List faces;
5264
5265
5266 if ( driver_name[m] &&
5267 ft_strcmp( module_name, driver_name[m] ) != 0 )
5268 continue;
5269
5270 if ( ( module->clazz->module_flags & FT_MODULE_FONT_DRIVER ) == 0 )
5271 continue;
5272
5273 FT_TRACE7(( "FT_Done_Library: close faces for %s\n", module_name ));
5274
5275 faces = &FT_DRIVER( module )->faces_list;
5276 while ( faces->head )
5277 {
5278 FT_Done_Face( FT_FACE( faces->head->data ) );
5279 if ( faces->head )
5280 FT_TRACE0(( "FT_Done_Library: failed to free some faces\n" ));
5281 }
5282 }
5283 }
5284 }
5285
5286 /* Close all other modules in the library */
5287#if 1
5288 /* XXX Modules are removed in the reversed order so that */
5289 /* type42 module is removed before truetype module. This */
5290 /* avoids double free in some occasions. It is a hack. */
5291 while ( library->num_modules > 0 )
5294#else
5295 {
5296 FT_UInt n;
5297
5298
5299 for ( n = 0; n < library->num_modules; n++ )
5300 {
5302
5303
5304 if ( module )
5305 {
5307 library->modules[n] = NULL;
5308 }
5309 }
5310 }
5311#endif
5312
5313#ifdef FT_CONFIG_OPTION_PIC
5314 /* Destroy pic container contents */
5315 ft_pic_container_destroy( library );
5316#endif
5317
5318 FT_FREE( library );
5319
5320 Exit:
5321 return FT_Err_Ok;
5322 }
5323
5324
5325 /* documentation is in ftmodapi.h */
5326
5327 FT_EXPORT_DEF( void )
5329 FT_UInt hook_index,
5330 FT_DebugHook_Func debug_hook )
5331 {
5332 if ( library && debug_hook &&
5333 hook_index <
5334 ( sizeof ( library->debug_hooks ) / sizeof ( void* ) ) )
5335 library->debug_hooks[hook_index] = debug_hook;
5336 }
5337
5338
5339 /* documentation is in ftmodapi.h */
5340
5343 {
5345
5346
5347 if ( library )
5348 {
5349 FT_Module module = FT_Get_Module( library, "truetype" );
5350
5351
5352 if ( module )
5353 {
5354 FT_Service_TrueTypeEngine service;
5355
5356
5357 service = (FT_Service_TrueTypeEngine)
5360 0 );
5361 if ( service )
5362 result = service->engine_type;
5363 }
5364 }
5365
5366 return result;
5367 }
5368
5369
5370 /* documentation is in freetype.h */
5371
5374 FT_UInt sub_index,
5375 FT_Int *p_index,
5376 FT_UInt *p_flags,
5377 FT_Int *p_arg1,
5378 FT_Int *p_arg2,
5379 FT_Matrix *p_transform )
5380 {
5381 FT_Error error = FT_ERR( Invalid_Argument );
5382
5383
5384 if ( glyph &&
5385 glyph->subglyphs &&
5386 glyph->format == FT_GLYPH_FORMAT_COMPOSITE &&
5387 sub_index < glyph->num_subglyphs )
5388 {
5389 FT_SubGlyph subg = glyph->subglyphs + sub_index;
5390
5391
5392 *p_index = subg->index;
5393 *p_flags = subg->flags;
5394 *p_arg1 = subg->arg1;
5395 *p_arg2 = subg->arg2;
5396 *p_transform = subg->transform;
5397
5398 error = FT_Err_Ok;
5399 }
5400
5401 return error;
5402 }
5403
5404
5405/* END */
ios_base &_STLP_CALL internal(ios_base &__s)
Definition: _ios_base.h:311
_STLP_MOVE_TO_STD_NAMESPACE void _STLP_CALL advance(_InputIterator &__i, _Distance __n)
#define open
Definition: acwin.h:95
#define close
Definition: acwin.h:98
struct FT_AutoHinter_InterfaceRec_ * FT_AutoHinter_Interface
typedefFT_BEGIN_HEADER struct FT_AutoHinterRec_ * FT_AutoHinter
Definition: autohint.h:80
int get_name(unsigned char **pos, uint32_t *remaining, const char **out_name)
Definition: util.c:55
#define interface
Definition: basetyps.h:61
FT_Library library
Definition: cffdrivr.c:654
TT_CMapInfo * cmap_info
Definition: cffdrivr.c:649
Definition: _set.h:50
#define md5
Definition: compat-1.3.h:2034
static LPCWSTR LPCWSTR module_name
Definition: db.cpp:170
#define FT_MAX_MODULES
Definition: ftoption.h:376
#define NULL
Definition: types.h:112
#define TRUE
Definition: types.h:120
#define FALSE
Definition: types.h:117
WORD face[3]
Definition: mesh.c:4747
#define TT_PLATFORM_MICROSOFT
Definition: font.c:1174
#define TT_PLATFORM_APPLE_UNICODE
Definition: font.c:1172
unsigned int(__cdecl typeof(jpeg_read_scanlines))(struct jpeg_decompress_struct *
Definition: typeof.h:31
unsigned char
Definition: typeof.h:29
int global
Definition: ehframes.cpp:22
int Fail
Definition: ehthrow.cxx:24
@ Success
Definition: eventcreate.c:712
#define FT_LOAD_RENDER
Definition: freetype.h:3011
#define FT_LOAD_VERTICAL_LAYOUT
Definition: freetype.h:3013
#define FT_LOAD_TARGET_MODE(x)
Definition: freetype.h:3137
FT_BEGIN_HEADER struct FT_Glyph_Metrics_ FT_Glyph_Metrics
#define FT_LOAD_SBITS_ONLY
Definition: freetype.h:3032
#define FT_LOAD_NO_BITMAP
Definition: freetype.h:3012
FT_Vector_Transform(FT_Vector *vec, const FT_Matrix *matrix)
Definition: ftoutln.c:688
#define FT_IS_SFNT(face)
Definition: freetype.h:1331
#define FT_LOAD_IGNORE_TRANSFORM
Definition: freetype.h:3019
@ FT_SIZE_REQUEST_TYPE_BBOX
Definition: freetype.h:2572
@ FT_SIZE_REQUEST_TYPE_NOMINAL
Definition: freetype.h:2570
@ FT_SIZE_REQUEST_TYPE_REAL_DIM
Definition: freetype.h:2571
@ FT_SIZE_REQUEST_TYPE_SCALES
Definition: freetype.h:2574
@ FT_SIZE_REQUEST_TYPE_MAX
Definition: freetype.h:2576
@ FT_SIZE_REQUEST_TYPE_CELL
Definition: freetype.h:2573
#define FT_LOAD_NO_SCALE
Definition: freetype.h:3009
#define FT_OPEN_PATHNAME
Definition: freetype.h:2036
#define FREETYPE_PATCH
Definition: freetype.h:4555
#define FT_LOAD_NO_RECURSE
Definition: freetype.h:3018
#define FT_LOAD_BITMAP_METRICS_ONLY
Definition: freetype.h:3026
#define FT_OPEN_PARAMS
Definition: freetype.h:2038
enum FT_Render_Mode_ FT_Render_Mode
#define FT_LOAD_NO_HINTING
Definition: freetype.h:3010
FT_DivFix(FT_Long a, FT_Long b)
Definition: ftcalc.c:608
#define FT_OPEN_DRIVER
Definition: freetype.h:2037
#define FT_HAS_FIXED_SIZES(face)
Definition: freetype.h:1361
#define FT_LOAD_FORCE_AUTOHINT
Definition: freetype.h:3014
#define FT_IS_SCALABLE(face)
Definition: freetype.h:1312
#define FT_LOAD_MONOCHROME
Definition: freetype.h:3020
#define FT_HAS_VERTICAL(face)
Definition: freetype.h:1283
struct FT_SizeRec_ * FT_Size
Definition: freetype.h:534
#define FT_OPEN_MEMORY
Definition: freetype.h:2034
#define FT_FACE_FLAG_EXTERNAL_STREAM
Definition: freetype.h:1248
#define FREETYPE_MAJOR
Definition: freetype.h:4553
#define FREETYPE_MINOR
Definition: freetype.h:4554
enum FT_Encoding_ FT_Encoding
#define FT_HAS_GLYPH_NAMES(face)
Definition: freetype.h:1387
#define FT_LOAD_NO_AUTOHINT
Definition: freetype.h:3022
@ FT_RENDER_MODE_MONO
Definition: freetype.h:3236
@ FT_RENDER_MODE_NORMAL
Definition: freetype.h:3234
@ FT_RENDER_MODE_LIGHT
Definition: freetype.h:3235
@ FT_RENDER_MODE_LCD_V
Definition: freetype.h:3238
@ FT_RENDER_MODE_LCD
Definition: freetype.h:3237
#define FT_IS_TRICKY(face)
Definition: freetype.h:1474
#define FT_LOAD_LINEAR_DESIGN
Definition: freetype.h:3021
@ FT_KERNING_UNFITTED
Definition: freetype.h:3390
@ FT_KERNING_UNSCALED
Definition: freetype.h:3391
FT_MulDiv(FT_Long a, FT_Long b, FT_Long c)
Definition: ftcalc.c:416
FT_MulFix(FT_Long a, FT_Long b)
Definition: ftcalc.c:509
#define FT_OPEN_STREAM
Definition: freetype.h:2035
struct FT_CharMapRec_ * FT_CharMap
Definition: freetype.h:588
return FT_Err_Ok
Definition: ftbbox.c:511
FT_Bitmap_Convert(FT_Library library, const FT_Bitmap *source, FT_Bitmap *target, FT_Int alignment)
Definition: ftbitmap.c:504
FT_BEGIN_HEADER FT_Bitmap_Init(FT_Bitmap *abitmap)
Definition: ftbitmap.c:34
FT_Bitmap_Done(FT_Library library, FT_Bitmap *bitmap)
Definition: ftbitmap.c:826
#define SUB_LONG(a, b)
Definition: ftcalc.h:422
#define ADD_LONG(a, b)
Definition: ftcalc.h:420
#define FT_LOCAL_DEF(x)
Definition: ftconfig.h:388
#define FT_UNUSED(arg)
Definition: ftconfig.h:101
#define FT_EXPORT_DEF(x)
Definition: ftconfig.h:483
#define FT_BASE_DEF(x)
Definition: ftconfig.h:419
#define FT_ASSERT(condition)
Definition: ftdebug.h:211
#define FT_TRACE0(varformat)
Definition: ftdebug.h:157
#define FT_ERROR(varformat)
Definition: ftdebug.h:181
#define FT_TRACE5(varformat)
Definition: ftdebug.h:162
#define FT_TRACE7(varformat)
Definition: ftdebug.h:164
#define FT_TRACE3(varformat)
Definition: ftdebug.h:160
#define FT_THROW(e)
Definition: ftdebug.h:213
#define FT_TRACE2(varformat)
Definition: ftdebug.h:159
ft_debug_init(void)
Definition: ftdebug.c:241
#define FT_TRACE1(varformat)
Definition: ftdebug.h:158
#define FT_TRACE4(varformat)
Definition: ftdebug.h:161
#define FT_HINTING_ADOBE
Definition: ftdriver.h:346
struct FT_Driver_ClassRec_ * FT_Driver_Class
FT_BEGIN_HEADER FT_Get_Font_Format(FT_Face face)
Definition: ftfntfmt.c:28
FT_GlyphLoader_Done(FT_GlyphLoader loader)
Definition: ftgloadr.c:128
FT_GlyphLoader_New(FT_Memory memory, FT_GlyphLoader *aloader)
Definition: ftgloadr.c:70
@ FT_PIXEL_MODE_LCD_V
Definition: ftimage.h:188
@ FT_PIXEL_MODE_MONO
Definition: ftimage.h:183
@ FT_PIXEL_MODE_GRAY
Definition: ftimage.h:184
@ FT_PIXEL_MODE_LCD
Definition: ftimage.h:187
enum FT_Glyph_Format_ FT_Glyph_Format
enum FT_Pixel_Mode_ FT_Pixel_Mode
FT_BEGIN_HEADER typedef signed long FT_Pos
Definition: ftimage.h:58
FT_Incremental_InterfaceRec * FT_Incremental_Interface
Definition: ftincrem.h:332
#define FT_LCD_FILTER_FIVE_TAPS
Definition: ftlcdfil.h:296
FT_List_Up(FT_List list, FT_ListNode node)
Definition: ftutil.c:348
void(* FT_List_Destructor)(FT_Memory memory, void *data, void *user)
Definition: ftlist.h:234
FT_List_Finalize(FT_List list, FT_List_Destructor destroy, FT_Memory memory, void *user)
Definition: ftutil.c:413
FT_List_Remove(FT_List list, FT_ListNode node)
Definition: ftutil.c:321
FT_BEGIN_HEADER FT_List_Find(FT_List list, void *data)
Definition: ftutil.c:244
FT_List_Add(FT_List list, FT_ListNode node)
Definition: ftutil.c:269
#define FT_NEW(ptr)
Definition: ftmemory.h:331
#define FT_ALLOC(ptr, size)
Definition: ftmemory.h:303
#define FT_FREE(ptr)
Definition: ftmemory.h:329
#define FT_ZERO(p)
Definition: ftmemory.h:237
#define FT_RENEW_ARRAY(ptr, curcnt, newcnt)
Definition: ftmemory.h:336
#define FT_MODULE_FONT_DRIVER
Definition: ftmodapi.h:110
@ FT_TRUETYPE_ENGINE_TYPE_NONE
Definition: ftmodapi.h:673
enum FT_TrueTypeEngineType_ FT_TrueTypeEngineType
void(* FT_DebugHook_Func)(void *arg)
Definition: ftmodapi.h:573
FT_Load_Glyph(FT_Face face, FT_UInt glyph_index, FT_Int32 load_flags)
Definition: ftobjs.c:760
static void destroy_charmaps(FT_Face face, FT_Memory memory)
Definition: ftobjs.c:1079
FT_Remove_Module(FT_Library library, FT_Module module)
Definition: ftobjs.c:4927
static FT_Error ft_add_renderer(FT_Module module)
Definition: ftobjs.c:4332
FT_Get_Next_Char(FT_Face face, FT_ULong charcode, FT_UInt *agindex)
Definition: ftobjs.c:3722
FT_Get_Sfnt_Table(FT_Face face, FT_Sfnt_Tag tag)
Definition: ftobjs.c:4113
static FT_CharMap find_variant_selector_charmap(FT_Face face)
Definition: ftobjs.c:1268
FT_Set_Transform(FT_Face face, FT_Matrix *matrix, FT_Vector *delta)
Definition: ftobjs.c:653
static void destroy_face(FT_Memory memory, FT_Face face, FT_Driver driver)
Definition: ftobjs.c:1105
FT_Match_Size(FT_Face face, FT_Size_Request req, FT_Bool ignore_width, FT_ULong *size_index)
Definition: ftobjs.c:2875
FT_Face_GetVariantSelectors(FT_Face face)
Definition: ftobjs.c:3923
static void destroy_size(FT_Memory memory, FT_Size size, FT_Driver driver)
Definition: ftobjs.c:1057
FT_Library_Version(FT_Library library, FT_Int *amajor, FT_Int *aminor, FT_Int *apatch)
Definition: ftobjs.c:5189
FT_Property_Get(FT_Library library, const FT_String *module_name, const FT_String *property_name, void *value)
Definition: ftobjs.c:5072
FT_Set_Pixel_Sizes(FT_Face face, FT_UInt pixel_width, FT_UInt pixel_height)
Definition: ftobjs.c:3309
static FT_Error open_face(FT_Driver driver, FT_Stream *astream, FT_Bool external_stream, FT_Long face_index, FT_Int num_params, FT_Parameter *params, FT_Face *aface)
Definition: ftobjs.c:1306
static void ft_glyphslot_clear(FT_GlyphSlot slot)
Definition: ftobjs.c:496
static void ft_cmap_done_internal(FT_CMap cmap)
Definition: ftobjs.c:3553
static FT_Error ft_open_face_internal(FT_Library library, const FT_Open_Args *args, FT_Long face_index, FT_Face *aface, FT_Bool test_mac_fonts)
Definition: ftobjs.c:2327
FT_Set_Renderer(FT_Library library, FT_Renderer renderer, FT_UInt num_params, FT_Parameter *parameters)
Definition: ftobjs.c:4428
ft_synthesize_vertical_metrics(FT_Glyph_Metrics *metrics, FT_Pos advance)
Definition: ftobjs.c:2933
FT_Done_Face(FT_Face face)
Definition: ftobjs.c:2721
FT_Get_First_Char(FT_Face face, FT_UInt *agindex)
Definition: ftobjs.c:3697
FT_Get_CMap_Language_ID(FT_CharMap charmap)
Definition: ftobjs.c:4182
FT_Face_GetVariantsOfChar(FT_Face face, FT_ULong charcode)
Definition: ftobjs.c:3950
FT_Select_Metrics(FT_Face face, FT_ULong strike_index)
Definition: ftobjs.c:2993
FT_Open_Face(FT_Library library, const FT_Open_Args *args, FT_Long face_index, FT_Face *aface)
Definition: ftobjs.c:2317
static void Destroy_Module(FT_Module module)
Definition: ftobjs.c:4694
FT_Done_Size(FT_Size size)
Definition: ftobjs.c:2827
ft_validator_run(FT_Validator valid)
Definition: ftobjs.c:135
static FT_Renderer ft_lookup_glyph_renderer(FT_GlyphSlot slot)
Definition: ftobjs.c:4306
ft_glyphslot_preset_bitmap(FT_GlyphSlot slot, FT_Render_Mode mode, const FT_Vector *origin)
Definition: ftobjs.c:334
FT_Load_Sfnt_Table(FT_Face face, FT_ULong tag, FT_Long offset, FT_Byte *buffer, FT_ULong *length)
Definition: ftobjs.c:4134
FT_Get_Char_Index(FT_Face face, FT_ULong charcode)
Definition: ftobjs.c:3668
ft_glyphslot_free_bitmap(FT_GlyphSlot slot)
Definition: ftobjs.c:314
FT_Add_Module(FT_Library library, const FT_Module_Class *clazz)
Definition: ftobjs.c:4724
FT_New_Face(FT_Library library, const char *pathname, FT_Long face_index, FT_Face *aface)
Definition: ftobjs.c:1406
static void Destroy_Driver(FT_Driver driver)
Definition: ftobjs.c:1156
FT_Select_Charmap(FT_Face face, FT_Encoding encoding)
Definition: ftobjs.c:3457
ft_validator_init(FT_Validator valid, const FT_Byte *base, const FT_Byte *limit, FT_ValidationLevel level)
Definition: ftobjs.c:122
static FT_Error ft_property_do(FT_Library library, const FT_String *module_name, const FT_String *property_name, void *value, FT_Bool set, FT_Bool value_is_string)
Definition: ftobjs.c:4967
static void ft_glyphslot_done(FT_GlyphSlot slot)
Definition: ftobjs.c:528
FT_Activate_Size(FT_Size size)
Definition: ftobjs.c:4230
static FT_Error find_unicode_charmap(FT_Face face)
Definition: ftobjs.c:1180
FT_Done_Library(FT_Library library)
Definition: ftobjs.c:5220
FT_Select_Size(FT_Face face, FT_Int strike_index)
Definition: ftobjs.c:3138
FT_CMap_Done(FT_CMap cmap)
Definition: ftobjs.c:3568
FT_New_GlyphSlot(FT_Face face, FT_GlyphSlot *aslot)
Definition: ftobjs.c:559
FT_Set_Debug_Hook(FT_Library library, FT_UInt hook_index, FT_DebugHook_Func debug_hook)
Definition: ftobjs.c:5328
FT_Request_Size(FT_Face face, FT_Size_Request req)
Definition: ftobjs.c:3192
FT_Request_Metrics(FT_Face face, FT_Size_Request req)
Definition: ftobjs.c:3028
FT_Get_Postscript_Name(FT_Face face)
Definition: ftobjs.c:4084
FT_New_Library(FT_Memory memory, FT_Library *alibrary)
Definition: ftobjs.c:5138
#define FREETYPE_VER_FIXED
ft_module_get_service(FT_Module module, const char *service_id, FT_Bool global)
Definition: ftobjs.c:4880
FT_Face_GetCharVariantIndex(FT_Face face, FT_ULong charcode, FT_ULong variantSelector)
Definition: ftobjs.c:3834
FT_Get_Renderer(FT_Library library, FT_Glyph_Format format)
Definition: ftobjs.c:4416
FT_Get_Charmap_Index(FT_CharMap charmap)
Definition: ftobjs.c:3534
FT_Set_Charmap(FT_Face face, FT_CharMap charmap)
Definition: ftobjs.c:3499
ft_validator_error(FT_Validator valid, FT_Error error)
Definition: ftobjs.c:145
FT_CMap_New(FT_CMap_Class clazz, FT_Pointer init_data, FT_CharMap charmap, FT_CMap *acmap)
Definition: ftobjs.c:3614
FT_Render_Glyph_Internal(FT_Library library, FT_GlyphSlot slot, FT_Render_Mode render_mode)
Definition: ftobjs.c:4485
FT_Get_CMap_Format(FT_CharMap charmap)
Definition: ftobjs.c:4206
static FT_Error ft_glyphslot_init(FT_GlyphSlot slot)
Definition: ftobjs.c:286
FT_Get_Module(FT_Library library, const char *module_name)
Definition: ftobjs.c:4837
FT_New_Size(FT_Face face, FT_Size *asize)
Definition: ftobjs.c:2762
FT_Get_TrueType_Engine_Type(FT_Library library)
Definition: ftobjs.c:5342
FT_Get_Glyph_Name(FT_Face face, FT_UInt glyph_index, FT_Pointer buffer, FT_UInt buffer_max)
Definition: ftobjs.c:4047
FT_Reference_Library(FT_Library library)
Definition: ftobjs.c:5124
static void ft_glyphslot_grid_fit_metrics(FT_GlyphSlot slot, FT_Bool vertical)
Definition: ftobjs.c:707
FT_Stream_New(FT_Library library, const FT_Open_Args *args, FT_Stream *astream)
Definition: ftobjs.c:178
FT_Render_Glyph(FT_GlyphSlot slot, FT_Render_Mode render_mode)
Definition: ftobjs.c:4650
FT_Get_Module_Interface(FT_Library library, const char *mod_name)
Definition: ftobjs.c:4865
FT_Get_Track_Kerning(FT_Face face, FT_Fixed point_size, FT_Int degree, FT_Fixed *akerning)
Definition: ftobjs.c:3426
FT_Get_Name_Index(FT_Face face, FT_String *glyph_name)
Definition: ftobjs.c:4019
FT_Stream_Free(FT_Stream stream, FT_Int external)
Definition: ftobjs.c:246
FT_Get_Kerning(FT_Face face, FT_UInt left_glyph, FT_UInt right_glyph, FT_UInt kern_mode, FT_Vector *akerning)
Definition: ftobjs.c:3347
static void ft_set_current_renderer(FT_Library library)
Definition: ftobjs.c:4321
FT_Attach_Stream(FT_Face face, FT_Open_Args *parameters)
Definition: ftobjs.c:2663
FT_Done_GlyphSlot(FT_GlyphSlot slot)
Definition: ftobjs.c:612
FT_Property_Set(FT_Library library, const FT_String *module_name, const FT_String *property_name, const void *value)
Definition: ftobjs.c:5055
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:5373
FT_Face_GetCharVariantIsDefault(FT_Face face, FT_ULong charcode, FT_ULong variantSelector)
Definition: ftobjs.c:3880
FT_Face_GetCharsOfVariant(FT_Face face, FT_ULong variantSelector)
Definition: ftobjs.c:3984
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:3267
FT_Sfnt_Table_Info(FT_Face face, FT_UInt table_index, FT_ULong *tag, FT_ULong *length)
Definition: ftobjs.c:4157
FT_Lookup_Renderer(FT_Library library, FT_Glyph_Format format, FT_ListNode *node)
Definition: ftobjs.c:4264
ft_glyphslot_alloc_bitmap(FT_GlyphSlot slot, FT_ULong size)
Definition: ftobjs.c:478
FT_Face_Properties(FT_Face face, FT_UInt num_properties, FT_Parameter *properties)
Definition: ftobjs.c:3755
FT_Reference_Face(FT_Face face)
Definition: ftobjs.c:2707
FT_Attach_File(FT_Face face, const char *filepathname)
Definition: ftobjs.c:2641
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:1431
ft_service_list_lookup(FT_ServiceDesc service_descriptors, const char *service_id)
Definition: ftobjs.c:98
static void ft_recompute_scaled_metrics(FT_Face face, FT_Size_Metrics *metrics)
Definition: ftobjs.c:2959
FT_Load_Char(FT_Face face, FT_ULong char_code, FT_Int32 load_flags)
Definition: ftobjs.c:1037
static void ft_remove_renderer(FT_Module module)
Definition: ftobjs.c:4380
ft_glyphslot_set_bitmap(FT_GlyphSlot slot, FT_Byte *buffer)
Definition: ftobjs.c:466
#define FT_PIX_CEIL(x)
Definition: ftobjs.h:94
#define FT_FACE_LIBRARY(x)
Definition: ftobjs.h:635
#define FT_DRIVER_HAS_HINTER(x)
Definition: ftobjs.h:568
#define FT_DRIVER_IS_SCALABLE(x)
Definition: ftobjs.h:562
#define FT_MODULE_IS_RENDERER(x)
Definition: ftobjs.h:553
#define FT_FACE(x)
Definition: ftobjs.h:630
#define FT_DRIVER_USES_OUTLINES(x)
Definition: ftobjs.h:565
#define FT_PIX_FLOOR(x)
Definition: ftobjs.h:92
#define FT_REQUEST_WIDTH(req)
Definition: ftobjs.h:689
#define FT_MIN(a, b)
Definition: ftobjs.h:71
#define FT_REQUEST_HEIGHT(req)
Definition: ftobjs.h:694
#define FT_FACE_MEMORY(x)
Definition: ftobjs.h:636
#define FT_PIX_ROUND_LONG(x)
Definition: ftobjs.h:102
#define FT_PIX_ROUND(x)
Definition: ftobjs.h:93
#define FT_DRIVER_HINTS_LIGHTLY(x)
Definition: ftobjs.h:571
#define FT_DRIVER(x)
Definition: ftobjs.h:799
#define FT_CMAP(x)
Definition: ftobjs.h:159
#define FT_GLYPH_OWN_BITMAP
Definition: ftobjs.h:463
#define FT_MODULE_IS_DRIVER(x)
Definition: ftobjs.h:550
ft_lcd_padding(FT_Pos *Min, FT_Pos *Max, FT_GlyphSlot slot)
Definition: ftlcdfil.c:348
#define FT_PIX_CEIL_LONG(x)
Definition: ftobjs.h:103
#define FT_MODULE_IS_HINTER(x)
Definition: ftobjs.h:556
#define FT_PAD_CEIL(x, n)
Definition: ftobjs.h:90
#define FT_RENDERER(x)
Definition: ftobjs.h:765
FT_Outline_Check(FT_Outline *outline)
Definition: ftoutln.c:357
FT_Outline_Translate(const FT_Outline *outline, FT_Pos xOffset, FT_Pos yOffset)
Definition: ftoutln.c:528
FT_Outline_Transform(const FT_Outline *outline, const FT_Matrix *matrix)
Definition: ftoutln.c:711
FT_Outline_Get_CBox(const FT_Outline *outline, FT_BBox *acbox)
Definition: ftoutln.c:478
#define FT_PARAM_TAG_INCREMENTAL
Definition: ftparams.h:112
#define FT_PARAM_TAG_RANDOM_SEED
Definition: ftparams.h:151
#define FT_PARAM_TAG_LCD_FILTER_WEIGHTS
Definition: ftparams.h:132
#define FT_PARAM_TAG_STEM_DARKENING
Definition: ftparams.h:175
FT_Error(* FT_Renderer_SetModeFunc)(FT_Renderer renderer, FT_ULong mode_tag, FT_Pointer mode_ptr)
Definition: ftrender.h:108
FT_Raccess_Guess(FT_Library library, FT_Stream stream, char *base_name, char **new_names, FT_Long *offsets, FT_Error *errors)
Definition: ftrfork.c:917
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:51
#define FT_RACCESS_N_RULES
Definition: ftrfork.h:37
FT_Raccess_Get_DataOffsets(FT_Library library, FT_Stream stream, FT_Long map_offset, FT_Long rdata_pos, FT_Long tag, FT_Bool sort_by_res_id, FT_Long **offsets, FT_Long *count)
Definition: ftrfork.c:185
#define FT_FACE_LOOKUP_SERVICE(face, ptr, id)
Definition: ftserv.h:950
#define FT_FACE_FIND_SERVICE(face, ptr, id)
Definition: ftserv.h:75
smooth FT_Module_Constructor FT_Module_Destructor FT_Module_Requester FT_GLYPH_FORMAT_OUTLINE
Definition: ftsmooth.c:426
#define ft_memcpy
Definition: ftstdlib.h:82
#define ft_memcmp
Definition: ftstdlib.h:81
#define ft_jmp_buf
Definition: ftstdlib.h:158
#define ft_longjmp
Definition: ftstdlib.h:162
#define ft_strcmp
Definition: ftstdlib.h:86
#define ft_strstr
Definition: ftstdlib.h:92
#define FT_READ_USHORT(var)
Definition: ftstream.h:309
#define FT_READ_ULONG(var)
Definition: ftstream.h:313
#define FT_READ_LONG(var)
Definition: ftstream.h:312
#define FT_STREAM_POS()
Definition: ftstream.h:486
FT_Stream_Close(FT_Stream stream)
Definition: ftstream.c:49
FT_Stream_Open(FT_Stream stream, const char *filepathname)
Definition: ftsystem.c:224
#define FT_STREAM_SKIP(distance)
Definition: ftstream.h:493
FT_Stream_Read(FT_Stream stream, FT_Byte *buffer, FT_ULong count)
Definition: ftstream.c:110
FT_Stream_Seek(FT_Stream stream, FT_ULong pos)
Definition: ftstream.c:57
FT_Stream_OpenMemory(FT_Stream stream, const FT_Byte *base, FT_ULong size)
Definition: ftstream.c:35
typedefFT_BEGIN_HEADER struct FT_MemoryRec_ * FT_Memory
Definition: ftsystem.h:66
void(* FT_Stream_CloseFunc)(FT_Stream stream)
Definition: ftsystem.h:272
void * FT_Pointer
Definition: fttypes.h:311
FT_BEGIN_HEADER typedef unsigned char FT_Bool
Definition: fttypes.h:108
signed long FT_F26Dot6
Definition: fttypes.h:276
unsigned long FT_ULong
Definition: fttypes.h:253
unsigned char FT_Byte
Definition: fttypes.h:154
#define FT_ERR_EQ(x, e)
Definition: fttypes.h:591
signed long FT_Fixed
Definition: fttypes.h:288
int FT_Error
Definition: fttypes.h:300
signed long FT_Long
Definition: fttypes.h:242
#define FT_ERR_NEQ(x, e)
Definition: fttypes.h:593
#define FT_ERR(e)
Definition: fttypes.h:586
unsigned short FT_UShort
Definition: fttypes.h:209
char FT_String
Definition: fttypes.h:187
signed short FT_Short
Definition: fttypes.h:198
unsigned int FT_UInt
Definition: fttypes.h:231
#define FT_BOOL(x)
Definition: fttypes.h:578
signed int FT_Int
Definition: fttypes.h:220
enum FT_ValidationLevel_ FT_ValidationLevel
typedefFT_BEGIN_HEADER struct FT_ValidatorRec_ volatile * FT_Validator
Definition: ftvalid.h:42
static const FxOffsetAndName offsets[]
BOOLEAN valid
FxCollectionEntry * cur
GLint level
Definition: gl.h:1546
GLuint GLuint GLsizei GLenum type
Definition: gl.h:1545
GLuint GLuint end
Definition: gl.h:1545
GLuint GLuint GLsizei count
Definition: gl.h:1545
GLint GLenum GLsizei GLsizei GLsizei GLint GLsizei const GLvoid * data
Definition: gl.h:1950
GLint GLint GLsizei GLsizei GLsizei GLint GLenum format
Definition: gl.h:1546
GLint GLint GLsizei GLsizei height
Definition: gl.h:1546
GLint GLint GLsizei width
Definition: gl.h:1546
GLsizeiptr size
Definition: glext.h:5919
GLdouble n
Definition: glext.h:7729
GLuint buffer
Definition: glext.h:5915
GLdouble GLdouble right
Definition: glext.h:10859
GLenum GLuint GLint GLenum face
Definition: glext.h:7025
GLsizei GLenum const GLvoid GLuint GLsizei GLfloat * metrics
Definition: glext.h:11745
GLint limit
Definition: glext.h:10326
GLuint GLenum matrix
Definition: glext.h:9407
GLenum mode
Definition: glext.h:6217
GLenum const GLfloat * params
Definition: glext.h:5645
GLbitfield flags
Definition: glext.h:7161
GLuint GLsizei GLsizei * length
Definition: glext.h:6040
GLint GLint bottom
Definition: glext.h:7726
const GLint * first
Definition: glext.h:5794
GLenum GLsizei len
Definition: glext.h:6722
GLubyte GLubyte GLubyte GLubyte w
Definition: glext.h:6102
GLuint64EXT * result
Definition: glext.h:11304
GLintptr offset
Definition: glext.h:5920
const GLfloat * m
Definition: glext.h:10848
GLfloat GLfloat GLfloat GLfloat h
Definition: glext.h:7723
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble const GLfloat const GLdouble const GLfloat GLint i
Definition: glfuncs.h:248
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble const GLfloat const GLdouble const GLfloat GLint GLint GLint j
Definition: glfuncs.h:250
voidpf uLong int origin
Definition: ioapi.h:144
if(dx< 0)
Definition: linetemp.h:194
#define error(str)
Definition: mkdosfs.c:1605
char pathname[512]
Definition: util.h:13
static const WCHAR desc[]
Definition: protectdata.c:36
static char memory[1024 *256]
Definition: process.c:116
struct @1669::@1670 driver
#define minor(rdev)
Definition: propsheet.cpp:929
#define major(rdev)
Definition: propsheet.cpp:928
FT_BEGIN_HEADER struct PS_DriverRec_ * PS_Driver
#define err(...)
static unsigned int file_size
Definition: regtests2xml.c:47
void func_name(void)
static calc_node_t temp
Definition: rpn_ieee.c:38
#define error2(s, a, b)
Definition: debug.h:126
#define error1(s, a)
Definition: debug.h:125
void MD5_Init(MD5_CTX *ctx)
Definition: md5.c:207
void MD5_Update(MD5_CTX *ctx, const void *data, unsigned long size)
Definition: md5.c:218
void MD5_Final(unsigned char *result, MD5_CTX *ctx)
Definition: md5.c:258
#define args
Definition: format.c:66
static void Exit(void)
Definition: sock.c:1330
static void render(void)
Definition: ssstars.c:272
FT_AutoHinter_GlyphLoadFunc load_glyph
Definition: autohint.h:195
FT_Pos xMin
Definition: ftimage.h:117
FT_Pos yMax
Definition: ftimage.h:118
FT_Pos yMin
Definition: ftimage.h:117
FT_Pos xMax
Definition: ftimage.h:118
FT_Pos y_ppem
Definition: freetype.h:379
FT_Pos x_ppem
Definition: freetype.h:378
FT_Short width
Definition: freetype.h:374
FT_Short height
Definition: freetype.h:373
FT_CharMapRec charmap
Definition: ftobjs.h:153
FT_CMap_Class clazz
Definition: ftobjs.h:154
FT_CMap_DoneFunc done
Definition: ftobjs.h:215
FT_CMap_CharNextFunc char_next
Definition: ftobjs.h:217
FT_CMap_CharVariantListFunc charvariant_list
Definition: ftobjs.h:225
FT_CMap_CharVarIndexFunc char_var_index
Definition: ftobjs.h:222
FT_CMap_VariantCharListFunc variantchar_list
Definition: ftobjs.h:226
FT_CMap_CharVarIsDefaultFunc char_var_default
Definition: ftobjs.h:223
FT_CMap_CharIndexFunc char_index
Definition: ftobjs.h:216
FT_CMap_VariantListFunc variant_list
Definition: ftobjs.h:224
FT_Face face
Definition: freetype.h:842
FT_Size_RequestFunc request_size
Definition: ftdrv.h:181
FT_Size_InitFunc init_size
Definition: ftdrv.h:168
FT_Long face_object_size
Definition: ftdrv.h:161
FT_Size_SelectFunc select_size
Definition: ftdrv.h:182
FT_Long size_object_size
Definition: ftdrv.h:162
FT_Slot_DoneFunc done_slot
Definition: ftdrv.h:172
FT_Face_InitFunc init_face
Definition: ftdrv.h:165
FT_Face_DoneFunc done_face
Definition: ftdrv.h:166
FT_Face_AttachFunc attach_file
Definition: ftdrv.h:177
FT_Long slot_object_size
Definition: ftdrv.h:163
FT_Slot_InitFunc init_slot
Definition: ftdrv.h:171
FT_CharMap charmap
Definition: freetype.h:1107
FT_GlyphSlot next
Definition: freetype.h:1912
FT_DebugHook_Func debug_hooks[4]
Definition: ftobjs.h:931
FT_Int version_minor
Definition: ftobjs.h:921
FT_Int version_major
Definition: ftobjs.h:920
FT_Int version_patch
Definition: ftobjs.h:922
FT_Renderer cur_renderer
Definition: ftobjs.h:928
FT_Int refcount
Definition: ftobjs.h:942
FT_ListRec renderers
Definition: ftobjs.h:927
FT_Module auto_hinter
Definition: ftobjs.h:929
FT_Module modules[FT_MAX_MODULES]
Definition: ftobjs.h:925
FT_UInt num_modules
Definition: ftobjs.h:924
FT_Memory memory
Definition: ftobjs.h:918
void * data
Definition: fttypes.h:548
FT_ListNode head
Definition: fttypes.h:569
FT_Module_Class * clazz
Definition: ftobjs.h:535
const void * module_interface
Definition: ftmodapi.h:225
FT_Module_Destructor module_done
Definition: ftmodapi.h:228
FT_UInt flags
Definition: freetype.h:2137
FT_String * pathname
Definition: freetype.h:2140
FT_Raster_NewFunc raster_new
Definition: ftimage.h:1184
FT_Raster_RenderFunc raster_render
Definition: ftimage.h:1187
FT_Raster_DoneFunc raster_done
Definition: ftimage.h:1188
FT_Renderer_RenderFunc render
Definition: ftobjs.h:780
FT_Renderer_Class * clazz
Definition: ftobjs.h:774
FT_Glyph_Format glyph_format
Definition: ftobjs.h:775
FT_Raster raster
Definition: ftobjs.h:778
FT_Renderer_TransformFunc transform_glyph
Definition: ftrender.h:152
FT_Glyph_Format glyph_format
Definition: ftrender.h:149
FT_Raster_Funcs * raster_class
Definition: ftrender.h:156
FT_Renderer_RenderFunc render_glyph
Definition: ftrender.h:151
FT_Renderer_SetModeFunc set_mode
Definition: ftrender.h:154
FT_UInt horiResolution
Definition: freetype.h:2622
FT_Size_Request_Type type
Definition: freetype.h:2619
FT_UInt vertResolution
Definition: freetype.h:2623
FT_Int arg2
Definition: ftgloadr.h:44
FT_UShort flags
Definition: ftgloadr.h:42
FT_Matrix transform
Definition: ftgloadr.h:45
FT_Int index
Definition: ftgloadr.h:41
FT_Int arg1
Definition: ftgloadr.h:43
Definition: msi.c:4013
FT_Long format
Definition: svttcmap.h:61
FT_ULong language
Definition: svttcmap.h:60
TT_MaxProfile max_profile
Definition: tttypes.h:1404
FT_ULong num_locations
Definition: tttypes.h:1523
FT_ULong font_program_size
Definition: tttypes.h:1475
FT_ULong cvt_program_size
Definition: tttypes.h:1479
FT_UShort maxSizeOfInstructions
Definition: tttables.h:581
Definition: vfat.h:185
Definition: match.c:390
Definition: uimain.c:89
uint32 width
Definition: uimain.c:91
Definition: inflate.c:139
Definition: mesh.c:5330
Definition: parse.h:23
unsigned int size
Definition: parse.h:27
Definition: ecma_167.h:138
#define FT_SERVICE_ID_PROPERTIES
Definition: svprop.h:26
#define FT_SERVICE_ID_TRUETYPE_ENGINE
Definition: svtteng.h:33
FT_UInt left_glyph
Definition: ttdriver.c:201
FT_UInt FT_UInt right_glyph
Definition: ttdriver.c:202
#define TT_APPLE_ID_UNICODE_32
Definition: ttnameid.h:132
#define TT_MS_ID_UCS_4
Definition: ttnameid.h:255
#define TT_APPLE_ID_VARIANT_SELECTOR
Definition: ttnameid.h:133
enum FT_Sfnt_Tag_ FT_Sfnt_Tag
#define TTAG_CID
Definition: tttags.h:47
#define TTAG_TYP1
Definition: tttags.h:101
#define TTAG_sfnt
Definition: tttags.h:95
#define TTAG_typ1
Definition: tttags.h:102
#define TTAG_POST
Definition: tttags.h:90
struct TT_FaceRec_ * TT_Face
Definition: tttypes.h:973
Definition: dlist.c:348
GLvoid * data
Definition: dlist.c:359
Definition: pdh_main.c:94
struct _slot slot
Definition: vfat.h:196
static void set_name(msft_typelib_t *typelib)
Definition: write_msft.c:2395
ActualNumberDriverObjects * sizeof(PDRIVER_OBJECT)) PDRIVER_OBJECT *DriverObjectList
static char * encoding
Definition: xmllint.c:155
#define const
Definition: zconf.h:233