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