Index: reactos/sdk/lib/3rdparty/freetype/ChangeLog =================================================================== --- reactos/sdk/lib/3rdparty/freetype/ChangeLog (revision 74184) +++ reactos/sdk/lib/3rdparty/freetype/ChangeLog (working copy) @@ -1,5 +1,1448 @@ 2016-09-08 Werner Lemberg + * Version 2.7.1 released. + ========================= + + + Tag sources with `VER-2-7-1'. + + * docs/VERSION.TXT: Add entry for version 2.7.1. + + * README, Jamfile (RefDoc), builds/windows/vc2005/freetype.vcproj, + builds/windows/vc2005/index.html, + builds/windows/vc2008/freetype.vcproj, + builds/windows/vc2008/index.html, + builds/windows/vc2010/freetype.vcxproj, + builds/windows/vc2010/index.html, + builds/windows/visualc/freetype.dsp, + builds/windows/visualc/freetype.vcproj, + builds/windows/visualc/index.html, + builds/windows/visualce/freetype.dsp, + builds/windows/visualce/freetype.vcproj, + builds/windows/visualce/index.html, + builds/wince/vc2005-ce/freetype.vcproj, + builds/wince/vc2005-ce/index.html, + builds/wince/vc2008-ce/freetype.vcproj, + builds/wince/vc2008-ce/index.html: s/2.7/2.7.1/, s/27/271/. + + * include/freetype/freetype.h (FREETYPE_PATCH): Set to 1. + + * builds/unix/configure.raw (version_info): Set to 19:0:13. + * CMakeLists.txt (VERSION_PATCH): Set to 1. + +2016-12-30 Werner Lemberg + + [ftfuzzer] Replace `rand' with an xorshift algorithm. + + * src/tools/ftfuzzer/ftfuzzer.cc: Don't include `stdlib.h'. + (Random): Implement and use a 32bit `xorshift' algorithm. + +2016-12-30 Werner Lemberg + + [ftfuzzer] Restrict number of tested bitmap strikes. + + Malformed fonts often have large values for the number of bitmap + strikes, and FreeType doesn't check the validity of all bitmap + strikes in advance. + + Reported as + + https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=353 + + * src/tools/ftfuzzer/ftfuzzer.cc: Include `stdlib.h' for `rand'. + (Random): Small class to provide n randomly selected numbers + (without repitition) out of the value set [1,N]. + (LLVMFuzzerTestOneInput): Use it to test only up to 10 bitmap + strikes. + +2016-12-29 Werner Lemberg + + [truetype] Variation font API stability issues. + + Make some functions work before a call to `TT_Set_MM_Blend'. + + * src/truetype/ttgxvar.c (tt_hadvance_adjust): Exit immediately if + we don't blend. + (TT_Get_MM_Blend, TT_Get_Var_Design): Return default values if we + don't blend. + +2016-12-29 Werner Lemberg + + * src/truetype/ttgxvar.c (TT_Get_MM_Var): Check axis data. + + Reported as + + https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=348 + +2016-12-29 Werner Lemberg + + [truetype] Tracing fixes. + + * src/truetype/ttgxvar.c (tt_hadvance_adjust): Emit correct + information. + (TT_Set_Var_Design): Fix typo. + (TT_Get_Var_Design): Fix typos. + +2016-12-29 Werner Lemberg + + */*: Use `0.5f' for tracing 16.16 numbers. + +2016-12-29 Werner Lemberg + + [pcf] Protect against gzip bombs. + + Fix suggested by Kostya; reported as + + https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=345 + + * src/pcf/pcfread.c (pcf_read_TOC): Limit number of TOC entries to + 1024. + +2016-12-28 Werner Lemberg + + [psnames] Only declare, not define, data in `pstables.h' (#49949). + + Pdfium includes `pstables.h' a second time; moving the definition + from `pstables.h' to `psmodule.c' saves more than 60kByte data + segment space for this case. + + * src/tools/glnames.py (StringTable::dump, + StringTable::dump_sublist, dump_encoding, dump_array): Emit + additional code to only define tables if `DEFINE_PS_TABLES' is set. + + * src/psnames/pstables.h: Regenerated. + * src/psnames/psmodule.c (DEFINE_PS_TABLES): Define. + +2016-12-28 Werner Lemberg + + [cff] Catch `blend' op in non-variant fonts. + + Reported as + + https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=334 + + * src/cff/cf2intrp.c (cf2_interpT2CharString) : Don't + allow `blend' op for non-variant fonts. + +2016-12-28 Werner Lemberg + + [cff] Better check of number of blends. + + * src/cff/cf2intrp.c (cf2_interpT2CharString) , + src/cff/cffparse.c (cff_parse_blend): Compare number of blends with + stack size. + +2016-12-27 Werner Lemberg + + Documentation updates. + + * docs/CHANGES: Add missing information. + + * docs/formats.txt: Rewritten and updated. + +2016-12-27 Werner Lemberg + + [truetype, type1] Implement `FT_Get_Var_Design_Coordinates'. + + * src/truetype/ttgxvar.c (TT_Get_Var_Design): Implement. + (TT_Set_Var_Design): Fix tracing. + + * src/type1/t1load.c (T1_Get_Var_Design): Implement. + +2016-12-24 Werner Lemberg + + * src/truetype/ttpload.c (tt_face_load_hdmx): Ignore `version'. + + Problem reported by 張俊芝 <418092625@qq.com>. + +2016-12-24 Werner Lemberg + + * src/sfnt/ttsbit.c (tt_face_load_sbit): Allow more version values. + + Some fonts seem to have the `version' field in the wrong byte order. + + Problem reported by 張俊芝 <418092625@qq.com>. + +2016-12-24 Werner Lemberg + + * src/truetype/ttpload.c (tt_face_load_loca): Sanitize table length. + + This trivial fix allows us to accept more fonts. + + Problem reported by 張俊芝 <418092625@qq.com>. + +2016-12-24 Werner Lemberg + + * src/sfnt/sfobjs.c (sfnt_init_face): Fix tracing. + +2016-12-22 Werner Lemberg + + * CMakeLists.txt: Make it work with cmake 2.8.11.2 (#49909). + +2016-12-22 Werner Lemberg + + Ensure used preprocessor symbols are defined (#49790). + + * builds/unix/ftconfig.in, builds/vms/ftconfig.h, + include/freetype/config/ftconfig.h: Check `__GNUC__', `__IBMC__', + and `__SUNPRO_C' correctly. + +2016-12-22 Werner Lemberg + + * src/base/ftrfork.c (FT_Raccess_Get_DataOffsets): Check `count'. + + Reported as + + https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=308 + +2016-12-22 Werner Lemberg + + [cff] Protect against invalid `vsindex' and `blend' values. + + Reported as + + https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=305 + + * src/cff/cf2intrp.c (cf2_interpT2CharString) : Implement it. + +2016-12-22 Werner Lemberg + + [ftfuzzer] Always use Adobe CFF engine. + + * src/tools/ftfuzzer/ftfuzzer.cc (FT_Global::FT_Global): Implement + it. + +2016-12-21 Werner Lemberg + + * src/truetype/ttgxvar.c (TT_Vary_Apply_Glyph_Deltas): Thinko. + + I should really stop coding late in the evening... + + Thanks again to Ben for checking. + +2016-12-21 Werner Lemberg + + [autofit] Support variation fonts. + + (This ChangeLog entry was added later on.) + + * src/autofit/afglobal.c (af_face_globals_free): Remove useless + code. + + * src/base/ftmm.c (FT_Set_MM_Design_Coordinates, + * FT_Set_Var_Design_Coordinates, FT_Set_MM_Blend_Coordinates, + FT_Set_Var_Blend_Coordinates): Finalize + auto-hinter data to enforce recomputation. Note that this is a + brute-force method which should be improved. + +2016-12-21 Werner Lemberg + + * src/truetype/ttgxvar.c (TT_Vary_Apply_Glyph_Deltas): Thinko. + + Don't apply deltas twice for non-phantom points. + + Spotted by Ben Wagner. + +2016-12-21 Werner Lemberg + + [cff, truetype] Another try for #49829. + + * src/cff/cffdrivr.c: Don't include + `FT_SERVICE_METRICS_VARIATIONS_H'. + (cff_get_advances): Use `ttface->variation_support'. + + * src/truetype/ttdriver.c (tt_get_advances): Use + `ttface->variation_support'. + + * src/truetype/ttgload.c (TT_Process_Simple_Glyph, + load_truetype_glyph): Use `ttface->variation_support'. + +2016-12-21 Werner Lemberg + + [truetype, sfnt] Introduce font variation flags to `TT_Face'. + + * include/freetype/internal/tttypes.h (TT_FACE_FLAG_VAR_XXX): + New macros describing available functionality of various OpenType + tables related to font variation. + (TT_Face): New fields `variation_support' and `mvar_support', + replacing and extending `use_fvar'. + + * src/sfnt/sfobjs.c (sfnt_init_face, sfnt_load_face): Use + `variation_support'. + + * src/truetype/ttgxvar.c (ft_var_load_hvar): Set `variation_support' + field. + (TT_Vary_Apply_Glyph_Deltas): Updated. + +2016-12-21 Werner Lemberg + + [base] Improve sanity check for Mac resources (#49888). + + * src/base/ftobjs.c (Mac_Read_sfnt_Resource): Abort if `rlen' is not + positive. + +2016-12-20 Werner Lemberg + + [base] More sanity checks for Mac resources. + + We use + + https://github.com/kreativekorp/ksfl/wiki/Macintosh-Resource-File-Format + + and + + https://developer.apple.com/legacy/library/documentation/mac/pdf/MoreMacintoshToolbox.pdf#page=151 + + as references. + + * include/freetype/internal/ftrfork.h (FT_RFork_Ref): Use FT_Short + for `res_id'. + + * src/base/ftrfork.c (FT_Raccess_Get_HeaderInfo): Extract map length + and use it to improve sanity checks. + Follow the specification more closely;in particular, all data types + are signed, not unsigned. + (FT_Raccess_Get_DataOffsets): Follow the specification more closely; + in particular, all data types are signed, not unsigned. + Add some sanity checks. + +2016-12-20 Werner Lemberg + + [truetype] Improve logic for getting fast advance widths. + + * src/cff/cffdrivr.c (cff_get_advances), src/truetype/ttdriver.c + (tt_get_advances): Use `is_default_instance' for test; this gets + recomputed after changing blend coordinates. + +2016-12-20 Ben Wagner + Werner Lemberg + + [truetype] Fix linear metrics of GX variation fonts (#49829). + + When asking for an unhinted non-default variations, + `linearVertAdvance' is currently the value from the `hmtx' table + instead of the actual value after applying the variation. `HVAR' + support fixes this, but fonts will exist without that table and will + need sane fallback. + + Problem also reported as + + https://bugs.chromium.org/p/skia/issues/detail?id=5917 + + * src/truetype/ttgload.c (TT_Process_Simple_Glyph, + load_truetype_glyph): Implement linear advance adjustments if `HVAR' + or `VVAR' tables are missing. + +2016-12-20 Werner Lemberg + + [cff, truetype] Fast advance width retrieval for fonts with HVAR. + + Everything is guarded with TT_CONFIG_OPTION_GX_VAR_SUPPORT. + + * src/base/ftadvanc.c (LOAD_ADVANCE_FAST_CHECK): Don't handle MM. + + * src/cff/cffdrivr.c: Include FT_SERVICE_METRICS_VARIATIONS_H. + (cff_get_advances): Test for HVAR and VVAR. + + * src/truetype/ttdriver.c (tt_get_advances): Test for HVAR and VVAR. + +2016-12-18 Werner Lemberg + + [base] Fix invalid mac font recursion. + + Reported as + + https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=304 + + * src/base/ftobjs.c (FT_Open_Face): Code moved to... + (ft_open_face_internal): ... this function. + Add a parameter to control whether we try special Mac font handling + in case of failure. + (FT_Open_Face, FT_New_Face, FT_New_Memory_Face, + open_face_from_buffer): Use `ft_open_face_internal'. + +2016-12-18 Werner Lemberg + + * src/cff/cffobjs.c (cff_face_init): Make named instances work. + +2016-12-18 Werner Lemberg + + [truetype, cff] Extend `get_var_blend' function of MM service. + + In particular, we need access to named instance data. + + * include/freetype/internal/services/svmm.h (FT_Get_Var_Blend_Func): + Add argument for `FT_MM_Var'. + + * src/cff/cffload.c (cff_get_var_blend): Updated. + * src/cff/cffload.h: Updated. + + * src/cff/cf2ft.c (cf2_getNormalizedVector): Updated. + + * src/truetype/ttgxvar.c (tt_get_var_blend): Updated. + Accept value `NULL' for arguments. + * src/truetype/ttgxvar.h: Updated. + +2016-12-18 Werner Lemberg + + [sfnt] Handle `fvar' with zero axes as a non-MM font. + + This is better behaviour than exiting with an error. + + * include/freetype/internal/tttypes.h (TT_Face): Add `use_fvar' + field. + + * src/sfnt/sfobjs.c (sfnt_init_face): Compute `use_fvar', also + updating the validation code. + Use `use_fvar' to compute FT_FACE_FLAG_MULTIPLE_MASTERS. + + * src/truetype/ttgxvar.c (TT_Get_MM_Var): Remove `fvar' validation + code. + +2016-12-18 Werner Lemberg + + Minor GX code shuffling. + + * include/freetype/internal/tttypes.h (TT_Face): Move + `is_default_instance' into TT_CONFIG_OPTION_GX_VAR_SUPPORT + block. + + * src/sfnt/sfobjs.c (sfnt_init_face): Updated. + * src/truetype/ttgload.c (IS_DEFAULT_INSTANCE): New macro. + (TT_Load_Glyph): Use it. + +2016-12-18 Werner Lemberg + + [cff] Better handling of non-CFF font formats. + + * src/cff/cffload.c (cff_font_load): Pure CFFs don't have a + signature, so return `FT_Err_Unknown_File_Format' more often. + +2016-12-17 Werner Lemberg + + * src/cff/cffload.c (cff_build_blend_vector): Remove redundant code. + +2016-12-17 Werner Lemberg + + * src/truetype/ttobjs.c (tt_face_init): Simplify conditional code. + +2016-12-17 Werner Lemberg + + [sfnt, truetype] Various sanitizing fixes. + + * src/sfnt/sfobjs.c (sfnt_init_face): If the axis count in `fvar' is + zero, set `num_instances' to zero. + + * src/truetype/ttgxvar.c (TT_Get_MM_Var): Handle `fvar' table with + zero axes as invalid. + + * src/truetype/ttobjs.c (tt_face_init): Improve logic of loading + `loca', `cvt', `fpgm', and `prep' table. + +2016-12-17 Werner Lemberg + + Improve tracing of `FT_Open_Face'. + + * src/base/ftobjs.c (FT_Open_Face): Return info on number of + available faces and numbered instances, or the indices of the + requested face and numbered instance. + + * src/sfnt/sfobjs. (sfnt_open_font): Trace number of subfonts. + +2016-12-17 Werner Lemberg + + * src/cff/cffload.c (cff_load_private_dict): Always init `blend'. + + Reported as + + https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=295 + +2016-12-16 Werner Lemberg + + [truetype] Fix `cvar' sanity test. + + Reported by Dave Arnold. + + * src/truetype/ttgxvar.c (tt_face_vary_cvt): Use tuple count mask. + +2016-12-16 Werner Lemberg + + [cff, truetype] Remove compiler warnings; fix `make multi'. + + * src/cff/cf2font.h: Include `cffload.h'. + + * src/cff/cffload.c: Include FT_MULTIPLE_MASTERS_H and + FT_SERVICE_MULTIPLE_MASTERS_H. + (cff_vstore_load): Eliminate `vsSize'. + (cff_load_private_dict): Tag as `FT_LOCAL_DEF'. + + * src/cff/cffload.h: Include `cffobjs.h'. + Provide declaration for `cff_load_private_dict'. + + * src/truetype/ttgxvar.c (ft_var_load_hvar): Eliminate + `minorVersion' and `map_offset'. + +2016-12-16 Werner Lemberg + + [cff] Fix heap buffer overflow (#49858). + + * src/cff/cffparse.c (cff_parser_run): Add one more stack size + check. + +2016-12-15 Werner Lemberg + + Fix clang warnings. + + * src/cff/cffload.c (cff_blend_doBlend): Add cast. + (cff_subfont_load): Set `error' correctly. + + * src/sfnt/ttmtx.c (tt_face_get_metrics): Typo. + +2016-12-15 Dave Arnold + Werner Lemberg + + [cff] Implement CFF2 support (2/2). + + The font variation code. All parts dependent on the GX code in the + `truetype' module are guarded with TT_CONFIG_OPTION_GX_VAR_SUPPORT. + In other words, you can still compile the `cff' module without + defining TT_CONFIG_OPTION_GX_VAR_SUPPORT (which brings you CFF2 + support without font variation). + + * src/cff/cf2font.c (cf2_font_setup): Add support for font + variation. + * src/cff/cf2font.h (CF2_Font): Add fields for variation data. + + * src/cff/cf2ft.c (cf2_free_instance): Free blend data. + (cf2_getVStore, cf2_getNormalizedVector): New functions. + * src/cff/cf2ft.h: Updated. + + * src/cff/cf2intrp.c: Include `cffload.h'. + (cf2_cmdRESERVED_15, cf2_cmdRESERVED_16): Replace with... + (cf2_cmdVSINDEX, cf2_cmdBLEND): ... this new enum values. + (cf2_doBlend): New function. + (cf2_interpT2CharString): Handle `vsindex' and `blend' opcodes. + + * src/cff/cffload.c (FT_fdot14ToFixed): New macro. + (cff_vstore_done, cff_vstore_load): New functions. + (cff_blend_clear, cff_blend_doBlend, cff_blend_build_vector, + cff_blend_check_vector): New functions. + (cff_load_private_dict): Add arguments for blend vector. + Handle blend data. + (cff_subfont_load, cff_subfont_done): Updated. + (cff_font_load): Handle CFF2 variation store data. + (cff_font_done): Updated. + * src/cff/cffload.h: Include `cffparse.h'. + Updated. + + * src/cff/cffobjs.c (cff_face_done): Updated. + + * src/cff/cffparse.c: Include `cffload.h'. + (cff_parse_num): Handle internal value 255. + (cff_parse_vsindex, cff_parse_blend): New functions. + (CFF_FIELD_BLEND): New macro. + (cff_parser_run): Updated. + * src/cff/cffparse.h (cff_kind_blend): New enum value. + + * src/cff/cfftoken.h: Handle `vstore', `vsindex', and `blend' + dictionary values. + + * src/cff/cfftypes.h (CFF_VarData, CFF_AxisCoords, CFF_VarRegion, + CFF_VStore, CFF_Blend): New structures. + (CFF_FontRecDict): Add `vstore_offset' field. + (CFF_Private): Add `vsindex' field. + (CFF_SubFont): Add fields for blend data. + (CFF_Font): Add `vstore' field. + + * src/truetype/ttgxvar.c (TT_Get_MM_Var): `CFF2' is equal to `gvar', + since glyph variation data is directly embedded. + (TT_Set_MM_Blend): Don't load `gvar' table for CFF2 fonts. + +2016-12-15 Dave Arnold + Werner Lemberg + + [cff] Implement CFF2 support (1/2). + + This commit does not contain the blend code for font variation + support, which follows in another commit. + + You should ignore whitespace while inspecting this commit. + + * include/freetype/internal/tttypes.h (TT_Face): Add `isCFF2' + member. + + * src/cff/cf2font.h (CF2_Font): Add `isCFF2' member. + + * src/cff/cf2ft.c (cf2_decoder_parse_charstrings): Handle `isCFF2' + flag. + (cf2_getMaxstack): New function. + * src/cff/cf2ft.h: Updated. + + * src/cff/cf2intrp.c (cf2_escRESERVED_38): New enum. + (cf2_interpT2CharString): Handle CFF2 differences. + Add tracing message for errors. + + * src/cff/cffdrivr.c (cff_get_glyph_name, cff_get_name_index): + Update for CFF2. + + * src/cff/cffload.c (FT_FIXED_ONE): New macro. + (cff_index_init, cff_index_load_offsets, cff_index_access_element, + cff_index_get_name, cff_ft_select_get, cff_load_private_dict, + cff_subfont_load, cff_font_load): Handle CFF2. + * src/cff/cffload.h: Updated. + + * src/cff/cffobjs.c (cff_face_init): Handle CFF2. + + * src/cff/cffparse.c (cff_parse_maxstack): New function. + (CFFCODE_TOPDICT, CFFCODE_PRIVATE): Removed + * src/cff/cffparse.h (CFF2_MAX_STACK, CFF2_DEFAULT_STACK): New + macros. + (CFF2_CODE_TOPDICT, CFF2_CODE_FONTDICT, CFF2_CODE_PRIVATE): New + macros. + + * src/cff/cfftoken.h: Add fields for CFF2 dictionaries (but no blend + stuff). + + * src/cff/cfftypes.h (CFF_Index): Add `hdr_size' field. + (CFF_FontRecDict): Add `maxstack' field. + (CFF_Private): Add `subfont' field. + (CFF_Font): Add `top_dict_length' and `cff2' fields. + + * src/sfnt/sfobjs.c (sfnt_load_face): Handle `CFF2' table. + +2016-12-15 Werner Lemberg + Dave Arnold + + [truetype] Provide HVAR advance width variation as a service. + + Everything is guarded with TT_CONFIG_OPTION_GX_VAR_SUPPORT. + + * src/truetype/ttdriver.c (tt_service_metrics_variations): Updated. + + * src/truetype/ttgxvar.c (TT_Vary_Apply_Glyph_Deltas): Prevent + double adjustment of advance width. + + * src/sfnt/ttmtx.c: Include FT_SERVICE_METRICS_VARIATIONS_H. + (tt_face_get_metrics): Apply metrics variations. + +2016-12-15 Dave Arnold + Werner Lemberg + + [truetype] Provide function to apply `HVAR' advance width variation. + + Everything is guarded with TT_CONFIG_OPTION_GX_VAR_SUPPORT. + + * src/truetype/ttgxvar.c (tt_hadvance_adjust): New function. + * src/truetype/ttgxvar.h: Updated. + +2016-12-15 Dave Arnold + Werner Lemberg + + [truetype] Add `HVAR' table parsing. + + Note that this is not complete yet; it only handles advance width + variation. + + Activation of the code follows in another commit. + + Everything is guarded with TT_CONFIG_OPTION_GX_VAR_SUPPORT. + + * include/freetype/ftmm.h (FT_Var_Named_Style): Add `psid' member. + + * src/truetype/ttgxvar.h (GX_HVarData, GX_AxisCoords, GX_HVarRegion, + GX_HVStore, GX_WidthMap): New auxiliary structures for... + (GX_HVarTable): ... HVAR main structure. + (GX_BlendRec): Add data for HVAR loading. + + * src/truetype/ttgxvar.c (FT_FIXED_ONE, FT_fdot14ToFixed, + FT_intToFixed, FT_fixedToInt): New macros. + (ft_var_load_hvar): New function. + (TT_Get_MM_Var): Updated. + (tt_done_blend): Deallocate HVAR data. + +2016-12-15 Dave Arnold + + [cff] Extend number parsing. + + The forthcoming CFF2 support needs a dynamic parsing limit. + + * src/cff/cffparse.c (cff_parse_num, do_fixed, cff_parse_fixed, + cff_parse_fixed_scaled, cff_parse_fixed_dynamic): Add argument for + parser. + (cff_parse_font_matrix, cff_parse_font_bbox, cff_parse_private_dict, + cff_parse_multiple_master, cff_parse_cid_ros, cff_parser_run): Updated. + + * src/cff/cffparse.h (cff_parse_num): Export locally. + +2016-12-15 Dave Arnold + + [cff] Implement dynamic stack size for Adobe engine. + + This also adds `cf2_stack_setReal' and `cf2_stack_pop', needed for + the forthcoming CFF2 support. + + * src/cff/cf2stack.c (cf2_stack_init): Add argument for stack size. + (cf2_stack_free): Deallocate stack. + (cf2_stack_count, cf2_stack_pushInt, cf2_stack_pushFixed, + cf2_stack_popInt, cf2_stack_popFixed, cf2_stack_getReal, + cf2_stack_clear): Updated. + (cf2_stack_setReal, cf2_stack_pop): New functions. + + * src/cff/cf2stack.h (CF2_Stack): Add `stackSize' member. + Update function declarations. + + * src/cff/cf2intrp.c (cf2_interpT2CharString): Updated. + + * src/cff/cffparse.c (cff_parser_init): Add parameter for stack + size; return error code. + (cff_parser_done): New function. + (cff_parser_run): Updated. + + * src/cff/cffparse.h (CFF_Parser): Add `stackSize' member and make + `stack' a pointer. + Update function declarations. + + * src/cff/cffload.c (cff_load_private_dict, cff_subfont_load): + Updated. + +2016-12-15 Dave Arnold + Werner Lemberg + + [cff] Code shuffling. + + * src/cff/cfftypes.h (CFF_Font): Add `library' and `base_offset' + fields. + + * src/cff/cffload.c (cff_subfont_load): Change last argument to + `CFF_Font' + Split off parsing of private dictionary into... + (cff_load_private_dict): ...this new function. + (cff_font_load): Updated. + +2016-12-14 Werner Lemberg + + [sfnt, truetype] Add framework for Metrics Variations service. + + No effect yet; service functions will be implemented later on. + + Everything is guarded with TT_CONFIG_OPTION_GX_VAR_SUPPORT. + + * include/freetype/internal/services/svmetric.h: New file. + + * include/freetype/internal/ftserv.h + (FT_SERVICE_METRICS_VARIATIONS_H): New macro. + + * include/freetype/internal/tttypes.h (TT_Face): New field `var'. + + * src/sfnt/sfobjs.c: Include FT_SERVICE_METRICS_VARIATIONS_H. + (sfnt_init_face): Initialize `face->var'. + + * src/truetype/ttdriver.c: Include FT_SERVICE_METRICS_VARIATIONS_H. + (tt_service_metrics_variations): New service. + (tt_services): Updated. + + * src/truetype/ttpic.h: Updated. + +2016-12-14 Werner Lemberg + + [cff] Add Multiple Masters service. + + The code simply uses the MM functions from the `truetype' module. + + Everything is guarded with TT_CONFIG_OPTION_GX_VAR_SUPPORT. + + * include/freetype/internal/tttypes.h (TT_Face): New field `mm'. + + * src/cff/cffdrivr.c: Include FT_SERVICE_MULTIPLE_MASTERS_H. + (cff_set_mm_blend, cff_get_mm_blend, cff_get_mm_var, + cff_set_var_design, cff_get_var_design): New functions. + (cff_service_multi_masters): New service. + (cff_services): Updated. + + * src/cff/cffload.c (cff_get_var_blend, cff_done_blend): New + functions. + * src/cff/cffload.h: Updated. + + * src/cff/cffpic.h (CFF_SERVICE_MULTI_MASTERS_GET): New macro. + + * src/sfnt/sfobjs.c: Include FT_SERVICE_MULTIPLE_MASTERS_H. + (sfnt_init_face): Initialize `face->mm'. + +2016-12-14 Werner Lemberg + + Extend functionality of `ft_module_get_service'. + + It can now differentiate between local and global searches. + + * src/base/ftobjs.c (ft_module_get_service): Add `global' argument. + (FT_Get_TrueType_Engine_Type): Updated. + + * src/cff/cffdrivr.c (cff_get_ps_name, cff_get_cmap_info): Updated. + + * include/freetype/internal/ftobjs.h: Updated. + * include/freetype/internal/ftserv.h (FT_FACE_FIND_GLOBAL_SERVICE): + Updated. + +2016-12-14 Werner Lemberg + + * src/truetype/ttgxvar.c (tt_get_var_blend): Fix compiler warning. + +2016-12-14 Dave Arnold + Werner Lemberg + + [sfnt, cff] Minor preparations. + + * include/freetype/tttags.h (TTAG_CFF2, TTAG_HVAR, TTAG_MVAR, + TTAG_VVAR): New SFNT table tags. + + * src/cff/cf2fixed.h (CF2_FIXED_ONE, CF2_FIXED_EPSILON): Add cast. + +2016-12-10 Werner Lemberg + + [truetype, type1] Add `get_var_blend' to MM service. + + For internal use; we want to share code between the forthcoming CFF2 + support and TrueType. + + * include/freetype/internal/services/svmm.h (FT_Get_Var_Blend_Func): + New typedef. + (MultiMasters): Add `get_var_blend'. + (FT_Service_MultiMasters): Updated. + + * src/truetype/ttgxvar.c (tt_get_var_blend): New function. + * src/truetype/ttgxvar.h: Updated. + + * src/truetype/ttdriver.c (tt_service_gx_multi_masters): Updated. + * src/type1/t1driver.c (t1_service_multi_masters): Updated. + +2016-12-10 Werner Lemberg + + [truetype, type1] Add `done_blend' to MM service. + + For internal use; we want to share code between the forthcoming CFF2 + support and TrueType. + + * include/freetype/internal/services/svmm.h (FT_Done_Blend_Func): + New typedef. + (MultiMasters): Add `done_blend'. + (FT_Service_MultiMasters): Updated. + + * src/truetype/ttgxvar.c (tt_done_blend): Use `TT_Face' as argument. + * src/truetype/ttgxvar.h: Updated. + + * src/truetype/ttobjs.c (TT_Face_Done): Updated. + + * src/truetype/ttdriver.c (tt_service_gx_multi_masters): Updated. + * src/type1/t1driver.c (t1_service_multi_masters): Updated. + +2016-12-09 Werner Lemberg + + [sfnt] Revert change from 2016-12-08. + + I missed the functionality of `ft_module_get_service', which makes + the change unnecessary. + +2016-12-08 Werner Lemberg + + Add framework to support services with 8 functions. + + We will need this for CFF variation font support. + + * include/freetype/internal/ftserv.h (FT_DEFINE_SERVICEDESCREC8): + New macro. + +2016-12-08 Werner Lemberg + + [sfnt] Add `get_glyph_name' and `get_name_index' to SFNT interface. + + CFF2 fonts will need access to those two functions. + + * include/freetype/internal/sfnt.h: Include FT_SERVICE_GLYPH_DICT_H. + (SFNT_Interface): Add `get_glyph_name' and `get_name_index' members. + (FT_DEFINE_SFNT_INTERFACE): Updated. + + * src/sfnt/sfdriver.c (sfnt_get_glyph_name, sfnt_get_name_index): + Fix signatures to exactly correspond to the glyph dict service + function typedefs. + (sfnt_interface): Updated. + +2016-12-06 Dave Arnold + + Add `FT_Get_Var_Design_Coordinates' function. + + Note that the low-level functions aren't implemented yet. + + * include/freetype/ftmm.h: Declare. + + * include/freetype/internal/services/svmm.h + (FT_Get_Var_Design_Func): New typedef. + (MultiMasters): New MM service function `get_var_design'. + (FT_DEFINE_SERVICE_MULTIMASTERSREC): Updated. + Update all callers. + + * src/base/ftmm.c (FT_Get_Var_Design_Coordinates): Implement. + + * src/truetype/ttdriver.c: Updated. + + * src/truetype/ttgxvar.c (TT_Get_Var_Design): New dummy function to + handle `get_var_design' service. + * src/truetype/ttgxvar.h: Updated. + + * src/type1/t1driver.c: Updated. + + * src/type1/t1load.c (T1_Get_Var_Design): New dummp function to + handle `get_var_design' service. + * src/type1/t1load.h: Updated. + +2016-12-06 Werner Lemberg + + * src/type1/t1load.c (parse_subrs): Fix memory leak. + + The `subrs' keyword might erroneously occur multiple times. + + Reported as + + https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=231 + +2016-12-01 Werner Lemberg + + [gzip] Improve building with external zlib (#49673). + + Building FreeType with external zlib 1.2.8 makes msvc 14 stop with + the following error. + + ftgzip.c + zlib-1.2.8\zlib.h(86): error C2061: + syntax error: identifier 'z_const' + zlib-1.2.8\zlib.h(94): error C2054: + expected '(' to follow 'z_const' + zlib-1.2.8\zlib.h(94): error C2085: + 'msg': not in formal parameter list + ... + zlib-1.2.8\zlib.h(877): fatal error C1003: + error count exceeds 100; stopping compilation + + The error happens because FreeType keeps an own copy of zlib-1.1.4 + under `src/gzip'. When building `src/gzip/ftgzip.c' with + FT_CONFIG_OPTION_SYSTEM_ZLIB defined, it uses + + #include + + which correctly finds an external `zlib.h', but `zlib.h' itself has + a line + + #include "zconf.h" + + which makes Visual Studio 2015 find `src/gzip/zconf.h' while + compiling the files in `src/gzip'. + + * src/gzip/zconf.h: Rename to... + * src/gzip/ftzconf.h: ... this. + * src/gzip/zlib.h, src/gzip/rules.mk (GZIP_DRV_SRCS): Updated. + +2016-12-01 Oleksandr Chekhovskyi + + [autofit] Fix Emscripten crash (patch #9180). + + Function calls through pointers must use a matching signature to + work on Emscripten, since such calls are dispatched through lookup + tables grouped by signature. + + * src/autofit/aftypes.h (AF_WritingSystem_ApplyHintsFunc): Fix + typedef. + +2016-11-29 Werner Lemberg + + [smooth] Revert previous commit. Already fixed with 6ca54c64. + +2016-11-29 Werner Lemberg + + [smooth] Avoid conditional jump on uninitialized value (#49711). + + * src/smooth/ftgrays.c (gray_raster_render): Initialize `worker'. + +2016-11-27 Nikolaus Waxweiler + + [autofit] Code shuffling. + + Also improve some comments and remove unused code. + + No functional change. + + * src/autofit/afloader.c (af_loader_load_g): Merged with... + (af_loader_load_glyph): ...this function. + Split off emboldening code into... + (af_loader_embolden_glyph_in_slot): ... this function. + +2016-11-17 Werner Lemberg + + Better support of LLP64 systems with gcc (and clang). + + * builds/unix/configure.raw: Call `AC_TYPE_LONG_LONG_INT'. + + * builds/unix/ftconfig.in (FT_LONG64): Enable for LLP64 systems (and + suppress warnings) even without `FT_CONFIG_OPTION_FORCE_INT64'. + +2016-11-10 Werner Lemberg + + Fix `lcd_weights' array size. + + * include/freetype/internal/ftobjs.h (FT_LibraryRec): Do it. + + Reported by Nikolaus. + +2016-11-06 Werner Lemberg + + * src/base/ftobjs.c (FT_Render_Glyph_Internal): Fix tracing. + +2016-11-06 Werner Lemberg + + [sfnt] Improve FT_LOAD_BITMAP_METRICS_ONLY for `sbix' format. + + It's unavoidable to call the PNG engine, but to get the metrics it + is sufficient to read the PNG image's header only. + + * src/sfnt/pngshim.c (Load_SBit_Png): Add argument to control the + allocation of the glyph slot. + * src/sfnt/pngshim.h: Updated. + * src/sfnt/ttsbit.c (tt_sbit_decoder_load_png, + tt_face_load_sbix_image, tt_face_load_sbit_image): Updated. + +2016-11-06 Werner Lemberg + + [sfnt] Speed up `sbix' lookup. + + This also fixes a bug introduced in 2016-10-01 which prevents + display of embedded bitmap fonts that use the `sbix' format. + + * src/sfnt/ttsbit.c (tt_face_load_sbit): Store `sbix' size and + offset also in `ebdt_size' and `ebdt_start', respectively. This + makes the test for an embedded bitmap data table succeed for this + format. + + (tt_face_load_strike_metrics) : Use + `ebdt_size' and `ebdt_start' + (tt_face_load_sbix_image): Ditto. + +2016-11-06 Seigo Nonaka + Werner Lemberg + + Introduce a way of quickly retrieving (embedded) bitmap metrics. + + `FT_Load_Glyph' doesn't generate a bitmap for a non-bitmap glyph + until the user calls `FT_Render_Glyph'. However, it always + allocates memory for bitmaps and copies or decodes the contents of a + bitmap glyph, which can be quite slow for PNG data. + + * include/freetype/freetype.h (FT_LOAD_BITMAP_METRICS_ONLY): New + macro. + + * src/base/ftobjs.c (FT_Load_Glyph): Unset FT_LOAD_RENDER if + FT_LOAD_BITMAP_METRICS_ONLY is used. + + * src/sfnt/ttsbit.c (tt_sbit_decoder_alloc_bitmap, + tt_sbit_decoder_load_bitmap): Add argument to control allocation of + the glyph slot. + (tt_sbit_decoder_load_image, tt_sbit_decoder_load_compound, + tt_face_load_sbit_image): Updated. + + * src/pcf/pcfdrivr.c (PCF_Glyph_Load): Quickly exit if + `FT_LOAD_BITMAP_METRICS_ONLY' is set. + + * src/pfr/pfrsbit.c, src/pfr/pfrsbit.h (pfr_slot_load_bitmap): Add + argument to control allocation of the glyph slot. + * src/pfr/pfrobjs (pfr_slot_load): Updated. + + * src/winfonts/winfnt.c (FNT_Load_Glyph): Ditto. + + * docs/CHANGES: Updated. + +2016-11-06 Werner Lemberg + + Synchronize with gnulib (#49448). + + * include/freetype/config/ftconfig.h, builds/unix/ftconfig.in, + builds/vms/ftconfig.h (FT_TYPEOF): Update code to use definition in + current version of `intprops.h'. + Other minor synchronization to reduce code differences between the + three files. + +2016-11-03 Behdad Esfahbod + + [truetype] Clamp variation requests to valid range. + + This is required by OpenType 1.8; it also avoids rounding surprises. + + * src/truetype/ttgxvar.c (TT_Set_Var_Design): Clamp design coordinates + outside of the allowed range to always stay within the range instead + of producing an error. + +2016-10-29 Werner Lemberg + + [truetype] Remove clang warnings. + + * src/truetype/ttinterp.h (TT_ExecContextRec): Using `FT_ULong' for + loop counter handling. + + * src/truetype/ttinterp.c: Updated. + (Ins_SCANTYPE): Use signed constant. + (TT_RunIns): Ensure `num_twilight_points' is 16bit. + +2016-10-27 Werner Lemberg + + [truetype] Fix commit from 2014-11-24. + + Problem reported by Hin-Tak Leung . + + * src/truetype/ttpload.c (tt_face_load_hdmx): Fix file checking + logic. + +2016-10-26 Werner Lemberg + + Add `FT_Get_{MM,Var}_Blend_Coordinates' functions. + + * include/freetype/ftmm.h: Declare. + + * include/freetype/internal/services/svmm.h (FT_Get_MM_Blend_Func): + New typedef. + (MultiMasters): New MM service function `get_mm_blend'. + (FT_DEFINE_SERVICE_MULTIMASTERSREC): Updated. + Update all callers. + + * src/base/ftmm.c (FT_Get_MM_Blend_Coordinates, + FT_Get_Var_Blend_Coordinates): Implement. + + * src/truetype/ttdriver.c: Updated. + + * src/truetype/ttgxvar.c (TT_Get_MM_Blend): New function to handle + `get_mm_blend' service. + * src/truetype/ttgxvar.h: Updated. + + * src/type1/t1driver.c: Updated. + + * src/type1/t1load.c (T1_Get_MM_Blend): New function to handle + `get_mm_blend' service. + * src/type1/t1load.h: Updated. + + * docs/CHANGES: Document. + +2016-10-26 Werner Lemberg + + * src/type1/t1load.c (parse_subrs): Fix limit check. + + Reported as + + https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=81 + +2016-10-25 Alexei Podtelezhnikov + + [cff] Correct cmap format reporting (#24819). + + * src/cff/cffdrivr.c (cff_get_cmap_info): Throw an error on synthetic + charmap instead of guessing its format and language. + +2016-10-22 Werner Lemberg + + [truetype] Fix SCANTYPE instruction (#49394). + + * src/truetype/ttinterp.c (Ins_SCANTYPE): Only use lower 16bits. + +2016-10-22 Werner Lemberg + + [sfnt] Improve handling of invalid post 2.5 tables [#49393]. + + * src/sfnt/ttpost.c (load_format_25): We need at least a single + table entry. + +2016-10-14 Werner Lemberg + + [truetype] Fix handling of `cvar' table data. + + Reported as + + https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=53 + + * src/truetype/ttgxvar.c (tt_face_vary_cvt): Ignore invalid CVT + indices. + +2016-10-11 Werner Lemberg + + [psaux] Fix handling of invalid flex subrs. + + Problem reported as + + https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=52 + + * src/psaux/t1decode.c (t1_decoder_parse_charstrings) + : Set `flex_state' after error checking. + +2016-10-11 Werner Lemberg + + * src/truetype/ttgxvar.c (tt_done_blend): Fix deallocation. + +2016-10-08 Werner Lemberg + + * src/cid/cidload.c (cid_face_open): Properly propagate `error'. + +2016-10-08 Werner Lemberg + + [cid] Fix parsing of subr offsets. + + Bug introduced 2016-05-16. + + * src/cid/cidparse.c (cid_parser_new): Fix off-by-one error. + +2016-10-01 Werner Lemberg + + [sfnt] Disable bitmap strikes if we don't have a bitmap data table. + + * src/sfnt/ttsbit.c (tt_face_load_sbit): Check whether we have + a bitmap data table. + +2016-10-01 Alexei Podtelezhnikov + + [smooth] Remove impossibility. + + * src/smooth/ftgrays.c (TWorker): Rearrange fields. + (gray_convert_glyph): Remove impossible condition and clean up. + +2016-09-29 Werner Lemberg + + [pcf] Enrich family name with foundry name and glyph width info. + + This is a very old patch from openSuSE (from 2006, submitted to + FreeType in 2011) that I forgot to apply. + + https://build.opensuse.org/package/view_file/openSUSE:Factory/freetype2/freetype2-bitmap-foundry.patch + + Prepend the foundry name plus a space to the family name. There are + many fonts just called `Fixed' which look completely different, and + which have nothing to do with each other. When selecting `Fixed' in + KDE or Gnome one gets results that appear rather random, the style + changes often if one changes the size and one cannot select some + fonts at all. + + We also check whether we have `wide' characters; all put together, + we get family names like `Sony Fixed' or `Misc Fixed Wide'. + + * src/pcf/pcfread.c (pcf_load_font): Implement it. + + * docs/CHANGES: Document it. + +2016-09-29 Werner Lemberg + + [ftfuzzer] Speed up. + + * src/tools/ftfuzzer/ftfuzzer.cc (LLVMFuzzerTestOneInput): Don't + check for embedded bitmaps if we have a non-default instance. + +2016-09-29 Werner Lemberg + + [truetype] Disallow bitmap strokes for non-default instances. + + Also speed up access of default instances if GX variations are + active. + + * include/freetype/internal/tttypes.h (TT_FaceRec): Add + `is_default_instance' member. + + * src/sfnt/sfobjs.c (sfnt_init_face): Initialize + `is_default_instance'. + + * src/truetype/ttgload.c (TT_Process_Simple_Glyph, + load_truetype_glyph): Add test for default instance. + (TT_Load_Glyph): Load embedded bitmaps for default instance only. + + * src/truetype/ttgxvar.c (TT_Set_MM_Blend): Compute + `is_default_instance'. + +2016-09-29 Werner Lemberg + + [truetype] Clean up `TT_Face' structure. + + * include/freetype/internal/tttypes.h (TT_FaceRec): Remove unused + fields `horz_metrics' and `vert_metrics'. + Update documentation. + + * src/sfnt/sfobjs.c (sfnt_done_face): Updated. + +2016-09-28 Werner Lemberg + + More FT_ZERO usage. + + * src/gxvalid/gxvcommn.c (gxv_ClassTable_validate): + s/ft_memset/FT_MEM_ZERO/. + + * src/psaux/t1decode.c (t1_decoder_parse_charstrings): + s/ft_memset/FT_ARRAY_ZERO/. + + * src/raster/ftraster.c (FT_ZERO): Define. + (ft_black_new): Use it. + * src/raster/ftrend1.c (ft_raster1_get_cbox): + s/FT_MEM_ZERO/FT_ZERO/. + + * src/smooth/ftgrays.c (FT_ZERO): Define. + (gray_raster_new): Use it. + * src/smooth/ftsmooth.c (ft_smooth_get_cbox): + s/FT_MEM_ZERO/FT_ZERO/. + +2016-09-28 Werner Lemberg + + */*: s/FT_MEM_ZERO/FT_ZERO/ where appropriate. + +2016-09-27 Werner Lemberg + + [truetype] Trace number of executed opcodes. + + * src/truetype/ttinterp.c (TT_RunIns): Implement it. + +2016-09-27 Werner Lemberg + + [truetype] Speed up `TT_Load_Glyph'. + + This avoids additional calls to `tt_face_lookup_table' for the + `glyf' table, which can be expensive. + + * include/freetype/internal/tttypes.h (TT_LoaderRec): Move + `glyf_offset' field to ... + (TT_FaceRec): ... this structure. + * src/truetype/ttgload.c (load_truetype_glyph): Updated. + (tt_loader_init): Move initialization of `glyf_offset' to ... + * src/truetype/ttpload.c (tt_face_load_loca): ... this function. + +2016-09-27 Werner Lemberg + + [truetype] Introduce dynamic limits for some bytecode opcodes. + + This speeds up FreeType's handling of malformed fonts. + + * src/truetype/ttinterp.c (TT_RunIns): Set up limits for the number + of twilight points, the total number of negative jumps, and the + total number of loops in LOOPCALL opcodes. The values are based on + the number of points and entries in the CVT table. + (Ins_JMPR): Test negative jump counter. + (Ins_LOOPCALL): Test loopcall counter. + + * src/truetype/ttinterp.h (TT_ExecContext): Updated. + + * docs/CHANGES: Updated. + +2016-09-25 Werner Lemberg + + [truetype] Sanitize only last entry of `loca' table. + + Without this patch, a loca sequence like `0 100000 0 100000 ...', + where value 100000 is larger than the `glyf' table size, makes + FreeType handle the whole `glyf' table as a single glyph again and + again, which is certainly invalid (and can be very slow, too). + + * src/truetype/ttpload.c (tt_face_get_location): Implement. + Improve tracing messages. + +2016-09-25 Werner Lemberg + + * src/tools/ftfuzzer/ftfuzzer.cc (LLVMFuzzerTestOneInput): Fix typo. + +2016-09-24 Werner Lemberg + + [autofit] Tracing fixes. + + * src/autofit/afmodule.c (af_autofitter_load_glyph): Call dumping + functions only if we actually do tracing. + +2016-09-22 Alexei Podtelezhnikov + + [smooth] Reduce divisions in the line renderer. + + We don't need some divisions if a line segments stays within a single + row or a single column of pixels. + + * src/smooth/ftgrays.c (gray_render_line) [FT_LONG64]: Make divisions + conditional. + +2016-09-15 Alexei Podtelezhnikov + + * src/smooth/ftgrays.c (gray_sweep): Remove check for empty table. + +2016-09-14 Alexei Podtelezhnikov + + [smooth] Another tiny speed-up. + + * src/smooth/ftgrays.c (gray_find_cell): Merge into... + (gray_record_cell): ... this function. + +2016-09-11 Alexei Podtelezhnikov + + * src/smooth/ftgrays.c (gray_{find,set}_cell): Remove dubious code. + +2016-09-11 Alexei Podtelezhnikov + + [smooth] Fix valgrind warning and reoptimize. + + The algorithm calls `gray_set_cell' at the start of each new contour + or when the contours cross the cell boundaries. Double-checking for + that is wasteful. + + * src/smooth/ftgrays.c (gray_set_cell): Remove check for a new cell. + (gray_convert_glyph): Remove initialization introduced by 44b172e88. + +2016-09-10 Werner Lemberg + + [sfnt] Fix previous commit. + + Problems reported as + + https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=40 + + We now map the strike index right before accessing the physical + data, not earlier. + + * src/sfnt/sfobjs.c (sfnt_load_face): Set `face->sbit_strike_map' + after creating the map so that... + + * src/sfnt/ttsbit.c (tt_face_load_strike_metrics): ... this function + can be used before and after setting up `sbit_strike_map'. + (tt_face_set_sbit_strike): Revert change. + (tt_sbit_decoder_init, tt_face_load_sbix_image): Map strike index. + + * src/truetype/ttdriver.c (tt_size_select): Revert change. + +2016-09-09 Werner Lemberg + + [ftfuzzer] Minor improvements. + + * src/tools/ftfuzzer/ftfuzzer.cc (LLVMFuzzerTestOneInput): Ignore + invalid strikes. + Use better values for call to `FT_Set_Char_Size'. + +2016-09-09 Werner Lemberg + + [sfnt] Don't provide (completely) broken strike data. + + FreeType tries to sanitize strike header data; we now reject + completely broken ones. + + * include/freetype/internal/tttypes.h (TT_FaceRec): New + `sbit_strike_map' array pointer. + + * src/base/ftobjs.c (FT_Match_Size): Reject matches where either + width or height would be zero. + Add tracing message in case of error. + + * src/sfnt/sfobjs.c (sfnt_load_face): Populate `sbit_strike_map', + only using (more or less) valid strike header data for + FT_Face's `available_sizes' array. + (sfnt_done_face): Updated. + + * src/sfnt/ttsbit.c (tt_face_set_sbit_strike): Use + `sbit_strike_map'. + (tt_face_load_strike_metrics): Improve tracing. + + * src/truetype/ttdriver.c (tt_size_select): Use `sbit_strike_map'. + +2016-09-08 Werner Lemberg + * Version 2.7 released. ======================= Index: reactos/sdk/lib/3rdparty/freetype/include/freetype/config/ftconfig.h =================================================================== --- reactos/sdk/lib/3rdparty/freetype/include/freetype/config/ftconfig.h (revision 74184) +++ reactos/sdk/lib/3rdparty/freetype/include/freetype/config/ftconfig.h (working copy) @@ -143,6 +143,14 @@ #endif + /* Fix compiler warning with sgi compiler */ +#if defined( __sgi ) && !defined( __GNUC__ ) +#if defined( _COMPILER_VERSION ) && ( _COMPILER_VERSION >= 730 ) +#pragma set woff 3505 +#endif +#endif + + /*************************************************************************/ /* */ /*
*/ @@ -338,10 +346,11 @@ /* typeof condition taken from gnulib's `intprops.h' header file */ -#if ( __GNUC__ >= 2 || \ - defined( __IBM__TYPEOF__ ) || \ - ( __SUNPRO_C >= 0x5110 && !__STDC__ ) ) -#define FT_TYPEOF( type ) (__typeof__ (type)) +#if ( ( defined( __GNUC__ ) && __GNUC__ >= 2 ) || \ + ( defined( __IBMC__ ) && __IBMC__ >= 1210 && \ + defined( __IBM__TYPEOF__ ) ) || \ + ( defined( __SUNPRO_C ) && __SUNPRO_C >= 0x5110 && !__STDC__ ) ) +#define FT_TYPEOF( type ) ( __typeof__ ( type ) ) #else #define FT_TYPEOF( type ) /* empty */ #endif Index: reactos/sdk/lib/3rdparty/freetype/include/freetype/freetype.h =================================================================== --- reactos/sdk/lib/3rdparty/freetype/include/freetype/freetype.h (revision 74184) +++ reactos/sdk/lib/3rdparty/freetype/include/freetype/freetype.h (working copy) @@ -951,6 +951,10 @@ /* strikes in the face. It is set to NULL if */ /* there is no bitmap strike. */ /* */ + /* Note that FreeType tries to sanitize the */ + /* strike data since they are sometimes sloppy */ + /* or incorrect, but this can easily fail. */ + /* */ /* num_charmaps :: The number of charmaps in the face. */ /* */ /* charmaps :: An array of the charmaps of the face. */ @@ -1727,7 +1731,6 @@ /* position (e.g., coordinates (0,0) on the baseline). Of course, */ /* `slot->format' is also changed to @FT_GLYPH_FORMAT_BITMAP. */ /* */ - /* */ /* Here is a small pseudo code fragment that shows how to use */ /* `lsb_delta' and `rsb_delta': */ /* */ @@ -1755,6 +1758,12 @@ /* endfor */ /* } */ /* */ + /* If you use strong auto-hinting, you *must* apply these delta */ + /* values! Otherwise you will experience far too large inter-glyph */ + /* spacing at small rendering sizes in most cases. Note that it */ + /* doesn't harm to use the above code for other hinting modes also, */ + /* since the delta values are zero then. */ + /* */ typedef struct FT_GlyphSlotRec_ { FT_Library library; @@ -2322,7 +2331,10 @@ /* FT_Select_Size */ /* */ /* */ - /* Select a bitmap strike. */ + /* Select a bitmap strike. To be more precise, this function sets */ + /* the scaling factors of the active @FT_Size object in a face so */ + /* that bitmaps from this particular strike are taken by */ + /* @FT_Load_Glyph and friends. */ /* */ /* */ /* face :: A handle to a target face object. */ @@ -2334,6 +2346,20 @@ /* */ /* FreeType error code. 0~means success. */ /* */ + /* */ + /* For bitmaps embedded in outline fonts it is common that only a */ + /* subset of the available glyphs at a given ppem value is available. */ + /* FreeType silently uses outlines if there is no bitmap for a given */ + /* glyph index. */ + /* */ + /* For GX variation fonts, a bitmap strike makes sense only if the */ + /* default instance is active (this is, no glyph variation takes */ + /* place); otherwise, FreeType simply ignores bitmap strikes. The */ + /* same is true for all named instances that are different from the */ + /* default instance. */ + /* */ + /* Don't use this function if you are using the FreeType cache API. */ + /* */ FT_EXPORT( FT_Error ) FT_Select_Size( FT_Face face, FT_Int strike_index ); @@ -2786,6 +2812,14 @@ * * Currently, this flag is only implemented for TrueType fonts. * + * FT_LOAD_BITMAP_METRICS_ONLY :: + * This flag is used to request loading of the metrics and bitmap + * image information of a (possibly embedded) bitmap glyph without + * allocating or copying the bitmap image data itself. No effect if + * the target glyph is not a bitmap image. + * + * This flag unsets @FT_LOAD_RENDER. + * * FT_LOAD_CROP_BITMAP :: * Ignored. Deprecated. * @@ -2832,6 +2866,7 @@ /* Bits 16..19 are used by `FT_LOAD_TARGET_' */ #define FT_LOAD_COLOR ( 1L << 20 ) #define FT_LOAD_COMPUTE_METRICS ( 1L << 21 ) +#define FT_LOAD_BITMAP_METRICS_ONLY ( 1L << 22 ) /* */ @@ -4206,7 +4241,7 @@ */ #define FREETYPE_MAJOR 2 #define FREETYPE_MINOR 7 -#define FREETYPE_PATCH 0 +#define FREETYPE_PATCH 1 /*************************************************************************/ Index: reactos/sdk/lib/3rdparty/freetype/include/freetype/ftimage.h =================================================================== --- reactos/sdk/lib/3rdparty/freetype/include/freetype/ftimage.h (revision 74184) +++ reactos/sdk/lib/3rdparty/freetype/include/freetype/ftimage.h (working copy) @@ -1180,6 +1180,7 @@ typedef struct FT_Raster_Funcs_ { FT_Glyph_Format glyph_format; + FT_Raster_NewFunc raster_new; FT_Raster_ResetFunc raster_reset; FT_Raster_SetModeFunc raster_set_mode; Index: reactos/sdk/lib/3rdparty/freetype/include/freetype/ftmm.h =================================================================== --- reactos/sdk/lib/3rdparty/freetype/include/freetype/ftmm.h (revision 74184) +++ reactos/sdk/lib/3rdparty/freetype/include/freetype/ftmm.h (working copy) @@ -171,6 +171,7 @@ { FT_Fixed* coords; FT_UInt strid; + FT_UInt psid; /* since 2.7.1 */ } FT_Var_Named_Style; @@ -337,6 +338,34 @@ /*************************************************************************/ /* */ /* */ + /* FT_Get_Var_Design_Coordinates */ + /* */ + /* */ + /* For Multiple Master and GX Var fonts, get the design coordinates */ + /* of the currently selected interpolated font. */ + /* */ + /* */ + /* face :: A handle to the source face. */ + /* */ + /* num_coords :: The number of design coordinates to retrieve. If it */ + /* is larger than the number of axes, set the excess */ + /* values to~0. */ + /* */ + /* */ + /* coords :: The design coordinates array. */ + /* */ + /* */ + /* FreeType error code. 0~means success. */ + /* */ + FT_EXPORT( FT_Error ) + FT_Get_Var_Design_Coordinates( FT_Face face, + FT_UInt num_coords, + FT_Fixed* coords ); + + + /*************************************************************************/ + /* */ + /* */ /* FT_Set_MM_Blend_Coordinates */ /* */ /* */ @@ -353,7 +382,8 @@ /* use default values for the remaining axes. */ /* */ /* coords :: The design coordinates array (each element must be */ - /* between 0 and 1.0). */ + /* between 0 and 1.0 for MM fonts, and between -1.0 and */ + /* 1.0 for GX var fonts). */ /* */ /* */ /* FreeType error code. 0~means success. */ @@ -367,6 +397,35 @@ /*************************************************************************/ /* */ /* */ + /* FT_Get_MM_Blend_Coordinates */ + /* */ + /* */ + /* For Multiple Masters and GX var fonts, get the normalized blend */ + /* coordinates of the currently selected interpolated font. */ + /* */ + /* */ + /* face :: A handle to the source face. */ + /* */ + /* num_coords :: The number of normalized blend coordinates to */ + /* retrieve. If it is larger than the number of axes, */ + /* set the excess values to~0.5 for MM fonts, and to~0 */ + /* for GX var fonts. */ + /* */ + /* */ + /* coords :: The normalized blend coordinates array. */ + /* */ + /* */ + /* FreeType error code. 0~means success. */ + /* */ + FT_EXPORT( FT_Error ) + FT_Get_MM_Blend_Coordinates( FT_Face face, + FT_UInt num_coords, + FT_Fixed* coords ); + + + /*************************************************************************/ + /* */ + /* */ /* FT_Set_Var_Blend_Coordinates */ /* */ /* */ @@ -377,6 +436,20 @@ FT_UInt num_coords, FT_Fixed* coords ); + + /*************************************************************************/ + /* */ + /* */ + /* FT_Get_Var_Blend_Coordinates */ + /* */ + /* */ + /* This is another name of @FT_Get_MM_Blend_Coordinates. */ + /* */ + FT_EXPORT( FT_Error ) + FT_Get_Var_Blend_Coordinates( FT_Face face, + FT_UInt num_coords, + FT_Fixed* coords ); + /* */ Index: reactos/sdk/lib/3rdparty/freetype/include/freetype/ftrender.h =================================================================== --- reactos/sdk/lib/3rdparty/freetype/include/freetype/ftrender.h (revision 74184) +++ reactos/sdk/lib/3rdparty/freetype/include/freetype/ftrender.h (working copy) @@ -75,6 +75,7 @@ { FT_Long glyph_size; FT_Glyph_Format glyph_format; + FT_Glyph_InitFunc glyph_init; FT_Glyph_DoneFunc glyph_done; FT_Glyph_CopyFunc glyph_copy; Index: reactos/sdk/lib/3rdparty/freetype/include/freetype/internal/ftobjs.h =================================================================== --- reactos/sdk/lib/3rdparty/freetype/include/freetype/internal/ftobjs.h (revision 74184) +++ reactos/sdk/lib/3rdparty/freetype/include/freetype/internal/ftobjs.h (working copy) @@ -193,6 +193,7 @@ typedef struct FT_CMap_ClassRec_ { FT_ULong size; + FT_CMap_InitFunc init; FT_CMap_DoneFunc done; FT_CMap_CharIndexFunc char_index; @@ -530,7 +531,8 @@ FT_BASE( FT_Pointer ) ft_module_get_service( FT_Module module, - const char* service_id ); + const char* service_id, + FT_Bool global ); #ifdef FT_CONFIG_OPTION_ENVIRONMENT_PROPERTIES FT_BASE( FT_Error ) @@ -874,7 +876,7 @@ #ifdef FT_CONFIG_OPTION_SUBPIXEL_RENDERING FT_LcdFilter lcd_filter; FT_Int lcd_extra; /* number of extra pixels */ - FT_Byte lcd_weights[7]; /* filter weights, if any */ + FT_Byte lcd_weights[5]; /* filter weights, if any */ FT_Bitmap_LcdFilterFunc lcd_filter_func; /* filtering callback */ #endif Index: reactos/sdk/lib/3rdparty/freetype/include/freetype/internal/ftrfork.h =================================================================== --- reactos/sdk/lib/3rdparty/freetype/include/freetype/internal/ftrfork.h (revision 74184) +++ reactos/sdk/lib/3rdparty/freetype/include/freetype/internal/ftrfork.h (working copy) @@ -43,11 +43,12 @@ typedef struct FT_RFork_Ref_ { - FT_UShort res_id; - FT_Long offset; + FT_Short res_id; + FT_Long offset; } FT_RFork_Ref; + #ifdef FT_CONFIG_OPTION_GUESSING_EMBEDDED_RFORK typedef FT_Error (*ft_raccess_guess_func)( FT_Library library, Index: reactos/sdk/lib/3rdparty/freetype/include/freetype/internal/ftserv.h =================================================================== --- reactos/sdk/lib/3rdparty/freetype/include/freetype/internal/ftserv.h (revision 74184) +++ reactos/sdk/lib/3rdparty/freetype/include/freetype/internal/ftserv.h (working copy) @@ -109,27 +109,27 @@ */ #ifdef __cplusplus -#define FT_FACE_FIND_GLOBAL_SERVICE( face, ptr, id ) \ - FT_BEGIN_STMNT \ - FT_Module module = FT_MODULE( FT_FACE( face )->driver ); \ - FT_Pointer _tmp_; \ - FT_Pointer* _pptr_ = (FT_Pointer*)&(ptr); \ - \ - \ - _tmp_ = ft_module_get_service( module, FT_SERVICE_ID_ ## id ); \ - *_pptr_ = _tmp_; \ +#define FT_FACE_FIND_GLOBAL_SERVICE( face, ptr, id ) \ + FT_BEGIN_STMNT \ + FT_Module module = FT_MODULE( FT_FACE( face )->driver ); \ + FT_Pointer _tmp_; \ + FT_Pointer* _pptr_ = (FT_Pointer*)&(ptr); \ + \ + \ + _tmp_ = ft_module_get_service( module, FT_SERVICE_ID_ ## id, 1 ); \ + *_pptr_ = _tmp_; \ FT_END_STMNT #else /* !C++ */ -#define FT_FACE_FIND_GLOBAL_SERVICE( face, ptr, id ) \ - FT_BEGIN_STMNT \ - FT_Module module = FT_MODULE( FT_FACE( face )->driver ); \ - FT_Pointer _tmp_; \ - \ - \ - _tmp_ = ft_module_get_service( module, FT_SERVICE_ID_ ## id ); \ - ptr = _tmp_; \ +#define FT_FACE_FIND_GLOBAL_SERVICE( face, ptr, id ) \ + FT_BEGIN_STMNT \ + FT_Module module = FT_MODULE( FT_FACE( face )->driver ); \ + FT_Pointer _tmp_; \ + \ + \ + _tmp_ = ft_module_get_service( module, FT_SERVICE_ID_ ## id, 1 ); \ + ptr = _tmp_; \ FT_END_STMNT #endif /* !C++ */ @@ -167,6 +167,7 @@ /* FT_DEFINE_SERVICEDESCREC5 */ /* FT_DEFINE_SERVICEDESCREC6 */ /* FT_DEFINE_SERVICEDESCREC7 */ + /* FT_DEFINE_SERVICEDESCREC8 */ /* */ /* */ /* Used to initialize an array of FT_ServiceDescRec structures. */ @@ -283,6 +284,28 @@ { NULL, NULL } \ }; +#define FT_DEFINE_SERVICEDESCREC8( class_, \ + serv_id_1, serv_data_1, \ + serv_id_2, serv_data_2, \ + serv_id_3, serv_data_3, \ + serv_id_4, serv_data_4, \ + serv_id_5, serv_data_5, \ + serv_id_6, serv_data_6, \ + serv_id_7, serv_data_7, \ + serv_id_8, serv_data_8 ) \ + static const FT_ServiceDescRec class_[] = \ + { \ + { serv_id_1, serv_data_1 }, \ + { serv_id_2, serv_data_2 }, \ + { serv_id_3, serv_data_3 }, \ + { serv_id_4, serv_data_4 }, \ + { serv_id_5, serv_data_5 }, \ + { serv_id_6, serv_data_6 }, \ + { serv_id_7, serv_data_7 }, \ + { serv_id_8, serv_data_8 }, \ + { NULL, NULL } \ + }; + #else /* FT_CONFIG_OPTION_PIC */ #define FT_DEFINE_SERVICEDESCREC1( class_, \ @@ -593,6 +616,62 @@ return FT_Err_Ok; \ } +#define FT_DEFINE_SERVICEDESCREC8( class_, \ + serv_id_1, serv_data_1, \ + serv_id_2, serv_data_2, \ + serv_id_3, serv_data_3, \ + serv_id_4, serv_data_4, \ + serv_id_5, serv_data_5, \ + serv_id_6, serv_data_6, \ + serv_id_7, serv_data_7, \ + serv_id_8, serv_data_8 ) \ + void \ + FT_Destroy_Class_ ## class_( FT_Library library, \ + FT_ServiceDescRec* clazz ) \ + { \ + FT_Memory memory = library->memory; \ + \ + \ + if ( clazz ) \ + FT_FREE( clazz ); \ + } \ + \ + FT_Error \ + FT_Create_Class_ ## class_( FT_Library library, \ + FT_ServiceDescRec** output_class) \ + { \ + FT_ServiceDescRec* clazz = NULL; \ + FT_Error error; \ + FT_Memory memory = library->memory; \ + \ + \ + if ( FT_ALLOC( clazz, sizeof ( *clazz ) * 9 ) ) \ + return error; \ + \ + clazz[0].serv_id = serv_id_1; \ + clazz[0].serv_data = serv_data_1; \ + clazz[1].serv_id = serv_id_2; \ + clazz[1].serv_data = serv_data_2; \ + clazz[2].serv_id = serv_id_3; \ + clazz[2].serv_data = serv_data_3; \ + clazz[3].serv_id = serv_id_4; \ + clazz[3].serv_data = serv_data_4; \ + clazz[4].serv_id = serv_id_5; \ + clazz[4].serv_data = serv_data_5; \ + clazz[5].serv_id = serv_id_6; \ + clazz[5].serv_data = serv_data_6; \ + clazz[6].serv_id = serv_id_7; \ + clazz[6].serv_data = serv_data_7; \ + clazz[7].serv_id = serv_id_8; \ + clazz[7].serv_data = serv_data_8; \ + clazz[8].serv_id = NULL; \ + clazz[8].serv_data = NULL; \ + \ + *output_class = clazz; \ + \ + return FT_Err_Ok; \ + } + #endif /* FT_CONFIG_OPTION_PIC */ @@ -739,6 +818,7 @@ #define FT_SERVICE_GLYPH_DICT_H #define FT_SERVICE_GX_VALIDATE_H #define FT_SERVICE_KERNING_H +#define FT_SERVICE_METRICS_VARIATIONS_H #define FT_SERVICE_MULTIPLE_MASTERS_H #define FT_SERVICE_OPENTYPE_VALIDATE_H #define FT_SERVICE_PFR_H Index: reactos/sdk/lib/3rdparty/freetype/include/freetype/internal/services/svmetric.h =================================================================== --- reactos/sdk/lib/3rdparty/freetype/include/freetype/internal/services/svmetric.h (nonexistent) +++ reactos/sdk/lib/3rdparty/freetype/include/freetype/internal/services/svmetric.h (working copy) @@ -0,0 +1,155 @@ +/***************************************************************************/ +/* */ +/* svmetric.h */ +/* */ +/* The FreeType services for metrics variations (specification). */ +/* */ +/* Copyright 2016 by */ +/* David Turner, Robert Wilhelm, and Werner Lemberg. */ +/* */ +/* This file is part of the FreeType project, and may only be used, */ +/* modified, and distributed under the terms of the FreeType project */ +/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ +/* this file you indicate that you have read the license and */ +/* understand and accept it fully. */ +/* */ +/***************************************************************************/ + + +#ifndef SVMETRIC_H_ +#define SVMETRIC_H_ + +#include FT_INTERNAL_SERVICE_H + + +FT_BEGIN_HEADER + + + /* + * A service to manage the `HVAR, `MVAR', and `VVAR' OpenType tables. + * + */ + +#define FT_SERVICE_ID_METRICS_VARIATIONS "metrics-variations" + + + /* HVAR */ + + typedef FT_Error + (*FT_HAdvance_Adjust_Func)( FT_Face face, + FT_UInt gindex, + FT_Int *avalue ); + + typedef FT_Error + (*FT_LSB_Adjust_Func)( FT_Face face, + FT_UInt gindex, + FT_Int *avalue ); + + typedef FT_Error + (*FT_RSB_Adjust_Func)( FT_Face face, + FT_UInt gindex, + FT_Int *avalue ); + + /* VVAR */ + + typedef FT_Error + (*FT_VAdvance_Adjust_Func)( FT_Face face, + FT_UInt gindex, + FT_Int *avalue ); + + typedef FT_Error + (*FT_TSB_Adjust_Func)( FT_Face face, + FT_UInt gindex, + FT_Int *avalue ); + + typedef FT_Error + (*FT_BSB_Adjust_Func)( FT_Face face, + FT_UInt gindex, + FT_Int *avalue ); + + typedef FT_Error + (*FT_VOrg_Adjust_Func)( FT_Face face, + FT_UInt gindex, + FT_Int *avalue ); + + /* MVAR */ + + typedef FT_Error + (*FT_Metrics_Adjust_Func)( FT_Face face, + FT_ULong tag, + FT_Int *avalue ); + + + FT_DEFINE_SERVICE( MetricsVariations ) + { + FT_HAdvance_Adjust_Func hadvance_adjust; + FT_LSB_Adjust_Func lsb_adjust; + FT_RSB_Adjust_Func rsb_adjust; + + FT_VAdvance_Adjust_Func vadvance_adjust; + FT_TSB_Adjust_Func tsb_adjust; + FT_BSB_Adjust_Func bsb_adjust; + FT_VOrg_Adjust_Func vorg_adjust; + + FT_Metrics_Adjust_Func metrics_adjust; + }; + + +#ifndef FT_CONFIG_OPTION_PIC + +#define FT_DEFINE_SERVICE_METRICSVARIATIONSREC( class_, \ + hadvance_adjust_, \ + lsb_adjust_, \ + rsb_adjust_, \ + vadvance_adjust_, \ + tsb_adjust_, \ + bsb_adjust_, \ + vorg_adjust_, \ + metrics_adjust_ ) \ + static const FT_Service_MetricsVariationsRec class_ = \ + { \ + hadvance_adjust_, \ + lsb_adjust_, \ + rsb_adjust_, \ + vadvance_adjust_, \ + tsb_adjust_, \ + bsb_adjust_, \ + vorg_adjust_, \ + metrics_adjust_ \ + }; + +#else /* FT_CONFIG_OPTION_PIC */ + +#define FT_DEFINE_SERVICE_METRICSVARIATIONSREC( class_, \ + hadvance_adjust_, \ + lsb_adjust_, \ + rsb_adjust_, \ + vadvance_adjust_, \ + tsb_adjust_, \ + bsb_adjust_, \ + vorg_adjust_, \ + metrics_adjust_ ) \ + void \ + FT_Init_Class_ ## class_( FT_Service_MetricsVariationsRec* clazz ) \ + { \ + clazz->hadvance_adjust = hadvance_adjust_; \ + clazz->lsb_adjust = lsb_adjust_; \ + clazz->rsb_adjust = rsb_adjust_; \ + clazz->vadvance_adjust = vadvance_adjust_; \ + clazz->tsb_adjust = tsb_adjust_; \ + clazz->bsb_adjust = bsb_adjust_; \ + clazz->vorg_adjust = vorg_adjust_; \ + clazz->metrics_adjust = metrics_adjust_; \ + }; + +#endif /* FT_CONFIG_OPTION_PIC */ + + /* */ + + +FT_END_HEADER + +#endif /* SVMETRIC_H_ */ + + +/* END */ Index: reactos/sdk/lib/3rdparty/freetype/include/freetype/internal/services/svmm.h =================================================================== --- reactos/sdk/lib/3rdparty/freetype/include/freetype/internal/services/svmm.h (revision 74184) +++ reactos/sdk/lib/3rdparty/freetype/include/freetype/internal/services/svmm.h (working copy) @@ -58,46 +58,91 @@ FT_UInt num_coords, FT_Long* coords ); + typedef FT_Error + (*FT_Get_Var_Design_Func)( FT_Face face, + FT_UInt num_coords, + FT_Fixed* coords ); + typedef FT_Error + (*FT_Get_MM_Blend_Func)( FT_Face face, + FT_UInt num_coords, + FT_Long* coords ); + + typedef FT_Error + (*FT_Get_Var_Blend_Func)( FT_Face face, + FT_UInt *num_coords, + FT_Fixed* *coords, + FT_MM_Var* *mm_var ); + + typedef void + (*FT_Done_Blend_Func)( FT_Face ); + + FT_DEFINE_SERVICE( MultiMasters ) { FT_Get_MM_Func get_mm; FT_Set_MM_Design_Func set_mm_design; FT_Set_MM_Blend_Func set_mm_blend; + FT_Get_MM_Blend_Func get_mm_blend; FT_Get_MM_Var_Func get_mm_var; FT_Set_Var_Design_Func set_var_design; + FT_Get_Var_Design_Func get_var_design; + + /* for internal use; only needed for code sharing between modules */ + FT_Get_Var_Blend_Func get_var_blend; + FT_Done_Blend_Func done_blend; }; #ifndef FT_CONFIG_OPTION_PIC -#define FT_DEFINE_SERVICE_MULTIMASTERSREC( class_, \ - get_mm_, \ - set_mm_design_, \ - set_mm_blend_, \ - get_mm_var_, \ - set_var_design_ ) \ - static const FT_Service_MultiMastersRec class_ = \ - { \ - get_mm_, set_mm_design_, set_mm_blend_, get_mm_var_, set_var_design_ \ +#define FT_DEFINE_SERVICE_MULTIMASTERSREC( class_, \ + get_mm_, \ + set_mm_design_, \ + set_mm_blend_, \ + get_mm_blend_, \ + get_mm_var_, \ + set_var_design_, \ + get_var_design_, \ + get_var_blend_, \ + done_blend_ ) \ + static const FT_Service_MultiMastersRec class_ = \ + { \ + get_mm_, \ + set_mm_design_, \ + set_mm_blend_, \ + get_mm_blend_, \ + get_mm_var_, \ + set_var_design_, \ + get_var_design_, \ + get_var_blend_, \ + done_blend_ \ }; #else /* FT_CONFIG_OPTION_PIC */ -#define FT_DEFINE_SERVICE_MULTIMASTERSREC( class_, \ - get_mm_, \ - set_mm_design_, \ - set_mm_blend_, \ - get_mm_var_, \ - set_var_design_ ) \ - void \ - FT_Init_Class_ ## class_( FT_Service_MultiMastersRec* clazz ) \ - { \ - clazz->get_mm = get_mm_; \ - clazz->set_mm_design = set_mm_design_; \ - clazz->set_mm_blend = set_mm_blend_; \ - clazz->get_mm_var = get_mm_var_; \ - clazz->set_var_design = set_var_design_; \ +#define FT_DEFINE_SERVICE_MULTIMASTERSREC( class_, \ + get_mm_, \ + set_mm_design_, \ + set_mm_blend_, \ + get_mm_blend_, \ + get_mm_var_, \ + set_var_design_, \ + get_var_design_, \ + get_var_blend_, \ + done_blend_ ) \ + void \ + FT_Init_Class_ ## class_( FT_Service_MultiMastersRec* clazz ) \ + { \ + clazz->get_mm = get_mm_; \ + clazz->set_mm_design = set_mm_design_; \ + clazz->set_mm_blend = set_mm_blend_; \ + clazz->get_mm_blend = get_mm_blend_; \ + clazz->get_mm_var = get_mm_var_; \ + clazz->set_var_design = set_var_design_; \ + clazz->get_var_design = get_var_design_; \ + clazz->get_var_blend = get_var_blend_; \ + clazz->done_blend = done_blend_; \ } #endif /* FT_CONFIG_OPTION_PIC */ Index: reactos/sdk/lib/3rdparty/freetype/include/freetype/internal/tttypes.h =================================================================== --- reactos/sdk/lib/3rdparty/freetype/include/freetype/internal/tttypes.h (revision 74184) +++ reactos/sdk/lib/3rdparty/freetype/include/freetype/internal/tttypes.h (working copy) @@ -1060,6 +1060,75 @@ } TT_SbitTableType; + /* OpenType 1.8 brings new tables for variation font support; */ + /* to make the old MM and GX fonts still work we need to check */ + /* the presence (and validity) of the functionality provided */ + /* by those tables. The following flag macros are for the */ + /* field `variation_support'. */ + /* */ + /* Note that `fvar' gets checked immediately at font loading, */ + /* while the other features are only loaded if MM support is */ + /* actually requested. */ + + /* FVAR */ +#define TT_FACE_FLAG_VAR_FVAR ( 1 << 0 ) + + /* HVAR */ +#define TT_FACE_FLAG_VAR_HADVANCE ( 1 << 1 ) +#define TT_FACE_FLAG_VAR_LSB ( 1 << 2 ) +#define TT_FACE_FLAG_VAR_RSB ( 1 << 3 ) + + /* VVAR */ +#define TT_FACE_FLAG_VAR_VADVANCE ( 1 << 4 ) +#define TT_FACE_FLAG_VAR_TSB ( 1 << 5 ) +#define TT_FACE_FLAG_VAR_BSB ( 1 << 6 ) +#define TT_FACE_FLAG_VAR_VORG ( 1 << 7 ) + + /* MVAR gasp data */ +#define TT_FACE_FLAG_VAR_GASP_0 ( 1 << 20 ) +#define TT_FACE_FLAG_VAR_GASP_1 ( 1 << 21 ) +#define TT_FACE_FLAG_VAR_GASP_2 ( 1 << 22 ) +#define TT_FACE_FLAG_VAR_GASP_3 ( 1 << 23 ) +#define TT_FACE_FLAG_VAR_GASP_4 ( 1 << 24 ) +#define TT_FACE_FLAG_VAR_GASP_5 ( 1 << 25 ) +#define TT_FACE_FLAG_VAR_GASP_6 ( 1 << 26 ) +#define TT_FACE_FLAG_VAR_GASP_7 ( 1 << 27 ) +#define TT_FACE_FLAG_VAR_GASP_8 ( 1 << 28 ) +#define TT_FACE_FLAG_VAR_GASP_9 ( 1 << 29 ) + + /* The following flag macros are for the field `mvar_support'. */ + + /* remaining MVAR data */ +#define TT_FACE_FLAG_VAR_CPHT ( 1 << 0 ) +#define TT_FACE_FLAG_VAR_HASC ( 1 << 1 ) +#define TT_FACE_FLAG_VAR_HCLA ( 1 << 2 ) +#define TT_FACE_FLAG_VAR_HCLD ( 1 << 3 ) +#define TT_FACE_FLAG_VAR_HCOF ( 1 << 4 ) +#define TT_FACE_FLAG_VAR_HCRN ( 1 << 5 ) +#define TT_FACE_FLAG_VAR_HCRS ( 1 << 6 ) +#define TT_FACE_FLAG_VAR_HDSC ( 1 << 7 ) +#define TT_FACE_FLAG_VAR_HLGP ( 1 << 8 ) +#define TT_FACE_FLAG_VAR_SBXO ( 1 << 9 ) +#define TT_FACE_FLAG_VAR_SBXS ( 1 << 10 ) +#define TT_FACE_FLAG_VAR_SBYO ( 1 << 11 ) +#define TT_FACE_FLAG_VAR_SBYS ( 1 << 12 ) +#define TT_FACE_FLAG_VAR_SPXO ( 1 << 13 ) +#define TT_FACE_FLAG_VAR_SPXS ( 1 << 14 ) +#define TT_FACE_FLAG_VAR_SPYO ( 1 << 15 ) +#define TT_FACE_FLAG_VAR_SPYS ( 1 << 16 ) +#define TT_FACE_FLAG_VAR_STRO ( 1 << 17 ) +#define TT_FACE_FLAG_VAR_STRS ( 1 << 18 ) +#define TT_FACE_FLAG_VAR_UNDO ( 1 << 19 ) +#define TT_FACE_FLAG_VAR_UNDS ( 1 << 20 ) +#define TT_FACE_FLAG_VAR_VASC ( 1 << 21 ) +#define TT_FACE_FLAG_VAR_VCOF ( 1 << 22 ) +#define TT_FACE_FLAG_VAR_VCRN ( 1 << 23 ) +#define TT_FACE_FLAG_VAR_VCRS ( 1 << 24 ) +#define TT_FACE_FLAG_VAR_VDSC ( 1 << 25 ) +#define TT_FACE_FLAG_VAR_VLGP ( 1 << 26 ) +#define TT_FACE_FLAG_VAR_XHGT ( 1 << 27 ) + + /*************************************************************************/ /* */ /* TrueType Face Type */ @@ -1161,6 +1230,11 @@ /* */ /* psnames :: A pointer to the PostScript names service. */ /* */ + /* mm :: A pointer to the Multiple Masters service. */ + /* */ + /* var :: A pointer to the Metrics Variations */ + /* service. */ + /* */ /* hdmx :: The face's horizontal device metrics */ /* (`hdmx' table). This table is optional in */ /* TrueType/OpenType fonts. */ @@ -1182,18 +1256,6 @@ /* file `ttconfig.h' for comments on the */ /* TT_CONFIG_OPTION_POSTSCRIPT_NAMES option. */ /* */ - /* num_locations :: The number of glyph locations in this */ - /* TrueType file. This should be */ - /* identical to the number of glyphs. */ - /* Ignored for Type 2 fonts. */ - /* */ - /* glyph_locations :: An array of longs. These are offsets to */ - /* glyph data within the `glyf' table. */ - /* Ignored for Type 2 font faces. */ - /* */ - /* glyf_len :: The length of the `glyf' table. Needed */ - /* for malformed `loca' tables. */ - /* */ /* font_program_size :: Size in bytecodes of the face's font */ /* program. 0 if none defined. Ignored for */ /* Type 2 fonts. */ @@ -1219,20 +1281,20 @@ /* units. Comes from the `cvt ' table. */ /* Ignored for Type 2 fonts. */ /* */ - /* num_kern_pairs :: The number of kerning pairs present in the */ - /* font file. The engine only loads the */ - /* first horizontal format 0 kern table it */ - /* finds in the font file. Ignored for */ - /* Type 2 fonts. */ - /* */ - /* kern_table_index :: The index of the kerning table in the font */ - /* kerning directory. Ignored for Type 2 */ - /* fonts. */ - /* */ /* interpreter :: A pointer to the TrueType bytecode */ /* interpreters field is also used to hook */ /* the debugger in `ttdebug'. */ /* */ + /* extra :: Reserved for third-party font drivers. */ + /* */ + /* postscript_name :: The PS name of the font. Used by the */ + /* postscript name service. */ + /* */ + /* glyf_len :: The length of the `glyf' table. Needed */ + /* for malformed `loca' tables. */ + /* */ + /* glyf_offset :: The file offset of the `glyf' table. */ + /* */ /* doblend :: A boolean which is set if the font should */ /* be blended (this is for GX var). */ /* */ @@ -1240,11 +1302,93 @@ /* variation tables (rather like Multiple */ /* Master data). */ /* */ - /* extra :: Reserved for third-party font drivers. */ + /* is_default_instance :: Set if the glyph outlines can be used */ + /* unmodified (i.e., without applying glyph */ + /* variation deltas). */ /* */ - /* postscript_name :: The PS name of the font. Used by the */ - /* postscript name service. */ + /* variation_support :: Flags that indicate which OpenType */ + /* functionality related to font variation */ + /* support is present, valid, and usable. */ + /* For example, TT_FACE_FLAG_VAR_FVAR is only */ + /* set if we have at least one design axis. */ /* */ + /* mvar_support :: Flags that indicate which metrics */ + /* variations are supported. */ + /* */ + /* horz_metrics_size :: The size of the `hmtx' table. */ + /* */ + /* vert_metrics_size :: The size of the `vmtx' table. */ + /* */ + /* num_locations :: The number of glyph locations in this */ + /* TrueType file. This should be */ + /* identical to the number of glyphs. */ + /* Ignored for Type 2 fonts. */ + /* */ + /* glyph_locations :: An array of longs. These are offsets to */ + /* glyph data within the `glyf' table. */ + /* Ignored for Type 2 font faces. */ + /* */ + /* hdmx_table :: A pointer to the `hdmx' table. */ + /* */ + /* hdmx_table_size :: The size of the `hdmx' table. */ + /* */ + /* hdmx_record_count :: The number of hdmx records. */ + /* */ + /* hdmx_record_size :: The size of a single hdmx record. */ + /* */ + /* hdmx_record_sizes :: An array holding the ppem sizes available */ + /* in the `hdmx' table. */ + /* */ + /* sbit_table :: A pointer to the font's embedded bitmap */ + /* location table. */ + /* */ + /* sbit_table_size :: The size of `sbit_table'. */ + /* */ + /* sbit_table_type :: The sbit table type (CBLC, SBIX, etc.). */ + /* */ + /* sbit_num_strikes :: The number of sbit strikes exposed by */ + /* FreeType's API, omitting invalid strikes. */ + /* */ + /* sbit_strike_map :: A mapping between the strike indices */ + /* exposed by the API and the indices used in */ + /* the font's sbit table. */ + /* */ + /* kern_table :: A pointer to the `kern' table. */ + /* */ + /* kern_table_size :: The size of the `kern' table. */ + /* */ + /* num_kern_tables :: The number of supported kern subtables */ + /* (up to 32; FreeType recognizes only */ + /* horizontal ones with format 0). */ + /* */ + /* kern_avail_bits :: The availability status of kern subtables; */ + /* if bit n is set, table n is available. */ + /* */ + /* kern_order_bits :: The sortedness status of kern subtables; */ + /* if bit n is set, table n is sorted. */ + /* */ + /* bdf :: Data related to an SFNT font's `bdf' */ + /* table; see `tttypes.h'. */ + /* */ + /* horz_metrics_offset :: The file offset of the `hmtx' table. */ + /* */ + /* vert_metrics_offset :: The file offset of the `vmtx' table. */ + /* */ + /* sph_found_func_flags :: Flags identifying special bytecode */ + /* functions (used by the v38 implementation */ + /* of the bytecode interpreter). */ + /* */ + /* sph_compatibility_mode :: */ + /* This flag is set if we are in ClearType */ + /* backwards compatibility mode (used by the */ + /* v38 implementation of the bytecode */ + /* interpreter). */ + /* */ + /* ebdt_start :: The file offset of the sbit data table */ + /* (CBDT, bdat, etc.). */ + /* */ + /* ebdt_size :: The size of the sbit data table. */ + /* */ typedef struct TT_FaceRec_ { FT_FaceRec root; @@ -1288,7 +1432,17 @@ /* handle glyph names <-> unicode & Mac values */ void* psnames; +#ifdef TT_CONFIG_OPTION_GX_VAR_SUPPORT + /* a typeless pointer to the FT_Service_MultiMasters table used to */ + /* handle variation fonts */ + void* mm; + /* a typeless pointer to the FT_Service_MetricsVariationsRec table */ + /* used to handle the HVAR, VVAR, and MVAR OpenType tables */ + void* var; +#endif + + /***********************************************************************/ /* */ /* Optional TrueType/OpenType tables */ @@ -1344,18 +1498,22 @@ const char* postscript_name; FT_ULong glyf_len; + FT_ULong glyf_offset; /* since 2.7.1 */ + FT_Bool isCFF2; /* since 2.7.1 */ + #ifdef TT_CONFIG_OPTION_GX_VAR_SUPPORT FT_Bool doblend; GX_Blend blend; + + FT_Bool is_default_instance; /* since 2.7.1 */ + FT_UInt32 variation_support; /* since 2.7.1 */ + FT_UInt32 mvar_support; /* since 2.7.1 */ #endif /* since version 2.2 */ - FT_Byte* horz_metrics; FT_ULong horz_metrics_size; - - FT_Byte* vert_metrics; FT_ULong vert_metrics_size; FT_ULong num_locations; /* in broken TTF, gid > 0xFFFF */ @@ -1371,6 +1529,7 @@ FT_ULong sbit_table_size; TT_SbitTableType sbit_table_type; FT_UInt sbit_num_strikes; + FT_UInt* sbit_strike_map; FT_Byte* kern_table; FT_ULong kern_table_size; @@ -1491,8 +1650,6 @@ FT_Vector pp1; FT_Vector pp2; - FT_ULong glyf_offset; - /* the zone where we load our glyphs */ TT_GlyphZoneRec base; TT_GlyphZoneRec zone; Index: reactos/sdk/lib/3rdparty/freetype/include/freetype/tttags.h =================================================================== --- reactos/sdk/lib/3rdparty/freetype/include/freetype/tttags.h (revision 74184) +++ reactos/sdk/lib/3rdparty/freetype/include/freetype/tttags.h (working copy) @@ -43,6 +43,7 @@ #define TTAG_CBDT FT_MAKE_TAG( 'C', 'B', 'D', 'T' ) #define TTAG_CBLC FT_MAKE_TAG( 'C', 'B', 'L', 'C' ) #define TTAG_CFF FT_MAKE_TAG( 'C', 'F', 'F', ' ' ) +#define TTAG_CFF2 FT_MAKE_TAG( 'C', 'F', 'F', '2' ) #define TTAG_CID FT_MAKE_TAG( 'C', 'I', 'D', ' ' ) #define TTAG_cmap FT_MAKE_TAG( 'c', 'm', 'a', 'p' ) #define TTAG_cvar FT_MAKE_TAG( 'c', 'v', 'a', 'r' ) @@ -61,6 +62,7 @@ #define TTAG_GPOS FT_MAKE_TAG( 'G', 'P', 'O', 'S' ) #define TTAG_GSUB FT_MAKE_TAG( 'G', 'S', 'U', 'B' ) #define TTAG_gvar FT_MAKE_TAG( 'g', 'v', 'a', 'r' ) +#define TTAG_HVAR FT_MAKE_TAG( 'H', 'V', 'A', 'R' ) #define TTAG_hdmx FT_MAKE_TAG( 'h', 'd', 'm', 'x' ) #define TTAG_head FT_MAKE_TAG( 'h', 'e', 'a', 'd' ) #define TTAG_hhea FT_MAKE_TAG( 'h', 'h', 'e', 'a' ) @@ -79,6 +81,7 @@ #define TTAG_MMSD FT_MAKE_TAG( 'M', 'M', 'S', 'D' ) #define TTAG_mort FT_MAKE_TAG( 'm', 'o', 'r', 't' ) #define TTAG_morx FT_MAKE_TAG( 'm', 'o', 'r', 'x' ) +#define TTAG_MVAR FT_MAKE_TAG( 'M', 'V', 'A', 'R' ) #define TTAG_name FT_MAKE_TAG( 'n', 'a', 'm', 'e' ) #define TTAG_opbd FT_MAKE_TAG( 'o', 'p', 'b', 'd' ) #define TTAG_OS2 FT_MAKE_TAG( 'O', 'S', '/', '2' ) @@ -100,6 +103,7 @@ #define TTAG_VDMX FT_MAKE_TAG( 'V', 'D', 'M', 'X' ) #define TTAG_vhea FT_MAKE_TAG( 'v', 'h', 'e', 'a' ) #define TTAG_vmtx FT_MAKE_TAG( 'v', 'm', 't', 'x' ) +#define TTAG_VVAR FT_MAKE_TAG( 'V', 'V', 'A', 'R' ) #define TTAG_wOFF FT_MAKE_TAG( 'w', 'O', 'F', 'F' ) Index: reactos/sdk/lib/3rdparty/freetype/README =================================================================== --- reactos/sdk/lib/3rdparty/freetype/README (revision 74184) +++ reactos/sdk/lib/3rdparty/freetype/README (working copy) @@ -1,5 +1,5 @@ - FreeType 2.7 - ============ + FreeType 2.7.1 + ============== Homepage: http://www.freetype.org @@ -24,9 +24,9 @@ and download one of the following files. - freetype-doc-2.7.tar.bz2 - freetype-doc-2.7.tar.gz - ftdoc27.zip + freetype-doc-2.7.1.tar.bz2 + freetype-doc-2.7.1.tar.gz + ftdoc271.zip To view the documentation online, go to Index: reactos/sdk/lib/3rdparty/freetype/src/autofit/afcjk.c =================================================================== --- reactos/sdk/lib/3rdparty/freetype/src/autofit/afcjk.c (revision 74184) +++ reactos/sdk/lib/3rdparty/freetype/src/autofit/afcjk.c (working copy) @@ -2366,13 +2366,13 @@ sizeof ( AF_CJKMetricsRec ), - (AF_WritingSystem_InitMetricsFunc) af_cjk_metrics_init, - (AF_WritingSystem_ScaleMetricsFunc)af_cjk_metrics_scale, - (AF_WritingSystem_DoneMetricsFunc) NULL, - (AF_WritingSystem_GetStdWidthsFunc)af_cjk_get_standard_widths, + (AF_WritingSystem_InitMetricsFunc) af_cjk_metrics_init, /* style_metrics_init */ + (AF_WritingSystem_ScaleMetricsFunc)af_cjk_metrics_scale, /* style_metrics_scale */ + (AF_WritingSystem_DoneMetricsFunc) NULL, /* style_metrics_done */ + (AF_WritingSystem_GetStdWidthsFunc)af_cjk_get_standard_widths, /* style_metrics_getstdw */ - (AF_WritingSystem_InitHintsFunc) af_cjk_hints_init, - (AF_WritingSystem_ApplyHintsFunc) af_cjk_hints_apply + (AF_WritingSystem_InitHintsFunc) af_cjk_hints_init, /* style_hints_init */ + (AF_WritingSystem_ApplyHintsFunc) af_cjk_hints_apply /* style_hints_apply */ ) @@ -2386,13 +2386,13 @@ sizeof ( AF_CJKMetricsRec ), - (AF_WritingSystem_InitMetricsFunc) NULL, - (AF_WritingSystem_ScaleMetricsFunc)NULL, - (AF_WritingSystem_DoneMetricsFunc) NULL, - (AF_WritingSystem_GetStdWidthsFunc)NULL, + (AF_WritingSystem_InitMetricsFunc) NULL, /* style_metrics_init */ + (AF_WritingSystem_ScaleMetricsFunc)NULL, /* style_metrics_scale */ + (AF_WritingSystem_DoneMetricsFunc) NULL, /* style_metrics_done */ + (AF_WritingSystem_GetStdWidthsFunc)NULL, /* style_metrics_getstdw */ - (AF_WritingSystem_InitHintsFunc) NULL, - (AF_WritingSystem_ApplyHintsFunc) NULL + (AF_WritingSystem_InitHintsFunc) NULL, /* style_hints_init */ + (AF_WritingSystem_ApplyHintsFunc) NULL /* style_hints_apply */ ) Index: reactos/sdk/lib/3rdparty/freetype/src/autofit/afdummy.c =================================================================== --- reactos/sdk/lib/3rdparty/freetype/src/autofit/afdummy.c (revision 74184) +++ reactos/sdk/lib/3rdparty/freetype/src/autofit/afdummy.c (working copy) @@ -62,13 +62,13 @@ sizeof ( AF_StyleMetricsRec ), - (AF_WritingSystem_InitMetricsFunc) NULL, - (AF_WritingSystem_ScaleMetricsFunc)NULL, - (AF_WritingSystem_DoneMetricsFunc) NULL, - (AF_WritingSystem_GetStdWidthsFunc)NULL, + (AF_WritingSystem_InitMetricsFunc) NULL, /* style_metrics_init */ + (AF_WritingSystem_ScaleMetricsFunc)NULL, /* style_metrics_scale */ + (AF_WritingSystem_DoneMetricsFunc) NULL, /* style_metrics_done */ + (AF_WritingSystem_GetStdWidthsFunc)NULL, /* style_metrics_getstdw */ - (AF_WritingSystem_InitHintsFunc) af_dummy_hints_init, - (AF_WritingSystem_ApplyHintsFunc) af_dummy_hints_apply + (AF_WritingSystem_InitHintsFunc) af_dummy_hints_init, /* style_hints_init */ + (AF_WritingSystem_ApplyHintsFunc) af_dummy_hints_apply /* style_hints_apply */ ) Index: reactos/sdk/lib/3rdparty/freetype/src/autofit/afglobal.c =================================================================== --- reactos/sdk/lib/3rdparty/freetype/src/autofit/afglobal.c (revision 74184) +++ reactos/sdk/lib/3rdparty/freetype/src/autofit/afglobal.c (working copy) @@ -168,7 +168,7 @@ AF_Script_UniRange range; - if ( script_class->script_uni_ranges == NULL ) + if ( !script_class->script_uni_ranges ) continue; /* @@ -417,17 +417,8 @@ globals->hb_buf = NULL; #endif - globals->glyph_count = 0; - globals->stem_darkening_for_ppem = 0; - globals->darken_x = 0; - globals->darken_y = 0; - globals->standard_vertical_width = 0; - globals->standard_horizontal_width = 0; - globals->scale_down_factor = 0; - /* no need to free this one! */ - globals->glyph_styles = NULL; - globals->face = NULL; - + /* no need to free `globals->glyph_styles'; */ + /* it is part of the `globals' array */ FT_FREE( globals ); } } @@ -465,7 +456,7 @@ [style_class->writing_system]; metrics = globals->metrics[style]; - if ( metrics == NULL ) + if ( !metrics ) { /* create the global metrics object if necessary */ FT_Memory memory = globals->face->memory; Index: reactos/sdk/lib/3rdparty/freetype/src/autofit/afhints.c =================================================================== --- reactos/sdk/lib/3rdparty/freetype/src/autofit/afhints.c (revision 74184) +++ reactos/sdk/lib/3rdparty/freetype/src/autofit/afhints.c (working copy) @@ -45,7 +45,7 @@ if ( axis->num_segments < AF_SEGMENTS_EMBEDDED ) { - if ( axis->segments == NULL ) + if ( !axis->segments ) { axis->segments = axis->embedded.segments; axis->max_segments = AF_SEGMENTS_EMBEDDED; @@ -110,7 +110,7 @@ if ( axis->num_edges < AF_EDGES_EMBEDDED ) { - if ( axis->edges == NULL ) + if ( !axis->edges ) { axis->edges = axis->embedded.edges; axis->max_edges = AF_EDGES_EMBEDDED; @@ -743,7 +743,7 @@ if ( new_max <= AF_CONTOURS_EMBEDDED ) { - if ( hints->contours == NULL ) + if ( !hints->contours ) { hints->contours = hints->embedded.contours; hints->max_contours = AF_CONTOURS_EMBEDDED; @@ -772,7 +772,7 @@ if ( new_max <= AF_POINTS_EMBEDDED ) { - if ( hints->points == NULL ) + if ( !hints->points ) { hints->points = hints->embedded.points; hints->max_points = AF_POINTS_EMBEDDED; @@ -1182,7 +1182,7 @@ AF_Point point, first, last; - if ( edge == NULL ) + if ( !edge ) continue; first = seg->first; @@ -1208,7 +1208,7 @@ AF_Point point, first, last; - if ( edge == NULL ) + if ( !edge ) continue; first = seg->first; Index: reactos/sdk/lib/3rdparty/freetype/src/autofit/afindic.c =================================================================== --- reactos/sdk/lib/3rdparty/freetype/src/autofit/afindic.c (revision 74184) +++ reactos/sdk/lib/3rdparty/freetype/src/autofit/afindic.c (working copy) @@ -121,13 +121,13 @@ sizeof ( AF_CJKMetricsRec ), - (AF_WritingSystem_InitMetricsFunc) af_indic_metrics_init, - (AF_WritingSystem_ScaleMetricsFunc)af_indic_metrics_scale, - (AF_WritingSystem_DoneMetricsFunc) NULL, - (AF_WritingSystem_GetStdWidthsFunc)af_indic_get_standard_widths, + (AF_WritingSystem_InitMetricsFunc) af_indic_metrics_init, /* style_metrics_init */ + (AF_WritingSystem_ScaleMetricsFunc)af_indic_metrics_scale, /* style_metrics_scale */ + (AF_WritingSystem_DoneMetricsFunc) NULL, /* style_metrics_done */ + (AF_WritingSystem_GetStdWidthsFunc)af_indic_get_standard_widths, /* style_metrics_getstdw */ - (AF_WritingSystem_InitHintsFunc) af_indic_hints_init, - (AF_WritingSystem_ApplyHintsFunc) af_indic_hints_apply + (AF_WritingSystem_InitHintsFunc) af_indic_hints_init, /* style_hints_init */ + (AF_WritingSystem_ApplyHintsFunc) af_indic_hints_apply /* style_hints_apply */ ) @@ -141,13 +141,13 @@ sizeof ( AF_CJKMetricsRec ), - (AF_WritingSystem_InitMetricsFunc) NULL, - (AF_WritingSystem_ScaleMetricsFunc)NULL, - (AF_WritingSystem_DoneMetricsFunc) NULL, - (AF_WritingSystem_GetStdWidthsFunc)NULL, + (AF_WritingSystem_InitMetricsFunc) NULL, /* style_metrics_init */ + (AF_WritingSystem_ScaleMetricsFunc)NULL, /* style_metrics_scale */ + (AF_WritingSystem_DoneMetricsFunc) NULL, /* style_metrics_done */ + (AF_WritingSystem_GetStdWidthsFunc)NULL, /* style_metrics_getstdw */ - (AF_WritingSystem_InitHintsFunc) NULL, - (AF_WritingSystem_ApplyHintsFunc) NULL + (AF_WritingSystem_InitHintsFunc) NULL, /* style_hints_init */ + (AF_WritingSystem_ApplyHintsFunc) NULL /* style_hints_apply */ ) Index: reactos/sdk/lib/3rdparty/freetype/src/autofit/aflatin.c =================================================================== --- reactos/sdk/lib/3rdparty/freetype/src/autofit/aflatin.c (revision 74184) +++ reactos/sdk/lib/3rdparty/freetype/src/autofit/aflatin.c (working copy) @@ -1143,7 +1143,7 @@ "af_latin_metrics_scale_dim:" " x height alignment (style `%s'):\n" " " - " vertical scaling changed from %.4f to %.4f (by %d%%)\n" + " vertical scaling changed from %.5f to %.5f (by %d%%)\n" "\n", af_style_names[metrics->root.style_class->style], scale / 65536.0, @@ -2227,7 +2227,7 @@ seg->serif->edge && seg->serif->edge != edge ); - if ( ( seg->link && seg->link->edge != NULL ) || is_serif ) + if ( ( seg->link && seg->link->edge ) || is_serif ) { AF_Edge edge2; AF_Segment seg2; @@ -3493,13 +3493,13 @@ sizeof ( AF_LatinMetricsRec ), - (AF_WritingSystem_InitMetricsFunc) af_latin_metrics_init, - (AF_WritingSystem_ScaleMetricsFunc)af_latin_metrics_scale, - (AF_WritingSystem_DoneMetricsFunc) NULL, - (AF_WritingSystem_GetStdWidthsFunc)af_latin_get_standard_widths, + (AF_WritingSystem_InitMetricsFunc) af_latin_metrics_init, /* style_metrics_init */ + (AF_WritingSystem_ScaleMetricsFunc)af_latin_metrics_scale, /* style_metrics_scale */ + (AF_WritingSystem_DoneMetricsFunc) NULL, /* style_metrics_done */ + (AF_WritingSystem_GetStdWidthsFunc)af_latin_get_standard_widths, /* style_metrics_getstdw */ - (AF_WritingSystem_InitHintsFunc) af_latin_hints_init, - (AF_WritingSystem_ApplyHintsFunc) af_latin_hints_apply + (AF_WritingSystem_InitHintsFunc) af_latin_hints_init, /* style_hints_init */ + (AF_WritingSystem_ApplyHintsFunc) af_latin_hints_apply /* style_hints_apply */ ) Index: reactos/sdk/lib/3rdparty/freetype/src/autofit/aflatin2.c =================================================================== --- reactos/sdk/lib/3rdparty/freetype/src/autofit/aflatin2.c (revision 74184) +++ reactos/sdk/lib/3rdparty/freetype/src/autofit/aflatin2.c (working copy) @@ -1303,7 +1303,7 @@ seg->serif->edge && seg->serif->edge != edge ); - if ( ( seg->link && seg->link->edge != NULL ) || is_serif ) + if ( ( seg->link && seg->link->edge ) || is_serif ) { AF_Edge edge2; AF_Segment seg2; @@ -2410,13 +2410,13 @@ sizeof ( AF_LatinMetricsRec ), - (AF_WritingSystem_InitMetricsFunc) af_latin2_metrics_init, - (AF_WritingSystem_ScaleMetricsFunc)af_latin2_metrics_scale, - (AF_WritingSystem_DoneMetricsFunc) NULL, - (AF_WritingSystem_GetStdWidthsFunc)af_latin2_get_standard_widths, + (AF_WritingSystem_InitMetricsFunc) af_latin2_metrics_init, /* style_metrics_init */ + (AF_WritingSystem_ScaleMetricsFunc)af_latin2_metrics_scale, /* style_metrics_scale */ + (AF_WritingSystem_DoneMetricsFunc) NULL, /* style_metrics_done */ + (AF_WritingSystem_GetStdWidthsFunc)af_latin2_get_standard_widths, /* style_metrics_getstdw */ - (AF_WritingSystem_InitHintsFunc) af_latin2_hints_init, - (AF_WritingSystem_ApplyHintsFunc) af_latin2_hints_apply + (AF_WritingSystem_InitHintsFunc) af_latin2_hints_init, /* style_hints_init */ + (AF_WritingSystem_ApplyHintsFunc) af_latin2_hints_apply /* style_hints_apply */ ) Index: reactos/sdk/lib/3rdparty/freetype/src/autofit/afloader.c =================================================================== --- reactos/sdk/lib/3rdparty/freetype/src/autofit/afloader.c (revision 74184) +++ reactos/sdk/lib/3rdparty/freetype/src/autofit/afloader.c (working copy) @@ -51,7 +51,7 @@ loader->face = face; loader->globals = (AF_FaceGlobals)face->autohint.data; - if ( loader->globals == NULL ) + if ( !loader->globals ) { error = af_face_globals_new( face, &loader->globals, module ); if ( !error ) @@ -86,161 +86,258 @@ ( (FT_Fixed)( (f) * 65536.0 + 0.5 ) ) - /* Do the main work of `af_loader_load_glyph'. Note that we never */ - /* have to deal with composite glyphs as those get loaded into */ - /* FT_GLYPH_FORMAT_OUTLINE by the recursed `FT_Load_Glyph' function. */ - /* In the rare cases where FT_LOAD_NO_RECURSE is set, it implies */ - /* FT_LOAD_NO_SCALE and as such the auto-hinter is never called. */ - static FT_Error - af_loader_load_g( AF_Loader loader, - AF_Scaler scaler, - FT_UInt glyph_index, - FT_Int32 load_flags ) + af_loader_embolden_glyph_in_slot( AF_Loader loader, + FT_Face face, + AF_StyleMetrics style_metrics ) { - AF_Module module = loader->globals->module; + FT_Error error = FT_Err_Ok; - FT_Error error; - FT_Face face = loader->face; - AF_StyleMetrics metrics = loader->metrics; - AF_GlyphHints hints = loader->hints; - FT_GlyphSlot slot = face->glyph; - FT_Slot_Internal internal = slot->internal; - FT_GlyphLoader gloader = internal->loader; - FT_Int32 flags; + FT_GlyphSlot slot = face->glyph; + AF_FaceGlobals globals = loader->globals; + AF_WritingSystemClass writing_system_class; + FT_Pos stdVW = 0; + FT_Pos stdHW = 0; - flags = load_flags | FT_LOAD_LINEAR_DESIGN; - error = FT_Load_Glyph( face, glyph_index, flags ); - if ( error ) + FT_Bool size_changed = face->size->metrics.x_ppem + != globals->stem_darkening_for_ppem; + + FT_Fixed em_size = af_intToFixed( face->units_per_EM ); + FT_Fixed em_ratio = FT_DivFix( af_intToFixed( 1000 ), em_size ); + + FT_Matrix scale_down_matrix = { 0x10000L, 0, 0, 0x10000L }; + + + /* Skip stem darkening for broken fonts. */ + if ( !face->units_per_EM ) + { + error = FT_Err_Corrupted_Font_Header; goto Exit; + } /* - * Apply stem darkening (emboldening) here before hints are applied to - * the outline. Glyphs are scaled down proportionally to the - * emboldening so that curve points don't fall outside their precomputed - * blue zones. - * - * Any emboldening done by the font driver (e.g., the CFF driver) - * doesn't reach here because the autohinter loads the unprocessed - * glyphs in font units for analysis (functions `af_*_metrics_init_*') - * and then above to prepare it for the rasterizers by itself, - * independently of the font driver. So emboldening must be done here, - * within the autohinter. - * - * All glyphs to be autohinted pass through here one by one. The - * standard widths can therefore change from one glyph to the next, - * depending on what script a glyph is assigned to (each script has its - * own set of standard widths and other metrics). The darkening amount - * must therefore be recomputed for each size and - * `standard_{vertical,horizontal}_width' change. + * We depend on the writing system (script analyzers) to supply + * standard widths for the script of the glyph we are looking at. If + * it can't deliver, stem darkening is disabled. */ - if ( !module->no_stem_darkening ) + writing_system_class = + AF_WRITING_SYSTEM_CLASSES_GET[style_metrics->style_class->writing_system]; + + if ( writing_system_class->style_metrics_getstdw ) + writing_system_class->style_metrics_getstdw( style_metrics, + &stdHW, + &stdVW ); + else { - AF_FaceGlobals globals = loader->globals; - AF_WritingSystemClass writing_system_class; + error = FT_Err_Unimplemented_Feature; + goto Exit; + } - FT_Pos stdVW = 0; - FT_Pos stdHW = 0; + if ( size_changed || + ( stdVW > 0 && stdVW != globals->standard_vertical_width ) ) + { + FT_Fixed darken_by_font_units_x, darken_x; - FT_Bool size_changed = face->size->metrics.x_ppem - != globals->stem_darkening_for_ppem; - FT_Fixed em_size = af_intToFixed( face->units_per_EM ); - FT_Fixed em_ratio = FT_DivFix( af_intToFixed( 1000 ), em_size ); + darken_by_font_units_x = + af_intToFixed( af_loader_compute_darkening( loader, + face, + stdVW ) ); + darken_x = FT_DivFix( FT_MulFix( darken_by_font_units_x, + face->size->metrics.x_scale ), + em_ratio ); - FT_Matrix scale_down_matrix = { 0x10000L, 0, 0, 0x10000L }; + globals->standard_vertical_width = stdVW; + globals->stem_darkening_for_ppem = face->size->metrics.x_ppem; + globals->darken_x = af_fixedToInt( darken_x ); + } + if ( size_changed || + ( stdHW > 0 && stdHW != globals->standard_horizontal_width ) ) + { + FT_Fixed darken_by_font_units_y, darken_y; - /* Skip stem darkening for broken fonts. */ - if ( !face->units_per_EM ) - goto After_Emboldening; + darken_by_font_units_y = + af_intToFixed( af_loader_compute_darkening( loader, + face, + stdHW ) ); + darken_y = FT_DivFix( FT_MulFix( darken_by_font_units_y, + face->size->metrics.y_scale ), + em_ratio ); + + globals->standard_horizontal_width = stdHW; + globals->stem_darkening_for_ppem = face->size->metrics.x_ppem; + globals->darken_y = af_fixedToInt( darken_y ); + /* - * We depend on the writing system (script analyzers) to supply - * standard widths for the script of the glyph we are looking at. If - * it can't deliver, stem darkening is effectively disabled. + * Scale outlines down on the Y-axis to keep them inside their blue + * zones. The stronger the emboldening, the stronger the downscaling + * (plus heuristical padding to prevent outlines still falling out + * their zones due to rounding). + * + * Reason: `FT_Outline_Embolden' works by shifting the rightmost + * points of stems farther to the right, and topmost points farther + * up. This positions points on the Y-axis outside their + * pre-computed blue zones and leads to distortion when applying the + * hints in the code further below. Code outside this emboldening + * block doesn't know we are presenting it with modified outlines the + * analyzer didn't see! + * + * An unfortunate side effect of downscaling is that the emboldening + * effect is slightly decreased. The loss becomes more pronounced + * versus the CFF driver at smaller sizes, e.g., at 9ppem and below. */ - writing_system_class = - AF_WRITING_SYSTEM_CLASSES_GET[metrics->style_class->writing_system]; + globals->scale_down_factor = + FT_DivFix( em_size - ( darken_by_font_units_y + af_intToFixed( 8 ) ), + em_size ); + } - if ( writing_system_class->style_metrics_getstdw ) - writing_system_class->style_metrics_getstdw( metrics, - &stdHW, - &stdVW ); - else - goto After_Emboldening; + FT_Outline_EmboldenXY( &slot->outline, + globals->darken_x, + globals->darken_y ); + scale_down_matrix.yy = globals->scale_down_factor; + FT_Outline_Transform( &slot->outline, &scale_down_matrix ); - if ( size_changed || - ( stdVW > 0 && stdVW != globals->standard_vertical_width ) ) - { - FT_Fixed darken_by_font_units_x, darken_x; + Exit: + return error; + } - darken_by_font_units_x = - af_intToFixed( af_loader_compute_darkening( loader, - face, - stdVW ) ); - darken_x = FT_DivFix( FT_MulFix( darken_by_font_units_x, - face->size->metrics.x_scale ), - em_ratio ); + /* Load the glyph at index into the current slot of a face and hint it. */ - globals->standard_vertical_width = stdVW; - globals->stem_darkening_for_ppem = face->size->metrics.x_ppem; - globals->darken_x = af_fixedToInt( darken_x ); - } + FT_LOCAL_DEF( FT_Error ) + af_loader_load_glyph( AF_Loader loader, + AF_Module module, + FT_Face face, + FT_UInt glyph_index, + FT_Int32 load_flags ) + { + FT_Error error; - if ( size_changed || - ( stdHW > 0 && stdHW != globals->standard_horizontal_width ) ) - { - FT_Fixed darken_by_font_units_y, darken_y; + FT_Size size = face->size; + FT_GlyphSlot slot = face->glyph; + FT_Slot_Internal internal = slot->internal; + FT_GlyphLoader gloader = internal->loader; + AF_GlyphHints hints = loader->hints; + AF_ScalerRec scaler; + AF_StyleMetrics style_metrics; + FT_UInt style_options = AF_STYLE_NONE_DFLT; + AF_StyleClass style_class; + AF_WritingSystemClass writing_system_class; - darken_by_font_units_y = - af_intToFixed( af_loader_compute_darkening( loader, - face, - stdHW ) ); - darken_y = FT_DivFix( FT_MulFix( darken_by_font_units_y, - face->size->metrics.y_scale ), - em_ratio ); +#ifdef FT_CONFIG_OPTION_PIC + AF_FaceGlobals globals = loader->globals; +#endif - globals->standard_horizontal_width = stdHW; - globals->stem_darkening_for_ppem = face->size->metrics.x_ppem; - globals->darken_y = af_fixedToInt( darken_y ); - /* - * Scale outlines down on the Y-axis to keep them inside their blue - * zones. The stronger the emboldening, the stronger the - * downscaling (plus heuristical padding to prevent outlines still - * falling out their zones due to rounding). - * - * Reason: `FT_Outline_Embolden' works by shifting the rightmost - * points of stems farther to the right, and topmost points farther - * up. This positions points on the Y-axis outside their - * pre-computed blue zones and leads to distortion when applying the - * hints in the code further below. Code outside this emboldening - * block doesn't know we are presenting it with modified outlines - * the analyzer didn't see! - * - * An unfortunate side effect of downscaling is that the emboldening - * effect is slightly decreased. The loss becomes more pronounced - * versus the CFF driver at smaller sizes, e.g., at 9ppem and below. - */ - globals->scale_down_factor = - FT_DivFix( em_size - ( darken_by_font_units_y + af_intToFixed( 8 ) ), - em_size ); - } + if ( !size ) + return FT_THROW( Invalid_Size_Handle ); - FT_Outline_EmboldenXY( &slot->outline, - globals->darken_x, - globals->darken_y ); + FT_ZERO( &scaler ); - scale_down_matrix.yy = globals->scale_down_factor; - FT_Outline_Transform( &slot->outline, &scale_down_matrix ); + /* + * TODO: This code currently doesn't support fractional advance widths, + * i.e. placing hinted glyphs at anything other than integer + * x-positions. This is only relevant for the warper code, which + * scales and shifts glyphs to optimize blackness of stems (hinting on + * the x-axis by nature places things on pixel integers, hinting on the + * y-axis only, i.e. LIGHT mode, doesn't touch the x-axis). The delta + * values of the scaler would need to be adjusted. + */ + scaler.face = face; + scaler.x_scale = size->metrics.x_scale; + scaler.x_delta = 0; + scaler.y_scale = size->metrics.y_scale; + scaler.y_delta = 0; + + scaler.render_mode = FT_LOAD_TARGET_MODE( load_flags ); + scaler.flags = 0; + + error = af_loader_reset( loader, module, face ); + if ( error ) + goto Exit; + +#ifdef FT_OPTION_AUTOFIT2 + /* XXX: undocumented hook to activate the latin2 writing system. */ + if ( load_flags & ( 1UL << 20 ) ) + style_options = AF_STYLE_LTN2_DFLT; +#endif + + /* + * Glyphs (really code points) are assigned to scripts. Script + * analysis is done lazily: For each glyph that passes through here, + * the corresponding script analyzer is called, but returns immediately + * if it has been run already. + */ + error = af_face_globals_get_metrics( loader->globals, glyph_index, + style_options, &style_metrics ); + if ( error ) + goto Exit; + + style_class = style_metrics->style_class; + writing_system_class = + AF_WRITING_SYSTEM_CLASSES_GET[style_class->writing_system]; + + loader->metrics = style_metrics; + + if ( writing_system_class->style_metrics_scale ) + writing_system_class->style_metrics_scale( style_metrics, &scaler ); + else + style_metrics->scaler = scaler; + + if ( writing_system_class->style_hints_init ) + { + error = writing_system_class->style_hints_init( hints, + style_metrics ); + if ( error ) + goto Exit; } - After_Emboldening: + /* + * Do the main work of `af_loader_load_glyph'. Note that we never have + * to deal with composite glyphs as those get loaded into + * FT_GLYPH_FORMAT_OUTLINE by the recursed `FT_Load_Glyph' function. + * In the rare cases where FT_LOAD_NO_RECURSE is set, it implies + * FT_LOAD_NO_SCALE and as such the auto-hinter is never called. + */ + load_flags |= FT_LOAD_NO_SCALE | + FT_LOAD_IGNORE_TRANSFORM | + FT_LOAD_LINEAR_DESIGN; + load_flags &= ~FT_LOAD_RENDER; + + error = FT_Load_Glyph( face, glyph_index, load_flags ); + if ( error ) + goto Exit; + + /* + * Apply stem darkening (emboldening) here before hints are applied to + * the outline. Glyphs are scaled down proportionally to the + * emboldening so that curve points don't fall outside their + * precomputed blue zones. + * + * Any emboldening done by the font driver (e.g., the CFF driver) + * doesn't reach here because the autohinter loads the unprocessed + * glyphs in font units for analysis (functions `af_*_metrics_init_*') + * and then above to prepare it for the rasterizers by itself, + * independently of the font driver. So emboldening must be done here, + * within the autohinter. + * + * All glyphs to be autohinted pass through here one by one. The + * standard widths can therefore change from one glyph to the next, + * depending on what script a glyph is assigned to (each script has its + * own set of standard widths and other metrics). The darkening amount + * must therefore be recomputed for each size and + * `standard_{vertical,horizontal}_width' change. + * + * Ignore errors and carry on without emboldening. + */ + if ( !module->no_stem_darkening ) + af_loader_embolden_glyph_in_slot( loader, face, style_metrics ); + loader->transformed = internal->glyph_transformed; if ( loader->transformed ) { @@ -264,8 +361,8 @@ loader->trans_delta.x, loader->trans_delta.y ); - /* compute original horizontal phantom points (and ignore */ - /* vertical ones) */ + /* compute original horizontal phantom points */ + /* (and ignore vertical ones) */ loader->pp1.x = hints->x_delta; loader->pp1.y = hints->y_delta; loader->pp2.x = FT_MulFix( slot->metrics.horiAdvance, @@ -276,15 +373,12 @@ if ( slot->outline.n_points == 0 ) goto Hint_Metrics; - /* now load the slot image into the auto-outline and run the */ - /* automatic hinting process */ + /* now load the slot image into the auto-outline */ + /* and run the automatic hinting process */ { #ifdef FT_CONFIG_OPTION_PIC - AF_FaceGlobals globals = loader->globals; + AF_FaceGlobals globals = loader->globals; #endif - AF_StyleClass style_class = metrics->style_class; - AF_WritingSystemClass writing_system_class = - AF_WRITING_SYSTEM_CLASSES_GET[style_class->writing_system]; if ( writing_system_class->style_hints_apply ) @@ -291,15 +385,16 @@ writing_system_class->style_hints_apply( glyph_index, hints, &gloader->base.outline, - metrics ); + style_metrics ); } /* we now need to adjust the metrics according to the change in */ /* width/positioning that occurred during the hinting process */ - if ( scaler->render_mode != FT_RENDER_MODE_LIGHT ) + if ( scaler.render_mode != FT_RENDER_MODE_LIGHT ) { - FT_Pos old_rsb, old_lsb, new_lsb; - FT_Pos pp1x_uh, pp2x_uh; + FT_Pos old_rsb, old_lsb, new_lsb; + FT_Pos pp1x_uh, pp2x_uh; + AF_AxisHints axis = &hints->axis[AF_DIMENSION_HORZ]; AF_Edge edge1 = axis->edges; /* leftmost edge */ AF_Edge edge2 = edge1 + @@ -309,12 +404,10 @@ if ( axis->num_edges > 1 && AF_HINTS_DO_ADVANCE( hints ) ) { old_rsb = loader->pp2.x - edge2->opos; - old_lsb = edge1->opos; + /* loader->pp1.x is always zero at this point of time */ + old_lsb = edge1->opos /* - loader->pp1.x */; new_lsb = edge1->pos; - /* remember unhinted values to later account */ - /* for rounding errors */ - pp1x_uh = new_lsb - old_lsb; pp2x_uh = edge2->pos + old_rsb; @@ -380,8 +473,8 @@ vvector.x = slot->metrics.vertBearingX - slot->metrics.horiBearingX; vvector.y = slot->metrics.vertBearingY - slot->metrics.horiBearingY; - vvector.x = FT_MulFix( vvector.x, metrics->scaler.x_scale ); - vvector.y = FT_MulFix( vvector.y, metrics->scaler.y_scale ); + vvector.x = FT_MulFix( vvector.x, style_metrics->scaler.x_scale ); + vvector.y = FT_MulFix( vvector.y, style_metrics->scaler.y_scale ); /* transform the hinted outline if needed */ if ( loader->transformed ) @@ -389,12 +482,12 @@ FT_Outline_Transform( &gloader->base.outline, &loader->trans_matrix ); FT_Vector_Transform( &vvector, &loader->trans_matrix ); } -#if 1 + /* we must translate our final outline by -pp1.x and compute */ /* the new metrics */ if ( loader->pp1.x ) FT_Outline_Translate( &gloader->base.outline, -loader->pp1.x, 0 ); -#endif + FT_Outline_Get_CBox( &gloader->base.outline, &bbox ); bbox.xMin = FT_PIX_FLOOR( bbox.xMin ); @@ -413,20 +506,14 @@ /* for mono-width fonts (like Andale, Courier, etc.) we need */ /* to keep the original rounded advance width; ditto for */ /* digits if all have the same advance width */ -#if 0 - if ( !FT_IS_FIXED_WIDTH( slot->face ) ) - slot->metrics.horiAdvance = loader->pp2.x - loader->pp1.x; - else - slot->metrics.horiAdvance = FT_MulFix( slot->metrics.horiAdvance, - x_scale ); -#else - if ( scaler->render_mode != FT_RENDER_MODE_LIGHT && + if ( scaler.render_mode != FT_RENDER_MODE_LIGHT && ( FT_IS_FIXED_WIDTH( slot->face ) || ( af_face_globals_is_digit( loader->globals, glyph_index ) && - metrics->digits_have_same_width ) ) ) + style_metrics->digits_have_same_width ) ) ) { - slot->metrics.horiAdvance = FT_MulFix( slot->metrics.horiAdvance, - metrics->scaler.x_scale ); + slot->metrics.horiAdvance = + FT_MulFix( slot->metrics.horiAdvance, + style_metrics->scaler.x_scale ); /* Set delta values to 0. Otherwise code that uses them is */ /* going to ruin the fixed advance width. */ @@ -439,23 +526,13 @@ if ( slot->metrics.horiAdvance ) slot->metrics.horiAdvance = loader->pp2.x - loader->pp1.x; } -#endif slot->metrics.vertAdvance = FT_MulFix( slot->metrics.vertAdvance, - metrics->scaler.y_scale ); + style_metrics->scaler.y_scale ); slot->metrics.horiAdvance = FT_PIX_ROUND( slot->metrics.horiAdvance ); slot->metrics.vertAdvance = FT_PIX_ROUND( slot->metrics.vertAdvance ); -#if 0 - /* reassign all outline fields except flags to protect them */ - slot->outline.n_contours = internal->loader->base.outline.n_contours; - slot->outline.n_points = internal->loader->base.outline.n_points; - slot->outline.points = internal->loader->base.outline.points; - slot->outline.tags = internal->loader->base.outline.tags; - slot->outline.contours = internal->loader->base.outline.contours; -#endif - slot->format = FT_GLYPH_FORMAT_OUTLINE; } @@ -464,85 +541,6 @@ } - /* Load a glyph. */ - - FT_LOCAL_DEF( FT_Error ) - af_loader_load_glyph( AF_Loader loader, - AF_Module module, - FT_Face face, - FT_UInt gindex, - FT_Int32 load_flags ) - { - FT_Error error; - FT_Size size = face->size; - AF_ScalerRec scaler; - - - if ( !size ) - return FT_THROW( Invalid_Size_Handle ); - - FT_ZERO( &scaler ); - - scaler.face = face; - scaler.x_scale = size->metrics.x_scale; - scaler.x_delta = 0; /* XXX: TODO: add support for sub-pixel hinting */ - scaler.y_scale = size->metrics.y_scale; - scaler.y_delta = 0; /* XXX: TODO: add support for sub-pixel hinting */ - - scaler.render_mode = FT_LOAD_TARGET_MODE( load_flags ); - scaler.flags = 0; /* XXX: fix this */ - - error = af_loader_reset( loader, module, face ); - if ( !error ) - { - AF_StyleMetrics metrics; - FT_UInt options = AF_STYLE_NONE_DFLT; - - -#ifdef FT_OPTION_AUTOFIT2 - /* XXX: undocumented hook to activate the latin2 writing system */ - if ( load_flags & ( 1UL << 20 ) ) - options = AF_STYLE_LTN2_DFLT; -#endif - - error = af_face_globals_get_metrics( loader->globals, gindex, - options, &metrics ); - if ( !error ) - { -#ifdef FT_CONFIG_OPTION_PIC - AF_FaceGlobals globals = loader->globals; -#endif - AF_StyleClass style_class = metrics->style_class; - AF_WritingSystemClass writing_system_class = - AF_WRITING_SYSTEM_CLASSES_GET[style_class->writing_system]; - - - loader->metrics = metrics; - - if ( writing_system_class->style_metrics_scale ) - writing_system_class->style_metrics_scale( metrics, &scaler ); - else - metrics->scaler = scaler; - - load_flags |= FT_LOAD_NO_SCALE | FT_LOAD_IGNORE_TRANSFORM; - load_flags &= ~FT_LOAD_RENDER; - - if ( writing_system_class->style_hints_init ) - { - error = writing_system_class->style_hints_init( loader->hints, - metrics ); - if ( error ) - goto Exit; - } - - error = af_loader_load_g( loader, &scaler, gindex, load_flags ); - } - } - Exit: - return error; - } - - /* * Compute amount of font units the face should be emboldened by, in * analogy to the CFF driver's `cf2_computeDarkening' function. See there Index: reactos/sdk/lib/3rdparty/freetype/src/autofit/afmodule.c =================================================================== --- reactos/sdk/lib/3rdparty/freetype/src/autofit/afmodule.c (revision 74184) +++ reactos/sdk/lib/3rdparty/freetype/src/autofit/afmodule.c (working copy) @@ -421,6 +421,7 @@ FT_DEFINE_SERVICE_PROPERTIESREC( af_service_properties, + (FT_Properties_SetFunc)af_property_set, /* set_property */ (FT_Properties_GetFunc)af_property_get ) /* get_property */ @@ -427,6 +428,7 @@ FT_DEFINE_SERVICEDESCREC1( af_services, + FT_SERVICE_ID_PROPERTIES, &AF_SERVICE_PROPERTIES_GET ) @@ -519,9 +521,16 @@ error = af_loader_load_glyph( loader, module, slot->face, glyph_index, load_flags ); - af_glyph_hints_dump_points( hints, 0 ); - af_glyph_hints_dump_segments( hints, 0 ); - af_glyph_hints_dump_edges( hints, 0 ); +#ifdef FT_DEBUG_LEVEL_TRACE + if ( ft_trace_levels[FT_COMPONENT] ) + { +#endif + af_glyph_hints_dump_points( hints, 0 ); + af_glyph_hints_dump_segments( hints, 0 ); + af_glyph_hints_dump_edges( hints, 0 ); +#ifdef FT_DEBUG_LEVEL_TRACE + } +#endif af_loader_done( loader ); @@ -561,6 +570,7 @@ FT_DEFINE_AUTOHINTER_INTERFACE( af_autofitter_interface, + NULL, /* reset_face */ NULL, /* get_global_hints */ NULL, /* done_global_hints */ @@ -579,9 +589,10 @@ (const void*)&AF_INTERFACE_GET, - (FT_Module_Constructor)af_autofitter_init, - (FT_Module_Destructor) af_autofitter_done, - (FT_Module_Requester) af_get_interface ) + (FT_Module_Constructor)af_autofitter_init, /* module_init */ + (FT_Module_Destructor) af_autofitter_done, /* module_done */ + (FT_Module_Requester) af_get_interface /* get_interface */ + ) /* END */ Index: reactos/sdk/lib/3rdparty/freetype/src/autofit/aftypes.h =================================================================== --- reactos/sdk/lib/3rdparty/freetype/src/autofit/aftypes.h (revision 74184) +++ reactos/sdk/lib/3rdparty/freetype/src/autofit/aftypes.h (working copy) @@ -221,7 +221,7 @@ (*AF_WritingSystem_InitHintsFunc)( AF_GlyphHints hints, AF_StyleMetrics metrics ); - typedef void + typedef FT_Error (*AF_WritingSystem_ApplyHintsFunc)( FT_UInt glyph_index, AF_GlyphHints hints, FT_Outline* outline, Index: reactos/sdk/lib/3rdparty/freetype/src/base/ftadvanc.c =================================================================== --- reactos/sdk/lib/3rdparty/freetype/src/base/ftadvanc.c (revision 74184) +++ reactos/sdk/lib/3rdparty/freetype/src/base/ftadvanc.c (working copy) @@ -36,7 +36,7 @@ if ( flags & FT_LOAD_NO_SCALE ) return FT_Err_Ok; - if ( face->size == NULL ) + if ( !face->size ) return FT_THROW( Invalid_Size_Handle ); if ( flags & FT_LOAD_VERTICAL_LAYOUT ) @@ -60,12 +60,13 @@ /* - unscaled load */ /* - unhinted load */ /* - light-hinted load */ - /* - neither a MM nor a GX font */ + /* - if a variations font, it must have an `HVAR' or `VVAR' */ + /* table (thus the old MM or GX fonts don't qualify; this */ + /* gets checked by the driver-specific functions) */ -#define LOAD_ADVANCE_FAST_CHECK( face, flags ) \ - ( ( flags & ( FT_LOAD_NO_SCALE | FT_LOAD_NO_HINTING ) || \ - FT_LOAD_TARGET_MODE( flags ) == FT_RENDER_MODE_LIGHT ) && \ - !FT_HAS_MULTIPLE_MASTERS( face ) ) +#define LOAD_ADVANCE_FAST_CHECK( face, flags ) \ + ( flags & ( FT_LOAD_NO_SCALE | FT_LOAD_NO_HINTING ) || \ + FT_LOAD_TARGET_MODE( flags ) == FT_RENDER_MODE_LIGHT ) /* documentation is in ftadvanc.h */ Index: reactos/sdk/lib/3rdparty/freetype/src/base/ftbbox.c =================================================================== --- reactos/sdk/lib/3rdparty/freetype/src/base/ftbbox.c (revision 74184) +++ reactos/sdk/lib/3rdparty/freetype/src/base/ftbbox.c (working copy) @@ -423,12 +423,15 @@ } - FT_DEFINE_OUTLINE_FUNCS(bbox_interface, - (FT_Outline_MoveTo_Func) BBox_Move_To, - (FT_Outline_LineTo_Func) BBox_Line_To, - (FT_Outline_ConicTo_Func)BBox_Conic_To, - (FT_Outline_CubicTo_Func)BBox_Cubic_To, - 0, 0 + FT_DEFINE_OUTLINE_FUNCS( + bbox_interface, + + (FT_Outline_MoveTo_Func) BBox_Move_To, /* move_to */ + (FT_Outline_LineTo_Func) BBox_Line_To, /* line_to */ + (FT_Outline_ConicTo_Func)BBox_Conic_To, /* conic_to */ + (FT_Outline_CubicTo_Func)BBox_Cubic_To, /* cubic_to */ + 0, /* shift */ + 0 /* delta */ ) @@ -457,6 +460,7 @@ { abbox->xMin = abbox->xMax = 0; abbox->yMin = abbox->yMax = 0; + return 0; } @@ -468,10 +472,10 @@ for ( n = 0; n < outline->n_points; n++ ) { - FT_UPDATE_BBOX( vec, cbox); + FT_UPDATE_BBOX( vec, cbox ); if ( FT_CURVE_TAG( outline->tags[n] ) == FT_CURVE_TAG_ON ) - FT_UPDATE_BBOX( vec, bbox); + FT_UPDATE_BBOX( vec, bbox ); vec++; } @@ -487,8 +491,10 @@ TBBox_Rec user; #ifdef FT_CONFIG_OPTION_PIC - FT_Outline_Funcs bbox_interface; - Init_Class_bbox_interface(&bbox_interface); + FT_Outline_Funcs bbox_interface; + + + Init_Class_bbox_interface( &bbox_interface ); #endif user.bbox = bbox; Index: reactos/sdk/lib/3rdparty/freetype/src/base/ftbitmap.c =================================================================== --- reactos/sdk/lib/3rdparty/freetype/src/base/ftbitmap.c (revision 74184) +++ reactos/sdk/lib/3rdparty/freetype/src/base/ftbitmap.c (working copy) @@ -76,7 +76,7 @@ source_pitch_sign = source->pitch < 0 ? -1 : 1; target_pitch_sign = target->pitch < 0 ? -1 : 1; - if ( source->buffer == NULL ) + if ( !source->buffer ) { *target = *source; if ( source_pitch_sign != target_pitch_sign ) Index: reactos/sdk/lib/3rdparty/freetype/src/base/ftcalc.c =================================================================== --- reactos/sdk/lib/3rdparty/freetype/src/base/ftcalc.c (revision 74184) +++ reactos/sdk/lib/3rdparty/freetype/src/base/ftcalc.c (working copy) @@ -449,8 +449,8 @@ FT_Add64( &temp, &temp2, &temp ); /* last attempt to ditch long division */ - a = temp.hi == 0 ? temp.lo / c - : ft_div64by32( temp.hi, temp.lo, c ); + a = ( temp.hi == 0 ) ? temp.lo / c + : ft_div64by32( temp.hi, temp.lo, c ); } a_ = (FT_Long)a; @@ -492,8 +492,8 @@ ft_multo64( a, b, &temp ); /* last attempt to ditch long division */ - a = temp.hi == 0 ? temp.lo / c - : ft_div64by32( temp.hi, temp.lo, c ); + a = ( temp.hi == 0 ) ? temp.lo / c + : ft_div64by32( temp.hi, temp.lo, c ); } a_ = (FT_Long)a; Index: reactos/sdk/lib/3rdparty/freetype/src/base/ftdbgmem.c =================================================================== --- reactos/sdk/lib/3rdparty/freetype/src/base/ftdbgmem.c (revision 74184) +++ reactos/sdk/lib/3rdparty/freetype/src/base/ftdbgmem.c (working copy) @@ -268,7 +268,7 @@ ft_mem_table_alloc( table, new_size * (FT_Long)sizeof ( FT_MemNode ) ); - if ( new_buckets == NULL ) + if ( !new_buckets ) return; FT_ARRAY_ZERO( new_buckets, new_size ); @@ -309,7 +309,7 @@ table = (FT_MemTable)memory->alloc( memory, sizeof ( *table ) ); - if ( table == NULL ) + if ( !table ) goto Exit; FT_ZERO( table ); @@ -466,7 +466,7 @@ for (;;) { node = *pnode; - if ( node == NULL ) + if ( !node ) break; if ( node->file_name == _ft_debug_file && @@ -477,7 +477,7 @@ } node = (FT_MemSource)ft_mem_table_alloc( table, sizeof ( *node ) ); - if ( node == NULL ) + if ( !node ) ft_mem_debug_panic( "not enough memory to perform memory debugging\n" ); @@ -545,7 +545,7 @@ /* we need to create a new node in this table */ node = (FT_MemNode)ft_mem_table_alloc( table, sizeof ( *node ) ); - if ( node == NULL ) + if ( !node ) ft_mem_debug_panic( "not enough memory to run memory tests" ); node->address = address; @@ -717,7 +717,7 @@ FT_MemTable table = (FT_MemTable)memory->user; - if ( block == NULL ) + if ( !block ) ft_mem_debug_panic( "trying to free NULL in (%s:%ld)", FT_FILENAME( _ft_debug_file ), _ft_debug_lineno ); @@ -755,7 +755,7 @@ /* the following is valid according to ANSI C */ #if 0 - if ( block == NULL || cur_size == 0 ) + if ( !block || !cur_size ) ft_mem_debug_panic( "trying to reallocate NULL in (%s:%ld)", file_name, line_no ); #endif @@ -799,7 +799,7 @@ return NULL; new_block = (FT_Pointer)ft_mem_table_alloc( table, new_size ); - if ( new_block == NULL ) + if ( !new_block ) return NULL; ft_mem_table_set( table, (FT_Byte*)new_block, new_size, delta ); @@ -840,7 +840,7 @@ memory->free = ft_mem_debug_free; p = getenv( "FT2_ALLOC_TOTAL_MAX" ); - if ( p != NULL ) + if ( p ) { FT_Long total_max = ft_strtol( p, NULL, 10 ); @@ -853,7 +853,7 @@ } p = getenv( "FT2_ALLOC_COUNT_MAX" ); - if ( p != NULL ) + if ( p ) { FT_Long total_count = ft_strtol( p, NULL, 10 ); @@ -866,7 +866,7 @@ } p = getenv( "FT2_KEEP_ALIVE" ); - if ( p != NULL ) + if ( p ) { FT_Long keep_alive = ft_strtol( p, NULL, 10 ); Index: reactos/sdk/lib/3rdparty/freetype/src/base/ftglyph.c =================================================================== --- reactos/sdk/lib/3rdparty/freetype/src/base/ftglyph.c (revision 74184) +++ reactos/sdk/lib/3rdparty/freetype/src/base/ftglyph.c (working copy) @@ -132,16 +132,18 @@ } - FT_DEFINE_GLYPH(ft_bitmap_glyph_class, + FT_DEFINE_GLYPH( + ft_bitmap_glyph_class, + sizeof ( FT_BitmapGlyphRec ), FT_GLYPH_FORMAT_BITMAP, - ft_bitmap_glyph_init, - ft_bitmap_glyph_done, - ft_bitmap_glyph_copy, - 0, /* FT_Glyph_TransformFunc */ - ft_bitmap_glyph_bbox, - 0 /* FT_Glyph_PrepareFunc */ + ft_bitmap_glyph_init, /* FT_Glyph_InitFunc glyph_init */ + ft_bitmap_glyph_done, /* FT_Glyph_DoneFunc glyph_done */ + ft_bitmap_glyph_copy, /* FT_Glyph_CopyFunc glyph_copy */ + NULL, /* FT_Glyph_TransformFunc glyph_transform */ + ft_bitmap_glyph_bbox, /* FT_Glyph_GetBBoxFunc glyph_bbox */ + NULL /* FT_Glyph_PrepareFunc glyph_prepare */ ) @@ -260,16 +262,18 @@ } - FT_DEFINE_GLYPH( ft_outline_glyph_class, + FT_DEFINE_GLYPH( + ft_outline_glyph_class, + sizeof ( FT_OutlineGlyphRec ), FT_GLYPH_FORMAT_OUTLINE, - ft_outline_glyph_init, - ft_outline_glyph_done, - ft_outline_glyph_copy, - ft_outline_glyph_transform, - ft_outline_glyph_bbox, - ft_outline_glyph_prepare + ft_outline_glyph_init, /* FT_Glyph_InitFunc glyph_init */ + ft_outline_glyph_done, /* FT_Glyph_DoneFunc glyph_done */ + ft_outline_glyph_copy, /* FT_Glyph_CopyFunc glyph_copy */ + ft_outline_glyph_transform, /* FT_Glyph_TransformFunc glyph_transform */ + ft_outline_glyph_bbox, /* FT_Glyph_GetBBoxFunc glyph_bbox */ + ft_outline_glyph_prepare /* FT_Glyph_PrepareFunc glyph_prepare */ ) @@ -542,8 +546,8 @@ /* we render the glyph into a glyph bitmap using a `dummy' glyph slot */ /* then calling FT_Render_Glyph_Internal() */ - FT_MEM_ZERO( &dummy, sizeof ( dummy ) ); - FT_MEM_ZERO( &dummy_internal, sizeof ( dummy_internal ) ); + FT_ZERO( &dummy ); + FT_ZERO( &dummy_internal ); dummy.internal = &dummy_internal; dummy.library = library; dummy.format = clazz->glyph_format; Index: reactos/sdk/lib/3rdparty/freetype/src/base/ftmac.c =================================================================== --- reactos/sdk/lib/3rdparty/freetype/src/base/ftmac.c (revision 74184) +++ reactos/sdk/lib/3rdparty/freetype/src/base/ftmac.c (working copy) @@ -605,7 +605,7 @@ for (;;) { post_data = Get1Resource( TTAG_POST, res_id++ ); - if ( post_data == NULL ) + if ( !post_data ) break; /* we are done */ code = (*post_data)[0]; @@ -644,7 +644,7 @@ for (;;) { post_data = Get1Resource( TTAG_POST, res_id++ ); - if ( post_data == NULL ) + if ( !post_data ) break; /* we are done */ post_size = (FT_ULong)GetHandleSize( post_data ) - 2; @@ -655,7 +655,7 @@ if ( last_code != -1 ) { /* we are done adding a chunk, fill in the size field */ - if ( size_p != NULL ) + if ( size_p ) { *size_p++ = (FT_Byte)( pfb_chunk_size & 0xFF ); *size_p++ = (FT_Byte)( ( pfb_chunk_size >> 8 ) & 0xFF ); @@ -743,7 +743,7 @@ sfnt = GetResource( TTAG_sfnt, sfnt_id ); - if ( sfnt == NULL ) + if ( !sfnt ) return FT_THROW( Invalid_Handle ); sfnt_size = (FT_ULong)GetHandleSize( sfnt ); @@ -821,7 +821,7 @@ return FT_THROW( Cannot_Open_Resource ); num_faces_in_res = 0; - for ( res_index = 1; ; ++res_index ) + for ( res_index = 1; ; res_index++ ) { short num_faces_in_fond; @@ -942,13 +942,14 @@ /* if it works, fine. */ error = FT_New_Face_From_Suitcase( library, pathname, face_index, aface ); - if ( error == 0 ) - return error; + if ( error ) + { + /* let it fall through to normal loader (.ttf, .otf, etc.); */ + /* we signal this by returning no error and no FT_Face */ + *aface = NULL; + } - /* let it fall through to normal loader (.ttf, .otf, etc.); */ - /* we signal this by returning no error and no FT_Face */ - *aface = NULL; - return 0; + return FT_Err_Ok; } @@ -982,12 +983,13 @@ /* try resourcefork based font: LWFN, FFIL */ error = FT_New_Face_From_Resource( library, (UInt8 *)pathname, face_index, aface ); - if ( error != 0 || *aface != NULL ) + if ( error || *aface ) return error; /* let it fall through to normal loader (.ttf, .otf, etc.) */ args.flags = FT_OPEN_PATHNAME; args.pathname = (char*)pathname; + return FT_Open_Face( library, &args, face_index, aface ); } @@ -1027,7 +1029,7 @@ error = FT_THROW( Cannot_Open_Resource ); error = FT_New_Face_From_Resource( library, pathname, face_index, aface ); - if ( error != 0 || *aface != NULL ) + if ( error || *aface ) return error; /* fallback to datafork font */ Index: reactos/sdk/lib/3rdparty/freetype/src/base/ftmm.c =================================================================== --- reactos/sdk/lib/3rdparty/freetype/src/base/ftmm.c (revision 74184) +++ reactos/sdk/lib/3rdparty/freetype/src/base/ftmm.c (working copy) @@ -140,6 +140,13 @@ error = service->set_mm_design( face, num_coords, coords ); } + /* enforce recomputation of auto-hinting data */ + if ( !error && face->autohint.finalizer ) + { + face->autohint.finalizer( face->autohint.data ); + face->autohint.data = NULL; + } + return error; } @@ -168,6 +175,13 @@ error = service->set_var_design( face, num_coords, coords ); } + /* enforce recomputation of auto-hinting data */ + if ( !error && face->autohint.finalizer ) + { + face->autohint.finalizer( face->autohint.data ); + face->autohint.data = NULL; + } + return error; } @@ -175,6 +189,34 @@ /* documentation is in ftmm.h */ FT_EXPORT_DEF( FT_Error ) + FT_Get_Var_Design_Coordinates( FT_Face face, + FT_UInt num_coords, + FT_Fixed* coords ) + { + FT_Error error; + FT_Service_MultiMasters service; + + + /* check of `face' delayed to `ft_face_get_mm_service' */ + + if ( !coords ) + return FT_THROW( Invalid_Argument ); + + error = ft_face_get_mm_service( face, &service ); + if ( !error ) + { + error = FT_ERR( Invalid_Argument ); + if ( service->get_var_design ) + error = service->get_var_design( face, num_coords, coords ); + } + + return error; + } + + + /* documentation is in ftmm.h */ + + FT_EXPORT_DEF( FT_Error ) FT_Set_MM_Blend_Coordinates( FT_Face face, FT_UInt num_coords, FT_Fixed* coords ) @@ -193,9 +235,16 @@ { error = FT_ERR( Invalid_Argument ); if ( service->set_mm_blend ) - error = service->set_mm_blend( face, num_coords, coords ); + error = service->set_mm_blend( face, num_coords, coords ); } + /* enforce recomputation of auto-hinting data */ + if ( !error && face->autohint.finalizer ) + { + face->autohint.finalizer( face->autohint.data ); + face->autohint.data = NULL; + } + return error; } @@ -224,11 +273,77 @@ { error = FT_ERR( Invalid_Argument ); if ( service->set_mm_blend ) - error = service->set_mm_blend( face, num_coords, coords ); + error = service->set_mm_blend( face, num_coords, coords ); } + /* enforce recomputation of auto-hinting data */ + if ( !error && face->autohint.finalizer ) + { + face->autohint.finalizer( face->autohint.data ); + face->autohint.data = NULL; + } + return error; } + /* documentation is in ftmm.h */ + + FT_EXPORT_DEF( FT_Error ) + FT_Get_MM_Blend_Coordinates( FT_Face face, + FT_UInt num_coords, + FT_Fixed* coords ) + { + FT_Error error; + FT_Service_MultiMasters service; + + + /* check of `face' delayed to `ft_face_get_mm_service' */ + + if ( !coords ) + return FT_THROW( Invalid_Argument ); + + error = ft_face_get_mm_service( face, &service ); + if ( !error ) + { + error = FT_ERR( Invalid_Argument ); + if ( service->get_mm_blend ) + error = service->get_mm_blend( face, num_coords, coords ); + } + + return error; + } + + + /* documentation is in ftmm.h */ + + /* This is exactly the same as the previous function. It exists for */ + /* orthogonality. */ + + FT_EXPORT_DEF( FT_Error ) + FT_Get_Var_Blend_Coordinates( FT_Face face, + FT_UInt num_coords, + FT_Fixed* coords ) + { + FT_Error error; + FT_Service_MultiMasters service; + + + /* check of `face' delayed to `ft_face_get_mm_service' */ + + if ( !coords ) + return FT_THROW( Invalid_Argument ); + + error = ft_face_get_mm_service( face, &service ); + if ( !error ) + { + error = FT_ERR( Invalid_Argument ); + if ( service->get_mm_blend ) + error = service->get_mm_blend( face, num_coords, coords ); + } + + return error; + } + + /* END */ Index: reactos/sdk/lib/3rdparty/freetype/src/base/ftobjs.c =================================================================== --- reactos/sdk/lib/3rdparty/freetype/src/base/ftobjs.c (revision 74184) +++ reactos/sdk/lib/3rdparty/freetype/src/base/ftobjs.c (working copy) @@ -79,6 +79,15 @@ #define GRID_FIT_METRICS + /* forward declaration */ + 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 ); + + FT_BASE_DEF( FT_Pointer ) ft_service_list_lookup( FT_ServiceDesc service_descriptors, const char* service_id ) @@ -641,6 +650,9 @@ load_flags &= ~FT_LOAD_RENDER; } + if ( load_flags & FT_LOAD_BITMAP_METRICS_ONLY ) + load_flags &= ~FT_LOAD_RENDER; + /* * Determine whether we need to auto-hint or not. * The general rules are: @@ -1102,7 +1114,7 @@ end = first + face->num_charmaps; /* points after the last one */ - for ( cur = first; cur < end; ++cur ) + for ( cur = first; cur < end; cur++ ) { if ( cur[0]->platform_id == TT_PLATFORM_APPLE_UNICODE && cur[0]->encoding_id == TT_APPLE_ID_VARIANT_SELECTOR && @@ -1237,7 +1249,7 @@ args.pathname = (char*)pathname; args.stream = NULL; - return FT_Open_Face( library, &args, face_index, aface ); + return ft_open_face_internal( library, &args, face_index, aface, 1 ); } #endif @@ -1264,7 +1276,7 @@ args.memory_size = file_size; args.stream = NULL; - return FT_Open_Face( library, &args, face_index, aface ); + return ft_open_face_internal( library, &args, face_index, aface, 1 ); } @@ -1299,7 +1311,7 @@ /* Finalizer for a memory stream; gets called by FT_Done_Face(). */ /* It frees the memory it uses. */ - /* From ftmac.c. */ + /* From `ftmac.c'. */ static void memory_stream_close( FT_Stream stream ) { @@ -1315,7 +1327,7 @@ /* Create a new memory stream from a buffer and a size. */ - /* From ftmac.c. */ + /* From `ftmac.c'. */ static FT_Error new_memory_stream( FT_Library library, FT_Byte* base, @@ -1335,7 +1347,7 @@ return FT_THROW( Invalid_Argument ); *astream = NULL; - memory = library->memory; + memory = library->memory; if ( FT_NEW( stream ) ) goto Exit; @@ -1351,7 +1363,7 @@ /* Create a new FT_Face given a buffer and a driver name. */ - /* from ftmac.c */ + /* From `ftmac.c'. */ FT_LOCAL_DEF( FT_Error ) open_face_from_buffer( FT_Library library, FT_Byte* base, @@ -1377,11 +1389,11 @@ return error; } - args.flags = FT_OPEN_STREAM; + args.flags = FT_OPEN_STREAM; args.stream = stream; if ( driver_name ) { - args.flags = args.flags | FT_OPEN_DRIVER; + args.flags = args.flags | FT_OPEN_DRIVER; args.driver = FT_Get_Module( library, driver_name ); } @@ -1395,9 +1407,9 @@ face_index &= 0x7FFF0000L; /* retain GX data */ #endif - error = FT_Open_Face( library, &args, face_index, aface ); + error = ft_open_face_internal( library, &args, face_index, aface, 0 ); - if ( error == FT_Err_Ok ) + if ( !error ) (*aface)->face_flags &= ~FT_FACE_FLAG_EXTERNAL_STREAM; else #ifdef FT_MACINTOSH @@ -1589,6 +1601,7 @@ { FT_Error error = FT_ERR( Cannot_Open_Resource ); FT_Memory memory = library->memory; + FT_Byte* pfb_data = NULL; int i, type, flags; FT_ULong len; @@ -1604,12 +1617,12 @@ /* Find the length of all the POST resources, concatenated. Assume */ /* worst case (each resource in its own section). */ pfb_len = 0; - for ( i = 0; i < resource_cnt; ++i ) + for ( i = 0; i < resource_cnt; i++ ) { error = FT_Stream_Seek( stream, (FT_ULong)offsets[i] ); if ( error ) goto Exit; - if ( FT_READ_ULONG( temp ) ) + if ( FT_READ_ULONG( temp ) ) /* actually LONG */ goto Exit; /* FT2 allocator takes signed long buffer length, @@ -1617,12 +1630,15 @@ */ FT_TRACE4(( " POST fragment #%d: length=0x%08x" " total pfb_len=0x%08x\n", - i, temp, pfb_len + temp + 6)); + i, temp, pfb_len + temp + 6 )); + if ( FT_MAC_RFORK_MAX_LEN < temp || FT_MAC_RFORK_MAX_LEN - temp < pfb_len + 6 ) { FT_TRACE2(( " MacOS resource length cannot exceed" - " 0x%08x\n", FT_MAC_RFORK_MAX_LEN )); + " 0x%08x\n", + FT_MAC_RFORK_MAX_LEN )); + error = FT_THROW( Invalid_Offset ); goto Exit; } @@ -1630,15 +1646,20 @@ pfb_len += temp + 6; } - FT_TRACE2(( " total buffer size to concatenate %d" - " POST fragments: 0x%08x\n", - resource_cnt, pfb_len + 2)); - if ( pfb_len + 2 < 6 ) { + FT_TRACE2(( " total buffer size to concatenate" + " %d POST fragments: 0x%08x\n", + resource_cnt, pfb_len + 2 )); + + if ( pfb_len + 2 < 6 ) + { FT_TRACE2(( " too long fragment length makes" - " pfb_len confused: pfb_len=0x%08x\n", pfb_len )); + " pfb_len confused: pfb_len=0x%08x\n", + pfb_len )); + error = FT_THROW( Array_Too_Large ); goto Exit; } + if ( FT_ALLOC( pfb_data, (FT_Long)pfb_len + 2 ) ) goto Exit; @@ -1651,9 +1672,10 @@ pfb_pos = 6; pfb_lenpos = 2; - len = 0; + len = 0; type = 1; - for ( i = 0; i < resource_cnt; ++i ) + + for ( i = 0; i < resource_cnt; i++ ) { error = FT_Stream_Seek( stream, (FT_ULong)offsets[i] ); if ( error ) @@ -1672,18 +1694,24 @@ if ( FT_READ_USHORT( flags ) ) goto Exit2; - FT_TRACE3(( "POST fragment[%d]: offsets=0x%08x, rlen=0x%08x, flags=0x%04x\n", - i, offsets[i], rlen, flags )); + FT_TRACE3(( "POST fragment[%d]:" + " offsets=0x%08x, rlen=0x%08x, flags=0x%04x\n", + i, offsets[i], rlen, flags )); + error = FT_ERR( Array_Too_Large ); - /* postpone the check of rlen longer than buffer until FT_Stream_Read() */ + + /* postpone the check of `rlen longer than buffer' */ + /* until `FT_Stream_Read' */ + if ( ( flags >> 8 ) == 0 ) /* Comment, should not be loaded */ { - FT_TRACE3(( " Skip POST fragment #%d because it is a comment\n", i )); + FT_TRACE3(( " Skip POST fragment #%d because it is a comment\n", + i )); continue; } - /* the flags are part of the resource, so rlen >= 2. */ + /* the flags are part of the resource, so rlen >= 2, */ /* but some fonts declare rlen = 0 for empty fragment */ if ( rlen > 2 ) rlen -= 2; @@ -1695,9 +1723,12 @@ else { FT_TRACE3(( " Write POST fragment #%d header (4-byte) to buffer" - " %p + 0x%08x\n", i, pfb_data, pfb_lenpos )); + " %p + 0x%08x\n", + i, pfb_data, pfb_lenpos )); + if ( pfb_lenpos + 3 > pfb_len + 2 ) goto Exit2; + pfb_data[pfb_lenpos ] = (FT_Byte)( len ); pfb_data[pfb_lenpos + 1] = (FT_Byte)( len >> 8 ); pfb_data[pfb_lenpos + 2] = (FT_Byte)( len >> 16 ); @@ -1707,13 +1738,16 @@ break; FT_TRACE3(( " Write POST fragment #%d header (6-byte) to buffer" - " %p + 0x%08x\n", i, pfb_data, pfb_pos )); + " %p + 0x%08x\n", + i, pfb_data, pfb_pos )); + if ( pfb_pos + 6 > pfb_len + 2 ) goto Exit2; + pfb_data[pfb_pos++] = 0x80; type = flags >> 8; - len = rlen; + len = rlen; pfb_data[pfb_pos++] = (FT_Byte)type; pfb_lenpos = pfb_pos; @@ -1727,14 +1761,18 @@ goto Exit2; FT_TRACE3(( " Load POST fragment #%d (%d byte) to buffer" - " %p + 0x%08x\n", i, rlen, pfb_data, pfb_pos )); + " %p + 0x%08x\n", + i, rlen, pfb_data, pfb_pos )); + error = FT_Stream_Read( stream, (FT_Byte *)pfb_data + pfb_pos, rlen ); if ( error ) goto Exit2; + pfb_pos += rlen; } error = FT_ERR( Array_Too_Large ); + if ( pfb_pos + 2 > pfb_len + 2 ) goto Exit2; pfb_data[pfb_pos++] = 0x80; @@ -1755,11 +1793,12 @@ aface ); Exit2: - if ( error == FT_ERR( Array_Too_Large ) ) + if ( FT_ERR_EQ( error, Array_Too_Large ) ) FT_TRACE2(( " Abort due to too-short buffer to store" " all POST fragments\n" )); - else if ( error == FT_ERR( Invalid_Offset ) ) + else if ( FT_ERR_EQ( error, Invalid_Offset ) ) FT_TRACE2(( " Abort due to invalid offset in a POST fragment\n" )); + if ( error ) error = FT_ERR( Cannot_Open_Resource ); FT_FREE( pfb_data ); @@ -1803,7 +1842,7 @@ if ( FT_READ_LONG( rlen ) ) goto Exit; - if ( rlen == -1 ) + if ( rlen < 1 ) return FT_THROW( Cannot_Open_Resource ); if ( (FT_ULong)rlen > FT_MAC_RFORK_MAX_LEN ) return FT_THROW( Invalid_Offset ); @@ -1856,19 +1895,19 @@ { FT_Memory memory = library->memory; FT_Error error; - FT_Long map_offset, rdara_pos; + FT_Long map_offset, rdata_pos; FT_Long *data_offsets; FT_Long count; error = FT_Raccess_Get_HeaderInfo( library, stream, resource_offset, - &map_offset, &rdara_pos ); + &map_offset, &rdata_pos ); if ( error ) return error; /* POST resources must be sorted to concatenate properly */ error = FT_Raccess_Get_DataOffsets( library, stream, - map_offset, rdara_pos, + map_offset, rdata_pos, TTAG_POST, TRUE, &data_offsets, &count ); if ( !error ) @@ -1885,7 +1924,7 @@ /* sfnt resources should not be sorted to preserve the face order by QuickDraw API */ error = FT_Raccess_Get_DataOffsets( library, stream, - map_offset, rdara_pos, + map_offset, rdata_pos, TTAG_sfnt, FALSE, &data_offsets, &count ); if ( !error ) @@ -1918,7 +1957,7 @@ FT_Long dlen, offset; - if ( NULL == stream ) + if ( !stream ) return FT_THROW( Invalid_Stream_Operation ); error = FT_Stream_Seek( stream, 0 ); @@ -2108,6 +2147,17 @@ FT_Long face_index, FT_Face *aface ) { + return ft_open_face_internal( library, args, face_index, aface, 1 ); + } + + + 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 ) + { FT_Error error; FT_Driver driver = NULL; FT_Memory memory = NULL; @@ -2118,7 +2168,24 @@ FT_Module* cur; FT_Module* limit; +#ifndef FT_CONFIG_OPTION_MAC_FONTS + FT_UNUSED( test_mac_fonts ); +#endif + +#ifdef FT_DEBUG_LEVEL_TRACE + FT_TRACE3(( "FT_Open_Face: " )); + if ( face_index < 0 ) + FT_TRACE3(( "Requesting number of faces and named instances\n")); + else + { + FT_TRACE3(( "Requesting face %ld", face_index & 0xFFFFL )); + if ( face_index & 0x7FFF0000L ) + FT_TRACE3(( ", named instance %ld", face_index >> 16 )); + FT_TRACE3(( "\n" )); + } +#endif + /* test for valid `library' delayed to `FT_Stream_New' */ if ( ( !aface && face_index >= 0 ) || !args ) @@ -2195,7 +2262,8 @@ goto Success; #ifdef FT_CONFIG_OPTION_MAC_FONTS - if ( ft_strcmp( cur[0]->clazz->module_name, "truetype" ) == 0 && + if ( test_mac_fonts && + ft_strcmp( cur[0]->clazz->module_name, "truetype" ) == 0 && FT_ERR_EQ( error, Table_Missing ) ) { /* TrueType but essential tables are missing */ @@ -2232,16 +2300,20 @@ goto Fail2; #if !defined( FT_MACINTOSH ) && defined( FT_CONFIG_OPTION_MAC_FONTS ) - error = load_mac_face( library, stream, face_index, aface, args ); - if ( !error ) + if ( test_mac_fonts ) { - /* We don't want to go to Success here. We've already done that. */ - /* On the other hand, if we succeeded we still need to close this */ - /* stream (we opened a different stream which extracted the */ - /* interesting information out of this stream here. That stream */ - /* will still be open and the face will point to it). */ - FT_Stream_Free( stream, external_stream ); - return error; + error = load_mac_face( library, stream, face_index, aface, args ); + if ( !error ) + { + /* We don't want to go to Success here. We've already done */ + /* that. On the other hand, if we succeeded we still need to */ + /* close this stream (we opened a different stream which */ + /* extracted the interesting information out of this stream */ + /* here. That stream will still be open and the face will */ + /* point to it). */ + FT_Stream_Free( stream, external_stream ); + return error; + } } if ( FT_ERR_NEQ( error, Unknown_File_Format ) ) @@ -2365,6 +2437,17 @@ destroy_face( memory, face, driver ); Exit: +#ifdef FT_DEBUG_LEVEL_TRACE + if ( !error && face_index < 0 ) + { + FT_TRACE3(( "FT_Open_Face: The font has %ld faces\n" + " and %ld named instances for face %ld\n", + face->num_faces, + face->style_flags >> 16, + -face_index - 1 )); + } +#endif + FT_TRACE4(( "FT_Open_Face: Return %d\n", error )); return error; @@ -2631,6 +2714,9 @@ w = FT_PIX_ROUND( w ); h = FT_PIX_ROUND( h ); + if ( !w || !h ) + return FT_THROW( Invalid_Pixel_Size ); + for ( i = 0; i < face->num_fixed_sizes; i++ ) { FT_Bitmap_Size* bsize = face->available_sizes + i; @@ -2650,6 +2736,8 @@ } } + FT_TRACE3(( "FT_Match_Size: no matching bitmap strike\n" )); + return FT_THROW( Invalid_Pixel_Size ); } @@ -3369,7 +3457,7 @@ FT_CMap cmap = NULL; - if ( clazz == NULL || charmap == NULL || charmap->face == NULL ) + if ( !clazz || !charmap || !charmap->face ) return FT_THROW( Invalid_Argument ); face = charmap->face; @@ -3514,7 +3602,7 @@ FT_CMap ucmap = FT_CMAP( face->charmap ); - if ( charmap != NULL ) + if ( charmap ) { FT_CMap vcmap = FT_CMAP( charmap ); @@ -3555,7 +3643,7 @@ FT_CharMap charmap = find_variant_selector_charmap( face ); - if ( charmap != NULL ) + if ( charmap ) { FT_CMap vcmap = FT_CMAP( charmap ); @@ -3594,7 +3682,7 @@ FT_CharMap charmap = find_variant_selector_charmap( face ); - if ( charmap != NULL ) + if ( charmap ) { FT_CMap vcmap = FT_CMAP( charmap ); FT_Memory memory = FT_FACE_MEMORY( face ); @@ -3622,7 +3710,7 @@ FT_CharMap charmap = find_variant_selector_charmap( face ); - if ( charmap != NULL ) + if ( charmap ) { FT_CMap vcmap = FT_CMAP( charmap ); FT_Memory memory = FT_FACE_MEMORY( face ); @@ -3656,7 +3744,7 @@ FT_CharMap charmap = find_variant_selector_charmap( face ); - if ( charmap != NULL ) + if ( charmap ) { FT_CMap vcmap = FT_CMAP( charmap ); FT_Memory memory = FT_FACE_MEMORY( face ); @@ -3784,7 +3872,7 @@ if ( face && FT_IS_SFNT( face ) ) { FT_FACE_FIND_SERVICE( face, service, SFNT_TABLE ); - if ( service != NULL ) + if ( service ) table = service->get_table( face, tag ); } @@ -3808,7 +3896,7 @@ return FT_THROW( Invalid_Face_Handle ); FT_FACE_FIND_SERVICE( face, service, SFNT_TABLE ); - if ( service == NULL ) + if ( !service ) return FT_THROW( Unimplemented_Feature ); return service->load_table( face, tag, offset, buffer, length ); @@ -3833,7 +3921,7 @@ return FT_THROW( Invalid_Face_Handle ); FT_FACE_FIND_SERVICE( face, service, SFNT_TABLE ); - if ( service == NULL ) + if ( !service ) return FT_THROW( Unimplemented_Feature ); return service->table_info( face, table_index, tag, &offset, length ); @@ -3855,7 +3943,7 @@ face = charmap->face; FT_FACE_FIND_SERVICE( face, service, TT_CMAP ); - if ( service == NULL ) + if ( !service ) return 0; if ( service->get_cmap_info( charmap, &cmap_info )) return 0; @@ -3879,7 +3967,7 @@ face = charmap->face; FT_FACE_FIND_SERVICE( face, service, TT_CMAP ); - if ( service == NULL ) + if ( !service ) return -1; if ( service->get_cmap_info( charmap, &cmap_info )) return -1; @@ -4209,7 +4297,7 @@ if ( ft_trace_levels[trace_bitmap] >= 3 ) { /* we convert to a single bitmap format for computing the checksum */ - if ( !error ) + if ( !error && slot->bitmap.buffer ) { FT_Bitmap bitmap; FT_Error err; @@ -4488,7 +4576,8 @@ FT_BASE_DEF( FT_Pointer ) ft_module_get_service( FT_Module module, - const char* service_id ) + const char* service_id, + FT_Bool global ) { FT_Pointer result = NULL; @@ -4501,7 +4590,7 @@ if ( module->clazz->get_interface ) result = module->clazz->get_interface( module, service_id ); - if ( result == NULL ) + if ( global && !result ) { /* we didn't find it, look in all other modules then */ FT_Library library = module->library; @@ -4518,7 +4607,7 @@ if ( cur[0]->clazz->get_interface ) { result = cur[0]->clazz->get_interface( cur[0], service_id ); - if ( result != NULL ) + if ( result ) break; } } @@ -4969,7 +5058,8 @@ service = (FT_Service_TrueTypeEngine) ft_module_get_service( module, - FT_SERVICE_ID_TRUETYPE_ENGINE ); + FT_SERVICE_ID_TRUETYPE_ENGINE, + 0 ); if ( service ) result = service->engine_type; } Index: reactos/sdk/lib/3rdparty/freetype/src/base/ftrfork.c =================================================================== --- reactos/sdk/lib/3rdparty/freetype/src/base/ftrfork.c (revision 74184) +++ reactos/sdk/lib/3rdparty/freetype/src/base/ftrfork.c (working copy) @@ -56,7 +56,7 @@ { FT_Error error; unsigned char head[16], head2[16]; - FT_Long map_pos, rdata_len; + FT_Long map_pos, map_len, rdata_len; int allzeros, allmatch, i; FT_Long type_list; @@ -67,12 +67,15 @@ if ( error ) return error; - error = FT_Stream_Read( stream, (FT_Byte *)head, 16 ); + error = FT_Stream_Read( stream, (FT_Byte*)head, 16 ); if ( error ) return error; /* ensure positive values */ - if ( head[0] >= 0x80 || head[4] >= 0x80 || head[8] >= 0x80 ) + if ( head[0] >= 0x80 || + head[4] >= 0x80 || + head[8] >= 0x80 || + head[12] >= 0x80 ) return FT_THROW( Unknown_File_Format ); *rdata_pos = ( head[ 0] << 24 ) | @@ -87,14 +90,36 @@ ( head[ 9] << 16 ) | ( head[10] << 8 ) | head[11]; + map_len = ( head[12] << 24 ) | + ( head[13] << 16 ) | + ( head[14] << 8 ) | + head[15]; - /* map_len = head[12] .. head[15] */ - - if ( *rdata_pos != map_pos - rdata_len || map_pos == 0 ) + /* the map must not be empty */ + if ( !map_pos ) return FT_THROW( Unknown_File_Format ); - if ( FT_LONG_MAX - rfork_offset < *rdata_pos || - FT_LONG_MAX - rfork_offset < map_pos ) + /* check whether rdata and map overlap */ + if ( *rdata_pos < map_pos ) + { + if ( *rdata_pos > map_pos - rdata_len ) + return FT_THROW( Unknown_File_Format ); + } + else + { + if ( map_pos > *rdata_pos - map_len ) + return FT_THROW( Unknown_File_Format ); + } + + /* check whether end of rdata or map exceeds stream size */ + if ( FT_LONG_MAX - rdata_len < *rdata_pos || + FT_LONG_MAX - map_len < map_pos || + + FT_LONG_MAX - ( *rdata_pos + rdata_len ) < rfork_offset || + FT_LONG_MAX - ( map_pos + map_len ) < rfork_offset || + + (FT_ULong)( rfork_offset + *rdata_pos + rdata_len ) > stream->size || + (FT_ULong)( rfork_offset + map_pos + map_len ) > stream->size ) return FT_THROW( Unknown_File_Format ); *rdata_pos += rfork_offset; @@ -112,7 +137,7 @@ allzeros = 1; allmatch = 1; - for ( i = 0; i < 16; ++i ) + for ( i = 0; i < 16; i++ ) { if ( head2[i] != 0 ) allzeros = 0; @@ -124,15 +149,14 @@ /* If we have reached this point then it is probably a mac resource */ /* file. Now, does it contain any interesting resources? */ - /* Skip handle to next resource map, the file resource number, and */ - /* attributes. */ + (void)FT_STREAM_SKIP( 4 /* skip handle to next resource map */ + 2 /* skip file resource number */ + 2 ); /* skip attributes */ - if ( FT_READ_USHORT( type_list ) ) + if ( FT_READ_SHORT( type_list ) ) return error; - if ( type_list == -1 ) + if ( type_list < 0 ) return FT_THROW( Unknown_File_Format ); error = FT_Stream_Seek( stream, (FT_ULong)( map_pos + type_list ) ); @@ -181,15 +205,34 @@ if ( error ) return error; - if ( FT_READ_USHORT( cnt ) ) + if ( FT_READ_SHORT( cnt ) ) return error; cnt++; - for ( i = 0; i < cnt; ++i ) + /* `rpos' is a signed 16bit integer offset to resource records; the */ + /* size of a resource record is 12 bytes. The map header is 28 bytes, */ + /* and a type list needs 10 bytes or more. If we assume that the name */ + /* list is empty and we have only a single entry in the type list, */ + /* there can be at most */ + /* */ + /* (32768 - 28 - 10) / 12 = 2727 */ + /* */ + /* resources. */ + /* */ + /* A type list starts with a two-byte counter, followed by 10-byte */ + /* type records. Assuming that there are no resources, the number of */ + /* type records can be at most */ + /* */ + /* (32768 - 28 - 2) / 8 = 4079 */ + /* */ + if ( cnt > 4079 ) + return FT_THROW( Invalid_Table ); + + for ( i = 0; i < cnt; i++ ) { if ( FT_READ_LONG( tag_internal ) || - FT_READ_USHORT( subcnt ) || - FT_READ_USHORT( rpos ) ) + FT_READ_SHORT( subcnt ) || + FT_READ_SHORT( rpos ) ) return error; FT_TRACE2(( "Resource tags: %c%c%c%c\n", @@ -205,6 +248,11 @@ *count = subcnt + 1; rpos += map_offset; + /* a zero count might be valid in the resource specification, */ + /* however, it is completely useless to us */ + if ( *count < 1 || *count > 2727 ) + return FT_THROW( Invalid_Table ); + error = FT_Stream_Seek( stream, (FT_ULong)rpos ); if ( error ) return error; @@ -212,35 +260,44 @@ if ( FT_NEW_ARRAY( ref, *count ) ) return error; - for ( j = 0; j < *count; ++j ) + for ( j = 0; j < *count; j++ ) { - if ( FT_READ_USHORT( ref[j].res_id ) ) + if ( FT_READ_SHORT( ref[j].res_id ) ) goto Exit; - if ( FT_STREAM_SKIP( 2 ) ) /* resource name */ + if ( FT_STREAM_SKIP( 2 ) ) /* resource name offset */ goto Exit; - if ( FT_READ_LONG( temp ) ) + if ( FT_READ_LONG( temp ) ) /* attributes (8bit), offset (24bit) */ goto Exit; - if ( FT_STREAM_SKIP( 4 ) ) /* mbz */ + if ( FT_STREAM_SKIP( 4 ) ) /* mbz */ goto Exit; + if ( ref[j].res_id < 0 || temp < 0 ) + { + error = FT_THROW( Invalid_Table ); + goto Exit; + } + ref[j].offset = temp & 0xFFFFFFL; + FT_TRACE3(( " [%d]:" " resource_id=0x%04x, offset=0x%08x\n", j, ref[j].res_id, ref[j].offset )); } - if (sort_by_res_id) + if ( sort_by_res_id ) { - ft_qsort( ref, (size_t)*count, sizeof ( FT_RFork_Ref ), - ( int(*)(const void*, const void*) ) - ft_raccess_sort_ref_by_id ); + ft_qsort( ref, + (size_t)*count, + sizeof ( FT_RFork_Ref ), + ( int(*)(const void*, + const void*) )ft_raccess_sort_ref_by_id ); FT_TRACE3(( " -- sort resources by their ids --\n" )); - for ( j = 0; j < *count; ++ j ) { + + for ( j = 0; j < *count; j++ ) FT_TRACE3(( " [%d]:" " resource_id=0x%04x, offset=0x%08x\n", j, ref[j].res_id, ref[j].offset )); - } } if ( FT_NEW_ARRAY( offsets_internal, *count ) ) @@ -250,7 +307,7 @@ * gap between reference IDs are acceptable? * further investigation on Apple implementation is needed. */ - for ( j = 0; j < *count; ++j ) + for ( j = 0; j < *count; j++ ) offsets_internal[j] = rdata_pos + ref[j].offset; *offsets = offsets_internal; Index: reactos/sdk/lib/3rdparty/freetype/src/base/ftsnames.c =================================================================== --- reactos/sdk/lib/3rdparty/freetype/src/base/ftsnames.c (revision 74184) +++ reactos/sdk/lib/3rdparty/freetype/src/base/ftsnames.c (working copy) @@ -58,7 +58,7 @@ /* load name on demand */ - if ( entry->stringLength > 0 && entry->string == NULL ) + if ( entry->stringLength > 0 && !entry->string ) { FT_Memory memory = face->memory; FT_Stream stream = face->stream; Index: reactos/sdk/lib/3rdparty/freetype/src/base/ftutil.c =================================================================== --- reactos/sdk/lib/3rdparty/freetype/src/base/ftutil.c (revision 74184) +++ reactos/sdk/lib/3rdparty/freetype/src/base/ftutil.c (working copy) @@ -74,7 +74,7 @@ if ( size > 0 ) { block = memory->alloc( memory, size ); - if ( block == NULL ) + if ( !block ) error = FT_THROW( Out_Of_Memory ); } else if ( size < 0 ) @@ -141,7 +141,7 @@ } else if ( cur_count == 0 ) { - FT_ASSERT( block == NULL ); + FT_ASSERT( !block ); block = ft_mem_alloc( memory, new_count*item_size, &error ); } @@ -153,7 +153,7 @@ block2 = memory->realloc( memory, cur_size, new_size, block ); - if ( block2 == NULL ) + if ( !block2 ) error = FT_THROW( Out_Of_Memory ); else block = block2; Index: reactos/sdk/lib/3rdparty/freetype/src/bdf/bdfdrivr.c =================================================================== --- reactos/sdk/lib/3rdparty/freetype/src/bdf/bdfdrivr.c (revision 74184) +++ reactos/sdk/lib/3rdparty/freetype/src/bdf/bdfdrivr.c (working copy) @@ -276,7 +276,7 @@ len = lengths[nn]; - if ( src == NULL ) + if ( !src ) continue; /* separate elements with a space */ @@ -423,7 +423,7 @@ else bdfface->family_name = NULL; - if ( ( error = bdf_interpret_style( face ) ) != 0 ) + if ( FT_SET_ERROR( bdf_interpret_style( face ) ) ) goto Exit; /* the number of glyphs (with one slot for the undefined glyph */ @@ -439,7 +439,7 @@ FT_Short resolution_x = 0, resolution_y = 0; - FT_MEM_ZERO( bsize, sizeof ( FT_Bitmap_Size ) ); + FT_ZERO( bsize ); bsize->height = (FT_Short)( font->font_ascent + font->font_descent ); @@ -866,10 +866,10 @@ 0x10000L, 0x20000L, - 0, /* module-specific interface */ + NULL, /* module-specific interface */ - 0, /* FT_Module_Constructor module_init */ - 0, /* FT_Module_Destructor module_done */ + NULL, /* FT_Module_Constructor module_init */ + NULL, /* FT_Module_Destructor module_done */ bdf_driver_requester /* FT_Module_Requester get_interface */ }, @@ -879,16 +879,16 @@ BDF_Face_Init, /* FT_Face_InitFunc init_face */ BDF_Face_Done, /* FT_Face_DoneFunc done_face */ - 0, /* FT_Size_InitFunc init_size */ - 0, /* FT_Size_DoneFunc done_size */ - 0, /* FT_Slot_InitFunc init_slot */ - 0, /* FT_Slot_DoneFunc done_slot */ + NULL, /* FT_Size_InitFunc init_size */ + NULL, /* FT_Size_DoneFunc done_size */ + NULL, /* FT_Slot_InitFunc init_slot */ + NULL, /* FT_Slot_DoneFunc done_slot */ BDF_Glyph_Load, /* FT_Slot_LoadFunc load_glyph */ - 0, /* FT_Face_GetKerningFunc get_kerning */ - 0, /* FT_Face_AttachFunc attach_file */ - 0, /* FT_Face_GetAdvancesFunc get_advances */ + NULL, /* FT_Face_GetKerningFunc get_kerning */ + NULL, /* FT_Face_AttachFunc attach_file */ + NULL, /* FT_Face_GetAdvancesFunc get_advances */ BDF_Size_Request, /* FT_Size_RequestFunc request_size */ BDF_Size_Select /* FT_Size_SelectFunc select_size */ Index: reactos/sdk/lib/3rdparty/freetype/src/bdf/bdflib.c =================================================================== --- reactos/sdk/lib/3rdparty/freetype/src/bdf/bdflib.c (revision 74184) +++ reactos/sdk/lib/3rdparty/freetype/src/bdf/bdflib.c (working copy) @@ -1119,7 +1119,7 @@ /* See whether this property type exists yet or not. */ /* If not, create it. */ propid = ft_hash_str_lookup( name, &(font->proptbl) ); - if ( propid == NULL ) + if ( !propid ) { error = bdf_create_property( name, BDF_ATOM, font ); if ( error ) @@ -1144,7 +1144,7 @@ } fp = font->props + font->props_size; - FT_MEM_ZERO( fp, sizeof ( bdf_property_t ) ); + FT_ZERO( fp ); font->props_size++; } @@ -2301,7 +2301,7 @@ p->font->comments[p->font->comments_len] = 0; } } - else if ( error == FT_Err_Ok ) + else if ( !error ) error = FT_THROW( Invalid_File_Format ); *font = p->font; Index: reactos/sdk/lib/3rdparty/freetype/src/bzip2/ftbzip2.c =================================================================== --- reactos/sdk/lib/3rdparty/freetype/src/bzip2/ftbzip2.c (revision 74184) +++ reactos/sdk/lib/3rdparty/freetype/src/bzip2/ftbzip2.c (working copy) @@ -180,7 +180,7 @@ bzstream->next_in = (char*)zip->buffer; if ( BZ2_bzDecompressInit( bzstream, 0, 0 ) != BZ_OK || - bzstream->next_in == NULL ) + !bzstream->next_in ) error = FT_THROW( Invalid_File_Format ); Exit: Index: reactos/sdk/lib/3rdparty/freetype/src/cache/ftcbasic.c =================================================================== --- reactos/sdk/lib/3rdparty/freetype/src/cache/ftcbasic.c (revision 74184) +++ reactos/sdk/lib/3rdparty/freetype/src/cache/ftcbasic.c (working copy) @@ -237,12 +237,14 @@ { { sizeof ( FTC_BasicFamilyRec ), - ftc_basic_family_compare, - ftc_basic_family_init, - 0, /* FTC_MruNode_ResetFunc */ - 0 /* FTC_MruNode_DoneFunc */ + + ftc_basic_family_compare, /* FTC_MruNode_CompareFunc node_compare */ + ftc_basic_family_init, /* FTC_MruNode_InitFunc node_init */ + NULL, /* FTC_MruNode_ResetFunc node_reset */ + NULL /* FTC_MruNode_DoneFunc node_done */ }, - ftc_basic_family_load_glyph + + ftc_basic_family_load_glyph /* FTC_IFamily_LoadGlyphFunc family_load_glyph */ }; @@ -250,16 +252,17 @@ const FTC_GCacheClassRec ftc_basic_image_cache_class = { { - ftc_inode_new, - ftc_inode_weight, - ftc_gnode_compare, - ftc_basic_gnode_compare_faceid, - ftc_inode_free, + ftc_inode_new, /* FTC_Node_NewFunc node_new */ + ftc_inode_weight, /* FTC_Node_WeightFunc node_weight */ + ftc_gnode_compare, /* FTC_Node_CompareFunc node_compare */ + ftc_basic_gnode_compare_faceid, /* FTC_Node_CompareFunc node_remove_faceid */ + ftc_inode_free, /* FTC_Node_FreeFunc node_free */ sizeof ( FTC_GCacheRec ), - ftc_gcache_init, - ftc_gcache_done + ftc_gcache_init, /* FTC_Cache_InitFunc cache_init */ + ftc_gcache_done /* FTC_Cache_DoneFunc cache_done */ }, + (FTC_MruListClass)&ftc_basic_image_family_class }; @@ -419,11 +422,12 @@ { { sizeof ( FTC_BasicFamilyRec ), - ftc_basic_family_compare, - ftc_basic_family_init, - 0, /* FTC_MruNode_ResetFunc */ - 0 /* FTC_MruNode_DoneFunc */ + ftc_basic_family_compare, /* FTC_MruNode_CompareFunc node_compare */ + ftc_basic_family_init, /* FTC_MruNode_InitFunc node_init */ + NULL, /* FTC_MruNode_ResetFunc node_reset */ + NULL /* FTC_MruNode_DoneFunc node_done */ }, + ftc_basic_family_get_count, ftc_basic_family_load_bitmap }; @@ -433,16 +437,17 @@ const FTC_GCacheClassRec ftc_basic_sbit_cache_class = { { - ftc_snode_new, - ftc_snode_weight, - ftc_snode_compare, - ftc_basic_gnode_compare_faceid, - ftc_snode_free, + ftc_snode_new, /* FTC_Node_NewFunc node_new */ + ftc_snode_weight, /* FTC_Node_WeightFunc node_weight */ + ftc_snode_compare, /* FTC_Node_CompareFunc node_compare */ + ftc_basic_gnode_compare_faceid, /* FTC_Node_CompareFunc node_remove_faceid */ + ftc_snode_free, /* FTC_Node_FreeFunc node_free */ sizeof ( FTC_GCacheRec ), - ftc_gcache_init, - ftc_gcache_done + ftc_gcache_init, /* FTC_Cache_InitFunc cache_init */ + ftc_gcache_done /* FTC_Cache_DoneFunc cache_done */ }, + (FTC_MruListClass)&ftc_basic_sbit_family_class }; Index: reactos/sdk/lib/3rdparty/freetype/src/cache/ftccache.c =================================================================== --- reactos/sdk/lib/3rdparty/freetype/src/cache/ftccache.c (revision 74184) +++ reactos/sdk/lib/3rdparty/freetype/src/cache/ftccache.c (working copy) @@ -147,7 +147,7 @@ for (;;) { node = *pnode; - if ( node == NULL ) + if ( !node ) break; if ( node->hash & ( mask + 1 ) ) @@ -232,7 +232,7 @@ FTC_Node node = *pnode; - if ( node == NULL ) + if ( !node ) { FT_TRACE0(( "ftc_node_hash_unlink: unknown node\n" )); return; @@ -288,7 +288,7 @@ cache = manager->caches[node->cache_index]; #ifdef FT_DEBUG_ERROR - if ( cache == NULL ) + if ( !cache ) { FT_TRACE0(( "ftc_node_destroy: invalid node handle\n" )); return; @@ -494,7 +494,7 @@ FTC_Node_CompareFunc compare = cache->clazz.node_compare; - if ( cache == NULL || anode == NULL ) + if ( !cache || !anode ) return FT_THROW( Invalid_Argument ); /* Go to the `top' node of the list sharing same masked hash */ @@ -505,7 +505,7 @@ for (;;) { node = *pnode; - if ( node == NULL ) + if ( !node ) goto NewNode; if ( node->hash == hash && @@ -523,7 +523,7 @@ /* Update pnode by modified linked list */ while ( *pnode != node ) { - if ( *pnode == NULL ) + if ( !*pnode ) { FT_ERROR(( "FTC_Cache_Lookup: oops!!! node missing\n" )); goto NewNode; @@ -582,7 +582,7 @@ FT_Bool list_changed = FALSE; - if ( node == NULL ) + if ( !node ) break; if ( cache->clazz.node_remove_faceid( node, face_id, Index: reactos/sdk/lib/3rdparty/freetype/src/cache/ftccache.h =================================================================== --- reactos/sdk/lib/3rdparty/freetype/src/cache/ftccache.h (revision 74184) +++ reactos/sdk/lib/3rdparty/freetype/src/cache/ftccache.h (working copy) @@ -227,7 +227,7 @@ for (;;) \ { \ _node = *_pnode; \ - if ( _node == NULL ) \ + if ( !_node ) \ goto NewNode_; \ \ if ( _node->hash == _hash && \ @@ -245,7 +245,7 @@ /* Update _pnode by possibly modified linked list */ \ while ( *_pnode != _node ) \ { \ - if ( *_pnode == NULL ) \ + if ( !*_pnode ) \ { \ FT_ERROR(( "FTC_CACHE_LOOKUP_CMP: oops!!! node missing\n" )); \ goto NewNode_; \ @@ -325,7 +325,7 @@ break; \ \ _try_done = FTC_Manager_FlushN( _try_manager, _try_count ); \ - if ( _try_done > 0 && ( list_changed != NULL ) ) \ + if ( _try_done > 0 && list_changed != NULL ) \ *(FT_Bool*)( list_changed ) = TRUE; \ \ if ( _try_done == 0 ) \ Index: reactos/sdk/lib/3rdparty/freetype/src/cache/ftccmap.c =================================================================== --- reactos/sdk/lib/3rdparty/freetype/src/cache/ftccmap.c (revision 74184) +++ reactos/sdk/lib/3rdparty/freetype/src/cache/ftccmap.c (working copy) @@ -201,15 +201,15 @@ static const FTC_CacheClassRec ftc_cmap_cache_class = { - ftc_cmap_node_new, - ftc_cmap_node_weight, - ftc_cmap_node_compare, - ftc_cmap_node_remove_faceid, - ftc_cmap_node_free, + ftc_cmap_node_new, /* FTC_Node_NewFunc node_new */ + ftc_cmap_node_weight, /* FTC_Node_WeightFunc node_weight */ + ftc_cmap_node_compare, /* FTC_Node_CompareFunc node_compare */ + ftc_cmap_node_remove_faceid, /* FTC_Node_CompareFunc node_remove_faceid */ + ftc_cmap_node_free, /* FTC_Node_FreeFunc node_free */ sizeof ( FTC_CacheRec ), - ftc_cache_init, - ftc_cache_done, + ftc_cache_init, /* FTC_Cache_InitFunc cache_init */ + ftc_cache_done, /* FTC_Cache_DoneFunc cache_done */ }; Index: reactos/sdk/lib/3rdparty/freetype/src/cache/ftcmanag.c =================================================================== --- reactos/sdk/lib/3rdparty/freetype/src/cache/ftcmanag.c (revision 74184) +++ reactos/sdk/lib/3rdparty/freetype/src/cache/ftcmanag.c (working copy) @@ -156,10 +156,11 @@ const FTC_MruListClassRec ftc_size_list_class = { sizeof ( FTC_SizeNodeRec ), - ftc_size_node_compare, - ftc_size_node_init, - ftc_size_node_reset, - ftc_size_node_done + + ftc_size_node_compare, /* FTC_MruNode_CompareFunc node_compare */ + ftc_size_node_init, /* FTC_MruNode_InitFunc node_init */ + ftc_size_node_reset, /* FTC_MruNode_ResetFunc node_reset */ + ftc_size_node_done /* FTC_MruNode_DoneFunc node_done */ }; @@ -296,10 +297,10 @@ { sizeof ( FTC_FaceNodeRec), - ftc_face_node_compare, - ftc_face_node_init, - 0, /* FTC_MruNode_ResetFunc */ - ftc_face_node_done + ftc_face_node_compare, /* FTC_MruNode_CompareFunc node_compare */ + ftc_face_node_init, /* FTC_MruNode_InitFunc node_init */ + NULL, /* FTC_MruNode_ResetFunc node_reset */ + ftc_face_node_done /* FTC_MruNode_DoneFunc node_done */ }; @@ -552,7 +553,7 @@ manager->num_nodes )); #endif - if ( manager->cur_weight < manager->max_weight || first == NULL ) + if ( manager->cur_weight < manager->max_weight || !first ) return; /* go to last node -- it's a circular list */ @@ -637,7 +638,7 @@ /* try to remove `count' nodes from the list */ - if ( first == NULL ) /* empty list! */ + if ( !first ) /* empty list! */ return 0; /* go to last node - it's a circular list */ Index: reactos/sdk/lib/3rdparty/freetype/src/cache/ftcmru.c =================================================================== --- reactos/sdk/lib/3rdparty/freetype/src/cache/ftcmru.c (revision 74184) +++ reactos/sdk/lib/3rdparty/freetype/src/cache/ftcmru.c (working copy) @@ -76,7 +76,7 @@ FTC_MruNode first = *plist; - FT_ASSERT( first != NULL ); + FT_ASSERT( first ); if ( first != node ) { @@ -126,7 +126,7 @@ FTC_MruNode prev, next; - FT_ASSERT( first != NULL ); + FT_ASSERT( first ); #ifdef FT_DEBUG_ERROR { @@ -238,7 +238,7 @@ FTC_MruNode *anode ) { FT_Error error; - FTC_MruNode node = NULL; + FTC_MruNode node = NULL; FT_Memory memory = list->memory; @@ -296,7 +296,7 @@ node = FTC_MruList_Find( list, key ); - if ( node == NULL ) + if ( !node ) return FTC_MruList_New( list, key, anode ); *anode = node; @@ -332,7 +332,7 @@ first = list->nodes; - while ( first && ( selection == NULL || selection( first, key ) ) ) + while ( first && ( !selection || selection( first, key ) ) ) { FTC_MruList_Remove( list, first ); first = list->nodes; Index: reactos/sdk/lib/3rdparty/freetype/src/cache/ftcmru.h =================================================================== --- reactos/sdk/lib/3rdparty/freetype/src/cache/ftcmru.h (revision 74184) +++ reactos/sdk/lib/3rdparty/freetype/src/cache/ftcmru.h (working copy) @@ -108,6 +108,7 @@ typedef struct FTC_MruListClassRec_ { FT_Offset node_size; + FTC_MruNode_CompareFunc node_compare; FTC_MruNode_InitFunc node_init; FTC_MruNode_ResetFunc node_reset; @@ -115,6 +116,7 @@ } FTC_MruListClassRec; + typedef struct FTC_MruListRec_ { FT_UInt num_nodes; Index: reactos/sdk/lib/3rdparty/freetype/src/cache/ftcsbits.c =================================================================== --- reactos/sdk/lib/3rdparty/freetype/src/cache/ftcsbits.c (revision 74184) +++ reactos/sdk/lib/3rdparty/freetype/src/cache/ftcsbits.c (working copy) @@ -378,7 +378,7 @@ * */ - if ( sbit->buffer == NULL && sbit->width == 255 ) + if ( !sbit->buffer && sbit->width == 255 ) { FT_ULong size; FT_Error error; Index: reactos/sdk/lib/3rdparty/freetype/src/cff/cf2arrst.c =================================================================== --- reactos/sdk/lib/3rdparty/freetype/src/cff/cf2arrst.c (revision 74184) +++ reactos/sdk/lib/3rdparty/freetype/src/cff/cf2arrst.c (working copy) @@ -58,7 +58,7 @@ FT_Error* error, size_t sizeItem ) { - FT_ASSERT( arrstack != NULL ); + FT_ASSERT( arrstack ); /* initialize the structure */ arrstack->memory = memory; @@ -78,7 +78,7 @@ FT_Memory memory = arrstack->memory; /* for FT_FREE */ - FT_ASSERT( arrstack != NULL ); + FT_ASSERT( arrstack ); arrstack->allocated = 0; arrstack->count = 0; @@ -95,7 +95,7 @@ cf2_arrstack_setNumElements( CF2_ArrStack arrstack, size_t numElements ) { - FT_ASSERT( arrstack != NULL ); + FT_ASSERT( arrstack ); { FT_Error error = FT_Err_Ok; /* for FT_REALLOC */ @@ -140,7 +140,7 @@ cf2_arrstack_setCount( CF2_ArrStack arrstack, size_t numElements ) { - FT_ASSERT( arrstack != NULL ); + FT_ASSERT( arrstack ); if ( numElements > arrstack->allocated ) { @@ -157,7 +157,7 @@ FT_LOCAL_DEF( void ) cf2_arrstack_clear( CF2_ArrStack arrstack ) { - FT_ASSERT( arrstack != NULL ); + FT_ASSERT( arrstack ); arrstack->count = 0; } @@ -167,7 +167,7 @@ FT_LOCAL_DEF( size_t ) cf2_arrstack_size( const CF2_ArrStack arrstack ) { - FT_ASSERT( arrstack != NULL ); + FT_ASSERT( arrstack ); return arrstack->count; } @@ -176,7 +176,7 @@ FT_LOCAL_DEF( void* ) cf2_arrstack_getBuffer( const CF2_ArrStack arrstack ) { - FT_ASSERT( arrstack != NULL ); + FT_ASSERT( arrstack ); return arrstack->ptr; } @@ -190,7 +190,7 @@ void* newPtr; - FT_ASSERT( arrstack != NULL ); + FT_ASSERT( arrstack ); if ( idx >= arrstack->count ) { @@ -212,7 +212,7 @@ cf2_arrstack_push( CF2_ArrStack arrstack, const void* ptr ) { - FT_ASSERT( arrstack != NULL ); + FT_ASSERT( arrstack ); if ( arrstack->count == arrstack->allocated ) { @@ -225,7 +225,7 @@ } } - FT_ASSERT( ptr != NULL ); + FT_ASSERT( ptr ); { size_t offset = arrstack->count * arrstack->sizeItem; Index: reactos/sdk/lib/3rdparty/freetype/src/cff/cf2error.c =================================================================== --- reactos/sdk/lib/3rdparty/freetype/src/cff/cf2error.c (revision 74184) +++ reactos/sdk/lib/3rdparty/freetype/src/cff/cf2error.c (working copy) @@ -44,7 +44,7 @@ cf2_setError( FT_Error* error, FT_Error value ) { - if ( error && *error == 0 ) + if ( error && !*error ) *error = value; } Index: reactos/sdk/lib/3rdparty/freetype/src/cff/cf2fixed.h =================================================================== --- reactos/sdk/lib/3rdparty/freetype/src/cff/cf2fixed.h (revision 74184) +++ reactos/sdk/lib/3rdparty/freetype/src/cff/cf2fixed.h (working copy) @@ -51,8 +51,8 @@ #define CF2_FIXED_MAX ( (CF2_Fixed)0x7FFFFFFFL ) #define CF2_FIXED_MIN ( (CF2_Fixed)0x80000000L ) -#define CF2_FIXED_ONE 0x10000L -#define CF2_FIXED_EPSILON 0x0001 +#define CF2_FIXED_ONE ( (CF2_Fixed)0x10000L ) +#define CF2_FIXED_EPSILON ( (CF2_Fixed)0x0001 ) /* in C 89, left and right shift of negative numbers is */ /* implementation specific behaviour in the general case */ Index: reactos/sdk/lib/3rdparty/freetype/src/cff/cf2font.c =================================================================== --- reactos/sdk/lib/3rdparty/freetype/src/cff/cf2font.c (revision 74184) +++ reactos/sdk/lib/3rdparty/freetype/src/cff/cf2font.c (working copy) @@ -234,7 +234,8 @@ } - /* set up values for the current FontDict and matrix */ + /* set up values for the current FontDict and matrix; */ + /* called for each glyph to be rendered */ /* caller's transform is adjusted for subpixel positioning */ static void @@ -246,6 +247,9 @@ FT_Bool needExtraSetup = FALSE; + CFF_VStoreRec* vstore; + FT_Bool hasVariations = FALSE; + /* character space units */ CF2_Fixed boldenX = font->syntheticEmboldeningAmountX; CF2_Fixed boldenY = font->syntheticEmboldeningAmountY; @@ -253,7 +257,10 @@ CFF_SubFont subFont; CF2_Fixed ppem; + CF2_UInt lenNormalizedV = 0; + FT_Fixed* normalizedV = NULL; + /* clear previous error */ font->error = FT_Err_Ok; @@ -266,6 +273,48 @@ needExtraSetup = TRUE; } + /* check for variation vectors */ + vstore = cf2_getVStore( decoder ); + hasVariations = ( vstore->dataCount != 0 ); + + if ( hasVariations ) + { +#ifdef TT_CONFIG_OPTION_GX_VAR_SUPPORT + /* check whether Private DICT in this subfont needs to be reparsed */ + font->error = cf2_getNormalizedVector( decoder, + &lenNormalizedV, + &normalizedV ); + if ( font->error ) + return; + + if ( cff_blend_check_vector( &subFont->blend, + subFont->private_dict.vsindex, + lenNormalizedV, + normalizedV ) ) + { + /* blend has changed, reparse */ + cff_load_private_dict( decoder->cff, + subFont, + lenNormalizedV, + normalizedV ); + needExtraSetup = TRUE; + } +#endif + + /* copy from subfont */ + font->blend.font = subFont->blend.font; + + /* clear state of charstring blend */ + font->blend.usedBV = FALSE; + + /* initialize value for charstring */ + font->vsindex = subFont->private_dict.vsindex; + + /* store vector inputs for blends in charstring */ + font->lenNDV = lenNormalizedV; + font->NDV = normalizedV; + } + /* if ppem has changed, we need to recompute some cached data */ /* note: because of CID font matrix concatenation, ppem and transform */ /* do not necessarily track. */ @@ -423,7 +472,8 @@ /* compute blue zones for this instance */ cf2_blues_init( &font->blues, font ); - } + + } /* needExtraSetup */ } Index: reactos/sdk/lib/3rdparty/freetype/src/cff/cf2font.h =================================================================== --- reactos/sdk/lib/3rdparty/freetype/src/cff/cf2font.h (revision 74184) +++ reactos/sdk/lib/3rdparty/freetype/src/cff/cf2font.h (working copy) @@ -42,6 +42,7 @@ #include "cf2ft.h" #include "cf2blues.h" +#include "cffload.h" FT_BEGIN_HEADER @@ -63,6 +64,7 @@ FT_Memory memory; FT_Error error; /* shared error for this instance */ + FT_Bool isCFF2; CF2_RenderingFlags renderingFlags; /* variables that depend on Transform: */ @@ -74,6 +76,12 @@ CF2_Matrix outerTransform; /* post hinting; includes rotations */ CF2_Fixed ppem; /* transform-dependent */ + /* variation data */ + CFF_BlendRec blend; /* cached charstring blend vector */ + CF2_UInt vsindex; /* current vsindex */ + CF2_UInt lenNDV; /* current length NDV or zero */ + FT_Fixed* NDV; /* ptr to current NDV or NULL */ + CF2_Int unitsPerEm; CF2_Fixed syntheticEmboldeningAmountX; /* character space units */ Index: reactos/sdk/lib/3rdparty/freetype/src/cff/cf2ft.c =================================================================== --- reactos/sdk/lib/3rdparty/freetype/src/cff/cf2ft.c (revision 74184) +++ reactos/sdk/lib/3rdparty/freetype/src/cff/cf2ft.c (working copy) @@ -104,7 +104,8 @@ FT_Memory memory = font->memory; - (void)memory; + FT_FREE( font->blend.lastNDV ); + FT_FREE( font->blend.BV ); } } @@ -239,7 +240,7 @@ FT_Memory memory, FT_Error* error ) { - FT_MEM_ZERO( outline, sizeof ( CF2_OutlineRec ) ); + FT_ZERO( outline ); outline->root.memory = memory; outline->root.error = error; @@ -311,7 +312,7 @@ font = (CF2_Font)decoder->cff->cf2_instance.data; /* on first glyph, allocate instance structure */ - if ( decoder->cff->cf2_instance.data == NULL ) + if ( !decoder->cff->cf2_instance.data ) { decoder->cff->cf2_instance.finalizer = (FT_Generic_Finalizer)cf2_free_instance; @@ -366,6 +367,9 @@ &hinted, &scaled ); + /* copy isCFF2 boolean from TT_Face to CF2_Font */ + font->isCFF2 = builder->face->isCFF2; + font->renderingFlags = 0; if ( hinted ) font->renderingFlags |= CF2_FlagsHinted; @@ -413,6 +417,44 @@ } + /* get pointer to VStore structure */ + FT_LOCAL_DEF( CFF_VStore ) + cf2_getVStore( CFF_Decoder* decoder ) + { + FT_ASSERT( decoder && decoder->cff ); + + return &decoder->cff->vstore; + } + + + /* get maxstack value from CFF2 Top DICT */ + FT_LOCAL_DEF( FT_UInt ) + cf2_getMaxstack( CFF_Decoder* decoder ) + { + FT_ASSERT( decoder && decoder->cff ); + + return decoder->cff->top_font.font_dict.maxstack; + } + + +#ifdef TT_CONFIG_OPTION_GX_VAR_SUPPORT + /* Get normalized design vector for current render request; */ + /* return pointer and length. */ + /* */ + /* Note: Uses FT_Fixed not CF2_Fixed for the vector. */ + FT_LOCAL_DEF( FT_Error ) + cf2_getNormalizedVector( CFF_Decoder* decoder, + CF2_UInt *len, + FT_Fixed* *vec ) + { + FT_ASSERT( decoder && decoder->builder.face ); + FT_ASSERT( vec && len ); + + return cff_get_var_blend( decoder->builder.face, len, vec, NULL ); + } +#endif + + /* get `y_ppem' from `CFF_Size' */ FT_LOCAL_DEF( CF2_Fixed ) cf2_getPpemY( CFF_Decoder* decoder ) Index: reactos/sdk/lib/3rdparty/freetype/src/cff/cf2ft.h =================================================================== --- reactos/sdk/lib/3rdparty/freetype/src/cff/cf2ft.h (revision 74184) +++ reactos/sdk/lib/3rdparty/freetype/src/cff/cf2ft.h (working copy) @@ -64,7 +64,19 @@ FT_LOCAL( CFF_SubFont ) cf2_getSubfont( CFF_Decoder* decoder ); + FT_LOCAL( CFF_VStore ) + cf2_getVStore( CFF_Decoder* decoder ); + FT_LOCAL( FT_UInt ) + cf2_getMaxstack( CFF_Decoder* decoder ); + +#ifdef TT_CONFIG_OPTION_GX_VAR_SUPPORT + FT_LOCAL( FT_Error ) + cf2_getNormalizedVector( CFF_Decoder* decoder, + CF2_UInt *len, + FT_Fixed* *vec ); +#endif + FT_LOCAL( CF2_Fixed ) cf2_getPpemY( CFF_Decoder* decoder ); FT_LOCAL( CF2_Fixed ) Index: reactos/sdk/lib/3rdparty/freetype/src/cff/cf2hints.c =================================================================== --- reactos/sdk/lib/3rdparty/freetype/src/cff/cf2hints.c (revision 74184) +++ reactos/sdk/lib/3rdparty/freetype/src/cff/cf2hints.c (working copy) @@ -401,10 +401,10 @@ /* calculate all four possibilities; moves down are negative */ CF2_Fixed downMoveDown = 0 - fracDown; CF2_Fixed upMoveDown = 0 - fracUp; - CF2_Fixed downMoveUp = fracDown == 0 + CF2_Fixed downMoveUp = ( fracDown == 0 ) ? 0 : cf2_intToFixed( 1 ) - fracDown; - CF2_Fixed upMoveUp = fracUp == 0 + CF2_Fixed upMoveUp = ( fracUp == 0 ) ? 0 : cf2_intToFixed( 1 ) - fracUp; Index: reactos/sdk/lib/3rdparty/freetype/src/cff/cf2intrp.c =================================================================== --- reactos/sdk/lib/3rdparty/freetype/src/cff/cf2intrp.c (revision 74184) +++ reactos/sdk/lib/3rdparty/freetype/src/cff/cf2intrp.c (working copy) @@ -47,7 +47,9 @@ #include "cf2error.h" +#include "cffload.h" + /*************************************************************************/ /* */ /* The macro FT_COMPONENT is used in trace mode. It is an implicit */ @@ -215,8 +217,8 @@ cf2_cmdESC, /* 12 */ cf2_cmdRESERVED_13, /* 13 */ cf2_cmdENDCHAR, /* 14 */ - cf2_cmdRESERVED_15, /* 15 */ - cf2_cmdRESERVED_16, /* 16 */ + cf2_cmdVSINDEX, /* 15 */ + cf2_cmdBLEND, /* 16 */ cf2_cmdRESERVED_17, /* 17 */ cf2_cmdHSTEMHM, /* 18 */ cf2_cmdHINTMASK, /* 19 */ @@ -273,7 +275,8 @@ cf2_escHFLEX, /* 34 */ cf2_escFLEX, /* 35 */ cf2_escHFLEX1, /* 36 */ - cf2_escFLEX1 /* 37 */ + cf2_escFLEX1, /* 37 */ + cf2_escRESERVED_38 /* 38 & all higher */ }; @@ -344,7 +347,7 @@ vals[0] = *curX; vals[1] = *curY; index = 0; - isHFlex = readFromStack[9] == FALSE; + isHFlex = FT_BOOL( readFromStack[9] == FALSE ); top = isHFlex ? 9 : 10; for ( i = 0; i < top; i++ ) @@ -403,6 +406,43 @@ } + /* Blend numOperands on the stack, */ + /* store results into the first numBlends values, */ + /* then pop remaining arguments. */ + static void + cf2_doBlend( const CFF_Blend blend, + CF2_Stack opStack, + CF2_UInt numBlends ) + { + CF2_UInt delta; + CF2_UInt base; + CF2_UInt i, j; + CF2_UInt numOperands = (CF2_UInt)( numBlends * blend->lenBV ); + + + base = cf2_stack_count( opStack ) - numOperands; + delta = base + numBlends; + + for ( i = 0; i < numBlends; i++ ) + { + const CF2_Fixed* weight = &blend->BV[1]; + + /* start with first term */ + CF2_Fixed sum = cf2_stack_getReal( opStack, i + base ); + + + for ( j = 1; j < blend->lenBV; j++ ) + sum += FT_MulFix( *weight++, cf2_stack_getReal( opStack, delta++ ) ); + + /* store blended result */ + cf2_stack_setReal( opStack, i + base, sum ); + } + + /* leave only `numBlends' results on stack */ + cf2_stack_pop( opStack, numOperands - numBlends ); + } + + /* * `error' is a shared error code used by many objects in this * routine. Before the code continues from an error, it must check and @@ -445,6 +485,7 @@ CF2_Fixed hintOriginY = curY; CF2_Stack opStack = NULL; + FT_UInt stackSize; FT_Byte op1; /* first opcode byte */ CF2_F16Dot16 storage[CF2_STORAGE_SIZE]; /* for `put' and `get' */ @@ -525,19 +566,24 @@ * If one of the above operators occurs without explicitly specifying * a width, we assume the default width. * + * CFF2 charstrings always return the default width (0). + * */ - haveWidth = FALSE; + haveWidth = font->isCFF2 ? TRUE : FALSE; *width = cf2_getDefaultWidthX( decoder ); /* - * Note: at this point, all pointers to resources must be NULL - * and all local objects must be initialized. - * There must be no branches to exit: above this point. + * Note: At this point, all pointers to resources must be NULL + * and all local objects must be initialized. + * There must be no branches to `exit:' above this point. * */ /* allocate an operand stack */ - opStack = cf2_stack_init( memory, error ); + stackSize = font->isCFF2 ? cf2_getMaxstack( decoder ) + : CF2_OPERAND_STACK_SIZE; + opStack = cf2_stack_init( memory, error, stackSize ); + if ( !opStack ) { lastError = FT_THROW( Out_Of_Memory ); @@ -566,6 +612,7 @@ { /* If we've reached the end of the charstring, simulate a */ /* cf2_cmdRETURN or cf2_cmdENDCHAR. */ + /* We do this for both CFF and CFF2. */ if ( charstringIndex ) op1 = cf2_cmdRETURN; /* end of buffer for subroutine */ else @@ -572,8 +619,16 @@ op1 = cf2_cmdENDCHAR; /* end of buffer for top level charstring */ } else + { op1 = (FT_Byte)cf2_buf_readByte( charstring ); + /* Explicit RETURN and ENDCHAR in CFF2 should be ignored. */ + /* Note: Trace message will report 0 instead of 11 or 14. */ + if ( ( op1 == cf2_cmdRETURN || op1 == cf2_cmdENDCHAR ) && + font->isCFF2 ) + op1 = cf2_cmdRESERVED_0; + } + /* check for errors once per loop */ if ( *error ) goto exit; @@ -591,13 +646,78 @@ case cf2_cmdRESERVED_2: case cf2_cmdRESERVED_9: case cf2_cmdRESERVED_13: - case cf2_cmdRESERVED_15: - case cf2_cmdRESERVED_16: case cf2_cmdRESERVED_17: /* we may get here if we have a prior error */ FT_TRACE4(( " unknown op (%d)\n", op1 )); break; + case cf2_cmdVSINDEX: + FT_TRACE4(( " vsindex\n" )); + + if ( !font->isCFF2 ) + break; /* clear stack & ignore */ + + if ( font->blend.usedBV ) + { + /* vsindex not allowed after blend */ + lastError = FT_THROW( Invalid_Glyph_Format ); + goto exit; + } + + { + FT_Int temp = cf2_stack_popInt( opStack ); + + + if ( temp >= 0 ) + font->vsindex = (FT_UInt)temp; + } + break; + + case cf2_cmdBLEND: + { + FT_UInt numBlends; + + + FT_TRACE4(( " blend\n" )); + + if ( !font->isCFF2 ) + break; /* clear stack & ignore */ + + /* do we have a `blend' op in a non-variant font? */ + if ( !font->blend.font ) + { + lastError = FT_THROW( Invalid_Glyph_Format ); + goto exit; + } + + /* check cached blend vector */ + if ( cff_blend_check_vector( &font->blend, + font->vsindex, + font->lenNDV, + font->NDV ) ) + { + lastError = cff_blend_build_vector( &font->blend, + font->vsindex, + font->lenNDV, + font->NDV ); + if ( lastError ) + goto exit; + } + + /* do the blend */ + numBlends = (FT_UInt)cf2_stack_popInt( opStack ); + if ( numBlends > stackSize ) + { + lastError = FT_THROW( Invalid_Glyph_Format ); + goto exit; + } + + cf2_doBlend( &font->blend, opStack, numBlends ); + + font->blend.usedBV = TRUE; + } + continue; /* do not clear the stack */ + case cf2_cmdHSTEMHM: case cf2_cmdHSTEM: FT_TRACE4(( op1 == cf2_cmdHSTEMHM ? " hstemhm\n" : " hstem\n" )); @@ -690,7 +810,7 @@ CF2_UInt index; CF2_UInt count = cf2_stack_count( opStack ); - FT_Bool isX = op1 == cf2_cmdHLINETO; + FT_Bool isX = FT_BOOL( op1 == cf2_cmdHLINETO ); FT_TRACE4(( isX ? " hlineto\n" : " vlineto\n" )); @@ -835,440 +955,456 @@ FT_Byte op2 = (FT_Byte)cf2_buf_readByte( charstring ); + /* first switch for 2-byte operators handles CFF2 */ + /* and opcodes that are reserved for both CFF and CFF2 */ switch ( op2 ) { - case cf2_escDOTSECTION: - /* something about `flip type of locking' -- ignore it */ - FT_TRACE4(( " dotsection\n" )); + case cf2_escHFLEX: + { + static const FT_Bool readFromStack[12] = + { + TRUE /* dx1 */, FALSE /* dy1 */, + TRUE /* dx2 */, TRUE /* dy2 */, + TRUE /* dx3 */, FALSE /* dy3 */, + TRUE /* dx4 */, FALSE /* dy4 */, + TRUE /* dx5 */, FALSE /* dy5 */, + TRUE /* dx6 */, FALSE /* dy6 */ + }; - break; - case cf2_escAND: + FT_TRACE4(( " hflex\n" )); + + cf2_doFlex( opStack, + &curX, + &curY, + &glyphPath, + readFromStack, + FALSE /* doConditionalLastRead */ ); + } + continue; + + case cf2_escFLEX: { - CF2_F16Dot16 arg1; - CF2_F16Dot16 arg2; + static const FT_Bool readFromStack[12] = + { + TRUE /* dx1 */, TRUE /* dy1 */, + TRUE /* dx2 */, TRUE /* dy2 */, + TRUE /* dx3 */, TRUE /* dy3 */, + TRUE /* dx4 */, TRUE /* dy4 */, + TRUE /* dx5 */, TRUE /* dy5 */, + TRUE /* dx6 */, TRUE /* dy6 */ + }; - FT_TRACE4(( " and\n" )); + FT_TRACE4(( " flex\n" )); - arg2 = cf2_stack_popFixed( opStack ); - arg1 = cf2_stack_popFixed( opStack ); - - cf2_stack_pushInt( opStack, arg1 && arg2 ); + cf2_doFlex( opStack, + &curX, + &curY, + &glyphPath, + readFromStack, + FALSE /* doConditionalLastRead */ ); } - continue; /* do not clear the stack */ + break; /* TODO: why is this not a continue? */ - case cf2_escOR: + case cf2_escHFLEX1: { - CF2_F16Dot16 arg1; - CF2_F16Dot16 arg2; + static const FT_Bool readFromStack[12] = + { + TRUE /* dx1 */, TRUE /* dy1 */, + TRUE /* dx2 */, TRUE /* dy2 */, + TRUE /* dx3 */, FALSE /* dy3 */, + TRUE /* dx4 */, FALSE /* dy4 */, + TRUE /* dx5 */, TRUE /* dy5 */, + TRUE /* dx6 */, FALSE /* dy6 */ + }; - FT_TRACE4(( " or\n" )); + FT_TRACE4(( " hflex1\n" )); - arg2 = cf2_stack_popFixed( opStack ); - arg1 = cf2_stack_popFixed( opStack ); - - cf2_stack_pushInt( opStack, arg1 || arg2 ); + cf2_doFlex( opStack, + &curX, + &curY, + &glyphPath, + readFromStack, + FALSE /* doConditionalLastRead */ ); } - continue; /* do not clear the stack */ + continue; - case cf2_escNOT: + case cf2_escFLEX1: { - CF2_F16Dot16 arg; + static const FT_Bool readFromStack[12] = + { + TRUE /* dx1 */, TRUE /* dy1 */, + TRUE /* dx2 */, TRUE /* dy2 */, + TRUE /* dx3 */, TRUE /* dy3 */, + TRUE /* dx4 */, TRUE /* dy4 */, + TRUE /* dx5 */, TRUE /* dy5 */, + FALSE /* dx6 */, FALSE /* dy6 */ + }; - FT_TRACE4(( " not\n" )); + FT_TRACE4(( " flex1\n" )); - arg = cf2_stack_popFixed( opStack ); - - cf2_stack_pushInt( opStack, !arg ); + cf2_doFlex( opStack, + &curX, + &curY, + &glyphPath, + readFromStack, + TRUE /* doConditionalLastRead */ ); } - continue; /* do not clear the stack */ + continue; - case cf2_escABS: + /* these opcodes are reserved in both CFF & CFF2 */ + case cf2_escRESERVED_1: + case cf2_escRESERVED_2: + case cf2_escRESERVED_6: + case cf2_escRESERVED_7: + case cf2_escRESERVED_8: + case cf2_escRESERVED_13: + case cf2_escRESERVED_16: + case cf2_escRESERVED_17: + case cf2_escRESERVED_19: + case cf2_escRESERVED_25: + case cf2_escRESERVED_31: + case cf2_escRESERVED_32: + case cf2_escRESERVED_33: + FT_TRACE4(( " unknown op (12, %d)\n", op2 )); + break; + + default: { - CF2_F16Dot16 arg; + if ( font->isCFF2 || op2 >= cf2_escRESERVED_38 ) + FT_TRACE4(( " unknown op (12, %d)\n", op2 )); + else + { + /* second switch for 2-byte operators handles just CFF */ + switch ( op2 ) + { + case cf2_escDOTSECTION: + /* something about `flip type of locking' -- ignore it */ + FT_TRACE4(( " dotsection\n" )); - FT_TRACE4(( " abs\n" )); + break; - arg = cf2_stack_popFixed( opStack ); + case cf2_escAND: + { + CF2_F16Dot16 arg1; + CF2_F16Dot16 arg2; - cf2_stack_pushFixed( opStack, FT_ABS( arg ) ); - } - continue; /* do not clear the stack */ - case cf2_escADD: - { - CF2_F16Dot16 summand1; - CF2_F16Dot16 summand2; + FT_TRACE4(( " and\n" )); + arg2 = cf2_stack_popFixed( opStack ); + arg1 = cf2_stack_popFixed( opStack ); - FT_TRACE4(( " add\n" )); + cf2_stack_pushInt( opStack, arg1 && arg2 ); + } + continue; /* do not clear the stack */ - summand2 = cf2_stack_popFixed( opStack ); - summand1 = cf2_stack_popFixed( opStack ); + case cf2_escOR: + { + CF2_F16Dot16 arg1; + CF2_F16Dot16 arg2; - cf2_stack_pushFixed( opStack, summand1 + summand2 ); - } - continue; /* do not clear the stack */ - case cf2_escSUB: - { - CF2_F16Dot16 minuend; - CF2_F16Dot16 subtrahend; + FT_TRACE4(( " or\n" )); + arg2 = cf2_stack_popFixed( opStack ); + arg1 = cf2_stack_popFixed( opStack ); - FT_TRACE4(( " sub\n" )); + cf2_stack_pushInt( opStack, arg1 || arg2 ); + } + continue; /* do not clear the stack */ - subtrahend = cf2_stack_popFixed( opStack ); - minuend = cf2_stack_popFixed( opStack ); + case cf2_escNOT: + { + CF2_F16Dot16 arg; - cf2_stack_pushFixed( opStack, minuend - subtrahend ); - } - continue; /* do not clear the stack */ - case cf2_escDIV: - { - CF2_F16Dot16 dividend; - CF2_F16Dot16 divisor; + FT_TRACE4(( " not\n" )); + arg = cf2_stack_popFixed( opStack ); - FT_TRACE4(( " div\n" )); + cf2_stack_pushInt( opStack, !arg ); + } + continue; /* do not clear the stack */ - divisor = cf2_stack_popFixed( opStack ); - dividend = cf2_stack_popFixed( opStack ); + case cf2_escABS: + { + CF2_F16Dot16 arg; - cf2_stack_pushFixed( opStack, FT_DivFix( dividend, divisor ) ); - } - continue; /* do not clear the stack */ - case cf2_escNEG: - { - CF2_F16Dot16 arg; + FT_TRACE4(( " abs\n" )); + arg = cf2_stack_popFixed( opStack ); - FT_TRACE4(( " neg\n" )); + cf2_stack_pushFixed( opStack, FT_ABS( arg ) ); + } + continue; /* do not clear the stack */ - arg = cf2_stack_popFixed( opStack ); + case cf2_escADD: + { + CF2_F16Dot16 summand1; + CF2_F16Dot16 summand2; - cf2_stack_pushFixed( opStack, -arg ); - } - continue; /* do not clear the stack */ - case cf2_escEQ: - { - CF2_F16Dot16 arg1; - CF2_F16Dot16 arg2; + FT_TRACE4(( " add\n" )); + summand2 = cf2_stack_popFixed( opStack ); + summand1 = cf2_stack_popFixed( opStack ); - FT_TRACE4(( " eq\n" )); + cf2_stack_pushFixed( opStack, summand1 + summand2 ); + } + continue; /* do not clear the stack */ - arg2 = cf2_stack_popFixed( opStack ); - arg1 = cf2_stack_popFixed( opStack ); + case cf2_escSUB: + { + CF2_F16Dot16 minuend; + CF2_F16Dot16 subtrahend; - cf2_stack_pushInt( opStack, arg1 == arg2 ); - } - continue; /* do not clear the stack */ - case cf2_escDROP: - FT_TRACE4(( " drop\n" )); + FT_TRACE4(( " sub\n" )); - (void)cf2_stack_popFixed( opStack ); - continue; /* do not clear the stack */ + subtrahend = cf2_stack_popFixed( opStack ); + minuend = cf2_stack_popFixed( opStack ); - case cf2_escPUT: - { - CF2_F16Dot16 val; - CF2_Int idx; + cf2_stack_pushFixed( opStack, minuend - subtrahend ); + } + continue; /* do not clear the stack */ + case cf2_escDIV: + { + CF2_F16Dot16 dividend; + CF2_F16Dot16 divisor; - FT_TRACE4(( " put\n" )); - idx = cf2_stack_popInt( opStack ); - val = cf2_stack_popFixed( opStack ); + FT_TRACE4(( " div\n" )); - if ( idx >= 0 && idx < CF2_STORAGE_SIZE ) - storage[idx] = val; - } - continue; /* do not clear the stack */ + divisor = cf2_stack_popFixed( opStack ); + dividend = cf2_stack_popFixed( opStack ); - case cf2_escGET: - { - CF2_Int idx; + cf2_stack_pushFixed( opStack, FT_DivFix( dividend, divisor ) ); + } + continue; /* do not clear the stack */ + case cf2_escNEG: + { + CF2_F16Dot16 arg; - FT_TRACE4(( " get\n" )); - idx = cf2_stack_popInt( opStack ); + FT_TRACE4(( " neg\n" )); - if ( idx >= 0 && idx < CF2_STORAGE_SIZE ) - cf2_stack_pushFixed( opStack, storage[idx] ); - } - continue; /* do not clear the stack */ + arg = cf2_stack_popFixed( opStack ); - case cf2_escIFELSE: - { - CF2_F16Dot16 arg1; - CF2_F16Dot16 arg2; - CF2_F16Dot16 cond1; - CF2_F16Dot16 cond2; + cf2_stack_pushFixed( opStack, -arg ); + } + continue; /* do not clear the stack */ + case cf2_escEQ: + { + CF2_F16Dot16 arg1; + CF2_F16Dot16 arg2; - FT_TRACE4(( " ifelse\n" )); - cond2 = cf2_stack_popFixed( opStack ); - cond1 = cf2_stack_popFixed( opStack ); - arg2 = cf2_stack_popFixed( opStack ); - arg1 = cf2_stack_popFixed( opStack ); + FT_TRACE4(( " eq\n" )); - cf2_stack_pushFixed( opStack, cond1 <= cond2 ? arg1 : arg2 ); - } - continue; /* do not clear the stack */ + arg2 = cf2_stack_popFixed( opStack ); + arg1 = cf2_stack_popFixed( opStack ); - case cf2_escRANDOM: /* in spec */ - FT_TRACE4(( " random\n" )); + cf2_stack_pushInt( opStack, arg1 == arg2 ); + } + continue; /* do not clear the stack */ - CF2_FIXME; - break; + case cf2_escDROP: + FT_TRACE4(( " drop\n" )); - case cf2_escMUL: - { - CF2_F16Dot16 factor1; - CF2_F16Dot16 factor2; + (void)cf2_stack_popFixed( opStack ); + continue; /* do not clear the stack */ + case cf2_escPUT: + { + CF2_F16Dot16 val; + CF2_Int idx; - FT_TRACE4(( " mul\n" )); - factor2 = cf2_stack_popFixed( opStack ); - factor1 = cf2_stack_popFixed( opStack ); + FT_TRACE4(( " put\n" )); - cf2_stack_pushFixed( opStack, FT_MulFix( factor1, factor2 ) ); - } - continue; /* do not clear the stack */ + idx = cf2_stack_popInt( opStack ); + val = cf2_stack_popFixed( opStack ); - case cf2_escSQRT: - { - CF2_F16Dot16 arg; + if ( idx >= 0 && idx < CF2_STORAGE_SIZE ) + storage[idx] = val; + } + continue; /* do not clear the stack */ + case cf2_escGET: + { + CF2_Int idx; - FT_TRACE4(( " sqrt\n" )); - arg = cf2_stack_popFixed( opStack ); - if ( arg > 0 ) - { - FT_Fixed root = arg; - FT_Fixed new_root; + FT_TRACE4(( " get\n" )); + idx = cf2_stack_popInt( opStack ); - /* Babylonian method */ - for (;;) - { - new_root = ( root + FT_DivFix( arg, root ) + 1 ) >> 1; - if ( new_root == root ) - break; - root = new_root; - } - arg = new_root; - } - else - arg = 0; + if ( idx >= 0 && idx < CF2_STORAGE_SIZE ) + cf2_stack_pushFixed( opStack, storage[idx] ); + } + continue; /* do not clear the stack */ - cf2_stack_pushFixed( opStack, arg ); - } - continue; /* do not clear the stack */ + case cf2_escIFELSE: + { + CF2_F16Dot16 arg1; + CF2_F16Dot16 arg2; + CF2_F16Dot16 cond1; + CF2_F16Dot16 cond2; - case cf2_escDUP: - { - CF2_F16Dot16 arg; + FT_TRACE4(( " ifelse\n" )); - FT_TRACE4(( " dup\n" )); + cond2 = cf2_stack_popFixed( opStack ); + cond1 = cf2_stack_popFixed( opStack ); + arg2 = cf2_stack_popFixed( opStack ); + arg1 = cf2_stack_popFixed( opStack ); - arg = cf2_stack_popFixed( opStack ); + cf2_stack_pushFixed( opStack, cond1 <= cond2 ? arg1 : arg2 ); + } + continue; /* do not clear the stack */ - cf2_stack_pushFixed( opStack, arg ); - cf2_stack_pushFixed( opStack, arg ); - } - continue; /* do not clear the stack */ + case cf2_escRANDOM: /* in spec */ + FT_TRACE4(( " random\n" )); - case cf2_escEXCH: - { - CF2_F16Dot16 arg1; - CF2_F16Dot16 arg2; + CF2_FIXME; + break; + case cf2_escMUL: + { + CF2_F16Dot16 factor1; + CF2_F16Dot16 factor2; - FT_TRACE4(( " exch\n" )); - arg2 = cf2_stack_popFixed( opStack ); - arg1 = cf2_stack_popFixed( opStack ); + FT_TRACE4(( " mul\n" )); - cf2_stack_pushFixed( opStack, arg2 ); - cf2_stack_pushFixed( opStack, arg1 ); - } - continue; /* do not clear the stack */ + factor2 = cf2_stack_popFixed( opStack ); + factor1 = cf2_stack_popFixed( opStack ); - case cf2_escINDEX: - { - CF2_Int idx; - CF2_UInt size; + cf2_stack_pushFixed( opStack, FT_MulFix( factor1, factor2 ) ); + } + continue; /* do not clear the stack */ + case cf2_escSQRT: + { + CF2_F16Dot16 arg; - FT_TRACE4(( " index\n" )); - idx = cf2_stack_popInt( opStack ); - size = cf2_stack_count( opStack ); + FT_TRACE4(( " sqrt\n" )); - if ( size > 0 ) - { - /* for `cf2_stack_getReal', index 0 is bottom of stack */ - CF2_UInt gr_idx; + arg = cf2_stack_popFixed( opStack ); + if ( arg > 0 ) + { + FT_Fixed root = arg; + FT_Fixed new_root; - if ( idx < 0 ) - gr_idx = size - 1; - else if ( (CF2_UInt)idx >= size ) - gr_idx = 0; - else - gr_idx = size - 1 - (CF2_UInt)idx; + /* Babylonian method */ + for (;;) + { + new_root = ( root + FT_DivFix( arg, root ) + 1 ) >> 1; + if ( new_root == root ) + break; + root = new_root; + } + arg = new_root; + } + else + arg = 0; - cf2_stack_pushFixed( opStack, - cf2_stack_getReal( opStack, gr_idx ) ); - } - } - continue; /* do not clear the stack */ + cf2_stack_pushFixed( opStack, arg ); + } + continue; /* do not clear the stack */ - case cf2_escROLL: - { - CF2_Int idx; - CF2_Int count; + case cf2_escDUP: + { + CF2_F16Dot16 arg; - FT_TRACE4(( " roll\n" )); + FT_TRACE4(( " dup\n" )); - idx = cf2_stack_popInt( opStack ); - count = cf2_stack_popInt( opStack ); + arg = cf2_stack_popFixed( opStack ); - cf2_stack_roll( opStack, count, idx ); - } - continue; /* do not clear the stack */ + cf2_stack_pushFixed( opStack, arg ); + cf2_stack_pushFixed( opStack, arg ); + } + continue; /* do not clear the stack */ - case cf2_escHFLEX: - { - static const FT_Bool readFromStack[12] = - { - TRUE /* dx1 */, FALSE /* dy1 */, - TRUE /* dx2 */, TRUE /* dy2 */, - TRUE /* dx3 */, FALSE /* dy3 */, - TRUE /* dx4 */, FALSE /* dy4 */, - TRUE /* dx5 */, FALSE /* dy5 */, - TRUE /* dx6 */, FALSE /* dy6 */ - }; + case cf2_escEXCH: + { + CF2_F16Dot16 arg1; + CF2_F16Dot16 arg2; - FT_TRACE4(( " hflex\n" )); + FT_TRACE4(( " exch\n" )); - cf2_doFlex( opStack, - &curX, - &curY, - &glyphPath, - readFromStack, - FALSE /* doConditionalLastRead */ ); - } - continue; + arg2 = cf2_stack_popFixed( opStack ); + arg1 = cf2_stack_popFixed( opStack ); - case cf2_escFLEX: - { - static const FT_Bool readFromStack[12] = - { - TRUE /* dx1 */, TRUE /* dy1 */, - TRUE /* dx2 */, TRUE /* dy2 */, - TRUE /* dx3 */, TRUE /* dy3 */, - TRUE /* dx4 */, TRUE /* dy4 */, - TRUE /* dx5 */, TRUE /* dy5 */, - TRUE /* dx6 */, TRUE /* dy6 */ - }; + cf2_stack_pushFixed( opStack, arg2 ); + cf2_stack_pushFixed( opStack, arg1 ); + } + continue; /* do not clear the stack */ + case cf2_escINDEX: + { + CF2_Int idx; + CF2_UInt size; - FT_TRACE4(( " flex\n" )); - cf2_doFlex( opStack, - &curX, - &curY, - &glyphPath, - readFromStack, - FALSE /* doConditionalLastRead */ ); - } - break; /* TODO: why is this not a continue? */ + FT_TRACE4(( " index\n" )); - case cf2_escHFLEX1: - { - static const FT_Bool readFromStack[12] = - { - TRUE /* dx1 */, TRUE /* dy1 */, - TRUE /* dx2 */, TRUE /* dy2 */, - TRUE /* dx3 */, FALSE /* dy3 */, - TRUE /* dx4 */, FALSE /* dy4 */, - TRUE /* dx5 */, TRUE /* dy5 */, - TRUE /* dx6 */, FALSE /* dy6 */ - }; + idx = cf2_stack_popInt( opStack ); + size = cf2_stack_count( opStack ); + if ( size > 0 ) + { + /* for `cf2_stack_getReal', index 0 is bottom of stack */ + CF2_UInt gr_idx; - FT_TRACE4(( " hflex1\n" )); - cf2_doFlex( opStack, - &curX, - &curY, - &glyphPath, - readFromStack, - FALSE /* doConditionalLastRead */ ); - } - continue; + if ( idx < 0 ) + gr_idx = size - 1; + else if ( (CF2_UInt)idx >= size ) + gr_idx = 0; + else + gr_idx = size - 1 - (CF2_UInt)idx; - case cf2_escFLEX1: - { - static const FT_Bool readFromStack[12] = - { - TRUE /* dx1 */, TRUE /* dy1 */, - TRUE /* dx2 */, TRUE /* dy2 */, - TRUE /* dx3 */, TRUE /* dy3 */, - TRUE /* dx4 */, TRUE /* dy4 */, - TRUE /* dx5 */, TRUE /* dy5 */, - FALSE /* dx6 */, FALSE /* dy6 */ - }; + cf2_stack_pushFixed( opStack, + cf2_stack_getReal( opStack, gr_idx ) ); + } + } + continue; /* do not clear the stack */ + case cf2_escROLL: + { + CF2_Int idx; + CF2_Int count; - FT_TRACE4(( " flex1\n" )); - cf2_doFlex( opStack, - &curX, - &curY, - &glyphPath, - readFromStack, - TRUE /* doConditionalLastRead */ ); - } - continue; + FT_TRACE4(( " roll\n" )); - case cf2_escRESERVED_1: - case cf2_escRESERVED_2: - case cf2_escRESERVED_6: - case cf2_escRESERVED_7: - case cf2_escRESERVED_8: - case cf2_escRESERVED_13: - case cf2_escRESERVED_16: - case cf2_escRESERVED_17: - case cf2_escRESERVED_19: - case cf2_escRESERVED_25: - case cf2_escRESERVED_31: - case cf2_escRESERVED_32: - case cf2_escRESERVED_33: - default: - FT_TRACE4(( " unknown op (12, %d)\n", op2 )); + idx = cf2_stack_popInt( opStack ); + count = cf2_stack_popInt( opStack ); - }; /* end of switch statement checking `op2' */ + cf2_stack_roll( opStack, count, idx ); + } + continue; /* do not clear the stack */ + } /* end of 2nd switch checking op2 */ + } + } + } /* end of 1st switch checking op2 */ } /* case cf2_cmdESC */ + break; case cf2_cmdENDCHAR: @@ -1290,7 +1426,8 @@ /* close path if still open */ cf2_glyphpath_closeOpenPath( &glyphPath ); - if ( cf2_stack_count( opStack ) > 1 ) + /* disable seac for CFF2 (charstring ending with args on stack) */ + if ( !font->isCFF2 && cf2_stack_count( opStack ) > 1 ) { /* must be either 4 or 5 -- */ /* this is a (deprecated) implied `seac' operator */ @@ -1528,7 +1665,7 @@ { x1 = cf2_stack_getReal( opStack, index ) + curX; - ++index; + index++; } else x1 = curX; @@ -1573,7 +1710,7 @@ { y1 = cf2_stack_getReal( opStack, index ) + curY; - ++index; + index++; } else y1 = curY; @@ -1601,7 +1738,7 @@ CF2_UInt count, count1 = cf2_stack_count( opStack ); CF2_UInt index = 0; - FT_Bool alternate = op1 == cf2_cmdHVCURVETO; + FT_Bool alternate = FT_BOOL( op1 == cf2_cmdHVCURVETO ); /* if `cf2_stack_count' isn't of the form 8n, 8n+1, */ @@ -1630,7 +1767,7 @@ { x3 = cf2_stack_getReal( opStack, index + 4 ) + x2; - ++index; + index++; } else x3 = x2; @@ -1649,7 +1786,7 @@ { y3 = cf2_stack_getReal( opStack, index + 4 ) + y2; - ++index; + index++; } else y3 = y2; @@ -1750,7 +1887,7 @@ ( byte3 << 8 ) | byte4 ); - FT_TRACE4(( " %.2f", v / 65536.0 )); + FT_TRACE4(( " %.5f", v / 65536.0 )); cf2_stack_pushFixed( opStack, v ); } @@ -1771,6 +1908,9 @@ /* check whether last error seen is also the first one */ cf2_setError( error, lastError ); + if ( *error ) + FT_TRACE4(( "charstring error %d\n", *error )); + /* free resources from objects we've used */ cf2_glyphpath_finalize( &glyphPath ); cf2_arrstack_finalize( &vStemHintArray ); Index: reactos/sdk/lib/3rdparty/freetype/src/cff/cf2stack.c =================================================================== --- reactos/sdk/lib/3rdparty/freetype/src/cff/cf2stack.c (revision 74184) +++ reactos/sdk/lib/3rdparty/freetype/src/cff/cf2stack.c (working copy) @@ -51,7 +51,8 @@ /* `error'). */ FT_LOCAL_DEF( CF2_Stack ) cf2_stack_init( FT_Memory memory, - FT_Error* e ) + FT_Error* e, + FT_UInt stackSize ) { FT_Error error = FT_Err_Ok; /* for FT_NEW */ @@ -63,9 +64,18 @@ /* initialize the structure; FT_NEW zeroes it */ stack->memory = memory; stack->error = e; - stack->top = &stack->buffer[0]; /* empty stack */ } + /* allocate the stack buffer */ + if ( FT_NEW_ARRAY( stack->buffer, stackSize ) ) + { + FT_FREE( stack ); + return NULL; + } + + stack->stackSize = stackSize; + stack->top = stack->buffer; /* empty stack */ + return stack; } @@ -77,6 +87,8 @@ { FT_Memory memory = stack->memory; + /* free the buffer */ + FT_FREE( stack->buffer ); /* free the main structure */ FT_FREE( stack ); @@ -87,7 +99,7 @@ FT_LOCAL_DEF( CF2_UInt ) cf2_stack_count( CF2_Stack stack ) { - return (CF2_UInt)( stack->top - &stack->buffer[0] ); + return (CF2_UInt)( stack->top - stack->buffer ); } @@ -95,7 +107,7 @@ cf2_stack_pushInt( CF2_Stack stack, CF2_Int val ) { - if ( stack->top == &stack->buffer[CF2_OPERAND_STACK_SIZE] ) + if ( stack->top == stack->buffer + stack->stackSize ) { CF2_SET_ERROR( stack->error, Stack_Overflow ); return; /* stack overflow */ @@ -103,7 +115,7 @@ stack->top->u.i = val; stack->top->type = CF2_NumberInt; - ++stack->top; + stack->top++; } @@ -111,7 +123,7 @@ cf2_stack_pushFixed( CF2_Stack stack, CF2_Fixed val ) { - if ( stack->top == &stack->buffer[CF2_OPERAND_STACK_SIZE] ) + if ( stack->top == stack->buffer + stack->stackSize ) { CF2_SET_ERROR( stack->error, Stack_Overflow ); return; /* stack overflow */ @@ -119,7 +131,7 @@ stack->top->u.r = val; stack->top->type = CF2_NumberFixed; - ++stack->top; + stack->top++; } @@ -127,7 +139,7 @@ FT_LOCAL_DEF( CF2_Int ) cf2_stack_popInt( CF2_Stack stack ) { - if ( stack->top == &stack->buffer[0] ) + if ( stack->top == stack->buffer ) { CF2_SET_ERROR( stack->error, Stack_Underflow ); return 0; /* underflow */ @@ -138,7 +150,7 @@ return 0; /* type mismatch */ } - --stack->top; + stack->top--; return stack->top->u.i; } @@ -149,13 +161,13 @@ FT_LOCAL_DEF( CF2_Fixed ) cf2_stack_popFixed( CF2_Stack stack ) { - if ( stack->top == &stack->buffer[0] ) + if ( stack->top == stack->buffer ) { CF2_SET_ERROR( stack->error, Stack_Underflow ); return cf2_intToFixed( 0 ); /* underflow */ } - --stack->top; + stack->top--; switch ( stack->top->type ) { @@ -175,7 +187,7 @@ cf2_stack_getReal( CF2_Stack stack, CF2_UInt idx ) { - FT_ASSERT( cf2_stack_count( stack ) <= CF2_OPERAND_STACK_SIZE ); + FT_ASSERT( cf2_stack_count( stack ) <= stack->stackSize ); if ( idx >= cf2_stack_count( stack ) ) { @@ -195,7 +207,38 @@ } - FT_LOCAL( void ) + /* provide random access to stack */ + FT_LOCAL_DEF( void ) + cf2_stack_setReal( CF2_Stack stack, + CF2_UInt idx, + CF2_Fixed val ) + { + if ( idx > cf2_stack_count( stack ) ) + { + CF2_SET_ERROR( stack->error, Stack_Overflow ); + return; + } + + stack->buffer[idx].u.r = val; + stack->buffer[idx].type = CF2_NumberFixed; + } + + + /* discard (pop) num values from stack */ + FT_LOCAL_DEF( void ) + cf2_stack_pop( CF2_Stack stack, + CF2_UInt num ) + { + if ( num > cf2_stack_count( stack ) ) + { + CF2_SET_ERROR( stack->error, Stack_Underflow ); + return; + } + stack->top -= num; + } + + + FT_LOCAL_DEF( void ) cf2_stack_roll( CF2_Stack stack, CF2_Int count, CF2_Int shift ) @@ -278,7 +321,7 @@ FT_LOCAL_DEF( void ) cf2_stack_clear( CF2_Stack stack ) { - stack->top = &stack->buffer[0]; + stack->top = stack->buffer; } Index: reactos/sdk/lib/3rdparty/freetype/src/cff/cf2stack.h =================================================================== --- reactos/sdk/lib/3rdparty/freetype/src/cff/cf2stack.h (revision 74184) +++ reactos/sdk/lib/3rdparty/freetype/src/cff/cf2stack.h (working copy) @@ -62,8 +62,9 @@ { FT_Memory memory; FT_Error* error; - CF2_StackNumber buffer[CF2_OPERAND_STACK_SIZE]; + CF2_StackNumber* buffer; CF2_StackNumber* top; + FT_UInt stackSize; } CF2_StackRec, *CF2_Stack; @@ -70,7 +71,8 @@ FT_LOCAL( CF2_Stack ) cf2_stack_init( FT_Memory memory, - FT_Error* error ); + FT_Error* error, + FT_UInt stackSize ); FT_LOCAL( void ) cf2_stack_free( CF2_Stack stack ); @@ -92,8 +94,16 @@ FT_LOCAL( CF2_Fixed ) cf2_stack_getReal( CF2_Stack stack, CF2_UInt idx ); + FT_LOCAL( void ) + cf2_stack_setReal( CF2_Stack stack, + CF2_UInt idx, + CF2_Fixed val ); FT_LOCAL( void ) + cf2_stack_pop( CF2_Stack stack, + CF2_UInt num ); + + FT_LOCAL( void ) cf2_stack_roll( CF2_Stack stack, CF2_Int count, CF2_Int idx ); Index: reactos/sdk/lib/3rdparty/freetype/src/cff/cffcmap.c =================================================================== --- reactos/sdk/lib/3rdparty/freetype/src/cff/cffcmap.c (revision 74184) +++ reactos/sdk/lib/3rdparty/freetype/src/cff/cffcmap.c (working copy) @@ -104,15 +104,21 @@ } - FT_DEFINE_CMAP_CLASS(cff_cmap_encoding_class_rec, + FT_DEFINE_CMAP_CLASS( + cff_cmap_encoding_class_rec, + sizeof ( CFF_CMapStdRec ), - (FT_CMap_InitFunc) cff_cmap_encoding_init, - (FT_CMap_DoneFunc) cff_cmap_encoding_done, - (FT_CMap_CharIndexFunc)cff_cmap_encoding_char_index, - (FT_CMap_CharNextFunc) cff_cmap_encoding_char_next, + (FT_CMap_InitFunc) cff_cmap_encoding_init, /* init */ + (FT_CMap_DoneFunc) cff_cmap_encoding_done, /* done */ + (FT_CMap_CharIndexFunc)cff_cmap_encoding_char_index, /* char_index */ + (FT_CMap_CharNextFunc) cff_cmap_encoding_char_next, /* char_next */ - NULL, NULL, NULL, NULL, NULL + (FT_CMap_CharVarIndexFunc) NULL, /* char_var_index */ + (FT_CMap_CharVarIsDefaultFunc)NULL, /* char_var_default */ + (FT_CMap_VariantListFunc) NULL, /* variant_list */ + (FT_CMap_CharVariantListFunc) NULL, /* charvariant_list */ + (FT_CMap_VariantCharListFunc) NULL /* variantchar_list */ ) @@ -202,15 +208,22 @@ } - FT_DEFINE_CMAP_CLASS(cff_cmap_unicode_class_rec, + FT_DEFINE_CMAP_CLASS( + cff_cmap_unicode_class_rec, + sizeof ( PS_UnicodesRec ), - (FT_CMap_InitFunc) cff_cmap_unicode_init, - (FT_CMap_DoneFunc) cff_cmap_unicode_done, - (FT_CMap_CharIndexFunc)cff_cmap_unicode_char_index, - (FT_CMap_CharNextFunc) cff_cmap_unicode_char_next, + (FT_CMap_InitFunc) cff_cmap_unicode_init, /* init */ + (FT_CMap_DoneFunc) cff_cmap_unicode_done, /* done */ + (FT_CMap_CharIndexFunc)cff_cmap_unicode_char_index, /* char_index */ + (FT_CMap_CharNextFunc) cff_cmap_unicode_char_next, /* char_next */ - NULL, NULL, NULL, NULL, NULL + (FT_CMap_CharVarIndexFunc) NULL, /* char_var_index */ + (FT_CMap_CharVarIsDefaultFunc)NULL, /* char_var_default */ + (FT_CMap_VariantListFunc) NULL, /* variant_list */ + (FT_CMap_CharVariantListFunc) NULL, /* charvariant_list */ + (FT_CMap_VariantCharListFunc) NULL /* variantchar_list */ ) + /* END */ Index: reactos/sdk/lib/3rdparty/freetype/src/cff/cffdrivr.c =================================================================== --- reactos/sdk/lib/3rdparty/freetype/src/cff/cffdrivr.c (revision 74184) +++ reactos/sdk/lib/3rdparty/freetype/src/cff/cffdrivr.c (working copy) @@ -32,6 +32,10 @@ #include "cffcmap.h" #include "cffparse.h" +#ifdef TT_CONFIG_OPTION_GX_VAR_SUPPORT +#include FT_SERVICE_MULTIPLE_MASTERS_H +#endif + #include "cfferrs.h" #include "cffpic.h" @@ -207,6 +211,13 @@ if ( flags & FT_LOAD_VERTICAL_LAYOUT ) { +#ifdef TT_CONFIG_OPTION_GX_VAR_SUPPORT + /* no fast retrieval for blended MM fonts without VVAR table */ + if ( !ttface->is_default_instance && + !( ttface->variation_support & TT_FACE_FLAG_VAR_VADVANCE ) ) + return FT_THROW( Unimplemented_Feature ); +#endif + /* check whether we have data from the `vmtx' table at all; */ /* otherwise we extract the info from the CFF glyphstrings */ /* (instead of synthesizing a global value using the `OS/2' */ @@ -232,6 +243,13 @@ } else { +#ifdef TT_CONFIG_OPTION_GX_VAR_SUPPORT + /* no fast retrieval for blended MM fonts without HVAR table */ + if ( !ttface->is_default_instance && + !( ttface->variation_support & TT_FACE_FLAG_VAR_HADVANCE ) ) + return FT_THROW( Unimplemented_Feature ); +#endif + /* check whether we have data from the `hmtx' table at all */ if ( !ttface->horizontal.number_Of_HMetrics ) goto Missing_Table; @@ -291,6 +309,35 @@ FT_Error error; + /* CFF2 table does not have glyph names; */ + /* we need to use `post' table method */ + if ( font->version_major == 2 ) + { + FT_Library library = FT_FACE_LIBRARY( face ); + FT_Module sfnt_module = FT_Get_Module( library, "sfnt" ); + FT_Service_GlyphDict service = + (FT_Service_GlyphDict)ft_module_get_service( + sfnt_module, + FT_SERVICE_ID_GLYPH_DICT, + 0 ); + + + if ( service && service->get_name ) + return service->get_name( FT_FACE( face ), + glyph_index, + buffer, + buffer_max ); + else + { + FT_ERROR(( "cff_get_glyph_name:" + " cannot get glyph name from a CFF2 font\n" + " " + " without the `PSNames' module\n" )); + error = FT_THROW( Missing_Module ); + goto Exit; + } + } + if ( !font->psnames ) { FT_ERROR(( "cff_get_glyph_name:" @@ -332,6 +379,31 @@ cff = (CFF_FontRec *)face->extra.data; charset = &cff->charset; + /* CFF2 table does not have glyph names; */ + /* we need to use `post' table method */ + if ( cff->version_major == 2 ) + { + FT_Library library = FT_FACE_LIBRARY( face ); + FT_Module sfnt_module = FT_Get_Module( library, "sfnt" ); + FT_Service_GlyphDict service = + (FT_Service_GlyphDict)ft_module_get_service( + sfnt_module, + FT_SERVICE_ID_GLYPH_DICT, + 0 ); + + + if ( service && service->name_index ) + return service->name_index( FT_FACE( face ), glyph_name ); + else + { + FT_ERROR(( "cff_get_name_index:" + " cannot get glyph index from a CFF2 font\n" + " " + " without the `PSNames' module\n" )); + return 0; + } + } + FT_FACE_FIND_GLOBAL_SERVICE( face, psnames, POSTSCRIPT_CMAPS ); if ( !psnames ) return 0; @@ -358,6 +430,7 @@ FT_DEFINE_SERVICE_GLYPHDICTREC( cff_service_glyph_dict, + (FT_GlyphDict_GetNameFunc) cff_get_glyph_name, /* get_name */ (FT_GlyphDict_NameIndexFunc)cff_get_name_index /* name_index */ ) @@ -383,11 +456,11 @@ FT_Error error = FT_Err_Ok; - if ( cff && cff->font_info == NULL ) + if ( cff && !cff->font_info ) { - CFF_FontRecDict dict = &cff->top_font.font_dict; + CFF_FontRecDict dict = &cff->top_font.font_dict; PS_FontInfoRec *font_info = NULL; - FT_Memory memory = face->root.memory; + FT_Memory memory = face->root.memory; if ( FT_ALLOC( font_info, sizeof ( *font_info ) ) ) @@ -421,6 +494,7 @@ FT_DEFINE_SERVICE_PSINFOREC( cff_service_ps_info, + (PS_GetFontInfoFunc) cff_ps_get_font_info, /* ps_get_font_info */ (PS_GetFontExtraFunc) NULL, /* ps_get_font_extra */ (PS_HasGlyphNamesFunc) cff_ps_has_glyph_names, /* ps_has_glyph_names */ @@ -453,7 +527,8 @@ FT_Service_PsFontName service = (FT_Service_PsFontName)ft_module_get_service( sfnt_module, - FT_SERVICE_ID_POSTSCRIPT_FONT_NAME ); + FT_SERVICE_ID_POSTSCRIPT_FONT_NAME, + 0 ); if ( service && service->get_ps_font_name ) @@ -466,6 +541,7 @@ FT_DEFINE_SERVICE_PSFONTNAMEREC( cff_service_ps_name, + (FT_PsName_GetFunc)cff_get_ps_name /* get_ps_font_name */ ) @@ -491,9 +567,6 @@ FT_Library library = FT_FACE_LIBRARY( face ); - cmap_info->language = 0; - cmap_info->format = 0; - if ( cmap->clazz != &CFF_CMAP_ENCODING_CLASS_REC_GET && cmap->clazz != &CFF_CMAP_UNICODE_CLASS_REC_GET ) { @@ -500,12 +573,15 @@ FT_Module sfnt = FT_Get_Module( library, "sfnt" ); FT_Service_TTCMaps service = (FT_Service_TTCMaps)ft_module_get_service( sfnt, - FT_SERVICE_ID_TT_CMAP ); + FT_SERVICE_ID_TT_CMAP, + 0 ); if ( service && service->get_cmap_info ) error = service->get_cmap_info( charmap, cmap_info ); } + else + error = FT_THROW( Invalid_CharMap_Format ); return error; } @@ -513,6 +589,7 @@ FT_DEFINE_SERVICE_TTCMAPSREC( cff_service_get_cmap_info, + (TT_CMap_Info_GetFunc)cff_get_cmap_info /* get_cmap_info */ ) @@ -544,7 +621,7 @@ if ( registry ) { - if ( cff->registry == NULL ) + if ( !cff->registry ) cff->registry = cff_index_get_sid_string( cff, dict->cid_registry ); *registry = cff->registry; @@ -552,7 +629,7 @@ if ( ordering ) { - if ( cff->ordering == NULL ) + if ( !cff->ordering ) cff->ordering = cff_index_get_sid_string( cff, dict->cid_ordering ); *ordering = cff->ordering; @@ -643,6 +720,7 @@ FT_DEFINE_SERVICE_CIDREC( cff_service_cid_info, + (FT_CID_GetRegistryOrderingSupplementFunc) cff_get_ros, /* get_ros */ (FT_CID_GetIsInternallyCIDKeyedFunc) @@ -855,10 +933,94 @@ FT_DEFINE_SERVICE_PROPERTIESREC( cff_service_properties, + (FT_Properties_SetFunc)cff_property_set, /* set_property */ (FT_Properties_GetFunc)cff_property_get ) /* get_property */ +#ifdef TT_CONFIG_OPTION_GX_VAR_SUPPORT + + /* + * MULTIPLE MASTER SERVICE + * + */ + + static FT_Error + cff_set_mm_blend( CFF_Face face, + FT_UInt num_coords, + FT_Fixed* coords ) + { + FT_Service_MultiMasters mm = (FT_Service_MultiMasters)face->mm; + + + return mm->set_mm_blend( FT_FACE( face ), num_coords, coords ); + } + + + static FT_Error + cff_get_mm_blend( CFF_Face face, + FT_UInt num_coords, + FT_Fixed* coords ) + { + FT_Service_MultiMasters mm = (FT_Service_MultiMasters)face->mm; + + + return mm->get_mm_blend( FT_FACE( face ), num_coords, coords ); + } + + + static FT_Error + cff_get_mm_var( CFF_Face face, + FT_MM_Var* *master ) + { + FT_Service_MultiMasters mm = (FT_Service_MultiMasters)face->mm; + + + return mm->get_mm_var( FT_FACE( face ), master ); + } + + + static FT_Error + cff_set_var_design( CFF_Face face, + FT_UInt num_coords, + FT_Fixed* coords ) + { + FT_Service_MultiMasters mm = (FT_Service_MultiMasters)face->mm; + + + return mm->set_var_design( FT_FACE( face ), num_coords, coords ); + } + + + static FT_Error + cff_get_var_design( CFF_Face face, + FT_UInt num_coords, + FT_Fixed* coords ) + { + FT_Service_MultiMasters mm = (FT_Service_MultiMasters)face->mm; + + + return mm->get_var_design( FT_FACE( face ), num_coords, coords ); + } + + + FT_DEFINE_SERVICE_MULTIMASTERSREC( + cff_service_multi_masters, + + (FT_Get_MM_Func) NULL, /* get_mm */ + (FT_Set_MM_Design_Func) NULL, /* set_mm_design */ + (FT_Set_MM_Blend_Func) cff_set_mm_blend, /* set_mm_blend */ + (FT_Get_MM_Blend_Func) cff_get_mm_blend, /* get_mm_blend */ + (FT_Get_MM_Var_Func) cff_get_mm_var, /* get_mm_var */ + (FT_Set_Var_Design_Func)cff_set_var_design, /* set_var_design */ + (FT_Get_Var_Design_Func)cff_get_var_design, /* get_var_design */ + + (FT_Get_Var_Blend_Func) cff_get_var_blend, /* get_var_blend */ + (FT_Done_Blend_Func) cff_done_blend /* done_blend */ + ) +#endif + + /*************************************************************************/ /*************************************************************************/ /*************************************************************************/ @@ -871,9 +1033,24 @@ /*************************************************************************/ /*************************************************************************/ -#ifndef FT_CONFIG_OPTION_NO_GLYPH_NAMES +#if !defined FT_CONFIG_OPTION_NO_GLYPH_NAMES && \ + defined TT_CONFIG_OPTION_GX_VAR_SUPPORT + FT_DEFINE_SERVICEDESCREC8( + cff_services, + + FT_SERVICE_ID_FONT_FORMAT, FT_FONT_FORMAT_CFF, + FT_SERVICE_ID_MULTI_MASTERS, &CFF_SERVICE_MULTI_MASTERS_GET, + FT_SERVICE_ID_POSTSCRIPT_INFO, &CFF_SERVICE_PS_INFO_GET, + FT_SERVICE_ID_POSTSCRIPT_FONT_NAME, &CFF_SERVICE_PS_NAME_GET, + FT_SERVICE_ID_GLYPH_DICT, &CFF_SERVICE_GLYPH_DICT_GET, + FT_SERVICE_ID_TT_CMAP, &CFF_SERVICE_GET_CMAP_INFO_GET, + FT_SERVICE_ID_CID, &CFF_SERVICE_CID_INFO_GET, + FT_SERVICE_ID_PROPERTIES, &CFF_SERVICE_PROPERTIES_GET + ) +#elif !defined FT_CONFIG_OPTION_NO_GLYPH_NAMES FT_DEFINE_SERVICEDESCREC7( cff_services, + FT_SERVICE_ID_FONT_FORMAT, FT_FONT_FORMAT_CFF, FT_SERVICE_ID_POSTSCRIPT_INFO, &CFF_SERVICE_PS_INFO_GET, FT_SERVICE_ID_POSTSCRIPT_FONT_NAME, &CFF_SERVICE_PS_NAME_GET, @@ -882,9 +1059,22 @@ FT_SERVICE_ID_CID, &CFF_SERVICE_CID_INFO_GET, FT_SERVICE_ID_PROPERTIES, &CFF_SERVICE_PROPERTIES_GET ) +#elif defined TT_CONFIG_OPTION_GX_VAR_SUPPORT + FT_DEFINE_SERVICEDESCREC7( + cff_services, + + FT_SERVICE_ID_FONT_FORMAT, FT_FONT_FORMAT_CFF, + FT_SERVICE_ID_MULTI_MASTERS, &CFF_SERVICE_MULTI_MASTERS_GET, + FT_SERVICE_ID_POSTSCRIPT_INFO, &CFF_SERVICE_PS_INFO_GET, + FT_SERVICE_ID_POSTSCRIPT_FONT_NAME, &CFF_SERVICE_PS_NAME_GET, + FT_SERVICE_ID_TT_CMAP, &CFF_SERVICE_GET_CMAP_INFO_GET, + FT_SERVICE_ID_CID, &CFF_SERVICE_CID_INFO_GET, + FT_SERVICE_ID_PROPERTIES, &CFF_SERVICE_PROPERTIES_GET + ) #else FT_DEFINE_SERVICEDESCREC6( cff_services, + FT_SERVICE_ID_FONT_FORMAT, FT_FONT_FORMAT_CFF, FT_SERVICE_ID_POSTSCRIPT_INFO, &CFF_SERVICE_PS_INFO_GET, FT_SERVICE_ID_POSTSCRIPT_FONT_NAME, &CFF_SERVICE_PS_NAME_GET, @@ -914,7 +1104,7 @@ #endif result = ft_service_list_lookup( CFF_SERVICES_GET, module_interface ); - if ( result != NULL ) + if ( result ) return result; /* `driver' is not yet evaluated in non-PIC mode */ @@ -954,7 +1144,7 @@ 0x10000L, 0x20000L, - 0, /* module-specific interface */ + NULL, /* module-specific interface */ cff_driver_init, /* FT_Module_Constructor module_init */ cff_driver_done, /* FT_Module_Destructor module_done */ @@ -974,7 +1164,7 @@ cff_glyph_load, /* FT_Slot_LoadFunc load_glyph */ cff_get_kerning, /* FT_Face_GetKerningFunc get_kerning */ - 0, /* FT_Face_AttachFunc attach_file */ + NULL, /* FT_Face_AttachFunc attach_file */ cff_get_advances, /* FT_Face_GetAdvancesFunc get_advances */ cff_size_request, /* FT_Size_RequestFunc request_size */ Index: reactos/sdk/lib/3rdparty/freetype/src/cff/cffgload.c =================================================================== --- reactos/sdk/lib/3rdparty/freetype/src/cff/cffgload.c (revision 74184) +++ reactos/sdk/lib/3rdparty/freetype/src/cff/cffgload.c (working copy) @@ -391,7 +391,7 @@ /* clear everything */ - FT_MEM_ZERO( decoder, sizeof ( *decoder ) ); + FT_ZERO( decoder ); /* initialize builder */ cff_builder_init( &decoder->builder, face, size, slot, hinting ); @@ -1026,7 +1026,7 @@ if ( !( val & 0xFFFFL ) ) FT_TRACE4(( " %hd", (FT_Short)( (FT_UInt32)val >> 16 ) )); else - FT_TRACE4(( " %.2f", val / 65536.0 )); + FT_TRACE4(( " %.5f", val / 65536.0 )); #endif } @@ -2445,7 +2445,7 @@ case cff_op_and: { - FT_Fixed cond = args[0] && args[1]; + FT_Fixed cond = ( args[0] && args[1] ); FT_TRACE4(( " and\n" )); @@ -2457,7 +2457,7 @@ case cff_op_or: { - FT_Fixed cond = args[0] || args[1]; + FT_Fixed cond = ( args[0] || args[1] ); FT_TRACE4(( " or\n" )); @@ -2481,7 +2481,7 @@ case cff_op_eq: { - FT_Fixed cond = args[0] == args[1]; + FT_Fixed cond = ( args[0] == args[1] ); FT_TRACE4(( " eq\n" )); Index: reactos/sdk/lib/3rdparty/freetype/src/cff/cffload.c =================================================================== --- reactos/sdk/lib/3rdparty/freetype/src/cff/cffload.c (revision 74184) +++ reactos/sdk/lib/3rdparty/freetype/src/cff/cffload.c (working copy) @@ -23,6 +23,11 @@ #include FT_TRUETYPE_TAGS_H #include FT_TYPE1_TABLES_H +#ifdef TT_CONFIG_OPTION_GX_VAR_SUPPORT +#include FT_MULTIPLE_MASTERS_H +#include FT_SERVICE_MULTIPLE_MASTERS_H +#endif + #include "cffload.h" #include "cffparse.h" @@ -29,6 +34,9 @@ #include "cfferrs.h" +#define FT_FIXED_ONE ( (FT_Fixed)0x10000 ) + + #if 1 static const FT_UShort cff_isoadobe_charset[229] = @@ -225,20 +233,34 @@ static FT_Error cff_index_init( CFF_Index idx, FT_Stream stream, - FT_Bool load ) + FT_Bool load, + FT_Bool cff2 ) { FT_Error error; FT_Memory memory = stream->memory; - FT_UShort count; + FT_UInt count; - FT_MEM_ZERO( idx, sizeof ( *idx ) ); + FT_ZERO( idx ); idx->stream = stream; idx->start = FT_STREAM_POS(); - if ( !FT_READ_USHORT( count ) && - count > 0 ) + + if ( cff2 ) { + if ( FT_READ_ULONG( count ) ) + goto Exit; + idx->hdr_size = 5; + } + else + { + if ( FT_READ_USHORT( count ) ) + goto Exit; + idx->hdr_size = 3; + } + + if ( count > 0 ) + { FT_Byte offsize; FT_ULong size; @@ -258,7 +280,7 @@ idx->off_size = offsize; size = (FT_ULong)( count + 1 ) * offsize; - idx->data_offset = idx->start + 3 + size; + idx->data_offset = idx->start + idx->hdr_size + size; if ( FT_STREAM_SKIP( size - offsize ) ) goto Exit; @@ -310,7 +332,7 @@ FT_FRAME_RELEASE( idx->bytes ); FT_FREE( idx->offsets ); - FT_MEM_ZERO( idx, sizeof ( *idx ) ); + FT_ZERO( idx ); } } @@ -323,7 +345,7 @@ FT_Memory memory = stream->memory; - if ( idx->count > 0 && idx->offsets == NULL ) + if ( idx->count > 0 && !idx->offsets ) { FT_Byte offsize = idx->off_size; FT_ULong data_size; @@ -335,7 +357,7 @@ data_size = (FT_ULong)( idx->count + 1 ) * offsize; if ( FT_NEW_ARRAY( idx->offsets, idx->count + 1 ) || - FT_STREAM_SEEK( idx->start + 3 ) || + FT_STREAM_SEEK( idx->start + idx->hdr_size ) || FT_FRAME_ENTER( data_size ) ) goto Exit; @@ -395,7 +417,7 @@ *table = NULL; - if ( idx->offsets == NULL ) + if ( !idx->offsets ) { error = cff_index_load_offsets( idx ); if ( error ) @@ -493,7 +515,7 @@ FT_ULong pos = element * idx->off_size; - if ( FT_STREAM_SEEK( idx->start + 3 + pos ) ) + if ( FT_STREAM_SEEK( idx->start + idx->hdr_size + pos ) ) goto Exit; off1 = cff_index_read_offset( idx, &error ); @@ -589,7 +611,7 @@ FT_UInt element ) { CFF_Index idx = &font->name_index; - FT_Memory memory = idx->stream->memory; + FT_Memory memory; FT_Byte* bytes; FT_ULong byte_len; FT_Error error; @@ -596,6 +618,11 @@ FT_String* name = 0; + if ( !idx->stream ) /* CFF2 does not include a name index */ + goto Exit; + + memory = idx->stream->memory; + error = cff_index_access_element( idx, element, &bytes, &byte_len ); if ( error ) goto Exit; @@ -725,6 +752,11 @@ FT_Byte fd = 0; + /* if there is no FDSelect, return zero */ + /* Note: CFF2 with just one Font Dict has no FDSelect */ + if ( !fdselect->data ) + goto Exit; + switch ( fdselect->format ) { case 0: @@ -777,6 +809,7 @@ ; } + Exit: return fd; } @@ -1055,6 +1088,491 @@ static void + cff_vstore_done( CFF_VStoreRec* vstore, + FT_Memory memory ) + { + FT_UInt i; + + + /* free regionList and axisLists */ + if ( vstore->varRegionList ) + { + for ( i = 0; i < vstore->regionCount; i++ ) + FT_FREE( vstore->varRegionList[i].axisList ); + } + FT_FREE( vstore->varRegionList ); + + /* free varData and indices */ + if ( vstore->varData ) + { + for ( i = 0; i < vstore->dataCount; i++ ) + FT_FREE( vstore->varData[i].regionIndices ); + } + FT_FREE( vstore->varData ); + } + + + /* convert 2.14 to Fixed */ + #define FT_fdot14ToFixed( x ) ( ( (FT_Fixed)( (FT_Int16)(x) ) ) << 2 ) + + + static FT_Error + cff_vstore_load( CFF_VStoreRec* vstore, + FT_Stream stream, + FT_ULong base_offset, + FT_ULong offset ) + { + FT_Memory memory = stream->memory; + FT_Error error = FT_ERR( Invalid_File_Format ); + + FT_ULong* dataOffsetArray = NULL; + FT_UInt i, j; + + + /* no offset means no vstore to parse */ + if ( offset ) + { + FT_UInt vsOffset; + FT_UInt format; + FT_ULong regionListOffset; + + + /* we need to parse the table to determine its size; */ + /* skip table length */ + if ( FT_STREAM_SEEK( base_offset + offset ) || + FT_STREAM_SKIP( 2 ) ) + goto Exit; + + /* actual variation store begins after the length */ + vsOffset = FT_STREAM_POS(); + + /* check the header */ + if ( FT_READ_USHORT( format ) ) + goto Exit; + if ( format != 1 ) + { + error = FT_THROW( Invalid_File_Format ); + goto Exit; + } + + /* read top level fields */ + if ( FT_READ_ULONG( regionListOffset ) || + FT_READ_USHORT( vstore->dataCount ) ) + goto Exit; + + /* make temporary copy of item variation data offsets; */ + /* we'll parse region list first, then come back */ + if ( FT_NEW_ARRAY( dataOffsetArray, vstore->dataCount ) ) + goto Exit; + + for ( i = 0; i < vstore->dataCount; i++ ) + { + if ( FT_READ_ULONG( dataOffsetArray[i] ) ) + goto Exit; + } + + /* parse regionList and axisLists */ + if ( FT_STREAM_SEEK( vsOffset + regionListOffset ) || + FT_READ_USHORT( vstore->axisCount ) || + FT_READ_USHORT( vstore->regionCount ) ) + goto Exit; + + if ( FT_NEW_ARRAY( vstore->varRegionList, vstore->regionCount ) ) + goto Exit; + + for ( i = 0; i < vstore->regionCount; i++ ) + { + CFF_VarRegion* region = &vstore->varRegionList[i]; + + + if ( FT_NEW_ARRAY( region->axisList, vstore->axisCount ) ) + goto Exit; + + for ( j = 0; j < vstore->axisCount; j++ ) + { + CFF_AxisCoords* axis = ®ion->axisList[j]; + + FT_Int16 start14, peak14, end14; + + + if ( FT_READ_SHORT( start14 ) || + FT_READ_SHORT( peak14 ) || + FT_READ_SHORT( end14 ) ) + goto Exit; + + axis->startCoord = FT_fdot14ToFixed( start14 ); + axis->peakCoord = FT_fdot14ToFixed( peak14 ); + axis->endCoord = FT_fdot14ToFixed( end14 ); + } + } + + /* use dataOffsetArray now to parse varData items */ + if ( FT_NEW_ARRAY( vstore->varData, vstore->dataCount ) ) + goto Exit; + + for ( i = 0; i < vstore->dataCount; i++ ) + { + CFF_VarData* data = &vstore->varData[i]; + + + if ( FT_STREAM_SEEK( vsOffset + dataOffsetArray[i] ) ) + goto Exit; + + /* ignore `itemCount' and `shortDeltaCount' */ + /* because CFF2 has no delta sets */ + if ( FT_STREAM_SKIP( 4 ) ) + goto Exit; + + /* Note: just record values; consistency is checked later */ + /* by cff_blend_build_vector when it consumes `vstore' */ + + if ( FT_READ_USHORT( data->regionIdxCount ) ) + goto Exit; + + if ( FT_NEW_ARRAY( data->regionIndices, data->regionIdxCount ) ) + goto Exit; + + for ( j = 0; j < data->regionIdxCount; j++ ) + { + if ( FT_READ_USHORT( data->regionIndices[j] ) ) + goto Exit; + } + } + } + + error = FT_Err_Ok; + + Exit: + FT_FREE( dataOffsetArray ); + if ( error ) + cff_vstore_done( vstore, memory ); + + return error; + } + + + /* Clear blend stack (after blend values are consumed). */ + /* */ + /* TODO: Should do this in cff_run_parse, but subFont */ + /* ref is not available there. */ + /* */ + /* Allocation is not changed when stack is cleared. */ + FT_LOCAL_DEF( void ) + cff_blend_clear( CFF_SubFont subFont ) + { + subFont->blend_top = subFont->blend_stack; + subFont->blend_used = 0; + } + + + /* Blend numOperands on the stack, */ + /* store results into the first numBlends values, */ + /* then pop remaining arguments. */ + /* */ + /* This is comparable to `cf2_doBlend' but */ + /* the cffparse stack is different and can't be written. */ + /* Blended values are written to a different buffer, */ + /* using reserved operator 255. */ + /* */ + /* Blend calculation is done in 16.16 fixed point. */ + FT_LOCAL_DEF( FT_Error ) + cff_blend_doBlend( CFF_SubFont subFont, + CFF_Parser parser, + FT_UInt numBlends ) + { + FT_UInt delta; + FT_UInt base; + FT_UInt i, j; + FT_UInt size; + + CFF_Blend blend = &subFont->blend; + + FT_Memory memory = subFont->blend.font->memory; /* for FT_REALLOC */ + FT_Error error = FT_Err_Ok; /* for FT_REALLOC */ + + /* compute expected number of operands for this blend */ + FT_UInt numOperands = (FT_UInt)( numBlends * blend->lenBV ); + FT_UInt count = (FT_UInt)( parser->top - 1 - parser->stack ); + + + if ( numOperands > count ) + { + FT_TRACE4(( " cff_blend_doBlend: Stack underflow %d args\n", count )); + + error = FT_THROW( Stack_Underflow ); + goto Exit; + } + + /* check whether we have room for `numBlends' values at `blend_top' */ + size = 5 * numBlends; /* add 5 bytes per entry */ + if ( subFont->blend_used + size > subFont->blend_alloc ) + { + /* increase or allocate `blend_stack' and reset `blend_top'; */ + /* prepare to append `numBlends' values to the buffer */ + if ( FT_REALLOC( subFont->blend_stack, + subFont->blend_alloc, + subFont->blend_alloc + size ) ) + goto Exit; + + subFont->blend_top = subFont->blend_stack + subFont->blend_used; + subFont->blend_alloc += size; + } + subFont->blend_used += size; + + base = count - numOperands; /* index of first blend arg */ + delta = base + numBlends; /* index of first delta arg */ + + for ( i = 0; i < numBlends; i++ ) + { + const FT_Int32* weight = &blend->BV[1]; + FT_Int32 sum; + + + /* convert inputs to 16.16 fixed point */ + sum = cff_parse_num( parser, &parser->stack[i + base] ) << 16; + + for ( j = 1; j < blend->lenBV; j++ ) + sum += FT_MulFix( *weight++, + cff_parse_num( parser, + &parser->stack[delta++] ) << 16 ); + + /* point parser stack to new value on blend_stack */ + parser->stack[i + base] = subFont->blend_top; + + /* Push blended result as Type 2 5-byte fixed point number (except */ + /* that host byte order is used). This will not conflict with */ + /* actual DICTs because 255 is a reserved opcode in both CFF and */ + /* CFF2 DICTs. See `cff_parse_num' for decode of this, which rounds */ + /* to an integer. */ + *subFont->blend_top++ = 255; + *((FT_UInt32*)subFont->blend_top) = (FT_UInt32)sum; /* write 4 bytes */ + subFont->blend_top += 4; + } + + /* leave only numBlends results on parser stack */ + parser->top = &parser->stack[base + numBlends]; + + Exit: + return error; + } + + + /* Compute a blend vector from variation store index and normalized */ + /* vector based on pseudo-code in OpenType Font Variations Overview. */ + /* */ + /* Note: lenNDV == 0 produces a default blend vector, (1,0,0,...). */ + FT_LOCAL_DEF( FT_Error ) + cff_blend_build_vector( CFF_Blend blend, + FT_UInt vsindex, + FT_UInt lenNDV, + FT_Fixed* NDV ) + { + FT_Error error = FT_Err_Ok; /* for FT_REALLOC */ + FT_Memory memory = blend->font->memory; /* for FT_REALLOC */ + + FT_UInt len; + CFF_VStore vs; + CFF_VarData* varData; + FT_UInt master; + + + FT_ASSERT( lenNDV == 0 || NDV ); + + blend->builtBV = FALSE; + + vs = &blend->font->vstore; + + /* VStore and fvar must be consistent */ + if ( lenNDV != 0 && lenNDV != vs->axisCount ) + { + FT_TRACE4(( " cff_blend_build_vector: Axis count mismatch\n" )); + error = FT_THROW( Invalid_File_Format ); + goto Exit; + } + + if ( vsindex >= vs->dataCount ) + { + FT_TRACE4(( " cff_blend_build_vector: vsindex out of range\n" )); + error = FT_THROW( Invalid_File_Format ); + goto Exit; + } + + /* select the item variation data structure */ + varData = &vs->varData[vsindex]; + + /* prepare buffer for the blend vector */ + len = varData->regionIdxCount + 1; /* add 1 for default component */ + if ( FT_REALLOC( blend->BV, + blend->lenBV * sizeof( *blend->BV ), + len * sizeof( *blend->BV ) ) ) + goto Exit; + + blend->lenBV = len; + + /* outer loop steps through master designs to be blended */ + for ( master = 0; master < len; master++ ) + { + FT_UInt j; + FT_UInt idx; + CFF_VarRegion* varRegion; + + + /* default factor is always one */ + if ( master == 0 ) + { + blend->BV[master] = FT_FIXED_ONE; + FT_TRACE4(( " build blend vector len %d\n" + " [ %f ", + len, + blend->BV[master] / 65536.0 )); + continue; + } + + /* VStore array does not include default master, so subtract one */ + idx = varData->regionIndices[master - 1]; + varRegion = &vs->varRegionList[idx]; + + if ( idx >= vs->regionCount ) + { + FT_TRACE4(( " cff_blend_build_vector:" + " region index out of range\n" )); + error = FT_THROW( Invalid_File_Format ); + goto Exit; + } + + /* Note: `lenNDV' could be zero. */ + /* In that case, build default blend vector (1,0,0...). */ + /* In the normal case, initialize each component to 1 */ + /* before inner loop. */ + if ( lenNDV != 0 ) + blend->BV[master] = FT_FIXED_ONE; /* default */ + + /* inner loop steps through axes in this region */ + for ( j = 0; j < lenNDV; j++ ) + { + CFF_AxisCoords* axis = &varRegion->axisList[j]; + FT_Fixed axisScalar; + + + /* compute the scalar contribution of this axis; */ + /* ignore invalid ranges */ + if ( axis->startCoord > axis->peakCoord || + axis->peakCoord > axis->endCoord ) + axisScalar = FT_FIXED_ONE; + + else if ( axis->startCoord < 0 && + axis->endCoord > 0 && + axis->peakCoord != 0 ) + axisScalar = FT_FIXED_ONE; + + /* peak of 0 means ignore this axis */ + else if ( axis->peakCoord == 0 ) + axisScalar = FT_FIXED_ONE; + + /* ignore this region if coords are out of range */ + else if ( NDV[j] < axis->startCoord || + NDV[j] > axis->endCoord ) + axisScalar = 0; + + /* calculate a proportional factor */ + else + { + if ( NDV[j] == axis->peakCoord ) + axisScalar = FT_FIXED_ONE; + else if ( NDV[j] < axis->peakCoord ) + axisScalar = FT_DivFix( NDV[j] - axis->startCoord, + axis->peakCoord - axis->startCoord ); + else + axisScalar = FT_DivFix( axis->endCoord - NDV[j], + axis->endCoord - axis->peakCoord ); + } + + /* take product of all the axis scalars */ + blend->BV[master] = FT_MulFix( blend->BV[master], axisScalar ); + } + + FT_TRACE4(( ", %f ", + blend->BV[master] / 65536.0 )); + } + + FT_TRACE4(( "]\n" )); + + /* record the parameters used to build the blend vector */ + blend->lastVsindex = vsindex; + + if ( lenNDV != 0 ) + { + /* user has set a normalized vector */ + if ( FT_REALLOC( blend->lastNDV, + blend->lenNDV * sizeof ( *NDV ), + lenNDV * sizeof ( *NDV ) ) ) + goto Exit; + + blend->lenNDV = lenNDV; + FT_MEM_COPY( blend->lastNDV, + NDV, + lenNDV * sizeof ( *NDV ) ); + } + + blend->builtBV = TRUE; + + Exit: + return error; + } + + + /* `lenNDV' is zero for default vector; */ + /* return TRUE if blend vector needs to be built. */ + FT_LOCAL_DEF( FT_Bool ) + cff_blend_check_vector( CFF_Blend blend, + FT_UInt vsindex, + FT_UInt lenNDV, + FT_Fixed* NDV ) + { + if ( !blend->builtBV || + blend->lastVsindex != vsindex || + blend->lenNDV != lenNDV || + ( lenNDV && + memcmp( NDV, + blend->lastNDV, + lenNDV * sizeof ( *NDV ) ) != 0 ) ) + { + /* need to build blend vector */ + return TRUE; + } + + return FALSE; + } + + +#ifdef TT_CONFIG_OPTION_GX_VAR_SUPPORT + + FT_LOCAL_DEF( FT_Error ) + cff_get_var_blend( CFF_Face face, + FT_UInt *num_coords, + FT_Fixed* *coords, + FT_MM_Var* *mm_var ) + { + FT_Service_MultiMasters mm = (FT_Service_MultiMasters)face->mm; + + + return mm->get_var_blend( FT_FACE( face ), num_coords, coords, mm_var ); + } + + + FT_LOCAL_DEF( void ) + cff_done_blend( CFF_Face face ) + { + FT_Service_MultiMasters mm = (FT_Service_MultiMasters)face->mm; + + + mm->done_blend( FT_FACE( face ) ); + } + +#endif /* TT_CONFIG_OPTION_GX_VAR_SUPPORT */ + + + static void cff_encoding_done( CFF_Encoding encoding ) { encoding->format = 0; @@ -1306,31 +1824,127 @@ } + /* Parse private dictionary; first call is always from `cff_face_init', */ + /* so NDV has not been set for CFF2 variation. */ + /* */ + /* `cff_slot_load' must call this function each time NDV changes. */ + FT_LOCAL_DEF( FT_Error ) + cff_load_private_dict( CFF_Font font, + CFF_SubFont subfont, + FT_UInt lenNDV, + FT_Fixed* NDV ) + { + FT_Error error = FT_Err_Ok; + CFF_ParserRec parser; + CFF_FontRecDict top = &subfont->font_dict; + CFF_Private priv = &subfont->private_dict; + FT_Stream stream = font->stream; + FT_UInt stackSize; + + + /* store handle needed to access memory, vstore for blend; */ + /* we need this for clean-up even if there is no private DICT */ + subfont->blend.font = font; + subfont->blend.usedBV = FALSE; /* clear state */ + + if ( !top->private_offset || !top->private_size ) + goto Exit2; /* no private DICT, do nothing */ + + /* set defaults */ + FT_ZERO( priv ); + + priv->blue_shift = 7; + priv->blue_fuzz = 1; + priv->lenIV = -1; + priv->expansion_factor = (FT_Fixed)( 0.06 * 0x10000L ); + priv->blue_scale = (FT_Fixed)( 0.039625 * 0x10000L * 1000 ); + + /* provide inputs for blend calculations */ + priv->subfont = subfont; + subfont->lenNDV = lenNDV; + subfont->NDV = NDV; + + stackSize = font->cff2 ? font->top_font.font_dict.maxstack + : CFF_MAX_STACK_DEPTH + 1; + + if ( cff_parser_init( &parser, + font->cff2 ? CFF2_CODE_PRIVATE : CFF_CODE_PRIVATE, + priv, + font->library, + stackSize, + top->num_designs, + top->num_axes ) ) + goto Exit; + + if ( FT_STREAM_SEEK( font->base_offset + top->private_offset ) || + FT_FRAME_ENTER( top->private_size ) ) + goto Exit; + + FT_TRACE4(( " private dictionary:\n" )); + error = cff_parser_run( &parser, + (FT_Byte*)stream->cursor, + (FT_Byte*)stream->limit ); + FT_FRAME_EXIT(); + + if ( error ) + goto Exit; + + /* ensure that `num_blue_values' is even */ + priv->num_blue_values &= ~1; + + Exit: + /* clean up */ + cff_blend_clear( subfont ); /* clear blend stack */ + cff_parser_done( &parser ); /* free parser stack */ + + Exit2: + /* no clean up (parser not initialized) */ + return error; + } + + + /* There are 3 ways to call this function, distinguished by code. */ + /* */ + /* . CFF_CODE_TOPDICT for either a CFF Top DICT or a CFF Font DICT */ + /* . CFF2_CODE_TOPDICT for CFF2 Top DICT */ + /* . CFF2_CODE_FONTDICT for CFF2 Font DICT */ + static FT_Error - cff_subfont_load( CFF_SubFont font, + cff_subfont_load( CFF_SubFont subfont, CFF_Index idx, FT_UInt font_index, FT_Stream stream, FT_ULong base_offset, - FT_Library library ) + FT_UInt code, + CFF_Font font ) { FT_Error error; CFF_ParserRec parser; FT_Byte* dict = NULL; FT_ULong dict_len; - CFF_FontRecDict top = &font->font_dict; - CFF_Private priv = &font->private_dict; + CFF_FontRecDict top = &subfont->font_dict; + CFF_Private priv = &subfont->private_dict; + FT_Bool cff2 = FT_BOOL( code == CFF2_CODE_TOPDICT || + code == CFF2_CODE_FONTDICT ); + FT_UInt stackSize = cff2 ? CFF2_DEFAULT_STACK + : CFF_MAX_STACK_DEPTH; - cff_parser_init( &parser, - CFF_CODE_TOPDICT, - &font->font_dict, - library, - 0, - 0 ); + /* Note: We use default stack size for CFF2 Font DICT because */ + /* Top and Font DICTs are not allowed to have blend operators. */ + error = cff_parser_init( &parser, + code, + &subfont->font_dict, + font->library, + stackSize, + 0, + 0 ); + if ( error ) + goto Exit; + /* set defaults */ - FT_MEM_ZERO( top, sizeof ( *top ) ); + FT_ZERO( top ); top->underline_position = -( 100L << 16 ); top->underline_thickness = 50L << 16; @@ -1353,7 +1967,24 @@ top->cid_ordering = 0xFFFFU; top->cid_font_name = 0xFFFFU; - error = cff_index_access_element( idx, font_index, &dict, &dict_len ); + /* set default stack size */ + top->maxstack = cff2 ? CFF2_DEFAULT_STACK : 48; + + if ( idx->count ) /* count is nonzero for a real index */ + error = cff_index_access_element( idx, font_index, &dict, &dict_len ); + else + { + /* CFF2 has a fake top dict index; */ + /* simulate `cff_index_access_element' */ + + /* Note: macros implicitly use `stream' and set `error' */ + if ( FT_STREAM_SEEK( idx->data_offset ) || + FT_FRAME_EXTRACT( idx->data_size, dict ) ) + goto Exit; + + dict_len = idx->data_size; + } + if ( !error ) { FT_TRACE4(( " top dictionary:\n" )); @@ -1360,7 +1991,11 @@ error = cff_parser_run( &parser, dict, dict + dict_len ); } - cff_index_forget_element( idx, &dict ); + /* clean up regardless of error */ + if ( idx->count ) + cff_index_forget_element( idx, &dict ); + else + FT_FRAME_RELEASE( dict ); if ( error ) goto Exit; @@ -1369,41 +2004,15 @@ if ( top->cid_registry != 0xFFFFU ) goto Exit; - /* parse the private dictionary, if any */ - if ( top->private_offset && top->private_size ) - { - /* set defaults */ - FT_MEM_ZERO( priv, sizeof ( *priv ) ); + /* Parse the private dictionary, if any. */ + /* */ + /* CFF2 does not have a private dictionary in the Top DICT */ + /* but may have one in a Font DICT. We need to parse */ + /* the latter here in order to load any local subrs. */ + error = cff_load_private_dict( font, subfont, 0, 0 ); + if ( error ) + goto Exit; - priv->blue_shift = 7; - priv->blue_fuzz = 1; - priv->lenIV = -1; - priv->expansion_factor = (FT_Fixed)( 0.06 * 0x10000L ); - priv->blue_scale = (FT_Fixed)( 0.039625 * 0x10000L * 1000 ); - - cff_parser_init( &parser, - CFF_CODE_PRIVATE, - priv, - library, - top->num_designs, - top->num_axes ); - - if ( FT_STREAM_SEEK( base_offset + font->font_dict.private_offset ) || - FT_FRAME_ENTER( font->font_dict.private_size ) ) - goto Exit; - - FT_TRACE4(( " private dictionary:\n" )); - error = cff_parser_run( &parser, - (FT_Byte*)stream->cursor, - (FT_Byte*)stream->limit ); - FT_FRAME_EXIT(); - if ( error ) - goto Exit; - - /* ensure that `num_blue_values' is even */ - priv->num_blue_values &= ~1; - } - /* read the local subrs, if any */ if ( priv->local_subrs_offset ) { @@ -1411,17 +2020,19 @@ priv->local_subrs_offset ) ) goto Exit; - error = cff_index_init( &font->local_subrs_index, stream, 1 ); + error = cff_index_init( &subfont->local_subrs_index, stream, 1, cff2 ); if ( error ) goto Exit; - error = cff_index_get_pointers( &font->local_subrs_index, - &font->local_subrs, NULL, NULL ); + error = cff_index_get_pointers( &subfont->local_subrs_index, + &subfont->local_subrs, NULL, NULL ); if ( error ) goto Exit; } Exit: + cff_parser_done( &parser ); /* free parser stack */ + return error; } @@ -1434,6 +2045,10 @@ { cff_index_done( &subfont->local_subrs_index ); FT_FREE( subfont->local_subrs ); + + FT_FREE( subfont->blend.lastNDV ); + FT_FREE( subfont->blend.BV ); + FT_FREE( subfont->blend_stack ); } } @@ -1443,7 +2058,8 @@ FT_Stream stream, FT_Int face_index, CFF_Font font, - FT_Bool pure_cff ) + FT_Bool pure_cff, + FT_Bool cff2 ) { static const FT_Frame_Field cff_header_fields[] = { @@ -1450,11 +2066,10 @@ #undef FT_STRUCTURE #define FT_STRUCTURE CFF_FontRec - FT_FRAME_START( 4 ), + FT_FRAME_START( 3 ), FT_FRAME_BYTE( version_major ), FT_FRAME_BYTE( version_minor ), FT_FRAME_BYTE( header_size ), - FT_FRAME_BYTE( absolute_offsize ), FT_FRAME_END }; @@ -1469,44 +2084,113 @@ FT_ZERO( font ); FT_ZERO( &string_index ); - font->stream = stream; - font->memory = memory; - dict = &font->top_font.font_dict; - base_offset = FT_STREAM_POS(); + dict = &font->top_font.font_dict; + base_offset = FT_STREAM_POS(); + font->library = library; + font->stream = stream; + font->memory = memory; + font->cff2 = cff2; + font->base_offset = base_offset; + /* read CFF font header */ if ( FT_STREAM_READ_FIELDS( cff_header_fields, font ) ) goto Exit; - /* check format */ - if ( font->version_major != 1 || - font->header_size < 4 || - font->absolute_offsize > 4 ) + if ( cff2 ) { - FT_TRACE2(( " not a CFF font header\n" )); - error = FT_THROW( Unknown_File_Format ); - goto Exit; + if ( font->version_major != 2 || + font->header_size < 5 ) + { + FT_TRACE2(( " not a CFF2 font header\n" )); + error = FT_THROW( Unknown_File_Format ); + goto Exit; + } + + if ( FT_READ_USHORT( font->top_dict_length ) ) + goto Exit; } + else + { + FT_Byte absolute_offset; + + if ( FT_READ_BYTE( absolute_offset ) ) + goto Exit; + + if ( font->version_major != 1 || + font->header_size < 4 || + absolute_offset > 4 ) + { + FT_TRACE2(( " not a CFF font header\n" )); + error = FT_THROW( Unknown_File_Format ); + goto Exit; + } + } + /* skip the rest of the header */ - if ( FT_STREAM_SKIP( font->header_size - 4 ) ) + if ( FT_STREAM_SEEK( base_offset + font->header_size ) ) + { + /* For pure CFFs we have read only four bytes so far. Contrary to */ + /* other formats like SFNT those bytes doesn't define a signature; */ + /* it is thus possible that the font isn't a CFF at all. */ + if ( pure_cff ) + { + FT_TRACE2(( " not a CFF file\n" )); + error = FT_THROW( Unknown_File_Format ); + } goto Exit; + } - /* read the name, top dict, string and global subrs index */ - if ( FT_SET_ERROR( cff_index_init( &font->name_index, - stream, 0 ) ) || - FT_SET_ERROR( cff_index_init( &font->font_dict_index, - stream, 0 ) ) || - FT_SET_ERROR( cff_index_init( &string_index, - stream, 1 ) ) || - FT_SET_ERROR( cff_index_init( &font->global_subrs_index, - stream, 1 ) ) || - FT_SET_ERROR( cff_index_get_pointers( &string_index, - &font->strings, - &font->string_pool, - &font->string_pool_size ) ) ) - goto Exit; + if ( cff2 ) + { + /* For CFF2, the top dict data immediately follow the header */ + /* and the length is stored in the header `offSize' field; */ + /* there is no index for it. */ + /* */ + /* Use the `font_dict_index' to save the current position */ + /* and length of data, but leave count at zero as an indicator. */ + FT_ZERO( &font->font_dict_index ); + font->font_dict_index.data_offset = FT_STREAM_POS(); + font->font_dict_index.data_size = font->top_dict_length; + + /* skip the top dict data for now, we will parse it later */ + if ( FT_STREAM_SKIP( font->top_dict_length ) ) + goto Exit; + + /* next, read the global subrs index */ + if ( FT_SET_ERROR( cff_index_init( &font->global_subrs_index, + stream, 1, cff2 ) ) ) + goto Exit; + } + else + { + /* for CFF, read the name, top dict, string and global subrs index */ + if ( FT_SET_ERROR( cff_index_init( &font->name_index, + stream, 0, cff2 ) ) ) + { + if ( pure_cff ) + { + FT_TRACE2(( " not a CFF file\n" )); + error = FT_THROW( Unknown_File_Format ); + } + goto Exit; + } + + if ( FT_SET_ERROR( cff_index_init( &font->font_dict_index, + stream, 0, cff2 ) ) || + FT_SET_ERROR( cff_index_init( &string_index, + stream, 1, cff2 ) ) || + FT_SET_ERROR( cff_index_init( &font->global_subrs_index, + stream, 1, cff2 ) ) || + FT_SET_ERROR( cff_index_get_pointers( &string_index, + &font->strings, + &font->string_pool, + &font->string_pool_size ) ) ) + goto Exit; + } + font->num_strings = string_index.count; if ( pure_cff ) @@ -1551,7 +2235,8 @@ subfont_index, stream, base_offset, - library ); + cff2 ? CFF2_CODE_TOPDICT : CFF_CODE_TOPDICT, + font ); if ( error ) goto Exit; @@ -1558,12 +2243,13 @@ if ( FT_STREAM_SEEK( base_offset + dict->charstrings_offset ) ) goto Exit; - error = cff_index_init( &font->charstrings_index, stream, 0 ); + error = cff_index_init( &font->charstrings_index, stream, 0, cff2 ); if ( error ) goto Exit; - /* now, check for a CID font */ - if ( dict->cid_registry != 0xFFFFU ) + /* now, check for a CID or CFF2 font */ + if ( dict->cid_registry != 0xFFFFU || + cff2 ) { CFF_IndexRec fd_index; CFF_SubFont sub = NULL; @@ -1570,15 +2256,26 @@ FT_UInt idx; + /* for CFF2, read the Variation Store if available; */ + /* this must follow the Top DICT parse and precede any Private DICT */ + error = cff_vstore_load( &font->vstore, + stream, + base_offset, + dict->vstore_offset ); + if ( error ) + goto Exit; + /* this is a CID-keyed font, we must now allocate a table of */ /* sub-fonts, then load each of them separately */ if ( FT_STREAM_SEEK( base_offset + dict->cid_fd_array_offset ) ) goto Exit; - error = cff_index_init( &fd_index, stream, 0 ); + error = cff_index_init( &fd_index, stream, 0, cff2 ); if ( error ) goto Exit; + /* Font Dicts are not limited to 256 for CFF2. */ + /* TODO: support this for CFF2 */ if ( fd_index.count > CFF_MAX_CID_FONTS ) { FT_TRACE0(( "cff_font_load: FD array too large in CID font\n" )); @@ -1599,17 +2296,25 @@ { sub = font->subfonts[idx]; FT_TRACE4(( "parsing subfont %u\n", idx )); - error = cff_subfont_load( sub, &fd_index, idx, - stream, base_offset, library ); + error = cff_subfont_load( sub, + &fd_index, + idx, + stream, + base_offset, + cff2 ? CFF2_CODE_FONTDICT + : CFF_CODE_TOPDICT, + font ); if ( error ) goto Fail_CID; } - /* now load the FD Select array */ - error = CFF_Load_FD_Select( &font->fd_select, - font->charstrings_index.count, - stream, - base_offset + dict->cid_fd_select_offset ); + /* now load the FD Select array; */ + /* CFF2 omits FDSelect if there is only one FD */ + if ( !cff2 || fd_index.count > 1 ) + error = CFF_Load_FD_Select( &font->fd_select, + font->charstrings_index.count, + stream, + base_offset + dict->cid_fd_select_offset ); Fail_CID: cff_index_done( &fd_index ); @@ -1637,7 +2342,7 @@ goto Exit; /* read the Charset and Encoding tables if available */ - if ( font->num_glyphs > 0 ) + if ( !cff2 && font->num_glyphs > 0 ) { FT_Bool invert = FT_BOOL( dict->cid_registry != 0xFFFFU && pure_cff ); @@ -1685,7 +2390,7 @@ cff_index_done( &font->charstrings_index ); /* release font dictionaries, but only if working with */ - /* a CID keyed CFF font */ + /* a CID keyed CFF font or a CFF2 font */ if ( font->num_subfonts > 0 ) { for ( idx = 0; idx < font->num_subfonts; idx++ ) @@ -1697,6 +2402,7 @@ cff_encoding_done( &font->encoding ); cff_charset_done( &font->charset, font->stream ); + cff_vstore_done( &font->vstore, memory ); cff_subfont_done( memory, &font->top_font ); Index: reactos/sdk/lib/3rdparty/freetype/src/cff/cffload.h =================================================================== --- reactos/sdk/lib/3rdparty/freetype/src/cff/cffload.h (revision 74184) +++ reactos/sdk/lib/3rdparty/freetype/src/cff/cffload.h (working copy) @@ -22,6 +22,8 @@ #include #include "cfftypes.h" +#include "cffparse.h" +#include "cffobjs.h" /* for CFF_Face */ FT_BEGIN_HEADER @@ -60,21 +62,59 @@ FT_LOCAL( FT_Error ) - cff_font_load( FT_Library library, - FT_Stream stream, - FT_Int face_index, - CFF_Font font, - FT_Bool pure_cff ); + cff_font_load( FT_Library library, + FT_Stream stream, + FT_Int face_index, + CFF_Font font, + FT_Bool pure_cff, + FT_Bool cff2 ); FT_LOCAL( void ) cff_font_done( CFF_Font font ); + FT_LOCAL( FT_Error ) + cff_load_private_dict( CFF_Font font, + CFF_SubFont subfont, + FT_UInt lenNDV, + FT_Fixed* NDV ); + FT_LOCAL( FT_Byte ) cff_fd_select_get( CFF_FDSelect fdselect, FT_UInt glyph_index ); + FT_LOCAL( FT_Bool ) + cff_blend_check_vector( CFF_Blend blend, + FT_UInt vsindex, + FT_UInt lenNDV, + FT_Fixed* NDV ); + FT_LOCAL( FT_Error ) + cff_blend_build_vector( CFF_Blend blend, + FT_UInt vsindex, + FT_UInt lenNDV, + FT_Fixed* NDV ); + + FT_LOCAL( void ) + cff_blend_clear( CFF_SubFont subFont ); + + FT_LOCAL( FT_Error ) + cff_blend_doBlend( CFF_SubFont subfont, + CFF_Parser parser, + FT_UInt numBlends ); + +#ifdef TT_CONFIG_OPTION_GX_VAR_SUPPORT + FT_LOCAL( FT_Error ) + cff_get_var_blend( CFF_Face face, + FT_UInt *num_coords, + FT_Fixed* *coords, + FT_MM_Var* *mm_var ); + + FT_LOCAL( void ) + cff_done_blend( CFF_Face face ); +#endif + + FT_END_HEADER #endif /* CFFLOAD_H_ */ Index: reactos/sdk/lib/3rdparty/freetype/src/cff/cffobjs.c =================================================================== --- reactos/sdk/lib/3rdparty/freetype/src/cff/cffobjs.c (revision 74184) +++ reactos/sdk/lib/3rdparty/freetype/src/cff/cffobjs.c (working copy) @@ -114,7 +114,7 @@ FT_UInt n, count; - FT_MEM_ZERO( priv, sizeof ( *priv ) ); + FT_ZERO( priv ); count = priv->num_blue_values = cpriv->num_blue_values; for ( n = 0; n < count; n++ ) @@ -450,7 +450,7 @@ FT_Int idx; - for ( idx = 1; idx <= style_name_length; ++idx ) + for ( idx = 1; idx <= style_name_length; idx++ ) { if ( family_name[family_name_length - idx] != style_name[style_name_length - idx] ) @@ -469,7 +469,7 @@ family_name[idx] == ' ' || family_name[idx] == '_' || family_name[idx] == '+' ) ) - --idx; + idx--; if ( idx > 0 ) family_name[idx + 1] = '\0'; @@ -491,6 +491,7 @@ FT_Service_PsCMaps psnames; PSHinter_Service pshinter; FT_Bool pure_cff = 1; + FT_Bool cff2 = 0; FT_Bool sfnt_format = 0; FT_Library library = cffface->driver->root.library; @@ -553,8 +554,18 @@ goto Exit; } - /* now load the CFF part of the file */ - error = face->goto_table( face, TTAG_CFF, stream, 0 ); + /* now load the CFF part of the file; */ + /* give priority to CFF2 */ + error = face->goto_table( face, TTAG_CFF2, stream, 0 ); + if ( !error ) + { + cff2 = 1; + face->isCFF2 = cff2; + } + + if ( FT_ERR_EQ( error, Table_Missing ) ) + error = face->goto_table( face, TTAG_CFF, stream, 0 ); + if ( error ) goto Exit; } @@ -579,7 +590,12 @@ goto Exit; face->extra.data = cff; - error = cff_font_load( library, stream, face_index, cff, pure_cff ); + error = cff_font_load( library, + stream, + face_index, + cff, + pure_cff, + cff2 ); if ( error ) goto Exit; @@ -667,6 +683,62 @@ } #endif /* FT_DEBUG_LEVEL_TRACE */ + + +#ifdef TT_CONFIG_OPTION_GX_VAR_SUPPORT + + { + FT_Service_MultiMasters mm = (FT_Service_MultiMasters)face->mm; + + FT_Int instance_index = face_index >> 16; + + + if ( FT_HAS_MULTIPLE_MASTERS( cffface ) && + mm && + instance_index > 0 ) + { + FT_MM_Var* mm_var; + + + error = mm->get_mm_var( cffface, NULL ); + if ( error ) + goto Exit; + + mm->get_var_blend( cffface, NULL, NULL, &mm_var ); + + if ( mm_var->namedstyle ) + { + FT_Var_Named_Style* named_style; + FT_String* style_name; + + + /* in `face_index', the instance index starts with value 1 */ + named_style = mm_var->namedstyle + instance_index - 1; + error = sfnt->get_name( face, + (FT_UShort)named_style->strid, + &style_name ); + if ( error ) + goto Exit; + + /* set style name; if already set, replace it */ + if ( face->root.style_name ) + FT_FREE( face->root.style_name ); + face->root.style_name = style_name; + + /* finally, select the named instance */ + error = mm->set_var_design( cffface, + mm_var->num_axis, + named_style->coords ); + if ( error ) + goto Exit; + } + } + } + +#endif /* TT_CONFIG_OPTION_GX_VAR_SUPPORT */ + + + if ( !dict->has_font_matrix ) dict->units_per_em = pure_cff ? 1000 : face->root.units_per_EM; @@ -1011,7 +1083,7 @@ error = FT_Err_Ok; /* if no Unicode charmap was previously selected, select this one */ - if ( cffface->charmap == NULL && nn != (FT_UInt)cffface->num_charmaps ) + if ( !cffface->charmap && nn != (FT_UInt)cffface->num_charmaps ) cffface->charmap = cffface->charmaps[nn]; Skip_Unicode: @@ -1079,6 +1151,11 @@ FT_FREE( face->extra.data ); } } + +#ifdef TT_CONFIG_OPTION_GX_VAR_SUPPORT + cff_done_blend( face ); + face->blend = NULL; +#endif } Index: reactos/sdk/lib/3rdparty/freetype/src/cff/cffparse.c =================================================================== --- reactos/sdk/lib/3rdparty/freetype/src/cff/cffparse.c (revision 74184) +++ reactos/sdk/lib/3rdparty/freetype/src/cff/cffparse.c (working copy) @@ -24,6 +24,7 @@ #include "cfferrs.h" #include "cffpic.h" #include "cffgload.h" +#include "cffload.h" /*************************************************************************/ @@ -36,25 +37,55 @@ #define FT_COMPONENT trace_cffparse - FT_LOCAL_DEF( void ) + FT_LOCAL_DEF( FT_Error ) cff_parser_init( CFF_Parser parser, FT_UInt code, void* object, FT_Library library, + FT_UInt stackSize, FT_UShort num_designs, FT_UShort num_axes ) { - FT_MEM_ZERO( parser, sizeof ( *parser ) ); + FT_Memory memory = library->memory; /* for FT_NEW_ARRAY */ + FT_Error error; /* for FT_NEW_ARRAY */ + + FT_ZERO( parser ); + +#if 0 parser->top = parser->stack; +#endif parser->object_code = code; parser->object = object; parser->library = library; parser->num_designs = num_designs; parser->num_axes = num_axes; + + /* allocate the stack buffer */ + if ( FT_NEW_ARRAY( parser->stack, stackSize ) ) + { + FT_FREE( parser->stack ); + goto Exit; + } + + parser->stackSize = stackSize; + parser->top = parser->stack; /* empty stack */ + + Exit: + return error; } + FT_LOCAL_DEF( void ) + cff_parser_done( CFF_Parser parser ) + { + FT_Memory memory = parser->library->memory; /* for FT_FREE */ + + + FT_FREE( parser->stack ); + } + + /* read an integer */ static FT_Long cff_parse_integer( FT_Byte* start, @@ -402,24 +433,42 @@ /* read a number, either integer or real */ - static FT_Long - cff_parse_num( FT_Byte** d ) + FT_LOCAL_DEF( FT_Long ) + cff_parse_num( CFF_Parser parser, + FT_Byte** d ) { - return **d == 30 ? ( cff_parse_real( d[0], d[1], 0, NULL ) >> 16 ) - : cff_parse_integer( d[0], d[1] ); + if ( **d == 30 ) + { + /* binary-coded decimal is truncated to integer */ + return cff_parse_real( *d, parser->limit, 0, NULL ) >> 16; + } + + else if ( **d == 255 ) + { + /* 16.16 fixed point is used internally for CFF2 blend results. */ + /* Since these are trusted values, a limit check is not needed. */ + + /* After the 255, 4 bytes are in host order. */ + /* Blend result is rounded to integer. */ + return (FT_Long)( *( (FT_UInt32 *) ( d[0] + 1 ) ) + 0x8000U ) >> 16; + } + + else + return cff_parse_integer( *d, parser->limit ); } /* read a floating point number, either integer or real */ static FT_Fixed - do_fixed( FT_Byte** d, - FT_Long scaling ) + do_fixed( CFF_Parser parser, + FT_Byte** d, + FT_Long scaling ) { if ( **d == 30 ) - return cff_parse_real( d[0], d[1], scaling, NULL ); + return cff_parse_real( *d, parser->limit, scaling, NULL ); else { - FT_Long val = cff_parse_integer( d[0], d[1] ); + FT_Long val = cff_parse_integer( *d, parser->limit ); if ( scaling ) @@ -447,9 +496,10 @@ /* read a floating point number, either integer or real */ static FT_Fixed - cff_parse_fixed( FT_Byte** d ) + cff_parse_fixed( CFF_Parser parser, + FT_Byte** d ) { - return do_fixed( d, 0 ); + return do_fixed( parser, d, 0 ); } @@ -456,10 +506,11 @@ /* read a floating point number, either integer or real, */ /* but return `10^scaling' times the number read in */ static FT_Fixed - cff_parse_fixed_scaled( FT_Byte** d, - FT_Long scaling ) + cff_parse_fixed_scaled( CFF_Parser parser, + FT_Byte** d, + FT_Long scaling ) { - return do_fixed( d, scaling ); + return do_fixed( parser, d, scaling ); } @@ -467,13 +518,14 @@ /* and return it as precise as possible -- `scaling' returns */ /* the scaling factor (as a power of 10) */ static FT_Fixed - cff_parse_fixed_dynamic( FT_Byte** d, - FT_Long* scaling ) + cff_parse_fixed_dynamic( CFF_Parser parser, + FT_Byte** d, + FT_Long* scaling ) { FT_ASSERT( scaling ); if ( **d == 30 ) - return cff_parse_real( d[0], d[1], 0, scaling ); + return cff_parse_real( *d, parser->limit, 0, scaling ); else { FT_Long number; @@ -543,7 +595,7 @@ for ( i = 0; i < 6; i++ ) { - values[i] = cff_parse_fixed_dynamic( data++, &scalings[i] ); + values[i] = cff_parse_fixed_dynamic( parser, data++, &scalings[i] ); if ( values[i] ) { if ( scalings[i] > max_scaling ) @@ -640,10 +692,10 @@ if ( parser->top >= parser->stack + 4 ) { - bbox->xMin = FT_RoundFix( cff_parse_fixed( data++ ) ); - bbox->yMin = FT_RoundFix( cff_parse_fixed( data++ ) ); - bbox->xMax = FT_RoundFix( cff_parse_fixed( data++ ) ); - bbox->yMax = FT_RoundFix( cff_parse_fixed( data ) ); + bbox->xMin = FT_RoundFix( cff_parse_fixed( parser, data++ ) ); + bbox->yMin = FT_RoundFix( cff_parse_fixed( parser, data++ ) ); + bbox->xMax = FT_RoundFix( cff_parse_fixed( parser, data++ ) ); + bbox->yMax = FT_RoundFix( cff_parse_fixed( parser, data ) ); error = FT_Err_Ok; FT_TRACE4(( " [%d %d %d %d]\n", @@ -672,7 +724,7 @@ FT_Long tmp; - tmp = cff_parse_num( data++ ); + tmp = cff_parse_num( parser, data++ ); if ( tmp < 0 ) { FT_ERROR(( "cff_parse_private_dict: Invalid dictionary size\n" )); @@ -681,7 +733,7 @@ } dict->private_size = (FT_ULong)tmp; - tmp = cff_parse_num( data ); + tmp = cff_parse_num( parser, data ); if ( tmp < 0 ) { FT_ERROR(( "cff_parse_private_dict: Invalid dictionary offset\n" )); @@ -726,7 +778,7 @@ /* currently, we handle only the first argument */ if ( parser->top >= parser->stack + 5 ) { - FT_Long num_designs = cff_parse_num( parser->stack ); + FT_Long num_designs = cff_parse_num( parser, parser->stack ); if ( num_designs > 16 || num_designs < 2 ) @@ -763,11 +815,11 @@ if ( parser->top >= parser->stack + 3 ) { - dict->cid_registry = (FT_UInt)cff_parse_num( data++ ); - dict->cid_ordering = (FT_UInt)cff_parse_num( data++ ); + dict->cid_registry = (FT_UInt)cff_parse_num( parser, data++ ); + dict->cid_ordering = (FT_UInt)cff_parse_num( parser, data++ ); if ( **data == 30 ) FT_TRACE1(( "cff_parse_cid_ros: real supplement is rounded\n" )); - dict->cid_supplement = cff_parse_num( data ); + dict->cid_supplement = cff_parse_num( parser, data ); if ( dict->cid_supplement < 0 ) FT_TRACE1(( "cff_parse_cid_ros: negative supplement %d is found\n", dict->cid_supplement )); @@ -783,6 +835,125 @@ } + static FT_Error + cff_parse_vsindex( CFF_Parser parser ) + { + /* vsindex operator can only be used in a Private DICT */ + CFF_Private priv = (CFF_Private)parser->object; + FT_Byte** data = parser->stack; + CFF_Blend blend; + FT_Error error; + + + if ( !priv || !priv->subfont ) + { + error = FT_THROW( Invalid_File_Format ); + goto Exit; + } + + blend = &priv->subfont->blend; + + if ( blend->usedBV ) + { + FT_ERROR(( " cff_parse_vsindex: vsindex not allowed after blend\n" )); + error = FT_THROW( Syntax_Error ); + goto Exit; + } + + priv->vsindex = (FT_UInt)cff_parse_num( parser, data++ ); + + FT_TRACE4(( " %d\n", priv->vsindex )); + + error = FT_Err_Ok; + + Exit: + return error; + } + + + static FT_Error + cff_parse_blend( CFF_Parser parser ) + { + /* blend operator can only be used in a Private DICT */ + CFF_Private priv = (CFF_Private)parser->object; + CFF_SubFont subFont; + CFF_Blend blend; + FT_UInt numBlends; + FT_Error error; + + + error = FT_ERR( Stack_Underflow ); + + if ( !priv || !priv->subfont ) + { + error = FT_THROW( Invalid_File_Format ); + goto Exit; + } + + subFont = priv->subfont; + blend = &subFont->blend; + + if ( cff_blend_check_vector( blend, + priv->vsindex, + subFont->lenNDV, + subFont->NDV ) ) + { + error = cff_blend_build_vector( blend, + priv->vsindex, + subFont->lenNDV, + subFont->NDV ); + if ( error ) + goto Exit; + } + + numBlends = (FT_UInt)cff_parse_num( parser, parser->top - 1 ); + if ( numBlends > parser->stackSize ) + { + FT_ERROR(( "cff_parse_blend: Invalid number of blends\n" )); + error = FT_THROW( Invalid_File_Format ); + goto Exit; + } + + FT_TRACE4(( " %d values blended\n", numBlends )); + + error = cff_blend_doBlend( subFont, parser, numBlends ); + + blend->usedBV = TRUE; + + Exit: + return error; + } + + + /* maxstack operator increases parser and operand stacks for CFF2 */ + static FT_Error + cff_parse_maxstack( CFF_Parser parser ) + { + /* maxstack operator can only be used in a Top DICT */ + CFF_FontRecDict dict = (CFF_FontRecDict)parser->object; + FT_Byte** data = parser->stack; + FT_Error error = FT_Err_Ok; + + + if ( !dict ) + { + error = FT_THROW( Invalid_File_Format ); + goto Exit; + } + + dict->maxstack = (FT_UInt)cff_parse_num( parser, data++ ); + if ( dict->maxstack > CFF2_MAX_STACK ) + dict->maxstack = CFF2_MAX_STACK; + if ( dict->maxstack < CFF2_DEFAULT_STACK ) + dict->maxstack = CFF2_DEFAULT_STACK; + + FT_TRACE4(( " %d\n", dict->maxstack )); + + Exit: + return error; + } + + #define CFF_FIELD_NUM( code, name, id ) \ CFF_FIELD( code, name, id, cff_kind_num ) #define CFF_FIELD_FIXED( code, name, id ) \ @@ -794,10 +965,7 @@ #define CFF_FIELD_BOOL( code, name, id ) \ CFF_FIELD( code, name, id, cff_kind_bool ) -#define CFFCODE_TOPDICT 0x1000 -#define CFFCODE_PRIVATE 0x2000 - #ifndef FT_CONFIG_OPTION_PIC @@ -817,6 +985,15 @@ 0, 0 \ }, +#define CFF_FIELD_BLEND( code, id ) \ + { \ + cff_kind_blend, \ + code | CFFCODE, \ + 0, 0, \ + cff_parse_blend, \ + 0, 0 \ + }, + #define CFF_FIELD( code, name, id, kind ) \ { \ kind, \ @@ -860,6 +1037,16 @@ id \ }, +#define CFF_FIELD_BLEND( code, id ) \ + { \ + cff_kind_blend, \ + code | CFFCODE, \ + 0, 0, \ + cff_parse_blend, \ + 0, 0, \ + id \ + }, + #define CFF_FIELD( code, name, id, kind ) \ { \ kind, \ @@ -1067,11 +1254,13 @@ { FT_UInt v = *p; - - if ( v >= 27 && v != 31 ) + /* Opcode 31 is legacy MM T2 operator, not a number. */ + /* Opcode 255 is reserved and should not appear in fonts; */ + /* it is used internally for CFF2 blends. */ + if ( v >= 27 && v != 31 && v != 255 ) { /* it's a number; we will push its position on the stack */ - if ( parser->top - parser->stack >= CFF_MAX_STACK_DEPTH ) + if ( (FT_UInt)( parser->top - parser->stack ) >= parser->stackSize ) goto Stack_Overflow; *parser->top++ = p; @@ -1132,8 +1321,8 @@ charstring_len = (FT_ULong)( p - charstring_base ) + 1; /* construct CFF_Decoder object */ - FT_MEM_ZERO( &decoder, sizeof ( decoder ) ); - FT_MEM_ZERO( &cff_rec, sizeof ( cff_rec ) ); + FT_ZERO( &decoder ); + FT_ZERO( &cff_rec ); cff_rec.top_font.font_dict.num_designs = parser->num_designs; cff_rec.top_font.font_dict.num_axes = parser->num_axes; @@ -1162,7 +1351,7 @@ FT_Bool neg; - if ( parser->top - parser->stack >= CFF_MAX_STACK_DEPTH ) + if ( (FT_UInt)( parser->top - parser->stack ) >= parser->stackSize ) goto Stack_Overflow; *parser->top++ = q; @@ -1239,13 +1428,17 @@ /* and look for it in our current list. */ FT_UInt code; - FT_UInt num_args = (FT_UInt) - ( parser->top - parser->stack ); + FT_UInt num_args; const CFF_Field_Handler* field; + if ( (FT_UInt)( parser->top - parser->stack ) >= parser->stackSize ) + goto Stack_Overflow; + + num_args = (FT_UInt)( parser->top - parser->stack ); *parser->top = p; - code = v; + code = v; + if ( v == 12 ) { /* two byte operator */ @@ -1280,15 +1473,15 @@ case cff_kind_bool: case cff_kind_string: case cff_kind_num: - val = cff_parse_num( parser->stack ); + val = cff_parse_num( parser, parser->stack ); goto Store_Number; case cff_kind_fixed: - val = cff_parse_fixed( parser->stack ); + val = cff_parse_fixed( parser, parser->stack ); goto Store_Number; case cff_kind_fixed_thousand: - val = cff_parse_fixed_scaled( parser->stack, 3 ); + val = cff_parse_fixed_scaled( parser, parser->stack, 3 ); Store_Number: switch ( field->size ) @@ -1357,7 +1550,7 @@ val = 0; while ( num_args > 0 ) { - val += cff_parse_num( data++ ); + val += cff_parse_num( parser, data++ ); switch ( field->size ) { case (8 / FT_CHAR_BIT): @@ -1386,7 +1579,7 @@ } break; - default: /* callback */ + default: /* callback or blend */ error = field->reader( parser ); if ( error ) goto Exit; @@ -1400,7 +1593,10 @@ Found: /* clear stack */ - parser->top = parser->stack; + /* TODO: could clear blend stack here, */ + /* but we don't have access to subFont */ + if ( field->kind != cff_kind_blend ) + parser->top = parser->stack; } p++; } Index: reactos/sdk/lib/3rdparty/freetype/src/cff/cffparse.h =================================================================== --- reactos/sdk/lib/3rdparty/freetype/src/cff/cffparse.h (revision 74184) +++ reactos/sdk/lib/3rdparty/freetype/src/cff/cffparse.h (working copy) @@ -28,10 +28,17 @@ FT_BEGIN_HEADER + /* CFF uses constant parser stack size; */ + /* CFF2 can increase from default 193 */ #define CFF_MAX_STACK_DEPTH 96 +#define CFF2_MAX_STACK 513 +#define CFF2_DEFAULT_STACK 193 -#define CFF_CODE_TOPDICT 0x1000 -#define CFF_CODE_PRIVATE 0x2000 +#define CFF_CODE_TOPDICT 0x1000 +#define CFF_CODE_PRIVATE 0x2000 +#define CFF2_CODE_TOPDICT 0x3000 +#define CFF2_CODE_FONTDICT 0x4000 +#define CFF2_CODE_PRIVATE 0x5000 typedef struct CFF_ParserRec_ @@ -41,8 +48,9 @@ FT_Byte* limit; FT_Byte* cursor; - FT_Byte* stack[CFF_MAX_STACK_DEPTH + 1]; + FT_Byte** stack; FT_Byte** top; + FT_UInt stackSize; /* allocated size */ FT_UInt object_code; void* object; @@ -53,14 +61,22 @@ } CFF_ParserRec, *CFF_Parser; - FT_LOCAL( void ) + FT_LOCAL( FT_Long ) + cff_parse_num( CFF_Parser parser, + FT_Byte** d ); + + FT_LOCAL( FT_Error ) cff_parser_init( CFF_Parser parser, FT_UInt code, void* object, FT_Library library, + FT_UInt stackSize, FT_UShort num_designs, FT_UShort num_axes ); + FT_LOCAL( void ) + cff_parser_done( CFF_Parser parser ); + FT_LOCAL( FT_Error ) cff_parser_run( CFF_Parser parser, FT_Byte* start, @@ -77,6 +93,7 @@ cff_kind_bool, cff_kind_delta, cff_kind_callback, + cff_kind_blend, cff_kind_max /* do not remove */ }; Index: reactos/sdk/lib/3rdparty/freetype/src/cff/cffpic.h =================================================================== --- reactos/sdk/lib/3rdparty/freetype/src/cff/cffpic.h (revision 74184) +++ reactos/sdk/lib/3rdparty/freetype/src/cff/cffpic.h (working copy) @@ -32,6 +32,7 @@ #define CFF_SERVICE_CID_INFO_GET cff_service_cid_info #define CFF_SERVICE_PROPERTIES_GET cff_service_properties #define CFF_SERVICES_GET cff_services +#define CFF_SERVICE_MULTI_MASTERS_GET cff_service_multi_masters #define CFF_CMAP_ENCODING_CLASS_REC_GET cff_cmap_encoding_class_rec #define CFF_CMAP_UNICODE_CLASS_REC_GET cff_cmap_unicode_class_rec #define CFF_FIELD_HANDLERS_GET cff_field_handlers Index: reactos/sdk/lib/3rdparty/freetype/src/cff/cfftoken.h =================================================================== --- reactos/sdk/lib/3rdparty/freetype/src/cff/cfftoken.h (revision 74184) +++ reactos/sdk/lib/3rdparty/freetype/src/cff/cfftoken.h (working copy) @@ -20,7 +20,7 @@ #define FT_STRUCTURE CFF_FontRecDictRec #undef CFFCODE -#define CFFCODE CFFCODE_TOPDICT +#define CFFCODE CFF_CODE_TOPDICT CFF_FIELD_STRING ( 0, version, "Version" ) CFF_FIELD_STRING ( 1, notice, "Notice" ) @@ -78,7 +78,7 @@ #undef FT_STRUCTURE #define FT_STRUCTURE CFF_PrivateRec #undef CFFCODE -#define CFFCODE CFFCODE_PRIVATE +#define CFFCODE CFF_CODE_PRIVATE CFF_FIELD_DELTA ( 6, blue_values, 14, "BlueValues" ) CFF_FIELD_DELTA ( 7, other_blues, 10, "OtherBlues" ) @@ -102,4 +102,49 @@ CFF_FIELD_NUM ( 21, nominal_width, "nominalWidthX" ) +#undef FT_STRUCTURE +#define FT_STRUCTURE CFF_FontRecDictRec +#undef CFFCODE +#define CFFCODE CFF2_CODE_TOPDICT + + CFF_FIELD_CALLBACK( 0x107, font_matrix, "FontMatrix" ) + CFF_FIELD_NUM ( 17, charstrings_offset, "CharStrings" ) + CFF_FIELD_NUM ( 0x124, cid_fd_array_offset, "FDArray" ) + CFF_FIELD_NUM ( 0x125, cid_fd_select_offset, "FDSelect" ) + CFF_FIELD_NUM ( 24, vstore_offset, "vstore" ) + CFF_FIELD_CALLBACK( 25, maxstack, "maxstack" ) + + +#undef FT_STRUCTURE +#define FT_STRUCTURE CFF_FontRecDictRec +#undef CFFCODE +#define CFFCODE CFF2_CODE_FONTDICT + + CFF_FIELD_CALLBACK( 18, private_dict, "Private" ) + CFF_FIELD_CALLBACK( 0x107, font_matrix, "FontMatrix" ) + + +#undef FT_STRUCTURE +#define FT_STRUCTURE CFF_PrivateRec +#undef CFFCODE +#define CFFCODE CFF2_CODE_PRIVATE + + CFF_FIELD_DELTA ( 6, blue_values, 14, "BlueValues" ) + CFF_FIELD_DELTA ( 7, other_blues, 10, "OtherBlues" ) + CFF_FIELD_DELTA ( 8, family_blues, 14, "FamilyBlues" ) + CFF_FIELD_DELTA ( 9, family_other_blues, 10, "FamilyOtherBlues" ) + CFF_FIELD_FIXED_1000( 0x109, blue_scale, "BlueScale" ) + CFF_FIELD_NUM ( 0x10A, blue_shift, "BlueShift" ) + CFF_FIELD_NUM ( 0x10B, blue_fuzz, "BlueFuzz" ) + CFF_FIELD_NUM ( 10, standard_width, "StdHW" ) + CFF_FIELD_NUM ( 11, standard_height, "StdVW" ) + CFF_FIELD_DELTA ( 0x10C, snap_widths, 13, "StemSnapH" ) + CFF_FIELD_DELTA ( 0x10D, snap_heights, 13, "StemSnapV" ) + CFF_FIELD_NUM ( 0x111, language_group, "LanguageGroup" ) + CFF_FIELD_FIXED ( 0x112, expansion_factor, "ExpansionFactor" ) + CFF_FIELD_CALLBACK ( 22, vsindex, "vsindex" ) + CFF_FIELD_BLEND ( 23, "blend" ) + CFF_FIELD_NUM ( 19, local_subrs_offset, "Subrs" ) + + /* END */ Index: reactos/sdk/lib/3rdparty/freetype/src/cff/cfftypes.h =================================================================== --- reactos/sdk/lib/3rdparty/freetype/src/cff/cfftypes.h (revision 74184) +++ reactos/sdk/lib/3rdparty/freetype/src/cff/cfftypes.h (working copy) @@ -64,6 +64,7 @@ { FT_Stream stream; FT_ULong start; + FT_UInt hdr_size; FT_UInt count; FT_Byte off_size; FT_ULong data_offset; @@ -102,6 +103,79 @@ } CFF_CharsetRec, *CFF_Charset; + /* cf. similar fields in file `ttgxvar.h' from the `truetype' module */ + + typedef struct CFF_VarData_ + { +#if 0 + FT_UInt itemCount; /* not used; always zero */ + FT_UInt shortDeltaCount; /* not used; always zero */ +#endif + + FT_UInt regionIdxCount; /* number of regions in this var data */ + FT_UInt* regionIndices; /* array of `regionCount' indices; */ + /* these index `varRegionList' */ + } CFF_VarData; + + + /* contribution of one axis to a region */ + typedef struct CFF_AxisCoords_ + { + FT_Fixed startCoord; + FT_Fixed peakCoord; /* zero peak means no effect (factor = 1) */ + FT_Fixed endCoord; + + } CFF_AxisCoords; + + + typedef struct CFF_VarRegion_ + { + CFF_AxisCoords* axisList; /* array of axisCount records */ + + } CFF_VarRegion; + + + typedef struct CFF_VStoreRec_ + { + FT_UInt dataCount; + CFF_VarData* varData; /* array of dataCount records */ + /* vsindex indexes this array */ + FT_UShort axisCount; + FT_UInt regionCount; /* total number of regions defined */ + CFF_VarRegion* varRegionList; + + } CFF_VStoreRec, *CFF_VStore; + + + /* forward reference */ + typedef struct CFF_FontRec_* CFF_Font; + + + /* This object manages one cached blend vector. */ + /* */ + /* There is a BlendRec for Private DICT parsing in each subfont */ + /* and a BlendRec for charstrings in CF2_Font instance data. */ + /* A cached BV may be used across DICTs or Charstrings if inputs */ + /* have not changed. */ + /* */ + /* `usedBV' is reset at the start of each parse or charstring. */ + /* vsindex cannot be changed after a BV is used. */ + /* */ + /* Note: NDV is long (32/64 bit), while BV is 16.16 (FT_Int32). */ + typedef struct CFF_BlendRec_ + { + FT_Bool builtBV; /* blendV has been built */ + FT_Bool usedBV; /* blendV has been used */ + CFF_Font font; /* top level font struct */ + FT_UInt lastVsindex; /* last vsindex used */ + FT_UInt lenNDV; /* normDV length (aka numAxes) */ + FT_Fixed* lastNDV; /* last NDV used */ + FT_UInt lenBV; /* BlendV length (aka numMasters) */ + FT_Int32* BV; /* current blendV (per DICT/glyph) */ + + } CFF_BlendRec, *CFF_Blend; + + typedef struct CFF_FontRecDictRec_ { FT_UInt version; @@ -151,9 +225,17 @@ FT_UShort num_designs; FT_UShort num_axes; + /* fields for CFF2 */ + FT_ULong vstore_offset; + FT_UInt maxstack; + } CFF_FontRecDictRec, *CFF_FontRecDict; + /* forward reference */ + typedef struct CFF_SubFontRec_* CFF_SubFont; + + typedef struct CFF_PrivateRec_ { FT_Byte num_blue_values; @@ -186,6 +268,10 @@ FT_Pos default_width; FT_Pos nominal_width; + /* fields for CFF2 */ + FT_UInt vsindex; + CFF_SubFont subfont; + } CFF_PrivateRec, *CFF_Private; @@ -213,19 +299,40 @@ CFF_FontRecDictRec font_dict; CFF_PrivateRec private_dict; - CFF_IndexRec local_subrs_index; - FT_Byte** local_subrs; /* array of pointers into Local Subrs INDEX data */ + /* fields for CFF2 */ + CFF_BlendRec blend; /* current blend vector */ + FT_UInt lenNDV; /* current length NDV or zero */ + FT_Fixed* NDV; /* ptr to current NDV or NULL */ - } CFF_SubFontRec, *CFF_SubFont; + /* `blend_stack' is a writable buffer to hold blend results. */ + /* This buffer is to the side of the normal cff parser stack; */ + /* `cff_parse_blend' and `cff_blend_doBlend' push blend results here. */ + /* The normal stack then points to these values instead of the DICT */ + /* because all other operators in Private DICT clear the stack. */ + /* `blend_stack' could be cleared at each operator other than blend. */ + /* Blended values are stored as 5-byte fixed point values. */ + FT_Byte* blend_stack; /* base of stack allocation */ + FT_Byte* blend_top; /* first empty slot */ + FT_UInt blend_used; /* number of bytes in use */ + FT_UInt blend_alloc; /* number of bytes allocated */ + CFF_IndexRec local_subrs_index; + FT_Byte** local_subrs; /* array of pointers */ + /* into Local Subrs INDEX data */ + + } CFF_SubFontRec; + + #define CFF_MAX_CID_FONTS 256 typedef struct CFF_FontRec_ { + FT_Library library; FT_Stream stream; - FT_Memory memory; + FT_Memory memory; /* TODO: take this from stream->memory? */ + FT_ULong base_offset; /* offset to start of CFF */ FT_UInt num_faces; FT_UInt num_glyphs; @@ -232,9 +339,11 @@ FT_Byte version_major; FT_Byte version_minor; FT_Byte header_size; - FT_Byte absolute_offsize; + FT_UInt top_dict_length; /* cff2 only */ + FT_Bool cff2; + CFF_IndexRec name_index; CFF_IndexRec top_dict_index; CFF_IndexRec global_subrs_index; @@ -280,9 +389,11 @@ /* since version 2.4.12 */ FT_Generic cf2_instance; - } CFF_FontRec, *CFF_Font; + CFF_VStoreRec vstore; /* parsed vstore structure */ + } CFF_FontRec; + FT_END_HEADER #endif /* CFFTYPES_H_ */ Index: reactos/sdk/lib/3rdparty/freetype/src/cid/cidload.c =================================================================== --- reactos/sdk/lib/3rdparty/freetype/src/cid/cidload.c (revision 74184) +++ reactos/sdk/lib/3rdparty/freetype/src/cid/cidload.c (working copy) @@ -570,7 +570,7 @@ { FT_UNUSED( face ); - FT_MEM_ZERO( loader, sizeof ( *loader ) ); + FT_ZERO( loader ); } @@ -733,9 +733,11 @@ } /* we must convert the data section from hexadecimal to binary */ - if ( FT_ALLOC( face->binary_data, parser->binary_length ) || - cid_hex_to_binary( face->binary_data, parser->binary_length, - parser->data_offset, face ) ) + if ( FT_ALLOC( face->binary_data, parser->binary_length ) || + FT_SET_ERROR( cid_hex_to_binary( face->binary_data, + parser->binary_length, + parser->data_offset, + face ) ) ) goto Exit; FT_Stream_OpenMemory( face->cid_stream, Index: reactos/sdk/lib/3rdparty/freetype/src/cid/cidparse.c =================================================================== --- reactos/sdk/lib/3rdparty/freetype/src/cid/cidparse.c (revision 74184) +++ reactos/sdk/lib/3rdparty/freetype/src/cid/cidparse.c (working copy) @@ -65,7 +65,7 @@ FT_Byte *arg1, *arg2; - FT_MEM_ZERO( parser, sizeof ( *parser ) ); + FT_ZERO( parser ); psaux->ps_parser_funcs->init( &parser->root, 0, 0, memory ); parser->stream = stream; @@ -138,13 +138,13 @@ ft_strncmp( (char*)p, STARTDATA, STARTDATA_LEN ) == 0 ) { /* save offset of binary data after `StartData' */ - offset += (FT_ULong)( p - buffer ) + STARTDATA_LEN; + offset += (FT_ULong)( p - buffer ) + STARTDATA_LEN + 1; goto Found; } else if ( p[1] == 's' && ft_strncmp( (char*)p, SFNTS, SFNTS_LEN ) == 0 ) { - offset += (FT_ULong)( p - buffer ) + SFNTS_LEN; + offset += (FT_ULong)( p - buffer ) + SFNTS_LEN + 1; goto Found; } } Index: reactos/sdk/lib/3rdparty/freetype/src/cid/cidriver.c =================================================================== --- reactos/sdk/lib/3rdparty/freetype/src/cid/cidriver.c (revision 74184) +++ reactos/sdk/lib/3rdparty/freetype/src/cid/cidriver.c (working copy) @@ -206,7 +206,7 @@ 0x10000L, /* version 1.0 of driver */ 0x20000L, /* requires FreeType 2.0 */ - 0, /* module-specific interface */ + NULL, /* module-specific interface */ cid_driver_init, /* FT_Module_Constructor module_init */ cid_driver_done, /* FT_Module_Destructor module_done */ @@ -226,12 +226,12 @@ cid_slot_load_glyph, /* FT_Slot_LoadFunc load_glyph */ - 0, /* FT_Face_GetKerningFunc get_kerning */ - 0, /* FT_Face_AttachFunc attach_file */ - 0, /* FT_Face_GetAdvancesFunc get_advances */ + NULL, /* FT_Face_GetKerningFunc get_kerning */ + NULL, /* FT_Face_AttachFunc attach_file */ + NULL, /* FT_Face_GetAdvancesFunc get_advances */ cid_size_request, /* FT_Size_RequestFunc request_size */ - 0 /* FT_Size_SelectFunc select_size */ + NULL /* FT_Size_SelectFunc select_size */ }; Index: reactos/sdk/lib/3rdparty/freetype/src/gxvalid/gxvcommn.c =================================================================== --- reactos/sdk/lib/3rdparty/freetype/src/gxvalid/gxvcommn.c (revision 74184) +++ reactos/sdk/lib/3rdparty/freetype/src/gxvalid/gxvcommn.c (working copy) @@ -789,7 +789,7 @@ FT_INVALID_FORMAT; func = fmt_funcs_table[format]; - if ( func == NULL ) + if ( !func ) FT_INVALID_FORMAT; func( p, limit, gxvalid ); @@ -972,7 +972,7 @@ FT_UShort i; - ft_memset( nGlyphInClass, 0, 256 ); + FT_MEM_ZERO( nGlyphInClass, 256 ); for ( i = 0; i < nGlyphs; i++ ) @@ -1161,7 +1161,7 @@ break; } - if ( NULL != gxvalid->statetable.entry_validate_func ) + if ( gxvalid->statetable.entry_validate_func ) gxvalid->statetable.entry_validate_func( state, flags, &glyphOffset, @@ -1244,10 +1244,10 @@ if ( stateSize > 0xFF ) FT_INVALID_DATA; - if ( gxvalid->statetable.optdata_load_func != NULL ) + if ( gxvalid->statetable.optdata_load_func ) gxvalid->statetable.optdata_load_func( p, limit, gxvalid ); - if ( gxvalid->statetable.subtable_setup_func != NULL) + if ( gxvalid->statetable.subtable_setup_func ) setup_func = gxvalid->statetable.subtable_setup_func; else setup_func = gxv_StateTable_subtable_setup; @@ -1534,7 +1534,7 @@ goto Exit; } - if ( NULL != gxvalid->xstatetable.entry_validate_func ) + if ( gxvalid->xstatetable.entry_validate_func ) gxvalid->xstatetable.entry_validate_func( state, flags, &glyphOffset, @@ -1591,10 +1591,10 @@ GXV_TRACE(( "StateTable Subtables\n" )); - if ( gxvalid->xstatetable.optdata_load_func != NULL ) + if ( gxvalid->xstatetable.optdata_load_func ) gxvalid->xstatetable.optdata_load_func( p, limit, gxvalid ); - if ( gxvalid->xstatetable.subtable_setup_func != NULL ) + if ( gxvalid->xstatetable.subtable_setup_func ) setup_func = gxvalid->xstatetable.subtable_setup_func; else setup_func = gxv_XStateTable_subtable_setup; Index: reactos/sdk/lib/3rdparty/freetype/src/gxvalid/gxvmod.c =================================================================== --- reactos/sdk/lib/3rdparty/freetype/src/gxvalid/gxvmod.c (revision 74184) +++ reactos/sdk/lib/3rdparty/freetype/src/gxvalid/gxvmod.c (working copy) @@ -274,11 +274,11 @@ 0x10000L, 0x20000L, - 0, /* module-specific interface */ + NULL, /* module-specific interface */ - (FT_Module_Constructor)0, - (FT_Module_Destructor) 0, - (FT_Module_Requester) gxvalid_get_service + (FT_Module_Constructor)NULL, /* module_init */ + (FT_Module_Destructor) NULL, /* module_done */ + (FT_Module_Requester) gxvalid_get_service /* get_interface */ }; Index: reactos/sdk/lib/3rdparty/freetype/src/gxvalid/gxvmort.c =================================================================== --- reactos/sdk/lib/3rdparty/freetype/src/gxvalid/gxvmort.c (revision 74184) +++ reactos/sdk/lib/3rdparty/freetype/src/gxvalid/gxvmort.c (working copy) @@ -205,7 +205,7 @@ FT_INVALID_FORMAT; func = fmt_funcs_table[type]; - if ( func == NULL ) + if ( !func ) GXV_TRACE(( "morx type %d is reserved\n", type )); func( p, p + rest, gxvalid ); Index: reactos/sdk/lib/3rdparty/freetype/src/gxvalid/gxvmorx.c =================================================================== --- reactos/sdk/lib/3rdparty/freetype/src/gxvalid/gxvmorx.c (revision 74184) +++ reactos/sdk/lib/3rdparty/freetype/src/gxvalid/gxvmorx.c (working copy) @@ -98,7 +98,7 @@ FT_INVALID_FORMAT; func = fmt_funcs_table[type]; - if ( func == NULL ) + if ( !func ) GXV_TRACE(( "morx type %d is reserved\n", type )); func( p, p + rest, gxvalid ); Index: reactos/sdk/lib/3rdparty/freetype/src/gzip/ftgzip.c =================================================================== --- reactos/sdk/lib/3rdparty/freetype/src/gzip/ftgzip.c (revision 74184) +++ reactos/sdk/lib/3rdparty/freetype/src/gzip/ftgzip.c (working copy) @@ -51,17 +51,29 @@ #else /* !FT_CONFIG_OPTION_SYSTEM_ZLIB */ - /* In this case, we include our own modified sources of the ZLib */ - /* within the "ftgzip" component. The modifications were necessary */ - /* to #include all files without conflicts, as well as preventing */ - /* the definition of "extern" functions that may cause linking */ - /* conflicts when a program is linked with both FreeType and the */ - /* original ZLib. */ + /* In this case, we include our own modified sources of the ZLib */ + /* within the `gzip' component. The modifications were necessary */ + /* to #include all files without conflicts, as well as preventing */ + /* the definition of `extern' functions that may cause linking */ + /* conflicts when a program is linked with both FreeType and the */ + /* original ZLib. */ #ifndef USE_ZLIB_ZCALLOC #define MY_ZCALLOC /* prevent all zcalloc() & zfree() in zutil.c */ #endif + /* Note that our `zlib.h' includes `ftzconf.h' instead of `zconf.h'; */ + /* the main reason is that even a global `zlib.h' includes `zconf.h' */ + /* with */ + /* */ + /* #include "zconf.h" */ + /* */ + /* instead of the expected */ + /* */ + /* #include */ + /* */ + /* so that configuration with `FT_CONFIG_OPTION_SYSTEM_ZLIB' might */ + /* include the wrong `zconf.h' file, leading to errors. */ #include "zlib.h" #undef SLOW @@ -305,7 +317,7 @@ zstream->next_in = zip->buffer; if ( inflateInit2( zstream, -MAX_WBITS ) != Z_OK || - zstream->next_in == NULL ) + !zstream->next_in ) error = FT_THROW( Invalid_File_Format ); Exit: Index: reactos/sdk/lib/3rdparty/freetype/src/gzip/ftzconf.h =================================================================== --- reactos/sdk/lib/3rdparty/freetype/src/gzip/ftzconf.h (nonexistent) +++ reactos/sdk/lib/3rdparty/freetype/src/gzip/ftzconf.h (working copy) @@ -0,0 +1,284 @@ +/* zconf.h -- configuration of the zlib compression library + * Copyright (C) 1995-2002 Jean-loup Gailly. + * For conditions of distribution and use, see copyright notice in zlib.h + */ + +/* @(#) $Id$ */ + +#ifndef _ZCONF_H +#define _ZCONF_H + +/* + * If you *really* need a unique prefix for all types and library functions, + * compile with -DZ_PREFIX. The "standard" zlib should be compiled without it. + */ +#ifdef Z_PREFIX +# define deflateInit_ z_deflateInit_ +# define deflate z_deflate +# define deflateEnd z_deflateEnd +# define inflateInit_ z_inflateInit_ +# define inflate z_inflate +# define inflateEnd z_inflateEnd +# define deflateInit2_ z_deflateInit2_ +# define deflateSetDictionary z_deflateSetDictionary +# define deflateCopy z_deflateCopy +# define deflateReset z_deflateReset +# define deflateParams z_deflateParams +# define inflateInit2_ z_inflateInit2_ +# define inflateSetDictionary z_inflateSetDictionary +# define inflateSync z_inflateSync +# define inflateSyncPoint z_inflateSyncPoint +# define inflateReset z_inflateReset +# define compress z_compress +# define compress2 z_compress2 +# define uncompress z_uncompress +# define adler32 z_adler32 +# define crc32 z_crc32 +# define get_crc_table z_get_crc_table + +# define Byte z_Byte +# define uInt z_uInt +# define uLong z_uLong +# define Bytef z_Bytef +# define charf z_charf +# define intf z_intf +# define uIntf z_uIntf +# define uLongf z_uLongf +# define voidpf z_voidpf +# define voidp z_voidp +#endif + +#if (defined(_WIN32) || defined(__WIN32__)) && !defined(WIN32) +# define WIN32 +#endif +#if defined(__GNUC__) || defined(WIN32) || defined(__386__) || defined(i386) +# ifndef __32BIT__ +# define __32BIT__ +# endif +#endif +#if defined(__MSDOS__) && !defined(MSDOS) +# define MSDOS +#endif + +/* WinCE doesn't have errno.h */ +#ifdef _WIN32_WCE +# define NO_ERRNO_H +#endif + + +/* + * Compile with -DMAXSEG_64K if the alloc function cannot allocate more + * than 64k bytes at a time (needed on systems with 16-bit int). + */ +#if defined(MSDOS) && !defined(__32BIT__) +# define MAXSEG_64K +#endif +#ifdef MSDOS +# define UNALIGNED_OK +#endif + +#if (defined(MSDOS) || defined(_WINDOWS) || defined(WIN32)) && !defined(STDC) +# define STDC +#endif +#if defined(__STDC__) || defined(__cplusplus) || defined(__OS2__) +# ifndef STDC +# define STDC +# endif +#endif + +#ifndef STDC +# ifndef const /* cannot use !defined(STDC) && !defined(const) on Mac */ +# define const +# endif +#endif + +/* Some Mac compilers merge all .h files incorrectly: */ +#if defined(__MWERKS__) || defined(applec) ||defined(THINK_C) ||defined(__SC__) +# define NO_DUMMY_DECL +#endif + +/* Old Borland C and LCC incorrectly complains about missing returns: */ +#if defined(__BORLANDC__) && (__BORLANDC__ < 0x500) +# define NEED_DUMMY_RETURN +#endif + +#if defined(__LCC__) +# define NEED_DUMMY_RETURN +#endif + +/* Maximum value for memLevel in deflateInit2 */ +#ifndef MAX_MEM_LEVEL +# ifdef MAXSEG_64K +# define MAX_MEM_LEVEL 8 +# else +# define MAX_MEM_LEVEL 9 +# endif +#endif + +/* Maximum value for windowBits in deflateInit2 and inflateInit2. + * WARNING: reducing MAX_WBITS makes minigzip unable to extract .gz files + * created by gzip. (Files created by minigzip can still be extracted by + * gzip.) + */ +#ifndef MAX_WBITS +# define MAX_WBITS 15 /* 32K LZ77 window */ +#endif + +/* The memory requirements for deflate are (in bytes): + (1 << (windowBits+2)) + (1 << (memLevel+9)) + that is: 128K for windowBits=15 + 128K for memLevel = 8 (default values) + plus a few kilobytes for small objects. For example, if you want to reduce + the default memory requirements from 256K to 128K, compile with + make CFLAGS="-O -DMAX_WBITS=14 -DMAX_MEM_LEVEL=7" + Of course this will generally degrade compression (there's no free lunch). + + The memory requirements for inflate are (in bytes) 1 << windowBits + that is, 32K for windowBits=15 (default value) plus a few kilobytes + for small objects. +*/ + + /* Type declarations */ + +#ifndef OF /* function prototypes */ +# ifdef STDC +# define OF(args) args +# else +# define OF(args) () +# endif +#endif + +/* The following definitions for FAR are needed only for MSDOS mixed + * model programming (small or medium model with some far allocations). + * This was tested only with MSC; for other MSDOS compilers you may have + * to define NO_MEMCPY in zutil.h. If you don't need the mixed model, + * just define FAR to be empty. + */ +#if (defined(M_I86SM) || defined(M_I86MM)) && !defined(__32BIT__) + /* MSC small or medium model */ +# define SMALL_MEDIUM +# ifdef _MSC_VER +# define FAR _far +# else +# define FAR far +# endif +#endif +#if defined(__BORLANDC__) && (defined(__SMALL__) || defined(__MEDIUM__)) +# ifndef __32BIT__ +# define SMALL_MEDIUM +# define FAR _far +# endif +#endif + +/* Compile with -DZLIB_DLL for Windows DLL support */ +#if defined(ZLIB_DLL) +# if defined(_WINDOWS) || defined(WINDOWS) +# ifdef FAR +# undef FAR +# endif +# include +# define ZEXPORT(x) x WINAPI +# ifdef WIN32 +# define ZEXPORTVA(x) x WINAPIV +# else +# define ZEXPORTVA(x) x FAR _cdecl _export +# endif +# endif +# if defined (__BORLANDC__) +# if (__BORLANDC__ >= 0x0500) && defined (WIN32) +# include +# define ZEXPORT(x) x __declspec(dllexport) WINAPI +# define ZEXPORTRVA(x) x __declspec(dllexport) WINAPIV +# else +# if defined (_Windows) && defined (__DLL__) +# define ZEXPORT(x) x _export +# define ZEXPORTVA(x) x _export +# endif +# endif +# endif +#endif + + +#ifndef ZEXPORT +# define ZEXPORT(x) static x +#endif +#ifndef ZEXPORTVA +# define ZEXPORTVA(x) static x +#endif +#ifndef ZEXTERN +# define ZEXTERN(x) static x +#endif +#ifndef ZEXTERNDEF +# define ZEXTERNDEF(x) static x +#endif + +#ifndef FAR +# define FAR +#endif + +#if !defined(MACOS) && !defined(TARGET_OS_MAC) +typedef unsigned char Byte; /* 8 bits */ +#endif +typedef unsigned int uInt; /* 16 bits or more */ +typedef unsigned long uLong; /* 32 bits or more */ + +#ifdef SMALL_MEDIUM + /* Borland C/C++ and some old MSC versions ignore FAR inside typedef */ +# define Bytef Byte FAR +#else + typedef Byte FAR Bytef; +#endif +typedef char FAR charf; +typedef int FAR intf; +typedef uInt FAR uIntf; +typedef uLong FAR uLongf; + +#ifdef STDC + typedef void FAR *voidpf; + typedef void *voidp; +#else + typedef Byte FAR *voidpf; + typedef Byte *voidp; +#endif + +#ifdef HAVE_UNISTD_H +# include /* for off_t */ +# include /* for SEEK_* and off_t */ +# define z_off_t off_t +#endif +#ifndef SEEK_SET +# define SEEK_SET 0 /* Seek from beginning of file. */ +# define SEEK_CUR 1 /* Seek from current position. */ +# define SEEK_END 2 /* Set file pointer to EOF plus "offset" */ +#endif +#ifndef z_off_t +# define z_off_t long +#endif + +/* MVS linker does not support external names larger than 8 bytes */ +#if defined(__MVS__) +# pragma map(deflateInit_,"DEIN") +# pragma map(deflateInit2_,"DEIN2") +# pragma map(deflateEnd,"DEEND") +# pragma map(inflateInit_,"ININ") +# pragma map(inflateInit2_,"ININ2") +# pragma map(inflateEnd,"INEND") +# pragma map(inflateSync,"INSY") +# pragma map(inflateSetDictionary,"INSEDI") +# pragma map(inflate_blocks,"INBL") +# pragma map(inflate_blocks_new,"INBLNE") +# pragma map(inflate_blocks_free,"INBLFR") +# pragma map(inflate_blocks_reset,"INBLRE") +# pragma map(inflate_codes_free,"INCOFR") +# pragma map(inflate_codes,"INCO") +# pragma map(inflate_fast,"INFA") +# pragma map(inflate_flush,"INFLU") +# pragma map(inflate_mask,"INMA") +# pragma map(inflate_set_dictionary,"INSEDI2") +# pragma map(inflate_copyright,"INCOPY") +# pragma map(inflate_trees_bits,"INTRBI") +# pragma map(inflate_trees_dynamic,"INTRDY") +# pragma map(inflate_trees_fixed,"INTRFI") +# pragma map(inflate_trees_free,"INTRFR") +#endif + +#endif /* _ZCONF_H */ Index: reactos/sdk/lib/3rdparty/freetype/src/gzip/zlib.h =================================================================== --- reactos/sdk/lib/3rdparty/freetype/src/gzip/zlib.h (revision 74184) +++ reactos/sdk/lib/3rdparty/freetype/src/gzip/zlib.h (working copy) @@ -31,7 +31,7 @@ #ifndef _ZLIB_H #define _ZLIB_H -#include "zconf.h" +#include "ftzconf.h" #ifdef __cplusplus extern "C" { Index: reactos/sdk/lib/3rdparty/freetype/src/lzw/ftzopen.c =================================================================== --- reactos/sdk/lib/3rdparty/freetype/src/lzw/ftzopen.c (revision 74184) +++ reactos/sdk/lib/3rdparty/freetype/src/lzw/ftzopen.c (working copy) @@ -374,7 +374,7 @@ { while ( state->stack_top > 0 ) { - --state->stack_top; + state->stack_top--; if ( buffer ) buffer[result] = state->stack[state->stack_top]; Index: reactos/sdk/lib/3rdparty/freetype/src/otvalid/otvcommn.c =================================================================== --- reactos/sdk/lib/3rdparty/freetype/src/otvalid/otvcommn.c (revision 74184) +++ reactos/sdk/lib/3rdparty/freetype/src/otvalid/otvcommn.c (working copy) @@ -68,7 +68,7 @@ OTV_LIMIT_CHECK( GlyphCount * 2 ); /* GlyphArray */ - for ( i = 0; i < GlyphCount; ++i ) + for ( i = 0; i < GlyphCount; i++ ) { FT_UInt gid; Index: reactos/sdk/lib/3rdparty/freetype/src/otvalid/otvmath.c =================================================================== --- reactos/sdk/lib/3rdparty/freetype/src/otvalid/otvmath.c (revision 74184) +++ reactos/sdk/lib/3rdparty/freetype/src/otvalid/otvmath.c (working copy) @@ -60,7 +60,7 @@ table_size = 2 * ( 56 + 51 ); p += 4 * 2; /* First 4 constants have no device tables */ - for ( i = 0; i < 51; ++i ) + for ( i = 0; i < 51; i++ ) { p += 2; /* skip the value */ OTV_OPTIONAL_OFFSET( DeviceTableOffset ); @@ -110,7 +110,7 @@ OTV_SIZE_CHECK( Coverage ); otv_Coverage_validate( table + Coverage, otvalid, (FT_Int)cnt ); - for ( i = 0; i < cnt; ++i ) + for ( i = 0; i < cnt; i++ ) { p += 2; /* Skip the value */ OTV_OPTIONAL_OFFSET( DeviceTableOffset ); @@ -151,7 +151,7 @@ table_size = 4 + 4 * cnt; /* Heights */ - for ( i = 0; i < cnt; ++i ) + for ( i = 0; i < cnt; i++ ) { p += 2; /* Skip the value */ OTV_OPTIONAL_OFFSET( DeviceTableOffset ); @@ -161,7 +161,7 @@ } /* One more Kerning value */ - for ( i = 0; i < cnt + 1; ++i ) + for ( i = 0; i < cnt + 1; i++ ) { p += 2; /* Skip the value */ OTV_OPTIONAL_OFFSET( DeviceTableOffset ); @@ -198,9 +198,9 @@ OTV_SIZE_CHECK( Coverage ); otv_Coverage_validate( table + Coverage, otvalid, (FT_Int)cnt ); - for ( i = 0; i < cnt; ++i ) + for ( i = 0; i < cnt; i++ ) { - for ( j = 0; j < 4; ++j ) + for ( j = 0; j < 4; j++ ) { OTV_OPTIONAL_OFFSET( MKRecordOffset ); OTV_SIZE_CHECK( MKRecordOffset ); @@ -296,7 +296,7 @@ if ( DeviceTableOffset ) otv_Device_validate( table + DeviceTableOffset, otvalid ); - for ( i = 0; i < pcnt; ++i ) + for ( i = 0; i < pcnt; i++ ) { FT_UInt gid; @@ -332,7 +332,7 @@ OTV_LIMIT_CHECK( 4 * vcnt ); table_size = 4 + 4 * vcnt; - for ( i = 0; i < vcnt; ++i ) + for ( i = 0; i < vcnt; i++ ) { FT_UInt gid; @@ -384,7 +384,7 @@ if ( HCoverage ) otv_Coverage_validate( table + HCoverage, otvalid, (FT_Int)hcnt ); - for ( i = 0; i < vcnt; ++i ) + for ( i = 0; i < vcnt; i++ ) { OTV_OPTIONAL_OFFSET( Offset ); OTV_SIZE_CHECK( Offset ); @@ -391,7 +391,7 @@ otv_MathGlyphConstruction_validate( table + Offset, otvalid ); } - for ( i = 0; i < hcnt; ++i ) + for ( i = 0; i < hcnt; i++ ) { OTV_OPTIONAL_OFFSET( Offset ); OTV_SIZE_CHECK( Offset ); Index: reactos/sdk/lib/3rdparty/freetype/src/otvalid/otvmod.c =================================================================== --- reactos/sdk/lib/3rdparty/freetype/src/otvalid/otvmod.c (revision 74184) +++ reactos/sdk/lib/3rdparty/freetype/src/otvalid/otvmod.c (working copy) @@ -271,11 +271,11 @@ 0x10000L, 0x20000L, - 0, /* module-specific interface */ + NULL, /* module-specific interface */ - (FT_Module_Constructor)0, - (FT_Module_Destructor) 0, - (FT_Module_Requester) otvalid_get_service + (FT_Module_Constructor)NULL, /* module_init */ + (FT_Module_Destructor) NULL, /* module_done */ + (FT_Module_Requester) otvalid_get_service /* get_interface */ }; Index: reactos/sdk/lib/3rdparty/freetype/src/pcf/pcfdrivr.c =================================================================== --- reactos/sdk/lib/3rdparty/freetype/src/pcf/pcfdrivr.c (revision 74184) +++ reactos/sdk/lib/3rdparty/freetype/src/pcf/pcfdrivr.c (working copy) @@ -492,9 +492,7 @@ PCF_Metric metric; FT_ULong bytes; - FT_UNUSED( load_flags ); - FT_TRACE1(( "PCF_Glyph_Load: glyph index %d\n", glyph_index )); if ( !face ) @@ -550,6 +548,24 @@ return FT_THROW( Invalid_File_Format ); } + slot->format = FT_GLYPH_FORMAT_BITMAP; + slot->bitmap_left = metric->leftSideBearing; + slot->bitmap_top = metric->ascent; + + slot->metrics.horiAdvance = (FT_Pos)( metric->characterWidth * 64 ); + slot->metrics.horiBearingX = (FT_Pos)( metric->leftSideBearing * 64 ); + slot->metrics.horiBearingY = (FT_Pos)( metric->ascent * 64 ); + slot->metrics.width = (FT_Pos)( ( metric->rightSideBearing - + metric->leftSideBearing ) * 64 ); + slot->metrics.height = (FT_Pos)( bitmap->rows * 64 ); + + ft_synthesize_vertical_metrics( &slot->metrics, + ( face->accel.fontAscent + + face->accel.fontDescent ) * 64 ); + + if ( load_flags & FT_LOAD_BITMAP_METRICS_ONLY ) + goto Exit; + /* XXX: to do: are there cases that need repadding the bitmap? */ bytes = (FT_ULong)bitmap->pitch * bitmap->rows; @@ -582,21 +598,6 @@ } } - slot->format = FT_GLYPH_FORMAT_BITMAP; - slot->bitmap_left = metric->leftSideBearing; - slot->bitmap_top = metric->ascent; - - slot->metrics.horiAdvance = (FT_Pos)( metric->characterWidth * 64 ); - slot->metrics.horiBearingX = (FT_Pos)( metric->leftSideBearing * 64 ); - slot->metrics.horiBearingY = (FT_Pos)( metric->ascent * 64 ); - slot->metrics.width = (FT_Pos)( ( metric->rightSideBearing - - metric->leftSideBearing ) * 64 ); - slot->metrics.height = (FT_Pos)( bitmap->rows * 64 ); - - ft_synthesize_vertical_metrics( &slot->metrics, - ( face->accel.fontAscent + - face->accel.fontDescent ) * 64 ); - Exit: return error; } @@ -617,7 +618,7 @@ prop = pcf_find_property( face, prop_name ); - if ( prop != NULL ) + if ( prop ) { if ( prop->isString ) { @@ -700,10 +701,10 @@ 0x10000L, 0x20000L, - 0, /* module-specific interface */ + NULL, /* module-specific interface */ - 0, /* FT_Module_Constructor module_init */ - 0, /* FT_Module_Destructor module_done */ + NULL, /* FT_Module_Constructor module_init */ + NULL, /* FT_Module_Destructor module_done */ pcf_driver_requester /* FT_Module_Requester get_interface */ }, @@ -713,16 +714,16 @@ PCF_Face_Init, /* FT_Face_InitFunc init_face */ PCF_Face_Done, /* FT_Face_DoneFunc done_face */ - 0, /* FT_Size_InitFunc init_size */ - 0, /* FT_Size_DoneFunc done_size */ - 0, /* FT_Slot_InitFunc init_slot */ - 0, /* FT_Slot_DoneFunc done_slot */ + NULL, /* FT_Size_InitFunc init_size */ + NULL, /* FT_Size_DoneFunc done_size */ + NULL, /* FT_Slot_InitFunc init_slot */ + NULL, /* FT_Slot_DoneFunc done_slot */ PCF_Glyph_Load, /* FT_Slot_LoadFunc load_glyph */ - 0, /* FT_Face_GetKerningFunc get_kerning */ - 0, /* FT_Face_AttachFunc attach_file */ - 0, /* FT_Face_GetAdvancesFunc get_advances */ + NULL, /* FT_Face_GetKerningFunc get_kerning */ + NULL, /* FT_Face_AttachFunc attach_file */ + NULL, /* FT_Face_GetAdvancesFunc get_advances */ PCF_Size_Request, /* FT_Size_RequestFunc request_size */ PCF_Size_Select /* FT_Size_SelectFunc select_size */ Index: reactos/sdk/lib/3rdparty/freetype/src/pcf/pcfread.c =================================================================== --- reactos/sdk/lib/3rdparty/freetype/src/pcf/pcfread.c (revision 74184) +++ reactos/sdk/lib/3rdparty/freetype/src/pcf/pcfread.c (working copy) @@ -109,13 +109,18 @@ if ( stream->size < 16 ) return FT_THROW( Invalid_File_Format ); - /* we need 16 bytes per TOC entry */ - if ( toc->count > stream->size >> 4 ) + /* We need 16 bytes per TOC entry. Additionally, as a */ + /* heuristic protection against gzip bombs (i.e., very */ + /* small input files that expand to insanely large */ + /* files), we limit the number of TOC entries to 1024. */ + if ( toc->count > stream->size >> 4 || + toc->count > 1024 ) { FT_TRACE0(( "pcf_read_TOC: adjusting number of tables" " (from %d to %d)\n", - toc->count, stream->size >> 4 )); - toc->count = stream->size >> 4; + toc->count, + FT_MIN( stream->size >> 4, 1024 ) )); + toc->count = FT_MIN( stream->size >> 4, 1024 ); } if ( FT_NEW_ARRAY( face->toc.tables, toc->count ) ) @@ -319,7 +324,7 @@ /* parsing normal metrics */ - fields = PCF_BYTE_ORDER( format ) == MSBFirst + fields = ( PCF_BYTE_ORDER( format ) == MSBFirst ) ? pcf_metric_msb_header : pcf_metric_header; @@ -1156,7 +1161,7 @@ len = lengths[nn]; - if ( src == NULL ) + if ( !src ) continue; /* separate elements with a space */ @@ -1260,14 +1265,63 @@ if ( face->accel.constantWidth ) root->face_flags |= FT_FACE_FLAG_FIXED_WIDTH; - if ( ( error = pcf_interpret_style( face ) ) != 0 ) - goto Exit; + if ( FT_SET_ERROR( pcf_interpret_style( face ) ) ) + goto Exit; prop = pcf_find_property( face, "FAMILY_NAME" ); if ( prop && prop->isString ) { - if ( FT_STRDUP( root->family_name, prop->value.atom ) ) - goto Exit; + /* Prepend the foundry name plus a space to the family name. */ + /* There are many fonts just called `Fixed' which look completely */ + /* different, and which have nothing to do with each other. When */ + /* selecting `Fixed' in KDE or Gnome one gets results that appear */ + /* rather random, the style changes often if one changes the size */ + /* and one cannot select some fonts at all. */ + /* */ + /* We also check whether we have `wide' characters; all put */ + /* together, we get family names like `Sony Fixed' or `Misc Fixed */ + /* Wide'. */ + PCF_Property foundry_prop, point_size_prop, average_width_prop; + + int l = ft_strlen( prop->value.atom ) + 1; + int wide = 0; + + + foundry_prop = pcf_find_property( face, "FOUNDRY" ); + point_size_prop = pcf_find_property( face, "POINT_SIZE" ); + average_width_prop = pcf_find_property( face, "AVERAGE_WIDTH" ); + + if ( point_size_prop && average_width_prop ) + { + if ( average_width_prop->value.l >= point_size_prop->value.l ) + { + /* This font is at least square shaped or even wider */ + wide = 1; + l += ft_strlen( " Wide" ); + } + } + + if ( foundry_prop && foundry_prop->isString ) + { + l += ft_strlen( foundry_prop->value.atom ) + 1; + + if ( FT_NEW_ARRAY( root->family_name, l ) ) + goto Exit; + + ft_strcpy( root->family_name, foundry_prop->value.atom ); + ft_strcat( root->family_name, " " ); + ft_strcat( root->family_name, prop->value.atom ); + } + else + { + if ( FT_NEW_ARRAY( root->family_name, l ) ) + goto Exit; + + ft_strcpy( root->family_name, prop->value.atom ); + } + + if ( wide ) + ft_strcat( root->family_name, " Wide" ); } else root->family_name = NULL; @@ -1290,7 +1344,7 @@ FT_Short resolution_x = 0, resolution_y = 0; - FT_MEM_ZERO( bsize, sizeof ( FT_Bitmap_Size ) ); + FT_ZERO( bsize ); /* for simplicity, we take absolute values of integer properties */ Index: reactos/sdk/lib/3rdparty/freetype/src/pfr/pfrcmap.c =================================================================== --- reactos/sdk/lib/3rdparty/freetype/src/pfr/pfrcmap.c (revision 74184) +++ reactos/sdk/lib/3rdparty/freetype/src/pfr/pfrcmap.c (working copy) @@ -161,12 +161,16 @@ { sizeof ( PFR_CMapRec ), - (FT_CMap_InitFunc) pfr_cmap_init, - (FT_CMap_DoneFunc) pfr_cmap_done, - (FT_CMap_CharIndexFunc)pfr_cmap_char_index, - (FT_CMap_CharNextFunc) pfr_cmap_char_next, + (FT_CMap_InitFunc) pfr_cmap_init, /* init */ + (FT_CMap_DoneFunc) pfr_cmap_done, /* done */ + (FT_CMap_CharIndexFunc)pfr_cmap_char_index, /* char_index */ + (FT_CMap_CharNextFunc) pfr_cmap_char_next, /* char_next */ - NULL, NULL, NULL, NULL, NULL + (FT_CMap_CharVarIndexFunc) NULL, /* char_var_index */ + (FT_CMap_CharVarIsDefaultFunc)NULL, /* char_var_default */ + (FT_CMap_VariantListFunc) NULL, /* variant_list */ + (FT_CMap_CharVariantListFunc) NULL, /* charvariant_list */ + (FT_CMap_VariantCharListFunc) NULL /* variantchar_list */ }; Index: reactos/sdk/lib/3rdparty/freetype/src/pfr/pfrdrivr.c =================================================================== --- reactos/sdk/lib/3rdparty/freetype/src/pfr/pfrdrivr.c (revision 74184) +++ reactos/sdk/lib/3rdparty/freetype/src/pfr/pfrdrivr.c (working copy) @@ -181,10 +181,10 @@ 0x10000L, 0x20000L, - 0, /* module-specific interface */ + NULL, /* module-specific interface */ - 0, /* FT_Module_Constructor module_init */ - 0, /* FT_Module_Destructor module_done */ + NULL, /* FT_Module_Constructor module_init */ + NULL, /* FT_Module_Destructor module_done */ pfr_get_service /* FT_Module_Requester get_interface */ }, @@ -194,8 +194,8 @@ pfr_face_init, /* FT_Face_InitFunc init_face */ pfr_face_done, /* FT_Face_DoneFunc done_face */ - 0, /* FT_Size_InitFunc init_size */ - 0, /* FT_Size_DoneFunc done_size */ + NULL, /* FT_Size_InitFunc init_size */ + NULL, /* FT_Size_DoneFunc done_size */ pfr_slot_init, /* FT_Slot_InitFunc init_slot */ pfr_slot_done, /* FT_Slot_DoneFunc done_slot */ @@ -202,11 +202,11 @@ pfr_slot_load, /* FT_Slot_LoadFunc load_glyph */ pfr_get_kerning, /* FT_Face_GetKerningFunc get_kerning */ - 0, /* FT_Face_AttachFunc attach_file */ - 0, /* FT_Face_GetAdvancesFunc get_advances */ + NULL, /* FT_Face_AttachFunc attach_file */ + NULL, /* FT_Face_GetAdvancesFunc get_advances */ - 0, /* FT_Size_RequestFunc request_size */ - 0, /* FT_Size_SelectFunc select_size */ + NULL, /* FT_Size_RequestFunc request_size */ + NULL, /* FT_Size_SelectFunc select_size */ }; Index: reactos/sdk/lib/3rdparty/freetype/src/pfr/pfrload.c =================================================================== --- reactos/sdk/lib/3rdparty/freetype/src/pfr/pfrload.c (revision 74184) +++ reactos/sdk/lib/3rdparty/freetype/src/pfr/pfrload.c (working copy) @@ -562,7 +562,7 @@ FT_UInt len = (FT_UInt)( limit - p ); - if ( phy_font->font_id != NULL ) + if ( phy_font->font_id ) goto Exit; if ( FT_ALLOC( phy_font->font_id, len + 1 ) ) @@ -589,7 +589,7 @@ FT_Memory memory = phy_font->memory; - if ( phy_font->vertical.stem_snaps != NULL ) + if ( phy_font->vertical.stem_snaps ) goto Exit; PFR_CHECK( 1 ); Index: reactos/sdk/lib/3rdparty/freetype/src/pfr/pfrobjs.c =================================================================== --- reactos/sdk/lib/3rdparty/freetype/src/pfr/pfrobjs.c (revision 74184) +++ reactos/sdk/lib/3rdparty/freetype/src/pfr/pfrobjs.c (working copy) @@ -185,7 +185,7 @@ * nothing. */ pfrface->family_name = phy_font->family_name; - if ( pfrface->family_name == NULL ) + if ( !pfrface->family_name ) pfrface->family_name = phy_font->font_id; /* note that the style name can be NULL in certain PFR fonts, @@ -342,8 +342,12 @@ /* try to load an embedded bitmap */ if ( ( load_flags & ( FT_LOAD_NO_SCALE | FT_LOAD_NO_BITMAP ) ) == 0 ) { - error = pfr_slot_load_bitmap( slot, size, gindex ); - if ( error == 0 ) + error = pfr_slot_load_bitmap( + slot, + size, + gindex, + ( load_flags & FT_LOAD_BITMAP_METRICS_ONLY ) != 0 ); + if ( !error ) goto Exit; } Index: reactos/sdk/lib/3rdparty/freetype/src/pfr/pfrsbit.c =================================================================== --- reactos/sdk/lib/3rdparty/freetype/src/pfr/pfrsbit.c (revision 74184) +++ reactos/sdk/lib/3rdparty/freetype/src/pfr/pfrsbit.c (working copy) @@ -578,7 +578,8 @@ FT_LOCAL( FT_Error ) pfr_slot_load_bitmap( PFR_Slot glyph, PFR_Size size, - FT_UInt glyph_index ) + FT_UInt glyph_index, + FT_Bool metrics_only ) { FT_Error error; PFR_Face face = (PFR_Face) glyph->root.face; @@ -775,6 +776,9 @@ glyph->root.bitmap_left = (FT_Int)xpos; glyph->root.bitmap_top = (FT_Int)( ypos + (FT_Long)ysize ); + if ( metrics_only ) + goto Exit1; + /* Allocate and read bitmap data */ { FT_ULong len = (FT_ULong)glyph->root.bitmap.pitch * ysize; Index: reactos/sdk/lib/3rdparty/freetype/src/pfr/pfrsbit.h =================================================================== --- reactos/sdk/lib/3rdparty/freetype/src/pfr/pfrsbit.h (revision 74184) +++ reactos/sdk/lib/3rdparty/freetype/src/pfr/pfrsbit.h (working copy) @@ -26,7 +26,8 @@ FT_LOCAL( FT_Error ) pfr_slot_load_bitmap( PFR_Slot glyph, PFR_Size size, - FT_UInt glyph_index ); + FT_UInt glyph_index, + FT_Bool metrics_only ); FT_END_HEADER Index: reactos/sdk/lib/3rdparty/freetype/src/psaux/psauxmod.c =================================================================== --- reactos/sdk/lib/3rdparty/freetype/src/psaux/psauxmod.c (revision 74184) +++ reactos/sdk/lib/3rdparty/freetype/src/psaux/psauxmod.c (working copy) @@ -30,10 +30,10 @@ FT_CALLBACK_TABLE_DEF const PS_Table_FuncsRec ps_table_funcs = { - ps_table_new, - ps_table_done, - ps_table_add, - ps_table_release + ps_table_new, /* init */ + ps_table_done, /* done */ + ps_table_add, /* add */ + ps_table_release /* release */ }; @@ -40,19 +40,22 @@ FT_CALLBACK_TABLE_DEF const PS_Parser_FuncsRec ps_parser_funcs = { - ps_parser_init, - ps_parser_done, - ps_parser_skip_spaces, - ps_parser_skip_PS_token, - ps_parser_to_int, - ps_parser_to_fixed, - ps_parser_to_bytes, - ps_parser_to_coord_array, - ps_parser_to_fixed_array, - ps_parser_to_token, - ps_parser_to_token_array, - ps_parser_load_field, - ps_parser_load_field_table + ps_parser_init, /* init */ + ps_parser_done, /* done */ + + ps_parser_skip_spaces, /* skip_spaces */ + ps_parser_skip_PS_token, /* skip_PS_token */ + + ps_parser_to_int, /* to_int */ + ps_parser_to_fixed, /* to_fixed */ + ps_parser_to_bytes, /* to_bytes */ + ps_parser_to_coord_array, /* to_coord_array */ + ps_parser_to_fixed_array, /* to_fixed_array */ + ps_parser_to_token, /* to_token */ + ps_parser_to_token_array, /* to_token_array */ + + ps_parser_load_field, /* load_field */ + ps_parser_load_field_table /* load_field_table */ }; @@ -59,14 +62,15 @@ FT_CALLBACK_TABLE_DEF const T1_Builder_FuncsRec t1_builder_funcs = { - t1_builder_init, - t1_builder_done, - t1_builder_check_points, - t1_builder_add_point, - t1_builder_add_point1, - t1_builder_add_contour, - t1_builder_start_point, - t1_builder_close_contour + t1_builder_init, /* init */ + t1_builder_done, /* done */ + + t1_builder_check_points, /* check_points */ + t1_builder_add_point, /* add_point */ + t1_builder_add_point1, /* add_point1 */ + t1_builder_add_contour, /* add_contour */ + t1_builder_start_point, /* start_point */ + t1_builder_close_contour /* close_contour */ }; @@ -73,9 +77,9 @@ FT_CALLBACK_TABLE_DEF const T1_Decoder_FuncsRec t1_decoder_funcs = { - t1_decoder_init, - t1_decoder_done, - t1_decoder_parse_charstrings + t1_decoder_init, /* init */ + t1_decoder_done, /* done */ + t1_decoder_parse_charstrings /* parse_charstrings */ }; @@ -83,9 +87,9 @@ FT_CALLBACK_TABLE_DEF const AFM_Parser_FuncsRec afm_parser_funcs = { - afm_parser_init, - afm_parser_done, - afm_parser_parse + afm_parser_init, /* init */ + afm_parser_done, /* done */ + afm_parser_parse /* parse */ }; #endif @@ -130,9 +134,9 @@ &psaux_interface, /* module-specific interface */ - (FT_Module_Constructor)0, - (FT_Module_Destructor) 0, - (FT_Module_Requester) 0 + (FT_Module_Constructor)NULL, /* module_init */ + (FT_Module_Destructor) NULL, /* module_done */ + (FT_Module_Requester) NULL /* get_interface */ }; Index: reactos/sdk/lib/3rdparty/freetype/src/psaux/psobjs.c =================================================================== --- reactos/sdk/lib/3rdparty/freetype/src/psaux/psobjs.c (revision 74184) +++ reactos/sdk/lib/3rdparty/freetype/src/psaux/psobjs.c (working copy) @@ -344,7 +344,7 @@ FT_Byte c = *cur; - ++cur; + cur++; if ( c == '\\' ) { @@ -370,17 +370,17 @@ case '\\': case '(': case ')': - ++cur; + cur++; break; default: /* skip octal escape or ignore backslash */ - for ( i = 0; i < 3 && cur < limit; ++i ) + for ( i = 0; i < 3 && cur < limit; i++ ) { if ( !IS_OCTAL_DIGIT( *cur ) ) break; - ++cur; + cur++; } } } @@ -455,19 +455,19 @@ FT_ASSERT( **acur == '{' ); - for ( cur = *acur; cur < limit && error == FT_Err_Ok; ++cur ) + for ( cur = *acur; cur < limit && error == FT_Err_Ok; cur++ ) { switch ( *cur ) { case '{': - ++embed; + embed++; break; case '}': - --embed; + embed--; if ( embed == 0 ) { - ++cur; + cur++; goto end; } break; @@ -695,7 +695,7 @@ /* ************ otherwise, it is any token **************/ default: token->start = cur; - token->type = ( *cur == '/' ? T1_TOKEN_TYPE_KEY : T1_TOKEN_TYPE_ANY ); + token->type = ( *cur == '/' ) ? T1_TOKEN_TYPE_KEY : T1_TOKEN_TYPE_ANY; ps_parser_skip_PS_token( parser ); cur = parser->cursor; if ( !parser->error ) @@ -750,7 +750,7 @@ if ( !token.type ) break; - if ( tokens != NULL && cur < limit ) + if ( tokens && cur < limit ) *cur = token; cur++; @@ -815,12 +815,12 @@ old_cur = cur; - if ( coords != NULL && count >= max_coords ) + if ( coords && count >= max_coords ) break; /* call PS_Conv_ToFixed() even if coords == NULL */ /* to properly parse number at `cur' */ - *( coords != NULL ? &coords[count] : &dummy ) = + *( coords ? &coords[count] : &dummy ) = (FT_Short)( PS_Conv_ToFixed( &cur, limit, 0 ) >> 16 ); if ( old_cur == cur ) @@ -895,12 +895,12 @@ old_cur = cur; - if ( values != NULL && count >= max_values ) + if ( values && count >= max_values ) break; /* call PS_Conv_ToFixed() even if coords == NULL */ /* to properly parse number at `cur' */ - *( values != NULL ? &values[count] : &dummy ) = + *( values ? &values[count] : &dummy ) = PS_Conv_ToFixed( &cur, limit, power_ten ); if ( old_cur == cur ) @@ -1172,7 +1172,7 @@ /* for this to work (FT_String**)q must have been */ /* initialized to NULL */ - if ( *(FT_String**)q != NULL ) + if ( *(FT_String**)q ) { FT_TRACE0(( "ps_parser_load_field: overwriting field %s\n", field->ident )); Index: reactos/sdk/lib/3rdparty/freetype/src/psaux/t1cmap.c =================================================================== --- reactos/sdk/lib/3rdparty/freetype/src/psaux/t1cmap.c (revision 74184) +++ reactos/sdk/lib/3rdparty/freetype/src/psaux/t1cmap.c (working copy) @@ -45,7 +45,7 @@ cmap->code_to_sid = is_expert ? psnames->adobe_expert_encoding : psnames->adobe_std_encoding; - FT_ASSERT( cmap->code_to_sid != NULL ); + FT_ASSERT( cmap->code_to_sid ); } @@ -136,12 +136,16 @@ { sizeof ( T1_CMapStdRec ), - (FT_CMap_InitFunc) t1_cmap_standard_init, - (FT_CMap_DoneFunc) t1_cmap_std_done, - (FT_CMap_CharIndexFunc)t1_cmap_std_char_index, - (FT_CMap_CharNextFunc) t1_cmap_std_char_next, + (FT_CMap_InitFunc) t1_cmap_standard_init, /* init */ + (FT_CMap_DoneFunc) t1_cmap_std_done, /* done */ + (FT_CMap_CharIndexFunc)t1_cmap_std_char_index, /* char_index */ + (FT_CMap_CharNextFunc) t1_cmap_std_char_next, /* char_next */ - NULL, NULL, NULL, NULL, NULL + (FT_CMap_CharVarIndexFunc) NULL, /* char_var_index */ + (FT_CMap_CharVarIsDefaultFunc)NULL, /* char_var_default */ + (FT_CMap_VariantListFunc) NULL, /* variant_list */ + (FT_CMap_CharVariantListFunc) NULL, /* charvariant_list */ + (FT_CMap_VariantCharListFunc) NULL /* variantchar_list */ }; @@ -161,12 +165,16 @@ { sizeof ( T1_CMapStdRec ), - (FT_CMap_InitFunc) t1_cmap_expert_init, - (FT_CMap_DoneFunc) t1_cmap_std_done, - (FT_CMap_CharIndexFunc)t1_cmap_std_char_index, - (FT_CMap_CharNextFunc) t1_cmap_std_char_next, + (FT_CMap_InitFunc) t1_cmap_expert_init, /* init */ + (FT_CMap_DoneFunc) t1_cmap_std_done, /* done */ + (FT_CMap_CharIndexFunc)t1_cmap_std_char_index, /* char_index */ + (FT_CMap_CharNextFunc) t1_cmap_std_char_next, /* char_next */ - NULL, NULL, NULL, NULL, NULL + (FT_CMap_CharVarIndexFunc) NULL, /* char_var_index */ + (FT_CMap_CharVarIsDefaultFunc)NULL, /* char_var_default */ + (FT_CMap_VariantListFunc) NULL, /* variant_list */ + (FT_CMap_CharVariantListFunc) NULL, /* charvariant_list */ + (FT_CMap_VariantCharListFunc) NULL /* variantchar_list */ }; @@ -193,7 +201,7 @@ cmap->count = (FT_UInt)encoding->code_last - cmap->first; cmap->indices = encoding->char_index; - FT_ASSERT( cmap->indices != NULL ); + FT_ASSERT( cmap->indices ); FT_ASSERT( encoding->code_first <= encoding->code_last ); return 0; @@ -232,7 +240,7 @@ FT_UInt32 char_code = *pchar_code; - ++char_code; + char_code++; if ( char_code < cmap->first ) char_code = cmap->first; @@ -257,12 +265,16 @@ { sizeof ( T1_CMapCustomRec ), - (FT_CMap_InitFunc) t1_cmap_custom_init, - (FT_CMap_DoneFunc) t1_cmap_custom_done, - (FT_CMap_CharIndexFunc)t1_cmap_custom_char_index, - (FT_CMap_CharNextFunc) t1_cmap_custom_char_next, + (FT_CMap_InitFunc) t1_cmap_custom_init, /* init */ + (FT_CMap_DoneFunc) t1_cmap_custom_done, /* done */ + (FT_CMap_CharIndexFunc)t1_cmap_custom_char_index, /* char_index */ + (FT_CMap_CharNextFunc) t1_cmap_custom_char_next, /* char_next */ - NULL, NULL, NULL, NULL, NULL + (FT_CMap_CharVarIndexFunc) NULL, /* char_var_index */ + (FT_CMap_CharVarIsDefaultFunc)NULL, /* char_var_default */ + (FT_CMap_VariantListFunc) NULL, /* variant_list */ + (FT_CMap_CharVariantListFunc) NULL, /* charvariant_list */ + (FT_CMap_VariantCharListFunc) NULL /* variantchar_list */ }; @@ -343,12 +355,16 @@ { sizeof ( PS_UnicodesRec ), - (FT_CMap_InitFunc) t1_cmap_unicode_init, - (FT_CMap_DoneFunc) t1_cmap_unicode_done, - (FT_CMap_CharIndexFunc)t1_cmap_unicode_char_index, - (FT_CMap_CharNextFunc) t1_cmap_unicode_char_next, + (FT_CMap_InitFunc) t1_cmap_unicode_init, /* init */ + (FT_CMap_DoneFunc) t1_cmap_unicode_done, /* done */ + (FT_CMap_CharIndexFunc)t1_cmap_unicode_char_index, /* char_index */ + (FT_CMap_CharNextFunc) t1_cmap_unicode_char_next, /* char_next */ - NULL, NULL, NULL, NULL, NULL + (FT_CMap_CharVarIndexFunc) NULL, /* char_var_index */ + (FT_CMap_CharVarIsDefaultFunc)NULL, /* char_var_default */ + (FT_CMap_VariantListFunc) NULL, /* variant_list */ + (FT_CMap_CharVariantListFunc) NULL, /* charvariant_list */ + (FT_CMap_VariantCharListFunc) NULL /* variantchar_list */ }; Index: reactos/sdk/lib/3rdparty/freetype/src/psaux/t1decode.c =================================================================== --- reactos/sdk/lib/3rdparty/freetype/src/psaux/t1decode.c (revision 74184) +++ reactos/sdk/lib/3rdparty/freetype/src/psaux/t1decode.c (working copy) @@ -405,9 +405,7 @@ ( decoder->buildchar == NULL ) ); if ( decoder->buildchar && decoder->len_buildchar > 0 ) - ft_memset( &decoder->buildchar[0], - 0, - sizeof ( decoder->buildchar[0] ) * decoder->len_buildchar ); + FT_ARRAY_ZERO( decoder->buildchar, decoder->len_buildchar ); FT_TRACE4(( "\n" "Start charstring\n" )); @@ -736,7 +734,7 @@ if ( arg_cnt != 3 ) goto Unexpected_OtherSubr; - if ( decoder->flex_state == 0 || + if ( !decoder->flex_state || decoder->num_flex_vectors != 7 ) { FT_ERROR(( "t1_decoder_parse_charstrings:" @@ -754,13 +752,12 @@ if ( arg_cnt != 0 ) goto Unexpected_OtherSubr; + if ( FT_SET_ERROR( t1_builder_start_point( builder, x, y ) ) || + FT_SET_ERROR( t1_builder_check_points( builder, 6 ) ) ) + goto Fail; + decoder->flex_state = 1; decoder->num_flex_vectors = 0; - if ( ( error = t1_builder_start_point( builder, x, y ) ) - != FT_Err_Ok || - ( error = t1_builder_check_points( builder, 6 ) ) - != FT_Err_Ok ) - goto Fail; break; case 2: /* add flex vectors */ @@ -771,7 +768,7 @@ if ( arg_cnt != 0 ) goto Unexpected_OtherSubr; - if ( decoder->flex_state == 0 ) + if ( !decoder->flex_state ) { FT_ERROR(( "t1_decoder_parse_charstrings:" " missing flex start\n" )); @@ -876,7 +873,7 @@ PS_Blend blend = decoder->blend; - if ( arg_cnt != 1 || blend == NULL ) + if ( arg_cnt != 1 || !blend ) goto Unexpected_OtherSubr; idx = Fix2Int( top[0] ); @@ -944,7 +941,7 @@ PS_Blend blend = decoder->blend; - if ( arg_cnt != 2 || blend == NULL ) + if ( arg_cnt != 2 || !blend ) goto Unexpected_OtherSubr; idx = Fix2Int( top[1] ); @@ -965,7 +962,7 @@ PS_Blend blend = decoder->blend; - if ( arg_cnt != 1 || blend == NULL ) + if ( arg_cnt != 1 || !blend ) goto Unexpected_OtherSubr; idx = Fix2Int( top[0] ); @@ -1123,7 +1120,7 @@ FT_TRACE4(( "BuildCharArray = [ " )); - for ( i = 0; i < decoder->len_buildchar; ++i ) + for ( i = 0; i < decoder->len_buildchar; i++ ) FT_TRACE4(( "%d ", decoder->buildchar[i] )); FT_TRACE4(( "]\n" )); @@ -1201,8 +1198,7 @@ case op_hlineto: FT_TRACE4(( " hlineto" )); - if ( ( error = t1_builder_start_point( builder, x, y ) ) - != FT_Err_Ok ) + if ( FT_SET_ERROR( t1_builder_start_point( builder, x, y ) ) ) goto Fail; x += top[0]; @@ -1223,10 +1219,8 @@ case op_hvcurveto: FT_TRACE4(( " hvcurveto" )); - if ( ( error = t1_builder_start_point( builder, x, y ) ) - != FT_Err_Ok || - ( error = t1_builder_check_points( builder, 3 ) ) - != FT_Err_Ok ) + if ( FT_SET_ERROR( t1_builder_start_point( builder, x, y ) ) || + FT_SET_ERROR( t1_builder_check_points( builder, 3 ) ) ) goto Fail; x += top[0]; @@ -1241,8 +1235,7 @@ case op_rlineto: FT_TRACE4(( " rlineto" )); - if ( ( error = t1_builder_start_point( builder, x, y ) ) - != FT_Err_Ok ) + if ( FT_SET_ERROR( t1_builder_start_point( builder, x, y ) ) ) goto Fail; x += top[0]; @@ -1249,8 +1242,7 @@ y += top[1]; Add_Line: - if ( ( error = t1_builder_add_point1( builder, x, y ) ) - != FT_Err_Ok ) + if ( FT_SET_ERROR( t1_builder_add_point1( builder, x, y ) ) ) goto Fail; break; @@ -1270,10 +1262,8 @@ case op_rrcurveto: FT_TRACE4(( " rrcurveto" )); - if ( ( error = t1_builder_start_point( builder, x, y ) ) - != FT_Err_Ok || - ( error = t1_builder_check_points( builder, 3 ) ) - != FT_Err_Ok ) + if ( FT_SET_ERROR( t1_builder_start_point( builder, x, y ) ) || + FT_SET_ERROR( t1_builder_check_points( builder, 3 ) ) ) goto Fail; x += top[0]; @@ -1292,10 +1282,8 @@ case op_vhcurveto: FT_TRACE4(( " vhcurveto" )); - if ( ( error = t1_builder_start_point( builder, x, y ) ) - != FT_Err_Ok || - ( error = t1_builder_check_points( builder, 3 ) ) - != FT_Err_Ok ) + if ( FT_SET_ERROR( t1_builder_start_point( builder, x, y ) ) || + FT_SET_ERROR( t1_builder_check_points( builder, 3 ) ) ) goto Fail; y += top[0]; @@ -1310,8 +1298,7 @@ case op_vlineto: FT_TRACE4(( " vlineto" )); - if ( ( error = t1_builder_start_point( builder, x, y ) ) - != FT_Err_Ok ) + if ( FT_SET_ERROR( t1_builder_start_point( builder, x, y ) ) ) goto Fail; y += top[0]; @@ -1336,7 +1323,7 @@ /* otherwise, we divide numbers in 16.16 format -- */ /* in both cases, it is the same operation */ *top = FT_DivFix( top[0], top[1] ); - ++top; + top++; large_int = FALSE; break; @@ -1591,7 +1578,7 @@ FT_Render_Mode hint_mode, T1_Decoder_Callback parse_callback ) { - FT_MEM_ZERO( decoder, sizeof ( *decoder ) ); + FT_ZERO( decoder ); /* retrieve PSNames interface from list of current modules */ { Index: reactos/sdk/lib/3rdparty/freetype/src/pshinter/pshalgo.c =================================================================== --- reactos/sdk/lib/3rdparty/freetype/src/pshinter/pshalgo.c (revision 74184) +++ reactos/sdk/lib/3rdparty/freetype/src/pshinter/pshalgo.c (working copy) @@ -898,7 +898,7 @@ static void psh_print_zone( PSH_Zone zone ) { - printf( "zone [scale,delta,min,max] = [%.3f,%.3f,%d,%d]\n", + printf( "zone [scale,delta,min,max] = [%.5f,%.2f,%d,%d]\n", zone->scale / 65536.0, zone->delta / 64.0, zone->min, @@ -1162,7 +1162,7 @@ /* clear all fields */ - FT_MEM_ZERO( glyph, sizeof ( *glyph ) ); + FT_ZERO( glyph ); memory = glyph->memory = globals->memory; @@ -1531,7 +1531,7 @@ } } - if ( point->hint == NULL ) + if ( !point->hint ) { for ( nn = 0; nn < num_hints; nn++ ) { @@ -1572,8 +1572,8 @@ PS_Mask mask = table->hint_masks->masks; FT_UInt num_masks = table->hint_masks->num_masks; FT_UInt first = 0; - FT_Int major_dir = dimension == 0 ? PSH_DIR_VERTICAL - : PSH_DIR_HORIZONTAL; + FT_Int major_dir = ( dimension == 0 ) ? PSH_DIR_VERTICAL + : PSH_DIR_HORIZONTAL; PSH_Dimension dim = &glyph->globals->dimension[dimension]; FT_Fixed scale = dim->scale_mult; FT_Int threshold; Index: reactos/sdk/lib/3rdparty/freetype/src/pshinter/pshmod.c =================================================================== --- reactos/sdk/lib/3rdparty/freetype/src/pshinter/pshmod.c (revision 74184) +++ reactos/sdk/lib/3rdparty/freetype/src/pshinter/pshmod.c (working copy) @@ -95,9 +95,11 @@ FT_DEFINE_PSHINTER_INTERFACE( pshinter_interface, + pshinter_get_globals_funcs, pshinter_get_t1_funcs, - pshinter_get_t2_funcs ) + pshinter_get_t2_funcs + ) FT_DEFINE_MODULE( @@ -111,9 +113,9 @@ &PSHINTER_INTERFACE_GET, /* module-specific interface */ - (FT_Module_Constructor)ps_hinter_init, - (FT_Module_Destructor) ps_hinter_done, - (FT_Module_Requester) NULL ) /* no additional interface for now */ + (FT_Module_Constructor)ps_hinter_init, /* module_init */ + (FT_Module_Destructor) ps_hinter_done, /* module_done */ + (FT_Module_Requester) NULL /* get_interface */ + ) - /* END */ Index: reactos/sdk/lib/3rdparty/freetype/src/pshinter/pshrec.c =================================================================== --- reactos/sdk/lib/3rdparty/freetype/src/pshinter/pshrec.c (revision 74184) +++ reactos/sdk/lib/3rdparty/freetype/src/pshinter/pshrec.c (working copy) @@ -818,7 +818,7 @@ ps_hints_init( PS_Hints hints, FT_Memory memory ) { - FT_MEM_ZERO( hints, sizeof ( *hints ) ); + FT_ZERO( hints ); hints->memory = memory; } @@ -1140,7 +1140,7 @@ FT_LOCAL_DEF( void ) t1_hints_funcs_init( T1_Hints_FuncsRec* funcs ) { - FT_MEM_ZERO( (char*)funcs, sizeof ( *funcs ) ); + FT_ZERO( funcs ); funcs->open = (T1_Hints_OpenFunc) t1_hints_open; funcs->close = (T1_Hints_CloseFunc) ps_hints_close; @@ -1206,7 +1206,7 @@ FT_LOCAL_DEF( void ) t2_hints_funcs_init( T2_Hints_FuncsRec* funcs ) { - FT_MEM_ZERO( funcs, sizeof ( *funcs ) ); + FT_ZERO( funcs ); funcs->open = (T2_Hints_OpenFunc) t2_hints_open; funcs->close = (T2_Hints_CloseFunc) ps_hints_close; Index: reactos/sdk/lib/3rdparty/freetype/src/psnames/psmodule.c =================================================================== --- reactos/sdk/lib/3rdparty/freetype/src/psnames/psmodule.c (revision 74184) +++ reactos/sdk/lib/3rdparty/freetype/src/psnames/psmodule.c (working copy) @@ -22,6 +22,8 @@ #include FT_SERVICE_POSTSCRIPT_CMAPS_H #include "psmodule.h" + +#define DEFINE_PS_TABLES #include "pstables.h" #include "psnamerr.h" @@ -525,6 +527,7 @@ FT_DEFINE_SERVICE_PSCMAPSREC( pscmaps_interface, + (PS_Unicode_ValueFunc) ps_unicode_value, /* unicode_value */ (PS_Unicodes_InitFunc) ps_unicodes_init, /* unicodes_init */ (PS_Unicodes_CharIndexFunc)ps_unicodes_char_index, /* unicodes_char_index */ @@ -534,12 +537,14 @@ (PS_Adobe_Std_StringsFunc) ps_get_standard_strings, /* adobe_std_strings */ t1_standard_encoding, /* adobe_std_encoding */ - t1_expert_encoding ) /* adobe_expert_encoding */ + t1_expert_encoding /* adobe_expert_encoding */ + ) #else FT_DEFINE_SERVICE_PSCMAPSREC( pscmaps_interface, + NULL, /* unicode_value */ NULL, /* unicodes_init */ NULL, /* unicodes_char_index */ @@ -549,7 +554,8 @@ (PS_Adobe_Std_StringsFunc) ps_get_standard_strings, /* adobe_std_strings */ t1_standard_encoding, /* adobe_std_encoding */ - t1_expert_encoding ) /* adobe_expert_encoding */ + t1_expert_encoding /* adobe_expert_encoding */ + ) #endif /* FT_CONFIG_OPTION_ADOBE_GLYPH_LIST */ @@ -556,6 +562,7 @@ FT_DEFINE_SERVICEDESCREC1( pscmaps_services, + FT_SERVICE_ID_POSTSCRIPT_CMAPS, &PSCMAPS_INTERFACE_GET ) @@ -601,9 +608,11 @@ PUT_PS_NAMES_SERVICE( (void*)&PSCMAPS_INTERFACE_GET ), /* module specific interface */ - (FT_Module_Constructor)NULL, - (FT_Module_Destructor) NULL, - (FT_Module_Requester) PUT_PS_NAMES_SERVICE( psnames_get_service ) ) + (FT_Module_Constructor)NULL, /* module_init */ + (FT_Module_Destructor) NULL, /* module_done */ + (FT_Module_Requester) PUT_PS_NAMES_SERVICE( psnames_get_service ) /* get_interface */ + ) + /* END */ Index: reactos/sdk/lib/3rdparty/freetype/src/psnames/pstables.h =================================================================== --- reactos/sdk/lib/3rdparty/freetype/src/psnames/pstables.h (revision 74184) +++ reactos/sdk/lib/3rdparty/freetype/src/psnames/pstables.h (working copy) @@ -19,7 +19,16 @@ /* This file has been generated automatically -- do not edit! */ - static const char ft_standard_glyph_names[3696] = +#ifndef DEFINE_PS_TABLES +#ifdef __cplusplus + extern "C" +#else + extern +#endif +#endif + const char ft_standard_glyph_names[3696] +#ifdef DEFINE_PS_TABLES + = { '.','n','u','l','l', 0, 'n','o','n','m','a','r','k','i','n','g','r','e','t','u','r','n', 0, @@ -441,7 +450,9 @@ 'R','e','g','u','l','a','r', 0, 'R','o','m','a','n', 0, 'S','e','m','i','b','o','l','d', 0, - }; + } +#endif /* DEFINE_PS_TABLES */ + ; #define FT_NUM_MAC_NAMES 258 @@ -448,7 +459,16 @@ /* Values are offsets into the `ft_standard_glyph_names' table */ - static const short ft_mac_names[FT_NUM_MAC_NAMES] = +#ifndef DEFINE_PS_TABLES +#ifdef __cplusplus + extern "C" +#else + extern +#endif +#endif + const short ft_mac_names[FT_NUM_MAC_NAMES] +#ifdef DEFINE_PS_TABLES + = { 253, 0, 6, 261, 267, 274, 283, 294, 301, 309, 758, 330, 340, 351, 360, 365, 371, 378, 385, 391, 396, 400, 404, 410, 415, 420, 424, 430, @@ -469,7 +489,9 @@ 1066,1073,1101,1143,1536,1783,1596,1843,1253,1207,1319,1579,1826,1229, 1270,1313,1323,1171,1290,1332,1211,1235,1276, 169, 175, 182, 189, 200, 209, 218, 225, 232, 239, 246 - }; + } +#endif /* DEFINE_PS_TABLES */ + ; #define FT_NUM_SID_NAMES 391 @@ -476,7 +498,16 @@ /* Values are offsets into the `ft_standard_glyph_names' table */ - static const short ft_sid_names[FT_NUM_SID_NAMES] = +#ifndef DEFINE_PS_TABLES +#ifdef __cplusplus + extern "C" +#else + extern +#endif +#endif + const short ft_sid_names[FT_NUM_SID_NAMES] +#ifdef DEFINE_PS_TABLES + = { 253, 261, 267, 274, 283, 294, 301, 309, 319, 330, 340, 351, 360, 365, 371, 378, 385, 391, 396, 400, 404, 410, 415, 420, 424, 430, 436, 441, @@ -506,11 +537,22 @@ 3237,3249,3264,3275,3283,3297,3309,3321,3338,3353,3365,3377,3394,3409, 3418,3430,3442,3454,3471,3483,3498,3506,3518,3530,3542,3559,3574,3586, 3597,3612,3620,3628,3636,3644,3650,3655,3660,3666,3673,3681,3687 - }; + } +#endif /* DEFINE_PS_TABLES */ + ; /* the following are indices into the SID name table */ - static const unsigned short t1_standard_encoding[256] = +#ifndef DEFINE_PS_TABLES +#ifdef __cplusplus + extern "C" +#else + extern +#endif +#endif + const unsigned short t1_standard_encoding[256] +#ifdef DEFINE_PS_TABLES + = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, @@ -528,11 +570,22 @@ 137, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,138, 0,139, 0, 0, 0, 0,140,141,142,143, 0, 0, 0, 0, 0,144, 0, 0, 0,145, 0, 0,146,147,148,149, 0, 0, 0, 0 - }; + } +#endif /* DEFINE_PS_TABLES */ + ; /* the following are indices into the SID name table */ - static const unsigned short t1_expert_encoding[256] = +#ifndef DEFINE_PS_TABLES +#ifdef __cplusplus + extern "C" +#else + extern +#endif +#endif + const unsigned short t1_expert_encoding[256] +#ifdef DEFINE_PS_TABLES + = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, @@ -550,7 +603,9 @@ 331,332,333,334,335,336,337,338,339,340,341,342,343,344,345,346, 347,348,349,350,351,352,353,354,355,356,357,358,359,360,361,362, 363,364,365,366,367,368,369,370,371,372,373,374,375,376,377,378 - }; + } +#endif /* DEFINE_PS_TABLES */ + ; /* @@ -564,7 +619,16 @@ #ifdef FT_CONFIG_OPTION_ADOBE_GLYPH_LIST - static const unsigned char ft_adobe_glyph_list[55997L] = +#ifndef DEFINE_PS_TABLES +#ifdef __cplusplus + extern "C" +#else + extern +#endif +#endif + const unsigned char ft_adobe_glyph_list[55997L] +#ifdef DEFINE_PS_TABLES + = { 0, 52, 0,106, 2,167, 3, 63, 4,220, 6,125, 9,143, 10, 23, 11,137, 12,199, 14,246, 15, 87, 16,233, 17,219, 18,104, 19, 88, @@ -4066,7 +4130,9 @@ 248,232,239,239,107,128, 2,144,243,244,242,239,235,101,128, 1, 182,117, 2,218,167,218,178,232,233,242,225,231,225,238, 97,128, 48, 90,235,225,244,225,235,225,238, 97,128, 48,186 - }; + } +#endif /* DEFINE_PS_TABLES */ + ; /* Index: reactos/sdk/lib/3rdparty/freetype/src/raster/ftraster.c =================================================================== --- reactos/sdk/lib/3rdparty/freetype/src/raster/ftraster.c (revision 74184) +++ reactos/sdk/lib/3rdparty/freetype/src/raster/ftraster.c (working copy) @@ -251,6 +251,10 @@ #define FT_MEM_ZERO( dest, count ) FT_MEM_SET( dest, 0, count ) #endif +#ifndef FT_ZERO +#define FT_ZERO( p ) FT_MEM_ZERO( p, sizeof ( *(p) ) ) +#endif + /* FMulDiv means `Fast MulDiv'; it is used in case where `b' is */ /* typically a small value and the result of a*b is known to fit into */ /* 32 bits. */ @@ -1516,8 +1520,9 @@ state_bez = y1 < y3 ? Ascending_State : Descending_State; if ( ras.state != state_bez ) { - Bool o = state_bez == Ascending_State ? IS_BOTTOM_OVERSHOOT( y1 ) - : IS_TOP_OVERSHOOT( y1 ); + Bool o = ( state_bez == Ascending_State ) + ? IS_BOTTOM_OVERSHOOT( y1 ) + : IS_TOP_OVERSHOOT( y1 ); /* finalize current profile if any */ @@ -1652,8 +1657,9 @@ /* detect a change of direction */ if ( ras.state != state_bez ) { - Bool o = state_bez == Ascending_State ? IS_BOTTOM_OVERSHOOT( y1 ) - : IS_TOP_OVERSHOOT( y1 ); + Bool o = ( state_bez == Ascending_State ) + ? IS_BOTTOM_OVERSHOOT( y1 ) + : IS_TOP_OVERSHOOT( y1 ); /* finalize current profile if any */ @@ -2386,7 +2392,7 @@ pxl = e2; /* check that the other pixel isn't set */ - e1 = pxl == e1 ? e2 : e1; + e1 = ( pxl == e1 ) ? e2 : e1; e1 = TRUNC( e1 ); @@ -2587,7 +2593,7 @@ pxl = e2; /* check that the other pixel isn't set */ - e1 = pxl == e1 ? e2 : e1; + e1 = ( pxl == e1 ) ? e2 : e1; e1 = TRUNC( e1 ); @@ -3057,7 +3063,7 @@ *araster = (FT_Raster)&the_raster; - FT_MEM_ZERO( &the_raster, sizeof ( the_raster ) ); + FT_ZERO( &the_raster ); ft_black_init( &the_raster ); return 0; @@ -3230,11 +3236,12 @@ FT_GLYPH_FORMAT_OUTLINE, - (FT_Raster_New_Func) ft_black_new, - (FT_Raster_Reset_Func) ft_black_reset, - (FT_Raster_Set_Mode_Func)ft_black_set_mode, - (FT_Raster_Render_Func) ft_black_render, - (FT_Raster_Done_Func) ft_black_done ) + (FT_Raster_New_Func) ft_black_new, /* raster_new */ + (FT_Raster_Reset_Func) ft_black_reset, /* raster_reset */ + (FT_Raster_Set_Mode_Func)ft_black_set_mode, /* raster_set_mode */ + (FT_Raster_Render_Func) ft_black_render, /* raster_render */ + (FT_Raster_Done_Func) ft_black_done /* raster_done */ + ) /* END */ Index: reactos/sdk/lib/3rdparty/freetype/src/raster/ftrend1.c =================================================================== --- reactos/sdk/lib/3rdparty/freetype/src/raster/ftrend1.c (revision 74184) +++ reactos/sdk/lib/3rdparty/freetype/src/raster/ftrend1.c (working copy) @@ -88,7 +88,7 @@ FT_GlyphSlot slot, FT_BBox* cbox ) { - FT_MEM_ZERO( cbox, sizeof ( *cbox ) ); + FT_ZERO( cbox ); if ( slot->format == render->glyph_format ) FT_Outline_Get_CBox( &slot->outline, cbox ); @@ -224,7 +224,8 @@ } - FT_DEFINE_RENDERER( ft_raster1_renderer_class, + FT_DEFINE_RENDERER( + ft_raster1_renderer_class, FT_MODULE_RENDERER, sizeof ( FT_RendererRec ), @@ -233,21 +234,20 @@ 0x10000L, 0x20000L, - 0, /* module specific interface */ + NULL, /* module specific interface */ - (FT_Module_Constructor)ft_raster1_init, - (FT_Module_Destructor) 0, - (FT_Module_Requester) 0 - , + (FT_Module_Constructor)ft_raster1_init, /* module_init */ + (FT_Module_Destructor) NULL, /* module_done */ + (FT_Module_Requester) NULL, /* get_interface */ FT_GLYPH_FORMAT_OUTLINE, - (FT_Renderer_RenderFunc) ft_raster1_render, - (FT_Renderer_TransformFunc)ft_raster1_transform, - (FT_Renderer_GetCBoxFunc) ft_raster1_get_cbox, - (FT_Renderer_SetModeFunc) ft_raster1_set_mode, + (FT_Renderer_RenderFunc) ft_raster1_render, /* render_glyph */ + (FT_Renderer_TransformFunc)ft_raster1_transform, /* transform_glyph */ + (FT_Renderer_GetCBoxFunc) ft_raster1_get_cbox, /* get_glyph_cbox */ + (FT_Renderer_SetModeFunc) ft_raster1_set_mode, /* set_mode */ - (FT_Raster_Funcs*) &FT_STANDARD_RASTER_GET + (FT_Raster_Funcs*)&FT_STANDARD_RASTER_GET /* raster_class */ ) Index: reactos/sdk/lib/3rdparty/freetype/src/sfnt/pngshim.c =================================================================== --- reactos/sdk/lib/3rdparty/freetype/src/sfnt/pngshim.c (revision 74184) +++ reactos/sdk/lib/3rdparty/freetype/src/sfnt/pngshim.c (working copy) @@ -184,7 +184,8 @@ FT_Memory memory, FT_Byte* data, FT_UInt png_len, - FT_Bool populate_map_and_metrics ) + FT_Bool populate_map_and_metrics, + FT_Bool metrics_only ) { FT_Bitmap *map = &slot->bitmap; FT_Error error = FT_Err_Ok; @@ -258,9 +259,6 @@ if ( populate_map_and_metrics ) { - FT_ULong size; - - metrics->width = (FT_UShort)imgWidth; metrics->height = (FT_UShort)imgHeight; @@ -276,13 +274,6 @@ error = FT_THROW( Array_Too_Large ); goto DestroyExit; } - - /* this doesn't overflow: 0x7FFF * 0x7FFF * 4 < 2^32 */ - size = map->rows * (FT_ULong)map->pitch; - - error = ft_glyphslot_alloc_bitmap( slot, size ); - if ( error ) - goto DestroyExit; } /* convert palette/gray image to rgb */ @@ -334,6 +325,9 @@ goto DestroyExit; } + if ( metrics_only ) + goto DestroyExit; + switch ( color_type ) { default: @@ -349,6 +343,17 @@ break; } + if ( populate_map_and_metrics ) + { + /* this doesn't overflow: 0x7FFF * 0x7FFF * 4 < 2^32 */ + FT_ULong size = map->rows * (FT_ULong)map->pitch; + + + error = ft_glyphslot_alloc_bitmap( slot, size ); + if ( error ) + goto DestroyExit; + } + if ( FT_NEW_ARRAY( rows, imgHeight ) ) { error = FT_THROW( Out_Of_Memory ); Index: reactos/sdk/lib/3rdparty/freetype/src/sfnt/pngshim.h =================================================================== --- reactos/sdk/lib/3rdparty/freetype/src/sfnt/pngshim.h (revision 74184) +++ reactos/sdk/lib/3rdparty/freetype/src/sfnt/pngshim.h (working copy) @@ -38,7 +38,8 @@ FT_Memory memory, FT_Byte* data, FT_UInt png_len, - FT_Bool populate_map_and_metrics ); + FT_Bool populate_map_and_metrics, + FT_Bool metrics_only ); #endif Index: reactos/sdk/lib/3rdparty/freetype/src/sfnt/sfdriver.c =================================================================== --- reactos/sdk/lib/3rdparty/freetype/src/sfnt/sfdriver.c (revision 74184) +++ reactos/sdk/lib/3rdparty/freetype/src/sfnt/sfdriver.c (working copy) @@ -88,7 +88,7 @@ break; case FT_SFNT_OS2: - table = face->os2.version == 0xFFFFU ? NULL : &face->os2; + table = ( face->os2.version == 0xFFFFU ) ? NULL : &face->os2; break; case FT_SFNT_POST: @@ -139,9 +139,11 @@ FT_DEFINE_SERVICE_SFNT_TABLEREC( sfnt_service_sfnt_table, + (FT_SFNT_TableLoadFunc)tt_face_load_any, /* load_table */ (FT_SFNT_TableGetFunc) get_sfnt_table, /* get_table */ - (FT_SFNT_TableInfoFunc)sfnt_table_info ) /* table_info */ + (FT_SFNT_TableInfoFunc)sfnt_table_info /* table_info */ + ) #ifdef TT_CONFIG_OPTION_POSTSCRIPT_NAMES @@ -152,7 +154,7 @@ */ static FT_Error - sfnt_get_glyph_name( TT_Face face, + sfnt_get_glyph_name( FT_Face face, FT_UInt glyph_index, FT_Pointer buffer, FT_UInt buffer_max ) @@ -161,7 +163,7 @@ FT_Error error; - error = tt_face_get_ps_name( face, glyph_index, &gname ); + error = tt_face_get_ps_name( (TT_Face)face, glyph_index, &gname ); if ( !error ) FT_STRCPYN( buffer, gname, buffer_max ); @@ -170,26 +172,26 @@ static FT_UInt - sfnt_get_name_index( TT_Face face, + sfnt_get_name_index( FT_Face face, FT_String* glyph_name ) { - FT_Face root = &face->root; + TT_Face ttface = (TT_Face)face; FT_UInt i, max_gid = FT_UINT_MAX; - if ( root->num_glyphs < 0 ) + if ( face->num_glyphs < 0 ) return 0; - else if ( (FT_ULong)root->num_glyphs < FT_UINT_MAX ) - max_gid = (FT_UInt)root->num_glyphs; + else if ( (FT_ULong)face->num_glyphs < FT_UINT_MAX ) + max_gid = (FT_UInt)face->num_glyphs; else FT_TRACE0(( "Ignore glyph names for invalid GID 0x%08x - 0x%08x\n", - FT_UINT_MAX, root->num_glyphs )); + FT_UINT_MAX, face->num_glyphs )); for ( i = 0; i < max_gid; i++ ) { FT_String* gname; - FT_Error error = tt_face_get_ps_name( face, i, &gname ); + FT_Error error = tt_face_get_ps_name( ttface, i, &gname ); if ( error ) @@ -205,10 +207,11 @@ FT_DEFINE_SERVICE_GLYPHDICTREC( sfnt_service_glyph_dict, + (FT_GlyphDict_GetNameFunc) sfnt_get_glyph_name, /* get_name */ - (FT_GlyphDict_NameIndexFunc)sfnt_get_name_index ) /* name_index */ + (FT_GlyphDict_NameIndexFunc)sfnt_get_name_index /* name_index */ + ) - #endif /* TT_CONFIG_OPTION_POSTSCRIPT_NAMES */ @@ -330,17 +333,21 @@ FT_DEFINE_SERVICE_PSFONTNAMEREC( sfnt_service_ps_name, - (FT_PsName_GetFunc)sfnt_get_ps_name ) /* get_ps_font_name */ + (FT_PsName_GetFunc)sfnt_get_ps_name /* get_ps_font_name */ + ) + /* * TT CMAP INFO */ FT_DEFINE_SERVICE_TTCMAPSREC( tt_service_get_cmap_info, - (TT_CMap_Info_GetFunc)tt_get_cmap_info ) /* get_cmap_info */ + (TT_CMap_Info_GetFunc)tt_get_cmap_info /* get_cmap_info */ + ) + #ifdef TT_CONFIG_OPTION_BDF static FT_Error @@ -381,8 +388,10 @@ FT_DEFINE_SERVICE_BDFRec( sfnt_service_bdf, + (FT_BDF_GetCharsetIdFunc)sfnt_get_charset_id, /* get_charset_id */ - (FT_BDF_GetPropertyFunc) tt_face_find_bdf_prop ) /* get_property */ + (FT_BDF_GetPropertyFunc) tt_face_find_bdf_prop /* get_property */ + ) #endif /* TT_CONFIG_OPTION_BDF */ @@ -395,6 +404,7 @@ #if defined TT_CONFIG_OPTION_POSTSCRIPT_NAMES && defined TT_CONFIG_OPTION_BDF FT_DEFINE_SERVICEDESCREC5( sfnt_services, + FT_SERVICE_ID_SFNT_TABLE, &SFNT_SERVICE_SFNT_TABLE_GET, FT_SERVICE_ID_POSTSCRIPT_FONT_NAME, &SFNT_SERVICE_PS_NAME_GET, FT_SERVICE_ID_GLYPH_DICT, &SFNT_SERVICE_GLYPH_DICT_GET, @@ -403,6 +413,7 @@ #elif defined TT_CONFIG_OPTION_POSTSCRIPT_NAMES FT_DEFINE_SERVICEDESCREC4( sfnt_services, + FT_SERVICE_ID_SFNT_TABLE, &SFNT_SERVICE_SFNT_TABLE_GET, FT_SERVICE_ID_POSTSCRIPT_FONT_NAME, &SFNT_SERVICE_PS_NAME_GET, FT_SERVICE_ID_GLYPH_DICT, &SFNT_SERVICE_GLYPH_DICT_GET, @@ -410,6 +421,7 @@ #elif defined TT_CONFIG_OPTION_BDF FT_DEFINE_SERVICEDESCREC4( sfnt_services, + FT_SERVICE_ID_SFNT_TABLE, &SFNT_SERVICE_SFNT_TABLE_GET, FT_SERVICE_ID_POSTSCRIPT_FONT_NAME, &SFNT_SERVICE_PS_NAME_GET, FT_SERVICE_ID_BDF, &SFNT_SERVICE_BDF_GET, @@ -417,6 +429,7 @@ #else FT_DEFINE_SERVICEDESCREC3( sfnt_services, + FT_SERVICE_ID_SFNT_TABLE, &SFNT_SERVICE_SFNT_TABLE_GET, FT_SERVICE_ID_POSTSCRIPT_FONT_NAME, &SFNT_SERVICE_PS_NAME_GET, FT_SERVICE_ID_TT_CMAP, &TT_SERVICE_CMAP_INFO_GET ) @@ -459,6 +472,7 @@ FT_DEFINE_SFNT_INTERFACE( sfnt_interface, + tt_face_goto_table, /* TT_Loader_GotoTableFunc goto_table */ sfnt_init_face, /* TT_Init_Face_Func init_face */ @@ -530,9 +544,10 @@ (const void*)&SFNT_INTERFACE_GET, /* module specific interface */ - (FT_Module_Constructor)0, - (FT_Module_Destructor) 0, - (FT_Module_Requester) sfnt_get_interface ) + (FT_Module_Constructor)NULL, /* module_init */ + (FT_Module_Destructor) NULL, /* module_done */ + (FT_Module_Requester) sfnt_get_interface /* get_interface */ + ) /* END */ Index: reactos/sdk/lib/3rdparty/freetype/src/sfnt/sfobjs.c =================================================================== --- reactos/sdk/lib/3rdparty/freetype/src/sfnt/sfobjs.c (revision 74184) +++ reactos/sdk/lib/3rdparty/freetype/src/sfnt/sfobjs.c (working copy) @@ -28,6 +28,12 @@ #include FT_SERVICE_POSTSCRIPT_CMAPS_H #include FT_SFNT_NAMES_H #include FT_GZIP_H + +#ifdef TT_CONFIG_OPTION_GX_VAR_SUPPORT +#include FT_SERVICE_MULTIPLE_MASTERS_H +#include FT_SERVICE_METRICS_VARIATIONS_H +#endif + #include "sferrors.h" #ifdef TT_CONFIG_OPTION_BDF @@ -254,7 +260,7 @@ if ( rec && convert ) { - if ( rec->string == NULL ) + if ( !rec->string ) { FT_Stream stream = face->name_table.stream; @@ -798,6 +804,9 @@ if ( FT_STREAM_READ_FIELDS( ttc_header_fields, &face->ttc_header ) ) return error; + FT_TRACE3(( " with %ld subfonts\n", + face->ttc_header.count )); + if ( face->ttc_header.count == 0 ) return FT_THROW( Invalid_Table ); @@ -872,6 +881,21 @@ FT_FACE_FIND_GLOBAL_SERVICE( face, face->psnames, POSTSCRIPT_CMAPS ); +#ifdef TT_CONFIG_OPTION_GX_VAR_SUPPORT + if ( !face->mm ) + { + /* we want the MM interface from the `truetype' module only */ + FT_Module tt_module = FT_Get_Module( library, "truetype" ); + + + face->mm = ft_module_get_service( tt_module, + FT_SERVICE_ID_MULTI_MASTERS, + 0 ); + } + + FT_FACE_FIND_GLOBAL_SERVICE( face, face->var, METRICS_VARIATIONS ); +#endif + FT_TRACE2(( "SFNT driver\n" )); error = sfnt_open_font( stream, face ); @@ -881,7 +905,7 @@ /* Stream may have changed in sfnt_open_font. */ stream = face->root.stream; - FT_TRACE2(( "sfnt_init_face: %08p, %ld\n", face, face_instance_index )); + FT_TRACE2(( "sfnt_init_face: %08p, %d\n", face, face_instance_index )); face_index = FT_ABS( face_instance_index ) & 0xFFFF; @@ -916,6 +940,8 @@ FT_Int instance_index; + face->is_default_instance = 1; + instance_index = FT_ABS( face_instance_index ) >> 16; /* test whether current face is a GX font with named instances */ @@ -923,7 +949,7 @@ fvar_len < 20 || FT_READ_ULONG( version ) || FT_READ_USHORT( offset ) || - FT_STREAM_SKIP( 2 ) || + FT_STREAM_SKIP( 2 ) /* count_size_pairs */ || FT_READ_USHORT( num_axes ) || FT_READ_USHORT( axis_size ) || FT_READ_USHORT( num_instances ) || @@ -937,17 +963,27 @@ instance_size = 0; } - /* check that the data is bound by the table length; */ - /* based on similar code in function `TT_Get_MM_Var' */ + /* check that the data is bound by the table length */ if ( version != 0x00010000UL || +#if 0 + /* fonts like `JamRegular.ttf' have an incorrect value for */ + /* `count_size_pairs'; since value 2 is hard-coded in `fvar' */ + /* version 1.0, we simply ignore it */ + count_size_pairs != 2 || +#endif axis_size != 20 || + num_axes == 0 || + /* `num_axes' limit implied by 16-bit `instance_size' */ num_axes > 0x3FFE || - instance_size != 4 + 4 * num_axes || + !( instance_size == 4 + 4 * num_axes || + instance_size == 6 + 4 * num_axes ) || num_instances > 0x7EFF || offset + axis_size * num_axes + instance_size * num_instances > fvar_len ) num_instances = 0; + else + face->variation_support |= TT_FACE_FLAG_VAR_FVAR; /* we don't support Multiple Master CFFs yet */ if ( !face->goto_table( face, TTAG_CFF, stream, 0 ) ) @@ -1083,12 +1119,14 @@ /* do we have outlines in there? */ #ifdef FT_CONFIG_OPTION_INCREMENTAL - has_outline = FT_BOOL( face->root.internal->incremental_interface != 0 || - tt_face_lookup_table( face, TTAG_glyf ) != 0 || - tt_face_lookup_table( face, TTAG_CFF ) != 0 ); + has_outline = FT_BOOL( face->root.internal->incremental_interface || + tt_face_lookup_table( face, TTAG_glyf ) || + tt_face_lookup_table( face, TTAG_CFF ) || + tt_face_lookup_table( face, TTAG_CFF2 ) ); #else - has_outline = FT_BOOL( tt_face_lookup_table( face, TTAG_glyf ) != 0 || - tt_face_lookup_table( face, TTAG_CFF ) != 0 ); + has_outline = FT_BOOL( tt_face_lookup_table( face, TTAG_glyf ) || + tt_face_lookup_table( face, TTAG_CFF ) || + tt_face_lookup_table( face, TTAG_CFF2 ) ); #endif is_apple_sbit = 0; @@ -1327,10 +1365,14 @@ #ifdef TT_CONFIG_OPTION_GX_VAR_SUPPORT /* Don't bother to load the tables unless somebody asks for them. */ /* No need to do work which will (probably) not be used. */ - if ( tt_face_lookup_table( face, TTAG_glyf ) != 0 && - tt_face_lookup_table( face, TTAG_fvar ) != 0 && - tt_face_lookup_table( face, TTAG_gvar ) != 0 ) - flags |= FT_FACE_FLAG_MULTIPLE_MASTERS; + if ( face->variation_support & TT_FACE_FLAG_VAR_FVAR ) + { + if ( tt_face_lookup_table( face, TTAG_glyf ) != 0 && + tt_face_lookup_table( face, TTAG_gvar ) != 0 ) + flags |= FT_FACE_FLAG_MULTIPLE_MASTERS; + if ( tt_face_lookup_table( face, TTAG_CFF2 ) != 0 ) + flags |= FT_FACE_FLAG_MULTIPLE_MASTERS; + } #endif root->face_flags = flags; @@ -1393,7 +1435,7 @@ charmap->encoding_id ); #if 0 - if ( root->charmap == NULL && + if ( !root->charmap && charmap->encoding == FT_ENCODING_UNICODE ) { /* set 'root->charmap' to the first Unicode encoding we find */ @@ -1411,7 +1453,7 @@ * depths in the FT_Bitmap_Size record. This is a design error. */ { - FT_UInt i, count; + FT_UInt count; count = face->sbit_num_strikes; @@ -1423,7 +1465,10 @@ FT_Short avgwidth = face->os2.xAvgCharWidth; FT_Size_Metrics metrics; + FT_UInt* sbit_strike_map = NULL; + FT_UInt strike_idx, bsize_idx; + if ( em_size == 0 || face->os2.version == 0xFFFFU ) { avgwidth = 1; @@ -1430,21 +1475,26 @@ em_size = 1; } - if ( FT_NEW_ARRAY( root->available_sizes, count ) ) + /* to avoid invalid strike data in the `available_sizes' field */ + /* of `FT_Face', we map `available_sizes' indices to strike */ + /* indices */ + if ( FT_NEW_ARRAY( root->available_sizes, count ) || + FT_NEW_ARRAY( sbit_strike_map, count ) ) goto Exit; - for ( i = 0; i < count; i++ ) + bsize_idx = 0; + for ( strike_idx = 0; strike_idx < count; strike_idx++ ) { - FT_Bitmap_Size* bsize = root->available_sizes + i; + FT_Bitmap_Size* bsize = root->available_sizes + bsize_idx; - error = sfnt->load_strike_metrics( face, i, &metrics ); + error = sfnt->load_strike_metrics( face, strike_idx, &metrics ); if ( error ) - goto Exit; + continue; bsize->height = (FT_Short)( metrics.height >> 6 ); - bsize->width = (FT_Short)( - ( avgwidth * metrics.x_ppem + em_size / 2 ) / em_size ); + bsize->width = (FT_Short)( + ( avgwidth * metrics.x_ppem + em_size / 2 ) / em_size ); bsize->x_ppem = metrics.x_ppem << 6; bsize->y_ppem = metrics.y_ppem << 6; @@ -1451,10 +1501,24 @@ /* assume 72dpi */ bsize->size = metrics.y_ppem << 6; + + /* only use strikes with valid PPEM values */ + if ( bsize->x_ppem && bsize->y_ppem ) + sbit_strike_map[bsize_idx++] = strike_idx; } - root->face_flags |= FT_FACE_FLAG_FIXED_SIZES; - root->num_fixed_sizes = (FT_Int)count; + /* reduce array size to the actually used elements */ + (void)FT_RENEW_ARRAY( sbit_strike_map, count, bsize_idx ); + + /* from now on, all strike indices are mapped */ + /* using `sbit_strike_map' */ + if ( bsize_idx ) + { + face->sbit_strike_map = sbit_strike_map; + + root->face_flags |= FT_FACE_FLAG_FIXED_SIZES; + root->num_fixed_sizes = (FT_Int)bsize_idx; + } } } @@ -1615,18 +1679,10 @@ face->cmap_size = 0; } - /* freeing the horizontal metrics */ - { - FT_Stream stream = FT_FACE_STREAM( face ); + face->horz_metrics_size = 0; + face->vert_metrics_size = 0; - - FT_FRAME_RELEASE( face->horz_metrics ); - FT_FRAME_RELEASE( face->vert_metrics ); - face->horz_metrics_size = 0; - face->vert_metrics_size = 0; - } - - /* freeing the vertical ones, if any */ + /* freeing vertical metrics, if any */ if ( face->vertical_info ) { FT_FREE( face->vertical.long_metrics ); @@ -1648,6 +1704,7 @@ /* freeing sbit size table */ FT_FREE( face->root.available_sizes ); + FT_FREE( face->sbit_strike_map ); face->root.num_fixed_sizes = 0; FT_FREE( face->postscript_name ); Index: reactos/sdk/lib/3rdparty/freetype/src/sfnt/ttbdf.c =================================================================== --- reactos/sdk/lib/3rdparty/freetype/src/sfnt/ttbdf.c (revision 74184) +++ reactos/sdk/lib/3rdparty/freetype/src/sfnt/ttbdf.c (working copy) @@ -48,7 +48,7 @@ FT_Stream stream = FT_FACE(face)->stream; - if ( bdf->table != NULL ) + if ( bdf->table ) FT_FRAME_RELEASE( bdf->table ); bdf->table_end = NULL; @@ -165,7 +165,7 @@ error = FT_ERR( Invalid_Argument ); - if ( size == NULL || property_name == NULL ) + if ( !size || !property_name ) goto Exit; property_len = ft_strlen( property_name ); @@ -177,6 +177,7 @@ FT_UInt _ppem = FT_NEXT_USHORT( p ); FT_UInt _count = FT_NEXT_USHORT( p ); + if ( _ppem == size->metrics.y_ppem ) { count = _count; @@ -193,6 +194,7 @@ { FT_UInt type = FT_PEEK_USHORT( p + 4 ); + if ( ( type & 0x10 ) != 0 ) { FT_UInt32 name_offset = FT_PEEK_ULONG( p ); Index: reactos/sdk/lib/3rdparty/freetype/src/sfnt/ttcmap.c =================================================================== --- reactos/sdk/lib/3rdparty/freetype/src/sfnt/ttcmap.c (revision 74184) +++ reactos/sdk/lib/3rdparty/freetype/src/sfnt/ttcmap.c (working copy) @@ -180,22 +180,24 @@ FT_DEFINE_TT_CMAP( tt_cmap0_class_rec, - sizeof ( TT_CMapRec ), - (FT_CMap_InitFunc) tt_cmap_init, - (FT_CMap_DoneFunc) NULL, - (FT_CMap_CharIndexFunc)tt_cmap0_char_index, - (FT_CMap_CharNextFunc) tt_cmap0_char_next, + sizeof ( TT_CMapRec ), - NULL, - NULL, - NULL, - NULL, - NULL, + (FT_CMap_InitFunc) tt_cmap_init, /* init */ + (FT_CMap_DoneFunc) NULL, /* done */ + (FT_CMap_CharIndexFunc)tt_cmap0_char_index, /* char_index */ + (FT_CMap_CharNextFunc) tt_cmap0_char_next, /* char_next */ + (FT_CMap_CharVarIndexFunc) NULL, /* char_var_index */ + (FT_CMap_CharVarIsDefaultFunc)NULL, /* char_var_default */ + (FT_CMap_VariantListFunc) NULL, /* variant_list */ + (FT_CMap_CharVariantListFunc) NULL, /* charvariant_list */ + (FT_CMap_VariantCharListFunc) NULL, /* variantchar_list */ + 0, - (TT_CMap_ValidateFunc)tt_cmap0_validate, - (TT_CMap_Info_GetFunc)tt_cmap0_get_info ) + (TT_CMap_ValidateFunc)tt_cmap0_validate, /* validate */ + (TT_CMap_Info_GetFunc)tt_cmap0_get_info /* get_cmap_info */ + ) #endif /* TT_CONFIG_CMAP_FORMAT_0 */ @@ -571,22 +573,24 @@ FT_DEFINE_TT_CMAP( tt_cmap2_class_rec, - sizeof ( TT_CMapRec ), - (FT_CMap_InitFunc) tt_cmap_init, - (FT_CMap_DoneFunc) NULL, - (FT_CMap_CharIndexFunc)tt_cmap2_char_index, - (FT_CMap_CharNextFunc) tt_cmap2_char_next, + sizeof ( TT_CMapRec ), - NULL, - NULL, - NULL, - NULL, - NULL, + (FT_CMap_InitFunc) tt_cmap_init, /* init */ + (FT_CMap_DoneFunc) NULL, /* done */ + (FT_CMap_CharIndexFunc)tt_cmap2_char_index, /* char_index */ + (FT_CMap_CharNextFunc) tt_cmap2_char_next, /* char_next */ + (FT_CMap_CharVarIndexFunc) NULL, /* char_var_index */ + (FT_CMap_CharVarIsDefaultFunc)NULL, /* char_var_default */ + (FT_CMap_VariantListFunc) NULL, /* variant_list */ + (FT_CMap_CharVariantListFunc) NULL, /* charvariant_list */ + (FT_CMap_VariantCharListFunc) NULL, /* variantchar_list */ + 2, - (TT_CMap_ValidateFunc)tt_cmap2_validate, - (TT_CMap_Info_GetFunc)tt_cmap2_get_info ) + (TT_CMap_ValidateFunc)tt_cmap2_validate, /* validate */ + (TT_CMap_Info_GetFunc)tt_cmap2_get_info /* get_cmap_info */ + ) #endif /* TT_CONFIG_CMAP_FORMAT_2 */ @@ -1516,21 +1520,24 @@ FT_DEFINE_TT_CMAP( tt_cmap4_class_rec, - sizeof ( TT_CMap4Rec ), - (FT_CMap_InitFunc) tt_cmap4_init, - (FT_CMap_DoneFunc) NULL, - (FT_CMap_CharIndexFunc)tt_cmap4_char_index, - (FT_CMap_CharNextFunc) tt_cmap4_char_next, - NULL, - NULL, - NULL, - NULL, - NULL, + sizeof ( TT_CMap4Rec ), + (FT_CMap_InitFunc) tt_cmap4_init, /* init */ + (FT_CMap_DoneFunc) NULL, /* done */ + (FT_CMap_CharIndexFunc)tt_cmap4_char_index, /* char_index */ + (FT_CMap_CharNextFunc) tt_cmap4_char_next, /* char_next */ + + (FT_CMap_CharVarIndexFunc) NULL, /* char_var_index */ + (FT_CMap_CharVarIsDefaultFunc)NULL, /* char_var_default */ + (FT_CMap_VariantListFunc) NULL, /* variant_list */ + (FT_CMap_CharVariantListFunc) NULL, /* charvariant_list */ + (FT_CMap_VariantCharListFunc) NULL, /* variantchar_list */ + 4, - (TT_CMap_ValidateFunc)tt_cmap4_validate, - (TT_CMap_Info_GetFunc)tt_cmap4_get_info ) + (TT_CMap_ValidateFunc)tt_cmap4_validate, /* validate */ + (TT_CMap_Info_GetFunc)tt_cmap4_get_info /* get_cmap_info */ + ) #endif /* TT_CONFIG_CMAP_FORMAT_4 */ @@ -1683,22 +1690,24 @@ FT_DEFINE_TT_CMAP( tt_cmap6_class_rec, - sizeof ( TT_CMapRec ), - (FT_CMap_InitFunc) tt_cmap_init, - (FT_CMap_DoneFunc) NULL, - (FT_CMap_CharIndexFunc)tt_cmap6_char_index, - (FT_CMap_CharNextFunc) tt_cmap6_char_next, + sizeof ( TT_CMapRec ), - NULL, - NULL, - NULL, - NULL, - NULL, + (FT_CMap_InitFunc) tt_cmap_init, /* init */ + (FT_CMap_DoneFunc) NULL, /* done */ + (FT_CMap_CharIndexFunc)tt_cmap6_char_index, /* char_index */ + (FT_CMap_CharNextFunc) tt_cmap6_char_next, /* char_next */ + (FT_CMap_CharVarIndexFunc) NULL, /* char_var_index */ + (FT_CMap_CharVarIsDefaultFunc)NULL, /* char_var_default */ + (FT_CMap_VariantListFunc) NULL, /* variant_list */ + (FT_CMap_CharVariantListFunc) NULL, /* charvariant_list */ + (FT_CMap_VariantCharListFunc) NULL, /* variantchar_list */ + 6, - (TT_CMap_ValidateFunc)tt_cmap6_validate, - (TT_CMap_Info_GetFunc)tt_cmap6_get_info ) + (TT_CMap_ValidateFunc)tt_cmap6_validate, /* validate */ + (TT_CMap_Info_GetFunc)tt_cmap6_get_info /* get_cmap_info */ + ) #endif /* TT_CONFIG_CMAP_FORMAT_6 */ @@ -1975,22 +1984,24 @@ FT_DEFINE_TT_CMAP( tt_cmap8_class_rec, - sizeof ( TT_CMapRec ), - (FT_CMap_InitFunc) tt_cmap_init, - (FT_CMap_DoneFunc) NULL, - (FT_CMap_CharIndexFunc)tt_cmap8_char_index, - (FT_CMap_CharNextFunc) tt_cmap8_char_next, + sizeof ( TT_CMapRec ), - NULL, - NULL, - NULL, - NULL, - NULL, + (FT_CMap_InitFunc) tt_cmap_init, /* init */ + (FT_CMap_DoneFunc) NULL, /* done */ + (FT_CMap_CharIndexFunc)tt_cmap8_char_index, /* char_index */ + (FT_CMap_CharNextFunc) tt_cmap8_char_next, /* char_next */ + (FT_CMap_CharVarIndexFunc) NULL, /* char_var_index */ + (FT_CMap_CharVarIsDefaultFunc)NULL, /* char_var_default */ + (FT_CMap_VariantListFunc) NULL, /* variant_list */ + (FT_CMap_CharVariantListFunc) NULL, /* charvariant_list */ + (FT_CMap_VariantCharListFunc) NULL, /* variantchar_list */ + 8, - (TT_CMap_ValidateFunc)tt_cmap8_validate, - (TT_CMap_Info_GetFunc)tt_cmap8_get_info ) + (TT_CMap_ValidateFunc)tt_cmap8_validate, /* validate */ + (TT_CMap_Info_GetFunc)tt_cmap8_get_info /* get_cmap_info */ + ) #endif /* TT_CONFIG_CMAP_FORMAT_8 */ @@ -2145,22 +2156,24 @@ FT_DEFINE_TT_CMAP( tt_cmap10_class_rec, - sizeof ( TT_CMapRec ), - (FT_CMap_InitFunc) tt_cmap_init, - (FT_CMap_DoneFunc) NULL, - (FT_CMap_CharIndexFunc)tt_cmap10_char_index, - (FT_CMap_CharNextFunc) tt_cmap10_char_next, + sizeof ( TT_CMapRec ), - NULL, - NULL, - NULL, - NULL, - NULL, + (FT_CMap_InitFunc) tt_cmap_init, /* init */ + (FT_CMap_DoneFunc) NULL, /* done */ + (FT_CMap_CharIndexFunc)tt_cmap10_char_index, /* char_index */ + (FT_CMap_CharNextFunc) tt_cmap10_char_next, /* char_next */ + (FT_CMap_CharVarIndexFunc) NULL, /* char_var_index */ + (FT_CMap_CharVarIsDefaultFunc)NULL, /* char_var_default */ + (FT_CMap_VariantListFunc) NULL, /* variant_list */ + (FT_CMap_CharVariantListFunc) NULL, /* charvariant_list */ + (FT_CMap_VariantCharListFunc) NULL, /* variantchar_list */ + 10, - (TT_CMap_ValidateFunc)tt_cmap10_validate, - (TT_CMap_Info_GetFunc)tt_cmap10_get_info ) + (TT_CMap_ValidateFunc)tt_cmap10_validate, /* validate */ + (TT_CMap_Info_GetFunc)tt_cmap10_get_info /* get_cmap_info */ + ) #endif /* TT_CONFIG_CMAP_FORMAT_10 */ @@ -2499,22 +2512,24 @@ FT_DEFINE_TT_CMAP( tt_cmap12_class_rec, - sizeof ( TT_CMap12Rec ), - (FT_CMap_InitFunc) tt_cmap12_init, - (FT_CMap_DoneFunc) NULL, - (FT_CMap_CharIndexFunc)tt_cmap12_char_index, - (FT_CMap_CharNextFunc) tt_cmap12_char_next, + sizeof ( TT_CMap12Rec ), - NULL, - NULL, - NULL, - NULL, - NULL, + (FT_CMap_InitFunc) tt_cmap12_init, /* init */ + (FT_CMap_DoneFunc) NULL, /* done */ + (FT_CMap_CharIndexFunc)tt_cmap12_char_index, /* char_index */ + (FT_CMap_CharNextFunc) tt_cmap12_char_next, /* char_next */ + (FT_CMap_CharVarIndexFunc) NULL, /* char_var_index */ + (FT_CMap_CharVarIsDefaultFunc)NULL, /* char_var_default */ + (FT_CMap_VariantListFunc) NULL, /* variant_list */ + (FT_CMap_CharVariantListFunc) NULL, /* charvariant_list */ + (FT_CMap_VariantCharListFunc) NULL, /* variantchar_list */ + 12, - (TT_CMap_ValidateFunc)tt_cmap12_validate, - (TT_CMap_Info_GetFunc)tt_cmap12_get_info ) + (TT_CMap_ValidateFunc)tt_cmap12_validate, /* validate */ + (TT_CMap_Info_GetFunc)tt_cmap12_get_info /* get_cmap_info */ + ) #endif /* TT_CONFIG_CMAP_FORMAT_12 */ @@ -2823,22 +2838,24 @@ FT_DEFINE_TT_CMAP( tt_cmap13_class_rec, - sizeof ( TT_CMap13Rec ), - (FT_CMap_InitFunc) tt_cmap13_init, - (FT_CMap_DoneFunc) NULL, - (FT_CMap_CharIndexFunc)tt_cmap13_char_index, - (FT_CMap_CharNextFunc) tt_cmap13_char_next, + sizeof ( TT_CMap13Rec ), - NULL, - NULL, - NULL, - NULL, - NULL, + (FT_CMap_InitFunc) tt_cmap13_init, /* init */ + (FT_CMap_DoneFunc) NULL, /* done */ + (FT_CMap_CharIndexFunc)tt_cmap13_char_index, /* char_index */ + (FT_CMap_CharNextFunc) tt_cmap13_char_next, /* char_next */ + (FT_CMap_CharVarIndexFunc) NULL, /* char_var_index */ + (FT_CMap_CharVarIsDefaultFunc)NULL, /* char_var_default */ + (FT_CMap_VariantListFunc) NULL, /* variant_list */ + (FT_CMap_CharVariantListFunc) NULL, /* charvariant_list */ + (FT_CMap_VariantCharListFunc) NULL, /* variantchar_list */ + 13, - (TT_CMap_ValidateFunc)tt_cmap13_validate, - (TT_CMap_Info_GetFunc)tt_cmap13_get_info ) + (TT_CMap_ValidateFunc)tt_cmap13_validate, /* validate */ + (TT_CMap_Info_GetFunc)tt_cmap13_get_info /* get_cmap_info */ + ) #endif /* TT_CONFIG_CMAP_FORMAT_13 */ @@ -2929,7 +2946,7 @@ cmap->max_results = 0; - if ( memory != NULL && cmap->results != NULL ) + if ( memory && cmap->results ) FT_FREE( cmap->results ); } @@ -3036,7 +3053,7 @@ if ( numRanges > (FT_ULong)( valid->limit - defp ) / 4 ) FT_INVALID_TOO_SHORT; - for ( i = 0; i < numRanges; ++i ) + for ( i = 0; i < numRanges; i++ ) { FT_ULong base = TT_NEXT_UINT24( defp ); FT_ULong cnt = FT_NEXT_BYTE( defp ); @@ -3069,7 +3086,7 @@ if ( numMappings > ( (FT_ULong)( valid->limit - ndp ) ) / 5 ) FT_INVALID_TOO_SHORT; - for ( i = 0; i < numMappings; ++i ) + for ( i = 0; i < numMappings; i++ ) { FT_ULong uni = TT_NEXT_UINT24( ndp ); FT_ULong gid = TT_NEXT_USHORT( ndp ); @@ -3310,7 +3327,7 @@ return NULL; result = cmap14->results; - for ( i = 0; i < count; ++i ) + for ( i = 0; i < count; i++ ) { result[i] = (FT_UInt32)TT_NEXT_UINT24( p ); p += 8; @@ -3335,7 +3352,7 @@ if ( tt_cmap14_ensure( cmap14, ( count + 1 ), memory ) ) return NULL; - for ( q = cmap14->results; count > 0; --count ) + for ( q = cmap14->results; count > 0; count-- ) { FT_UInt32 varSel = TT_NEXT_UINT24( p ); FT_ULong defOff = TT_NEXT_ULONG( p ); @@ -3394,7 +3411,7 @@ if ( tt_cmap14_ensure( cmap14, ( cnt + 1 ), memory ) ) return NULL; - for ( q = cmap14->results; numRanges > 0; --numRanges ) + for ( q = cmap14->results; numRanges > 0; numRanges-- ) { FT_UInt32 uni = (FT_UInt32)TT_NEXT_UINT24( p ); @@ -3431,7 +3448,7 @@ return NULL; ret = cmap14->results; - for ( i = 0; i < numMappings; ++i ) + for ( i = 0; i < numMappings; i++ ) { ret[i] = (FT_UInt32)TT_NEXT_UINT24( p ); p += 2; @@ -3515,10 +3532,10 @@ { if ( nuni > duni + dcnt ) { - for ( k = 0; k <= dcnt; ++k ) + for ( k = 0; k <= dcnt; k++ ) ret[i++] = duni + k; - ++di; + di++; if ( di > numRanges ) break; @@ -3532,7 +3549,7 @@ ret[i++] = nuni; /* If it is within the default range then ignore it -- */ /* that should not have happened */ - ++ni; + ni++; if ( ni > numMappings ) break; @@ -3551,7 +3568,7 @@ { ret[i++] = (FT_UInt32)TT_NEXT_UINT24( p ); p += 2; - ++ni; + ni++; } } else if ( di <= numRanges ) @@ -3559,7 +3576,7 @@ /* If we get here then we have run out of all non-default */ /* mappings. We have read one default range which we haven't */ /* stored and there may be others that need to be read. */ - for ( k = 0; k <= dcnt; ++k ) + for ( k = 0; k <= dcnt; k++ ) ret[i++] = duni + k; while ( di < numRanges ) @@ -3567,9 +3584,9 @@ duni = (FT_UInt32)TT_NEXT_UINT24( dp ); dcnt = FT_NEXT_BYTE( dp ); - for ( k = 0; k <= dcnt; ++k ) + for ( k = 0; k <= dcnt; k++ ) ret[i++] = duni + k; - ++di; + di++; } } @@ -3582,23 +3599,25 @@ FT_DEFINE_TT_CMAP( tt_cmap14_class_rec, - sizeof ( TT_CMap14Rec ), - (FT_CMap_InitFunc) tt_cmap14_init, - (FT_CMap_DoneFunc) tt_cmap14_done, - (FT_CMap_CharIndexFunc)tt_cmap14_char_index, - (FT_CMap_CharNextFunc) tt_cmap14_char_next, + sizeof ( TT_CMap14Rec ), - /* Format 14 extension functions */ - (FT_CMap_CharVarIndexFunc) tt_cmap14_char_var_index, - (FT_CMap_CharVarIsDefaultFunc)tt_cmap14_char_var_isdefault, - (FT_CMap_VariantListFunc) tt_cmap14_variants, - (FT_CMap_CharVariantListFunc) tt_cmap14_char_variants, - (FT_CMap_VariantCharListFunc) tt_cmap14_variant_chars, + (FT_CMap_InitFunc) tt_cmap14_init, /* init */ + (FT_CMap_DoneFunc) tt_cmap14_done, /* done */ + (FT_CMap_CharIndexFunc)tt_cmap14_char_index, /* char_index */ + (FT_CMap_CharNextFunc) tt_cmap14_char_next, /* char_next */ + /* Format 14 extension functions */ + (FT_CMap_CharVarIndexFunc) tt_cmap14_char_var_index, + (FT_CMap_CharVarIsDefaultFunc)tt_cmap14_char_var_isdefault, + (FT_CMap_VariantListFunc) tt_cmap14_variants, + (FT_CMap_CharVariantListFunc) tt_cmap14_char_variants, + (FT_CMap_VariantCharListFunc) tt_cmap14_variant_chars, + 14, - (TT_CMap_ValidateFunc)tt_cmap14_validate, - (TT_CMap_Info_GetFunc)tt_cmap14_get_info ) + (TT_CMap_ValidateFunc)tt_cmap14_validate, /* validate */ + (TT_CMap_Info_GetFunc)tt_cmap14_get_info /* get_cmap_info */ + ) #endif /* TT_CONFIG_CMAP_FORMAT_14 */ @@ -3737,7 +3756,7 @@ error = clazz->validate( cmap, FT_VALIDATOR( &valid ) ); } - if ( valid.validator.error == 0 ) + if ( !valid.validator.error ) { FT_CMap ttcmap; @@ -3763,7 +3782,7 @@ } } - if ( *pclazz == NULL ) + if ( !*pclazz ) { FT_TRACE0(( "tt_face_build_cmaps:" " unsupported cmap sub-table ignored\n" )); Index: reactos/sdk/lib/3rdparty/freetype/src/sfnt/ttload.c =================================================================== --- reactos/sdk/lib/3rdparty/freetype/src/sfnt/ttload.c (revision 74184) +++ reactos/sdk/lib/3rdparty/freetype/src/sfnt/ttload.c (working copy) @@ -679,7 +679,7 @@ /*************************************************************************/ /* */ /* */ - /* tt_face_load_max_profile */ + /* tt_face_load_maxp */ /* */ /* */ /* Loads the maximum profile into a face object. */ Index: reactos/sdk/lib/3rdparty/freetype/src/sfnt/ttmtx.c =================================================================== --- reactos/sdk/lib/3rdparty/freetype/src/sfnt/ttmtx.c (revision 74184) +++ reactos/sdk/lib/3rdparty/freetype/src/sfnt/ttmtx.c (working copy) @@ -20,6 +20,11 @@ #include FT_INTERNAL_DEBUG_H #include FT_INTERNAL_STREAM_H #include FT_TRUETYPE_TAGS_H + +#ifdef TT_CONFIG_OPTION_GX_VAR_SUPPORT +#include FT_SERVICE_METRICS_VARIATIONS_H +#endif + #include "ttmtx.h" #include "sferrors.h" @@ -214,7 +219,12 @@ FT_ULong table_pos, table_size, table_end; FT_UShort k; +#ifdef TT_CONFIG_OPTION_GX_VAR_SUPPORT + FT_Service_MetricsVariations var = + (FT_Service_MetricsVariations)face->var; +#endif + if ( vertical ) { void* v = &face->vertical; @@ -274,6 +284,34 @@ *abearing = 0; *aadvance = 0; } + +#ifdef TT_CONFIG_OPTION_GX_VAR_SUPPORT + if ( var ) + { + FT_Face f = FT_FACE( face ); + FT_Int a = (FT_Int)*aadvance; + FT_Int b = (FT_Int)*abearing; + + + if ( vertical ) + { + if ( var->vadvance_adjust ) + var->vadvance_adjust( f, gindex, &a ); + if ( var->tsb_adjust ) + var->tsb_adjust( f, gindex, &b ); + } + else + { + if ( var->hadvance_adjust ) + var->hadvance_adjust( f, gindex, &a ); + if ( var->lsb_adjust ) + var->lsb_adjust( f, gindex, &b ); + } + + *aadvance = (FT_UShort)a; + *abearing = (FT_Short)b; + } +#endif } Index: reactos/sdk/lib/3rdparty/freetype/src/sfnt/ttpost.c =================================================================== --- reactos/sdk/lib/3rdparty/freetype/src/sfnt/ttpost.c (revision 74184) +++ reactos/sdk/lib/3rdparty/freetype/src/sfnt/ttpost.c (working copy) @@ -326,7 +326,9 @@ goto Exit; /* check the number of glyphs */ - if ( num_glyphs > face->max_profile.numGlyphs || num_glyphs > 258 ) + if ( num_glyphs > face->max_profile.numGlyphs || + num_glyphs > 258 || + num_glyphs < 1 ) { error = FT_THROW( Invalid_File_Format ); goto Exit; Index: reactos/sdk/lib/3rdparty/freetype/src/sfnt/ttsbit.c =================================================================== --- reactos/sdk/lib/3rdparty/freetype/src/sfnt/ttsbit.c (revision 74184) +++ reactos/sdk/lib/3rdparty/freetype/src/sfnt/ttsbit.c (working copy) @@ -48,6 +48,7 @@ { FT_Error error; FT_ULong table_size; + FT_ULong table_start; face->sbit_table = NULL; @@ -83,6 +84,8 @@ goto Exit; } + table_start = FT_STREAM_POS(); + switch ( (FT_UInt)face->sbit_table_type ) { case TT_SBIT_TABLE_TYPE_EBLC: @@ -104,8 +107,12 @@ version = FT_NEXT_LONG( p ); num_strikes = FT_NEXT_ULONG( p ); + /* there's at least one font (FZShuSong-Z01, version 3) */ + /* that uses the wrong byte order for the `version' field */ if ( ( (FT_ULong)version & 0xFFFF0000UL ) != 0x00020000UL && - ( (FT_ULong)version & 0xFFFF0000UL ) != 0x00030000UL ) + ( (FT_ULong)version & 0x0000FFFFUL ) != 0x00000200UL && + ( (FT_ULong)version & 0xFFFF0000UL ) != 0x00030000UL && + ( (FT_ULong)version & 0x0000FFFFUL ) != 0x00000300UL ) { error = FT_THROW( Unknown_File_Format ); goto Exit; @@ -190,18 +197,27 @@ break; default: + /* we ignore unknown table formats */ error = FT_THROW( Unknown_File_Format ); break; } if ( !error ) - FT_TRACE3(( "sbit_num_strikes: %u\n", face->sbit_num_strikes )); + FT_TRACE3(( "tt_face_load_sbit_strikes: found %u strikes\n", + face->sbit_num_strikes )); face->ebdt_start = 0; face->ebdt_size = 0; - if ( face->sbit_table_type != TT_SBIT_TABLE_TYPE_NONE ) + if ( face->sbit_table_type == TT_SBIT_TABLE_TYPE_SBIX ) { + /* the `sbix' table is self-contained; */ + /* it has no associated data table */ + face->ebdt_start = table_start; + face->ebdt_size = table_size; + } + else if ( face->sbit_table_type != TT_SBIT_TABLE_TYPE_NONE ) + { FT_ULong ebdt_size; @@ -218,6 +234,15 @@ } } + if ( !face->ebdt_size ) + { + FT_TRACE2(( "tt_face_load_sbit_strikes:" + " no embedded bitmap data table found;\n" + " " + " resetting number of strikes to zero\n" )); + face->sbit_num_strikes = 0; + } + return FT_Err_Ok; Exit: @@ -260,9 +285,23 @@ FT_ULong strike_index, FT_Size_Metrics* metrics ) { - if ( strike_index >= (FT_ULong)face->sbit_num_strikes ) - return FT_THROW( Invalid_Argument ); + /* we have to test for the existence of `sbit_strike_map' */ + /* because the function gets also used at the very beginning */ + /* to construct `sbit_strike_map' itself */ + if ( face->sbit_strike_map ) + { + if ( strike_index >= (FT_ULong)face->root.num_fixed_sizes ) + return FT_THROW( Invalid_Argument ); + /* map to real index */ + strike_index = face->sbit_strike_map[strike_index]; + } + else + { + if ( strike_index >= (FT_ULong)face->sbit_num_strikes ) + return FT_THROW( Invalid_Argument ); + } + switch ( (FT_UInt)face->sbit_table_type ) { case TT_SBIT_TABLE_TYPE_EBLC: @@ -305,7 +344,8 @@ FT_TRACE2(( "tt_face_load_strike_metrics:" " sanitizing invalid ascender and descender\n" " " - " values for strike (%d, %d)\n", + " values for strike %d (%dppem, %dppem)\n", + strike_index, metrics->x_ppem, metrics->y_ppem )); /* sanitize buggy ascender and descender values */ @@ -363,7 +403,6 @@ FT_UInt offset; FT_UShort upem, ppem, resolution; TT_HoriHeader *hori; - FT_ULong table_size; FT_Pos ppem_; /* to reduce casts */ FT_Error error; @@ -373,15 +412,11 @@ p = face->sbit_table + 8 + 4 * strike_index; offset = FT_NEXT_ULONG( p ); - error = face->goto_table( face, TTAG_sbix, stream, &table_size ); - if ( error ) - return error; - - if ( offset + 4 > table_size ) + if ( offset + 4 > face->ebdt_size ) return FT_THROW( Invalid_File_Format ); - if ( FT_STREAM_SEEK( FT_STREAM_POS() + offset ) || - FT_FRAME_ENTER( 4 ) ) + if ( FT_STREAM_SEEK( face->ebdt_start + offset ) || + FT_FRAME_ENTER( 4 ) ) return error; ppem = FT_GET_USHORT(); @@ -449,6 +484,8 @@ FT_Stream stream = face->root.stream; + strike_index = face->sbit_strike_map[strike_index]; + if ( !face->ebdt_size ) goto Exit; if ( FT_STREAM_SEEK( face->ebdt_start ) ) @@ -508,7 +545,8 @@ static FT_Error - tt_sbit_decoder_alloc_bitmap( TT_SBitDecoder decoder ) + tt_sbit_decoder_alloc_bitmap( TT_SBitDecoder decoder, + FT_Bool metrics_only ) { FT_Error error = FT_Err_Ok; FT_UInt width, height; @@ -571,6 +609,9 @@ if ( size == 0 ) goto Exit; /* exit successfully! */ + if ( metrics_only ) + goto Exit; /* only metrics are requested */ + error = ft_glyphslot_alloc_bitmap( decoder->face->root.glyph, size ); if ( error ) goto Exit; @@ -637,7 +678,8 @@ FT_UInt glyph_index, FT_Int x_pos, FT_Int y_pos, - FT_UInt recurse_count ); + FT_UInt recurse_count, + FT_Bool metrics_only ); typedef FT_Error (*TT_SBitDecoder_LoadFunc)( TT_SBitDecoder decoder, @@ -967,7 +1009,9 @@ gindex, x_pos + dx, y_pos + dy, - recurse_count + 1 ); + recurse_count + 1, + /* request full bitmap image */ + FALSE ); if ( error ) break; } @@ -1031,6 +1075,7 @@ decoder->stream->memory, p, png_len, + FALSE, FALSE ); Exit: @@ -1049,7 +1094,8 @@ FT_ULong glyph_size, FT_Int x_pos, FT_Int y_pos, - FT_UInt recurse_count ) + FT_UInt recurse_count, + FT_Bool metrics_only ) { FT_Error error; FT_Stream stream = decoder->stream; @@ -1171,11 +1217,15 @@ if ( !decoder->bitmap_allocated ) { - error = tt_sbit_decoder_alloc_bitmap( decoder ); + error = tt_sbit_decoder_alloc_bitmap( decoder, metrics_only ); + if ( error ) goto Fail; } + if ( metrics_only ) + goto Fail; /* this is not an error */ + error = loader( decoder, p, p_limit, x_pos, y_pos, recurse_count ); } @@ -1192,7 +1242,8 @@ FT_UInt glyph_index, FT_Int x_pos, FT_Int y_pos, - FT_UInt recurse_count ) + FT_UInt recurse_count, + FT_Bool metrics_only ) { FT_Byte* p = decoder->eblc_base + decoder->strike_index_array; FT_Byte* p_limit = decoder->eblc_limit; @@ -1377,7 +1428,8 @@ image_end, x_pos, y_pos, - recurse_count ); + recurse_count, + metrics_only ); Failure: return FT_THROW( Invalid_Table ); @@ -1396,10 +1448,10 @@ FT_UInt glyph_index, FT_Stream stream, FT_Bitmap *map, - TT_SBit_MetricsRec *metrics ) + TT_SBit_MetricsRec *metrics, + FT_Bool metrics_only ) { - FT_UInt sbix_pos, strike_offset, glyph_start, glyph_end; - FT_ULong table_size; + FT_UInt strike_offset, glyph_start, glyph_end; FT_Int originOffsetX, originOffsetY; FT_Tag graphicType; FT_Int recurse_depth = 0; @@ -1410,6 +1462,8 @@ FT_UNUSED( map ); + strike_index = face->sbit_strike_map[strike_index]; + metrics->width = 0; metrics->height = 0; @@ -1416,21 +1470,18 @@ p = face->sbit_table + 8 + 4 * strike_index; strike_offset = FT_NEXT_ULONG( p ); - error = face->goto_table( face, TTAG_sbix, stream, &table_size ); - if ( error ) - return error; - sbix_pos = FT_STREAM_POS(); - retry: if ( glyph_index > (FT_UInt)face->root.num_glyphs ) return FT_THROW( Invalid_Argument ); - if ( strike_offset >= table_size || - table_size - strike_offset < 4 + glyph_index * 4 + 8 ) + if ( strike_offset >= face->ebdt_size || + face->ebdt_size - strike_offset < 4 + glyph_index * 4 + 8 ) return FT_THROW( Invalid_File_Format ); - if ( FT_STREAM_SEEK( sbix_pos + strike_offset + 4 + glyph_index * 4 ) || - FT_FRAME_ENTER( 8 ) ) + if ( FT_STREAM_SEEK( face->ebdt_start + + strike_offset + 4 + + glyph_index * 4 ) || + FT_FRAME_ENTER( 8 ) ) return error; glyph_start = FT_GET_ULONG(); @@ -1440,13 +1491,13 @@ if ( glyph_start == glyph_end ) return FT_THROW( Invalid_Argument ); - if ( glyph_start > glyph_end || - glyph_end - glyph_start < 8 || - table_size - strike_offset < glyph_end ) + if ( glyph_start > glyph_end || + glyph_end - glyph_start < 8 || + face->ebdt_size - strike_offset < glyph_end ) return FT_THROW( Invalid_File_Format ); - if ( FT_STREAM_SEEK( sbix_pos + strike_offset + glyph_start ) || - FT_FRAME_ENTER( glyph_end - glyph_start ) ) + if ( FT_STREAM_SEEK( face->ebdt_start + strike_offset + glyph_start ) || + FT_FRAME_ENTER( glyph_end - glyph_start ) ) return error; originOffsetX = FT_GET_SHORT(); @@ -1477,7 +1528,8 @@ stream->memory, stream->cursor, glyph_end - glyph_start - 8, - TRUE ); + TRUE, + metrics_only ); #else error = FT_THROW( Unimplemented_Feature ); #endif @@ -1537,11 +1589,13 @@ error = tt_sbit_decoder_init( decoder, face, strike_index, metrics ); if ( !error ) { - error = tt_sbit_decoder_load_image( decoder, - glyph_index, - 0, - 0, - 0 ); + error = tt_sbit_decoder_load_image( + decoder, + glyph_index, + 0, + 0, + 0, + ( load_flags & FT_LOAD_BITMAP_METRICS_ONLY ) != 0 ); tt_sbit_decoder_done( decoder ); } } @@ -1548,12 +1602,14 @@ break; case TT_SBIT_TABLE_TYPE_SBIX: - error = tt_face_load_sbix_image( face, - strike_index, - glyph_index, - stream, - map, - metrics ); + error = tt_face_load_sbix_image( + face, + strike_index, + glyph_index, + stream, + map, + metrics, + ( load_flags & FT_LOAD_BITMAP_METRICS_ONLY ) != 0 ); break; default: @@ -1562,9 +1618,10 @@ } /* Flatten color bitmaps if color was not requested. */ - if ( !error && - !( load_flags & FT_LOAD_COLOR ) && - map->pixel_mode == FT_PIXEL_MODE_BGRA ) + if ( !error && + !( load_flags & FT_LOAD_COLOR ) && + !( load_flags & FT_LOAD_BITMAP_METRICS_ONLY ) && + map->pixel_mode == FT_PIXEL_MODE_BGRA ) { FT_Bitmap new_map; FT_Library library = face->root.glyph->library; Index: reactos/sdk/lib/3rdparty/freetype/src/smooth/ftgrays.c =================================================================== --- reactos/sdk/lib/3rdparty/freetype/src/smooth/ftgrays.c (revision 74184) +++ reactos/sdk/lib/3rdparty/freetype/src/smooth/ftgrays.c (working copy) @@ -286,6 +286,10 @@ #define FT_MEM_ZERO( dest, count ) FT_MEM_SET( dest, 0, count ) #endif +#ifndef FT_ZERO +#define FT_ZERO( p ) FT_MEM_ZERO( p, sizeof ( *(p) ) ) +#endif + /* as usual, for the speed hungry :-) */ #undef RAS_ARG @@ -371,8 +375,9 @@ /* These macros speed up repetitive divisions by replacing them */ /* with multiplications and right shifts. */ -#define FT_UDIVPREP( b ) \ - long b ## _r = (long)( FT_ULONG_MAX >> PIXEL_BITS ) / ( b ) +#define FT_UDIVPREP( c, b ) \ + long b ## _r = c ? (long)( FT_ULONG_MAX >> PIXEL_BITS ) / ( b ) \ + : 0 #define FT_UDIV( a, b ) \ ( ( (unsigned long)( a ) * (unsigned long)( b ## _r ) ) >> \ ( sizeof( long ) * FT_CHAR_BIT - PIXEL_BITS ) ) @@ -438,6 +443,7 @@ TCoord cover; int invalid; + PCell* ycells; PCell cells; FT_PtrDist max_cells; FT_PtrDist num_cells; @@ -450,8 +456,6 @@ FT_Raster_Span_Func render_span; void* render_span_data; - PCell* ycells; - } gray_TWorker, *gray_PWorker; #if defined( _MSC_VER ) @@ -504,25 +508,22 @@ /* */ /* Record the current cell in the table. */ /* */ - static PCell - gray_find_cell( RAS_ARG ) + static void + gray_record_cell( RAS_ARG ) { PCell *pcell, cell; TCoord x = ras.ex; - if ( x > ras.max_ex ) - x = ras.max_ex; - pcell = &ras.ycells[ras.ey - ras.min_ey]; for (;;) { cell = *pcell; - if ( cell == NULL || cell->x > x ) + if ( !cell || cell->x > x ) break; if ( cell->x == x ) - goto Exit; + goto Found; pcell = &cell->next; } @@ -530,30 +531,21 @@ if ( ras.num_cells >= ras.max_cells ) ft_longjmp( ras.jump_buffer, 1 ); + /* insert new cell */ cell = ras.cells + ras.num_cells++; cell->x = x; - cell->area = 0; - cell->cover = 0; + cell->area = ras.area; + cell->cover = ras.cover; cell->next = *pcell; *pcell = cell; - Exit: - return cell; - } + return; - - static void - gray_record_cell( RAS_ARG ) - { - if ( ras.area | ras.cover ) - { - PCell cell = gray_find_cell( RAS_VAR ); - - - cell->area += ras.area; - cell->cover += ras.cover; - } + Found: + /* update old cell */ + cell->area += ras.area; + cell->cover += ras.cover; } @@ -577,24 +569,18 @@ /* All cells that are on the left of the clipping region go to the */ /* min_ex - 1 horizontal position. */ - if ( ex > ras.max_ex ) - ex = ras.max_ex; if ( ex < ras.min_ex ) ex = ras.min_ex - 1; - /* are we moving to a different cell ? */ - if ( ex != ras.ex || ey != ras.ey ) - { - /* record the current one if it is valid */ - if ( !ras.invalid ) - gray_record_cell( RAS_VAR ); + /* record the current one if it is valid */ + if ( !ras.invalid ) + gray_record_cell( RAS_VAR ); - ras.area = 0; - ras.cover = 0; - ras.ex = ex; - ras.ey = ey; - } + ras.area = 0; + ras.cover = 0; + ras.ex = ex; + ras.ey = ey; ras.invalid = ( ey >= ras.max_ey || ey < ras.min_ey || ex >= ras.max_ex ); @@ -908,8 +894,8 @@ else /* any other line */ { TPos prod = dx * fy1 - dy * fx1; - FT_UDIVPREP( dx ); - FT_UDIVPREP( dy ); + FT_UDIVPREP( ex1 != ex2, dx ); + FT_UDIVPREP( ey1 != ey2, dy ); /* The fundamental value `prod' determines which side and the */ @@ -1316,9 +1302,6 @@ int y; - if ( ras.num_cells == 0 ) - return; - FT_TRACE7(( "gray_sweep: start\n" )); for ( y = ras.min_ey; y < ras.max_ey; y++ ) @@ -1718,14 +1701,16 @@ FT_DEFINE_OUTLINE_FUNCS( func_interface, - (FT_Outline_MoveTo_Func) gray_move_to, - (FT_Outline_LineTo_Func) gray_line_to, - (FT_Outline_ConicTo_Func)gray_conic_to, - (FT_Outline_CubicTo_Func)gray_cubic_to, - 0, - 0 ) + (FT_Outline_MoveTo_Func) gray_move_to, /* move_to */ + (FT_Outline_LineTo_Func) gray_line_to, /* line_to */ + (FT_Outline_ConicTo_Func)gray_conic_to, /* conic_to */ + (FT_Outline_CubicTo_Func)gray_cubic_to, /* cubic_to */ + 0, /* shift */ + 0 /* delta */ + ) + static int gray_convert_glyph_inner( RAS_ARG ) { @@ -1813,11 +1798,9 @@ cell_start = ( ycount * sizeof ( PCell ) + sizeof ( TCell ) - 1 ) / sizeof ( TCell ); - if ( FT_MAX_GRAY_POOL - cell_start < 2 ) - goto ReduceBands; - ras.cells = buffer + cell_start; ras.max_cells = (FT_PtrDist)( FT_MAX_GRAY_POOL - cell_start ); + ras.num_cells = 0; ras.ycells = (PCell*)buffer; while ( ycount ) @@ -1824,10 +1807,9 @@ ras.ycells[--ycount] = NULL; } - ras.num_cells = 0; ras.invalid = 1; ras.min_ey = band[1]; - ras.max_ey = ras.ey = band[0]; + ras.max_ey = band[0]; error = gray_convert_glyph_inner( RAS_VAR ); @@ -1845,7 +1827,6 @@ return 1; } - ReduceBands: /* render pool overflow; we will reduce the render band by half */ width >>= 1; @@ -1878,8 +1859,8 @@ gray_raster_render( FT_Raster raster, const FT_Raster_Params* params ) { - const FT_Outline* outline = (const FT_Outline*)params->source; - const FT_Bitmap* target_map = params->target; + const FT_Outline* outline = (const FT_Outline*)params->source; + const FT_Bitmap* target_map = params->target; FT_BBox cbox, clip; #ifndef FT_STATIC_RASTER @@ -2003,7 +1984,7 @@ *araster = (FT_Raster)&the_raster; - FT_MEM_ZERO( &the_raster, sizeof ( the_raster ) ); + FT_ZERO( &the_raster ); return 0; } @@ -2079,11 +2060,12 @@ FT_GLYPH_FORMAT_OUTLINE, - (FT_Raster_New_Func) gray_raster_new, - (FT_Raster_Reset_Func) gray_raster_reset, - (FT_Raster_Set_Mode_Func)gray_raster_set_mode, - (FT_Raster_Render_Func) gray_raster_render, - (FT_Raster_Done_Func) gray_raster_done ) + (FT_Raster_New_Func) gray_raster_new, /* raster_new */ + (FT_Raster_Reset_Func) gray_raster_reset, /* raster_reset */ + (FT_Raster_Set_Mode_Func)gray_raster_set_mode, /* raster_set_mode */ + (FT_Raster_Render_Func) gray_raster_render, /* raster_render */ + (FT_Raster_Done_Func) gray_raster_done /* raster_done */ + ) /* END */ Index: reactos/sdk/lib/3rdparty/freetype/src/smooth/ftsmooth.c =================================================================== --- reactos/sdk/lib/3rdparty/freetype/src/smooth/ftsmooth.c (revision 74184) +++ reactos/sdk/lib/3rdparty/freetype/src/smooth/ftsmooth.c (working copy) @@ -87,7 +87,7 @@ FT_GlyphSlot slot, FT_BBox* cbox ) { - FT_MEM_ZERO( cbox, sizeof ( *cbox ) ); + FT_ZERO( cbox ); if ( slot->format == render->glyph_format ) FT_Outline_Get_CBox( &slot->outline, cbox ); @@ -114,8 +114,8 @@ #ifndef FT_CONFIG_OPTION_SUBPIXEL_RENDERING FT_Pos height_org, width_org; #endif - FT_Int hmul = mode == FT_RENDER_MODE_LCD; - FT_Int vmul = mode == FT_RENDER_MODE_LCD_V; + FT_Int hmul = ( mode == FT_RENDER_MODE_LCD ); + FT_Int vmul = ( mode == FT_RENDER_MODE_LCD_V ); FT_Raster_Params params; @@ -428,7 +428,8 @@ } - FT_DEFINE_RENDERER( ft_smooth_renderer_class, + FT_DEFINE_RENDERER( + ft_smooth_renderer_class, FT_MODULE_RENDERER, sizeof ( FT_RendererRec ), @@ -437,25 +438,25 @@ 0x10000L, 0x20000L, - 0, /* module specific interface */ + NULL, /* module specific interface */ - (FT_Module_Constructor)ft_smooth_init, - (FT_Module_Destructor) 0, - (FT_Module_Requester) 0 - , + (FT_Module_Constructor)ft_smooth_init, /* module_init */ + (FT_Module_Destructor) NULL, /* module_done */ + (FT_Module_Requester) NULL, /* get_interface */ FT_GLYPH_FORMAT_OUTLINE, - (FT_Renderer_RenderFunc) ft_smooth_render, - (FT_Renderer_TransformFunc)ft_smooth_transform, - (FT_Renderer_GetCBoxFunc) ft_smooth_get_cbox, - (FT_Renderer_SetModeFunc) ft_smooth_set_mode, + (FT_Renderer_RenderFunc) ft_smooth_render, /* render_glyph */ + (FT_Renderer_TransformFunc)ft_smooth_transform, /* transform_glyph */ + (FT_Renderer_GetCBoxFunc) ft_smooth_get_cbox, /* get_glyph_cbox */ + (FT_Renderer_SetModeFunc) ft_smooth_set_mode, /* set_mode */ - (FT_Raster_Funcs*) &FT_GRAYS_RASTER_GET + (FT_Raster_Funcs*)&FT_GRAYS_RASTER_GET /* raster_class */ ) - FT_DEFINE_RENDERER( ft_smooth_lcd_renderer_class, + FT_DEFINE_RENDERER( + ft_smooth_lcd_renderer_class, FT_MODULE_RENDERER, sizeof ( FT_RendererRec ), @@ -464,25 +465,26 @@ 0x10000L, 0x20000L, - 0, /* module specific interface */ + NULL, /* module specific interface */ - (FT_Module_Constructor)ft_smooth_init, - (FT_Module_Destructor) 0, - (FT_Module_Requester) 0 - , + (FT_Module_Constructor)ft_smooth_init, /* module_init */ + (FT_Module_Destructor) NULL, /* module_done */ + (FT_Module_Requester) NULL, /* get_interface */ FT_GLYPH_FORMAT_OUTLINE, - (FT_Renderer_RenderFunc) ft_smooth_render_lcd, - (FT_Renderer_TransformFunc)ft_smooth_transform, - (FT_Renderer_GetCBoxFunc) ft_smooth_get_cbox, - (FT_Renderer_SetModeFunc) ft_smooth_set_mode, + (FT_Renderer_RenderFunc) ft_smooth_render_lcd, /* render_glyph */ + (FT_Renderer_TransformFunc)ft_smooth_transform, /* transform_glyph */ + (FT_Renderer_GetCBoxFunc) ft_smooth_get_cbox, /* get_glyph_cbox */ + (FT_Renderer_SetModeFunc) ft_smooth_set_mode, /* set_mode */ - (FT_Raster_Funcs*) &FT_GRAYS_RASTER_GET + (FT_Raster_Funcs*)&FT_GRAYS_RASTER_GET /* raster_class */ ) - FT_DEFINE_RENDERER( ft_smooth_lcdv_renderer_class, + FT_DEFINE_RENDERER( + ft_smooth_lcdv_renderer_class, + FT_MODULE_RENDERER, sizeof ( FT_RendererRec ), @@ -490,21 +492,20 @@ 0x10000L, 0x20000L, - 0, /* module specific interface */ + NULL, /* module specific interface */ - (FT_Module_Constructor)ft_smooth_init, - (FT_Module_Destructor) 0, - (FT_Module_Requester) 0 - , + (FT_Module_Constructor)ft_smooth_init, /* module_init */ + (FT_Module_Destructor) NULL, /* module_done */ + (FT_Module_Requester) NULL, /* get_interface */ FT_GLYPH_FORMAT_OUTLINE, - (FT_Renderer_RenderFunc) ft_smooth_render_lcd_v, - (FT_Renderer_TransformFunc)ft_smooth_transform, - (FT_Renderer_GetCBoxFunc) ft_smooth_get_cbox, - (FT_Renderer_SetModeFunc) ft_smooth_set_mode, + (FT_Renderer_RenderFunc) ft_smooth_render_lcd_v, /* render_glyph */ + (FT_Renderer_TransformFunc)ft_smooth_transform, /* transform_glyph */ + (FT_Renderer_GetCBoxFunc) ft_smooth_get_cbox, /* get_glyph_cbox */ + (FT_Renderer_SetModeFunc) ft_smooth_set_mode, /* set_mode */ - (FT_Raster_Funcs*) &FT_GRAYS_RASTER_GET + (FT_Raster_Funcs*)&FT_GRAYS_RASTER_GET /* raster_class */ ) Index: reactos/sdk/lib/3rdparty/freetype/src/tools/apinames.c =================================================================== --- reactos/sdk/lib/3rdparty/freetype/src/tools/apinames.c (revision 74184) +++ reactos/sdk/lib/3rdparty/freetype/src/tools/apinames.c (working copy) @@ -90,7 +90,7 @@ max_names += (max_names >> 1) + 4; the_names = (NameRec*)realloc( the_names, sizeof ( the_names[0] ) * max_names ); - if ( the_names == NULL ) + if ( !the_names ) panic( "not enough memory" ); } nm = &the_names[num_names++]; @@ -97,7 +97,7 @@ nm->hash = h; nm->name = (char*)malloc( len+1 ); - if ( nm->name == NULL ) + if ( !nm->name ) panic( "not enough memory" ); memcpy( nm->name, name, len ); @@ -159,7 +159,7 @@ char temp[512]; - if ( dll_name == NULL ) + if ( !dll_name ) { fprintf( stderr, "you must provide a DLL name with the -d option!\n" ); @@ -168,7 +168,7 @@ /* we must omit the .dll suffix from the library name */ dot = strchr( dll_name, '.' ); - if ( dot != NULL ) + if ( dot ) { int len = dot - dll_name; @@ -190,7 +190,7 @@ case OUTPUT_NETWARE_IMP: { - if ( dll_name != NULL ) + if ( dll_name ) fprintf( out, " (%s)\n", dll_name ); for ( nn = 0; nn < num_names - 1; nn++ ) fprintf( out, " %s,\n", the_names[nn].name ); @@ -371,7 +371,7 @@ arg += 2; out = fopen( arg, "wt" ); - if ( out == NULL ) + if ( !out ) { fprintf( stderr, "could not open '%s' for writing\n", argv[2] ); exit(3); @@ -440,7 +440,7 @@ { FILE* file = fopen( argv[0], "rb" ); - if ( file == NULL ) + if ( !file ) fprintf( stderr, "unable to open '%s'\n", argv[0] ); else { Index: reactos/sdk/lib/3rdparty/freetype/src/tools/ftrandom/ftrandom.c =================================================================== --- reactos/sdk/lib/3rdparty/freetype/src/tools/ftrandom/ftrandom.c (revision 74184) +++ reactos/sdk/lib/3rdparty/freetype/src/tools/ftrandom/ftrandom.c (working copy) @@ -177,7 +177,7 @@ FT_Set_Char_Size( face, 0, font_size, 72, 72 ); - for ( gid = 0; gid < face->num_glyphs; ++gid ) + for ( gid = 0; gid < face->num_glyphs; gid++ ) { if ( check_outlines && FT_IS_SCALABLE( face ) ) @@ -225,7 +225,7 @@ num = face->num_faces; FT_Done_Face( face ); - for ( i = 0; i < num; ++i ) + for ( i = 0; i < num; i++ ) { if ( !FT_New_Face( context, testfont, i, &face ) ) TestFace( face ); @@ -246,16 +246,16 @@ char* pt; - if ( extensions == NULL ) + if ( !extensions ) return true; pt = strrchr( filename, '.' ); - if ( pt == NULL ) + if ( !pt ) return false; if ( pt < strrchr( filename, '/' ) ) return false; - for ( i = 0; extensions[i] != NULL; ++i ) + for ( i = 0; extensions[i] != NULL; i++ ) if ( strcasecmp( pt + 1, extensions[i] ) == 0 || strcasecmp( pt, extensions[i] ) == 0 ) return true; @@ -273,7 +273,7 @@ item->isbinary = item->isascii = item->ishex = false; foo = fopen( item->name, "rb" ); - if ( foo != NULL ) + if ( foo ) { /* Try to guess the file type from the first few characters... */ int ch1 = getc( foo ); @@ -300,8 +300,8 @@ else if ( ch1 == '%' && ch2 == '!' ) { /* Random PostScript */ - if ( strstr( item->name, ".pfa" ) != NULL || - strstr( item->name, ".PFA" ) != NULL ) + if ( strstr( item->name, ".pfa" ) || + strstr( item->name, ".PFA" ) ) item->ishex = true; else item->isascii = true; @@ -357,7 +357,7 @@ max = 0; fcnt = 0; - for ( i = 0; fontdirs[i] != NULL; ++i ) + for ( i = 0; fontdirs[i] != NULL; i++ ) { DIR* examples; struct dirent* ent; @@ -364,7 +364,7 @@ examples = opendir( fontdirs[i] ); - if ( examples == NULL ) + if ( !examples ) { fprintf( stderr, "Can't open example font directory `%s'\n", @@ -378,13 +378,13 @@ "%s/%s", fontdirs[i], ent->d_name ); if ( stat( buffer, &statb ) == -1 || S_ISDIR( statb.st_mode ) ) continue; - if ( extensions == NULL || extmatch( buffer, extensions ) ) + if ( !extensions || extmatch( buffer, extensions ) ) { if ( fcnt >= max ) { max += 100; fontlist = realloc( fontlist, max * sizeof ( struct fontlist ) ); - if ( fontlist == NULL ) + if ( !fontlist ) { fprintf( stderr, "Can't allocate memory\n" ); exit( 1 ); @@ -395,7 +395,7 @@ fontlist[fcnt].len = statb.st_size; figurefiletype( &fontlist[fcnt] ); - ++fcnt; + fcnt++; } } @@ -438,20 +438,20 @@ char* newfont ) { static char buffer[8096]; - FILE *good, *new; + FILE *good, *newf; size_t len; unsigned int i, err_cnt; good = fopen( item->name, "r" ); - if ( good == NULL ) + if ( !good ) { fprintf( stderr, "Can't open `%s'\n", item->name ); return false; } - new = fopen( newfont, "w+" ); - if ( new == NULL ) + newf = fopen( newfont, "w+" ); + if ( !newf ) { fprintf( stderr, "Can't create temporary output file `%s'\n", newfont ); @@ -459,19 +459,19 @@ } while ( ( len = fread( buffer, 1, sizeof ( buffer ), good ) ) > 0 ) - fwrite( buffer, 1, len, new ); + fwrite( buffer, 1, len, newf ); fclose( good ); err_cnt = getErrorCnt( item ); - for ( i = 0; i < err_cnt; ++i ) + for ( i = 0; i < err_cnt; i++ ) { - fseek( new, getRandom( 0, (int)( item->len - 1 ) ), SEEK_SET ); + fseek( newf, getRandom( 0, (int)( item->len - 1 ) ), SEEK_SET ); if ( item->isbinary ) - putc( getRandom( 0, 0xFF ), new ); + putc( getRandom( 0, 0xFF ), newf ); else if ( item->isascii ) - putc( getRandom( 0x20, 0x7E ), new ); + putc( getRandom( 0x20, 0x7E ), newf ); else { int hex = getRandom( 0, 15 ); @@ -482,18 +482,18 @@ else hex += 'A' - 10; - putc( hex, new ); + putc( hex, newf ); } } - if ( ferror( new ) ) + if ( ferror( newf ) ) { - fclose( new ); + fclose( newf ); unlink( newfont ); return false; } - fclose( new ); + fclose( newf ); return true; } @@ -609,7 +609,7 @@ dirs = calloc( (size_t)( argc + 1 ), sizeof ( char ** ) ); exts = calloc( (size_t)( argc + 1 ), sizeof ( char ** ) ); - for ( i = 1; i < argc; ++i ) + for ( i = 1; i < argc; i++ ) { char* pt = argv[i]; char* end; @@ -616,7 +616,7 @@ if ( pt[0] == '-' && pt[1] == '-' ) - ++pt; + pt++; if ( strcmp( pt, "-all" ) == 0 ) allexts = true; @@ -701,7 +701,7 @@ dirs = default_dir_list; } - if ( testfile != NULL ) + if ( testfile ) ExecuteTest( testfile ); /* This should never return */ time( &now ); Index: reactos/sdk/lib/3rdparty/freetype/src/tools/glnames.py =================================================================== --- reactos/sdk/lib/3rdparty/freetype/src/tools/glnames.py (revision 74184) +++ reactos/sdk/lib/3rdparty/freetype/src/tools/glnames.py (working copy) @@ -415,7 +415,7 @@ # This data has been taken literally from the files `glyphlist.txt' # and `zapfdingbats.txt' version 2.0, Sept 2002. It is available from # -# http://sourceforge.net/adobe/aglfn/ +# https://github.com/adobe-type-tools/agl-aglfn # adobe_glyph_list = """\ A;0041 @@ -4920,8 +4920,17 @@ def dump( self, file ): write = file.write - write( " static const char " + self.master_table + - "[" + repr( self.total ) + "] =\n" ) + write( "#ifndef DEFINE_PS_TABLES\n" ) + write( "#ifdef __cplusplus\n" ) + write( ' extern "C"\n' ) + write( "#else\n" ) + write( " extern\n" ) + write( "#endif\n" ) + write( "#endif\n" ) + write( " const char " + self.master_table + + "[" + repr( self.total ) + "]\n" ) + write( "#ifdef DEFINE_PS_TABLES\n" ) + write( " =\n" ) write( " {\n" ) line = "" @@ -4930,7 +4939,10 @@ line += string.join( ( re.findall( ".", name ) ), "','" ) line += "', 0,\n" - write( line + " };\n\n\n" ) + write( line ) + write( " }\n" ) + write( "#endif /* DEFINE_PS_TABLES */\n" ) + write( " ;\n\n\n" ) def dump_sublist( self, file, table_name, macro_name, sublist ): write = file.write @@ -4938,8 +4950,17 @@ write( " /* Values are offsets into the `" + self.master_table + "' table */\n\n" ) - write( " static const short " + table_name + - "[" + macro_name + "] =\n" ) + write( "#ifndef DEFINE_PS_TABLES\n" ) + write( "#ifdef __cplusplus\n" ) + write( ' extern "C"\n' ) + write( "#else\n" ) + write( " extern\n" ) + write( "#endif\n" ) + write( "#endif\n" ) + write( " const short " + table_name + + "[" + macro_name + "]\n" ) + write( "#ifdef DEFINE_PS_TABLES\n" ) + write( " =\n" ) write( " {\n" ) line = " " @@ -4955,7 +4976,11 @@ col = 0 comma = ",\n " - write( line + "\n };\n\n\n" ) + write( line ) + write( "\n" ) + write( " }\n" ) + write( "#endif /* DEFINE_PS_TABLES */\n" ) + write( " ;\n\n\n" ) # We now store the Adobe Glyph List in compressed form. The list is put @@ -5188,8 +5213,17 @@ write = file.write write( " /* the following are indices into the SID name table */\n" ) - write( " static const unsigned short " + encoding_name + - "[" + repr( len( encoding_list ) ) + "] =\n" ) + write( "#ifndef DEFINE_PS_TABLES\n" ) + write( "#ifdef __cplusplus\n" ) + write( ' extern "C"\n' ) + write( "#else\n" ) + write( " extern\n" ) + write( "#endif\n" ) + write( "#endif\n" ) + write( " const unsigned short " + encoding_name + + "[" + repr( len( encoding_list ) ) + "]\n" ) + write( "#ifdef DEFINE_PS_TABLES\n" ) + write( " =\n" ) write( " {\n" ) line = " " @@ -5204,14 +5238,27 @@ col = 0 comma = ",\n " - write( line + "\n };\n\n\n" ) + write( line ) + write( "\n" ) + write( " }\n" ) + write( "#endif /* DEFINE_PS_TABLES */\n" ) + write( " ;\n\n\n" ) def dump_array( the_array, write, array_name ): """dumps a given encoding""" - write( " static const unsigned char " + array_name + - "[" + repr( len( the_array ) ) + "L] =\n" ) + write( "#ifndef DEFINE_PS_TABLES\n" ) + write( "#ifdef __cplusplus\n" ) + write( ' extern "C"\n' ) + write( "#else\n" ) + write( " extern\n" ) + write( "#endif\n" ) + write( "#endif\n" ) + write( " const unsigned char " + array_name + + "[" + repr( len( the_array ) ) + "L]\n" ) + write( "#ifdef DEFINE_PS_TABLES\n" ) + write( " =\n" ) write( " {\n" ) line = "" @@ -5232,7 +5279,11 @@ write( line ) line = "" - write( line + "\n };\n\n\n" ) + write( line ) + write( "\n" ) + write( " }\n" ) + write( "#endif /* DEFINE_PS_TABLES */\n" ) + write( " ;\n\n\n" ) def main(): @@ -5267,7 +5318,7 @@ write( "/* */\n" ) write( "/* PostScript glyph names. */\n" ) write( "/* */\n" ) - write( "/* Copyright 2005-2015 by */\n" ) + write( "/* Copyright 2005-2016 by */\n" ) write( "/* David Turner, Robert Wilhelm, and Werner Lemberg. */\n" ) write( "/* */\n" ) write( "/* This file is part of the FreeType project, and may only be used, */\n" ) Index: reactos/sdk/lib/3rdparty/freetype/src/truetype/ttdriver.c =================================================================== --- reactos/sdk/lib/3rdparty/freetype/src/truetype/ttdriver.c (revision 74184) +++ reactos/sdk/lib/3rdparty/freetype/src/truetype/ttdriver.c (working copy) @@ -25,6 +25,7 @@ #ifdef TT_CONFIG_OPTION_GX_VAR_SUPPORT #include FT_MULTIPLE_MASTERS_H #include FT_SERVICE_MULTIPLE_MASTERS_H +#include FT_SERVICE_METRICS_VARIATIONS_H #endif #include FT_SERVICE_TRUETYPE_ENGINE_H @@ -144,8 +145,10 @@ FT_DEFINE_SERVICE_PROPERTIESREC( tt_service_properties, + (FT_Properties_SetFunc)tt_property_set, /* set_property */ - (FT_Properties_GetFunc)tt_property_get ) /* get_property */ + (FT_Properties_GetFunc)tt_property_get /* get_property */ + ) /*************************************************************************/ @@ -221,7 +224,7 @@ FT_Fixed *advances ) { FT_UInt nn; - TT_Face face = (TT_Face) ttface; + TT_Face face = (TT_Face)ttface; /* XXX: TODO: check for sbits */ @@ -228,6 +231,13 @@ if ( flags & FT_LOAD_VERTICAL_LAYOUT ) { +#ifdef TT_CONFIG_OPTION_GX_VAR_SUPPORT + /* no fast retrieval for blended MM fonts without VVAR table */ + if ( !face->is_default_instance && + !( face->variation_support & TT_FACE_FLAG_VAR_VADVANCE ) ) + return FT_THROW( Unimplemented_Feature ); +#endif + for ( nn = 0; nn < count; nn++ ) { FT_Short tsb; @@ -241,6 +251,13 @@ } else { +#ifdef TT_CONFIG_OPTION_GX_VAR_SUPPORT + /* no fast retrieval for blended MM fonts without HVAR table */ + if ( !face->is_default_instance && + !( face->variation_support & TT_FACE_FLAG_VAR_HADVANCE ) ) + return FT_THROW( Unimplemented_Feature ); +#endif + for ( nn = 0; nn < count; nn++ ) { FT_Short lsb; @@ -291,7 +308,7 @@ } else { - SFNT_Service sfnt = (SFNT_Service) ttface->sfnt; + SFNT_Service sfnt = (SFNT_Service)ttface->sfnt; FT_Size_Metrics* metrics = &size->metrics; @@ -319,7 +336,7 @@ if ( FT_HAS_FIXED_SIZES( size->face ) ) { TT_Face ttface = (TT_Face)size->face; - SFNT_Service sfnt = (SFNT_Service) ttface->sfnt; + SFNT_Service sfnt = (SFNT_Service)ttface->sfnt; FT_ULong strike_index; @@ -462,16 +479,40 @@ /*************************************************************************/ #ifdef TT_CONFIG_OPTION_GX_VAR_SUPPORT + FT_DEFINE_SERVICE_MULTIMASTERSREC( tt_service_gx_multi_masters, + (FT_Get_MM_Func) NULL, /* get_mm */ (FT_Set_MM_Design_Func) NULL, /* set_mm_design */ (FT_Set_MM_Blend_Func) TT_Set_MM_Blend, /* set_mm_blend */ + (FT_Get_MM_Blend_Func) TT_Get_MM_Blend, /* get_mm_blend */ (FT_Get_MM_Var_Func) TT_Get_MM_Var, /* get_mm_var */ - (FT_Set_Var_Design_Func)TT_Set_Var_Design ) /* set_var_design */ -#endif + (FT_Set_Var_Design_Func)TT_Set_Var_Design, /* set_var_design */ + (FT_Get_Var_Design_Func)TT_Get_Var_Design, /* get_var_design */ + (FT_Get_Var_Blend_Func) tt_get_var_blend, /* get_var_blend */ + (FT_Done_Blend_Func) tt_done_blend /* done_blend */ + ) + FT_DEFINE_SERVICE_METRICSVARIATIONSREC( + tt_service_metrics_variations, + + (FT_HAdvance_Adjust_Func)tt_hadvance_adjust, /* hadvance_adjust */ + (FT_LSB_Adjust_Func) NULL, /* lsb_adjust */ + (FT_RSB_Adjust_Func) NULL, /* rsb_adjust */ + + (FT_VAdvance_Adjust_Func)NULL, /* vadvance_adjust */ + (FT_TSB_Adjust_Func) NULL, /* tsb_adjust */ + (FT_BSB_Adjust_Func) NULL, /* bsb_adjust */ + (FT_VOrg_Adjust_Func) NULL, /* vorg_adjust */ + + (FT_Metrics_Adjust_Func) NULL /* metrics_adjust */ + ) + +#endif /* TT_CONFIG_OPTION_GX_VAR_SUPPORT */ + + static const FT_Service_TrueTypeEngineRec tt_service_truetype_engine = { #ifdef TT_USE_BYTECODE_INTERPRETER @@ -488,20 +529,25 @@ FT_DEFINE_SERVICE_TTGLYFREC( tt_service_truetype_glyf, - (TT_Glyf_GetLocationFunc)tt_face_get_location ) /* get_location */ + (TT_Glyf_GetLocationFunc)tt_face_get_location /* get_location */ + ) + #ifdef TT_CONFIG_OPTION_GX_VAR_SUPPORT - FT_DEFINE_SERVICEDESCREC5( + FT_DEFINE_SERVICEDESCREC6( tt_services, - FT_SERVICE_ID_FONT_FORMAT, FT_FONT_FORMAT_TRUETYPE, - FT_SERVICE_ID_MULTI_MASTERS, &TT_SERVICE_GX_MULTI_MASTERS_GET, - FT_SERVICE_ID_TRUETYPE_ENGINE, &tt_service_truetype_engine, - FT_SERVICE_ID_TT_GLYF, &TT_SERVICE_TRUETYPE_GLYF_GET, - FT_SERVICE_ID_PROPERTIES, &TT_SERVICE_PROPERTIES_GET ) + + FT_SERVICE_ID_FONT_FORMAT, FT_FONT_FORMAT_TRUETYPE, + FT_SERVICE_ID_MULTI_MASTERS, &TT_SERVICE_GX_MULTI_MASTERS_GET, + FT_SERVICE_ID_METRICS_VARIATIONS, &TT_SERVICE_METRICS_VARIATIONS_GET, + FT_SERVICE_ID_TRUETYPE_ENGINE, &tt_service_truetype_engine, + FT_SERVICE_ID_TT_GLYF, &TT_SERVICE_TRUETYPE_GLYF_GET, + FT_SERVICE_ID_PROPERTIES, &TT_SERVICE_PROPERTIES_GET ) #else FT_DEFINE_SERVICEDESCREC4( tt_services, + FT_SERVICE_ID_FONT_FORMAT, FT_FONT_FORMAT_TRUETYPE, FT_SERVICE_ID_TRUETYPE_ENGINE, &tt_service_truetype_engine, FT_SERVICE_ID_TT_GLYF, &TT_SERVICE_TRUETYPE_GLYF_GET, @@ -529,7 +575,7 @@ #endif result = ft_service_list_lookup( TT_SERVICES_GET, tt_interface ); - if ( result != NULL ) + if ( result ) return result; #ifndef FT_CONFIG_OPTION_PIC @@ -580,7 +626,7 @@ 0x10000L, /* driver version == 1.0 */ 0x20000L, /* driver requires FreeType 2.0 or above */ - 0, /* module-specific interface */ + NULL, /* module-specific interface */ tt_driver_init, /* FT_Module_Constructor module_init */ tt_driver_done, /* FT_Module_Destructor module_done */ @@ -595,12 +641,12 @@ tt_size_init, /* FT_Size_InitFunc init_size */ tt_size_done, /* FT_Size_DoneFunc done_size */ tt_slot_init, /* FT_Slot_InitFunc init_slot */ - 0, /* FT_Slot_DoneFunc done_slot */ + NULL, /* FT_Slot_DoneFunc done_slot */ tt_glyph_load, /* FT_Slot_LoadFunc load_glyph */ tt_get_kerning, /* FT_Face_GetKerningFunc get_kerning */ - 0, /* FT_Face_AttachFunc attach_file */ + NULL, /* FT_Face_AttachFunc attach_file */ tt_get_advances, /* FT_Face_GetAdvancesFunc get_advances */ tt_size_request, /* FT_Size_RequestFunc request_size */ Index: reactos/sdk/lib/3rdparty/freetype/src/truetype/ttgload.c =================================================================== --- reactos/sdk/lib/3rdparty/freetype/src/truetype/ttgload.c (revision 74184) +++ reactos/sdk/lib/3rdparty/freetype/src/truetype/ttgload.c (working copy) @@ -441,7 +441,7 @@ flag = (FT_Byte*)outline->tags; flag_limit = flag + n_points; - FT_ASSERT( flag != NULL ); + FT_ASSERT( flag ); while ( flag < flag_limit ) { @@ -886,7 +886,7 @@ #ifdef TT_CONFIG_OPTION_GX_VAR_SUPPORT - if ( loader->face->doblend ) + if ( loader->face->doblend && !loader->face->is_default_instance ) { /* Deltas apply to the unscaled data. */ error = TT_Vary_Apply_Glyph_Deltas( loader->face, @@ -893,6 +893,16 @@ loader->glyph_index, outline, (FT_UInt)n_points ); + + /* recalculate linear horizontal and vertical advances */ + /* if we don't have HVAR and VVAR, respectively */ + if ( !( loader->face->variation_support & TT_FACE_FLAG_VAR_HADVANCE ) ) + loader->linear = outline->points[n_points - 3].x - + outline->points[n_points - 4].x; + if ( !( loader->face->variation_support & TT_FACE_FLAG_VAR_VADVANCE ) ) + loader->vadvance = outline->points[n_points - 1].x - + outline->points[n_points - 2].x; + if ( error ) return error; } @@ -1487,7 +1497,7 @@ offset = 0; loader->byte_len = glyph_data.length; - FT_MEM_ZERO( &inc_stream, sizeof ( inc_stream ) ); + FT_ZERO( &inc_stream ); FT_Stream_OpenMemory( &inc_stream, glyph_data.pointer, (FT_ULong)glyph_data.length ); @@ -1505,10 +1515,10 @@ { #ifdef FT_CONFIG_OPTION_INCREMENTAL /* for the incremental interface, `glyf_offset' is always zero */ - if ( !loader->glyf_offset && + if ( !face->glyf_offset && !face->root.internal->incremental_interface ) #else - if ( !loader->glyf_offset ) + if ( !face->glyf_offset ) #endif /* FT_CONFIG_OPTION_INCREMENTAL */ { FT_TRACE2(( "no `glyf' table but non-zero `loca' entry\n" )); @@ -1517,7 +1527,7 @@ } error = face->access_glyph_frame( loader, glyph_index, - loader->glyf_offset + offset, + face->glyf_offset + offset, (FT_UInt)loader->byte_len ); if ( error ) goto Exit; @@ -1564,7 +1574,7 @@ #ifdef TT_CONFIG_OPTION_GX_VAR_SUPPORT - if ( loader->face->doblend ) + if ( loader->face->doblend && !loader->face->is_default_instance ) { /* a small outline structure with four elements for */ /* communication with `TT_Vary_Apply_Glyph_Deltas' */ @@ -1607,6 +1617,14 @@ loader->pp3.y = points[2].y; loader->pp4.x = points[3].x; loader->pp4.y = points[3].y; + + + /* recalculate linear horizontal and vertical advances */ + /* if we don't have HVAR and VVAR, respectively */ + if ( !( loader->face->variation_support & TT_FACE_FLAG_VAR_HADVANCE ) ) + loader->linear = loader->pp2.x - loader->pp1.x; + if ( !( loader->face->variation_support & TT_FACE_FLAG_VAR_VADVANCE ) ) + loader->vadvance = loader->pp4.x - loader->pp3.x; } #endif /* TT_CONFIG_OPTION_GX_VAR_SUPPORT */ @@ -1727,7 +1745,7 @@ #ifdef TT_CONFIG_OPTION_GX_VAR_SUPPORT - if ( face->doblend ) + if ( face->doblend && !face->is_default_instance ) { short i, limit; FT_SubGlyph subglyph; @@ -1796,11 +1814,11 @@ /* this call provides additional offsets */ /* for each component's translation */ - if ( ( error = TT_Vary_Apply_Glyph_Deltas( - face, - glyph_index, - &outline, - (FT_UInt)outline.n_points ) ) != 0 ) + if ( FT_SET_ERROR( TT_Vary_Apply_Glyph_Deltas( + face, + glyph_index, + &outline, + (FT_UInt)outline.n_points ) ) ) goto Exit1; subglyph = gloader->current.subglyphs; @@ -1824,6 +1842,13 @@ loader->pp4.x = points[i + 3].x; loader->pp4.y = points[i + 3].y; + /* recalculate linear horizontal and vertical advances */ + /* if we don't have HVAR and VVAR, respectively */ + if ( !( face->variation_support & TT_FACE_FLAG_VAR_HADVANCE ) ) + loader->linear = loader->pp2.x - loader->pp1.x; + if ( !( face->variation_support & TT_FACE_FLAG_VAR_VADVANCE ) ) + loader->vadvance = loader->pp4.x - loader->pp3.x; + Exit1: FT_FREE( outline.points ); FT_FREE( outline.tags ); @@ -1883,7 +1908,10 @@ { FT_Vector pp[4]; + FT_Int linear_hadvance; + FT_Int linear_vadvance; + /* Each time we call load_truetype_glyph in this loop, the */ /* value of `gloader.base.subglyphs' can change due to table */ /* reallocations. We thus need to recompute the subglyph */ @@ -1895,6 +1923,9 @@ pp[2] = loader->pp3; pp[3] = loader->pp4; + linear_hadvance = loader->linear; + linear_vadvance = loader->vadvance; + num_base_points = (FT_UInt)gloader->base.outline.n_points; error = load_truetype_glyph( loader, @@ -1914,6 +1945,9 @@ loader->pp2 = pp[1]; loader->pp3 = pp[2]; loader->pp4 = pp[3]; + + loader->linear = linear_hadvance; + loader->vadvance = linear_vadvance; } num_points = (FT_UInt)gloader->base.outline.n_points; @@ -2252,7 +2286,7 @@ face = (TT_Face)glyph->face; stream = face->root.stream; - FT_MEM_ZERO( loader, sizeof ( TT_LoaderRec ) ); + FT_ZERO( loader ); #ifdef TT_USE_BYTECODE_INTERPRETER @@ -2497,32 +2531,6 @@ #endif /* TT_USE_BYTECODE_INTERPRETER */ - /* seek to the beginning of the glyph table -- for Type 42 fonts */ - /* the table might be accessed from a Postscript stream or something */ - /* else... */ - -#ifdef FT_CONFIG_OPTION_INCREMENTAL - - if ( face->root.internal->incremental_interface ) - loader->glyf_offset = 0; - else - -#endif - - { - error = face->goto_table( face, TTAG_glyf, stream, 0 ); - - if ( FT_ERR_EQ( error, Table_Missing ) ) - loader->glyf_offset = 0; - else if ( error ) - { - FT_ERROR(( "tt_loader_init: could not access glyph table\n" )); - return error; - } - else - loader->glyf_offset = FT_STREAM_POS(); - } - /* get face's glyph loader */ if ( !glyf_table_only ) { @@ -2593,17 +2601,21 @@ FT_Error error; TT_LoaderRec loader; +#ifdef TT_CONFIG_OPTION_GX_VAR_SUPPORT +#define IS_DEFAULT_INSTANCE ( ( (TT_Face)glyph->face )->is_default_instance ) +#else +#define IS_DEFAULT_INSTANCE 1 +#endif + FT_TRACE1(( "TT_Load_Glyph: glyph index %d\n", glyph_index )); #ifdef TT_CONFIG_OPTION_EMBEDDED_BITMAPS - /* try to load embedded bitmap if any */ - /* */ - /* XXX: The convention should be emphasized in */ - /* the documents because it can be confusing. */ + /* try to load embedded bitmap (if any) */ if ( size->strike_index != 0xFFFFFFFFUL && - ( load_flags & FT_LOAD_NO_BITMAP ) == 0 ) + ( load_flags & FT_LOAD_NO_BITMAP ) == 0 && + IS_DEFAULT_INSTANCE ) { error = load_sbit_image( size, glyph, glyph_index, load_flags ); if ( !error ) Index: reactos/sdk/lib/3rdparty/freetype/src/truetype/ttgxvar.c =================================================================== --- reactos/sdk/lib/3rdparty/freetype/src/truetype/ttgxvar.c (revision 74184) +++ reactos/sdk/lib/3rdparty/freetype/src/truetype/ttgxvar.c (working copy) @@ -380,7 +380,7 @@ segment->correspondence[j].fromCoord = FT_GET_SHORT() * 4; segment->correspondence[j].toCoord = FT_GET_SHORT() * 4; - FT_TRACE5(( " mapping %.4f to %.4f\n", + FT_TRACE5(( " mapping %.5f to %.5f\n", segment->correspondence[j].fromCoord / 65536.0, segment->correspondence[j].toCoord / 65536.0 )); } @@ -393,6 +393,514 @@ } + /* some macros we need */ + #define FT_FIXED_ONE ( (FT_Fixed)0x10000 ) + + #define FT_fdot14ToFixed( x ) \ + ( ( (FT_Fixed)( (FT_Int16)(x) ) ) << 2 ) + #define FT_intToFixed( i ) \ + ( (FT_Fixed)( (FT_UInt32)(i) << 16 ) ) + #define FT_fixedToInt( x ) \ + ( (FT_Short)( ( (FT_UInt32)(x) + 0x8000U ) >> 16 ) ) + + + /*************************************************************************/ + /* */ + /* */ + /* ft_var_load_hvar */ + /* */ + /* */ + /* Parse the `HVAR' table and set `blend->hvar_loaded' to TRUE. */ + /* */ + /* On success, `blend->hvar_checked' is set to TRUE. */ + /* */ + /* Some memory may remain allocated on error; it is always freed in */ + /* `tt_done_blend', however. */ + /* */ + /* */ + /* face :: The font face. */ + /* */ + /* */ + /* FreeType error code. 0 means success. */ + /* */ + static FT_Error + ft_var_load_hvar( TT_Face face ) + { + FT_Stream stream = FT_FACE_STREAM( face ); + FT_Memory memory = stream->memory; + + GX_Blend blend = face->blend; + + FT_Error error; + FT_UShort majorVersion; + FT_ULong table_len; + FT_ULong table_offset; + FT_ULong store_offset; + + FT_ULong* dataOffsetArray = NULL; + + + blend->hvar_loaded = TRUE; + + FT_TRACE2(( "HVAR " )); + + error = face->goto_table( face, TTAG_HVAR, stream, &table_len ); + if ( error ) + { + FT_TRACE2(( "is missing\n" )); + goto Exit; + } + + table_offset = FT_STREAM_POS(); + + /* skip minor version */ + if ( FT_READ_USHORT( majorVersion ) || + FT_STREAM_SKIP( 2 ) ) + goto Exit; + if ( majorVersion != 1 ) + { + FT_TRACE2(( "bad table version %d\n", majorVersion )); + error = FT_THROW( Invalid_Table ); + goto Exit; + } + + /* skip map offset */ + if ( FT_READ_ULONG( store_offset ) || + FT_STREAM_SKIP( 4 ) ) + goto Exit; + + /* parse item variation store */ + { + FT_UShort format; + FT_ULong region_offset; + FT_UInt i, j, k; + FT_UInt shortDeltaCount; + + GX_HVStore itemStore; + GX_HVarTable hvarTable; + GX_HVarData hvarData; + + + if ( FT_STREAM_SEEK( table_offset + store_offset ) || + FT_READ_USHORT( format ) ) + goto Exit; + if ( format != 1 ) + { + FT_TRACE2(( "bad store format %d\n", format )); + error = FT_THROW( Invalid_Table ); + goto Exit; + } + + if ( FT_NEW( blend->hvar_table ) ) /* allocate table at top level */ + goto Exit; + + hvarTable = blend->hvar_table; + itemStore = &hvarTable->itemStore; + + /* read top level fields */ + if ( FT_READ_ULONG( region_offset ) || + FT_READ_USHORT( itemStore->dataCount ) ) + goto Exit; + + /* make temporary copy of item variation data offsets; */ + /* we will parse region list first, then come back */ + if ( FT_NEW_ARRAY( dataOffsetArray, itemStore->dataCount ) ) + goto Exit; + + for ( i = 0; i < itemStore->dataCount; i++ ) + { + if ( FT_READ_ULONG( dataOffsetArray[i] ) ) + goto Exit; + } + + /* parse array of region records (region list) */ + if ( FT_STREAM_SEEK( table_offset + store_offset + region_offset ) ) + goto Exit; + + if ( FT_READ_USHORT( itemStore->axisCount ) || + FT_READ_USHORT( itemStore->regionCount ) ) + goto Exit; + + if ( FT_NEW_ARRAY( itemStore->varRegionList, itemStore->regionCount ) ) + goto Exit; + + for ( i = 0; i < itemStore->regionCount; i++ ) + { + GX_AxisCoords axisCoords; + + + if ( FT_NEW_ARRAY( itemStore->varRegionList[i].axisList, + itemStore->axisCount ) ) + goto Exit; + + axisCoords = itemStore->varRegionList[i].axisList; + + for ( j = 0; j < itemStore->axisCount; j++ ) + { + FT_Short start, peak, end; + + + if ( FT_READ_SHORT( start ) || + FT_READ_SHORT( peak ) || + FT_READ_SHORT( end ) ) + goto Exit; + + axisCoords[j].startCoord = FT_fdot14ToFixed( start ); + axisCoords[j].peakCoord = FT_fdot14ToFixed( peak ); + axisCoords[j].endCoord = FT_fdot14ToFixed( end ); + } + } + + /* end of region list parse */ + + /* use dataOffsetArray now to parse varData items */ + if ( FT_NEW_ARRAY( itemStore->varData, itemStore->dataCount ) ) + goto Exit; + + for ( i = 0; i < itemStore->dataCount; i++ ) + { + hvarData = &itemStore->varData[i]; + + if ( FT_STREAM_SEEK( table_offset + + store_offset + + dataOffsetArray[i] ) ) + goto Exit; + + if ( FT_READ_USHORT( hvarData->itemCount ) || + FT_READ_USHORT( shortDeltaCount ) || + FT_READ_USHORT( hvarData->regionIdxCount ) ) + goto Exit; + + /* check some data consistency */ + if ( shortDeltaCount > hvarData->regionIdxCount ) + { + FT_TRACE2(( "bad short count %d or region count %d\n", + shortDeltaCount, + hvarData->regionIdxCount )); + error = FT_THROW( Invalid_Table ); + goto Exit; + } + + if ( hvarData->regionIdxCount > itemStore->regionCount ) + { + FT_TRACE2(( "inconsistent regionCount %d in varData[%d]\n", + hvarData->regionIdxCount, + i )); + error = FT_THROW( Invalid_Table ); + goto Exit; + } + + /* parse region indices */ + if ( FT_NEW_ARRAY( hvarData->regionIndices, + hvarData->regionIdxCount ) ) + goto Exit; + + for ( j = 0; j < hvarData->regionIdxCount; j++ ) + { + if ( FT_READ_USHORT( hvarData->regionIndices[j] ) ) + goto Exit; + + if ( hvarData->regionIndices[j] >= itemStore->regionCount ) + { + FT_TRACE2(( "bad region index %d\n", + hvarData->regionIndices[j] )); + error = FT_THROW( Invalid_Table ); + goto Exit; + } + } + + /* Parse delta set. */ + /* */ + /* On input, deltas are ( shortDeltaCount + regionIdxCount ) bytes */ + /* each; on output, deltas are expanded to `regionIdxCount' shorts */ + /* each. */ + if ( FT_NEW_ARRAY( hvarData->deltaSet, + hvarData->regionIdxCount * hvarData->itemCount ) ) + goto Exit; + + /* the delta set is stored as a 2-dimensional array of shorts; */ + /* sign-extend signed bytes to signed shorts */ + for ( j = 0; j < hvarData->itemCount * hvarData->regionIdxCount; ) + { + for ( k = 0; k < shortDeltaCount; k++, j++ ) + { + /* read the short deltas */ + FT_Short delta; + + + if ( FT_READ_SHORT( delta ) ) + goto Exit; + + hvarData->deltaSet[j] = delta; + } + + for ( ; k < hvarData->regionIdxCount; k++, j++ ) + { + /* read the (signed) byte deltas */ + FT_Char delta; + + + if ( FT_READ_CHAR( delta ) ) + goto Exit; + + hvarData->deltaSet[j] = delta; + } + } + } + } + + /* end parse item variation store */ + + /* parse width map */ + { + GX_WidthMap widthMap; + + FT_UShort format; + FT_UInt entrySize; + FT_UInt innerBitCount; + FT_UInt innerIndexMask; + FT_UInt i, j; + + + widthMap = &blend->hvar_table->widthMap; + + if ( FT_READ_USHORT( format ) || + FT_READ_USHORT( widthMap->mapCount ) ) + goto Exit; + + if ( format & 0xFFC0 ) + { + FT_TRACE2(( "bad map format %d\n", format )); + error = FT_THROW( Invalid_Table ); + goto Exit; + } + + /* bytes per entry: 1, 2, 3, or 4 */ + entrySize = ( ( format & 0x0030 ) >> 4 ) + 1; + innerBitCount = ( format & 0x000F ) + 1; + innerIndexMask = ( 1 << innerBitCount ) - 1; + + if ( FT_NEW_ARRAY( widthMap->innerIndex, widthMap->mapCount ) ) + goto Exit; + + if ( FT_NEW_ARRAY( widthMap->outerIndex, widthMap->mapCount ) ) + goto Exit; + + for ( i = 0; i < widthMap->mapCount; i++ ) + { + FT_UInt mapData = 0; + FT_UInt outerIndex, innerIndex; + + + /* read map data one unsigned byte at a time, big endian */ + for ( j = 0; j < entrySize; j++ ) + { + FT_Byte data; + + + if ( FT_READ_BYTE( data ) ) + goto Exit; + + mapData = ( mapData << 8 ) | data; + } + + outerIndex = mapData >> innerBitCount; + + if ( outerIndex >= blend->hvar_table->itemStore.dataCount ) + { + FT_TRACE2(( "outerIndex[%d] == %d out of range\n", + i, + outerIndex )); + error = FT_THROW( Invalid_Table ); + goto Exit; + } + + widthMap->outerIndex[i] = outerIndex; + + innerIndex = mapData & innerIndexMask; + + if ( innerIndex >= + blend->hvar_table->itemStore.varData[outerIndex].itemCount ) + { + FT_TRACE2(( "innerIndex[%d] == %d out of range\n", + i, + innerIndex )); + error = FT_THROW( Invalid_Table ); + goto Exit; + } + + widthMap->innerIndex[i] = innerIndex; + } + } + + /* end parse width map */ + + FT_TRACE2(( "loaded\n" )); + error = FT_Err_Ok; + + Exit: + FT_FREE( dataOffsetArray ); + + if ( !error ) + { + blend->hvar_checked = TRUE; + + /* TODO: implement other HVAR stuff */ + face->variation_support |= TT_FACE_FLAG_VAR_HADVANCE; + } + + return error; + } + + + /*************************************************************************/ + /* */ + /* */ + /* tt_hadvance_adjust */ + /* */ + /* */ + /* Apply HVAR advance width adjustment of a given glyph. */ + /* */ + /* */ + /* gindex :: The glyph index. */ + /* */ + /* */ + /* face :: The font face. */ + /* */ + /* adelta :: Points to width value that gets modified. */ + /* */ + FT_LOCAL_DEF( FT_Error ) + tt_hadvance_adjust( TT_Face face, + FT_UInt gindex, + FT_Int *avalue ) + { + FT_Error error = FT_Err_Ok; + + GX_HVarData varData; + + FT_UInt innerIndex, outerIndex; + FT_UInt master, j; + FT_Fixed netAdjustment = 0; /* accumulated adjustment */ + FT_Fixed scaledDelta; + FT_Short* deltaSet; + FT_Fixed delta; + + + if ( !face->doblend || !face->blend ) + goto Exit; + + if ( !face->blend->hvar_loaded ) + { + /* initialize hvar table */ + face->blend->hvar_error = ft_var_load_hvar( face ); + } + + if ( !face->blend->hvar_checked ) + { + error = face->blend->hvar_error; + goto Exit; + } + + /* advance width adjustments are always present in an `HVAR' table, */ + /* so need to test for this capability */ + + if ( gindex >= face->blend->hvar_table->widthMap.mapCount ) + { + FT_TRACE2(( "gindex %d out of range\n", gindex )); + error = FT_THROW( Invalid_Argument ); + goto Exit; + } + + /* trust that HVAR parser has checked indices */ + outerIndex = face->blend->hvar_table->widthMap.outerIndex[gindex]; + innerIndex = face->blend->hvar_table->widthMap.innerIndex[gindex]; + varData = &face->blend->hvar_table->itemStore.varData[outerIndex]; + deltaSet = &varData->deltaSet[varData->regionIdxCount * innerIndex]; + + /* See pseudo code from `Font Variations Overview' */ + /* in the OpenType specification. */ + + /* outer loop steps through master designs to be blended */ + for ( master = 0; master < varData->regionIdxCount; master++ ) + { + FT_Fixed scalar = FT_FIXED_ONE; + FT_UInt regionIndex = varData->regionIndices[master]; + + GX_AxisCoords axis = face->blend + ->hvar_table + ->itemStore.varRegionList[regionIndex] + .axisList; + + + /* inner loop steps through axes in this region */ + for ( j = 0; + j < face->blend->hvar_table->itemStore.axisCount; + j++, axis++ ) + { + FT_Fixed axisScalar; + + + /* compute the scalar contribution of this axis; */ + /* ignore invalid ranges */ + if ( axis->startCoord > axis->peakCoord || + axis->peakCoord > axis->endCoord ) + axisScalar = FT_FIXED_ONE; + + else if ( axis->startCoord < 0 && + axis->endCoord > 0 && + axis->peakCoord != 0 ) + axisScalar = FT_FIXED_ONE; + + /* peak of 0 means ignore this axis */ + else if ( axis->peakCoord == 0 ) + axisScalar = FT_FIXED_ONE; + + /* ignore this region if coords are out of range */ + else if ( face->blend->normalizedcoords[j] < axis->startCoord || + face->blend->normalizedcoords[j] > axis->endCoord ) + axisScalar = 0; + + /* calculate a proportional factor */ + else + { + if ( face->blend->normalizedcoords[j] == axis->peakCoord ) + axisScalar = FT_FIXED_ONE; + else if ( face->blend->normalizedcoords[j] < axis->peakCoord ) + axisScalar = + FT_DivFix( face->blend->normalizedcoords[j] - axis->startCoord, + axis->peakCoord - axis->startCoord ); + else + axisScalar = + FT_DivFix( axis->endCoord - face->blend->normalizedcoords[j], + axis->endCoord - axis->peakCoord ); + } + + /* take product of all the axis scalars */ + scalar = FT_MulFix( scalar, axisScalar ); + + } /* per-axis loop */ + + /* get the scaled delta for this region */ + delta = FT_intToFixed( deltaSet[master] ); + scaledDelta = FT_MulFix( scalar, delta ); + + /* accumulate the adjustments from each region */ + netAdjustment = netAdjustment + scaledDelta; + + } /* per-region loop */ + + /* apply the accumulated adjustment to derive the interpolated value */ + FT_TRACE5(( "horizontal width %d adjusted by %d units (HVAR)\n", + *avalue, + FT_fixedToInt( netAdjustment ) )); + + *avalue += FT_fixedToInt( netAdjustment ); + + Exit: + return error; + } + + typedef struct GX_GVar_Head_ { FT_Long version; @@ -454,10 +962,10 @@ FT_TRACE2(( "GVAR " )); - if ( ( error = face->goto_table( face, - TTAG_gvar, - stream, - &table_len ) ) != 0 ) + if ( FT_SET_ERROR( face->goto_table( face, + TTAG_gvar, + stream, + &table_len ) ) ) { FT_TRACE2(( "is missing\n" )); goto Exit; @@ -556,7 +1064,7 @@ { blend->tuplecoords[i * gvar_head.axisCount + j] = FT_GET_SHORT() * 4; /* convert to FT_Fixed */ - FT_TRACE5(( "%.4f ", + FT_TRACE5(( "%.5f ", blend->tuplecoords[i * gvar_head.axisCount + j] / 65536.0 )); } FT_TRACE5(( "]\n" )); @@ -612,10 +1120,10 @@ for ( i = 0; i < blend->num_axis; i++ ) { - FT_TRACE6(( " axis coordinate %d (%.4f):\n", + FT_TRACE6(( " axis coordinate %d (%.5f):\n", i, blend->normalizedcoords[i] / 65536.0 )); if ( !( tupleIndex & GX_TI_INTERMEDIATE_TUPLE ) ) - FT_TRACE6(( " intermediate coordinates %d (%.4f, %.4f):\n", + FT_TRACE6(( " intermediate coordinates %d (%.5f, %.5f):\n", i, im_start_coords[i] / 65536.0, im_end_coords[i] / 65536.0 )); @@ -640,7 +1148,7 @@ if ( blend->normalizedcoords[i] == tuple_coords[i] ) { - FT_TRACE6(( " tuple coordinate value %.4f fits perfectly\n", + FT_TRACE6(( " tuple coordinate value %.5f fits perfectly\n", tuple_coords[i] / 65536.0 )); /* `apply' does not change */ continue; @@ -653,13 +1161,13 @@ if ( blend->normalizedcoords[i] < FT_MIN( 0, tuple_coords[i] ) || blend->normalizedcoords[i] > FT_MAX( 0, tuple_coords[i] ) ) { - FT_TRACE6(( " tuple coordinate value %.4f is exceeded, stop\n", + FT_TRACE6(( " tuple coordinate value %.5f is exceeded, stop\n", tuple_coords[i] / 65536.0 )); apply = 0; break; } - FT_TRACE6(( " tuple coordinate value %.4f fits\n", + FT_TRACE6(( " tuple coordinate value %.5f fits\n", tuple_coords[i] / 65536.0 )); apply = FT_MulDiv( apply, blend->normalizedcoords[i], @@ -672,7 +1180,7 @@ if ( blend->normalizedcoords[i] < im_start_coords[i] || blend->normalizedcoords[i] > im_end_coords[i] ) { - FT_TRACE6(( " intermediate tuple range [%.4f;%.4f] is exceeded," + FT_TRACE6(( " intermediate tuple range [%.5f;%.5f] is exceeded," " stop\n", im_start_coords[i] / 65536.0, im_end_coords[i] / 65536.0 )); @@ -682,7 +1190,7 @@ else if ( blend->normalizedcoords[i] < tuple_coords[i] ) { - FT_TRACE6(( " intermediate tuple range [%.4f;%.4f] fits\n", + FT_TRACE6(( " intermediate tuple range [%.5f;%.5f] fits\n", im_start_coords[i] / 65536.0, im_end_coords[i] / 65536.0 )); apply = FT_MulDiv( apply, @@ -692,7 +1200,7 @@ else { - FT_TRACE6(( " intermediate tuple range [%.4f;%.4f] fits\n", + FT_TRACE6(( " intermediate tuple range [%.5f;%.5f] fits\n", im_start_coords[i] / 65536.0, im_end_coords[i] / 65536.0 )); apply = FT_MulDiv( apply, @@ -702,7 +1210,7 @@ } } - FT_TRACE6(( " apply factor is %.4f\n", apply / 65536.0 )); + FT_TRACE6(( " apply factor is %.5f\n", apply / 65536.0 )); return apply; } @@ -778,6 +1286,7 @@ FT_Var_Axis* a; FT_Var_Named_Style* ns; GX_FVar_Head fvar_head; + FT_Bool usePsName; static const FT_Frame_Field fvar_fields[] = { @@ -816,21 +1325,26 @@ /* read the font data and set up the internal representation */ /* if not already done */ - if ( face->blend == NULL ) + if ( !face->blend ) { FT_TRACE2(( "FVAR " )); /* both `fvar' and `gvar' must be present */ - if ( ( error = face->goto_table( face, TTAG_gvar, - stream, &table_len ) ) != 0 ) + if ( FT_SET_ERROR( face->goto_table( face, TTAG_gvar, + stream, &table_len ) ) ) { - FT_TRACE1(( "\n" - "TT_Get_MM_Var: `gvar' table is missing\n" )); - goto Exit; + /* CFF2 is an alternate to gvar here */ + if ( FT_SET_ERROR( face->goto_table( face, TTAG_CFF2, + stream, &table_len ) ) ) + { + FT_TRACE1(( "\n" + "TT_Get_MM_Var: `gvar' or `CFF2' table is missing\n" )); + goto Exit; + } } - if ( ( error = face->goto_table( face, TTAG_fvar, - stream, &table_len ) ) != 0 ) + if ( FT_SET_ERROR( face->goto_table( face, TTAG_fvar, + stream, &table_len ) ) ) { FT_TRACE1(( "is missing\n" )); goto Exit; @@ -838,30 +1352,13 @@ fvar_start = FT_STREAM_POS( ); + /* the validity of the `fvar' header data was already checked */ + /* in function `sfnt_init_face' */ if ( FT_STREAM_READ_FIELDS( fvar_fields, &fvar_head ) ) goto Exit; - if ( fvar_head.version != (FT_Long)0x00010000L || -#if 0 - /* fonts like `JamRegular.ttf' have an incorrect value for */ - /* `countSizePairs'; since value 2 is hard-coded in `fvar' */ - /* version 1.0, we simply ignore it */ - fvar_head.countSizePairs != 2 || -#endif - fvar_head.axisSize != 20 || - /* axisCount limit implied by 16-bit instanceSize */ - fvar_head.axisCount > 0x3FFE || - fvar_head.instanceSize != 4 + 4 * fvar_head.axisCount || - /* instanceCount limit implied by limited range of name IDs */ - fvar_head.instanceCount > 0x7EFF || - fvar_head.offsetToData + fvar_head.axisCount * 20U + - fvar_head.instanceCount * fvar_head.instanceSize > table_len ) - { - FT_TRACE1(( "\n" - "TT_Get_MM_Var: invalid `fvar' header\n" )); - error = FT_THROW( Invalid_Table ); - goto Exit; - } + usePsName = FT_BOOL( fvar_head.instanceSize == + 6 + 4 * fvar_head.axisCount ); FT_TRACE2(( "loaded\n" )); @@ -938,7 +1435,18 @@ a->name[3] = (FT_String)( ( a->tag ) & 0xFF ); a->name[4] = '\0'; - FT_TRACE5(( " \"%s\": minimum=%.4f, default=%.4f, maximum=%.4f\n", + if ( a->minimum > a->def || + a->def > a->maximum ) + { + FT_TRACE2(( "TT_Get_MM_Var:" + " invalid \"%s\" axis record; disabling\n", + a->name )); + + a->minimum = a->def; + a->maximum = a->def; + } + + FT_TRACE5(( " \"%s\": minimum=%.5f, default=%.5f, maximum=%.5f\n", a->name, a->minimum / 65536.0, a->def / 65536.0, @@ -952,7 +1460,9 @@ ns = mmvar->namedstyle; for ( i = 0; i < fvar_head.instanceCount; i++, ns++ ) { - if ( FT_FRAME_ENTER( 4L + 4L * fvar_head.axisCount ) ) + /* PostScript names add 2 bytes to the instance record size */ + if ( FT_FRAME_ENTER( ( usePsName ? 6L : 4L ) + + 4L * fvar_head.axisCount ) ) goto Exit; ns->strid = FT_GET_USHORT(); @@ -961,6 +1471,9 @@ for ( j = 0; j < fvar_head.axisCount; j++ ) ns->coords[j] = FT_GET_LONG(); + if ( usePsName ) + ns->psid = FT_GET_USHORT(); + FT_FRAME_EXIT(); } } @@ -967,7 +1480,7 @@ /* fill the output array if requested */ - if ( master != NULL ) + if ( master ) { FT_UInt n; @@ -1051,6 +1564,7 @@ GX_Blend blend; FT_MM_Var* mmvar; FT_UInt i; + FT_Bool is_default_instance = 1; FT_Memory memory = face->root.memory; enum @@ -1064,9 +1578,9 @@ face->doblend = FALSE; - if ( face->blend == NULL ) + if ( !face->blend ) { - if ( ( error = TT_Get_MM_Var( face, NULL ) ) != 0 ) + if ( FT_SET_ERROR( TT_Get_MM_Var( face, NULL ) ) ) goto Exit; } @@ -1084,24 +1598,27 @@ for ( i = 0; i < num_coords; i++ ) { - FT_TRACE5(( " %.4f\n", coords[i] / 65536.0 )); + FT_TRACE5(( " %.5f\n", coords[i] / 65536.0 )); if ( coords[i] < -0x00010000L || coords[i] > 0x00010000L ) { - FT_TRACE1(( "TT_Set_MM_Blend: normalized design coordinate %.4f\n" + FT_TRACE1(( "TT_Set_MM_Blend: normalized design coordinate %.5f\n" " is out of range [-1;1]\n", coords[i] / 65536.0 )); error = FT_THROW( Invalid_Argument ); goto Exit; } + + if ( coords[i] != 0 ) + is_default_instance = 0; } FT_TRACE5(( "\n" )); - if ( blend->glyphoffsets == NULL ) - if ( ( error = ft_var_load_gvar( face ) ) != 0 ) + if ( !face->isCFF2 && !blend->glyphoffsets ) + if ( FT_SET_ERROR( ft_var_load_gvar( face ) ) ) goto Exit; - if ( blend->normalizedcoords == NULL ) + if ( !blend->normalizedcoords ) { if ( FT_NEW_ARRAY( blend->normalizedcoords, mmvar->num_axis ) ) goto Exit; @@ -1147,7 +1664,7 @@ face->doblend = TRUE; - if ( face->cvt != NULL ) + if ( face->cvt ) { switch ( manageCvt ) { @@ -1172,6 +1689,8 @@ } } + face->is_default_instance = is_default_instance; + Exit: return error; } @@ -1180,6 +1699,73 @@ /*************************************************************************/ /* */ /* */ + /* TT_Get_MM_Blend */ + /* */ + /* */ + /* Get the blend (normalized) coordinates for this instance of the */ + /* font. */ + /* */ + /* */ + /* face :: The font. */ + /* Initialize the blend structure with `gvar' data. */ + /* */ + /* */ + /* num_coords :: The number of available coordinates. If it is */ + /* larger than the number of axes, set the excess */ + /* values to 0. */ + /* */ + /* coords :: An array of `num_coords', each between [-1,1]. */ + /* */ + /* */ + /* FreeType error code. 0 means success. */ + /* */ + FT_LOCAL_DEF( FT_Error ) + TT_Get_MM_Blend( TT_Face face, + FT_UInt num_coords, + FT_Fixed* coords ) + { + FT_Error error = FT_Err_Ok; + GX_Blend blend; + FT_UInt i, nc; + + + if ( !face->blend ) + { + if ( FT_SET_ERROR( TT_Get_MM_Var( face, NULL ) ) ) + return error; + } + + blend = face->blend; + + nc = num_coords; + if ( num_coords > blend->num_axis ) + { + FT_TRACE2(( "TT_Get_MM_Blend: only using first %d of %d coordinates\n", + blend->num_axis, num_coords )); + nc = blend->num_axis; + } + + if ( face->doblend ) + { + for ( i = 0; i < nc; i++ ) + coords[i] = blend->normalizedcoords[i]; + } + else + { + for ( i = 0; i < nc; i++ ) + coords[i] = 0; + } + + for ( ; i < num_coords; i++ ) + coords[i] = 0; + + return FT_Err_Ok; + } + + + /*************************************************************************/ + /* */ + /* */ /* TT_Set_Var_Design */ /* */ /* */ @@ -1217,9 +1803,9 @@ FT_Memory memory = face->root.memory; - if ( face->blend == NULL ) + if ( !face->blend ) { - if ( ( error = TT_Get_MM_Var( face, NULL ) ) != 0 ) + if ( FT_SET_ERROR( TT_Get_MM_Var( face, NULL ) ) ) goto Exit; } @@ -1234,7 +1820,7 @@ num_coords = mmvar->num_axis; } - /* Axis normalization is a two stage process. First we normalize */ + /* Axis normalization is a two-stage process. First we normalize */ /* based on the [min,def,max] values for the axis to be [-1,0,1]. */ /* Then, if there's an `avar' table, we renormalize this range. */ @@ -1246,26 +1832,33 @@ a = mmvar->axis; for ( i = 0; i < num_coords; i++, a++ ) { - FT_TRACE5(( " %.4f\n", coords[i] / 65536.0 )); - if ( coords[i] > a->maximum || coords[i] < a->minimum ) + FT_Fixed coord = coords[i]; + + + FT_TRACE5(( " %.5f\n", coord / 65536.0 )); + if ( coord > a->maximum || coord < a->minimum ) { - FT_TRACE1(( "TT_Set_Var_Design: normalized design coordinate %.4f\n" - " is out of range [%.4f;%.4f]\n", - coords[i] / 65536.0, - a->minimum / 65536.0, - a->maximum / 65536.0 )); - error = FT_THROW( Invalid_Argument ); - goto Exit; + FT_TRACE1(( + "TT_Set_Var_Design: design coordinate %.5f\n" + " is out of range [%.5f;%.5f]; clamping\n", + coord / 65536.0, + a->minimum / 65536.0, + a->maximum / 65536.0 )); + + if ( coord > a->maximum) + coord = a->maximum; + else + coord = a->minimum; } - if ( coords[i] < a->def ) + if ( coord < a->def ) normalized[i] = -FT_DivFix( coords[i] - a->def, a->minimum - a->def ); - else if ( a->maximum == a->def ) - normalized[i] = 0; - else + else if ( coord > a->def ) normalized[i] = FT_DivFix( coords[i] - a->def, a->maximum - a->def ); + else + normalized[i] = 0; } FT_TRACE5(( "\n" )); @@ -1276,7 +1869,7 @@ if ( !blend->avar_checked ) ft_var_load_avar( face ); - if ( blend->avar_segment != NULL ) + if ( blend->avar_segment ) { FT_TRACE5(( "normalized design coordinates" " before applying `avar' data:\n" )); @@ -1286,9 +1879,10 @@ { for ( j = 1; j < (FT_UInt)av->pairCount; j++ ) { - FT_TRACE5(( " %.4f\n", normalized[i] / 65536.0 )); if ( normalized[i] < av->correspondence[j].fromCoord ) { + FT_TRACE5(( " %.5f\n", normalized[i] / 65536.0 )); + normalized[i] = FT_MulDiv( normalized[i] - av->correspondence[j - 1].fromCoord, av->correspondence[j].toCoord - @@ -1311,7 +1905,124 @@ /*************************************************************************/ + /* */ + /* */ + /* TT_Get_Var_Design */ + /* */ + /* */ + /* Get the design coordinates of the currently selected interpolated */ + /* font. */ + /* */ + /* */ + /* face :: A handle to the source face. */ + /* */ + /* num_coords :: The number of design coordinates to retrieve. If it */ + /* is larger than the number of axes, set the excess */ + /* values to~0. */ + /* */ + /* */ + /* coords :: The design coordinates array. */ + /* */ + /* */ + /* FreeType error code. 0~means success. */ + /* */ + FT_LOCAL_DEF( FT_Error ) + TT_Get_Var_Design( TT_Face face, + FT_UInt num_coords, + FT_Fixed* coords ) + { + FT_Error error = FT_Err_Ok; + + GX_Blend blend; + FT_MM_Var* mmvar; + FT_Var_Axis* a; + + FT_UInt i, j, nc; + + + if ( !face->blend ) + { + if ( FT_SET_ERROR( TT_Get_MM_Var( face, NULL ) ) ) + return error; + } + + blend = face->blend; + + nc = num_coords; + if ( num_coords > blend->num_axis ) + { + FT_TRACE2(( "TT_Get_Var_Design: only using first %d of %d coordinates\n", + blend->num_axis, num_coords )); + nc = blend->num_axis; + } + + if ( face->doblend ) + { + for ( i = 0; i < nc; i++ ) + coords[i] = blend->normalizedcoords[i]; + } + else + { + for ( i = 0; i < nc; i++ ) + coords[i] = 0; + } + + for ( ; i < num_coords; i++ ) + coords[i] = 0; + + if ( !blend->avar_checked ) + ft_var_load_avar( face ); + + if ( blend->avar_segment ) + { + GX_AVarSegment av = blend->avar_segment; + + + FT_TRACE5(( "design coordinates" + " after removing `avar' distortion:\n" )); + + for ( i = 0; i < nc; i++, av++ ) + { + for ( j = 1; j < (FT_UInt)av->pairCount; j++ ) + { + if ( coords[i] < av->correspondence[j].toCoord ) + { + coords[i] = + FT_MulDiv( coords[i] - av->correspondence[j - 1].toCoord, + av->correspondence[j].fromCoord - + av->correspondence[j - 1].fromCoord, + av->correspondence[j].toCoord - + av->correspondence[j - 1].toCoord ) + + av->correspondence[j - 1].fromCoord; + + FT_TRACE5(( " %.5f\n", coords[i] / 65536.0 )); + break; + } + } + } + } + + mmvar = blend->mmvar; + a = mmvar->axis; + + for ( i = 0; i < nc; i++, a++ ) + { + if ( coords[i] < 0 ) + coords[i] = a->def + FT_MulFix( coords[i], + a->def - a->minimum ); + else if ( coords[i] > 0 ) + coords[i] = a->def + FT_MulFix( coords[i], + a->maximum - a->def ); + else + coords[i] = a->def; + } + + return FT_Err_Ok; + } + + /*************************************************************************/ + /*************************************************************************/ /***** *****/ /***** GX VAR PARSING ROUTINES *****/ /***** *****/ @@ -1363,7 +2074,7 @@ FT_TRACE2(( "CVAR " )); - if ( blend == NULL ) + if ( !blend ) { FT_TRACE2(( "\n" "tt_face_vary_cvt: no blend specified\n" )); @@ -1371,7 +2082,7 @@ goto Exit; } - if ( face->cvt == NULL ) + if ( !face->cvt ) { FT_TRACE2(( "\n" "tt_face_vary_cvt: no `cvt ' table\n" )); @@ -1414,7 +2125,8 @@ offsetToData = FT_GET_USHORT(); /* rough sanity test */ - if ( offsetToData + tupleCount * 4 > table_len ) + if ( offsetToData + ( tupleCount & GX_TC_TUPLE_COUNT_MASK ) * 4 > + table_len ) { FT_TRACE2(( "tt_face_vary_cvt:" " invalid CVT variation array header\n" )); @@ -1498,7 +2210,7 @@ table_len, point_count == 0 ? face->cvt_size : point_count ); - if ( localpoints == NULL || deltas == NULL ) + if ( !localpoints || !deltas ) ; /* failure, ignore it */ else if ( localpoints == ALL_POINTS ) @@ -1546,10 +2258,15 @@ for ( j = 0; j < point_count; j++ ) { - int pindex = localpoints[j]; - FT_Long orig_cvt = face->cvt[pindex]; + int pindex; + FT_Long orig_cvt; + pindex = localpoints[j]; + if ( (FT_ULong)pindex >= face->cvt_size ) + continue; + + orig_cvt = face->cvt[pindex]; face->cvt[pindex] = (FT_Short)( orig_cvt + FT_MulFix( deltas[j], apply ) ); @@ -1858,7 +2575,7 @@ FT_Short *deltas_x, *deltas_y; - if ( !face->doblend || blend == NULL ) + if ( !face->doblend || !blend ) return FT_THROW( Invalid_Argument ); if ( glyph_index >= blend->gv_glyphcnt || @@ -2004,7 +2721,7 @@ point_count == 0 ? n_points : point_count ); - if ( points == NULL || deltas_y == NULL || deltas_x == NULL ) + if ( !points || !deltas_y || !deltas_x ) ; /* failure, ignore it */ else if ( points == ALL_POINTS ) @@ -2023,9 +2740,37 @@ FT_Pos delta_y = FT_MulFix( deltas_y[j], apply ); - outline->points[j].x += delta_x; - outline->points[j].y += delta_y; + if ( j < n_points - 3 ) + { + outline->points[j].x += delta_x; + outline->points[j].y += delta_y; + } + else + { + /* To avoid double adjustment of advance width or height, */ + /* adjust phantom points only if there is no HVAR or VVAR */ + /* support, respectively. */ + if ( j == ( n_points - 3 ) && + !( face->variation_support & + TT_FACE_FLAG_VAR_HADVANCE ) ) + outline->points[j].x += delta_x; + else if ( j == ( n_points - 2 ) && + !( face->variation_support & + TT_FACE_FLAG_VAR_LSB ) ) + outline->points[j].x += delta_x; + + else if ( j == ( n_points - 1 ) && + !( face->variation_support & + TT_FACE_FLAG_VAR_VADVANCE ) ) + outline->points[j].y += delta_y; + + else if ( j == ( n_points - 0 ) && + !( face->variation_support & + TT_FACE_FLAG_VAR_TSB ) ) + outline->points[j].y += delta_y; + } + #ifdef FT_DEBUG_LEVEL_TRACE if ( delta_x || delta_y ) { @@ -2146,6 +2891,45 @@ /*************************************************************************/ /* */ /* */ + /* tt_get_var_blend */ + /* */ + /* */ + /* An extended internal version of `TT_Get_MM_Blend' that returns */ + /* pointers instead of copying data, without any initialization of */ + /* the MM machinery in case it isn't loaded yet. */ + /* */ + FT_LOCAL_DEF( FT_Error ) + tt_get_var_blend( TT_Face face, + FT_UInt *num_coords, + FT_Fixed* *coords, + FT_MM_Var* *mm_var ) + { + if ( face->blend ) + { + if ( num_coords ) + *num_coords = face->blend->num_axis; + if ( coords ) + *coords = face->blend->normalizedcoords; + if ( mm_var ) + *mm_var = face->blend->mmvar; + } + else + { + if ( num_coords ) + *num_coords = 0; + if ( coords ) + *coords = NULL; + if ( mm_var ) + *mm_var = NULL; + } + + return FT_Err_Ok; + } + + + /*************************************************************************/ + /* */ + /* */ /* tt_done_blend */ /* */ /* */ @@ -2152,24 +2936,54 @@ /* Free the blend internal data structure. */ /* */ FT_LOCAL_DEF( void ) - tt_done_blend( FT_Memory memory, - GX_Blend blend ) + tt_done_blend( TT_Face face ) { - if ( blend != NULL ) + FT_Memory memory = FT_FACE_MEMORY( face ); + GX_Blend blend = face->blend; + + + if ( blend ) { - FT_UInt i; + FT_UInt i, num_axes; + /* blend->num_axis might not be set up yet */ + num_axes = blend->mmvar->num_axis; + FT_FREE( blend->normalizedcoords ); FT_FREE( blend->mmvar ); - if ( blend->avar_segment != NULL ) + if ( blend->avar_segment ) { - for ( i = 0; i < blend->num_axis; i++ ) + for ( i = 0; i < num_axes; i++ ) FT_FREE( blend->avar_segment[i].correspondence ); FT_FREE( blend->avar_segment ); } + if ( blend->hvar_table ) + { + if ( blend->hvar_table->itemStore.varData ) + { + for ( i = 0; i < blend->hvar_table->itemStore.dataCount; i++ ) + { + FT_FREE( blend->hvar_table->itemStore.varData[i].regionIndices ); + FT_FREE( blend->hvar_table->itemStore.varData[i].deltaSet ); + } + FT_FREE( blend->hvar_table->itemStore.varData ); + } + + if ( blend->hvar_table->itemStore.varRegionList ) + { + for ( i = 0; i < blend->hvar_table->itemStore.regionCount; i++ ) + FT_FREE( blend->hvar_table->itemStore.varRegionList[i].axisList ); + FT_FREE( blend->hvar_table->itemStore.varRegionList ); + } + + FT_FREE( blend->hvar_table->widthMap.innerIndex ); + FT_FREE( blend->hvar_table->widthMap.outerIndex ); + FT_FREE( blend->hvar_table ); + } + FT_FREE( blend->tuplecoords ); FT_FREE( blend->glyphoffsets ); FT_FREE( blend ); Index: reactos/sdk/lib/3rdparty/freetype/src/truetype/ttgxvar.h =================================================================== --- reactos/sdk/lib/3rdparty/freetype/src/truetype/ttgxvar.h (revision 74184) +++ reactos/sdk/lib/3rdparty/freetype/src/truetype/ttgxvar.h (working copy) @@ -61,9 +61,80 @@ } GX_AVarSegmentRec, *GX_AVarSegment; + typedef struct GX_HVarDataRec_ + { + FT_UInt itemCount; /* number of delta sets per item */ + FT_UInt regionIdxCount; /* number of region indices in this data */ + FT_UInt* regionIndices; /* array of `regionCount' indices; */ + /* these index `varRegionList' */ + FT_Short* deltaSet; /* array of `itemCount' deltas */ + /* use `innerIndex' for this array */ + + } GX_HVarDataRec, *GX_HVarData; + + + /* contribution of one axis to a region */ + typedef struct GX_AxisCoordsRec_ + { + FT_Fixed startCoord; + FT_Fixed peakCoord; /* zero means no effect (factor = 1) */ + FT_Fixed endCoord; + + } GX_AxisCoordsRec, *GX_AxisCoords; + + + typedef struct GX_HVarRegionRec_ + { + GX_AxisCoords axisList; /* array of axisCount records */ + + } GX_HVarRegionRec, *GX_HVarRegion; + + + /* HVAR item variation store */ + typedef struct GX_HVStoreRec_ + { + FT_UInt dataCount; + GX_HVarData varData; /* array of dataCount records; */ + /* use `outerIndex' for this array */ + FT_UShort axisCount; + FT_UInt regionCount; /* total number of regions defined */ + GX_HVarRegion varRegionList; + + } GX_HVStoreRec, *GX_HVStore; + + + typedef struct GX_WidthMapRec_ + { + FT_UInt mapCount; + FT_UInt* outerIndex; /* indices to item var data */ + FT_UInt* innerIndex; /* indices to delta set */ + + } GX_WidthMapRec, *GX_WidthMap; + + /*************************************************************************/ /* */ /* */ + /* GX_HVarTableRec */ + /* */ + /* */ + /* Data from the `HVAR' table. */ + /* */ + typedef struct GX_HVarTableRec_ + { + GX_HVStoreRec itemStore; /* Item Variation Store */ + GX_WidthMapRec widthMap; /* Advance Width Mapping */ +#if 0 + GX_LSBMap LsbMap; /* not implemented */ + GX_RSBMap RsbMap; /* not implemented */ +#endif + + } GX_HVarTableRec, *GX_HVarTable; + + + /*************************************************************************/ + /* */ + /* */ /* GX_BlendRec */ /* */ /* */ @@ -89,6 +160,11 @@ FT_Bool avar_checked; GX_AVarSegment avar_segment; + FT_Bool hvar_loaded; + FT_Bool hvar_checked; + FT_Error hvar_error; + GX_HVarTable hvar_table; + FT_UInt tuplecount; /* shared tuples in `gvar' */ FT_Fixed* tuplecoords; /* tuplecoords[tuplecount][num_axis] */ @@ -149,6 +225,11 @@ FT_Fixed* coords ); FT_LOCAL( FT_Error ) + TT_Get_MM_Blend( TT_Face face, + FT_UInt num_coords, + FT_Fixed* coords ); + + FT_LOCAL( FT_Error ) TT_Set_Var_Design( TT_Face face, FT_UInt num_coords, FT_Fixed* coords ); @@ -157,6 +238,10 @@ TT_Get_MM_Var( TT_Face face, FT_MM_Var* *master ); + FT_LOCAL( FT_Error ) + TT_Get_Var_Design( TT_Face face, + FT_UInt num_coords, + FT_Fixed* coords ); FT_LOCAL( FT_Error ) tt_face_vary_cvt( TT_Face face, @@ -169,10 +254,19 @@ FT_Outline* outline, FT_UInt n_points ); + FT_LOCAL( FT_Error ) + tt_hadvance_adjust( TT_Face face, + FT_UInt gindex, + FT_Int *adelta ); + FT_LOCAL( FT_Error ) + tt_get_var_blend( TT_Face face, + FT_UInt *num_coords, + FT_Fixed* *coords, + FT_MM_Var* *mm_var ); + FT_LOCAL( void ) - tt_done_blend( FT_Memory memory, - GX_Blend blend ); + tt_done_blend( TT_Face face ); FT_END_HEADER Index: reactos/sdk/lib/3rdparty/freetype/src/truetype/ttinterp.c =================================================================== --- reactos/sdk/lib/3rdparty/freetype/src/truetype/ttinterp.c (revision 74184) +++ reactos/sdk/lib/3rdparty/freetype/src/truetype/ttinterp.c (working copy) @@ -129,7 +129,7 @@ coderange = &exec->codeRangeTable[range - 1]; - FT_ASSERT( coderange->base != NULL ); + FT_ASSERT( coderange->base ); /* NOTE: Because the last instruction of a program may be a CALL */ /* which will return to the first byte *after* the code */ @@ -423,7 +423,7 @@ /* In case of multi-threading it can happen that the old size object */ /* no longer exists, thus we must clear all glyph zone references. */ - ft_memset( &exec->zp0, 0, sizeof ( exec->zp0 ) ); + FT_ZERO( &exec->zp0 ); exec->zp1 = exec->zp0; exec->zp2 = exec->zp0; } @@ -1613,7 +1613,7 @@ range = &exc->codeRangeTable[aRange - 1]; - if ( range->base == NULL ) /* invalid coderange */ + if ( !range->base ) /* invalid coderange */ { exc->error = FT_THROW( Invalid_CodeRange ); return FAILURE; @@ -3388,13 +3388,27 @@ FT_Long* args ) { if ( args[0] == 0 && exc->args == 0 ) + { exc->error = FT_THROW( Bad_Argument ); + return; + } + exc->IP += args[0]; if ( exc->IP < 0 || ( exc->callTop > 0 && exc->IP > exc->callStack[exc->callTop - 1].Def->end ) ) + { exc->error = FT_THROW( Bad_Argument ); + return; + } + exc->step_ins = FALSE; + + if ( args[0] < 0 ) + { + if ( ++exc->neg_jump_counter > exc->neg_jump_counter_max ) + exc->error = FT_THROW( Execution_Too_Long ); + } } @@ -3949,6 +3963,10 @@ Ins_Goto_CodeRange( exc, def->range, def->start ); exc->step_ins = FALSE; + + exc->loopcall_counter += (FT_ULong)args[0]; + if ( exc->loopcall_counter > exc->loopcall_counter_max ) + exc->error = FT_THROW( Execution_Too_Long ); } return; @@ -5155,7 +5173,7 @@ /* */ /* SCANTYPE[]: SCAN TYPE */ /* Opcode range: 0x8D */ - /* Stack: uint32? --> */ + /* Stack: uint16 --> */ /* */ static void Ins_SCANTYPE( TT_ExecContext exc, @@ -5162,7 +5180,7 @@ FT_Long* args ) { if ( args[0] >= 0 ) - exc->GS.scan_type = (FT_Int)args[0]; + exc->GS.scan_type = (FT_Int)args[0] & 0xFFFF; } @@ -5559,9 +5577,9 @@ FT_Int B1, B2; #endif #ifdef TT_SUPPORT_SUBPIXEL_HINTING_MINIMAL - FT_Bool in_twilight = exc->GS.gep0 == 0 || \ - exc->GS.gep1 == 0 || \ - exc->GS.gep2 == 0; + FT_Bool in_twilight = FT_BOOL( exc->GS.gep0 == 0 || + exc->GS.gep1 == 0 || + exc->GS.gep2 == 0 ); #endif @@ -6519,7 +6537,9 @@ * Otherwise, by definition, the value of exc->twilight.orus[n] is (0,0), * for every n. */ - twilight = exc->GS.gep0 == 0 || exc->GS.gep1 == 0 || exc->GS.gep2 == 0; + twilight = ( exc->GS.gep0 == 0 || + exc->GS.gep1 == 0 || + exc->GS.gep2 == 0 ); if ( BOUNDS( exc->GS.rp1, exc->zp0.n_points ) ) { @@ -6567,7 +6587,7 @@ cur_range = PROJECT( &exc->zp1.cur[exc->GS.rp2], cur_base ); } - for ( ; exc->GS.loop > 0; --exc->GS.loop ) + for ( ; exc->GS.loop > 0; exc->GS.loop-- ) { FT_UInt point = (FT_UInt)exc->stack[--exc->args]; FT_F26Dot6 org_dist, cur_dist, new_dist; @@ -7532,7 +7552,8 @@ FT_EXPORT_DEF( FT_Error ) TT_RunIns( TT_ExecContext exc ) { - FT_Long ins_counter = 0; /* executed instructions counter */ + FT_ULong ins_counter = 0; /* executed instructions counter */ + FT_ULong num_twilight_points; FT_UShort i; #ifdef TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY @@ -7568,6 +7589,44 @@ exc->iupy_called = FALSE; #endif + /* We restrict the number of twilight points to a reasonable, */ + /* heuristic value to avoid slow execution of malformed bytecode. */ + num_twilight_points = FT_MAX( 30, + 2 * ( exc->pts.n_points + exc->cvtSize ) ); + if ( exc->twilight.n_points > num_twilight_points ) + { + if ( num_twilight_points > 0xFFFFU ) + num_twilight_points = 0xFFFFU; + + FT_TRACE5(( "TT_RunIns: Resetting number of twilight points\n" + " from %d to the more reasonable value %d\n", + exc->twilight.n_points, + num_twilight_points )); + exc->twilight.n_points = (FT_UShort)num_twilight_points; + } + + /* Set up loop detectors. We restrict the number of LOOPCALL loops */ + /* and the number of JMPR, JROT, and JROF calls with a negative */ + /* argument to values that depend on the size of the CVT table and */ + /* the number of points in the current glyph (if applicable). */ + /* */ + /* The idea is that in real-world bytecode you either iterate over */ + /* all CVT entries, or over all points (or contours) of a glyph, and */ + /* such iterations don't happen very often. */ + exc->loopcall_counter = 0; + exc->neg_jump_counter = 0; + + /* The maximum values are heuristic. */ + exc->loopcall_counter_max = FT_MAX( 100, + 10 * ( exc->pts.n_points + + exc->cvtSize ) ); + FT_TRACE5(( "TT_RunIns: Limiting total number of loops in LOOPCALL" + " to %d\n", exc->loopcall_counter_max )); + + exc->neg_jump_counter_max = exc->loopcall_counter_max; + FT_TRACE5(( "TT_RunIns: Limiting total number of backward jumps" + " to %d\n", exc->neg_jump_counter_max )); + /* set PPEM and CVT functions */ exc->tt_metrics.ratio = 0; if ( exc->metrics.x_ppem != exc->metrics.y_ppem ) @@ -8328,6 +8387,7 @@ } while ( !exc->instruction_trap ); LNo_Error_: + FT_TRACE4(( " %d instructions executed\n", ins_counter )); return FT_Err_Ok; LErrorCodeOverflow_: Index: reactos/sdk/lib/3rdparty/freetype/src/truetype/ttinterp.h =================================================================== --- reactos/sdk/lib/3rdparty/freetype/src/truetype/ttinterp.h (revision 74184) +++ reactos/sdk/lib/3rdparty/freetype/src/truetype/ttinterp.h (working copy) @@ -408,6 +408,14 @@ #endif /* TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY */ + /* We maintain two counters (in addition to the instruction counter) */ + /* that act as loop detectors for LOOPCALL and jump opcodes with */ + /* negative arguments. */ + FT_ULong loopcall_counter; + FT_ULong loopcall_counter_max; + FT_ULong neg_jump_counter; + FT_ULong neg_jump_counter_max; + } TT_ExecContextRec; Index: reactos/sdk/lib/3rdparty/freetype/src/truetype/ttobjs.c =================================================================== --- reactos/sdk/lib/3rdparty/freetype/src/truetype/ttobjs.c (revision 74184) +++ reactos/sdk/lib/3rdparty/freetype/src/truetype/ttobjs.c (working copy) @@ -117,7 +117,7 @@ FT_Error error; - FT_MEM_ZERO( zone, sizeof ( *zone ) ); + FT_ZERO( zone ); zone->memory = memory; if ( FT_NEW_ARRAY( zone->org, maxPoints ) || @@ -577,58 +577,50 @@ if ( FT_IS_SCALABLE( ttface ) ) { - #ifdef FT_CONFIG_OPTION_INCREMENTAL - if ( !ttface->internal->incremental_interface ) +#endif + { error = tt_face_load_loca( face, stream ); - if ( !error ) - error = tt_face_load_cvt( face, stream ); - if ( !error ) - error = tt_face_load_fpgm( face, stream ); - if ( !error ) - error = tt_face_load_prep( face, stream ); - /* Check the scalable flag based on `loca'. */ - if ( !ttface->internal->incremental_interface && - ttface->num_fixed_sizes && - face->glyph_locations && - tt_check_single_notdef( ttface ) ) - { - FT_TRACE5(( "tt_face_init:" - " Only the `.notdef' glyph has an outline.\n" - " " - " Resetting scalable flag to FALSE.\n" )); - - ttface->face_flags &= ~FT_FACE_FLAG_SCALABLE; + /* having a (non-zero) `glyf' table without */ + /* a `loca' table is not valid */ + if ( face->glyf_len && FT_ERR_EQ( error, Table_Missing ) ) + goto Exit; + if ( error ) + goto Exit; } -#else /* !FT_CONFIG_OPTION_INCREMENTAL */ + /* `fpgm', `cvt', and `prep' are optional */ + error = tt_face_load_cvt( face, stream ); + if ( error && FT_ERR_NEQ( error, Table_Missing ) ) + goto Exit; - if ( !error ) - error = tt_face_load_loca( face, stream ); - if ( !error ) - error = tt_face_load_cvt( face, stream ); - if ( !error ) - error = tt_face_load_fpgm( face, stream ); - if ( !error ) - error = tt_face_load_prep( face, stream ); + error = tt_face_load_fpgm( face, stream ); + if ( error && FT_ERR_NEQ( error, Table_Missing ) ) + goto Exit; + error = tt_face_load_prep( face, stream ); + if ( error && FT_ERR_NEQ( error, Table_Missing ) ) + goto Exit; + /* Check the scalable flag based on `loca'. */ - if ( ttface->num_fixed_sizes && - face->glyph_locations && - tt_check_single_notdef( ttface ) ) +#ifdef FT_CONFIG_OPTION_INCREMENTAL + if ( !ttface->internal->incremental_interface ) +#endif { - FT_TRACE5(( "tt_face_init:" - " Only the `.notdef' glyph has an outline.\n" - " " - " Resetting scalable flag to FALSE.\n" )); + if ( ttface->num_fixed_sizes && + face->glyph_locations && + tt_check_single_notdef( ttface ) ) + { + FT_TRACE5(( "tt_face_init:" + " Only the `.notdef' glyph has an outline.\n" + " " + " Resetting scalable flag to FALSE.\n" )); - ttface->face_flags &= ~FT_FACE_FLAG_SCALABLE; + ttface->face_flags &= ~FT_FACE_FLAG_SCALABLE; + } } - -#endif /* !FT_CONFIG_OPTION_INCREMENTAL */ - } #ifdef TT_CONFIG_OPTION_GX_VAR_SUPPORT @@ -739,7 +731,7 @@ face->cvt_program_size = 0; #ifdef TT_CONFIG_OPTION_GX_VAR_SUPPORT - tt_done_blend( memory, face->blend ); + tt_done_blend( face ); face->blend = NULL; #endif } Index: reactos/sdk/lib/3rdparty/freetype/src/truetype/ttpic.h =================================================================== --- reactos/sdk/lib/3rdparty/freetype/src/truetype/ttpic.h (revision 74184) +++ reactos/sdk/lib/3rdparty/freetype/src/truetype/ttpic.h (working copy) @@ -25,15 +25,17 @@ #ifndef FT_CONFIG_OPTION_PIC -#define TT_SERVICES_GET tt_services -#define TT_SERVICE_GX_MULTI_MASTERS_GET tt_service_gx_multi_masters -#define TT_SERVICE_TRUETYPE_GLYF_GET tt_service_truetype_glyf -#define TT_SERVICE_PROPERTIES_GET tt_service_properties +#define TT_SERVICES_GET tt_services +#define TT_SERVICE_GX_MULTI_MASTERS_GET tt_service_gx_multi_masters +#define TT_SERVICE_METRICS_VARIATIONS_GET tt_service_metrics_variations +#define TT_SERVICE_TRUETYPE_GLYF_GET tt_service_truetype_glyf +#define TT_SERVICE_PROPERTIES_GET tt_service_properties #else /* FT_CONFIG_OPTION_PIC */ #include FT_MULTIPLE_MASTERS_H #include FT_SERVICE_MULTIPLE_MASTERS_H +#include FT_SERVICE_METRICS_VARIATIONS_H #include FT_SERVICE_TRUETYPE_GLYF_H #include FT_SERVICE_PROPERTIES_H @@ -42,12 +44,13 @@ typedef struct TTModulePIC_ { - FT_ServiceDescRec* tt_services; + FT_ServiceDescRec* tt_services; #ifdef TT_CONFIG_OPTION_GX_VAR_SUPPORT - FT_Service_MultiMastersRec tt_service_gx_multi_masters; + FT_Service_MultiMastersRec tt_service_gx_multi_masters; + FT_Service_MetricsVariationsRec tt_service_metrics_variations; #endif - FT_Service_TTGlyfRec tt_service_truetype_glyf; - FT_Service_PropertiesRec tt_service_properties; + FT_Service_TTGlyfRec tt_service_truetype_glyf; + FT_Service_PropertiesRec tt_service_properties; } TTModulePIC; @@ -56,6 +59,8 @@ ( (TTModulePIC*)((lib)->pic_container.truetype) ) #define TT_SERVICES_GET \ ( GET_PIC( library )->tt_services ) +#define TT_SERVICE_METRICS_VARIATIONS_GET \ + ( GET_PIC( library )->tt_service_metrics_variations ) #define TT_SERVICE_GX_MULTI_MASTERS_GET \ ( GET_PIC( library )->tt_service_gx_multi_masters ) #define TT_SERVICE_TRUETYPE_GLYF_GET \ Index: reactos/sdk/lib/3rdparty/freetype/src/truetype/ttpload.c =================================================================== --- reactos/sdk/lib/3rdparty/freetype/src/truetype/ttpload.c (revision 74184) +++ reactos/sdk/lib/3rdparty/freetype/src/truetype/ttpload.c (working copy) @@ -73,9 +73,21 @@ /* it is possible that a font doesn't have a glyf table at all */ /* or its size is zero */ if ( FT_ERR_EQ( error, Table_Missing ) ) - face->glyf_len = 0; + { + face->glyf_len = 0; + face->glyf_offset = 0; + } else if ( error ) goto Exit; + else + { +#ifdef FT_CONFIG_OPTION_INCREMENTAL + if ( face->root.internal->incremental_interface ) + face->glyf_offset = 0; + else +#endif + face->glyf_offset = FT_STREAM_POS(); + } FT_TRACE2(( "Locations " )); error = face->goto_table( face, TTAG_loca, stream, &table_len ); @@ -92,8 +104,7 @@ if ( table_len >= 0x40000L ) { FT_TRACE2(( "table too large\n" )); - error = FT_THROW( Invalid_Table ); - goto Exit; + table_len = 0x3FFFFL; } face->num_locations = table_len >> shift; } @@ -104,8 +115,7 @@ if ( table_len >= 0x20000L ) { FT_TRACE2(( "table too large\n" )); - error = FT_THROW( Invalid_Table ); - goto Exit; + table_len = 0x1FFFFL; } face->num_locations = table_len >> shift; } @@ -222,13 +232,13 @@ } } - /* Check broken location data */ + /* Check broken location data. */ if ( pos1 > face->glyf_len ) { FT_TRACE1(( "tt_face_get_location:" - " too large offset=0x%08lx found for gid=0x%04lx,\n" + " too large offset (0x%08lx) found for glyph index %ld,\n" " " - " exceeding the end of glyf table (0x%08lx)\n", + " exceeding the end of `glyf' table (0x%08lx)\n", pos1, gindex, face->glyf_len )); *asize = 0; return 0; @@ -236,12 +246,26 @@ if ( pos2 > face->glyf_len ) { - FT_TRACE1(( "tt_face_get_location:" - " too large offset=0x%08lx found for gid=0x%04lx,\n" - " " - " truncate at the end of glyf table (0x%08lx)\n", - pos2, gindex + 1, face->glyf_len )); - pos2 = face->glyf_len; + /* We try to sanitize the last `loca' entry. */ + if ( gindex == face->num_locations - 1 ) + { + FT_TRACE1(( "tt_face_get_location:" + " too large offset (0x%08lx) found for glyph index %ld,\n" + " " + " truncating at the end of `glyf' table (0x%08lx)\n", + pos2, gindex + 1, face->glyf_len )); + pos2 = face->glyf_len; + } + else + { + FT_TRACE1(( "tt_face_get_location:" + " too large offset (0x%08lx) found for glyph index %ld,\n" + " " + " exceeding the end of `glyf' table (0x%08lx)\n", + pos2, gindex + 1, face->glyf_len )); + *asize = 0; + return 0; + } } /* The `loca' table must be ordered; it refers to the length of */ @@ -500,7 +524,7 @@ { FT_Error error; FT_Memory memory = stream->memory; - FT_UInt version, nn, num_records; + FT_UInt nn, num_records; FT_ULong table_size, record_size; FT_Byte* p; FT_Byte* limit; @@ -517,7 +541,10 @@ p = face->hdmx_table; limit = p + table_size; - version = FT_NEXT_USHORT( p ); + /* Given that `hdmx' tables are losing its importance (for example, */ + /* variation fonts introduced in OpenType 1.8 must not have this */ + /* table) we no longer test for a correct `version' field. */ + p += 2; num_records = FT_NEXT_USHORT( p ); record_size = FT_NEXT_ULONG( p ); @@ -536,10 +563,10 @@ record_size &= 0xFFFFU; /* The limit for `num_records' is a heuristic value. */ - if ( version != 0 || - num_records > 255 || - record_size > 0x10001L || - record_size < 4 ) + if ( num_records > 255 || + ( num_records > 0 && + ( record_size > 0x10001L || + record_size < 4 ) ) ) { error = FT_THROW( Invalid_File_Format ); goto Fail; Index: reactos/sdk/lib/3rdparty/freetype/src/type1/t1afm.c =================================================================== --- reactos/sdk/lib/3rdparty/freetype/src/type1/t1afm.c (revision 74184) +++ reactos/sdk/lib/3rdparty/freetype/src/type1/t1afm.c (working copy) @@ -208,7 +208,7 @@ kp++; } - if ( oldcharmap != NULL ) + if ( oldcharmap ) error = FT_Set_Charmap( t1_face, oldcharmap ); if ( error ) goto Exit; @@ -309,7 +309,7 @@ { t1_face->face_flags |= FT_FACE_FLAG_KERNING; face->afm_data = fi; - fi = NULL; + fi = NULL; } } @@ -316,7 +316,7 @@ FT_FRAME_EXIT(); Exit: - if ( fi != NULL ) + if ( fi ) T1_Done_Metrics( memory, fi ); return error; Index: reactos/sdk/lib/3rdparty/freetype/src/type1/t1driver.c =================================================================== --- reactos/sdk/lib/3rdparty/freetype/src/type1/t1driver.c (revision 74184) +++ reactos/sdk/lib/3rdparty/freetype/src/type1/t1driver.c (working copy) @@ -122,8 +122,13 @@ (FT_Get_MM_Func) T1_Get_Multi_Master, /* get_mm */ (FT_Set_MM_Design_Func) T1_Set_MM_Design, /* set_mm_design */ (FT_Set_MM_Blend_Func) T1_Set_MM_Blend, /* set_mm_blend */ + (FT_Get_MM_Blend_Func) T1_Get_MM_Blend, /* get_mm_blend */ (FT_Get_MM_Var_Func) T1_Get_MM_Var, /* get_mm_var */ - (FT_Set_Var_Design_Func)T1_Set_Var_Design /* set_var_design */ + (FT_Set_Var_Design_Func)T1_Set_Var_Design, /* set_var_design */ + (FT_Get_Var_Design_Func)T1_Get_Var_Design, /* get_var_design */ + + (FT_Get_Var_Blend_Func) NULL, /* get_var_blend */ + (FT_Done_Blend_Func) T1_Done_Blend /* done_blend */ }; #endif @@ -714,7 +719,7 @@ 0x10000L, 0x20000L, - 0, /* module-specific interface */ + NULL, /* module-specific interface */ T1_Driver_Init, /* FT_Module_Constructor module_init */ T1_Driver_Done, /* FT_Module_Destructor module_done */ @@ -735,8 +740,8 @@ T1_Load_Glyph, /* FT_Slot_LoadFunc load_glyph */ #ifdef T1_CONFIG_OPTION_NO_AFM - 0, /* FT_Face_GetKerningFunc get_kerning */ - 0, /* FT_Face_AttachFunc attach_file */ + NULL, /* FT_Face_GetKerningFunc get_kerning */ + NULL, /* FT_Face_AttachFunc attach_file */ #else Get_Kerning, /* FT_Face_GetKerningFunc get_kerning */ T1_Read_Metrics, /* FT_Face_AttachFunc attach_file */ @@ -744,7 +749,7 @@ T1_Get_Advances, /* FT_Face_GetAdvancesFunc get_advances */ T1_Size_Request, /* FT_Size_RequestFunc request_size */ - 0 /* FT_Size_SelectFunc select_size */ + NULL /* FT_Size_SelectFunc select_size */ }; Index: reactos/sdk/lib/3rdparty/freetype/src/type1/t1load.c =================================================================== --- reactos/sdk/lib/3rdparty/freetype/src/type1/t1load.c (revision 74184) +++ reactos/sdk/lib/3rdparty/freetype/src/type1/t1load.c (working copy) @@ -237,7 +237,7 @@ if ( ncv <= axismap->blend_points[0] ) return INT_TO_FIXED( axismap->design_points[0] ); - for ( j = 1; j < axismap->num_points; ++j ) + for ( j = 1; j < axismap->num_points; j++ ) { if ( ncv <= axismap->blend_points[j] ) return INT_TO_FIXED( axismap->design_points[j - 1] ) + @@ -326,7 +326,7 @@ /* Point to axes after MM_Var struct */ mmvar->namedstyle = NULL; - for ( i = 0; i < mmaster.num_axis; ++i ) + for ( i = 0; i < mmaster.num_axis; i++ ) { mmvar->axis[i].name = mmaster.axis[i].name; mmvar->axis[i].minimum = INT_TO_FIXED( mmaster.axis[i].minimum); @@ -354,7 +354,7 @@ axiscoords, blend->num_axis ); - for ( i = 0; i < mmaster.num_axis; ++i ) + for ( i = 0; i < mmaster.num_axis; i++ ) mmvar->axis[i].def = mm_axis_unmap( &blend->design_map[i], axiscoords[i] ); } @@ -413,6 +413,41 @@ FT_LOCAL_DEF( FT_Error ) + T1_Get_MM_Blend( T1_Face face, + FT_UInt num_coords, + FT_Fixed* coords ) + { + PS_Blend blend = face->blend; + + FT_Fixed axiscoords[4]; + FT_UInt i, nc; + + + if ( !blend ) + return FT_THROW( Invalid_Argument ); + + mm_weights_unmap( blend->weight_vector, + axiscoords, + blend->num_axis ); + + nc = num_coords; + if ( num_coords > blend->num_axis ) + { + FT_TRACE2(( "T1_Get_MM_Blend: only using first %d of %d coordinates\n", + blend->num_axis, num_coords )); + nc = blend->num_axis; + } + + for ( i = 0; i < nc; i++ ) + coords[i] = axiscoords[i]; + for ( ; i < num_coords; i++ ) + coords[i] = 0x8000; + + return FT_Err_Ok; + } + + + FT_LOCAL_DEF( FT_Error ) T1_Set_MM_Design( T1_Face face, FT_UInt num_coords, FT_Long* coords ) @@ -504,7 +539,7 @@ if ( num_coords > T1_MAX_MM_AXIS ) num_coords = T1_MAX_MM_AXIS; - for ( i = 0; i < num_coords; ++i ) + for ( i = 0; i < num_coords; i++ ) lcoords[i] = FIXED_TO_INT( coords[i] ); return T1_Set_MM_Design( face, num_coords, lcoords ); @@ -511,6 +546,42 @@ } + FT_LOCAL_DEF( FT_Error ) + T1_Get_Var_Design( T1_Face face, + FT_UInt num_coords, + FT_Fixed* coords ) + { + PS_Blend blend = face->blend; + + FT_Fixed axiscoords[4]; + FT_UInt i, nc; + + + if ( !blend ) + return FT_THROW( Invalid_Argument ); + + mm_weights_unmap( blend->weight_vector, + axiscoords, + blend->num_axis ); + + nc = num_coords; + if ( num_coords > blend->num_axis ) + { + FT_TRACE2(( "T1_Get_Var_Design:" + " only using first %d of %d coordinates\n", + blend->num_axis, num_coords )); + nc = blend->num_axis; + } + + for ( i = 0; i < nc; i++ ) + coords[i] = mm_axis_unmap( &blend->design_map[i], axiscoords[i] ); + for ( ; i < num_coords; i++ ) + coords[i] = 0; + + return FT_Err_Ok; + } + + FT_LOCAL_DEF( void ) T1_Done_Blend( T1_Face face ) { @@ -1406,7 +1477,6 @@ FT_Error error; FT_Int num_subrs; FT_UInt count; - FT_Hash hash = NULL; PSAux_Service psaux = (PSAux_Service)face->psaux; @@ -1433,7 +1503,7 @@ } /* we certainly need more than 8 bytes per subroutine */ - if ( parser->root.limit > parser->root.cursor && + if ( parser->root.limit >= parser->root.cursor && num_subrs > ( parser->root.limit - parser->root.cursor ) >> 3 ) { /* @@ -1457,14 +1527,12 @@ ( parser->root.limit - parser->root.cursor ) >> 3 )); num_subrs = ( parser->root.limit - parser->root.cursor ) >> 3; - if ( !hash ) + if ( !loader->subrs_hash ) { - if ( FT_NEW( hash ) ) + if ( FT_NEW( loader->subrs_hash ) ) goto Fail; - loader->subrs_hash = hash; - - error = ft_hash_num_init( hash, memory ); + error = ft_hash_num_init( loader->subrs_hash, memory ); if ( error ) goto Fail; } @@ -1527,9 +1595,9 @@ /* if we use a hash, the subrs index is the key, and a running */ /* counter specified for `T1_Add_Table' acts as the value */ - if ( hash ) + if ( loader->subrs_hash ) { - ft_hash_num_insert( idx, count, hash, memory ); + ft_hash_num_insert( idx, count, loader->subrs_hash, memory ); idx = count; } @@ -2110,7 +2178,7 @@ parser->root.error = t1_load_keyword( face, loader, keyword ); - if ( parser->root.error != FT_Err_Ok ) + if ( parser->root.error ) { if ( FT_ERR_EQ( parser->root.error, Ignore ) ) parser->root.error = FT_Err_Ok; @@ -2149,7 +2217,7 @@ { FT_UNUSED( face ); - FT_MEM_ZERO( loader, sizeof ( *loader ) ); + FT_ZERO( loader ); } Index: reactos/sdk/lib/3rdparty/freetype/src/type1/t1load.h =================================================================== --- reactos/sdk/lib/3rdparty/freetype/src/type1/t1load.h (revision 74184) +++ reactos/sdk/lib/3rdparty/freetype/src/type1/t1load.h (working copy) @@ -70,7 +70,7 @@ T1_Get_Multi_Master( T1_Face face, FT_Multi_Master* master ); - FT_LOCAL_DEF( FT_Error ) + FT_LOCAL( FT_Error ) T1_Get_MM_Var( T1_Face face, FT_MM_Var* *master ); @@ -80,11 +80,21 @@ FT_Fixed* coords ); FT_LOCAL( FT_Error ) + T1_Get_MM_Blend( T1_Face face, + FT_UInt num_coords, + FT_Fixed* coords ); + + FT_LOCAL( FT_Error ) T1_Set_MM_Design( T1_Face face, FT_UInt num_coords, FT_Long* coords ); - FT_LOCAL_DEF( FT_Error ) + FT_LOCAL( FT_Error ) + T1_Get_Var_Design( T1_Face face, + FT_UInt num_coords, + FT_Fixed* coords ); + + FT_LOCAL( FT_Error ) T1_Set_Var_Design( T1_Face face, FT_UInt num_coords, FT_Fixed* coords ); Index: reactos/sdk/lib/3rdparty/freetype/src/type1/t1parse.c =================================================================== --- reactos/sdk/lib/3rdparty/freetype/src/type1/t1parse.c (revision 74184) +++ reactos/sdk/lib/3rdparty/freetype/src/type1/t1parse.c (working copy) @@ -437,7 +437,7 @@ *cur == '\t' || (test_cr && *cur == '\r' ) || *cur == '\n' ) ) - ++cur; + cur++; if ( cur >= limit ) { FT_ERROR(( "T1_Get_Private_Dict:" Index: reactos/sdk/lib/3rdparty/freetype/src/type42/t42drivr.c =================================================================== --- reactos/sdk/lib/3rdparty/freetype/src/type42/t42drivr.c (revision 74184) +++ reactos/sdk/lib/3rdparty/freetype/src/type42/t42drivr.c (working copy) @@ -214,7 +214,7 @@ 0x10000L, 0x20000L, - 0, /* module-specific interface */ + NULL, /* module-specific interface */ T42_Driver_Init, /* FT_Module_Constructor module_init */ T42_Driver_Done, /* FT_Module_Destructor module_done */ @@ -234,9 +234,9 @@ T42_GlyphSlot_Load, /* FT_Slot_LoadFunc load_glyph */ - 0, /* FT_Face_GetKerningFunc get_kerning */ - 0, /* FT_Face_AttachFunc attach_file */ - 0, /* FT_Face_GetAdvancesFunc get_advances */ + NULL, /* FT_Face_GetKerningFunc get_kerning */ + NULL, /* FT_Face_AttachFunc attach_file */ + NULL, /* FT_Face_GetAdvancesFunc get_advances */ T42_Size_Request, /* FT_Size_RequestFunc request_size */ T42_Size_Select /* FT_Size_SelectFunc select_size */ Index: reactos/sdk/lib/3rdparty/freetype/src/type42/t42objs.c =================================================================== --- reactos/sdk/lib/3rdparty/freetype/src/type42/t42objs.c (revision 74184) +++ reactos/sdk/lib/3rdparty/freetype/src/type42/t42objs.c (working copy) @@ -590,7 +590,7 @@ FT_Error error = FT_Err_Ok; - if ( face->glyph == NULL ) + if ( !face->glyph ) { /* First glyph slot for this face */ slot->ttslot = t42face->ttf_face->glyph; Index: reactos/sdk/lib/3rdparty/freetype/src/type42/t42parse.c =================================================================== --- reactos/sdk/lib/3rdparty/freetype/src/type42/t42parse.c (revision 74184) +++ reactos/sdk/lib/3rdparty/freetype/src/type42/t42parse.c (working copy) @@ -936,7 +936,7 @@ if ( *cur == '/' || *cur == '(' ) { FT_UInt len; - FT_Bool have_literal = ( *cur == '(' ); + FT_Bool have_literal = FT_BOOL( *cur == '(' ); if ( cur + ( have_literal ? 3 : 2 ) >= limit ) @@ -1268,7 +1268,7 @@ { FT_UNUSED( face ); - FT_MEM_ZERO( loader, sizeof ( *loader ) ); + FT_ZERO( loader ); loader->num_glyphs = 0; loader->num_chars = 0; Index: reactos/sdk/lib/3rdparty/freetype/src/winfonts/winfnt.c =================================================================== --- reactos/sdk/lib/3rdparty/freetype/src/winfonts/winfnt.c (revision 74184) +++ reactos/sdk/lib/3rdparty/freetype/src/winfonts/winfnt.c (working copy) @@ -1000,9 +1000,7 @@ FT_ULong offset; FT_Bool new_format; - FT_UNUSED( load_flags ); - if ( !face ) { error = FT_THROW( Invalid_Face_Handle ); @@ -1055,6 +1053,26 @@ goto Exit; } + bitmap->rows = font->header.pixel_height; + bitmap->pixel_mode = FT_PIXEL_MODE_MONO; + + slot->bitmap_left = 0; + slot->bitmap_top = font->header.ascent; + slot->format = FT_GLYPH_FORMAT_BITMAP; + + /* now set up metrics */ + slot->metrics.width = (FT_Pos)( bitmap->width << 6 ); + slot->metrics.height = (FT_Pos)( bitmap->rows << 6 ); + slot->metrics.horiAdvance = (FT_Pos)( bitmap->width << 6 ); + slot->metrics.horiBearingX = 0; + slot->metrics.horiBearingY = slot->bitmap_top << 6; + + ft_synthesize_vertical_metrics( &slot->metrics, + (FT_Pos)( bitmap->rows << 6 ) ); + + if ( load_flags & FT_LOAD_BITMAP_METRICS_ONLY ) + goto Exit; + /* jump to glyph data */ p = font->fnt_frame + /* font->header.bits_offset */ + offset; @@ -1066,10 +1084,7 @@ FT_Byte* write; - bitmap->pitch = (int)pitch; - bitmap->rows = font->header.pixel_height; - bitmap->pixel_mode = FT_PIXEL_MODE_MONO; - + bitmap->pitch = (int)pitch; if ( !pitch || offset + pitch * bitmap->rows > font->header.file_size ) { @@ -1093,23 +1108,10 @@ for ( write = column; p < limit; p++, write += bitmap->pitch ) *write = *p; } + + slot->internal->flags = FT_GLYPH_OWN_BITMAP; } - slot->internal->flags = FT_GLYPH_OWN_BITMAP; - slot->bitmap_left = 0; - slot->bitmap_top = font->header.ascent; - slot->format = FT_GLYPH_FORMAT_BITMAP; - - /* now set up metrics */ - slot->metrics.width = (FT_Pos)( bitmap->width << 6 ); - slot->metrics.height = (FT_Pos)( bitmap->rows << 6 ); - slot->metrics.horiAdvance = (FT_Pos)( bitmap->width << 6 ); - slot->metrics.horiBearingX = 0; - slot->metrics.horiBearingY = slot->bitmap_top << 6; - - ft_synthesize_vertical_metrics( &slot->metrics, - (FT_Pos)( bitmap->rows << 6 ) ); - Exit: return error; } @@ -1170,10 +1172,10 @@ 0x10000L, 0x20000L, - 0, /* module-specific interface */ + NULL, /* module-specific interface */ - 0, /* FT_Module_Constructor module_init */ - 0, /* FT_Module_Destructor module_done */ + NULL, /* FT_Module_Constructor module_init */ + NULL, /* FT_Module_Destructor module_done */ winfnt_get_service /* FT_Module_Requester get_interface */ }, @@ -1183,16 +1185,16 @@ FNT_Face_Init, /* FT_Face_InitFunc init_face */ FNT_Face_Done, /* FT_Face_DoneFunc done_face */ - 0, /* FT_Size_InitFunc init_size */ - 0, /* FT_Size_DoneFunc done_size */ - 0, /* FT_Slot_InitFunc init_slot */ - 0, /* FT_Slot_DoneFunc done_slot */ + NULL, /* FT_Size_InitFunc init_size */ + NULL, /* FT_Size_DoneFunc done_size */ + NULL, /* FT_Slot_InitFunc init_slot */ + NULL, /* FT_Slot_DoneFunc done_slot */ FNT_Load_Glyph, /* FT_Slot_LoadFunc load_glyph */ - 0, /* FT_Face_GetKerningFunc get_kerning */ - 0, /* FT_Face_AttachFunc attach_file */ - 0, /* FT_Face_GetAdvancesFunc get_advances */ + NULL, /* FT_Face_GetKerningFunc get_kerning */ + NULL, /* FT_Face_AttachFunc attach_file */ + NULL, /* FT_Face_GetAdvancesFunc get_advances */ FNT_Size_Request, /* FT_Size_RequestFunc request_size */ FNT_Size_Select /* FT_Size_SelectFunc select_size */