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