changeset 54876 | da3834261f0c |
parent 49234 | 3375a8039fde |
54875:bcfedddcf4ce | 54876:da3834261f0c |
---|---|
1 /***************************************************************************/ |
1 /**************************************************************************** |
2 /* */ |
2 * |
3 /* ftobjs.c */ |
3 * ftobjs.c |
4 /* */ |
4 * |
5 /* The FreeType private base classes (body). */ |
5 * The FreeType private base classes (body). |
6 /* */ |
6 * |
7 /* Copyright 1996-2018 by */ |
7 * Copyright (C) 1996-2019 by |
8 /* David Turner, Robert Wilhelm, and Werner Lemberg. */ |
8 * David Turner, Robert Wilhelm, and Werner Lemberg. |
9 /* */ |
9 * |
10 /* This file is part of the FreeType project, and may only be used, */ |
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 */ |
11 * modified, and distributed under the terms of the FreeType project |
12 /* license, LICENSE.TXT. By continuing to use, modify, or distribute */ |
12 * license, LICENSE.TXT. By continuing to use, modify, or distribute |
13 /* this file you indicate that you have read the license and */ |
13 * this file you indicate that you have read the license and |
14 /* understand and accept it fully. */ |
14 * understand and accept it fully. |
15 /* */ |
15 * |
16 /***************************************************************************/ |
16 */ |
17 |
17 |
18 |
18 |
19 #include <ft2build.h> |
19 #include <ft2build.h> |
20 #include FT_LIST_H |
20 #include FT_LIST_H |
21 #include FT_OUTLINE_H |
21 #include FT_OUTLINE_H |
76 #include "md5.c" |
76 #include "md5.c" |
77 |
77 |
78 #if defined( _MSC_VER ) |
78 #if defined( _MSC_VER ) |
79 #pragma warning( pop ) |
79 #pragma warning( pop ) |
80 #endif |
80 #endif |
81 |
|
82 static const char* const pixel_modes[] = |
|
83 { |
|
84 "none", |
|
85 "monochrome bitmap", |
|
86 "gray 8-bit bitmap", |
|
87 "gray 2-bit bitmap", |
|
88 "gray 4-bit bitmap", |
|
89 "LCD 8-bit bitmap", |
|
90 "vertical LCD 8-bit bitmap", |
|
91 "BGRA 32-bit color image bitmap" |
|
92 }; |
|
81 |
93 |
82 #endif /* FT_DEBUG_LEVEL_TRACE */ |
94 #endif /* FT_DEBUG_LEVEL_TRACE */ |
83 |
95 |
84 |
96 |
85 #define GRID_FIT_METRICS |
97 #define GRID_FIT_METRICS |
257 FT_FREE( stream ); |
269 FT_FREE( stream ); |
258 } |
270 } |
259 } |
271 } |
260 |
272 |
261 |
273 |
262 /*************************************************************************/ |
274 /************************************************************************** |
263 /* */ |
275 * |
264 /* The macro FT_COMPONENT is used in trace mode. It is an implicit */ |
276 * The macro FT_COMPONENT is used in trace mode. It is an implicit |
265 /* parameter of the FT_TRACE() and FT_ERROR() macros, used to print/log */ |
277 * parameter of the FT_TRACE() and FT_ERROR() macros, used to print/log |
266 /* messages during execution. */ |
278 * messages during execution. |
267 /* */ |
279 */ |
268 #undef FT_COMPONENT |
280 #undef FT_COMPONENT |
269 #define FT_COMPONENT trace_objs |
281 #define FT_COMPONENT objs |
270 |
282 |
271 |
283 |
272 /*************************************************************************/ |
284 /*************************************************************************/ |
273 /*************************************************************************/ |
285 /*************************************************************************/ |
274 /*************************************************************************/ |
286 /*************************************************************************/ |
328 slot->bitmap.buffer = NULL; |
340 slot->bitmap.buffer = NULL; |
329 } |
341 } |
330 } |
342 } |
331 |
343 |
332 |
344 |
333 FT_BASE_DEF( void ) |
345 /* overflow-resistant presetting of bitmap position and dimensions; */ |
346 /* also check whether the size is too large for rendering */ |
|
347 FT_BASE_DEF( FT_Bool ) |
|
334 ft_glyphslot_preset_bitmap( FT_GlyphSlot slot, |
348 ft_glyphslot_preset_bitmap( FT_GlyphSlot slot, |
335 FT_Render_Mode mode, |
349 FT_Render_Mode mode, |
336 const FT_Vector* origin ) |
350 const FT_Vector* origin ) |
337 { |
351 { |
338 FT_Outline* outline = &slot->outline; |
352 FT_Outline* outline = &slot->outline; |
339 FT_Bitmap* bitmap = &slot->bitmap; |
353 FT_Bitmap* bitmap = &slot->bitmap; |
340 |
354 |
341 FT_Pixel_Mode pixel_mode; |
355 FT_Pixel_Mode pixel_mode; |
342 |
356 |
343 FT_BBox cbox; |
357 FT_BBox cbox, pbox; |
344 FT_Pos x_shift = 0; |
358 FT_Pos x_shift = 0; |
345 FT_Pos y_shift = 0; |
359 FT_Pos y_shift = 0; |
346 FT_Pos x_left, y_top; |
360 FT_Pos x_left, y_top; |
347 FT_Pos width, height, pitch; |
361 FT_Pos width, height, pitch; |
348 |
362 |
349 |
363 |
350 if ( slot->internal && ( slot->internal->flags & FT_GLYPH_OWN_BITMAP ) ) |
364 if ( slot->format != FT_GLYPH_FORMAT_OUTLINE ) |
351 return; |
365 return 1; |
352 |
366 |
353 if ( origin ) |
367 if ( origin ) |
354 { |
368 { |
355 x_shift = origin->x; |
369 x_shift = origin->x; |
356 y_shift = origin->y; |
370 y_shift = origin->y; |
358 |
372 |
359 /* compute the control box, and grid-fit it, */ |
373 /* compute the control box, and grid-fit it, */ |
360 /* taking into account the origin shift */ |
374 /* taking into account the origin shift */ |
361 FT_Outline_Get_CBox( outline, &cbox ); |
375 FT_Outline_Get_CBox( outline, &cbox ); |
362 |
376 |
363 cbox.xMin += x_shift; |
377 /* rough estimate of pixel box */ |
364 cbox.yMin += y_shift; |
378 pbox.xMin = ( cbox.xMin >> 6 ) + ( x_shift >> 6 ); |
365 cbox.xMax += x_shift; |
379 pbox.yMin = ( cbox.yMin >> 6 ) + ( y_shift >> 6 ); |
366 cbox.yMax += y_shift; |
380 pbox.xMax = ( cbox.xMax >> 6 ) + ( x_shift >> 6 ); |
381 pbox.yMax = ( cbox.yMax >> 6 ) + ( y_shift >> 6 ); |
|
382 |
|
383 /* tiny remainder box */ |
|
384 cbox.xMin = ( cbox.xMin & 63 ) + ( x_shift & 63 ); |
|
385 cbox.yMin = ( cbox.yMin & 63 ) + ( y_shift & 63 ); |
|
386 cbox.xMax = ( cbox.xMax & 63 ) + ( x_shift & 63 ); |
|
387 cbox.yMax = ( cbox.yMax & 63 ) + ( y_shift & 63 ); |
|
367 |
388 |
368 switch ( mode ) |
389 switch ( mode ) |
369 { |
390 { |
370 case FT_RENDER_MODE_MONO: |
391 case FT_RENDER_MODE_MONO: |
371 pixel_mode = FT_PIXEL_MODE_MONO; |
392 pixel_mode = FT_PIXEL_MODE_MONO; |
372 #if 1 |
393 #if 1 |
373 /* undocumented but confirmed: bbox values get rounded */ |
394 /* x */ |
374 /* unless the rounded box can collapse for a narrow glyph */ |
395 |
375 if ( cbox.xMax - cbox.xMin < 64 ) |
396 /* undocumented but confirmed: bbox values get rounded; */ |
376 { |
397 /* we do asymmetric rounding so that the center of a pixel */ |
377 cbox.xMin = FT_PIX_FLOOR( cbox.xMin ); |
398 /* gets always included */ |
378 cbox.xMax = FT_PIX_CEIL_LONG( cbox.xMax ); |
399 |
379 } |
400 pbox.xMin += ( cbox.xMin + 31 ) >> 6; |
380 else |
401 pbox.xMax += ( cbox.xMax + 32 ) >> 6; |
381 { |
402 |
382 cbox.xMin = FT_PIX_ROUND_LONG( cbox.xMin ); |
403 /* if the bbox collapsed, we add a pixel based on the total */ |
383 cbox.xMax = FT_PIX_ROUND_LONG( cbox.xMax ); |
404 /* rounding remainder to cover most of the original cbox */ |
384 } |
405 |
385 |
406 if ( pbox.xMin == pbox.xMax ) |
386 if ( cbox.yMax - cbox.yMin < 64 ) |
407 { |
387 { |
408 if ( ( ( cbox.xMin + 31 ) & 63 ) - 31 + |
388 cbox.yMin = FT_PIX_FLOOR( cbox.yMin ); |
409 ( ( cbox.xMax + 32 ) & 63 ) - 32 < 0 ) |
389 cbox.yMax = FT_PIX_CEIL_LONG( cbox.yMax ); |
410 pbox.xMin -= 1; |
390 } |
411 else |
391 else |
412 pbox.xMax += 1; |
392 { |
413 } |
393 cbox.yMin = FT_PIX_ROUND_LONG( cbox.yMin ); |
414 |
394 cbox.yMax = FT_PIX_ROUND_LONG( cbox.yMax ); |
415 /* y */ |
395 } |
416 |
417 pbox.yMin += ( cbox.yMin + 31 ) >> 6; |
|
418 pbox.yMax += ( cbox.yMax + 32 ) >> 6; |
|
419 |
|
420 if ( pbox.yMin == pbox.yMax ) |
|
421 { |
|
422 if ( ( ( cbox.yMin + 31 ) & 63 ) - 31 + |
|
423 ( ( cbox.yMax + 32 ) & 63 ) - 32 < 0 ) |
|
424 pbox.yMin -= 1; |
|
425 else |
|
426 pbox.yMax += 1; |
|
427 } |
|
428 |
|
429 break; |
|
396 #else |
430 #else |
397 cbox.xMin = FT_PIX_FLOOR( cbox.xMin ); |
431 goto Adjust; |
398 cbox.yMin = FT_PIX_FLOOR( cbox.yMin ); |
|
399 cbox.xMax = FT_PIX_CEIL_LONG( cbox.xMax ); |
|
400 cbox.yMax = FT_PIX_CEIL_LONG( cbox.yMax ); |
|
401 #endif |
432 #endif |
402 break; |
|
403 |
433 |
404 case FT_RENDER_MODE_LCD: |
434 case FT_RENDER_MODE_LCD: |
405 pixel_mode = FT_PIXEL_MODE_LCD; |
435 pixel_mode = FT_PIXEL_MODE_LCD; |
406 ft_lcd_padding( &cbox.xMin, &cbox.xMax, slot ); |
436 ft_lcd_padding( &cbox, slot, mode ); |
407 goto Round; |
437 goto Adjust; |
408 |
438 |
409 case FT_RENDER_MODE_LCD_V: |
439 case FT_RENDER_MODE_LCD_V: |
410 pixel_mode = FT_PIXEL_MODE_LCD_V; |
440 pixel_mode = FT_PIXEL_MODE_LCD_V; |
411 ft_lcd_padding( &cbox.yMin, &cbox.yMax, slot ); |
441 ft_lcd_padding( &cbox, slot, mode ); |
412 goto Round; |
442 goto Adjust; |
413 |
443 |
414 case FT_RENDER_MODE_NORMAL: |
444 case FT_RENDER_MODE_NORMAL: |
415 case FT_RENDER_MODE_LIGHT: |
445 case FT_RENDER_MODE_LIGHT: |
416 default: |
446 default: |
417 pixel_mode = FT_PIXEL_MODE_GRAY; |
447 pixel_mode = FT_PIXEL_MODE_GRAY; |
418 Round: |
448 Adjust: |
419 cbox.xMin = FT_PIX_FLOOR( cbox.xMin ); |
449 pbox.xMin += cbox.xMin >> 6; |
420 cbox.yMin = FT_PIX_FLOOR( cbox.yMin ); |
450 pbox.yMin += cbox.yMin >> 6; |
421 cbox.xMax = FT_PIX_CEIL_LONG( cbox.xMax ); |
451 pbox.xMax += ( cbox.xMax + 63 ) >> 6; |
422 cbox.yMax = FT_PIX_CEIL_LONG( cbox.yMax ); |
452 pbox.yMax += ( cbox.yMax + 63 ) >> 6; |
423 } |
453 } |
424 |
454 |
425 x_shift = SUB_LONG( x_shift, cbox.xMin ); |
455 x_left = pbox.xMin; |
426 y_shift = SUB_LONG( y_shift, cbox.yMin ); |
456 y_top = pbox.yMax; |
427 |
457 |
428 x_left = cbox.xMin >> 6; |
458 width = pbox.xMax - pbox.xMin; |
429 y_top = cbox.yMax >> 6; |
459 height = pbox.yMax - pbox.yMin; |
430 |
|
431 width = ( (FT_ULong)cbox.xMax - (FT_ULong)cbox.xMin ) >> 6; |
|
432 height = ( (FT_ULong)cbox.yMax - (FT_ULong)cbox.yMin ) >> 6; |
|
433 |
460 |
434 switch ( pixel_mode ) |
461 switch ( pixel_mode ) |
435 { |
462 { |
436 case FT_PIXEL_MODE_MONO: |
463 case FT_PIXEL_MODE_MONO: |
437 pitch = ( ( width + 15 ) >> 4 ) << 1; |
464 pitch = ( ( width + 15 ) >> 4 ) << 1; |
457 bitmap->pixel_mode = (unsigned char)pixel_mode; |
484 bitmap->pixel_mode = (unsigned char)pixel_mode; |
458 bitmap->num_grays = 256; |
485 bitmap->num_grays = 256; |
459 bitmap->width = (unsigned int)width; |
486 bitmap->width = (unsigned int)width; |
460 bitmap->rows = (unsigned int)height; |
487 bitmap->rows = (unsigned int)height; |
461 bitmap->pitch = pitch; |
488 bitmap->pitch = pitch; |
489 |
|
490 if ( pbox.xMin < -0x8000 || pbox.xMax > 0x7FFF || |
|
491 pbox.yMin < -0x8000 || pbox.yMax > 0x7FFF ) |
|
492 { |
|
493 FT_TRACE3(( "ft_glyphslot_preset_bitmap: [%ld %ld %ld %ld]\n", |
|
494 pbox.xMin, pbox.yMin, pbox.xMax, pbox.yMax )); |
|
495 return 1; |
|
496 } |
|
497 |
|
498 return 0; |
|
462 } |
499 } |
463 |
500 |
464 |
501 |
465 FT_BASE_DEF( void ) |
502 FT_BASE_DEF( void ) |
466 ft_glyphslot_set_bitmap( FT_GlyphSlot slot, |
503 ft_glyphslot_set_bitmap( FT_GlyphSlot slot, |
805 * The general rules are: |
842 * The general rules are: |
806 * |
843 * |
807 * - Do only auto-hinting if we have |
844 * - Do only auto-hinting if we have |
808 * |
845 * |
809 * - a hinter module, |
846 * - a hinter module, |
810 * - a scalable font format dealing with outlines, |
847 * - a scalable font, |
811 * - not a tricky font, and |
848 * - not a tricky font, and |
812 * - no transforms except simple slants and/or rotations by |
849 * - no transforms except simple slants and/or rotations by |
813 * integer multiples of 90 degrees. |
850 * integer multiples of 90 degrees. |
814 * |
851 * |
815 * - Then, auto-hint if FT_LOAD_FORCE_AUTOHINT is set or if we don't |
852 * - Then, auto-hint if FT_LOAD_FORCE_AUTOHINT is set or if we don't |
823 */ |
860 */ |
824 |
861 |
825 if ( hinter && |
862 if ( hinter && |
826 !( load_flags & FT_LOAD_NO_HINTING ) && |
863 !( load_flags & FT_LOAD_NO_HINTING ) && |
827 !( load_flags & FT_LOAD_NO_AUTOHINT ) && |
864 !( load_flags & FT_LOAD_NO_AUTOHINT ) && |
828 FT_DRIVER_IS_SCALABLE( driver ) && |
865 FT_IS_SCALABLE( face ) && |
829 FT_DRIVER_USES_OUTLINES( driver ) && |
|
830 !FT_IS_TRICKY( face ) && |
866 !FT_IS_TRICKY( face ) && |
831 ( ( load_flags & FT_LOAD_IGNORE_TRANSFORM ) || |
867 ( ( load_flags & FT_LOAD_IGNORE_TRANSFORM ) || |
832 ( face->internal->transform_matrix.yx == 0 && |
868 ( face->internal->transform_matrix.yx == 0 && |
833 face->internal->transform_matrix.xx != 0 ) || |
869 face->internal->transform_matrix.xx != 0 ) || |
834 ( face->internal->transform_matrix.xx == 0 && |
870 ( face->internal->transform_matrix.xx == 0 && |
844 |
880 |
845 |
881 |
846 /* only the new Adobe engine (for both CFF and Type 1) is `light'; */ |
882 /* only the new Adobe engine (for both CFF and Type 1) is `light'; */ |
847 /* we use `strstr' to catch both `Type 1' and `CID Type 1' */ |
883 /* we use `strstr' to catch both `Type 1' and `CID Type 1' */ |
848 is_light_type1 = |
884 is_light_type1 = |
849 ft_strstr( FT_Get_Font_Format( face ), "Type 1" ) != NULL && |
885 ft_strstr( FT_Get_Font_Format( face ), "Type 1" ) != NULL && |
850 ((PS_Driver)driver)->hinting_engine == FT_HINTING_ADOBE; |
886 ((PS_Driver)driver)->hinting_engine == FT_HINTING_ADOBE; |
851 |
887 |
852 /* the check for `num_locations' assures that we actually */ |
888 /* the check for `num_locations' assures that we actually */ |
853 /* test for instructions in a TTF and not in a CFF-based OTF */ |
889 /* test for instructions in a TTF and not in a CFF-based OTF */ |
854 /* */ |
890 /* */ |
924 if ( error ) |
960 if ( error ) |
925 goto Exit; |
961 goto Exit; |
926 |
962 |
927 #ifdef GRID_FIT_METRICS |
963 #ifdef GRID_FIT_METRICS |
928 if ( !( load_flags & FT_LOAD_NO_HINTING ) ) |
964 if ( !( load_flags & FT_LOAD_NO_HINTING ) ) |
929 ft_glyphslot_grid_fit_metrics( slot, |
965 ft_glyphslot_grid_fit_metrics( |
930 FT_BOOL( load_flags & FT_LOAD_VERTICAL_LAYOUT ) ); |
966 slot, |
967 FT_BOOL( load_flags & FT_LOAD_VERTICAL_LAYOUT ) ); |
|
931 #endif |
968 #endif |
932 } |
969 } |
933 } |
970 } |
934 |
971 |
935 Load_Ok: |
972 Load_Ok: |
993 /* transform advance */ |
1030 /* transform advance */ |
994 FT_Vector_Transform( &slot->advance, &internal->transform_matrix ); |
1031 FT_Vector_Transform( &slot->advance, &internal->transform_matrix ); |
995 } |
1032 } |
996 } |
1033 } |
997 |
1034 |
1035 slot->glyph_index = glyph_index; |
|
1036 slot->internal->load_flags = load_flags; |
|
1037 |
|
998 /* do we need to render the image or preset the bitmap now? */ |
1038 /* do we need to render the image or preset the bitmap now? */ |
999 if ( !error && |
1039 if ( !error && |
1000 ( load_flags & FT_LOAD_NO_SCALE ) == 0 && |
1040 ( load_flags & FT_LOAD_NO_SCALE ) == 0 && |
1001 slot->format != FT_GLYPH_FORMAT_BITMAP && |
1041 slot->format != FT_GLYPH_FORMAT_BITMAP && |
1002 slot->format != FT_GLYPH_FORMAT_COMPOSITE ) |
1042 slot->format != FT_GLYPH_FORMAT_COMPOSITE ) |
1012 error = FT_Render_Glyph( slot, mode ); |
1052 error = FT_Render_Glyph( slot, mode ); |
1013 else |
1053 else |
1014 ft_glyphslot_preset_bitmap( slot, mode, NULL ); |
1054 ft_glyphslot_preset_bitmap( slot, mode, NULL ); |
1015 } |
1055 } |
1016 |
1056 |
1017 FT_TRACE5(( "FT_Load_Glyph: index %d, flags %x\n", |
1057 #ifdef FT_DEBUG_LEVEL_TRACE |
1018 glyph_index, load_flags )); |
1058 FT_TRACE5(( "FT_Load_Glyph: index %d, flags 0x%x\n", |
1059 glyph_index, load_flags )); |
|
1019 FT_TRACE5(( " x advance: %f\n", slot->advance.x / 64.0 )); |
1060 FT_TRACE5(( " x advance: %f\n", slot->advance.x / 64.0 )); |
1020 FT_TRACE5(( " y advance: %f\n", slot->advance.y / 64.0 )); |
1061 FT_TRACE5(( " y advance: %f\n", slot->advance.y / 64.0 )); |
1021 FT_TRACE5(( " linear x advance: %f\n", |
1062 FT_TRACE5(( " linear x advance: %f\n", |
1022 slot->linearHoriAdvance / 65536.0 )); |
1063 slot->linearHoriAdvance / 65536.0 )); |
1023 FT_TRACE5(( " linear y advance: %f\n", |
1064 FT_TRACE5(( " linear y advance: %f\n", |
1024 slot->linearVertAdvance / 65536.0 )); |
1065 slot->linearVertAdvance / 65536.0 )); |
1025 FT_TRACE5(( " bitmap %dx%d, mode %d\n", |
1066 FT_TRACE5(( " bitmap %dx%d, %s (mode %d)\n", |
1026 slot->bitmap.width, slot->bitmap.rows, |
1067 slot->bitmap.width, |
1027 slot->bitmap.pixel_mode )); |
1068 slot->bitmap.rows, |
1069 pixel_modes[slot->bitmap.pixel_mode], |
|
1070 slot->bitmap.pixel_mode )); |
|
1071 #endif |
|
1028 |
1072 |
1029 Exit: |
1073 Exit: |
1030 return error; |
1074 return error; |
1031 } |
1075 } |
1032 |
1076 |
1160 driver->root.memory, |
1204 driver->root.memory, |
1161 driver ); |
1205 driver ); |
1162 } |
1206 } |
1163 |
1207 |
1164 |
1208 |
1165 /*************************************************************************/ |
1209 /************************************************************************** |
1166 /* */ |
1210 * |
1167 /* <Function> */ |
1211 * @Function: |
1168 /* find_unicode_charmap */ |
1212 * find_unicode_charmap |
1169 /* */ |
1213 * |
1170 /* <Description> */ |
1214 * @Description: |
1171 /* This function finds a Unicode charmap, if there is one. */ |
1215 * This function finds a Unicode charmap, if there is one. |
1172 /* And if there is more than one, it tries to favour the more */ |
1216 * And if there is more than one, it tries to favour the more |
1173 /* extensive one, i.e., one that supports UCS-4 against those which */ |
1217 * extensive one, i.e., one that supports UCS-4 against those which |
1174 /* are limited to the BMP (said UCS-2 encoding.) */ |
1218 * are limited to the BMP (said UCS-2 encoding.) |
1175 /* */ |
1219 * |
1176 /* This function is called from open_face() (just below), and also */ |
1220 * This function is called from open_face() (just below), and also |
1177 /* from FT_Select_Charmap( ..., FT_ENCODING_UNICODE ). */ |
1221 * from FT_Select_Charmap( ..., FT_ENCODING_UNICODE ). |
1178 /* */ |
1222 */ |
1179 static FT_Error |
1223 static FT_Error |
1180 find_unicode_charmap( FT_Face face ) |
1224 find_unicode_charmap( FT_Face face ) |
1181 { |
1225 { |
1182 FT_CharMap* first; |
1226 FT_CharMap* first; |
1183 FT_CharMap* cur; |
1227 FT_CharMap* cur; |
1190 |
1234 |
1191 if ( !first ) |
1235 if ( !first ) |
1192 return FT_THROW( Invalid_CharMap_Handle ); |
1236 return FT_THROW( Invalid_CharMap_Handle ); |
1193 |
1237 |
1194 /* |
1238 /* |
1195 * The original TrueType specification(s) only specified charmap |
1239 * The original TrueType specification(s) only specified charmap |
1196 * formats that are capable of mapping 8 or 16 bit character codes to |
1240 * formats that are capable of mapping 8 or 16 bit character codes to |
1197 * glyph indices. |
1241 * glyph indices. |
1198 * |
1242 * |
1199 * However, recent updates to the Apple and OpenType specifications |
1243 * However, recent updates to the Apple and OpenType specifications |
1200 * introduced new formats that are capable of mapping 32-bit character |
1244 * introduced new formats that are capable of mapping 32-bit character |
1201 * codes as well. And these are already used on some fonts, mainly to |
1245 * codes as well. And these are already used on some fonts, mainly to |
1202 * map non-BMP Asian ideographs as defined in Unicode. |
1246 * map non-BMP Asian ideographs as defined in Unicode. |
1203 * |
1247 * |
1204 * For compatibility purposes, these fonts generally come with |
1248 * For compatibility purposes, these fonts generally come with |
1205 * *several* Unicode charmaps: |
1249 * *several* Unicode charmaps: |
1206 * |
1250 * |
1207 * - One of them in the "old" 16-bit format, that cannot access |
1251 * - One of them in the "old" 16-bit format, that cannot access |
1208 * all glyphs in the font. |
1252 * all glyphs in the font. |
1209 * |
1253 * |
1210 * - Another one in the "new" 32-bit format, that can access all |
1254 * - Another one in the "new" 32-bit format, that can access all |
1211 * the glyphs. |
1255 * the glyphs. |
1212 * |
1256 * |
1213 * This function has been written to always favor a 32-bit charmap |
1257 * This function has been written to always favor a 32-bit charmap |
1214 * when found. Otherwise, a 16-bit one is returned when found. |
1258 * when found. Otherwise, a 16-bit one is returned when found. |
1215 */ |
1259 */ |
1216 |
1260 |
1217 /* Since the `interesting' table, with IDs (3,10), is normally the */ |
1261 /* Since the `interesting' table, with IDs (3,10), is normally the */ |
1218 /* last one, we loop backwards. This loses with type1 fonts with */ |
1262 /* last one, we loop backwards. This loses with type1 fonts with */ |
1219 /* non-BMP characters (<.0001%), this wins with .ttf with non-BMP */ |
1263 /* non-BMP characters (<.0001%), this wins with .ttf with non-BMP */ |
1253 |
1297 |
1254 return FT_THROW( Invalid_CharMap_Handle ); |
1298 return FT_THROW( Invalid_CharMap_Handle ); |
1255 } |
1299 } |
1256 |
1300 |
1257 |
1301 |
1258 /*************************************************************************/ |
1302 /************************************************************************** |
1259 /* */ |
1303 * |
1260 /* <Function> */ |
1304 * @Function: |
1261 /* find_variant_selector_charmap */ |
1305 * find_variant_selector_charmap |
1262 /* */ |
1306 * |
1263 /* <Description> */ |
1307 * @Description: |
1264 /* This function finds the variant selector charmap, if there is one. */ |
1308 * This function finds the variant selector charmap, if there is one. |
1265 /* There can only be one (platform=0, specific=5, format=14). */ |
1309 * There can only be one (platform=0, specific=5, format=14). |
1266 /* */ |
1310 */ |
1267 static FT_CharMap |
1311 static FT_CharMap |
1268 find_variant_selector_charmap( FT_Face face ) |
1312 find_variant_selector_charmap( FT_Face face ) |
1269 { |
1313 { |
1270 FT_CharMap* first; |
1314 FT_CharMap* first; |
1271 FT_CharMap* end; |
1315 FT_CharMap* end; |
1292 |
1336 |
1293 return NULL; |
1337 return NULL; |
1294 } |
1338 } |
1295 |
1339 |
1296 |
1340 |
1297 /*************************************************************************/ |
1341 /************************************************************************** |
1298 /* */ |
1342 * |
1299 /* <Function> */ |
1343 * @Function: |
1300 /* open_face */ |
1344 * open_face |
1301 /* */ |
1345 * |
1302 /* <Description> */ |
1346 * @Description: |
1303 /* This function does some work for FT_Open_Face(). */ |
1347 * This function does some work for FT_Open_Face(). |
1304 /* */ |
1348 */ |
1305 static FT_Error |
1349 static FT_Error |
1306 open_face( FT_Driver driver, |
1350 open_face( FT_Driver driver, |
1307 FT_Stream *astream, |
1351 FT_Stream *astream, |
1308 FT_Bool external_stream, |
1352 FT_Bool external_stream, |
1309 FT_Long face_index, |
1353 FT_Long face_index, |
2174 FT_Face *aface, |
2218 FT_Face *aface, |
2175 const FT_Open_Args *args ) |
2219 const FT_Open_Args *args ) |
2176 { |
2220 { |
2177 |
2221 |
2178 #undef FT_COMPONENT |
2222 #undef FT_COMPONENT |
2179 #define FT_COMPONENT trace_raccess |
2223 #define FT_COMPONENT raccess |
2180 |
2224 |
2181 FT_Memory memory = library->memory; |
2225 FT_Memory memory = library->memory; |
2182 FT_Error error = FT_ERR( Unknown_File_Format ); |
2226 FT_Error error = FT_ERR( Unknown_File_Format ); |
2183 FT_UInt i; |
2227 FT_UInt i; |
2184 |
2228 |
2185 char * file_names[FT_RACCESS_N_RULES]; |
2229 char* file_names[FT_RACCESS_N_RULES]; |
2186 FT_Long offsets[FT_RACCESS_N_RULES]; |
2230 FT_Long offsets[FT_RACCESS_N_RULES]; |
2187 FT_Error errors[FT_RACCESS_N_RULES]; |
2231 FT_Error errors[FT_RACCESS_N_RULES]; |
2188 FT_Bool is_darwin_vfs, vfs_rfork_has_no_font = FALSE; /* not tested */ |
2232 FT_Bool is_darwin_vfs, vfs_rfork_has_no_font = FALSE; /* not tested */ |
2189 |
2233 |
2190 FT_Open_Args args2; |
2234 FT_Open_Args args2; |
2252 error = FT_ERR( Unknown_File_Format ); |
2296 error = FT_ERR( Unknown_File_Format ); |
2253 |
2297 |
2254 return error; |
2298 return error; |
2255 |
2299 |
2256 #undef FT_COMPONENT |
2300 #undef FT_COMPONENT |
2257 #define FT_COMPONENT trace_objs |
2301 #define FT_COMPONENT objs |
2258 |
2302 |
2259 } |
2303 } |
2260 |
2304 |
2261 |
2305 |
2262 /* Check for some macintosh formats without Carbon framework. */ |
2306 /* Check for some macintosh formats without Carbon framework. */ |
2280 error = IsMacBinary( library, stream, face_index, aface ); |
2324 error = IsMacBinary( library, stream, face_index, aface ); |
2281 if ( FT_ERR_EQ( error, Unknown_File_Format ) ) |
2325 if ( FT_ERR_EQ( error, Unknown_File_Format ) ) |
2282 { |
2326 { |
2283 |
2327 |
2284 #undef FT_COMPONENT |
2328 #undef FT_COMPONENT |
2285 #define FT_COMPONENT trace_raccess |
2329 #define FT_COMPONENT raccess |
2286 |
2330 |
2287 #ifdef FT_DEBUG_LEVEL_TRACE |
2331 #ifdef FT_DEBUG_LEVEL_TRACE |
2288 FT_TRACE3(( "Try as dfont: " )); |
2332 FT_TRACE3(( "Try as dfont: " )); |
2289 if ( !( args->flags & FT_OPEN_MEMORY ) ) |
2333 if ( !( args->flags & FT_OPEN_MEMORY ) ) |
2290 FT_TRACE3(( "%s ...", args->pathname )); |
2334 FT_TRACE3(( "%s ...", args->pathname )); |
2293 error = IsMacResource( library, stream, 0, face_index, aface ); |
2337 error = IsMacResource( library, stream, 0, face_index, aface ); |
2294 |
2338 |
2295 FT_TRACE3(( "%s\n", error ? "failed" : "successful" )); |
2339 FT_TRACE3(( "%s\n", error ? "failed" : "successful" )); |
2296 |
2340 |
2297 #undef FT_COMPONENT |
2341 #undef FT_COMPONENT |
2298 #define FT_COMPONENT trace_objs |
2342 #define FT_COMPONENT objs |
2299 |
2343 |
2300 } |
2344 } |
2301 |
2345 |
2302 if ( ( FT_ERR_EQ( error, Unknown_File_Format ) || |
2346 if ( ( FT_ERR_EQ( error, Unknown_File_Format ) || |
2303 FT_ERR_EQ( error, Invalid_Stream_Operation ) ) && |
2347 FT_ERR_EQ( error, Invalid_Stream_Operation ) ) && |
2691 if ( clazz->attach_file ) |
2735 if ( clazz->attach_file ) |
2692 error = clazz->attach_file( face, stream ); |
2736 error = clazz->attach_file( face, stream ); |
2693 |
2737 |
2694 /* close the attached stream */ |
2738 /* close the attached stream */ |
2695 FT_Stream_Free( stream, |
2739 FT_Stream_Free( stream, |
2696 (FT_Bool)( parameters->stream && |
2740 FT_BOOL( parameters->stream && |
2697 ( parameters->flags & FT_OPEN_STREAM ) ) ); |
2741 ( parameters->flags & FT_OPEN_STREAM ) ) ); |
2698 |
2742 |
2699 Exit: |
2743 Exit: |
2700 return error; |
2744 return error; |
2701 } |
2745 } |
2702 |
2746 |
3462 |
3506 |
3463 |
3507 |
3464 if ( !face ) |
3508 if ( !face ) |
3465 return FT_THROW( Invalid_Face_Handle ); |
3509 return FT_THROW( Invalid_Face_Handle ); |
3466 |
3510 |
3467 if ( encoding == FT_ENCODING_NONE ) |
3511 /* FT_ENCODING_NONE is a valid encoding for BDF, PCF, and Windows FNT */ |
3512 if ( encoding == FT_ENCODING_NONE && !face->num_charmaps ) |
|
3468 return FT_THROW( Invalid_Argument ); |
3513 return FT_THROW( Invalid_Argument ); |
3469 |
3514 |
3470 /* FT_ENCODING_UNICODE is special. We try to find the `best' Unicode */ |
3515 /* FT_ENCODING_UNICODE is special. We try to find the `best' Unicode */ |
3471 /* charmap available, i.e., one with UCS-4 characters, if possible. */ |
3516 /* charmap available, i.e., one with UCS-4 characters, if possible. */ |
3472 /* */ |
3517 /* */ |
3483 for ( ; cur < limit; cur++ ) |
3528 for ( ; cur < limit; cur++ ) |
3484 { |
3529 { |
3485 if ( cur[0]->encoding == encoding ) |
3530 if ( cur[0]->encoding == encoding ) |
3486 { |
3531 { |
3487 face->charmap = cur[0]; |
3532 face->charmap = cur[0]; |
3488 return 0; |
3533 return FT_Err_Ok; |
3489 } |
3534 } |
3490 } |
3535 } |
3491 |
3536 |
3492 return FT_THROW( Invalid_Argument ); |
3537 return FT_THROW( Invalid_Argument ); |
3493 } |
3538 } |
3508 |
3553 |
3509 cur = face->charmaps; |
3554 cur = face->charmaps; |
3510 if ( !cur || !charmap ) |
3555 if ( !cur || !charmap ) |
3511 return FT_THROW( Invalid_CharMap_Handle ); |
3556 return FT_THROW( Invalid_CharMap_Handle ); |
3512 |
3557 |
3513 if ( FT_Get_CMap_Format( charmap ) == 14 ) |
|
3514 return FT_THROW( Invalid_Argument ); |
|
3515 |
|
3516 limit = cur + face->num_charmaps; |
3558 limit = cur + face->num_charmaps; |
3517 |
3559 |
3518 for ( ; cur < limit; cur++ ) |
3560 for ( ; cur < limit; cur++ ) |
3519 { |
3561 { |
3520 if ( cur[0] == charmap ) |
3562 if ( cur[0] == charmap && |
3563 FT_Get_CMap_Format ( charmap ) != 14 ) |
|
3521 { |
3564 { |
3522 face->charmap = cur[0]; |
3565 face->charmap = cur[0]; |
3523 return FT_Err_Ok; |
3566 return FT_Err_Ok; |
3524 } |
3567 } |
3525 } |
3568 } |
4485 FT_Render_Glyph_Internal( FT_Library library, |
4528 FT_Render_Glyph_Internal( FT_Library library, |
4486 FT_GlyphSlot slot, |
4529 FT_GlyphSlot slot, |
4487 FT_Render_Mode render_mode ) |
4530 FT_Render_Mode render_mode ) |
4488 { |
4531 { |
4489 FT_Error error = FT_Err_Ok; |
4532 FT_Error error = FT_Err_Ok; |
4533 FT_Face face = slot->face; |
|
4490 FT_Renderer renderer; |
4534 FT_Renderer renderer; |
4491 |
4535 |
4492 |
4536 |
4493 /* if it is already a bitmap, no need to do anything */ |
|
4494 switch ( slot->format ) |
4537 switch ( slot->format ) |
4495 { |
4538 { |
4496 case FT_GLYPH_FORMAT_BITMAP: /* already a bitmap, don't do anything */ |
4539 case FT_GLYPH_FORMAT_BITMAP: /* already a bitmap, don't do anything */ |
4497 break; |
4540 break; |
4498 |
4541 |
4499 default: |
4542 default: |
4543 if ( slot->internal->load_flags & FT_LOAD_COLOR ) |
|
4544 { |
|
4545 FT_LayerIterator iterator; |
|
4546 |
|
4547 FT_UInt base_glyph = slot->glyph_index; |
|
4548 |
|
4549 FT_Bool have_layers; |
|
4550 FT_UInt glyph_index; |
|
4551 FT_UInt color_index; |
|
4552 |
|
4553 |
|
4554 /* check whether we have colored glyph layers */ |
|
4555 iterator.p = NULL; |
|
4556 have_layers = FT_Get_Color_Glyph_Layer( face, |
|
4557 base_glyph, |
|
4558 &glyph_index, |
|
4559 &color_index, |
|
4560 &iterator ); |
|
4561 if ( have_layers ) |
|
4562 { |
|
4563 error = FT_New_GlyphSlot( face, NULL ); |
|
4564 if ( !error ) |
|
4565 { |
|
4566 TT_Face ttface = (TT_Face)face; |
|
4567 SFNT_Service sfnt = (SFNT_Service)ttface->sfnt; |
|
4568 |
|
4569 |
|
4570 do |
|
4571 { |
|
4572 FT_Int32 load_flags = slot->internal->load_flags; |
|
4573 |
|
4574 |
|
4575 /* disable the `FT_LOAD_COLOR' flag to avoid recursion */ |
|
4576 /* right here in this function */ |
|
4577 load_flags &= ~FT_LOAD_COLOR; |
|
4578 |
|
4579 /* render into the new `face->glyph' glyph slot */ |
|
4580 load_flags |= FT_LOAD_RENDER; |
|
4581 |
|
4582 error = FT_Load_Glyph( face, glyph_index, load_flags ); |
|
4583 if ( error ) |
|
4584 break; |
|
4585 |
|
4586 /* blend new `face->glyph' into old `slot'; */ |
|
4587 /* at the first call, `slot' is still empty */ |
|
4588 error = sfnt->colr_blend( ttface, |
|
4589 color_index, |
|
4590 slot, |
|
4591 face->glyph ); |
|
4592 if ( error ) |
|
4593 break; |
|
4594 |
|
4595 } while ( FT_Get_Color_Glyph_Layer( face, |
|
4596 base_glyph, |
|
4597 &glyph_index, |
|
4598 &color_index, |
|
4599 &iterator ) ); |
|
4600 |
|
4601 if ( !error ) |
|
4602 slot->format = FT_GLYPH_FORMAT_BITMAP; |
|
4603 |
|
4604 /* this call also restores `slot' as the glyph slot */ |
|
4605 FT_Done_GlyphSlot( face->glyph ); |
|
4606 } |
|
4607 |
|
4608 if ( !error ) |
|
4609 return error; |
|
4610 |
|
4611 /* Failed to do the colored layer. Draw outline instead. */ |
|
4612 slot->format = FT_GLYPH_FORMAT_OUTLINE; |
|
4613 } |
|
4614 } |
|
4615 |
|
4500 { |
4616 { |
4501 FT_ListNode node = NULL; |
4617 FT_ListNode node = NULL; |
4502 |
4618 |
4503 |
4619 |
4504 /* small shortcut for the very common case */ |
4620 /* small shortcut for the very common case */ |
4530 } |
4646 } |
4531 |
4647 |
4532 #ifdef FT_DEBUG_LEVEL_TRACE |
4648 #ifdef FT_DEBUG_LEVEL_TRACE |
4533 |
4649 |
4534 #undef FT_COMPONENT |
4650 #undef FT_COMPONENT |
4535 #define FT_COMPONENT trace_bitmap |
4651 #define FT_COMPONENT checksum |
4536 |
4652 |
4537 /* |
4653 /* |
4538 * Computing the MD5 checksum is expensive, unnecessarily distorting a |
4654 * Computing the MD5 checksum is expensive, unnecessarily distorting a |
4539 * possible profiling of FreeType if compiled with tracing support. For |
4655 * possible profiling of FreeType if compiled with tracing support. For |
4540 * this reason, we execute the following code only if explicitly |
4656 * this reason, we execute the following code only if explicitly |
4541 * requested. |
4657 * requested. |
4542 */ |
4658 */ |
4543 |
4659 |
4544 /* we use FT_TRACE3 in this block */ |
4660 /* we use FT_TRACE3 in this block */ |
4545 if ( !error && |
4661 if ( !error && |
4546 ft_trace_levels[trace_bitmap] >= 3 && |
4662 ft_trace_levels[trace_checksum] >= 3 && |
4547 slot->bitmap.buffer ) |
4663 slot->bitmap.buffer ) |
4548 { |
4664 { |
4549 FT_Bitmap bitmap; |
4665 FT_Bitmap bitmap; |
4550 FT_Error err; |
4666 FT_Error err; |
4551 |
4667 |
4552 |
4668 |
4563 int i, j; |
4679 int i, j; |
4564 int rows = (int)bitmap.rows; |
4680 int rows = (int)bitmap.rows; |
4565 int pitch = bitmap.pitch; |
4681 int pitch = bitmap.pitch; |
4566 |
4682 |
4567 |
4683 |
4568 FT_TRACE3(( "FT_Render_Glyph: bitmap %dx%d, mode %d\n", |
4684 FT_TRACE3(( "FT_Render_Glyph: bitmap %dx%d, %s (mode %d)\n", |
4569 rows, pitch, slot->bitmap.pixel_mode )); |
4685 pitch, |
4686 rows, |
|
4687 pixel_modes[slot->bitmap.pixel_mode], |
|
4688 slot->bitmap.pixel_mode )); |
|
4570 |
4689 |
4571 for ( i = 0; i < rows; i++ ) |
4690 for ( i = 0; i < rows; i++ ) |
4572 for ( j = 0; j < pitch; j++ ) |
4691 for ( j = 0; j < pitch; j++ ) |
4573 coverage += bitmap.buffer[i * pitch + j]; |
4692 coverage += bitmap.buffer[i * pitch + j]; |
4574 |
4693 |
4592 /* |
4711 /* |
4593 * Dump bitmap in Netpbm format (PBM or PGM). |
4712 * Dump bitmap in Netpbm format (PBM or PGM). |
4594 */ |
4713 */ |
4595 |
4714 |
4596 /* we use FT_TRACE7 in this block */ |
4715 /* we use FT_TRACE7 in this block */ |
4597 if ( !error && |
4716 if ( !error && |
4598 ft_trace_levels[trace_bitmap] >= 7 && |
4717 ft_trace_levels[trace_checksum] >= 7 ) |
4599 slot->bitmap.rows < 128U && |
4718 { |
4600 slot->bitmap.width < 128U && |
4719 if ( slot->bitmap.rows < 128U && |
4601 slot->bitmap.buffer ) |
4720 slot->bitmap.width < 128U && |
4602 { |
4721 slot->bitmap.buffer ) |
4603 int rows = (int)slot->bitmap.rows; |
4722 { |
4604 int width = (int)slot->bitmap.width; |
4723 int rows = (int)slot->bitmap.rows; |
4605 int pitch = slot->bitmap.pitch; |
4724 int width = (int)slot->bitmap.width; |
4606 int i, j, m; |
4725 int pitch = slot->bitmap.pitch; |
4607 unsigned char* topleft = slot->bitmap.buffer; |
4726 int i, j, m; |
4608 |
4727 |
4609 if ( pitch < 0 ) |
4728 unsigned char* topleft = slot->bitmap.buffer; |
4610 topleft -= pitch * ( rows - 1 ); |
4729 |
4611 |
4730 |
4612 FT_TRACE7(( "Netpbm image: start\n" )); |
4731 if ( pitch < 0 ) |
4613 switch ( slot->bitmap.pixel_mode ) |
4732 topleft -= pitch * ( rows - 1 ); |
4614 { |
4733 |
4615 case FT_PIXEL_MODE_MONO: |
4734 FT_TRACE7(( "Netpbm image: start\n" )); |
4616 FT_TRACE7(( "P1 %d %d\n", width, rows )); |
4735 switch ( slot->bitmap.pixel_mode ) |
4617 for ( i = 0; i < rows; i++ ) |
|
4618 { |
4736 { |
4619 for ( j = 0; j < width; ) |
4737 case FT_PIXEL_MODE_MONO: |
4620 for ( m = 128; m > 0 && j < width; m >>= 1, j++ ) |
4738 FT_TRACE7(( "P1 %d %d\n", width, rows )); |
4621 FT_TRACE7(( " %d", ( topleft[i * pitch + j / 8] & m ) != 0 )); |
4739 for ( i = 0; i < rows; i++ ) |
4622 FT_TRACE7(( "\n" )); |
4740 { |
4741 for ( j = 0; j < width; ) |
|
4742 for ( m = 128; m > 0 && j < width; m >>= 1, j++ ) |
|
4743 FT_TRACE7(( " %d", |
|
4744 ( topleft[i * pitch + j / 8] & m ) != 0 )); |
|
4745 FT_TRACE7(( "\n" )); |
|
4746 } |
|
4747 break; |
|
4748 |
|
4749 default: |
|
4750 FT_TRACE7(( "P2 %d %d 255\n", width, rows )); |
|
4751 for ( i = 0; i < rows; i++ ) |
|
4752 { |
|
4753 for ( j = 0; j < width; j += 1 ) |
|
4754 FT_TRACE7(( " %3u", topleft[i * pitch + j] )); |
|
4755 FT_TRACE7(( "\n" )); |
|
4756 } |
|
4623 } |
4757 } |
4624 break; |
4758 FT_TRACE7(( "Netpbm image: end\n" )); |
4625 |
4759 } |
4626 default: |
4760 else |
4627 FT_TRACE7(( "P2 %d %d 255\n", width, rows )); |
4761 FT_TRACE7(( "Netpbm image: too large, omitted\n" )); |
4628 for ( i = 0; i < rows; i++ ) |
|
4629 { |
|
4630 for ( j = 0; j < width; j += 1 ) |
|
4631 FT_TRACE7(( " %3u", topleft[i * pitch + j] )); |
|
4632 FT_TRACE7(( "\n" )); |
|
4633 } |
|
4634 } |
|
4635 FT_TRACE7(( "Netpbm image: end\n" )); |
|
4636 } |
4762 } |
4637 |
4763 |
4638 #undef FT_COMPONENT |
4764 #undef FT_COMPONENT |
4639 #define FT_COMPONENT trace_objs |
4765 #define FT_COMPONENT objs |
4640 |
4766 |
4641 #endif /* FT_DEBUG_LEVEL_TRACE */ |
4767 #endif /* FT_DEBUG_LEVEL_TRACE */ |
4642 |
4768 |
4643 return error; |
4769 return error; |
4644 } |
4770 } |
4673 /*************************************************************************/ |
4799 /*************************************************************************/ |
4674 /*************************************************************************/ |
4800 /*************************************************************************/ |
4675 /*************************************************************************/ |
4801 /*************************************************************************/ |
4676 |
4802 |
4677 |
4803 |
4678 /*************************************************************************/ |
4804 /************************************************************************** |
4679 /* */ |
4805 * |
4680 /* <Function> */ |
4806 * @Function: |
4681 /* Destroy_Module */ |
4807 * Destroy_Module |
4682 /* */ |
4808 * |
4683 /* <Description> */ |
4809 * @Description: |
4684 /* Destroys a given module object. For drivers, this also destroys */ |
4810 * Destroys a given module object. For drivers, this also destroys |
4685 /* all child faces. */ |
4811 * all child faces. |
4686 /* */ |
4812 * |
4687 /* <InOut> */ |
4813 * @InOut: |
4688 /* module :: A handle to the target driver object. */ |
4814 * module :: |
4689 /* */ |
4815 * A handle to the target driver object. |
4690 /* <Note> */ |
4816 * |
4691 /* The driver _must_ be LOCKED! */ |
4817 * @Note: |
4692 /* */ |
4818 * The driver _must_ be LOCKED! |
4819 */ |
|
4693 static void |
4820 static void |
4694 Destroy_Module( FT_Module module ) |
4821 Destroy_Module( FT_Module module ) |
4695 { |
4822 { |
4696 FT_Memory memory = module->memory; |
4823 FT_Memory memory = module->memory; |
4697 FT_Module_Class* clazz = module->clazz; |
4824 FT_Module_Class* clazz = module->clazz; |
5026 } |
5153 } |
5027 |
5154 |
5028 service = (FT_Service_Properties)interface; |
5155 service = (FT_Service_Properties)interface; |
5029 |
5156 |
5030 if ( set ) |
5157 if ( set ) |
5031 missing_func = (FT_Bool)( !service->set_property ); |
5158 missing_func = FT_BOOL( !service->set_property ); |
5032 else |
5159 else |
5033 missing_func = (FT_Bool)( !service->get_property ); |
5160 missing_func = FT_BOOL( !service->get_property ); |
5034 |
5161 |
5035 if ( missing_func ) |
5162 if ( missing_func ) |
5036 { |
5163 { |
5037 FT_ERROR(( "%s: property service of module `%s' is broken\n", |
5164 FT_ERROR(( "%s: property service of module `%s' is broken\n", |
5038 func_name, module_name )); |
5165 func_name, module_name )); |
5154 if ( FT_NEW( library ) ) |
5281 if ( FT_NEW( library ) ) |
5155 return error; |
5282 return error; |
5156 |
5283 |
5157 library->memory = memory; |
5284 library->memory = memory; |
5158 |
5285 |
5159 #ifdef FT_CONFIG_OPTION_PIC |
|
5160 /* initialize position independent code containers */ |
|
5161 error = ft_pic_container_init( library ); |
|
5162 if ( error ) |
|
5163 goto Fail; |
|
5164 #endif |
|
5165 |
|
5166 library->version_major = FREETYPE_MAJOR; |
5286 library->version_major = FREETYPE_MAJOR; |
5167 library->version_minor = FREETYPE_MINOR; |
5287 library->version_minor = FREETYPE_MINOR; |
5168 library->version_patch = FREETYPE_PATCH; |
5288 library->version_patch = FREETYPE_PATCH; |
5169 |
5289 |
5170 library->refcount = 1; |
5290 library->refcount = 1; |
5171 |
5291 |
5172 /* That's ok now */ |
5292 /* That's ok now */ |
5173 *alibrary = library; |
5293 *alibrary = library; |
5174 |
5294 |
5175 return FT_Err_Ok; |
5295 return FT_Err_Ok; |
5176 |
|
5177 #ifdef FT_CONFIG_OPTION_PIC |
|
5178 Fail: |
|
5179 ft_pic_container_destroy( library ); |
|
5180 FT_FREE( library ); |
|
5181 return error; |
|
5182 #endif |
|
5183 } |
5296 } |
5184 |
5297 |
5185 |
5298 |
5186 /* documentation is in freetype.h */ |
5299 /* documentation is in freetype.h */ |
5187 |
5300 |
5235 * Close all faces in the library. If we don't do this, we can have |
5348 * Close all faces in the library. If we don't do this, we can have |
5236 * some subtle memory leaks. |
5349 * some subtle memory leaks. |
5237 * |
5350 * |
5238 * Example: |
5351 * Example: |
5239 * |
5352 * |
5240 * - the cff font driver uses the pshinter module in cff_size_done |
5353 * - the cff font driver uses the pshinter module in cff_size_done |
5241 * - if the pshinter module is destroyed before the cff font driver, |
5354 * - if the pshinter module is destroyed before the cff font driver, |
5242 * opened FT_Face objects managed by the driver are not properly |
5355 * opened FT_Face objects managed by the driver are not properly |
5243 * destroyed, resulting in a memory leak |
5356 * destroyed, resulting in a memory leak |
5244 * |
5357 * |
5245 * Some faces are dependent on other faces, like Type42 faces that |
5358 * Some faces are dependent on other faces, like Type42 faces that |
5246 * depend on TrueType faces synthesized internally. |
5359 * depend on TrueType faces synthesized internally. |
5247 * |
5360 * |
5248 * The order of drivers should be specified in driver_name[]. |
5361 * The order of drivers should be specified in driver_name[]. |
5308 } |
5421 } |
5309 } |
5422 } |
5310 } |
5423 } |
5311 #endif |
5424 #endif |
5312 |
5425 |
5313 #ifdef FT_CONFIG_OPTION_PIC |
|
5314 /* Destroy pic container contents */ |
|
5315 ft_pic_container_destroy( library ); |
|
5316 #endif |
|
5317 |
|
5318 FT_FREE( library ); |
5426 FT_FREE( library ); |
5319 |
5427 |
5320 Exit: |
5428 Exit: |
5321 return FT_Err_Ok; |
5429 return FT_Err_Ok; |
5322 } |
5430 } |
5400 |
5508 |
5401 return error; |
5509 return error; |
5402 } |
5510 } |
5403 |
5511 |
5404 |
5512 |
5513 /* documentation is in freetype.h */ |
|
5514 |
|
5515 FT_EXPORT_DEF( FT_Bool ) |
|
5516 FT_Get_Color_Glyph_Layer( FT_Face face, |
|
5517 FT_UInt base_glyph, |
|
5518 FT_UInt *aglyph_index, |
|
5519 FT_UInt *acolor_index, |
|
5520 FT_LayerIterator* iterator ) |
|
5521 { |
|
5522 TT_Face ttface; |
|
5523 SFNT_Service sfnt; |
|
5524 |
|
5525 |
|
5526 if ( !face || |
|
5527 !aglyph_index || |
|
5528 !acolor_index || |
|
5529 !iterator || |
|
5530 base_glyph >= (FT_UInt)face->num_glyphs ) |
|
5531 return 0; |
|
5532 |
|
5533 if ( !FT_IS_SFNT( face ) ) |
|
5534 return 0; |
|
5535 |
|
5536 ttface = (TT_Face)face; |
|
5537 sfnt = (SFNT_Service)ttface->sfnt; |
|
5538 |
|
5539 if ( sfnt->get_colr_layer ) |
|
5540 return sfnt->get_colr_layer( ttface, |
|
5541 base_glyph, |
|
5542 aglyph_index, |
|
5543 acolor_index, |
|
5544 iterator ); |
|
5545 else |
|
5546 return 0; |
|
5547 } |
|
5548 |
|
5549 |
|
5405 /* END */ |
5550 /* END */ |