diff --git a/CMakeLists.txt b/CMakeLists.txt index a4e583d..df77d96 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -16,11 +16,16 @@ # # cmake CMakeLists.txt # -# to create a Makefile that builds a static version of the library. For a -# dynamic library, use +# to create a Makefile that builds a static version of the library. +# +# For a dynamic library, use # # cmake CMakeLists.txt -DBUILD_SHARED_LIBS:BOOL=true # +# For a framework on OS X, use +# +# cmake CMakeLists.txt -DBUILD_FRAMEWORK:BOOL=true -G Xcode +# # instead. Please refer to the cmake manual for further options, in # particular, how to modify compilation and linking parameters. # @@ -39,6 +44,14 @@ cmake_minimum_required(VERSION 2.6) project(freetype) +if (BUILD_FRAMEWORK) + if (NOT "${CMAKE_GENERATOR}" STREQUAL "Xcode") + message(FATAL_ERROR "You should use Xcode generator with BUILD_FRAMEWORK enabled") + endif () + set(CMAKE_OSX_ARCHITECTURES "$(ARCHS_STANDARD_32_64_BIT)") + set(BUILD_SHARED_LIBS ON) +endif () + set(VERSION_MAJOR "2") set(VERSION_MINOR "5") set(VERSION_PATCH "3") @@ -51,22 +64,27 @@ add_definitions(-DFT2_BUILD_LIBRARY) include_directories("${PROJECT_SOURCE_DIR}/include") # Create the configuration file -message(STATUS "Creating directory, ${PROJECT_BINARY_DIR}/include.") -file(MAKE_DIRECTORY ${PROJECT_BINARY_DIR}/include) +message(STATUS "Creating directory, ${PROJECT_BINARY_DIR}/include/freetype2.") +file(MAKE_DIRECTORY ${PROJECT_BINARY_DIR}/include/freetype2) # For the auto-generated ftconfig.h file -include_directories("${PROJECT_BINARY_DIR}/include") -message(STATUS "Creating ${PROJECT_BINARY_DIR}/include/ftconfig.h.") +include_directories(BEFORE "${PROJECT_BINARY_DIR}/include/freetype2") +message(STATUS "Creating ${PROJECT_BINARY_DIR}/include/freetype2/ftconfig.h.") execute_process( COMMAND sed -e "s/FT_CONFIG_OPTIONS_H//" -e "s/FT_CONFIG_STANDARD_LIBRARY_H//" -e "s?/undef ?#undef ?" INPUT_FILE ${PROJECT_SOURCE_DIR}/builds/unix/ftconfig.in - OUTPUT_FILE ${PROJECT_BINARY_DIR}/include/ftconfig.h + OUTPUT_FILE ${PROJECT_BINARY_DIR}/include/freetype2/ftconfig.h ) +file(GLOB PUBLIC_HEADERS "include/*.h") +file(GLOB PUBLIC_CONFIG_HEADERS "include/config/*.h") +file(GLOB PRIVATE_HEADERS "include/internal/*.h") + set(BASE_SRCS src/autofit/autofit.c src/base/ftadvanc.c src/base/ftbbox.c + src/base/ftbdf.c src/base/ftbitmap.c src/base/ftcalc.c src/base/ftcid.c @@ -125,7 +143,31 @@ include_directories("src/raster") include_directories("src/psaux") include_directories("src/psnames") -add_library(freetype ${BASE_SRCS}) +if (BUILD_FRAMEWORK) + set(BASE_SRCS + ${BASE_SRCS} + builds/mac/freetype-Info.plist + ) +endif () + +add_library(freetype + ${PUBLIC_HEADERS} + ${PUBLIC_CONFIG_HEADERS} + ${PRIVATE_HEADERS} + ${BASE_SRCS} +) + +if (BUILD_FRAMEWORK) + set_property(SOURCE ${PUBLIC_CONFIG_HEADERS} + PROPERTY MACOSX_PACKAGE_LOCATION Headers/config + ) + set_target_properties(freetype PROPERTIES + FRAMEWORK TRUE + MACOSX_FRAMEWORK_INFO_PLIST builds/mac/freetype-Info.plist + PUBLIC_HEADER "${PUBLIC_HEADERS}" + XCODE_ATTRIBUTE_INSTALL_PATH "@rpath" + ) +endif () # Installations # Note the trailing slash in the argument to the `DIRECTORY' directive @@ -137,6 +179,7 @@ install(TARGETS freetype RUNTIME DESTINATION bin LIBRARY DESTINATION lib ARCHIVE DESTINATION lib + FRAMEWORK DESTINATION Library/Frameworks ) # Packaging diff --git a/ChangeLog b/ChangeLog index ea1eb4a..4e17454 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,703 @@ +2014-10-02 Alexei Podtelezhnikov + + [base] Significant optimization of `ft_div64by32' + + We shift as many bits as we can into the high register, perform + 32-bit division with modulo there, then work through the remaining + bits with long division. This optimization is especially noticeable + for smaller dividends that barely use the high register. + + * src/base/ftcalc.c (ft_div64by32): Updated. + +2014-10-02 Dave Arnold + + [cff] Fix Savannah bug #43271. + + * src/cff/cf2font.c (cf2_computeDarkening): Change overflow + detection to use logarithms and clamp `scaledStem'. + +2014-10-01 Alexei Podtelezhnikov + + * src/base/ftcalc.c: Remove miscellaneous type casts. + +2014-10-01 Alexei Podtelezhnikov + + [base] Use more common `FT_MSB' implementation with masks. + + * src/base/ftcalc.c (FT_MSB): Updated. + +2014-09-30 Alexei Podtelezhnikov + + [base] Clean up. + + * src/base/ftcalc.c (FT_MOVE_SIGN): New macro for frequently used + code. + +2014-09-25 Alexei Podtelezhnikov + + [base] Avoid unnecessary long division. + + This applies to `FT_MulDiv' but not to `FT_DivFix', where overflows or + lack thereof are predicted accurately. + + * src/base/ftcalc.c (ft_div64by32): Improve readability. + (FT_MulDiv, FT_MulDiv_No_Round) [!FT_LONG64]: Use straight division + when multiplication stayed within 32 bits. + +2014-09-24 Werner Lemberg + + [autofit] Minor clean-ups. + + * src/autofit/afhints.c (AF_FLAGS): Remove obsolete values. + + * src/autofit/afhints.c (af_glyph_hints_dump_points, + af_glyph_hints_align_strong_points): Updated. + + * src/autofit/aflatin.c (af_latin_hints_link_segments, + af_latin_hints_compute_segments), src/autofit/afcjk.c + (af_cjk_hints_link_segments), src/autofit/aflatin2.c + (af_latin2_hints_link_segments, af_latin2_hints_compute_segments): + There are no longer fake segments since more than 10 years... + +2014-09-22 Werner Lemberg + + [autofit] Minor code streamlining. + + * src/autofit/afhints.c (af_axis_hints_new_edge): Remove redundant + initialization. + +2014-09-19 Alexei Podtelezhnikov + + * src/base/ftcalc.c: Harmonize code. + +2014-09-15 Alexei Podtelezhnikov + + [base] Tighten the overflow check in `FT_MulDiv'. + + * src/base/ftcalc.c (FT_MulDiv) [!FT_LONG64]: Updated. + +2014-09-08 Alexei Podtelezhnikov + + Fix Savannah bug #43153. + + * src/psaux/psconv.c (PS_Conv_ToFixed): Add protection against + overflow in `divider'. + +2014-09-03 Alexei Podtelezhnikov + + [base] Tighten the overflow check in `FT_DivFix'. + + This fixes a 13-year old bug. The original overflow check should have + been updated when rounding was introduced into this function + (c2cd00443b). + + * src/base/ftcalc.c (FT_DivFix) [!FT_LONG64]: Updated. + * include/freetype.h (FT_DivFix): Updated documentation. + +2014-09-03 Alexei Podtelezhnikov + + [base] Tighten the overflow check in `FT_MulFix'. + + * src/base/ftcalc.c (FT_MulFix) [!FT_LONG64]: Updated. + +2014-09-02 Alexei Podtelezhnikov + + [truetype] Shortcut ppem calculations for square pixels. + + * src/truetype/ttinterp.h (TT_ExecContextRec): New field + `cur_ppem_func' with a function pointer. + * src/truetype/ttinterp.c (TT_RunIns): Initialize `cur_ppem_func' + depending on the pixel geometry to either... + (Current_Ppem_Stretched): ... this for stretched pixels. + (Current_Ppem): ... or this for square pixels. + (DO_MPPEM, DO_MPS, Ins_DELTAP, Ins_DELTAC): Use `cur_ppem_func'. + +2014-08-31 Behdad Esfahbod + + Don't use `register' keyword. Fixes compiler warnings. + + * src/base/ftcalc.c (FT_Add64) [!FT_LONG64]: Do it. + * src/gzip/inftrees.c (huft_build): Ditto. + * src/truetype/ttinterp.c (TT_MulFix14_arm): Ditto. + +2014-08-24 Alexei Podtelezhnikov + + [truetype] Optimize DELTAP and DELTAC. + + * src/truetype/ttinterp.c (Ins_DELTAP, Ins_DELTAC): Move ppem + calculations outside of the loop. + +2014-08-21 Alexei Podtelezhnikov + + Fix Savannah bug #43033. + + * include/config/ftconfig.h, builds/unix/ftconfig.in, + builds/vms/ftconfig.h [FT_LONG64]: Do not disable the macro when + 64-bit type is `long'. + +2014-08-20 Alexei Podtelezhnikov + + [base] Small optimization of `FT_MulFix'. + + * src/base/ftcalc.c (FT_MulFix): Loosen up the condition for direct + 32-bit calculations. + +2014-08-19 Alexei Podtelezhnikov + + [base] Use unsigned calculation in `FT_MulDiv'. + + * src/base/ftcalc.c (FT_MulDiv): Updated to expand 32-bit range. + +2014-08-18 Alexei Podtelezhnikov + + [base] Remove truncation in `FT_DivFix'. + + * src/base/ftcalc.c (FT_DivFix): Updated. + +2014-08-14 Alexei Podtelezhnikov + + Minor refactoring. + + * src/base/ftcalc.c (FT_MulDiv, FT_MulDiv_No_Round): Updated. + +2014-08-14 Alexei Podtelezhnikov + + Turn FT_MSB into a macro when using gcc builtins. + + * src/base/ftcalc.c, include/internal/ftcalc.h: Updated. + +2014-08-12 Alexei Podtelezhnikov + + [base] Avoid undefined FT_MSB in `BBox_Cubic_Check'. + + * src/base/ftbbox.c (BBox_Cubic_Check): Update. + (update_cubic_max): Repalce with... + (cubic_peak): ... this, which now handles upscaling. + +2014-08-11 Alexei Podtelezhnikov + + [base] Handle collapsed outlines to avoid undefined FT_MSB. + + * src/base/ftoutln.c (FT_Outline_Get_Orientation): Update. + +2014-08-11 Alexei Podtelezhnikov + + [base] Restore FT_MulFix inlining. + + * include/freetype.h (FT_MulFix): Unconditionally defined. + + * src/base/ftcalc.c [FT_MULFIX_ASSEMBLER]: Move code from here... + + * include/internal/ftcalc.h [FT_MULFIX_ASSEMBLER]: ... to here, + which conditionally replaces the function with an inline version + through the macro. + +2014-08-08 Alexei Podtelezhnikov + + * src/base/ftbitmap.c (ft_gray_for_premultiplied_srgb_bgra): Refactor. + +2014-07-26 Werner Lemberg + + [cff] Fix typo. + + * src/cff/cf2hints.c (cf2_glyphpath_computeOffset): Use correct + offsets in third quadrant. + + Reported by maks . + +2014-07-17 Werner Lemberg + + Fix Savannah bug #42788. + + * src/pfr/pfrobjs.c: Include `ftcalc.h'. + +2014-07-16 Alexei Podtelezhnikov + + Replace `ft_highpow2' function. + + * src/pfr/pfrobjs.c (pfr_face_get_kerning): Use `FT_MSB' instead of + `ft_highpow2'. + + * src/base/ftutil.c, include/internal/ftobjs.h (ft_highpow2): Remove + it. + +2014-07-15 Alexei Podtelezhnikov + + * src/base/ftcalc.c (FT_MSB): Utilize gcc builtins. + +2014-07-15 Alexei Podtelezhnikov + + [base] Move assembler code back in the source file. + + FT_MulFix assembler used to reside in ftcalc.c before f47d263f1b. + + * include/config/ftconfig.h, builds/unix/ftconfig.in, + builds/vms/ftconfig.h [FT_MULFIX_ASSEMBLER]: Move code from here... + + * src/base/ftcalc.c [FT_MULFIX_ASSEMBLER]: ... to here. + +2014-07-14 Alexei Podtelezhnikov + + [base] Further clean up color bitmap conversion. + + * src/base/ftbitmap.c (ft_gray_for_premultiplied_srgb_bgra): Stop + using FT_MulFix and FT_DivFix since all calculations fit into 32 bits. + +2014-07-13 Werner Lemberg + + [truetype] Improve handling of buggy `prep' tables. + + In case of an error in the `prep' table, no longer try to execute it + again and again. This makes FreeType handle endless loops in buggy + fonts much faster. + + * src/truetype/ttobjs.h (TT_SizeRec): The fields `bytecode_ready' + and `cvt_ready' are now negative if not initialized yet, otherwise + they indicate the error code of the last run. + + * src/truetype/ttobjs.c (tt_size_run_fpgm, tt_size_run_prep, + tt_size_done_bytecode, tt_size_init_bytecode, + tt_size_ready_bytecode, tt_size_init, tt_size_done, tt_size_reset): + Updated. + + * src/truetype/ttgload.c (tt_loader_init): Updated. + * src/truetype/ttinterp.c (TT_RunIns): Force reexecution of `fpgm' + and `prep' only if we are in the `glyf' table. + +2014-07-12 Werner Lemberg + + * builds/vms/ftconfig.h: Synchronize. + Problem reported by Alexei. + +2014-07-11 Alexei Podtelezhnikov + + [base] Clean up bitmap conversion. + + * src/base/ftbitmap.c (ft_gray_for_premultiplied_srgb_bgra): Use + appropriate FT_DivFix and remove superfluous upscaling. + +2014-07-04 Alexei Podtelezhnikov + + [base] Small optimization of the ancient code. + + * src/base/ftcalc.c (FT_MulDiv, FT_MulDiv_No_Round): Loosen up the + condition for direct 32-bit calculations. + +2014-06-27 Werner Lemberg + + Fix Apple standard glyph names. + + * src/sfnt/ttpost.c (tt_post_default_names): Synchronize with + `tools/glnames.py' + + Problem reported by Adam Twardoch . + +2014-06-17 Werner Lemberg + + Partially revert commit from 2014-06-13. + + * src/autofit/aflatin.c (af_latin_metrics_init_blues): Move + declaration of `p_first' and `p_last' out of the loop. + +2014-06-17 Werner Lemberg + + * builds/unix/freetype2.m4: s/AC_PATH_PROG/AC_PATH_TOOL/. + + This simplifies cross-compiling. + +2014-06-13 Werner Lemberg + + Fix more compiler warnings. + Reported by Wojciech Mamrak . + + * src/autofit/afglobal.c (af_face_globals_compute_style_coverage): + Make integer constant unsigned. + + * src/sfnt/ttsbit.c (tt_face_load_strike_metrics) + : Fix types. + (tt_sbit_decoder_load_compound, tt_face_load_sbix_image): Add proper + casts. + +2014-06-13 Werner Lemberg + + Fix compiler warnings. + Reported by Wojciech Mamrak . + + * src/autofit/afglobal.c (af_face_globals_compute_style_coverage), + src/autofit/afmodule.c (af_property_set): Fix `signed' vs. + `unsigned' issues. + + * src/autofit/aflatin.c (af_latin_metrics_init_blues): Make compiler + happy. + + * src/base/ftlcdfil.c (_ft_lcd_filter_fir): Use only four elements + for `fir'. + Fix `signed' vs. `unsigned' issues. + + * src/sfnt/sfobjs.c (WRITE_BYTE): Removed, unused. + (WRITE_USHORT, WRITE_ULONG): Add proper casts. + + * src/truetype/ttgload.c (TT_Get_VMetrics): Add proper casts. + + * src/truetype/ttinterp.c (Ins_DELTAP): Add proper casts for `B1' + and `B2'. + +2014-05-16 Alexey Petruchik + + [cmake] Add option to build OS X framework. + + * CMakeLists.txt: Update accordingly. + + * builds/mac/freetype-Info.plist: New file. + +2014-05-13 Pavel Koshevoy + + * CMakeLists.txt (BASE_SRCS): Add missing `ftbdf.c'. + +2014-05-11 Werner Lemberg + + [autofit] Fix variable initializations. + + * src/autofit/afhints.c (af_glyph_hints_reload): Assign default + values to `in_dir' and `out_dir' for all points. + +2014-05-11 Werner Lemberg + + [autofit] Fix crash with font `CabinSketch-Bold.ttf'. + + Problem reported by Ralf S. Engelschall . + + * src/autofit/afhints.c (af_glyph_hints_reload): Fix threshold for + finding first non-near point. + Properly initialize non-near point deltas. + +2014-05-01 Werner Lemberg + + [autofit] Add blue-zone support for Devanagari. + + This essentially moves the Devanagari script from the `Indic' hinter + to the `Latin' hinter. Thanks to Girish Dalvi + for guidance with blue zone characters! + + * src/autofit/afblue.dat: Add blue zone data for Devanagari. + + * src/autofit/afblue.c, src/autofit/afblue.h: Regenerated. + + * src/autofit/afscript.h: Add Devanagari standard characters and + move data out of AF_CONFIG_OPTION_INDIC block. + + * src/autofit/afranges.c: Move Devanagari data out of + AF_CONFIG_OPTION_INDIC block. + Move U+20B9, (new) Rupee sign, from Latin to Devanagari. + + * src/autofit/afstyles.h: Update Devanagari data; in particular, use + AF_WRITING_SYSTEM_LATIN. + +2014-05-01 Werner Lemberg + + [autofit] Fix handling of neutral blue zones in stems. + + * src/autofit/afhints.h (AF_Edge_Flags): New value + `AF_EDGE_NEUTRAL'. + + * src/autofit/aflatin.c (af_latin_hints_compute_blue_edges): Trace + neutral blue zones with AF_EDGE_NEUTRAL. + (af_latin_hint_edges): Skip neutral blue zones if necessary. + +2014-04-28 Werner Lemberg + + [autofit] Introduce neutral blue zones to the latin module. + + Such blue zones match either the top or the bottom of a contour. We + need them for scripts where accent-like elements directly touch the + base character (for example, some vowel signs in Devanagari, cf. + U+0913 or U+0914). + + * src/autofit/afblue.hin (AF_BLUE_PROPERTY_LATIN_NEUTRAL): New + property. + + * src/autofit/afblue.h: Regenerated. + + * src/autofit/aflatin.h (AF_LATIN_IS_NEUTRAL_BLUE): New macro. + (AF_LATIN_BLUE_NEUTRAL): New enumeration value. + + * src/autofit/aflatin.c (af_latin_metrics_init_blues, + af_latin_hints_compute_blue_edges): Handle neutral blue zones. + +2014-04-25 Werner Lemberg + + * src/autofit/hbshim.c: Partially revert commit from 2014-04-17. + + Using input glyph coverage data is simply wrong. + + Problem reported by Nikolaus Waxweiler and + Mantas Mikulėnas . + +2014-04-23 Werner Lemberg + + * src/raster/ftraster.c (Vertical_Sweep_Span): Use drop-out mode. + + This spot has been missed while introducing support for various + drop-out modes years ago (including no drop-out mode, which this + commit fixes). + + Problem reported by Patrick Thomas . + +2014-04-22 Werner Lemberg + + * src/sfnt/pngshim.c (error_callback): s/longjmp/ft_longjmp/. + +2014-04-20 Werner Lemberg + + [autofit] Fix Savannah bug #42148. + + The adaptation of the cjk auto-hinter module to blue stringsets in + 2013-08-25 had three severe bugs. Mea culpa. + + 1. Contrary to the latin auto-hinter, characters for reference and + overshoot values of a blue zone are specified separately. Due to + the screwed-up change it didn't work at all. + + 2. A boolean comparison was erroneously replaced with a cast, + causing invalid results with the `^' operator later on. The + visual artifact caused by this problem is the topic of the bug + report. + + 3. Two flag values were inverted, causing incorrect assignment of + reference and overshoot values. + + * src/autofit/afblue.dat: Fix CJK bluestrings, introducing a new + syntax to have both reference and overshoot characters in a single + string. This is error #1. + Add extensive comments. + + * src/autofit/afblue.hin (AF_BLUE_PROPERTY_CJK_FILL): Removed, no + longer used. + (AF_BLUE_PROPERTY_CJK_TOP, AF_BLUE_PROPERTY_CJK_HORIZ): Fix values. + This is error #3. + + * src/autofit/afblue.c, src/autofit/afblue.h: Regenerated. + + * src/autofit/afcjk.c (af_cjk_metrics_init_blues): Correct error #1. + Use character `|' to separate characters for reference and overshoot + values. + Improve tracing messages, synchronizing them with the latin + auto-hinter. + (af_cjk_hints_compute_blue_edges): Fix value of `is_top_right_blue'. + This is error #2. + (af_cjk_align_linked_edge): Add tracing message. + + * src/autofit/afcjk.h (AF_CJK_IS_FILLED_BLUE): Removed, no longer + used. + +2014-04-17 Werner Lemberg + + [autofit] More coverage fixes for complex scripts. + + * src/autofit/hbshim.c (af_get_coverage): Merge input glyph coverage + of GSUB lookups into output coverage. Otherwise, ligatures are not + handled properly. + Don't check blue zone characters for default coverage. + +2014-04-17 Werner Lemberg + + Make `FT_Get_SubGlyph_Info' actually work. + + * src/base/ftobjs.c (FT_Get_SubGlyph_Info): Return FT_Err_Ok + if there is no error. + +2014-04-15 Werner Lemberg + + [afblue.pl]: Minor improvements. + + * src/tools/afblue.pl: Allow whitespace before comments. + Ignore whitespace in strings. + +2014-04-14 Werner Lemberg + + [autofit] Improve coverage handling. + + * src/autofit/hbshim.c (af_get_coverage): Don't exclude glyphs + appearing in the GPOS table if we are processing the default + coverage. + +2014-04-13 David Weber + + [smooth] Fix stand-alone compilation. + + * src/smooth/ftgrays.c (FT_BEGIN_STMNT, FT_END_STMNT): Define. + +2014-04-12 Werner Lemberg + + [autofit] Redesign the recognition algorithm of strong points. + + In particular, local extrema without horizontal or vertical segments + are better recognized: + + + A + D + \ / + \ / + \ / + \ / + \ + C + \ / + B +/ + + If the distances AB and CD are large, point B wasn't previously + detected as an extremum since the `ft_corner_is_flat' function + `swallowed' BC regardless of its direction, tagging point B as weak. + The next iteration started at B and made `ft_corner_is_flat' swallow + point C, tagging it as weak also, et voilà. + + To improve that, another pass gets now performed before calling + `ft_corner_is_flat' to improve the `topology' of an outline: A + sequence of non-horizontal or non-vertical vectors that point into + the same quadrant are handled as a single, large vector. + + Additionally, distances of near points are now accumulated, which + makes the auto-hinter handle them as if they were prepended to the + next non-near vector. + + This generally improves the auto-hinter's rendering results. + + * src/autofit/afhints.c (af_glyph_hints_reload): Implement it. + + * src/autofit/afhints.h (AF_FLAGS): Remove no longer used flag + `AF_FLAG_NEAR'. + +2014-04-05 Werner Lemberg + + [autofit] Improve scoring algorithm for identifying stems. + + Problem reported by Karsten Lücke . + + The new algorithm takes care of the width of stems: If the distance + between two segments is larger than the largest stem width, the + demerits quickly increase for larger distances. This improves + hinting of slanted fonts (especially if the inner parts of serifs + have non-horizontal `shoulders'), avoiding false stem links. + + * src/autofit/aflatin.c (af_latin_hints_link_segments): Use largest + stem width (if available) to compute better demerits for distances + between stems. + (af_latin_hints_detect_features): Pass stem width array and array + size. + (af_latin_metrics_init_widths): Updated to use original algorithm. + (af_latin_hints_apply): Updated to use new algorithm. + + * src/autofit/aflatin.h: Updated. + * src/autofit/afcjk.c: Updated. + +2014-04-03 Werner Lemberg + + Don't require `gzip' module for `sfnt'. + + Reported by Preet . + + * src/sfnt/sfobjs.c (woff_open_font): Guard use of + FT_Gzip_Uncompress with FT_CONFIG_OPTION_USE_ZLIB. + +2014-03-27 Werner Lemberg + + Fix Savannah bug #38235. + + Work around a bug in pkg-config version 0.28 and earlier: If a + variable value gets surrounded by doublequotes (in particular values + for the `prefix' variable), the prefix override mechanism fails. + + * builds/unix/freetype2.in: Don't use doublequotes. + * builds/unix/unix-def.in (freetype.pc): Escape spaces in directory + names with backslashes. + +2014-03-24 Werner Lemberg + + Fix Savannah bug #41946. + + Based on a patch from Marek Kašík . + + * builds/unix/configure.raw (LIBS_CONFIG): Remove. + * builds/unix/freetype-config.in (libs): Hard-code value. + * builds/unix/unix-def.in: Updated. + +2014-03-22 Werner Lemberg + + Another revert for the change from 2014-03-18. + + Problem reported by Nikolaus Waxweiler . + + * src/base/ftcalc.c (FT_MulFix): Ensure that an `FT_MulFix' symbol + gets always exported. + +2014-03-20 Werner Lemberg + + CMakeLists.txt: Another fix for include directories. + + Problem reported by Taylor Holberton . + +2014-03-19 Werner Lemberg + + CMakeLists.txt: Fix include directories. + + Problem reported by Taylor Holberton . + +2014-03-19 Werner Lemberg + + Partially revert last commit. + + Found by Alexei. + + * src/autofit/aflatin.c (af_latin_metrics_init_blues): Initializing + those variables is plain wrong, since we are in a loop. + +2014-03-18 Sean McBride + Werner Lemberg + + Fix clang warnings. + + * src/autofit/aflatin.c (af_latin_metrics_init_blues): Initialize + some variables. + + * src/base/ftcalc.c (FT_MulFix): Only use code if + `FT_MULFIX_INLINED' is not defined. + + * src/bdf/bdfdrivr.c (bdf_cmap_class), src/cache/ftcbasic.c + (ftc_basic_image_family_class, ftc_basic_image_cache_class, + ftc_basic_sbit_family_class, ftc_basic_sbit_cache_class), + src/cache/ftccmap.c (ftc_cmap_cache_class), src/cache/ftcmanag.c + (ftc_size_list_class, ftc_face_list_class), src/pcf/pcfdrivr.c + (pcf_cmap_class), src/pfr/pfrdrivr.c (pfr_metrics_service_rec): Make + function static. + + * src/type1/t1driver.c (t1_ps_get_font_value): Remove redundant + code. + +2014-03-17 Werner Lemberg + + Fix Savannah bug #41869. + + This works around a problem with HarfBuzz (<= 0.9.26), which doesn't + validate glyph indices returned by + `hb_ot_layout_lookup_collect_glyphs'. + + * src/autofit/hbshim.c (af_get_coverage): Guard `idx'. + + * docs/CHANGES: Updated. + +2014-03-14 Werner Lemberg + + * builds/unix/configure.raw: Don't show error messages of `which'. + +2014-03-09 Alan Coopersmith + + Fix cppcheck 1.64 warning. + + * src/autofit/afglobal.c (af_face_globals_new): Catch NULL pointer + dereference in case of error. + +2014-03-09 Sean McBride + + * src/sfnt/ttcmap.c (tt_face_build_cmaps): Remove clang warning. + 2014-03-06 Werner Lemberg * Version 2.5.3 released. diff --git a/builds/mac/freetype-Info.plist b/builds/mac/freetype-Info.plist new file mode 100644 index 0000000..b3d114d --- /dev/null +++ b/builds/mac/freetype-Info.plist @@ -0,0 +1,36 @@ + + + + + + + CFBundleDevelopmentRegion + English + + CFBundleExecutable + FreeType + + CFBundleGetInfoString + FreeType ${PROJECT_VERSION} + + CFBundleInfoDictionaryVersion + 6.0 + + CFBundleName + FreeType + + CFBundlePackageType + FMWK + + CFBundleShortVersionString + ${PROJECT_VERSION} + + CFBundleSignature + ???? + + CFBundleVersion + ${PROJECT_VERSION} + + + diff --git a/builds/unix/configure.raw b/builds/unix/configure.raw index dd7e576..8a17ffe 100644 --- a/builds/unix/configure.raw +++ b/builds/unix/configure.raw @@ -437,7 +437,7 @@ if test x"$with_png" = xyes -o x"$with_png" = xauto; then else # fall back to config script. AC_MSG_CHECKING([for libpng-config]) - if which libpng-config > /dev/null; then + if which libpng-config > /dev/null 2>&1; then LIBPNG_CFLAGS=`libpng-config --cflags` LIBPNG_LIBS=`libpng-config --ldflags` libpng_libpriv=`libpng-config --static --ldflags` @@ -656,7 +656,7 @@ else fi -# Whether to use FileManager which is deprecated since Mac OS X 10.4. +# Whether to use FileManager, which is deprecated since Mac OS X 10.4. AC_ARG_WITH([fsspec], AS_HELP_STRING([--with-fsspec], @@ -765,7 +765,7 @@ elif test x$with_old_mac_fonts = xyes -a x$with_fsref != x; then fi -# Whether to use QuickDraw API in ToolBox which is deprecated since +# Whether to use QuickDraw API in ToolBox, which is deprecated since # Mac OS X 10.4. AC_ARG_WITH([quickdraw-toolbox], @@ -807,7 +807,7 @@ elif test x$with_old_mac_fonts = xyes -a x$with_quickdraw_toolbox != x; then fi -# Whether to use QuickDraw API in Carbon which is deprecated since +# Whether to use QuickDraw API in Carbon, which is deprecated since # Mac OS X 10.4. AC_ARG_WITH([quickdraw-carbon], @@ -937,21 +937,6 @@ LIBS_PRIVATE=`echo "$LIBS_PRIVATE" \ -e 's/ *$//' \ -e 's/ */ /g'` -LIBS_CONFIG="-lfreetype \ - $ZLIB_LIBS \ - $BZIP2_LIBS \ - $LIBPNG_LIBS \ - $HARFBUZZ_LIBS \ - $ft2_extra_libs" -# remove -L/usr/lib and -L/usr/lib64 since `freetype-config' adds them later -# on if necessary; also beautify -LIBS_CONFIG=`echo "$LIBS_CONFIG" \ - | sed -e 's|-L */usr/lib64/* | |g' \ - -e 's|-L */usr/lib/* | |g' \ - -e 's/^ *//' \ - -e 's/ *$//' \ - -e 's/ */ /g'` - LIBSSTATIC_CONFIG="-lfreetype \ $zlib_libstaticconf \ $bzip2_libstaticconf \ @@ -971,7 +956,6 @@ LIBSSTATIC_CONFIG=`echo "$LIBSSTATIC_CONFIG" \ AC_SUBST([ftmac_c]) AC_SUBST([REQUIRES_PRIVATE]) AC_SUBST([LIBS_PRIVATE]) -AC_SUBST([LIBS_CONFIG]) AC_SUBST([LIBSSTATIC_CONFIG]) AC_SUBST([hardcode_libdir_flag_spec]) diff --git a/builds/unix/freetype-config.in b/builds/unix/freetype-config.in index 41c3a88..ebc311f 100644 --- a/builds/unix/freetype-config.in +++ b/builds/unix/freetype-config.in @@ -142,7 +142,7 @@ if test "$echo_cflags" = "yes" ; then fi if test "$echo_libs" = "yes" ; then - libs="%LIBS_CONFIG%" + libs="-lfreetype" staticlibs="%LIBSSTATIC_CONFIG%" if test "$show_static" = "yes" ; then libs="$staticlibs" diff --git a/builds/unix/freetype2.in b/builds/unix/freetype2.in index 6e7fb10..a488d96 100644 --- a/builds/unix/freetype2.in +++ b/builds/unix/freetype2.in @@ -1,7 +1,7 @@ -prefix="%prefix%" -exec_prefix="%exec_prefix%" -libdir="%libdir%" -includedir="%includedir%/freetype2" +prefix=%prefix% +exec_prefix=%exec_prefix% +libdir=%libdir% +includedir=%includedir%/freetype2 Name: FreeType 2 URL: http://freetype.org diff --git a/builds/unix/freetype2.m4 b/builds/unix/freetype2.m4 index 3d0ecb3..3a806d9 100644 --- a/builds/unix/freetype2.m4 +++ b/builds/unix/freetype2.m4 @@ -1,7 +1,7 @@ # Configure paths for FreeType2 # Marcelo Magallon 2001-10-26, based on gtk.m4 by Owen Taylor # -# Copyright 2001, 2003, 2007, 2009 by +# Copyright 2001, 2003, 2007, 2009, 2014 by # David Turner, Robert Wilhelm, and Werner Lemberg. # # This file is part of the FreeType project, and may only be used, modified, @@ -15,7 +15,7 @@ # generated by Autoconf, under the same distribution terms as the rest of # that program. # -# serial 3 +# serial 4 # AC_CHECK_FT2([MINIMUM-VERSION [, ACTION-IF-FOUND [, ACTION-IF-NOT-FOUND]]]) # Test for FreeType 2, and define FT2_CFLAGS and FT2_LIBS. @@ -61,7 +61,7 @@ AC_DEFUN([AC_CHECK_FT2], fi if test "x$FT2_CONFIG" = x ; then - AC_PATH_PROG([FT2_CONFIG], [freetype-config], [no]) + AC_PATH_TOOL([FT2_CONFIG], [freetype-config], [no]) fi min_ft_version=m4_if([$1], [], [7.0.1], [$1]) diff --git a/builds/unix/ftconfig.in b/builds/unix/ftconfig.in index 2cf6708..e66f3ea 100644 --- a/builds/unix/ftconfig.in +++ b/builds/unix/ftconfig.in @@ -296,7 +296,16 @@ FT_BEGIN_HEADER #define FT_INT64 long #define FT_UINT64 unsigned long -#elif defined( _MSC_VER ) && _MSC_VER >= 900 /* Visual C++ (and Intel C++) */ + /*************************************************************************/ + /* */ + /* A 64-bit data type may create compilation problems if you compile */ + /* in strict ANSI mode. To avoid them, we disable other 64-bit data */ + /* types if __STDC__ is defined. You can however ignore this rule */ + /* by defining the FT_CONFIG_OPTION_FORCE_INT64 configuration macro. */ + /* */ +#elif !defined( __STDC__ ) || defined( FT_CONFIG_OPTION_FORCE_INT64 ) + +#if defined( _MSC_VER ) && _MSC_VER >= 900 /* Visual C++ (and Intel C++) */ /* this compiler provides the __int64 type */ #define FT_LONG64 @@ -330,30 +339,9 @@ FT_BEGIN_HEADER #define FT_INT64 long long int #define FT_UINT64 unsigned long long int -#endif /* FT_SIZEOF_LONG == 8 */ - - - /*************************************************************************/ - /* */ - /* A 64-bit data type will create compilation problems if you compile */ - /* in strict ANSI mode. To avoid them, we disable its use if __STDC__ */ - /* is defined. You can however ignore this rule by defining the */ - /* FT_CONFIG_OPTION_FORCE_INT64 configuration macro. */ - /* */ -#if defined( FT_LONG64 ) && !defined( FT_CONFIG_OPTION_FORCE_INT64 ) - -#ifdef __STDC__ - - /* Undefine the 64-bit macros in strict ANSI compilation mode. */ - /* Since `#undef' doesn't survive in configuration header files */ - /* we use the postprocessing facility of AC_CONFIG_HEADERS to */ - /* replace the leading `/' with `#'. */ -/undef FT_LONG64 -/undef FT_INT64 - -#endif /* __STDC__ */ +#endif /* _MSC_VER */ -#endif /* FT_LONG64 && !FT_CONFIG_OPTION_FORCE_INT64 */ +#endif /* FT_SIZEOF_LONG == 8 */ #ifdef FT_LONG64 typedef FT_INT64 FT_Int64; @@ -366,219 +354,6 @@ FT_BEGIN_HEADER #define FT_DUMMY_STMNT FT_BEGIN_STMNT FT_END_STMNT -#ifndef FT_CONFIG_OPTION_NO_ASSEMBLER - /* Provide assembler fragments for performance-critical functions. */ - /* These must be defined `static __inline__' with GCC. */ - -#if defined( __CC_ARM ) || defined( __ARMCC__ ) /* RVCT */ - -#define FT_MULFIX_ASSEMBLER FT_MulFix_arm - - /* documentation is in freetype.h */ - - static __inline FT_Int32 - FT_MulFix_arm( FT_Int32 a, - FT_Int32 b ) - { - register FT_Int32 t, t2; - - - __asm - { - smull t2, t, b, a /* (lo=t2,hi=t) = a*b */ - mov a, t, asr #31 /* a = (hi >> 31) */ - add a, a, #0x8000 /* a += 0x8000 */ - adds t2, t2, a /* t2 += a */ - adc t, t, #0 /* t += carry */ - mov a, t2, lsr #16 /* a = t2 >> 16 */ - orr a, a, t, lsl #16 /* a |= t << 16 */ - } - return a; - } - -#endif /* __CC_ARM || __ARMCC__ */ - - -#ifdef __GNUC__ - -#if defined( __arm__ ) && \ - ( !defined( __thumb__ ) || defined( __thumb2__ ) ) && \ - !( defined( __CC_ARM ) || defined( __ARMCC__ ) ) - -#define FT_MULFIX_ASSEMBLER FT_MulFix_arm - - /* documentation is in freetype.h */ - - static __inline__ FT_Int32 - FT_MulFix_arm( FT_Int32 a, - FT_Int32 b ) - { - register FT_Int32 t, t2; - - - __asm__ __volatile__ ( - "smull %1, %2, %4, %3\n\t" /* (lo=%1,hi=%2) = a*b */ - "mov %0, %2, asr #31\n\t" /* %0 = (hi >> 31) */ -#if defined( __clang__ ) && defined( __thumb2__ ) - "add.w %0, %0, #0x8000\n\t" /* %0 += 0x8000 */ -#else - "add %0, %0, #0x8000\n\t" /* %0 += 0x8000 */ -#endif - "adds %1, %1, %0\n\t" /* %1 += %0 */ - "adc %2, %2, #0\n\t" /* %2 += carry */ - "mov %0, %1, lsr #16\n\t" /* %0 = %1 >> 16 */ - "orr %0, %0, %2, lsl #16\n\t" /* %0 |= %2 << 16 */ - : "=r"(a), "=&r"(t2), "=&r"(t) - : "r"(a), "r"(b) - : "cc" ); - return a; - } - -#endif /* __arm__ && */ - /* ( __thumb2__ || !__thumb__ ) && */ - /* !( __CC_ARM || __ARMCC__ ) */ - - -#if defined( __i386__ ) - -#define FT_MULFIX_ASSEMBLER FT_MulFix_i386 - - /* documentation is in freetype.h */ - - static __inline__ FT_Int32 - FT_MulFix_i386( FT_Int32 a, - FT_Int32 b ) - { - register FT_Int32 result; - - - __asm__ __volatile__ ( - "imul %%edx\n" - "movl %%edx, %%ecx\n" - "sarl $31, %%ecx\n" - "addl $0x8000, %%ecx\n" - "addl %%ecx, %%eax\n" - "adcl $0, %%edx\n" - "shrl $16, %%eax\n" - "shll $16, %%edx\n" - "addl %%edx, %%eax\n" - : "=a"(result), "=d"(b) - : "a"(a), "d"(b) - : "%ecx", "cc" ); - return result; - } - -#endif /* i386 */ - -#endif /* __GNUC__ */ - - -#ifdef _MSC_VER /* Visual C++ */ - -#ifdef _M_IX86 - -#define FT_MULFIX_ASSEMBLER FT_MulFix_i386 - - /* documentation is in freetype.h */ - - static __inline FT_Int32 - FT_MulFix_i386( FT_Int32 a, - FT_Int32 b ) - { - register FT_Int32 result; - - __asm - { - mov eax, a - mov edx, b - imul edx - mov ecx, edx - sar ecx, 31 - add ecx, 8000h - add eax, ecx - adc edx, 0 - shr eax, 16 - shl edx, 16 - add eax, edx - mov result, eax - } - return result; - } - -#endif /* _M_IX86 */ - -#endif /* _MSC_VER */ - - -#if defined( __GNUC__ ) && defined( __x86_64__ ) - -#define FT_MULFIX_ASSEMBLER FT_MulFix_x86_64 - - static __inline__ FT_Int32 - FT_MulFix_x86_64( FT_Int32 a, - FT_Int32 b ) - { - /* Temporarily disable the warning that C90 doesn't support */ - /* `long long'. */ -#if ( __GNUC__ > 4 ) || ( ( __GNUC__ == 4 ) && ( __GNUC_MINOR__ >= 6 ) ) -#pragma GCC diagnostic push -#pragma GCC diagnostic ignored "-Wlong-long" -#endif - -#if 1 - /* Technically not an assembly fragment, but GCC does a really good */ - /* job at inlining it and generating good machine code for it. */ - long long ret, tmp; - - - ret = (long long)a * b; - tmp = ret >> 63; - ret += 0x8000 + tmp; - - return (FT_Int32)( ret >> 16 ); -#else - - /* For some reason, GCC 4.6 on Ubuntu 12.04 generates invalid machine */ - /* code from the lines below. The main issue is that `wide_a' is not */ - /* properly initialized by sign-extending `a'. Instead, the generated */ - /* machine code assumes that the register that contains `a' on input */ - /* can be used directly as a 64-bit value, which is wrong most of the */ - /* time. */ - long long wide_a = (long long)a; - long long wide_b = (long long)b; - long long result; - - - __asm__ __volatile__ ( - "imul %2, %1\n" - "mov %1, %0\n" - "sar $63, %0\n" - "lea 0x8000(%1, %0), %0\n" - "sar $16, %0\n" - : "=&r"(result), "=&r"(wide_a) - : "r"(wide_b) - : "cc" ); - - return (FT_Int32)result; -#endif - -#if ( __GNUC__ > 4 ) || ( ( __GNUC__ == 4 ) && ( __GNUC_MINOR__ >= 6 ) ) -#pragma GCC diagnostic pop -#endif - } - -#endif /* __GNUC__ && __x86_64__ */ - -#endif /* !FT_CONFIG_OPTION_NO_ASSEMBLER */ - - -#ifdef FT_CONFIG_OPTION_INLINE_MULFIX -#ifdef FT_MULFIX_ASSEMBLER -#define FT_MULFIX_INLINED FT_MULFIX_ASSEMBLER -#endif -#endif - - #ifdef FT_MAKE_OPTION_SINGLE_OBJECT #define FT_LOCAL( x ) static x diff --git a/builds/unix/unix-def.in b/builds/unix/unix-def.in index 35ea9c8..4c06a05 100644 --- a/builds/unix/unix-def.in +++ b/builds/unix/unix-def.in @@ -64,7 +64,6 @@ version_info := @version_info@ # REQUIRES_PRIVATE := @REQUIRES_PRIVATE@ LIBS_PRIVATE := @LIBS_PRIVATE@ -LIBS_CONFIG := @LIBS_CONFIG@ LIBSSTATIC_CONFIG := @LIBSSTATIC_CONFIG@ build_libtool_libs := @build_libtool_libs@ ft_version := @ft_version@ @@ -102,8 +101,7 @@ NO_OUTPUT := 2> /dev/null $(OBJ_BUILD)/freetype-config: $(TOP_DIR)/builds/unix/freetype-config.in rm -f $@ $@.tmp - sed -e 's|%LIBS_CONFIG%|$(LIBS_CONFIG)|' \ - -e 's|%LIBSSTATIC_CONFIG%|$(LIBSSTATIC_CONFIG)|' \ + sed -e 's|%LIBSSTATIC_CONFIG%|$(LIBSSTATIC_CONFIG)|' \ -e 's|%build_libtool_libs%|$(build_libtool_libs)|' \ -e 's|%exec_prefix%|$(exec_prefix)|' \ -e 's|%ft_version%|$(ft_version)|' \ @@ -116,16 +114,29 @@ $(OBJ_BUILD)/freetype-config: $(TOP_DIR)/builds/unix/freetype-config.in chmod a-w $@.tmp mv $@.tmp $@ +# To support directory names with spaces (as might easily happen on Windows +# platforms), the right solution would be to surround the pkg-variables in +# `freetype2.pc' with double quotes. However, doing so ironically disables +# the prefix override mechanism especially written for Windows. This is a +# bug in pkg-config version 0.28 and earlier. +# +# For this reason, we escape spaces with backslashes. + +exec_prefix_x := $(subst $(space),\\$(space),$(exec_prefix)) +includedir_x := $(subst $(space),\\$(space),$(includedir)) +libdir_x := $(subst $(space),\\$(space),$(libdir)) +prefix_x := $(subst $(space),\\$(space),$(prefix)) + $(OBJ_BUILD)/freetype2.pc: $(TOP_DIR)/builds/unix/freetype2.in rm -f $@ $@.tmp sed -e 's|%REQUIRES_PRIVATE%|$(REQUIRES_PRIVATE)|' \ -e 's|%LIBS_PRIVATE%|$(LIBS_PRIVATE)|' \ -e 's|%build_libtool_libs%|$(build_libtool_libs)|' \ - -e 's|%exec_prefix%|$(exec_prefix)|' \ + -e 's|%exec_prefix%|$(exec_prefix_x)|' \ -e 's|%ft_version%|$(ft_version)|' \ - -e 's|%includedir%|$(includedir)|' \ - -e 's|%libdir%|$(libdir)|' \ - -e 's|%prefix%|$(prefix)|' \ + -e 's|%includedir%|$(includedir_x)|' \ + -e 's|%libdir%|$(libdir_x)|' \ + -e 's|%prefix%|$(prefix_x)|' \ $< \ > $@.tmp chmod a-w $@.tmp diff --git a/builds/vms/ftconfig.h b/builds/vms/ftconfig.h index 3fb8f84..b309651 100644 --- a/builds/vms/ftconfig.h +++ b/builds/vms/ftconfig.h @@ -4,7 +4,7 @@ /* */ /* VMS-specific configuration file (specification only). */ /* */ -/* Copyright 1996-2004, 2006-2008, 2011, 2013 by */ +/* Copyright 1996-2004, 2006-2008, 2011, 2013, 2014 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -239,7 +239,16 @@ FT_BEGIN_HEADER #define FT_INT64 long #define FT_UINT64 unsigned long -#elif defined( _MSC_VER ) && _MSC_VER >= 900 /* Visual C++ (and Intel C++) */ + /*************************************************************************/ + /* */ + /* A 64-bit data type may create compilation problems if you compile */ + /* in strict ANSI mode. To avoid them, we disable other 64-bit data */ + /* types if __STDC__ is defined. You can however ignore this rule */ + /* by defining the FT_CONFIG_OPTION_FORCE_INT64 configuration macro. */ + /* */ +#elif !defined( __STDC__ ) || defined( FT_CONFIG_OPTION_FORCE_INT64 ) + +#if defined( _MSC_VER ) && _MSC_VER >= 900 /* Visual C++ (and Intel C++) */ /* this compiler provides the __int64 type */ #define FT_LONG64 @@ -273,27 +282,9 @@ FT_BEGIN_HEADER #define FT_INT64 long long int #define FT_UINT64 unsigned long long int -#endif /* FT_SIZEOF_LONG == (64 / FT_CHAR_BIT) */ - - - /*************************************************************************/ - /* */ - /* A 64-bit data type will create compilation problems if you compile */ - /* in strict ANSI mode. To avoid them, we disable its use if __STDC__ */ - /* is defined. You can however ignore this rule by defining the */ - /* FT_CONFIG_OPTION_FORCE_INT64 configuration macro. */ - /* */ -#if defined( FT_LONG64 ) && !defined( FT_CONFIG_OPTION_FORCE_INT64 ) - -#ifdef __STDC__ - - /* undefine the 64-bit macros in strict ANSI compilation mode */ -#undef FT_LONG64 -#undef FT_INT64 - -#endif /* __STDC__ */ +#endif /* _MSC_VER */ -#endif /* FT_LONG64 && !FT_CONFIG_OPTION_FORCE_INT64 */ +#endif /* FT_SIZEOF_LONG == (64 / FT_CHAR_BIT) */ #ifdef FT_LONG64 typedef FT_INT64 FT_Int64; @@ -306,215 +297,6 @@ FT_BEGIN_HEADER #define FT_DUMMY_STMNT FT_BEGIN_STMNT FT_END_STMNT -#ifndef FT_CONFIG_OPTION_NO_ASSEMBLER - /* Provide assembler fragments for performance-critical functions. */ - /* These must be defined `static __inline__' with GCC. */ - -#if defined( __CC_ARM ) || defined( __ARMCC__ ) /* RVCT */ - -#define FT_MULFIX_ASSEMBLER FT_MulFix_arm - - /* documentation is in freetype.h */ - - static __inline FT_Int32 - FT_MulFix_arm( FT_Int32 a, - FT_Int32 b ) - { - register FT_Int32 t, t2; - - - __asm - { - smull t2, t, b, a /* (lo=t2,hi=t) = a*b */ - mov a, t, asr #31 /* a = (hi >> 31) */ - add a, a, #0x8000 /* a += 0x8000 */ - adds t2, t2, a /* t2 += a */ - adc t, t, #0 /* t += carry */ - mov a, t2, lsr #16 /* a = t2 >> 16 */ - orr a, a, t, lsl #16 /* a |= t << 16 */ - } - return a; - } - -#endif /* __CC_ARM || __ARMCC__ */ - - -#ifdef __GNUC__ - -#if defined( __arm__ ) && \ - ( !defined( __thumb__ ) || defined( __thumb2__ ) ) && \ - !( defined( __CC_ARM ) || defined( __ARMCC__ ) ) - -#define FT_MULFIX_ASSEMBLER FT_MulFix_arm - - /* documentation is in freetype.h */ - - static __inline__ FT_Int32 - FT_MulFix_arm( FT_Int32 a, - FT_Int32 b ) - { - register FT_Int32 t, t2; - - - __asm__ __volatile__ ( - "smull %1, %2, %4, %3\n\t" /* (lo=%1,hi=%2) = a*b */ - "mov %0, %2, asr #31\n\t" /* %0 = (hi >> 31) */ - "add %0, %0, #0x8000\n\t" /* %0 += 0x8000 */ - "adds %1, %1, %0\n\t" /* %1 += %0 */ - "adc %2, %2, #0\n\t" /* %2 += carry */ - "mov %0, %1, lsr #16\n\t" /* %0 = %1 >> 16 */ - "orr %0, %0, %2, lsl #16\n\t" /* %0 |= %2 << 16 */ - : "=r"(a), "=&r"(t2), "=&r"(t) - : "r"(a), "r"(b) - : "cc" ); - return a; - } - -#endif /* __arm__ && */ - /* ( __thumb2__ || !__thumb__ ) && */ - /* !( __CC_ARM || __ARMCC__ ) */ - - -#if defined( __i386__ ) - -#define FT_MULFIX_ASSEMBLER FT_MulFix_i386 - - /* documentation is in freetype.h */ - - static __inline__ FT_Int32 - FT_MulFix_i386( FT_Int32 a, - FT_Int32 b ) - { - register FT_Int32 result; - - - __asm__ __volatile__ ( - "imul %%edx\n" - "movl %%edx, %%ecx\n" - "sarl $31, %%ecx\n" - "addl $0x8000, %%ecx\n" - "addl %%ecx, %%eax\n" - "adcl $0, %%edx\n" - "shrl $16, %%eax\n" - "shll $16, %%edx\n" - "addl %%edx, %%eax\n" - : "=a"(result), "=d"(b) - : "a"(a), "d"(b) - : "%ecx", "cc" ); - return result; - } - -#endif /* i386 */ - -#endif /* __GNUC__ */ - - -#ifdef _MSC_VER /* Visual C++ */ - -#ifdef _M_IX86 - -#define FT_MULFIX_ASSEMBLER FT_MulFix_i386 - - /* documentation is in freetype.h */ - - static __inline FT_Int32 - FT_MulFix_i386( FT_Int32 a, - FT_Int32 b ) - { - register FT_Int32 result; - - __asm - { - mov eax, a - mov edx, b - imul edx - mov ecx, edx - sar ecx, 31 - add ecx, 8000h - add eax, ecx - adc edx, 0 - shr eax, 16 - shl edx, 16 - add eax, edx - mov result, eax - } - return result; - } - -#endif /* _M_IX86 */ - -#endif /* _MSC_VER */ - - -#if defined( __GNUC__ ) && defined( __x86_64__ ) - -#define FT_MULFIX_ASSEMBLER FT_MulFix_x86_64 - - static __inline__ FT_Int32 - FT_MulFix_x86_64( FT_Int32 a, - FT_Int32 b ) - { - /* Temporarily disable the warning that C90 doesn't support */ - /* `long long'. */ -#if ( __GNUC__ > 4 ) || ( ( __GNUC__ == 4 ) && ( __GNUC_MINOR__ >= 6 ) ) -#pragma GCC diagnostic push -#pragma GCC diagnostic ignored "-Wlong-long" -#endif - -#if 1 - /* Technically not an assembly fragment, but GCC does a really good */ - /* job at inlining it and generating good machine code for it. */ - long long ret, tmp; - - - ret = (long long)a * b; - tmp = ret >> 63; - ret += 0x8000 + tmp; - - return (FT_Int32)( ret >> 16 ); -#else - - /* For some reason, GCC 4.6 on Ubuntu 12.04 generates invalid machine */ - /* code from the lines below. The main issue is that `wide_a' is not */ - /* properly initialized by sign-extending `a'. Instead, the generated */ - /* machine code assumes that the register that contains `a' on input */ - /* can be used directly as a 64-bit value, which is wrong most of the */ - /* time. */ - long long wide_a = (long long)a; - long long wide_b = (long long)b; - long long result; - - - __asm__ __volatile__ ( - "imul %2, %1\n" - "mov %1, %0\n" - "sar $63, %0\n" - "lea 0x8000(%1, %0), %0\n" - "sar $16, %0\n" - : "=&r"(result), "=&r"(wide_a) - : "r"(wide_b) - : "cc" ); - - return (FT_Int32)result; -#endif - -#if ( __GNUC__ > 4 ) || ( ( __GNUC__ == 4 ) && ( __GNUC_MINOR__ >= 6 ) ) -#pragma GCC diagnostic pop -#endif - } - -#endif /* __GNUC__ && __x86_64__ */ - -#endif /* !FT_CONFIG_OPTION_NO_ASSEMBLER */ - - -#ifdef FT_CONFIG_OPTION_INLINE_MULFIX -#ifdef FT_MULFIX_ASSEMBLER -#define FT_MULFIX_INLINED FT_MULFIX_ASSEMBLER -#endif -#endif - - #ifdef FT_MAKE_OPTION_SINGLE_OBJECT #define FT_LOCAL( x ) static x diff --git a/docs/CHANGES b/docs/CHANGES index 803f02d..51b829c 100644 --- a/docs/CHANGES +++ b/docs/CHANGES @@ -1,11 +1,40 @@ +CHANGES BETWEEN 2.5.3 and 2.5.4 + + I. IMPORTANT BUG FIXES + + - The new auto-hinter code using HarfBuzz crashed for some invalid + fonts. + + + II. IMPORTANT CHANGES + + - Full auto-hinter support of the Devanagari script. + + + III. MISCELLANEOUS + + - Improvements to the auto-hinter's algorithm to recognize stems + and local extrema. + + - Function `FT_Get_SubGlyph_Info' always returned an error even in + case of success. + + - Version 2.5.1 introduced major bugs in the cjk part of the + auto-hinter, which are now fixed. + + - `cmake' now supports a build of FreeType as an OS X framework. + + +====================================================================== + CHANGES BETWEEN 2.5.2 and 2.5.3 I. IMPORTANT BUG FIXES - - A vulnerability was identified and fixed in the new CFF driver - (cf. http://savannah.nongnu.org/bugs/?41697; it doesn't have a - CVE number yet). All users should upgrade. + - A vulnerability (CVE-2014-2240) was identified and fixed in the + new CFF driver (cf. http://savannah.nongnu.org/bugs/?41697). + All users should upgrade. - More bug fixes related to correct positioning of composite glyphs. @@ -261,6 +290,9 @@ CHANGES BETWEEN 2.4.12 and 2.5 it accepts a new command line option `-H' to select the hinting engine. + - `ftdump's verbose option has been renamed to `-V'. For all demo + programs, `-v' now shows version information. + - Another round of TrueType subpixel hinting fixes. - The `apinames' tool can now create an import file for NetWare. diff --git a/include/config/ftconfig.h b/include/config/ftconfig.h index d98a311..22d70fd 100644 --- a/include/config/ftconfig.h +++ b/include/config/ftconfig.h @@ -266,7 +266,16 @@ FT_BEGIN_HEADER #define FT_INT64 long #define FT_UINT64 unsigned long -#elif defined( _MSC_VER ) && _MSC_VER >= 900 /* Visual C++ (and Intel C++) */ + /*************************************************************************/ + /* */ + /* A 64-bit data type may create compilation problems if you compile */ + /* in strict ANSI mode. To avoid them, we disable other 64-bit data */ + /* types if __STDC__ is defined. You can however ignore this rule */ + /* by defining the FT_CONFIG_OPTION_FORCE_INT64 configuration macro. */ + /* */ +#elif !defined( __STDC__ ) || defined( FT_CONFIG_OPTION_FORCE_INT64 ) + +#if defined( _MSC_VER ) && _MSC_VER >= 900 /* Visual C++ (and Intel C++) */ /* this compiler provides the __int64 type */ #define FT_LONG64 @@ -300,27 +309,9 @@ FT_BEGIN_HEADER #define FT_INT64 long long int #define FT_UINT64 unsigned long long int -#endif /* FT_SIZEOF_LONG == (64 / FT_CHAR_BIT) */ - - - /*************************************************************************/ - /* */ - /* A 64-bit data type will create compilation problems if you compile */ - /* in strict ANSI mode. To avoid them, we disable its use if __STDC__ */ - /* is defined. You can however ignore this rule by defining the */ - /* FT_CONFIG_OPTION_FORCE_INT64 configuration macro. */ - /* */ -#if defined( FT_LONG64 ) && !defined( FT_CONFIG_OPTION_FORCE_INT64 ) - -#ifdef __STDC__ - - /* undefine the 64-bit macros in strict ANSI compilation mode */ -#undef FT_LONG64 -#undef FT_INT64 - -#endif /* __STDC__ */ +#endif /* _MSC_VER */ -#endif /* FT_LONG64 && !FT_CONFIG_OPTION_FORCE_INT64 */ +#endif /* FT_SIZEOF_LONG == (64 / FT_CHAR_BIT) */ #ifdef FT_LONG64 typedef FT_INT64 FT_Int64; @@ -333,219 +324,6 @@ FT_BEGIN_HEADER #define FT_DUMMY_STMNT FT_BEGIN_STMNT FT_END_STMNT -#ifndef FT_CONFIG_OPTION_NO_ASSEMBLER - /* Provide assembler fragments for performance-critical functions. */ - /* These must be defined `static __inline__' with GCC. */ - -#if defined( __CC_ARM ) || defined( __ARMCC__ ) /* RVCT */ - -#define FT_MULFIX_ASSEMBLER FT_MulFix_arm - - /* documentation is in freetype.h */ - - static __inline FT_Int32 - FT_MulFix_arm( FT_Int32 a, - FT_Int32 b ) - { - register FT_Int32 t, t2; - - - __asm - { - smull t2, t, b, a /* (lo=t2,hi=t) = a*b */ - mov a, t, asr #31 /* a = (hi >> 31) */ - add a, a, #0x8000 /* a += 0x8000 */ - adds t2, t2, a /* t2 += a */ - adc t, t, #0 /* t += carry */ - mov a, t2, lsr #16 /* a = t2 >> 16 */ - orr a, a, t, lsl #16 /* a |= t << 16 */ - } - return a; - } - -#endif /* __CC_ARM || __ARMCC__ */ - - -#ifdef __GNUC__ - -#if defined( __arm__ ) && \ - ( !defined( __thumb__ ) || defined( __thumb2__ ) ) && \ - !( defined( __CC_ARM ) || defined( __ARMCC__ ) ) - -#define FT_MULFIX_ASSEMBLER FT_MulFix_arm - - /* documentation is in freetype.h */ - - static __inline__ FT_Int32 - FT_MulFix_arm( FT_Int32 a, - FT_Int32 b ) - { - register FT_Int32 t, t2; - - - __asm__ __volatile__ ( - "smull %1, %2, %4, %3\n\t" /* (lo=%1,hi=%2) = a*b */ - "mov %0, %2, asr #31\n\t" /* %0 = (hi >> 31) */ -#if defined( __clang__ ) && defined( __thumb2__ ) - "add.w %0, %0, #0x8000\n\t" /* %0 += 0x8000 */ -#else - "add %0, %0, #0x8000\n\t" /* %0 += 0x8000 */ -#endif - "adds %1, %1, %0\n\t" /* %1 += %0 */ - "adc %2, %2, #0\n\t" /* %2 += carry */ - "mov %0, %1, lsr #16\n\t" /* %0 = %1 >> 16 */ - "orr %0, %0, %2, lsl #16\n\t" /* %0 |= %2 << 16 */ - : "=r"(a), "=&r"(t2), "=&r"(t) - : "r"(a), "r"(b) - : "cc" ); - return a; - } - -#endif /* __arm__ && */ - /* ( __thumb2__ || !__thumb__ ) && */ - /* !( __CC_ARM || __ARMCC__ ) */ - - -#if defined( __i386__ ) - -#define FT_MULFIX_ASSEMBLER FT_MulFix_i386 - - /* documentation is in freetype.h */ - - static __inline__ FT_Int32 - FT_MulFix_i386( FT_Int32 a, - FT_Int32 b ) - { - register FT_Int32 result; - - - __asm__ __volatile__ ( - "imul %%edx\n" - "movl %%edx, %%ecx\n" - "sarl $31, %%ecx\n" - "addl $0x8000, %%ecx\n" - "addl %%ecx, %%eax\n" - "adcl $0, %%edx\n" - "shrl $16, %%eax\n" - "shll $16, %%edx\n" - "addl %%edx, %%eax\n" - : "=a"(result), "=d"(b) - : "a"(a), "d"(b) - : "%ecx", "cc" ); - return result; - } - -#endif /* i386 */ - -#endif /* __GNUC__ */ - - -#ifdef _MSC_VER /* Visual C++ */ - -#ifdef _M_IX86 - -#define FT_MULFIX_ASSEMBLER FT_MulFix_i386 - - /* documentation is in freetype.h */ - - static __inline FT_Int32 - FT_MulFix_i386( FT_Int32 a, - FT_Int32 b ) - { - register FT_Int32 result; - - __asm - { - mov eax, a - mov edx, b - imul edx - mov ecx, edx - sar ecx, 31 - add ecx, 8000h - add eax, ecx - adc edx, 0 - shr eax, 16 - shl edx, 16 - add eax, edx - mov result, eax - } - return result; - } - -#endif /* _M_IX86 */ - -#endif /* _MSC_VER */ - - -#if defined( __GNUC__ ) && defined( __x86_64__ ) - -#define FT_MULFIX_ASSEMBLER FT_MulFix_x86_64 - - static __inline__ FT_Int32 - FT_MulFix_x86_64( FT_Int32 a, - FT_Int32 b ) - { - /* Temporarily disable the warning that C90 doesn't support */ - /* `long long'. */ -#if ( __GNUC__ > 4 ) || ( ( __GNUC__ == 4 ) && ( __GNUC_MINOR__ >= 6 ) ) -#pragma GCC diagnostic push -#pragma GCC diagnostic ignored "-Wlong-long" -#endif - -#if 1 - /* Technically not an assembly fragment, but GCC does a really good */ - /* job at inlining it and generating good machine code for it. */ - long long ret, tmp; - - - ret = (long long)a * b; - tmp = ret >> 63; - ret += 0x8000 + tmp; - - return (FT_Int32)( ret >> 16 ); -#else - - /* For some reason, GCC 4.6 on Ubuntu 12.04 generates invalid machine */ - /* code from the lines below. The main issue is that `wide_a' is not */ - /* properly initialized by sign-extending `a'. Instead, the generated */ - /* machine code assumes that the register that contains `a' on input */ - /* can be used directly as a 64-bit value, which is wrong most of the */ - /* time. */ - long long wide_a = (long long)a; - long long wide_b = (long long)b; - long long result; - - - __asm__ __volatile__ ( - "imul %2, %1\n" - "mov %1, %0\n" - "sar $63, %0\n" - "lea 0x8000(%1, %0), %0\n" - "sar $16, %0\n" - : "=&r"(result), "=&r"(wide_a) - : "r"(wide_b) - : "cc" ); - - return (FT_Int32)result; -#endif - -#if ( __GNUC__ > 4 ) || ( ( __GNUC__ == 4 ) && ( __GNUC_MINOR__ >= 6 ) ) -#pragma GCC diagnostic pop -#endif - } - -#endif /* __GNUC__ && __x86_64__ */ - -#endif /* !FT_CONFIG_OPTION_NO_ASSEMBLER */ - - -#ifdef FT_CONFIG_OPTION_INLINE_MULFIX -#ifdef FT_MULFIX_ASSEMBLER -#define FT_MULFIX_INLINED FT_MULFIX_ASSEMBLER -#endif -#endif - - #ifdef FT_MAKE_OPTION_SINGLE_OBJECT #define FT_LOCAL( x ) static x diff --git a/include/freetype.h b/include/freetype.h index fb62b62..6a31502 100644 --- a/include/freetype.h +++ b/include/freetype.h @@ -1592,7 +1592,6 @@ FT_BEGIN_HEADER /* This field is only valid for the composite */ /* glyph format that should normally only be */ /* loaded with the @FT_LOAD_NO_RECURSE flag. */ - /* For now this is internal to FreeType. */ /* */ /* subglyphs :: An array of subglyph descriptors for */ /* composite glyphs. There are `num_subglyphs' */ @@ -2560,14 +2559,11 @@ FT_BEGIN_HEADER * Ignored. Deprecated. * * FT_LOAD_NO_RECURSE :: - * This flag is only used internally. It merely indicates that the - * font driver should not load composite glyphs recursively. Instead, - * it should set the `num_subglyph' and `subglyphs' values of the - * glyph slot accordingly, and set `glyph->format' to - * @FT_GLYPH_FORMAT_COMPOSITE. - * - * The description of sub-glyphs is not available to client - * applications for now. + * Indicate that the font driver should not load composite glyphs + * recursively. Instead, it should set the `num_subglyph' and + * `subglyphs' values of the glyph slot accordingly, and set + * `glyph->format' to @FT_GLYPH_FORMAT_COMPOSITE. The description of + * subglyphs can then be accessed with @FT_Get_SubGlyph_Info. * * This flag implies @FT_LOAD_NO_SCALE and @FT_LOAD_IGNORE_TRANSFORM. * @@ -3065,9 +3061,8 @@ FT_BEGIN_HEADER /* glyph index~0 always corresponds to the `missing glyph' (called */ /* `.notdef'). */ /* */ - /* This function is not compiled within the library if the config */ - /* macro `FT_CONFIG_OPTION_NO_GLYPH_NAMES' is defined in */ - /* `ftoptions.h'. */ + /* This function always returns an error if the config macro */ + /* `FT_CONFIG_OPTION_NO_GLYPH_NAMES' is not defined in `ftoptions.h'. */ /* */ FT_EXPORT( FT_Error ) FT_Get_Glyph_Name( FT_Face face, @@ -3767,12 +3762,6 @@ FT_BEGIN_HEADER FT_Long c ); - /* */ - - /* The following #if 0 ... #endif is for the documentation formatter, */ - /* hiding the internal `FT_MULFIX_INLINED' macro. */ - -#if 0 /*************************************************************************/ /* */ /* */ @@ -3806,17 +3795,6 @@ FT_BEGIN_HEADER FT_MulFix( FT_Long a, FT_Long b ); - /* */ -#endif - -#ifdef FT_MULFIX_INLINED -#define FT_MulFix( a, b ) FT_MULFIX_INLINED( a, b ) -#else - FT_EXPORT( FT_Long ) - FT_MulFix( FT_Long a, - FT_Long b ); -#endif - /*************************************************************************/ /* */ @@ -3829,18 +3807,12 @@ FT_BEGIN_HEADER /* used to divide a given value by a 16.16 fixed-point factor. */ /* */ /* */ - /* a :: The first multiplier. */ - /* b :: The second multiplier. Use a 16.16 factor here whenever */ - /* possible (see note below). */ + /* a :: The numerator. */ + /* b :: The denominator. Use a 16.16 factor here. */ /* */ /* */ /* The result of `(a*0x10000)/b'. */ /* */ - /* */ - /* The optimization for FT_DivFix() is simple: If (a~<<~16) fits in */ - /* 32~bits, then the division is computed directly. Otherwise, we */ - /* use a specialized version of @FT_MulDiv. */ - /* */ FT_EXPORT( FT_Long ) FT_DivFix( FT_Long a, FT_Long b ); diff --git a/include/fterrdef.h b/include/fterrdef.h index 76c7b9e..99b2fad 100644 --- a/include/fterrdef.h +++ b/include/fterrdef.h @@ -31,218 +31,218 @@ /* generic errors */ - FT_NOERRORDEF_( Ok, 0x00, \ + FT_NOERRORDEF_( Ok, 0x00, "no error" ) - FT_ERRORDEF_( Cannot_Open_Resource, 0x01, \ + FT_ERRORDEF_( Cannot_Open_Resource, 0x01, "cannot open resource" ) - FT_ERRORDEF_( Unknown_File_Format, 0x02, \ + FT_ERRORDEF_( Unknown_File_Format, 0x02, "unknown file format" ) - FT_ERRORDEF_( Invalid_File_Format, 0x03, \ + FT_ERRORDEF_( Invalid_File_Format, 0x03, "broken file" ) - FT_ERRORDEF_( Invalid_Version, 0x04, \ + FT_ERRORDEF_( Invalid_Version, 0x04, "invalid FreeType version" ) - FT_ERRORDEF_( Lower_Module_Version, 0x05, \ + FT_ERRORDEF_( Lower_Module_Version, 0x05, "module version is too low" ) - FT_ERRORDEF_( Invalid_Argument, 0x06, \ + FT_ERRORDEF_( Invalid_Argument, 0x06, "invalid argument" ) - FT_ERRORDEF_( Unimplemented_Feature, 0x07, \ + FT_ERRORDEF_( Unimplemented_Feature, 0x07, "unimplemented feature" ) - FT_ERRORDEF_( Invalid_Table, 0x08, \ + FT_ERRORDEF_( Invalid_Table, 0x08, "broken table" ) - FT_ERRORDEF_( Invalid_Offset, 0x09, \ + FT_ERRORDEF_( Invalid_Offset, 0x09, "broken offset within table" ) - FT_ERRORDEF_( Array_Too_Large, 0x0A, \ + FT_ERRORDEF_( Array_Too_Large, 0x0A, "array allocation size too large" ) - FT_ERRORDEF_( Missing_Module, 0x0B, \ + FT_ERRORDEF_( Missing_Module, 0x0B, "missing module" ) - FT_ERRORDEF_( Missing_Property, 0x0C, \ + FT_ERRORDEF_( Missing_Property, 0x0C, "missing property" ) /* glyph/character errors */ - FT_ERRORDEF_( Invalid_Glyph_Index, 0x10, \ + FT_ERRORDEF_( Invalid_Glyph_Index, 0x10, "invalid glyph index" ) - FT_ERRORDEF_( Invalid_Character_Code, 0x11, \ + FT_ERRORDEF_( Invalid_Character_Code, 0x11, "invalid character code" ) - FT_ERRORDEF_( Invalid_Glyph_Format, 0x12, \ + FT_ERRORDEF_( Invalid_Glyph_Format, 0x12, "unsupported glyph image format" ) - FT_ERRORDEF_( Cannot_Render_Glyph, 0x13, \ + FT_ERRORDEF_( Cannot_Render_Glyph, 0x13, "cannot render this glyph format" ) - FT_ERRORDEF_( Invalid_Outline, 0x14, \ + FT_ERRORDEF_( Invalid_Outline, 0x14, "invalid outline" ) - FT_ERRORDEF_( Invalid_Composite, 0x15, \ + FT_ERRORDEF_( Invalid_Composite, 0x15, "invalid composite glyph" ) - FT_ERRORDEF_( Too_Many_Hints, 0x16, \ + FT_ERRORDEF_( Too_Many_Hints, 0x16, "too many hints" ) - FT_ERRORDEF_( Invalid_Pixel_Size, 0x17, \ + FT_ERRORDEF_( Invalid_Pixel_Size, 0x17, "invalid pixel size" ) /* handle errors */ - FT_ERRORDEF_( Invalid_Handle, 0x20, \ + FT_ERRORDEF_( Invalid_Handle, 0x20, "invalid object handle" ) - FT_ERRORDEF_( Invalid_Library_Handle, 0x21, \ + FT_ERRORDEF_( Invalid_Library_Handle, 0x21, "invalid library handle" ) - FT_ERRORDEF_( Invalid_Driver_Handle, 0x22, \ + FT_ERRORDEF_( Invalid_Driver_Handle, 0x22, "invalid module handle" ) - FT_ERRORDEF_( Invalid_Face_Handle, 0x23, \ + FT_ERRORDEF_( Invalid_Face_Handle, 0x23, "invalid face handle" ) - FT_ERRORDEF_( Invalid_Size_Handle, 0x24, \ + FT_ERRORDEF_( Invalid_Size_Handle, 0x24, "invalid size handle" ) - FT_ERRORDEF_( Invalid_Slot_Handle, 0x25, \ + FT_ERRORDEF_( Invalid_Slot_Handle, 0x25, "invalid glyph slot handle" ) - FT_ERRORDEF_( Invalid_CharMap_Handle, 0x26, \ + FT_ERRORDEF_( Invalid_CharMap_Handle, 0x26, "invalid charmap handle" ) - FT_ERRORDEF_( Invalid_Cache_Handle, 0x27, \ + FT_ERRORDEF_( Invalid_Cache_Handle, 0x27, "invalid cache manager handle" ) - FT_ERRORDEF_( Invalid_Stream_Handle, 0x28, \ + FT_ERRORDEF_( Invalid_Stream_Handle, 0x28, "invalid stream handle" ) /* driver errors */ - FT_ERRORDEF_( Too_Many_Drivers, 0x30, \ + FT_ERRORDEF_( Too_Many_Drivers, 0x30, "too many modules" ) - FT_ERRORDEF_( Too_Many_Extensions, 0x31, \ + FT_ERRORDEF_( Too_Many_Extensions, 0x31, "too many extensions" ) /* memory errors */ - FT_ERRORDEF_( Out_Of_Memory, 0x40, \ + FT_ERRORDEF_( Out_Of_Memory, 0x40, "out of memory" ) - FT_ERRORDEF_( Unlisted_Object, 0x41, \ + FT_ERRORDEF_( Unlisted_Object, 0x41, "unlisted object" ) /* stream errors */ - FT_ERRORDEF_( Cannot_Open_Stream, 0x51, \ + FT_ERRORDEF_( Cannot_Open_Stream, 0x51, "cannot open stream" ) - FT_ERRORDEF_( Invalid_Stream_Seek, 0x52, \ + FT_ERRORDEF_( Invalid_Stream_Seek, 0x52, "invalid stream seek" ) - FT_ERRORDEF_( Invalid_Stream_Skip, 0x53, \ + FT_ERRORDEF_( Invalid_Stream_Skip, 0x53, "invalid stream skip" ) - FT_ERRORDEF_( Invalid_Stream_Read, 0x54, \ + FT_ERRORDEF_( Invalid_Stream_Read, 0x54, "invalid stream read" ) - FT_ERRORDEF_( Invalid_Stream_Operation, 0x55, \ + FT_ERRORDEF_( Invalid_Stream_Operation, 0x55, "invalid stream operation" ) - FT_ERRORDEF_( Invalid_Frame_Operation, 0x56, \ + FT_ERRORDEF_( Invalid_Frame_Operation, 0x56, "invalid frame operation" ) - FT_ERRORDEF_( Nested_Frame_Access, 0x57, \ + FT_ERRORDEF_( Nested_Frame_Access, 0x57, "nested frame access" ) - FT_ERRORDEF_( Invalid_Frame_Read, 0x58, \ + FT_ERRORDEF_( Invalid_Frame_Read, 0x58, "invalid frame read" ) /* raster errors */ - FT_ERRORDEF_( Raster_Uninitialized, 0x60, \ + FT_ERRORDEF_( Raster_Uninitialized, 0x60, "raster uninitialized" ) - FT_ERRORDEF_( Raster_Corrupted, 0x61, \ + FT_ERRORDEF_( Raster_Corrupted, 0x61, "raster corrupted" ) - FT_ERRORDEF_( Raster_Overflow, 0x62, \ + FT_ERRORDEF_( Raster_Overflow, 0x62, "raster overflow" ) - FT_ERRORDEF_( Raster_Negative_Height, 0x63, \ + FT_ERRORDEF_( Raster_Negative_Height, 0x63, "negative height while rastering" ) /* cache errors */ - FT_ERRORDEF_( Too_Many_Caches, 0x70, \ + FT_ERRORDEF_( Too_Many_Caches, 0x70, "too many registered caches" ) /* TrueType and SFNT errors */ - FT_ERRORDEF_( Invalid_Opcode, 0x80, \ + FT_ERRORDEF_( Invalid_Opcode, 0x80, "invalid opcode" ) - FT_ERRORDEF_( Too_Few_Arguments, 0x81, \ + FT_ERRORDEF_( Too_Few_Arguments, 0x81, "too few arguments" ) - FT_ERRORDEF_( Stack_Overflow, 0x82, \ + FT_ERRORDEF_( Stack_Overflow, 0x82, "stack overflow" ) - FT_ERRORDEF_( Code_Overflow, 0x83, \ + FT_ERRORDEF_( Code_Overflow, 0x83, "code overflow" ) - FT_ERRORDEF_( Bad_Argument, 0x84, \ + FT_ERRORDEF_( Bad_Argument, 0x84, "bad argument" ) - FT_ERRORDEF_( Divide_By_Zero, 0x85, \ + FT_ERRORDEF_( Divide_By_Zero, 0x85, "division by zero" ) - FT_ERRORDEF_( Invalid_Reference, 0x86, \ + FT_ERRORDEF_( Invalid_Reference, 0x86, "invalid reference" ) - FT_ERRORDEF_( Debug_OpCode, 0x87, \ + FT_ERRORDEF_( Debug_OpCode, 0x87, "found debug opcode" ) - FT_ERRORDEF_( ENDF_In_Exec_Stream, 0x88, \ + FT_ERRORDEF_( ENDF_In_Exec_Stream, 0x88, "found ENDF opcode in execution stream" ) - FT_ERRORDEF_( Nested_DEFS, 0x89, \ + FT_ERRORDEF_( Nested_DEFS, 0x89, "nested DEFS" ) - FT_ERRORDEF_( Invalid_CodeRange, 0x8A, \ + FT_ERRORDEF_( Invalid_CodeRange, 0x8A, "invalid code range" ) - FT_ERRORDEF_( Execution_Too_Long, 0x8B, \ + FT_ERRORDEF_( Execution_Too_Long, 0x8B, "execution context too long" ) - FT_ERRORDEF_( Too_Many_Function_Defs, 0x8C, \ + FT_ERRORDEF_( Too_Many_Function_Defs, 0x8C, "too many function definitions" ) - FT_ERRORDEF_( Too_Many_Instruction_Defs, 0x8D, \ + FT_ERRORDEF_( Too_Many_Instruction_Defs, 0x8D, "too many instruction definitions" ) - FT_ERRORDEF_( Table_Missing, 0x8E, \ + FT_ERRORDEF_( Table_Missing, 0x8E, "SFNT font table missing" ) - FT_ERRORDEF_( Horiz_Header_Missing, 0x8F, \ + FT_ERRORDEF_( Horiz_Header_Missing, 0x8F, "horizontal header (hhea) table missing" ) - FT_ERRORDEF_( Locations_Missing, 0x90, \ + FT_ERRORDEF_( Locations_Missing, 0x90, "locations (loca) table missing" ) - FT_ERRORDEF_( Name_Table_Missing, 0x91, \ + FT_ERRORDEF_( Name_Table_Missing, 0x91, "name table missing" ) - FT_ERRORDEF_( CMap_Table_Missing, 0x92, \ + FT_ERRORDEF_( CMap_Table_Missing, 0x92, "character map (cmap) table missing" ) - FT_ERRORDEF_( Hmtx_Table_Missing, 0x93, \ + FT_ERRORDEF_( Hmtx_Table_Missing, 0x93, "horizontal metrics (hmtx) table missing" ) - FT_ERRORDEF_( Post_Table_Missing, 0x94, \ + FT_ERRORDEF_( Post_Table_Missing, 0x94, "PostScript (post) table missing" ) - FT_ERRORDEF_( Invalid_Horiz_Metrics, 0x95, \ + FT_ERRORDEF_( Invalid_Horiz_Metrics, 0x95, "invalid horizontal metrics" ) - FT_ERRORDEF_( Invalid_CharMap_Format, 0x96, \ + FT_ERRORDEF_( Invalid_CharMap_Format, 0x96, "invalid character map (cmap) format" ) - FT_ERRORDEF_( Invalid_PPem, 0x97, \ + FT_ERRORDEF_( Invalid_PPem, 0x97, "invalid ppem value" ) - FT_ERRORDEF_( Invalid_Vert_Metrics, 0x98, \ + FT_ERRORDEF_( Invalid_Vert_Metrics, 0x98, "invalid vertical metrics" ) - FT_ERRORDEF_( Could_Not_Find_Context, 0x99, \ + FT_ERRORDEF_( Could_Not_Find_Context, 0x99, "could not find context" ) - FT_ERRORDEF_( Invalid_Post_Table_Format, 0x9A, \ + FT_ERRORDEF_( Invalid_Post_Table_Format, 0x9A, "invalid PostScript (post) table format" ) - FT_ERRORDEF_( Invalid_Post_Table, 0x9B, \ + FT_ERRORDEF_( Invalid_Post_Table, 0x9B, "invalid PostScript (post) table" ) /* CFF, CID, and Type 1 errors */ - FT_ERRORDEF_( Syntax_Error, 0xA0, \ + FT_ERRORDEF_( Syntax_Error, 0xA0, "opcode syntax error" ) - FT_ERRORDEF_( Stack_Underflow, 0xA1, \ + FT_ERRORDEF_( Stack_Underflow, 0xA1, "argument stack underflow" ) - FT_ERRORDEF_( Ignore, 0xA2, \ + FT_ERRORDEF_( Ignore, 0xA2, "ignore" ) - FT_ERRORDEF_( No_Unicode_Glyph_Name, 0xA3, \ + FT_ERRORDEF_( No_Unicode_Glyph_Name, 0xA3, "no Unicode glyph name found" ) - FT_ERRORDEF_( Glyph_Too_Big, 0xA4, \ + FT_ERRORDEF_( Glyph_Too_Big, 0xA4, "glyph to big for hinting" ) /* BDF errors */ - FT_ERRORDEF_( Missing_Startfont_Field, 0xB0, \ + FT_ERRORDEF_( Missing_Startfont_Field, 0xB0, "`STARTFONT' field missing" ) - FT_ERRORDEF_( Missing_Font_Field, 0xB1, \ + FT_ERRORDEF_( Missing_Font_Field, 0xB1, "`FONT' field missing" ) - FT_ERRORDEF_( Missing_Size_Field, 0xB2, \ + FT_ERRORDEF_( Missing_Size_Field, 0xB2, "`SIZE' field missing" ) - FT_ERRORDEF_( Missing_Fontboundingbox_Field, 0xB3, \ + FT_ERRORDEF_( Missing_Fontboundingbox_Field, 0xB3, "`FONTBOUNDINGBOX' field missing" ) - FT_ERRORDEF_( Missing_Chars_Field, 0xB4, \ + FT_ERRORDEF_( Missing_Chars_Field, 0xB4, "`CHARS' field missing" ) - FT_ERRORDEF_( Missing_Startchar_Field, 0xB5, \ + FT_ERRORDEF_( Missing_Startchar_Field, 0xB5, "`STARTCHAR' field missing" ) - FT_ERRORDEF_( Missing_Encoding_Field, 0xB6, \ + FT_ERRORDEF_( Missing_Encoding_Field, 0xB6, "`ENCODING' field missing" ) - FT_ERRORDEF_( Missing_Bbx_Field, 0xB7, \ + FT_ERRORDEF_( Missing_Bbx_Field, 0xB7, "`BBX' field missing" ) - FT_ERRORDEF_( Bbx_Too_Big, 0xB8, \ + FT_ERRORDEF_( Bbx_Too_Big, 0xB8, "`BBX' too big" ) - FT_ERRORDEF_( Corrupted_Font_Header, 0xB9, \ + FT_ERRORDEF_( Corrupted_Font_Header, 0xB9, "Font header corrupted or missing fields" ) - FT_ERRORDEF_( Corrupted_Font_Glyphs, 0xBA, \ + FT_ERRORDEF_( Corrupted_Font_Glyphs, 0xBA, "Font glyphs corrupted or missing fields" ) diff --git a/include/fttrigon.h b/include/fttrigon.h index 65143cb..9c7b543 100644 --- a/include/fttrigon.h +++ b/include/fttrigon.h @@ -237,7 +237,7 @@ FT_BEGIN_HEADER * * @input: * angle :: - * The address of angle. + * The input angle. * */ FT_EXPORT( void ) @@ -259,7 +259,7 @@ FT_BEGIN_HEADER * * @input: * angle :: - * The address of angle. + * The input angle. * */ FT_EXPORT( void ) diff --git a/include/internal/ftcalc.h b/include/internal/ftcalc.h index 03bd68e..95165bf 100644 --- a/include/internal/ftcalc.h +++ b/include/internal/ftcalc.h @@ -4,7 +4,7 @@ /* */ /* Arithmetic computations (specification). */ /* */ -/* Copyright 1996-2006, 2008, 2009, 2012-2013 by */ +/* Copyright 1996-2006, 2008, 2009, 2012-2014 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -27,36 +27,223 @@ FT_BEGIN_HEADER -#if 0 - /*************************************************************************/ /* */ - /* */ - /* FT_SqrtFixed */ - /* */ - /* */ - /* Computes the square root of a 16.16 fixed-point value. */ - /* */ - /* */ - /* x :: The value to compute the root for. */ - /* */ - /* */ - /* The result of `sqrt(x)'. */ - /* */ - /* */ - /* This function is not very fast. */ + /* FT_MulDiv() and FT_MulFix() are declared in freetype.h. */ /* */ - FT_BASE( FT_Int32 ) - FT_SqrtFixed( FT_Int32 x ); + /*************************************************************************/ -#endif /* 0 */ +#ifndef FT_CONFIG_OPTION_NO_ASSEMBLER + /* Provide assembler fragments for performance-critical functions. */ + /* These must be defined `static __inline__' with GCC. */ +#if defined( __CC_ARM ) || defined( __ARMCC__ ) /* RVCT */ - /*************************************************************************/ - /* */ - /* FT_MulDiv() and FT_MulFix() are declared in freetype.h. */ - /* */ - /*************************************************************************/ +#define FT_MULFIX_ASSEMBLER FT_MulFix_arm + + /* documentation is in freetype.h */ + + static __inline FT_Int32 + FT_MulFix_arm( FT_Int32 a, + FT_Int32 b ) + { + register FT_Int32 t, t2; + + + __asm + { + smull t2, t, b, a /* (lo=t2,hi=t) = a*b */ + mov a, t, asr #31 /* a = (hi >> 31) */ + add a, a, #0x8000 /* a += 0x8000 */ + adds t2, t2, a /* t2 += a */ + adc t, t, #0 /* t += carry */ + mov a, t2, lsr #16 /* a = t2 >> 16 */ + orr a, a, t, lsl #16 /* a |= t << 16 */ + } + return a; + } + +#endif /* __CC_ARM || __ARMCC__ */ + + +#ifdef __GNUC__ + +#if defined( __arm__ ) && \ + ( !defined( __thumb__ ) || defined( __thumb2__ ) ) && \ + !( defined( __CC_ARM ) || defined( __ARMCC__ ) ) + +#define FT_MULFIX_ASSEMBLER FT_MulFix_arm + + /* documentation is in freetype.h */ + + static __inline__ FT_Int32 + FT_MulFix_arm( FT_Int32 a, + FT_Int32 b ) + { + register FT_Int32 t, t2; + + + __asm__ __volatile__ ( + "smull %1, %2, %4, %3\n\t" /* (lo=%1,hi=%2) = a*b */ + "mov %0, %2, asr #31\n\t" /* %0 = (hi >> 31) */ +#if defined( __clang__ ) && defined( __thumb2__ ) + "add.w %0, %0, #0x8000\n\t" /* %0 += 0x8000 */ +#else + "add %0, %0, #0x8000\n\t" /* %0 += 0x8000 */ +#endif + "adds %1, %1, %0\n\t" /* %1 += %0 */ + "adc %2, %2, #0\n\t" /* %2 += carry */ + "mov %0, %1, lsr #16\n\t" /* %0 = %1 >> 16 */ + "orr %0, %0, %2, lsl #16\n\t" /* %0 |= %2 << 16 */ + : "=r"(a), "=&r"(t2), "=&r"(t) + : "r"(a), "r"(b) + : "cc" ); + return a; + } + +#endif /* __arm__ && */ + /* ( __thumb2__ || !__thumb__ ) && */ + /* !( __CC_ARM || __ARMCC__ ) */ + + +#if defined( __i386__ ) + +#define FT_MULFIX_ASSEMBLER FT_MulFix_i386 + + /* documentation is in freetype.h */ + + static __inline__ FT_Int32 + FT_MulFix_i386( FT_Int32 a, + FT_Int32 b ) + { + register FT_Int32 result; + + + __asm__ __volatile__ ( + "imul %%edx\n" + "movl %%edx, %%ecx\n" + "sarl $31, %%ecx\n" + "addl $0x8000, %%ecx\n" + "addl %%ecx, %%eax\n" + "adcl $0, %%edx\n" + "shrl $16, %%eax\n" + "shll $16, %%edx\n" + "addl %%edx, %%eax\n" + : "=a"(result), "=d"(b) + : "a"(a), "d"(b) + : "%ecx", "cc" ); + return result; + } + +#endif /* i386 */ + +#endif /* __GNUC__ */ + + +#ifdef _MSC_VER /* Visual C++ */ + +#ifdef _M_IX86 + +#define FT_MULFIX_ASSEMBLER FT_MulFix_i386 + + /* documentation is in freetype.h */ + + static __inline FT_Int32 + FT_MulFix_i386( FT_Int32 a, + FT_Int32 b ) + { + register FT_Int32 result; + + __asm + { + mov eax, a + mov edx, b + imul edx + mov ecx, edx + sar ecx, 31 + add ecx, 8000h + add eax, ecx + adc edx, 0 + shr eax, 16 + shl edx, 16 + add eax, edx + mov result, eax + } + return result; + } + +#endif /* _M_IX86 */ + +#endif /* _MSC_VER */ + + +#if defined( __GNUC__ ) && defined( __x86_64__ ) + +#define FT_MULFIX_ASSEMBLER FT_MulFix_x86_64 + + static __inline__ FT_Int32 + FT_MulFix_x86_64( FT_Int32 a, + FT_Int32 b ) + { + /* Temporarily disable the warning that C90 doesn't support */ + /* `long long'. */ +#if ( __GNUC__ > 4 ) || ( ( __GNUC__ == 4 ) && ( __GNUC_MINOR__ >= 6 ) ) +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wlong-long" +#endif + +#if 1 + /* Technically not an assembly fragment, but GCC does a really good */ + /* job at inlining it and generating good machine code for it. */ + long long ret, tmp; + + + ret = (long long)a * b; + tmp = ret >> 63; + ret += 0x8000 + tmp; + + return (FT_Int32)( ret >> 16 ); +#else + + /* For some reason, GCC 4.6 on Ubuntu 12.04 generates invalid machine */ + /* code from the lines below. The main issue is that `wide_a' is not */ + /* properly initialized by sign-extending `a'. Instead, the generated */ + /* machine code assumes that the register that contains `a' on input */ + /* can be used directly as a 64-bit value, which is wrong most of the */ + /* time. */ + long long wide_a = (long long)a; + long long wide_b = (long long)b; + long long result; + + + __asm__ __volatile__ ( + "imul %2, %1\n" + "mov %1, %0\n" + "sar $63, %0\n" + "lea 0x8000(%1, %0), %0\n" + "sar $16, %0\n" + : "=&r"(result), "=&r"(wide_a) + : "r"(wide_b) + : "cc" ); + + return (FT_Int32)result; +#endif + +#if ( __GNUC__ > 4 ) || ( ( __GNUC__ == 4 ) && ( __GNUC_MINOR__ >= 6 ) ) +#pragma GCC diagnostic pop +#endif + } + +#endif /* __GNUC__ && __x86_64__ */ + +#endif /* !FT_CONFIG_OPTION_NO_ASSEMBLER */ + + +#ifdef FT_CONFIG_OPTION_INLINE_MULFIX +#ifdef FT_MULFIX_ASSEMBLER +#define FT_MulFix( a, b ) FT_MULFIX_ASSEMBLER( a, b ) +#endif +#endif /*************************************************************************/ @@ -139,9 +326,32 @@ FT_BEGIN_HEADER /* * Return the most significant bit index. */ + +#ifndef FT_CONFIG_OPTION_NO_ASSEMBLER +#if defined( __GNUC__ ) +#if ( __GNUC__ > 3 ) || ( ( __GNUC__ == 3 ) && ( __GNUC_MINOR__ >= 4 ) ) + +#if FT_SIZEOF_INT == 4 + +#define FT_MSB( x ) ( 31 - __builtin_clz( x ) ) + +#elif FT_SIZEOF_LONG == 4 + +#define FT_MSB( x ) ( 31 - __builtin_clzl( x ) ) + +#endif + +#endif +#endif /* __GNUC__ */ +#endif /* !FT_CONFIG_OPTION_NO_ASSEMBLER */ + +#ifndef FT_MSB + FT_BASE( FT_Int ) FT_MSB( FT_UInt32 z ); +#endif + /* * Return sqrt(x*x+y*y), which is the same as `FT_Vector_Length' but uses @@ -152,6 +362,31 @@ FT_BEGIN_HEADER FT_Fixed y ); +#if 0 + + /*************************************************************************/ + /* */ + /* */ + /* FT_SqrtFixed */ + /* */ + /* */ + /* Computes the square root of a 16.16 fixed-point value. */ + /* */ + /* */ + /* x :: The value to compute the root for. */ + /* */ + /* */ + /* The result of `sqrt(x)'. */ + /* */ + /* */ + /* This function is not very fast. */ + /* */ + FT_BASE( FT_Int32 ) + FT_SqrtFixed( FT_Int32 x ); + +#endif /* 0 */ + + #define INT_TO_F26DOT6( x ) ( (FT_Long)(x) << 6 ) #define INT_TO_F2DOT14( x ) ( (FT_Long)(x) << 14 ) #define INT_TO_FIXED( x ) ( (FT_Long)(x) << 16 ) diff --git a/include/internal/ftobjs.h b/include/internal/ftobjs.h index 701c850..faa37f8 100644 --- a/include/internal/ftobjs.h +++ b/include/internal/ftobjs.h @@ -83,14 +83,6 @@ FT_BEGIN_HEADER /* - * Return the highest power of 2 that is <= value; this correspond to - * the highest bit in a given 32-bit value. - */ - FT_BASE( FT_UInt32 ) - ft_highpow2( FT_UInt32 value ); - - - /* * character classification functions -- since these are used to parse * font files, we must not use those in which are * locale-dependent diff --git a/src/autofit/afblue.c b/src/autofit/afblue.c index 6e214c8..f3526bf 100644 --- a/src/autofit/afblue.c +++ b/src/autofit/afblue.c @@ -26,15 +26,21 @@ af_blue_strings[] = { /* */ - 'T', 'H', 'E', 'Z', 'O', 'C', 'Q', 'S', /* THEZOCQS */ + '\xD0', '\x91', '\xD0', '\x92', '\xD0', '\x95', '\xD0', '\x9F', '\xD0', '\x97', '\xD0', '\x9E', '\xD0', '\xA1', '\xD0', '\xAD', /* БВЕПЗОСЭ */ '\0', - 'H', 'E', 'Z', 'L', 'O', 'C', 'U', 'S', /* HEZLOCUS */ + '\xD0', '\x91', '\xD0', '\x92', '\xD0', '\x95', '\xD0', '\xA8', '\xD0', '\x97', '\xD0', '\x9E', '\xD0', '\xA1', '\xD0', '\xAD', /* БВЕШЗОСЭ */ '\0', - 'f', 'i', 'j', 'k', 'd', 'b', 'h', /* fijkdbh */ + '\xD1', '\x85', '\xD0', '\xBF', '\xD0', '\xBD', '\xD1', '\x88', '\xD0', '\xB5', '\xD0', '\xB7', '\xD0', '\xBE', '\xD1', '\x81', /* хпншезос */ '\0', - 'x', 'z', 'r', 'o', 'e', 's', 'c', /* xzroesc */ + '\xD1', '\x80', '\xD1', '\x83', '\xD1', '\x84', /* руф */ '\0', - 'p', 'q', 'g', 'j', 'y', /* pqgjy */ + '\xE0', '\xA4', '\x95', '\xE0', '\xA4', '\xAE', '\xE0', '\xA4', '\x85', '\xE0', '\xA4', '\x86', '\xE0', '\xA4', '\xA5', '\xE0', '\xA4', '\xA7', '\xE0', '\xA4', '\xAD', '\xE0', '\xA4', '\xB6', /* क म अ आ थ ध भ श */ + '\0', + '\xE0', '\xA4', '\x88', '\xE0', '\xA4', '\x90', '\xE0', '\xA4', '\x93', '\xE0', '\xA4', '\x94', '\xE0', '\xA4', '\xBF', '\xE0', '\xA5', '\x80', '\xE0', '\xA5', '\x8B', '\xE0', '\xA5', '\x8C', /* ई ऐ ओ औ ि ी ो ौ */ + '\0', + '\xE0', '\xA4', '\x95', '\xE0', '\xA4', '\xAE', '\xE0', '\xA4', '\x85', '\xE0', '\xA4', '\x86', '\xE0', '\xA4', '\xA5', '\xE0', '\xA4', '\xA7', '\xE0', '\xA4', '\xAD', '\xE0', '\xA4', '\xB6', /* क म अ आ थ ध भ श */ + '\0', + '\xE0', '\xA5', '\x81', '\xE0', '\xA5', '\x83', /* ु ृ */ '\0', '\xCE', '\x93', '\xCE', '\x92', '\xCE', '\x95', '\xCE', '\x96', '\xCE', '\x98', '\xCE', '\x9F', '\xCE', '\xA9', /* ΓΒΕΖΘΟΩ */ '\0', @@ -46,26 +52,27 @@ '\0', '\xCE', '\xB2', '\xCE', '\xB3', '\xCE', '\xB7', '\xCE', '\xBC', '\xCF', '\x81', '\xCF', '\x86', '\xCF', '\x87', '\xCF', '\x88', /* βγημρφχψ */ '\0', - '\xD0', '\x91', '\xD0', '\x92', '\xD0', '\x95', '\xD0', '\x9F', '\xD0', '\x97', '\xD0', '\x9E', '\xD0', '\xA1', '\xD0', '\xAD', /* БВЕПЗОСЭ */ + '\xD7', '\x91', '\xD7', '\x93', '\xD7', '\x94', '\xD7', '\x97', '\xD7', '\x9A', '\xD7', '\x9B', '\xD7', '\x9D', '\xD7', '\xA1', /* בדהחךכםס */ '\0', - '\xD0', '\x91', '\xD0', '\x92', '\xD0', '\x95', '\xD0', '\xA8', '\xD0', '\x97', '\xD0', '\x9E', '\xD0', '\xA1', '\xD0', '\xAD', /* БВЕШЗОСЭ */ + '\xD7', '\x91', '\xD7', '\x98', '\xD7', '\x9B', '\xD7', '\x9D', '\xD7', '\xA1', '\xD7', '\xA6', /* בטכםסצ */ '\0', - '\xD1', '\x85', '\xD0', '\xBF', '\xD0', '\xBD', '\xD1', '\x88', '\xD0', '\xB5', '\xD0', '\xB7', '\xD0', '\xBE', '\xD1', '\x81', /* хпншезос */ + '\xD7', '\xA7', '\xD7', '\x9A', '\xD7', '\x9F', '\xD7', '\xA3', '\xD7', '\xA5', /* קךןףץ */ '\0', - '\xD1', '\x80', '\xD1', '\x83', '\xD1', '\x84', /* руф */ + 'T', 'H', 'E', 'Z', 'O', 'C', 'Q', 'S', /* THEZOCQS */ '\0', - '\xD7', '\x91', '\xD7', '\x93', '\xD7', '\x94', '\xD7', '\x97', '\xD7', '\x9A', '\xD7', '\x9B', '\xD7', '\x9D', '\xD7', '\xA1', /* בדהחךכםס */ + 'H', 'E', 'Z', 'L', 'O', 'C', 'U', 'S', /* HEZLOCUS */ '\0', - '\xD7', '\x91', '\xD7', '\x98', '\xD7', '\x9B', '\xD7', '\x9D', '\xD7', '\xA1', '\xD7', '\xA6', /* בטכםסצ */ + 'f', 'i', 'j', 'k', 'd', 'b', 'h', /* fijkdbh */ '\0', - '\xD7', '\xA7', '\xD7', '\x9A', '\xD7', '\x9F', '\xD7', '\xA3', '\xD7', '\xA5', /* קךןףץ */ + 'x', 'z', 'r', 'o', 'e', 's', 'c', /* xzroesc */ + '\0', + 'p', 'q', 'g', 'j', 'y', /* pqgjy */ #ifdef AF_CONFIG_OPTION_CJK '\0', '\xE4', '\xBB', '\x96', '\xE4', '\xBB', '\xAC', '\xE4', '\xBD', '\xA0', '\xE4', '\xBE', '\x86', '\xE5', '\x80', '\x91', '\xE5', '\x88', '\xB0', '\xE5', '\x92', '\x8C', '\xE5', '\x9C', '\xB0', /* 他们你來們到和地 */ '\xE5', '\xAF', '\xB9', '\xE5', '\xB0', '\x8D', '\xE5', '\xB0', '\xB1', '\xE5', '\xB8', '\xAD', '\xE6', '\x88', '\x91', '\xE6', '\x97', '\xB6', '\xE6', '\x99', '\x82', '\xE6', '\x9C', '\x83', /* 对對就席我时時會 */ '\xE6', '\x9D', '\xA5', '\xE7', '\x82', '\xBA', '\xE8', '\x83', '\xBD', '\xE8', '\x88', '\xB0', '\xE8', '\xAA', '\xAA', '\xE8', '\xAF', '\xB4', '\xE8', '\xBF', '\x99', '\xE9', '\x80', '\x99', /* 来為能舰說说这這 */ - '\xE9', '\xBD', '\x8A', /* 齊 */ - '\0', + '\xE9', '\xBD', '\x8A', '|', /* 齊 | */ '\xE5', '\x86', '\x9B', '\xE5', '\x90', '\x8C', '\xE5', '\xB7', '\xB2', '\xE6', '\x84', '\xBF', '\xE6', '\x97', '\xA2', '\xE6', '\x98', '\x9F', '\xE6', '\x98', '\xAF', '\xE6', '\x99', '\xAF', /* 军同已愿既星是景 */ '\xE6', '\xB0', '\x91', '\xE7', '\x85', '\xA7', '\xE7', '\x8E', '\xB0', '\xE7', '\x8F', '\xBE', '\xE7', '\x90', '\x86', '\xE7', '\x94', '\xA8', '\xE7', '\xBD', '\xAE', '\xE8', '\xA6', '\x81', /* 民照现現理用置要 */ '\xE8', '\xBB', '\x8D', '\xE9', '\x82', '\xA3', '\xE9', '\x85', '\x8D', '\xE9', '\x87', '\x8C', '\xE9', '\x96', '\x8B', '\xE9', '\x9B', '\xB7', '\xE9', '\x9C', '\xB2', '\xE9', '\x9D', '\xA2', /* 軍那配里開雷露面 */ @@ -74,8 +81,7 @@ '\xE4', '\xB8', '\xAA', '\xE4', '\xB8', '\xBA', '\xE4', '\xBA', '\xBA', '\xE4', '\xBB', '\x96', '\xE4', '\xBB', '\xA5', '\xE4', '\xBB', '\xAC', '\xE4', '\xBD', '\xA0', '\xE4', '\xBE', '\x86', /* 个为人他以们你來 */ '\xE5', '\x80', '\x8B', '\xE5', '\x80', '\x91', '\xE5', '\x88', '\xB0', '\xE5', '\x92', '\x8C', '\xE5', '\xA4', '\xA7', '\xE5', '\xAF', '\xB9', '\xE5', '\xB0', '\x8D', '\xE5', '\xB0', '\xB1', /* 個們到和大对對就 */ '\xE6', '\x88', '\x91', '\xE6', '\x97', '\xB6', '\xE6', '\x99', '\x82', '\xE6', '\x9C', '\x89', '\xE6', '\x9D', '\xA5', '\xE7', '\x82', '\xBA', '\xE8', '\xA6', '\x81', '\xE8', '\xAA', '\xAA', /* 我时時有来為要說 */ - '\xE8', '\xAF', '\xB4', /* 说 */ - '\0', + '\xE8', '\xAF', '\xB4', '|', /* 说 | */ '\xE4', '\xB8', '\xBB', '\xE4', '\xBA', '\x9B', '\xE5', '\x9B', '\xA0', '\xE5', '\xAE', '\x83', '\xE6', '\x83', '\xB3', '\xE6', '\x84', '\x8F', '\xE7', '\x90', '\x86', '\xE7', '\x94', '\x9F', /* 主些因它想意理生 */ '\xE7', '\x95', '\xB6', '\xE7', '\x9C', '\x8B', '\xE7', '\x9D', '\x80', '\xE7', '\xBD', '\xAE', '\xE8', '\x80', '\x85', '\xE8', '\x87', '\xAA', '\xE8', '\x91', '\x97', '\xE8', '\xA3', '\xA1', /* 當看着置者自著裡 */ '\xE8', '\xBF', '\x87', '\xE8', '\xBF', '\x98', '\xE8', '\xBF', '\x9B', '\xE9', '\x80', '\xB2', '\xE9', '\x81', '\x8E', '\xE9', '\x81', '\x93', '\xE9', '\x82', '\x84', '\xE9', '\x87', '\x8C', /* 过还进進過道還里 */ @@ -85,8 +91,7 @@ '\xE4', '\xBA', '\x9B', '\xE4', '\xBB', '\xAC', '\xE4', '\xBD', '\xA0', '\xE4', '\xBE', '\x86', '\xE5', '\x80', '\x91', '\xE5', '\x88', '\xB0', '\xE5', '\x92', '\x8C', '\xE5', '\x9C', '\xB0', /* 些们你來們到和地 */ '\xE5', '\xA5', '\xB9', '\xE5', '\xB0', '\x86', '\xE5', '\xB0', '\x87', '\xE5', '\xB0', '\xB1', '\xE5', '\xB9', '\xB4', '\xE5', '\xBE', '\x97', '\xE6', '\x83', '\x85', '\xE6', '\x9C', '\x80', /* 她将將就年得情最 */ '\xE6', '\xA0', '\xB7', '\xE6', '\xA8', '\xA3', '\xE7', '\x90', '\x86', '\xE8', '\x83', '\xBD', '\xE8', '\xAA', '\xAA', '\xE8', '\xAF', '\xB4', '\xE8', '\xBF', '\x99', '\xE9', '\x80', '\x99', /* 样樣理能說说这這 */ - '\xE9', '\x80', '\x9A', /* 通 */ - '\0', + '\xE9', '\x80', '\x9A', '|', /* 通 | */ '\xE5', '\x8D', '\xB3', '\xE5', '\x90', '\x97', '\xE5', '\x90', '\xA7', '\xE5', '\x90', '\xAC', '\xE5', '\x91', '\xA2', '\xE5', '\x93', '\x81', '\xE5', '\x93', '\x8D', '\xE5', '\x97', '\x8E', /* 即吗吧听呢品响嗎 */ '\xE5', '\xB8', '\x88', '\xE5', '\xB8', '\xAB', '\xE6', '\x94', '\xB6', '\xE6', '\x96', '\xAD', '\xE6', '\x96', '\xB7', '\xE6', '\x98', '\x8E', '\xE7', '\x9C', '\xBC', '\xE9', '\x96', '\x93', /* 师師收断斷明眼間 */ '\xE9', '\x97', '\xB4', '\xE9', '\x99', '\x85', '\xE9', '\x99', '\x88', '\xE9', '\x99', '\x90', '\xE9', '\x99', '\xA4', '\xE9', '\x99', '\xB3', '\xE9', '\x9A', '\x8F', '\xE9', '\x9A', '\x9B', /* 间际陈限除陳随際 */ @@ -95,8 +100,7 @@ '\xE4', '\xBA', '\x8B', '\xE5', '\x89', '\x8D', '\xE5', '\xAD', '\xB8', '\xE5', '\xB0', '\x86', '\xE5', '\xB0', '\x87', '\xE6', '\x83', '\x85', '\xE6', '\x83', '\xB3', '\xE6', '\x88', '\x96', /* 事前學将將情想或 */ '\xE6', '\x94', '\xBF', '\xE6', '\x96', '\xAF', '\xE6', '\x96', '\xB0', '\xE6', '\xA0', '\xB7', '\xE6', '\xA8', '\xA3', '\xE6', '\xB0', '\x91', '\xE6', '\xB2', '\x92', '\xE6', '\xB2', '\xA1', /* 政斯新样樣民沒没 */ '\xE7', '\x84', '\xB6', '\xE7', '\x89', '\xB9', '\xE7', '\x8E', '\xB0', '\xE7', '\x8F', '\xBE', '\xE7', '\x90', '\x83', '\xE7', '\xAC', '\xAC', '\xE7', '\xB6', '\x93', '\xE8', '\xB0', '\x81', /* 然特现現球第經谁 */ - '\xE8', '\xB5', '\xB7', /* 起 */ - '\0', + '\xE8', '\xB5', '\xB7', '|', /* 起 | */ '\xE4', '\xBE', '\x8B', '\xE5', '\x88', '\xA5', '\xE5', '\x88', '\xAB', '\xE5', '\x88', '\xB6', '\xE5', '\x8A', '\xA8', '\xE5', '\x8B', '\x95', '\xE5', '\x90', '\x97', '\xE5', '\x97', '\x8E', /* 例別别制动動吗嗎 */ '\xE5', '\xA2', '\x9E', '\xE6', '\x8C', '\x87', '\xE6', '\x98', '\x8E', '\xE6', '\x9C', '\x9D', '\xE6', '\x9C', '\x9F', '\xE6', '\x9E', '\x84', '\xE7', '\x89', '\xA9', '\xE7', '\xA1', '\xAE', /* 增指明朝期构物确 */ '\xE7', '\xA7', '\x8D', '\xE8', '\xAA', '\xBF', '\xE8', '\xB0', '\x83', '\xE8', '\xB2', '\xBB', '\xE8', '\xB4', '\xB9', '\xE9', '\x82', '\xA3', '\xE9', '\x83', '\xBD', '\xE9', '\x96', '\x93', /* 种調调費费那都間 */ @@ -113,14 +117,21 @@ af_blue_stringsets[] = { /* */ - { AF_BLUE_STRING_LATIN_CAPITAL_TOP, AF_BLUE_PROPERTY_LATIN_TOP }, - { AF_BLUE_STRING_LATIN_CAPITAL_BOTTOM, 0 }, - { AF_BLUE_STRING_LATIN_SMALL_F_TOP, AF_BLUE_PROPERTY_LATIN_TOP }, - { AF_BLUE_STRING_LATIN_SMALL, AF_BLUE_PROPERTY_LATIN_TOP | - AF_BLUE_PROPERTY_LATIN_X_HEIGHT }, - { AF_BLUE_STRING_LATIN_SMALL, 0 }, - { AF_BLUE_STRING_LATIN_SMALL_DESCENDER, 0 }, - { AF_BLUE_STRING_MAX, 0 }, + { AF_BLUE_STRING_CYRILLIC_CAPITAL_TOP, AF_BLUE_PROPERTY_LATIN_TOP }, + { AF_BLUE_STRING_CYRILLIC_CAPITAL_BOTTOM, 0 }, + { AF_BLUE_STRING_CYRILLIC_SMALL, AF_BLUE_PROPERTY_LATIN_TOP | + AF_BLUE_PROPERTY_LATIN_X_HEIGHT }, + { AF_BLUE_STRING_CYRILLIC_SMALL, 0 }, + { AF_BLUE_STRING_CYRILLIC_SMALL_DESCENDER, 0 }, + { AF_BLUE_STRING_MAX, 0 }, + { AF_BLUE_STRING_DEVANAGARI_TOP, AF_BLUE_PROPERTY_LATIN_TOP }, + { AF_BLUE_STRING_DEVANAGARI_HEAD, AF_BLUE_PROPERTY_LATIN_TOP }, + { AF_BLUE_STRING_DEVANAGARI_BASE, AF_BLUE_PROPERTY_LATIN_TOP | + AF_BLUE_PROPERTY_LATIN_NEUTRAL | + AF_BLUE_PROPERTY_LATIN_X_HEIGHT }, + { AF_BLUE_STRING_DEVANAGARI_BASE, 0 }, + { AF_BLUE_STRING_DEVANAGARI_BOTTOM, 0 }, + { AF_BLUE_STRING_MAX, 0 }, { AF_BLUE_STRING_GREEK_CAPITAL_TOP, AF_BLUE_PROPERTY_LATIN_TOP }, { AF_BLUE_STRING_GREEK_CAPITAL_BOTTOM, 0 }, { AF_BLUE_STRING_GREEK_SMALL_BETA_TOP, AF_BLUE_PROPERTY_LATIN_TOP }, @@ -129,35 +140,28 @@ { AF_BLUE_STRING_GREEK_SMALL, 0 }, { AF_BLUE_STRING_GREEK_SMALL_DESCENDER, 0 }, { AF_BLUE_STRING_MAX, 0 }, - { AF_BLUE_STRING_CYRILLIC_CAPITAL_TOP, AF_BLUE_PROPERTY_LATIN_TOP }, - { AF_BLUE_STRING_CYRILLIC_CAPITAL_BOTTOM, 0 }, - { AF_BLUE_STRING_CYRILLIC_SMALL, AF_BLUE_PROPERTY_LATIN_TOP | - AF_BLUE_PROPERTY_LATIN_X_HEIGHT }, - { AF_BLUE_STRING_CYRILLIC_SMALL, 0 }, - { AF_BLUE_STRING_CYRILLIC_SMALL_DESCENDER, 0 }, - { AF_BLUE_STRING_MAX, 0 }, { AF_BLUE_STRING_HEBREW_TOP, AF_BLUE_PROPERTY_LATIN_TOP | AF_BLUE_PROPERTY_LATIN_LONG }, { AF_BLUE_STRING_HEBREW_BOTTOM, 0 }, { AF_BLUE_STRING_HEBREW_DESCENDER, 0 }, { AF_BLUE_STRING_MAX, 0 }, + { AF_BLUE_STRING_LATIN_CAPITAL_TOP, AF_BLUE_PROPERTY_LATIN_TOP }, + { AF_BLUE_STRING_LATIN_CAPITAL_BOTTOM, 0 }, + { AF_BLUE_STRING_LATIN_SMALL_F_TOP, AF_BLUE_PROPERTY_LATIN_TOP }, + { AF_BLUE_STRING_LATIN_SMALL, AF_BLUE_PROPERTY_LATIN_TOP | + AF_BLUE_PROPERTY_LATIN_X_HEIGHT }, + { AF_BLUE_STRING_LATIN_SMALL, 0 }, + { AF_BLUE_STRING_LATIN_SMALL_DESCENDER, 0 }, + { AF_BLUE_STRING_MAX, 0 }, #ifdef AF_CONFIG_OPTION_CJK - { AF_BLUE_STRING_CJK_TOP_FILL, AF_BLUE_PROPERTY_CJK_TOP | - AF_BLUE_PROPERTY_CJK_FILL }, - { AF_BLUE_STRING_CJK_TOP_UNFILL, AF_BLUE_PROPERTY_CJK_TOP }, - { AF_BLUE_STRING_CJK_BOTTOM_FILL, AF_BLUE_PROPERTY_CJK_FILL }, - { AF_BLUE_STRING_CJK_BOTTOM_UNFILL, 0 }, + { AF_BLUE_STRING_CJK_TOP, AF_BLUE_PROPERTY_CJK_TOP }, + { AF_BLUE_STRING_CJK_BOTTOM, 0 }, #ifdef AF_CONFIG_OPTION_CJK_BLUE_HANI_VERT - { AF_BLUE_STRING_CJK_LEFT_FILL, AF_BLUE_PROPERTY_CJK_HORIZ | - AF_BLUE_PROPERTY_CJK_FILL }, - { AF_BLUE_STRING_CJK_LEFT_UNFILL, AF_BLUE_PROPERTY_CJK_HORIZ }, - { AF_BLUE_STRING_CJK_RIGHT_FILL, AF_BLUE_PROPERTY_CJK_HORIZ | - AF_BLUE_PROPERTY_CJK_RIGHT | - AF_BLUE_PROPERTY_CJK_FILL }, - { AF_BLUE_STRING_CJK_RIGHT_UNFILL, AF_BLUE_PROPERTY_CJK_HORIZ | - AF_BLUE_PROPERTY_CJK_RIGHT }, + { AF_BLUE_STRING_CJK_LEFT, AF_BLUE_PROPERTY_CJK_HORIZ }, + { AF_BLUE_STRING_CJK_RIGHT, AF_BLUE_PROPERTY_CJK_HORIZ | + AF_BLUE_PROPERTY_CJK_RIGHT }, #endif /* AF_CONFIG_OPTION_CJK_BLUE_HANI_VERT */ - { AF_BLUE_STRING_MAX, 0 }, + { AF_BLUE_STRING_MAX, 0 }, #endif /* AF_CONFIG_OPTION_CJK */ }; diff --git a/src/autofit/afblue.dat b/src/autofit/afblue.dat index d488f3f..74a472d 100644 --- a/src/autofit/afblue.dat +++ b/src/autofit/afblue.dat @@ -2,7 +2,7 @@ // // Auto-fitter data for blue strings. // -// Copyright 2013 by +// Copyright 2013, 2014 by // David Turner, Robert Wilhelm, and Werner Lemberg. // // This file is part of the FreeType project, and may only be used, @@ -34,11 +34,11 @@ // using C syntax. There can be only one string per line, thus the // starting and ending double quote must be the first and last character // in the line, respectively, ignoring whitespace before and after the -// string. If there are multiple strings (in multiple lines), they are -// concatenated to a single string. In the output, a string gets -// represented as a series of singles bytes, followed by a zero byte. The -// enumeration values simply hold byte offsets to the start of the -// corresponding strings. +// string. Space characters within the string are ignored too. If there +// are multiple strings (in multiple lines), they are concatenated to a +// single string. In the output, a string gets represented as a series of +// singles bytes, followed by a zero byte. The enumeration values simply +// hold byte offsets to the start of the corresponding strings. // // - Data blocks enclosed in balanced braces, which get copied verbatim and // which can span multiple lines. The opening brace of a block must be @@ -63,18 +63,32 @@ // characters, not bytes. +// The blue zone string data, to be used in the blue stringsets below. + AF_BLUE_STRING_ENUM AF_BLUE_STRINGS_ARRAY AF_BLUE_STRING_MAX_LEN: - AF_BLUE_STRING_LATIN_CAPITAL_TOP - "THEZOCQS" - AF_BLUE_STRING_LATIN_CAPITAL_BOTTOM - "HEZLOCUS" - AF_BLUE_STRING_LATIN_SMALL_F_TOP - "fijkdbh" - AF_BLUE_STRING_LATIN_SMALL - "xzroesc" - AF_BLUE_STRING_LATIN_SMALL_DESCENDER - "pqgjy" + AF_BLUE_STRING_CYRILLIC_CAPITAL_TOP + "БВЕПЗОСЭ" + AF_BLUE_STRING_CYRILLIC_CAPITAL_BOTTOM + "БВЕШЗОСЭ" + AF_BLUE_STRING_CYRILLIC_SMALL + "хпншезос" + AF_BLUE_STRING_CYRILLIC_SMALL_DESCENDER + "руф" + + // we separate the letters with spaces to avoid ligatures; + // this is just for convenience to simplify reading + AF_BLUE_STRING_DEVANAGARI_BASE + "क म अ आ थ ध भ श" + AF_BLUE_STRING_DEVANAGARI_TOP + "ई ऐ ओ औ ि ी ो ौ" + // note that some fonts have extreme variation in the height of the + // round head elements; for this reason we also define the `base' + // blue zone, which must be always present + AF_BLUE_STRING_DEVANAGARI_HEAD + "क म अ आ थ ध भ श" + AF_BLUE_STRING_DEVANAGARI_BOTTOM + "ु ृ" AF_BLUE_STRING_GREEK_CAPITAL_TOP "ΓΒΕΖΘΟΩ" @@ -87,15 +101,6 @@ AF_BLUE_STRING_ENUM AF_BLUE_STRINGS_ARRAY AF_BLUE_STRING_MAX_LEN: AF_BLUE_STRING_GREEK_SMALL_DESCENDER "βγημρφχψ" - AF_BLUE_STRING_CYRILLIC_CAPITAL_TOP - "БВЕПЗОСЭ" - AF_BLUE_STRING_CYRILLIC_CAPITAL_BOTTOM - "БВЕШЗОСЭ" - AF_BLUE_STRING_CYRILLIC_SMALL - "хпншезос" - AF_BLUE_STRING_CYRILLIC_SMALL_DESCENDER - "руф" - AF_BLUE_STRING_HEBREW_TOP "בדהחךכםס" AF_BLUE_STRING_HEBREW_BOTTOM @@ -103,24 +108,33 @@ AF_BLUE_STRING_ENUM AF_BLUE_STRINGS_ARRAY AF_BLUE_STRING_MAX_LEN: AF_BLUE_STRING_HEBREW_DESCENDER "קךןףץ" + AF_BLUE_STRING_LATIN_CAPITAL_TOP + "THEZOCQS" + AF_BLUE_STRING_LATIN_CAPITAL_BOTTOM + "HEZLOCUS" + AF_BLUE_STRING_LATIN_SMALL_F_TOP + "fijkdbh" + AF_BLUE_STRING_LATIN_SMALL + "xzroesc" + AF_BLUE_STRING_LATIN_SMALL_DESCENDER + "pqgjy" + #ifdef AF_CONFIG_OPTION_CJK - AF_BLUE_STRING_CJK_TOP_FILL + AF_BLUE_STRING_CJK_TOP "他们你來們到和地" "对對就席我时時會" "来為能舰說说这這" - "齊" - AF_BLUE_STRING_CJK_TOP_UNFILL + "齊 |" "军同已愿既星是景" "民照现現理用置要" "軍那配里開雷露面" "顾" - AF_BLUE_STRING_CJK_BOTTOM_FILL + AF_BLUE_STRING_CJK_BOTTOM "个为人他以们你來" "個們到和大对對就" "我时時有来為要說" - "说" - AF_BLUE_STRING_CJK_BOTTOM_UNFILL + "说 |" "主些因它想意理生" "當看着置者自著裡" "过还进進過道還里" @@ -128,22 +142,20 @@ AF_BLUE_STRING_ENUM AF_BLUE_STRINGS_ARRAY AF_BLUE_STRING_MAX_LEN: #ifdef AF_CONFIG_OPTION_CJK_BLUE_HANI_VERT - AF_BLUE_STRING_CJK_LEFT_FILL + AF_BLUE_STRING_CJK_LEFT "些们你來們到和地" "她将將就年得情最" "样樣理能說说这這" - "通" - AF_BLUE_STRING_CJK_LEFT_UNFILL + "通 |" "即吗吧听呢品响嗎" "师師收断斷明眼間" "间际陈限除陳随際" "隨" - AF_BLUE_STRING_CJK_RIGHT_FILL + AF_BLUE_STRING_CJK_RIGHT "事前學将將情想或" "政斯新样樣民沒没" "然特现現球第經谁" - "起" - AF_BLUE_STRING_CJK_RIGHT_UNFILL + "起 |" "例別别制动動吗嗎" "增指明朝期构物确" "种調调費费那都間" @@ -154,17 +166,118 @@ AF_BLUE_STRING_ENUM AF_BLUE_STRINGS_ARRAY AF_BLUE_STRING_MAX_LEN: #endif /* AF_CONFIG_OPTION_CJK */ +// The blue zone stringsets, as used in the script styles, cf. `afstyles.h'. +// +// The AF_BLUE_PROPERTY_XXX flags are defined in `afblue.h'; here some +// explanations. +// +// A blue zone in general is defined by a reference and an overshoot line. +// During the hinting process, all coordinate values between those two lines +// are set equal to the reference value, provided that the blue zone is not +// wider than 0.75 pixels (otherwise the blue zone gets ignored). All +// entries must have `AF_BLUE_STRING_MAX' as the final line. +// +// During the glyph analysis, edges are sorted from bottom to top, and then +// sequentially checked, edge by edge, against the blue zones in the order +// given below. +// +// +// latin auto-hinter +// ----------------- +// +// Characters in a blue string are automatically classified as having a flat +// (reference) or a round (overshoot) extremum. The blue zone is then set +// up by the mean values of all flat extrema and all round extrema, +// respectively. Only horizontal blue zones (i.e., adjusting vertical +// coordinate values) are supported. +// +// For the latin auto-hinter, the overshoot should be larger than the +// reference for top zones, and vice versa for bottom zones. +// +// LATIN_TOP +// Take the maximum flat and round coordinate values of the blue string +// characters for computing the blue zone's reference and overshoot +// values. +// +// If not set, take the minimum values. +// +// LATIN_NEUTRAL +// Ignore round extrema and define the blue zone with flat values only. +// Both top and bottom of contours can match. This is useful for +// scripts like Devanagari where vowel signs attach to the base +// character and are implemented as components of composite glyphs. +// +// If not set, both round and flat extrema are taken into account. +// Additionally, only the top or the bottom of a contour can match, +// depending on the LATIN_TOP flag. +// +// Neutral blue zones should always follow non-neutral blue zones. +// +// LATIN_X_HEIGHT +// Scale all glyphs vertically from the corresponding script to make the +// reference line of this blue zone align on the grid. The scaling +// takes place before all other blue zones get aligned to the grid. +// Only one blue character string of a script style can have this flag. +// +// LATIN_LONG +// Apply an additional constraint for blue zone values: Don't +// necessarily use the extremum as-is but a segment of the topmost (or +// bottommost) contour that is longer than a heuristic threshold, and +// which is not too far away vertically from the real extremum. This +// ensures that small bumps in the outline are ignored (for example, the +// `vertical serifs' found in many Hebrew glyph designs). +// +// The segment must be at least EM/25 font units long, and the distance +// to the extremum must be smaller than EM/4. +// +// +// cjk auto-hinter +// --------------- +// +// Characters in a blue string are *not* automatically classified. Instead, +// first come the characters used for the overshoot value, then the +// character `|', then the characters used for the reference value. The +// blue zone is then set up by the mean values of all reference values and +// all overshoot values, respectively. Both horizontal and vertical blue +// zones (i.e., adjusting vertical and horizontal coordinate values, +// respectively) are supported. +// +// For the cjk auto-hinter, the overshoot should be smaller than the +// reference for top zones, and vice versa for bottom zones. +// +// CJK_TOP +// Take the maximum flat and round coordinate values of the blue string +// characters. If not set, take the minimum values. +// +// CJK_RIGHT +// A synonym for CJK_TOP. If CJK_HORIZ is set, this flag indicates the +// right blue zone, taking horizontal maximum values. +// +// CJK_HORIZ +// Define a blue zone for horizontal hinting (i.e., vertical blue +// zones). If not set, this is a blue zone for vertical hinting. + + AF_BLUE_STRINGSET_ENUM AF_BLUE_STRINGSETS_ARRAY AF_BLUE_STRINGSET_MAX_LEN: - AF_BLUE_STRINGSET_LATN - { AF_BLUE_STRING_LATIN_CAPITAL_TOP, AF_BLUE_PROPERTY_LATIN_TOP } - { AF_BLUE_STRING_LATIN_CAPITAL_BOTTOM, 0 } - { AF_BLUE_STRING_LATIN_SMALL_F_TOP, AF_BLUE_PROPERTY_LATIN_TOP } - { AF_BLUE_STRING_LATIN_SMALL, AF_BLUE_PROPERTY_LATIN_TOP | - AF_BLUE_PROPERTY_LATIN_X_HEIGHT } - { AF_BLUE_STRING_LATIN_SMALL, 0 } - { AF_BLUE_STRING_LATIN_SMALL_DESCENDER, 0 } - { AF_BLUE_STRING_MAX, 0 } + AF_BLUE_STRINGSET_CYRL + { AF_BLUE_STRING_CYRILLIC_CAPITAL_TOP, AF_BLUE_PROPERTY_LATIN_TOP } + { AF_BLUE_STRING_CYRILLIC_CAPITAL_BOTTOM, 0 } + { AF_BLUE_STRING_CYRILLIC_SMALL, AF_BLUE_PROPERTY_LATIN_TOP | + AF_BLUE_PROPERTY_LATIN_X_HEIGHT } + { AF_BLUE_STRING_CYRILLIC_SMALL, 0 } + { AF_BLUE_STRING_CYRILLIC_SMALL_DESCENDER, 0 } + { AF_BLUE_STRING_MAX, 0 } + + AF_BLUE_STRINGSET_DEVA + { AF_BLUE_STRING_DEVANAGARI_TOP, AF_BLUE_PROPERTY_LATIN_TOP } + { AF_BLUE_STRING_DEVANAGARI_HEAD, AF_BLUE_PROPERTY_LATIN_TOP } + { AF_BLUE_STRING_DEVANAGARI_BASE, AF_BLUE_PROPERTY_LATIN_TOP | + AF_BLUE_PROPERTY_LATIN_NEUTRAL | + AF_BLUE_PROPERTY_LATIN_X_HEIGHT } + { AF_BLUE_STRING_DEVANAGARI_BASE, 0 } + { AF_BLUE_STRING_DEVANAGARI_BOTTOM, 0 } + { AF_BLUE_STRING_MAX, 0 } AF_BLUE_STRINGSET_GREK { AF_BLUE_STRING_GREEK_CAPITAL_TOP, AF_BLUE_PROPERTY_LATIN_TOP } @@ -176,15 +289,6 @@ AF_BLUE_STRINGSET_ENUM AF_BLUE_STRINGSETS_ARRAY AF_BLUE_STRINGSET_MAX_LEN: { AF_BLUE_STRING_GREEK_SMALL_DESCENDER, 0 } { AF_BLUE_STRING_MAX, 0 } - AF_BLUE_STRINGSET_CYRL - { AF_BLUE_STRING_CYRILLIC_CAPITAL_TOP, AF_BLUE_PROPERTY_LATIN_TOP } - { AF_BLUE_STRING_CYRILLIC_CAPITAL_BOTTOM, 0 } - { AF_BLUE_STRING_CYRILLIC_SMALL, AF_BLUE_PROPERTY_LATIN_TOP | - AF_BLUE_PROPERTY_LATIN_X_HEIGHT } - { AF_BLUE_STRING_CYRILLIC_SMALL, 0 } - { AF_BLUE_STRING_CYRILLIC_SMALL_DESCENDER, 0 } - { AF_BLUE_STRING_MAX, 0 } - AF_BLUE_STRINGSET_HEBR { AF_BLUE_STRING_HEBREW_TOP, AF_BLUE_PROPERTY_LATIN_TOP | AF_BLUE_PROPERTY_LATIN_LONG } @@ -192,25 +296,27 @@ AF_BLUE_STRINGSET_ENUM AF_BLUE_STRINGSETS_ARRAY AF_BLUE_STRINGSET_MAX_LEN: { AF_BLUE_STRING_HEBREW_DESCENDER, 0 } { AF_BLUE_STRING_MAX, 0 } + AF_BLUE_STRINGSET_LATN + { AF_BLUE_STRING_LATIN_CAPITAL_TOP, AF_BLUE_PROPERTY_LATIN_TOP } + { AF_BLUE_STRING_LATIN_CAPITAL_BOTTOM, 0 } + { AF_BLUE_STRING_LATIN_SMALL_F_TOP, AF_BLUE_PROPERTY_LATIN_TOP } + { AF_BLUE_STRING_LATIN_SMALL, AF_BLUE_PROPERTY_LATIN_TOP | + AF_BLUE_PROPERTY_LATIN_X_HEIGHT } + { AF_BLUE_STRING_LATIN_SMALL, 0 } + { AF_BLUE_STRING_LATIN_SMALL_DESCENDER, 0 } + { AF_BLUE_STRING_MAX, 0 } + #ifdef AF_CONFIG_OPTION_CJK AF_BLUE_STRINGSET_HANI - { AF_BLUE_STRING_CJK_TOP_FILL, AF_BLUE_PROPERTY_CJK_TOP | - AF_BLUE_PROPERTY_CJK_FILL } - { AF_BLUE_STRING_CJK_TOP_UNFILL, AF_BLUE_PROPERTY_CJK_TOP } - { AF_BLUE_STRING_CJK_BOTTOM_FILL, AF_BLUE_PROPERTY_CJK_FILL } - { AF_BLUE_STRING_CJK_BOTTOM_UNFILL, 0 } + { AF_BLUE_STRING_CJK_TOP, AF_BLUE_PROPERTY_CJK_TOP } + { AF_BLUE_STRING_CJK_BOTTOM, 0 } #ifdef AF_CONFIG_OPTION_CJK_BLUE_HANI_VERT - { AF_BLUE_STRING_CJK_LEFT_FILL, AF_BLUE_PROPERTY_CJK_HORIZ | - AF_BLUE_PROPERTY_CJK_FILL } - { AF_BLUE_STRING_CJK_LEFT_UNFILL, AF_BLUE_PROPERTY_CJK_HORIZ } - { AF_BLUE_STRING_CJK_RIGHT_FILL, AF_BLUE_PROPERTY_CJK_HORIZ | - AF_BLUE_PROPERTY_CJK_RIGHT | - AF_BLUE_PROPERTY_CJK_FILL } - { AF_BLUE_STRING_CJK_RIGHT_UNFILL, AF_BLUE_PROPERTY_CJK_HORIZ | - AF_BLUE_PROPERTY_CJK_RIGHT } + { AF_BLUE_STRING_CJK_LEFT, AF_BLUE_PROPERTY_CJK_HORIZ } + { AF_BLUE_STRING_CJK_RIGHT, AF_BLUE_PROPERTY_CJK_HORIZ | + AF_BLUE_PROPERTY_CJK_RIGHT } #endif /* AF_CONFIG_OPTION_CJK_BLUE_HANI_VERT */ - { AF_BLUE_STRING_MAX, 0 } + { AF_BLUE_STRING_MAX, 0 } #endif /* AF_CONFIG_OPTION_CJK */ diff --git a/src/autofit/afblue.h b/src/autofit/afblue.h index 6f336ab..d239e8e 100644 --- a/src/autofit/afblue.h +++ b/src/autofit/afblue.h @@ -7,7 +7,7 @@ /* */ /* Auto-fitter data for blue strings (specification). */ /* */ -/* Copyright 2013 by */ +/* Copyright 2013, 2014 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -67,42 +67,42 @@ FT_BEGIN_HEADER /* At the bottommost level, we define strings for finding blue zones. */ -#define AF_BLUE_STRING_MAX_LEN 25 +#define AF_BLUE_STRING_MAX_LEN 51 /* The AF_Blue_String enumeration values are offsets into the */ /* `af_blue_strings' array. */ typedef enum AF_Blue_String_ { - AF_BLUE_STRING_LATIN_CAPITAL_TOP = 0, - AF_BLUE_STRING_LATIN_CAPITAL_BOTTOM = 9, - AF_BLUE_STRING_LATIN_SMALL_F_TOP = 18, - AF_BLUE_STRING_LATIN_SMALL = 26, - AF_BLUE_STRING_LATIN_SMALL_DESCENDER = 34, - AF_BLUE_STRING_GREEK_CAPITAL_TOP = 40, - AF_BLUE_STRING_GREEK_CAPITAL_BOTTOM = 55, - AF_BLUE_STRING_GREEK_SMALL_BETA_TOP = 68, - AF_BLUE_STRING_GREEK_SMALL = 81, - AF_BLUE_STRING_GREEK_SMALL_DESCENDER = 98, - AF_BLUE_STRING_CYRILLIC_CAPITAL_TOP = 115, - AF_BLUE_STRING_CYRILLIC_CAPITAL_BOTTOM = 132, - AF_BLUE_STRING_CYRILLIC_SMALL = 149, - AF_BLUE_STRING_CYRILLIC_SMALL_DESCENDER = 166, - AF_BLUE_STRING_HEBREW_TOP = 173, - AF_BLUE_STRING_HEBREW_BOTTOM = 190, - AF_BLUE_STRING_HEBREW_DESCENDER = 203, - af_blue_1_1 = 213, + AF_BLUE_STRING_CYRILLIC_CAPITAL_TOP = 0, + AF_BLUE_STRING_CYRILLIC_CAPITAL_BOTTOM = 17, + AF_BLUE_STRING_CYRILLIC_SMALL = 34, + AF_BLUE_STRING_CYRILLIC_SMALL_DESCENDER = 51, + AF_BLUE_STRING_DEVANAGARI_BASE = 58, + AF_BLUE_STRING_DEVANAGARI_TOP = 83, + AF_BLUE_STRING_DEVANAGARI_HEAD = 108, + AF_BLUE_STRING_DEVANAGARI_BOTTOM = 133, + AF_BLUE_STRING_GREEK_CAPITAL_TOP = 140, + AF_BLUE_STRING_GREEK_CAPITAL_BOTTOM = 155, + AF_BLUE_STRING_GREEK_SMALL_BETA_TOP = 168, + AF_BLUE_STRING_GREEK_SMALL = 181, + AF_BLUE_STRING_GREEK_SMALL_DESCENDER = 198, + AF_BLUE_STRING_HEBREW_TOP = 215, + AF_BLUE_STRING_HEBREW_BOTTOM = 232, + AF_BLUE_STRING_HEBREW_DESCENDER = 245, + AF_BLUE_STRING_LATIN_CAPITAL_TOP = 256, + AF_BLUE_STRING_LATIN_CAPITAL_BOTTOM = 265, + AF_BLUE_STRING_LATIN_SMALL_F_TOP = 274, + AF_BLUE_STRING_LATIN_SMALL = 282, + AF_BLUE_STRING_LATIN_SMALL_DESCENDER = 290, + af_blue_1_1 = 295, #ifdef AF_CONFIG_OPTION_CJK - AF_BLUE_STRING_CJK_TOP_FILL = af_blue_1_1 + 1, - AF_BLUE_STRING_CJK_TOP_UNFILL = af_blue_1_1 + 77, - AF_BLUE_STRING_CJK_BOTTOM_FILL = af_blue_1_1 + 153, - AF_BLUE_STRING_CJK_BOTTOM_UNFILL = af_blue_1_1 + 229, + AF_BLUE_STRING_CJK_TOP = af_blue_1_1 + 1, + AF_BLUE_STRING_CJK_BOTTOM = af_blue_1_1 + 153, af_blue_1_1_1 = af_blue_1_1 + 304, #ifdef AF_CONFIG_OPTION_CJK_BLUE_HANI_VERT - AF_BLUE_STRING_CJK_LEFT_FILL = af_blue_1_1_1 + 1, - AF_BLUE_STRING_CJK_LEFT_UNFILL = af_blue_1_1_1 + 77, - AF_BLUE_STRING_CJK_RIGHT_FILL = af_blue_1_1_1 + 153, - AF_BLUE_STRING_CJK_RIGHT_UNFILL = af_blue_1_1_1 + 229, + AF_BLUE_STRING_CJK_LEFT = af_blue_1_1_1 + 1, + AF_BLUE_STRING_CJK_RIGHT = af_blue_1_1_1 + 153, af_blue_1_1_2 = af_blue_1_1_1 + 304, #else af_blue_1_1_2 = af_blue_1_1_1 + 0, @@ -136,33 +136,34 @@ FT_BEGIN_HEADER /* Properties are specific to a writing system. We assume that a given */ /* blue string can't be used in more than a single writing system, which */ /* is a safe bet. */ -#define AF_BLUE_PROPERTY_LATIN_TOP ( 1 << 0 ) -#define AF_BLUE_PROPERTY_LATIN_X_HEIGHT ( 1 << 1 ) -#define AF_BLUE_PROPERTY_LATIN_LONG ( 1 << 2 ) +#define AF_BLUE_PROPERTY_LATIN_TOP ( 1 << 0 ) /* must have value 1 */ +#define AF_BLUE_PROPERTY_LATIN_NEUTRAL ( 1 << 1 ) +#define AF_BLUE_PROPERTY_LATIN_X_HEIGHT ( 1 << 2 ) +#define AF_BLUE_PROPERTY_LATIN_LONG ( 1 << 3 ) -#define AF_BLUE_PROPERTY_CJK_HORIZ ( 1 << 0 ) -#define AF_BLUE_PROPERTY_CJK_TOP ( 1 << 1 ) -#define AF_BLUE_PROPERTY_CJK_FILL ( 1 << 2 ) +#define AF_BLUE_PROPERTY_CJK_TOP ( 1 << 0 ) /* must have value 1 */ +#define AF_BLUE_PROPERTY_CJK_HORIZ ( 1 << 1 ) /* must have value 2 */ #define AF_BLUE_PROPERTY_CJK_RIGHT AF_BLUE_PROPERTY_CJK_TOP -#define AF_BLUE_STRINGSET_MAX_LEN 9 +#define AF_BLUE_STRINGSET_MAX_LEN 7 /* The AF_Blue_Stringset enumeration values are offsets into the */ /* `af_blue_stringsets' array. */ typedef enum AF_Blue_Stringset_ { - AF_BLUE_STRINGSET_LATN = 0, - AF_BLUE_STRINGSET_GREK = 7, - AF_BLUE_STRINGSET_CYRL = 14, - AF_BLUE_STRINGSET_HEBR = 20, - af_blue_2_1 = 24, + AF_BLUE_STRINGSET_CYRL = 0, + AF_BLUE_STRINGSET_DEVA = 6, + AF_BLUE_STRINGSET_GREK = 12, + AF_BLUE_STRINGSET_HEBR = 19, + AF_BLUE_STRINGSET_LATN = 23, + af_blue_2_1 = 30, #ifdef AF_CONFIG_OPTION_CJK AF_BLUE_STRINGSET_HANI = af_blue_2_1 + 0, - af_blue_2_1_1 = af_blue_2_1 + 4, + af_blue_2_1_1 = af_blue_2_1 + 2, #ifdef AF_CONFIG_OPTION_CJK_BLUE_HANI_VERT - af_blue_2_1_2 = af_blue_2_1_1 + 4, + af_blue_2_1_2 = af_blue_2_1_1 + 2, #else af_blue_2_1_2 = af_blue_2_1_1 + 0, #endif /* AF_CONFIG_OPTION_CJK_BLUE_HANI_VERT */ diff --git a/src/autofit/afblue.hin b/src/autofit/afblue.hin index 4fc9917..0b4b48d 100644 --- a/src/autofit/afblue.hin +++ b/src/autofit/afblue.hin @@ -4,7 +4,7 @@ /* */ /* Auto-fitter data for blue strings (specification). */ /* */ -/* Copyright 2013 by */ +/* Copyright 2013, 2014 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -96,13 +96,13 @@ FT_BEGIN_HEADER /* Properties are specific to a writing system. We assume that a given */ /* blue string can't be used in more than a single writing system, which */ /* is a safe bet. */ -#define AF_BLUE_PROPERTY_LATIN_TOP ( 1 << 0 ) -#define AF_BLUE_PROPERTY_LATIN_X_HEIGHT ( 1 << 1 ) -#define AF_BLUE_PROPERTY_LATIN_LONG ( 1 << 2 ) +#define AF_BLUE_PROPERTY_LATIN_TOP ( 1 << 0 ) /* must have value 1 */ +#define AF_BLUE_PROPERTY_LATIN_NEUTRAL ( 1 << 1 ) +#define AF_BLUE_PROPERTY_LATIN_X_HEIGHT ( 1 << 2 ) +#define AF_BLUE_PROPERTY_LATIN_LONG ( 1 << 3 ) -#define AF_BLUE_PROPERTY_CJK_HORIZ ( 1 << 0 ) -#define AF_BLUE_PROPERTY_CJK_TOP ( 1 << 1 ) -#define AF_BLUE_PROPERTY_CJK_FILL ( 1 << 2 ) +#define AF_BLUE_PROPERTY_CJK_TOP ( 1 << 0 ) /* must have value 1 */ +#define AF_BLUE_PROPERTY_CJK_HORIZ ( 1 << 1 ) /* must have value 2 */ #define AF_BLUE_PROPERTY_CJK_RIGHT AF_BLUE_PROPERTY_CJK_TOP diff --git a/src/autofit/afcjk.c b/src/autofit/afcjk.c index 3a65fc5..048e0e7 100644 --- a/src/autofit/afcjk.c +++ b/src/autofit/afcjk.c @@ -4,7 +4,7 @@ /* */ /* Auto-fitter hinting routines for CJK writing system (body). */ /* */ -/* Copyright 2006-2013 by */ +/* Copyright 2006-2014 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -178,6 +178,8 @@ goto Exit; af_latin_hints_link_segments( hints, + 0, + NULL, (AF_Dimension)dim ); seg = axhints->segments; @@ -261,6 +263,8 @@ FT_Int num_fills; FT_Int num_flats; + FT_Bool fill; + AF_CJKBlue blue; FT_Error error; AF_CJKAxis axis; @@ -271,22 +275,6 @@ AF_Blue_Stringset bss = sc->blue_stringset; const AF_Blue_StringRec* bs = &af_blue_stringsets[bss]; -#ifdef FT_DEBUG_LEVEL_TRACE - FT_String* cjk_blue_name[4] = - { - (FT_String*)"bottom", /* -- , -- */ - (FT_String*)"top", /* -- , TOP */ - (FT_String*)"left", /* HORIZ, -- */ - (FT_String*)"right" /* HORIZ, TOP */ - }; - - FT_String* cjk_blue_type_name[2] = - { - (FT_String*)"unfilled", /* -- */ - (FT_String*)"filled" /* FILL */ - }; -#endif - /* we walk over the blue character strings as specified in the */ /* style's entry in the `af_blue_stringset' array, computing its */ @@ -308,15 +296,29 @@ else axis = &metrics->axis[AF_DIMENSION_VERT]; - FT_TRACE5(( "blue zone %d:\n", axis->blue_count )); +#ifdef FT_DEBUG_LEVEL_TRACE + { + FT_String* cjk_blue_name[4] = + { + (FT_String*)"bottom", /* -- , -- */ + (FT_String*)"top", /* -- , TOP */ + (FT_String*)"left", /* HORIZ, -- */ + (FT_String*)"right" /* HORIZ, TOP */ + }; + + + FT_TRACE5(( "blue zone %d (%s):\n", + axis->blue_count, + cjk_blue_name[AF_CJK_IS_HORIZ_BLUE( bs ) | + AF_CJK_IS_TOP_BLUE( bs ) ] )); + } +#endif /* FT_DEBUG_LEVEL_TRACE */ num_fills = 0; num_flats = 0; - FT_TRACE5(( " cjk blue %s/%s\n", - cjk_blue_name[AF_CJK_IS_HORIZ_BLUE( bs ) | - AF_CJK_IS_TOP_BLUE( bs ) ], - cjk_blue_type_name[!!AF_CJK_IS_FILLED_BLUE( bs )] )); + fill = 1; /* start with characters that define fill values */ + FT_TRACE5(( " [overshoot values]\n" )); while ( *p ) { @@ -330,6 +332,14 @@ GET_UTF8_CHAR( ch, p ); + /* switch to characters that define flat values */ + if ( ch == '|' ) + { + fill = 0; + FT_TRACE5(( " [reference values]\n" )); + continue; + } + /* load the character in the face -- skip unknown or empty ones */ af_get_char_index( &metrics->root, ch, &glyph_index, &y_offset ); if ( glyph_index == 0 ) @@ -417,7 +427,7 @@ FT_TRACE5(( " U+%04lX: best_pos = %5ld\n", ch, best_pos )); } - if ( AF_CJK_IS_FILLED_BLUE( bs ) ) + if ( fill ) fills[num_fills++] = best_pos; else flats[num_flats++] = best_pos; @@ -429,15 +439,15 @@ * we couldn't find a single glyph to compute this blue zone, * we will simply ignore it then */ - FT_TRACE5(( " empty\n" )); + FT_TRACE5(( " empty\n" )); continue; } - /* we have computed the contents of the `fill' and `flats' tables, */ - /* now determine the reference position of the blue zone -- */ - /* we simply take the median value after a simple sort */ - af_sort_pos( num_flats, flats ); + /* we have computed the contents of the `fill' and `flats' tables, */ + /* now determine the reference and overshoot position of the blue -- */ + /* we simply take the median value after a simple sort */ af_sort_pos( num_fills, fills ); + af_sort_pos( num_flats, flats ); blue = &axis->blues[axis->blue_count]; blue_ref = &blue->ref.org; @@ -476,7 +486,7 @@ *blue_ref = *blue_shoot = ( shoot + ref ) / 2; - FT_TRACE5(( " [overshoot smaller than reference," + FT_TRACE5(( " [reference smaller than overshoot," " taking mean value]\n" )); } } @@ -755,10 +765,6 @@ /* now compare each segment to the others */ for ( seg1 = segments; seg1 < segment_limit; seg1++ ) { - /* the fake segments are for metrics hinting only */ - if ( seg1->first == seg1->last ) - continue; - if ( seg1->dir != major_dir ) continue; @@ -1018,10 +1024,11 @@ edge->first = seg; edge->last = seg; + edge->dir = seg->dir; edge->fpos = seg->pos; - edge->opos = edge->pos = FT_MulFix( seg->pos, scale ); + edge->opos = FT_MulFix( seg->pos, scale ); + edge->pos = edge->opos; seg->edge_next = seg; - edge->dir = seg->dir; } else { @@ -1230,8 +1237,10 @@ /* zone, check for left edges */ /* */ /* of course, that's for TrueType */ - is_top_right_blue = FT_BOOL( blue->flags & AF_CJK_BLUE_TOP ); - is_major_dir = FT_BOOL( edge->dir == axis->major_dir ); + is_top_right_blue = + (FT_Byte)( ( blue->flags & AF_CJK_BLUE_TOP ) != 0 ); + is_major_dir = + FT_BOOL( edge->dir == axis->major_dir ); /* if it is a top zone, the edge must be against the major */ /* direction; if it is a bottom zone, it must be in the major */ @@ -1528,6 +1537,12 @@ stem_edge->pos = base_edge->pos + fitted_width; + + FT_TRACE5(( " CJKLINK: edge %d @%d (opos=%.2f) linked to %.2f," + " dist was %.2f, now %.2f\n", + stem_edge - hints->axis[dim].edges, stem_edge->fpos, + stem_edge->opos / 64.0, stem_edge->pos / 64.0, + dist / 64.0, fitted_width / 64.0 )); } diff --git a/src/autofit/afcjk.h b/src/autofit/afcjk.h index a260b09..4dd4f39 100644 --- a/src/autofit/afcjk.h +++ b/src/autofit/afcjk.h @@ -4,7 +4,7 @@ /* */ /* Auto-fitter hinting routines for CJK writing system (specification). */ /* */ -/* Copyright 2006, 2007, 2011-2013 by */ +/* Copyright 2006, 2007, 2011-2014 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -50,8 +50,6 @@ FT_BEGIN_HEADER ( (b)->properties & AF_BLUE_PROPERTY_CJK_TOP ) #define AF_CJK_IS_HORIZ_BLUE( b ) \ ( (b)->properties & AF_BLUE_PROPERTY_CJK_HORIZ ) -#define AF_CJK_IS_FILLED_BLUE( b ) \ - ( (b)->properties & AF_BLUE_PROPERTY_CJK_FILL ) #define AF_CJK_IS_RIGHT_BLUE AF_CJK_IS_TOP_BLUE #define AF_CJK_MAX_WIDTHS 16 diff --git a/src/autofit/afglobal.c b/src/autofit/afglobal.c index 7aa2e11..a54c20c 100644 --- a/src/autofit/afglobal.c +++ b/src/autofit/afglobal.c @@ -138,7 +138,7 @@ FT_Byte* gstyles = globals->glyph_styles; FT_UInt ss; FT_UInt i; - FT_UInt dflt = -1; + FT_UInt dflt = ~0U; /* a non-valid value */ /* the value AF_STYLE_UNASSIGNED means `uncovered glyph' */ @@ -176,7 +176,8 @@ */ if ( style_class->coverage == AF_COVERAGE_DEFAULT ) { - if ( style_class->script == globals->module->default_script ) + if ( (FT_UInt)style_class->script == + globals->module->default_script ) dflt = ss; for ( range = script_class->script_uni_ranges; @@ -332,8 +333,8 @@ af_face_globals_free( globals ); globals = NULL; } - - globals->increase_x_height = AF_PROP_INCREASE_X_HEIGHT_MAX; + else + globals->increase_x_height = AF_PROP_INCREASE_X_HEIGHT_MAX; Exit: *aglobals = globals; diff --git a/src/autofit/afglobal.h b/src/autofit/afglobal.h index d2da40e..38d8d69 100644 --- a/src/autofit/afglobal.h +++ b/src/autofit/afglobal.h @@ -66,16 +66,16 @@ FT_BEGIN_HEADER /* index of fallback style in `af_style_classes' */ #ifdef AF_CONFIG_OPTION_CJK -#define AF_STYLE_FALLBACK AF_STYLE_HANI_DFLT +#define AF_STYLE_FALLBACK AF_STYLE_HANI_DFLT #else -#define AF_STYLE_FALLBACK AF_STYLE_NONE_DFLT +#define AF_STYLE_FALLBACK AF_STYLE_NONE_DFLT #endif /* default script for OpenType; ignored if HarfBuzz isn't used */ -#define AF_SCRIPT_DEFAULT AF_SCRIPT_LATN +#define AF_SCRIPT_DEFAULT AF_SCRIPT_LATN /* a bit mask indicating an uncovered glyph */ #define AF_STYLE_UNASSIGNED 0x7F /* if this flag is set, we have an ASCII digit */ -#define AF_DIGIT 0x80 +#define AF_DIGIT 0x80 /* `increase-x-height' property */ #define AF_PROP_INCREASE_X_HEIGHT_MIN 6 diff --git a/src/autofit/afhints.c b/src/autofit/afhints.c index 270a06b..9fbc541 100644 --- a/src/autofit/afhints.c +++ b/src/autofit/afhints.c @@ -74,7 +74,8 @@ } - /* Get new edge for given axis, direction, and position. */ + /* Get new edge for given axis, direction, and position, */ + /* without initializing the edge itself. */ FT_LOCAL( FT_Error ) af_axis_hints_new_edge( AF_AxisHints axis, @@ -130,10 +131,6 @@ axis->num_edges++; - FT_ZERO( edge ); - edge->fpos = (FT_Short)fpos; - edge->dir = (FT_Char)dir; - Exit: *anedge = edge; return error; @@ -204,7 +201,7 @@ for ( point = points; point < limit; point++ ) AF_DUMP(( " [ %5d | %5d | %5d | %6.2f | %6.2f" - " | %5.2f | %5.2f | %c%c%c%c%c%c ]\n", + " | %5.2f | %5.2f | %c ]\n", point - points, point->fx, point->fy, @@ -212,12 +209,7 @@ point->oy / 64.0, point->x / 64.0, point->y / 64.0, - ( point->flags & AF_FLAG_WEAK_INTERPOLATION ) ? 'w' : ' ', - ( point->flags & AF_FLAG_INFLECTION ) ? 'i' : ' ', - ( point->flags & AF_FLAG_EXTREMA_X ) ? '<' : ' ', - ( point->flags & AF_FLAG_EXTREMA_Y ) ? 'v' : ' ', - ( point->flags & AF_FLAG_ROUND_X ) ? '(' : ' ', - ( point->flags & AF_FLAG_ROUND_Y ) ? 'u' : ' ')); + ( point->flags & AF_FLAG_WEAK_INTERPOLATION ) ? 'w' : ' ')); AF_DUMP(( "\n" )); } #ifdef __cplusplus @@ -651,6 +643,9 @@ for ( point = points; point < point_limit; point++, vec++, tag++ ) { + point->in_dir = (FT_Char)AF_DIR_NONE; + point->out_dir = (FT_Char)AF_DIR_NONE; + point->fx = (FT_Short)vec->x; point->fy = (FT_Short)vec->y; point->ox = point->x = FT_MulFix( vec->x, x_scale ) + x_delta; @@ -698,91 +693,186 @@ } } - /* compute directions of in & out vectors */ { - AF_Point first = points; - AF_Point prev = NULL; - FT_Pos in_x = 0; - FT_Pos in_y = 0; - AF_Direction in_dir = AF_DIR_NONE; - - FT_Pos last_good_in_x = 0; - FT_Pos last_good_in_y = 0; - + /* + * Compute directions of `in' and `out' vectors. + * + * Note that distances between points that are very near to each + * other are accumulated. In other words, the auto-hinter + * prepends the small vectors between near points to the first + * non-near vector. All intermediate points are tagged as + * weak; the directions are adjusted also to be equal to the + * accumulated one. + */ + + /* value 20 in `near_limit' is heuristic */ FT_UInt units_per_em = hints->metrics->scaler.face->units_per_EM; FT_Int near_limit = 20 * units_per_em / 2048; + FT_Int near_limit2 = 2 * near_limit - 1; + AF_Point* contour; + AF_Point* contour_limit = hints->contours + hints->num_contours; - for ( point = points; point < point_limit; point++ ) + + for ( contour = hints->contours; contour < contour_limit; contour++ ) { - AF_Point next; - FT_Pos out_x, out_y; + AF_Point first = *contour; + AF_Point next, prev, curr; + + FT_Pos out_x, out_y; + FT_Bool is_first; - if ( point == first ) + + /* since the first point of a contour could be part of a */ + /* series of near points, go backwards to find the first */ + /* non-near point and adjust `first' */ + + point = first; + prev = first->prev; + + while ( prev != first ) { - prev = first->prev; + out_x = point->fx - prev->fx; + out_y = point->fy - prev->fy; + + /* + * We use Taxicab metrics to measure the vector length. + * + * Note that the accumulated distances so far could have the + * opposite direction of the distance measured here. For this + * reason we use `near_limit2' for the comparison to get a + * non-near point even in the worst case. + */ + if ( FT_ABS( out_x ) + FT_ABS( out_y ) >= near_limit2 ) + break; + + point = prev; + prev = prev->prev; + } - in_x = first->fx - prev->fx; - in_y = first->fy - prev->fy; + /* adjust first point */ + first = point; - last_good_in_x = in_x; - last_good_in_y = in_y; + /* now loop over all points of the contour to get */ + /* `in' and `out' vector directions */ - if ( FT_ABS( in_x ) + FT_ABS( in_y ) < near_limit ) - { - /* search first non-near point to get a good `in_dir' value */ + curr = first; - AF_Point point_ = prev; + /* + * We abuse the `u' and `v' fields to store index deltas to the + * next and previous non-near point, respectively. + * + * To avoid problems with not having non-near points, we point to + * `first' by default as the next non-near point. + * + */ + curr->u = (FT_Pos)( first - curr ); + first->v = -curr->u; + out_x = 0; + out_y = 0; - while ( point_ != first ) - { - AF_Point prev_ = point_->prev; + is_first = 1; - FT_Pos in_x_ = point_->fx - prev_->fx; - FT_Pos in_y_ = point_->fy - prev_->fy; + for ( point = first; + point != first || is_first; + point = point->next ) + { + AF_Direction out_dir; - if ( FT_ABS( in_x_ ) + FT_ABS( in_y_ ) >= near_limit ) - { - last_good_in_x = in_x_; - last_good_in_y = in_y_; + is_first = 0; - break; - } + next = point->next; - point_ = prev_; - } + out_x += next->fx - point->fx; + out_y += next->fy - point->fy; + + if ( FT_ABS( out_x ) + FT_ABS( out_y ) < near_limit ) + { + next->flags |= AF_FLAG_WEAK_INTERPOLATION; + continue; + } + + curr->u = (FT_Pos)( next - curr ); + next->v = -curr->u; + + out_dir = af_direction_compute( out_x, out_y ); + + /* adjust directions for all points inbetween; */ + /* the loop also updates position of `curr' */ + curr->out_dir = (FT_Char)out_dir; + for ( curr = curr->next; curr != next; curr = curr->next ) + { + curr->in_dir = (FT_Char)out_dir; + curr->out_dir = (FT_Char)out_dir; } + next->in_dir = (FT_Char)out_dir; - in_dir = af_direction_compute( in_x, in_y ); - first = prev + 1; + curr->u = (FT_Pos)( first - curr ); + first->v = -curr->u; + + out_x = 0; + out_y = 0; } + } - point->in_dir = (FT_Char)in_dir; + /* + * The next step is to `simplify' an outline's topology so that we + * can identify local extrema more reliably: A series of + * non-horizontal or non-vertical vectors pointing into the same + * quadrant are handled as a single, long vector. From a + * topological point of the view, the intermediate points are of no + * interest and thus tagged as weak. + */ - /* check whether the current point is near to the previous one */ - /* (value 20 in `near_limit' is heuristic; we use Taxicab */ - /* metrics for the test) */ + for ( point = points; point < point_limit; point++ ) + { + if ( point->flags & AF_FLAG_WEAK_INTERPOLATION ) + continue; - if ( FT_ABS( in_x ) + FT_ABS( in_y ) < near_limit ) - point->flags |= AF_FLAG_NEAR; - else + if ( point->in_dir == AF_DIR_NONE && + point->out_dir == AF_DIR_NONE ) { - last_good_in_x = in_x; - last_good_in_y = in_y; - } + /* check whether both vectors point into the same quadrant */ + + FT_Pos in_x, in_y; + FT_Pos out_x, out_y; + + AF_Point next_u = point + point->u; + AF_Point prev_v = point + point->v; + - next = point->next; - out_x = next->fx - point->fx; - out_y = next->fy - point->fy; + in_x = point->fx - prev_v->fx; + in_y = point->fy - prev_v->fy; + + out_x = next_u->fx - point->fx; + out_y = next_u->fy - point->fy; + + if ( ( in_x ^ out_x ) >= 0 && ( in_y ^ out_y ) >= 0 ) + { + /* yes, so tag current point as weak */ + /* and update index deltas */ + + point->flags |= AF_FLAG_WEAK_INTERPOLATION; + + prev_v->u = (FT_Pos)( next_u - prev_v ); + next_u->v = -prev_v->u; + } + } + } - in_dir = af_direction_compute( out_x, out_y ); - point->out_dir = (FT_Char)in_dir; + /* + * Finally, check for remaining weak points. Everything else not + * collected in edges so far is then implicitly classified as strong + * points. + */ - /* Check for weak points. The remaining points not collected */ - /* in edges are then implicitly classified as strong points. */ + for ( point = points; point < point_limit; point++ ) + { + if ( point->flags & AF_FLAG_WEAK_INTERPOLATION ) + continue; if ( point->flags & AF_FLAG_CONTROL ) { @@ -799,18 +889,25 @@ goto Is_Weak_Point; } - /* test whether `in' and `out' direction is approximately */ - /* the same (and use the last good `in' vector in case */ - /* the current point is near to the previous one) */ - if ( ft_corner_is_flat( - point->flags & AF_FLAG_NEAR ? last_good_in_x : in_x, - point->flags & AF_FLAG_NEAR ? last_good_in_y : in_y, - out_x, - out_y ) ) { - /* current point lies on a straight, diagonal line */ - /* (more or less) */ - goto Is_Weak_Point; + AF_Point next_u = point + point->u; + AF_Point prev_v = point + point->v; + + + if ( ft_corner_is_flat( point->fx - prev_v->fx, + point->fy - prev_v->fy, + next_u->fx - point->fx, + next_u->fy - point->fy ) ) + { + /* either the `in' or the `out' vector is much more */ + /* dominant than the other one, so tag current point */ + /* as weak and update index deltas */ + + prev_v->u = (FT_Pos)( next_u - prev_v ); + next_u->v = -prev_v->u; + + goto Is_Weak_Point; + } } } else if ( point->in_dir == -point->out_dir ) @@ -818,9 +915,6 @@ /* current point forms a spike */ goto Is_Weak_Point; } - - in_x = out_x; - in_y = out_y; } } } @@ -977,8 +1071,7 @@ /* if this point is candidate to weak interpolation, we */ /* interpolate it after all strong points have been processed */ - if ( ( point->flags & AF_FLAG_WEAK_INTERPOLATION ) && - !( point->flags & AF_FLAG_INFLECTION ) ) + if ( ( point->flags & AF_FLAG_WEAK_INTERPOLATION ) ) continue; if ( dim == AF_DIMENSION_VERT ) diff --git a/src/autofit/afhints.h b/src/autofit/afhints.h index 5f1507f..92101de 100644 --- a/src/autofit/afhints.h +++ b/src/autofit/afhints.h @@ -4,7 +4,7 @@ /* */ /* Auto-fitter hinting routines (specification). */ /* */ -/* Copyright 2003-2008, 2010-2012 by */ +/* Copyright 2003-2008, 2010-2012, 2014 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -72,13 +72,9 @@ FT_BEGIN_HEADER * `af_{cjk,latin,...}_hints_compute_segments' are the functions to * find segments in an outline. * - * A segment is a series of consecutive points that are approximately - * aligned along a coordinate axis. The analysis to do so is specific - * to a writing system. - * - * A segment must have at least two points, except in the case of - * `fake' segments that are generated to hint metrics appropriately, - * and which consist of a single point. + * A segment is a series of at least two consecutive points that are + * approximately aligned along a coordinate axis. The analysis to do + * so is specific to a writing system. * * * Edges @@ -148,7 +144,7 @@ FT_BEGIN_HEADER * Serifs are detected by `af_{cjk,latin,...}_hint_edges'. * * In comparison to a stem, a serif (as handled by the auto-hinter - * module which takes care of the `latin' writing system) has + * module that takes care of the `latin' writing system) has * * best segment_1 = segment_2 && best segment_2 != segment_1 * @@ -178,19 +174,19 @@ FT_BEGIN_HEADER * * Strong Points * - * Experience has shown that points which are not part of an edge need - * to be interpolated linearly between their two closest edges, even if - * these are not part of the contour of those particular points. - * Typical candidates for this are + * Experience has shown that points not part of an edge need to be + * interpolated linearly between their two closest edges, even if these + * are not part of the contour of those particular points. Typical + * candidates for this are * * - angle points (i.e., points where the `in' and `out' direction * differ greatly) * * - inflection points (i.e., where the `in' and `out' angles are the * same, but the curvature changes sign) [currently, such points - * aren't handled in the auto-hinter] + * aren't handled specially in the auto-hinter] * - * `af_glyph_hints_align_strong_points' is the function which takes + * `af_glyph_hints_align_strong_points' is the function that takes * care of such situations; it is equivalent to the TrueType `IP' * hinting instruction. * @@ -220,26 +216,12 @@ FT_BEGIN_HEADER AF_FLAG_CUBIC = 1 << 1, AF_FLAG_CONTROL = AF_FLAG_CONIC | AF_FLAG_CUBIC, - /* point extremum flags */ - AF_FLAG_EXTREMA_X = 1 << 2, - AF_FLAG_EXTREMA_Y = 1 << 3, - - /* point roundness flags */ - AF_FLAG_ROUND_X = 1 << 4, - AF_FLAG_ROUND_Y = 1 << 5, - /* point touch flags */ - AF_FLAG_TOUCH_X = 1 << 6, - AF_FLAG_TOUCH_Y = 1 << 7, + AF_FLAG_TOUCH_X = 1 << 2, + AF_FLAG_TOUCH_Y = 1 << 3, /* candidates for weak interpolation have this flag set */ - AF_FLAG_WEAK_INTERPOLATION = 1 << 8, - - /* all inflection points in the outline have this flag set */ - AF_FLAG_INFLECTION = 1 << 9, - - /* the current point is very near to another one */ - AF_FLAG_NEAR = 1 << 10 + AF_FLAG_WEAK_INTERPOLATION = 1 << 4 } AF_Flags; @@ -247,10 +229,11 @@ FT_BEGIN_HEADER /* edge hint flags */ typedef enum AF_Edge_Flags_ { - AF_EDGE_NORMAL = 0, - AF_EDGE_ROUND = 1 << 0, - AF_EDGE_SERIF = 1 << 1, - AF_EDGE_DONE = 1 << 2 + AF_EDGE_NORMAL = 0, + AF_EDGE_ROUND = 1 << 0, + AF_EDGE_SERIF = 1 << 1, + AF_EDGE_DONE = 1 << 2, + AF_EDGE_NEUTRAL = 1 << 3 /* set if edge aligns to a neutral blue zone */ } AF_Edge_Flags; diff --git a/src/autofit/aflatin.c b/src/autofit/aflatin.c index e3a7742..36a3689 100644 --- a/src/autofit/aflatin.c +++ b/src/autofit/aflatin.c @@ -171,7 +171,15 @@ if ( error ) goto Exit; + /* + * We assume that the glyphs selected for the stem width + * computation are `featureless' enough so that the linking + * algorithm works fine without adjustments of its scoring + * function. + */ af_latin_hints_link_segments( hints, + 0, + NULL, (AF_Dimension)dim ); seg = axhints->segments; @@ -298,6 +306,14 @@ have_flag = 1; } + if ( AF_LATIN_IS_NEUTRAL_BLUE( bs ) ) + { + if ( have_flag ) + FT_TRACE5(( ", " )); + FT_TRACE5(( "neutral" )); + have_flag = 1; + } + if ( AF_LATIN_IS_X_HEIGHT_BLUE( bs ) ) { if ( have_flag ) @@ -520,6 +536,13 @@ FT_Int last; FT_Bool hit; + /* we intentionally declare these two variables */ + /* outside of the loop since various compilers emit */ + /* incorrect warning messages otherwise, talking about */ + /* `possibly uninitialized variables' */ + FT_Int p_first = 0; /* make compiler happy */ + FT_Int p_last = 0; + FT_Bool left2right; @@ -552,7 +575,6 @@ { FT_Bool l2r; FT_Pos d; - FT_Int p_first, p_last; if ( !hit ) @@ -688,6 +710,13 @@ FT_CURVE_TAG( outline.tags[best_segment_last] ) != FT_CURVE_TAG_ON ); + if ( round && AF_LATIN_IS_NEUTRAL_BLUE( bs ) ) + { + /* only use flat segments for a neutral blue zone */ + FT_TRACE5(( " (round, skipped)\n" )); + continue; + } + FT_TRACE5(( " (%s)\n", round ? "round" : "flat" )); } @@ -758,6 +787,8 @@ blue->flags = 0; if ( AF_LATIN_IS_TOP_BLUE( bs ) ) blue->flags |= AF_LATIN_BLUE_TOP; + if ( AF_LATIN_IS_NEUTRAL_BLUE( bs ) ) + blue->flags |= AF_LATIN_BLUE_NEUTRAL; /* * The following flag is used later to adjust the y and x scales @@ -1262,17 +1293,19 @@ /* this is the start of a new segment! */ segment_dir = (AF_Direction)point->out_dir; - /* clear all segment fields */ error = af_axis_hints_new_segment( axis, memory, &segment ); if ( error ) goto Exit; - segment[0] = seg0; + /* clear all segment fields */ + segment[0] = seg0; + segment->dir = (FT_Char)segment_dir; min_pos = max_pos = point->u; segment->first = point; segment->last = point; - on_edge = 1; + + on_edge = 1; } point = point->next; @@ -1296,9 +1329,6 @@ FT_Pos last_v = last->v; - if ( first == last ) - continue; - if ( first_v < last_v ) { AF_Point p; @@ -1337,31 +1367,44 @@ } - /* Link segments to form stems and serifs. */ + /* Link segments to form stems and serifs. If `width_count' and */ + /* `widths' are non-zero, use them to fine-tune the scoring function. */ FT_LOCAL_DEF( void ) af_latin_hints_link_segments( AF_GlyphHints hints, + FT_UInt width_count, + AF_WidthRec* widths, AF_Dimension dim ) { AF_AxisHints axis = &hints->axis[dim]; AF_Segment segments = axis->segments; AF_Segment segment_limit = segments + axis->num_segments; - FT_Pos len_threshold, len_score; + FT_Pos len_threshold, len_score, dist_score, max_width; AF_Segment seg1, seg2; + if ( width_count ) + max_width = widths[width_count - 1].org; + else + max_width = 0; + + /* a heuristic value to set up a minimum value for overlapping */ len_threshold = AF_LATIN_CONSTANT( hints->metrics, 8 ); if ( len_threshold == 0 ) len_threshold = 1; + /* a heuristic value to weight lengths */ len_score = AF_LATIN_CONSTANT( hints->metrics, 6000 ); + /* a heuristic value to weight distances (no call to */ + /* AF_LATIN_CONSTANT needed, since we work on multiples */ + /* of the stem width) */ + dist_score = 3000; + /* now compare each segment to the others */ for ( seg1 = segments; seg1 < segment_limit; seg1++ ) { - /* the fake segments are introduced to hint the metrics -- */ - /* we must never link them to anything */ - if ( seg1->dir != axis->major_dir || seg1->first == seg1->last ) + if ( seg1->dir != axis->major_dir ) continue; /* search for stems having opposite directions, */ @@ -1375,10 +1418,9 @@ if ( seg1->dir + seg2->dir == 0 && pos2 > pos1 ) { /* compute distance between the two segments */ - FT_Pos dist = pos2 - pos1; - FT_Pos min = seg1->min_coord; - FT_Pos max = seg1->max_coord; - FT_Pos len, score; + FT_Pos min = seg1->min_coord; + FT_Pos max = seg1->max_coord; + FT_Pos len; if ( min < seg2->min_coord ) @@ -1388,15 +1430,49 @@ max = seg2->max_coord; /* compute maximum coordinate difference of the two segments */ + /* (this is, how much they overlap) */ len = max - min; if ( len >= len_threshold ) { - /* small coordinate differences cause a higher score, and */ - /* segments with a greater distance cause a higher score also */ - score = dist + len_score / len; + /* + * The score is the sum of two demerits indicating the + * `badness' of a fit, measured along the segments' main axis + * and orthogonal to it, respectively. + * + * o The less overlapping along the main axis, the worse it + * is, causing a larger demerit. + * + * o The nearer the orthogonal distance to a stem width, the + * better it is, causing a smaller demerit. For simplicity, + * however, we only increase the demerit for values that + * exceed the largest stem width. + */ + + FT_Pos dist = pos2 - pos1; + + FT_Pos dist_demerit, score; + + + if ( max_width ) + { + /* distance demerits are based on multiples of `max_width'; */ + /* we scale by 1024 for getting more precision */ + FT_Pos delta = ( dist << 10 ) / max_width - ( 1 << 10 ); + + + if ( delta > 10000 ) + dist_demerit = 32000; + else if ( delta > 0 ) + dist_demerit = delta * delta / dist_score; + else + dist_demerit = 0; + } + else + dist_demerit = dist; /* default if no widths available */ + + score = dist_demerit + len_score / len; /* and we search for the smallest score */ - /* of the sum of the two values */ if ( score < seg1->score ) { seg1->score = score; @@ -1728,6 +1804,8 @@ FT_LOCAL_DEF( FT_Error ) af_latin_hints_detect_features( AF_GlyphHints hints, + FT_UInt width_count, + AF_WidthRec* widths, AF_Dimension dim ) { FT_Error error; @@ -1736,7 +1814,7 @@ error = af_latin_hints_compute_segments( hints, dim ); if ( !error ) { - af_latin_hints_link_segments( hints, dim ); + af_latin_hints_link_segments( hints, width_count, widths, dim ); error = af_latin_hints_compute_edges( hints, dim ); } @@ -1765,8 +1843,9 @@ for ( ; edge < edge_limit; edge++ ) { FT_UInt bb; - AF_Width best_blue = NULL; - FT_Pos best_dist; /* initial threshold */ + AF_Width best_blue = NULL; + FT_Bool best_blue_is_neutral = 0; + FT_Pos best_dist; /* initial threshold */ /* compute the initial threshold as a fraction of the EM size */ @@ -1780,24 +1859,26 @@ for ( bb = 0; bb < latin->blue_count; bb++ ) { AF_LatinBlue blue = latin->blues + bb; - FT_Bool is_top_blue, is_major_dir; + FT_Bool is_top_blue, is_neutral_blue, is_major_dir; /* skip inactive blue zones (i.e., those that are too large) */ if ( !( blue->flags & AF_LATIN_BLUE_ACTIVE ) ) continue; - /* if it is a top zone, check for right edges -- if it is a bottom */ - /* zone, check for left edges */ - /* */ - /* of course, that's for TrueType */ - is_top_blue = (FT_Byte)( ( blue->flags & AF_LATIN_BLUE_TOP ) != 0 ); - is_major_dir = FT_BOOL( edge->dir == axis->major_dir ); - - /* if it is a top zone, the edge must be against the major */ - /* direction; if it is a bottom zone, it must be in the major */ - /* direction */ - if ( is_top_blue ^ is_major_dir ) + /* if it is a top zone, check for right edges (against the major */ + /* direction); if it is a bottom zone, check for left edges (in */ + /* the major direction) -- this assumes the TrueType convention */ + /* for the orientation of contours */ + is_top_blue = + (FT_Byte)( ( blue->flags & AF_LATIN_BLUE_TOP ) != 0 ); + is_neutral_blue = + (FT_Byte)( ( blue->flags & AF_LATIN_BLUE_NEUTRAL ) != 0); + is_major_dir = + FT_BOOL( edge->dir == axis->major_dir ); + + /* neutral blue zones are handled for both directions */ + if ( is_top_blue ^ is_major_dir || is_neutral_blue ) { FT_Pos dist; @@ -1810,15 +1891,19 @@ dist = FT_MulFix( dist, scale ); if ( dist < best_dist ) { - best_dist = dist; - best_blue = &blue->ref; + best_dist = dist; + best_blue = &blue->ref; + best_blue_is_neutral = is_neutral_blue; } /* now compare it to the overshoot position and check whether */ /* the edge is rounded, and whether the edge is over the */ /* reference position of a top zone, or under the reference */ - /* position of a bottom zone */ - if ( edge->flags & AF_EDGE_ROUND && dist != 0 ) + /* position of a bottom zone (provided we don't have a */ + /* neutral blue zone) */ + if ( edge->flags & AF_EDGE_ROUND && + dist != 0 && + !is_neutral_blue ) { FT_Bool is_under_ref = FT_BOOL( edge->fpos < blue->ref.org ); @@ -1832,8 +1917,9 @@ dist = FT_MulFix( dist, scale ); if ( dist < best_dist ) { - best_dist = dist; - best_blue = &blue->shoot; + best_dist = dist; + best_blue = &blue->shoot; + best_blue_is_neutral = is_neutral_blue; } } } @@ -1841,7 +1927,11 @@ } if ( best_blue ) + { edge->blue_edge = best_blue; + if ( best_blue_is_neutral ) + edge->flags |= AF_EDGE_NEUTRAL; + } } } @@ -2159,7 +2249,7 @@ FT_TRACE5(( " LINK: edge %d (opos=%.2f) linked to %.2f," " dist was %.2f, now %.2f\n", - stem_edge-hints->axis[dim].edges, stem_edge->opos / 64.0, + stem_edge - hints->axis[dim].edges, stem_edge->opos / 64.0, stem_edge->pos / 64.0, dist / 64.0, fitted_width / 64.0 )); } @@ -2226,14 +2316,41 @@ if ( edge->flags & AF_EDGE_DONE ) continue; - blue = edge->blue_edge; edge1 = NULL; edge2 = edge->link; + /* + * If a stem contains both a neutral and a non-neutral blue zone, + * skip the neutral one. Otherwise, outlines with different + * directions might be incorrectly aligned at the same vertical + * position. + * + * If we have two neutral blue zones, skip one of them. + * + */ + if ( edge->blue_edge && edge2 && edge2->blue_edge ) + { + FT_Byte neutral = edge->flags & AF_EDGE_NEUTRAL; + FT_Byte neutral2 = edge2->flags & AF_EDGE_NEUTRAL; + + + if ( ( neutral && neutral2 ) || neutral2 ) + { + edge2->blue_edge = NULL; + edge2->flags &= ~AF_EDGE_NEUTRAL; + } + else if ( neutral ) + { + edge->blue_edge = NULL; + edge->flags &= ~AF_EDGE_NEUTRAL; + } + } + + blue = edge->blue_edge; if ( blue ) edge1 = edge; - /* flip edges if the other stem is aligned to a blue zone */ + /* flip edges if the other edge is aligned to a blue zone */ else if ( edge2 && edge2->blue_edge ) { blue = edge2->blue_edge; @@ -2300,7 +2417,7 @@ /* this should not happen, but it's better to be safe */ if ( edge2->blue_edge ) { - FT_TRACE5(( " ASSERTION FAILED for edge %d\n", edge2-edges )); + FT_TRACE5(( " ASSERTION FAILED for edge %d\n", edge2 - edges )); af_latin_align_linked_edge( hints, dim, edge2, edge ); edge->flags |= AF_EDGE_DONE; @@ -2689,6 +2806,8 @@ FT_Error error; int dim; + AF_LatinAxis axis; + error = af_glyph_hints_reload( hints, outline ); if ( error ) @@ -2702,14 +2821,22 @@ if ( AF_HINTS_DO_HORIZONTAL( hints ) ) #endif { - error = af_latin_hints_detect_features( hints, AF_DIMENSION_HORZ ); + axis = &metrics->axis[AF_DIMENSION_HORZ]; + error = af_latin_hints_detect_features( hints, + axis->width_count, + axis->widths, + AF_DIMENSION_HORZ ); if ( error ) goto Exit; } if ( AF_HINTS_DO_VERTICAL( hints ) ) { - error = af_latin_hints_detect_features( hints, AF_DIMENSION_VERT ); + axis = &metrics->axis[AF_DIMENSION_VERT]; + error = af_latin_hints_detect_features( hints, + axis->width_count, + axis->widths, + AF_DIMENSION_VERT ); if ( error ) goto Exit; diff --git a/src/autofit/aflatin.h b/src/autofit/aflatin.h index a958af3..2c0bfca 100644 --- a/src/autofit/aflatin.h +++ b/src/autofit/aflatin.h @@ -5,7 +5,7 @@ /* Auto-fitter hinting routines for latin writing system */ /* (specification). */ /* */ -/* Copyright 2003-2007, 2009, 2011-2013 by */ +/* Copyright 2003-2007, 2009, 2011-2014 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -53,6 +53,8 @@ FT_BEGIN_HEADER #define AF_LATIN_IS_TOP_BLUE( b ) \ ( (b)->properties & AF_BLUE_PROPERTY_LATIN_TOP ) +#define AF_LATIN_IS_NEUTRAL_BLUE( b ) \ + ( (b)->properties & AF_BLUE_PROPERTY_LATIN_NEUTRAL ) #define AF_LATIN_IS_X_HEIGHT_BLUE( b ) \ ( (b)->properties & AF_BLUE_PROPERTY_LATIN_X_HEIGHT ) #define AF_LATIN_IS_LONG_BLUE( b ) \ @@ -63,10 +65,11 @@ FT_BEGIN_HEADER enum { - AF_LATIN_BLUE_ACTIVE = 1 << 0, /* set if zone height is <= 3/4px */ - AF_LATIN_BLUE_TOP = 1 << 1, /* result of AF_LATIN_IS_TOP_BLUE */ - AF_LATIN_BLUE_ADJUSTMENT = 1 << 2, /* used for scale adjustment */ - /* optimization */ + AF_LATIN_BLUE_ACTIVE = 1 << 0, /* set if zone height is <= 3/4px */ + AF_LATIN_BLUE_TOP = 1 << 1, /* set if we have a top blue zone */ + AF_LATIN_BLUE_NEUTRAL = 1 << 2, /* set if we have neutral blue zone */ + AF_LATIN_BLUE_ADJUSTMENT = 1 << 3, /* used for scale adjustment */ + /* optimization */ AF_LATIN_BLUE_FLAG_MAX }; @@ -169,6 +172,8 @@ FT_BEGIN_HEADER FT_LOCAL( void ) af_latin_hints_link_segments( AF_GlyphHints hints, + FT_UInt width_count, + AF_WidthRec* widths, AF_Dimension dim ); FT_LOCAL( FT_Error ) @@ -177,6 +182,8 @@ FT_BEGIN_HEADER FT_LOCAL( FT_Error ) af_latin_hints_detect_features( AF_GlyphHints hints, + FT_UInt width_count, + AF_WidthRec* widths, AF_Dimension dim ); /* */ diff --git a/src/autofit/aflatin2.c b/src/autofit/aflatin2.c index 930fa98..07590b3 100644 --- a/src/autofit/aflatin2.c +++ b/src/autofit/aflatin2.c @@ -4,7 +4,7 @@ /* */ /* Auto-fitter hinting routines for latin writing system (body). */ /* */ -/* Copyright 2003-2013 by */ +/* Copyright 2003-2014 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -890,9 +890,6 @@ FT_Pos last_v = last->v; - if ( first == last ) - continue; - if ( first_v < last_v ) { p = first->prev; @@ -984,7 +981,7 @@ #ifdef AF_SORT_SEGMENTS for ( seg1 = segments; seg1 < segment_mid; seg1++ ) { - if ( seg1->dir != axis->major_dir || seg1->first == seg1->last ) + if ( seg1->dir != axis->major_dir ) continue; for ( seg2 = segment_mid; seg2 < segment_limit; seg2++ ) @@ -992,9 +989,7 @@ /* now compare each segment to the others */ for ( seg1 = segments; seg1 < segment_limit; seg1++ ) { - /* the fake segments are introduced to hint the metrics -- */ - /* we must never link them to anything */ - if ( seg1->dir != axis->major_dir || seg1->first == seg1->last ) + if ( seg1->dir != axis->major_dir ) continue; for ( seg2 = segments; seg2 < segment_limit; seg2++ ) @@ -1194,9 +1189,10 @@ edge->first = seg; edge->last = seg; - edge->fpos = seg->pos; edge->dir = seg->dir; - edge->opos = edge->pos = FT_MulFix( seg->pos, scale ); + edge->fpos = seg->pos; + edge->opos = FT_MulFix( seg->pos, scale ); + edge->pos = edge->opos; seg->edge_next = seg; } else diff --git a/src/autofit/afmodule.c b/src/autofit/afmodule.c index 73bf832..181cf55 100644 --- a/src/autofit/afmodule.c +++ b/src/autofit/afmodule.c @@ -103,8 +103,8 @@ AF_StyleClass style_class = AF_STYLE_CLASSES_GET[ss]; - if ( style_class->script == *fallback_script && - style_class->coverage == AF_COVERAGE_DEFAULT ) + if ( (FT_UInt)style_class->script == *fallback_script && + style_class->coverage == AF_COVERAGE_DEFAULT ) { module->fallback_style = ss; break; diff --git a/src/autofit/afranges.c b/src/autofit/afranges.c index 3d919b5..139a4c1 100644 --- a/src/autofit/afranges.c +++ b/src/autofit/afranges.c @@ -21,51 +21,59 @@ const AF_Script_UniRangeRec af_cyrl_uniranges[] = { - AF_UNIRANGE_REC( 0x0400UL, 0x04FFUL ), /* Cyrillic */ + AF_UNIRANGE_REC( 0x0400UL, 0x04FFUL ), /* Cyrillic */ AF_UNIRANGE_REC( 0x0500UL, 0x052FUL ), /* Cyrillic Supplement */ AF_UNIRANGE_REC( 0x2DE0UL, 0x2DFFUL ), /* Cyrillic Extended-A */ AF_UNIRANGE_REC( 0xA640UL, 0xA69FUL ), /* Cyrillic Extended-B */ AF_UNIRANGE_REC( 0UL, 0UL ) }; + const AF_Script_UniRangeRec af_deva_uniranges[] = + { + AF_UNIRANGE_REC( 0x0900UL, 0x097FUL ), /* Devanagari */ + AF_UNIRANGE_REC( 0x20B9UL, 0x20B9UL ), /* (new) Rupee sign */ + AF_UNIRANGE_REC( 0UL, 0UL ) + }; + const AF_Script_UniRangeRec af_grek_uniranges[] = { AF_UNIRANGE_REC( 0x0370UL, 0x03FFUL ), /* Greek and Coptic */ - AF_UNIRANGE_REC( 0x1F00UL, 0x1FFFUL ), /* Greek Extended */ + AF_UNIRANGE_REC( 0x1F00UL, 0x1FFFUL ), /* Greek Extended */ AF_UNIRANGE_REC( 0UL, 0UL ) }; const AF_Script_UniRangeRec af_hebr_uniranges[] = { - AF_UNIRANGE_REC( 0x0590UL, 0x05FFUL ), /* Hebrew */ + AF_UNIRANGE_REC( 0x0590UL, 0x05FFUL ), /* Hebrew */ AF_UNIRANGE_REC( 0xFB1DUL, 0xFB4FUL ), /* Alphab. Present. Forms (Hebrew) */ AF_UNIRANGE_REC( 0UL, 0UL ) }; const AF_Script_UniRangeRec af_latn_uniranges[] = { - AF_UNIRANGE_REC( 0x0020UL, 0x007FUL ), /* Basic Latin (no control chars) */ - AF_UNIRANGE_REC( 0x00A0UL, 0x00FFUL ), /* Latin-1 Supplement (no control chars) */ - AF_UNIRANGE_REC( 0x0100UL, 0x017FUL ), /* Latin Extended-A */ - AF_UNIRANGE_REC( 0x0180UL, 0x024FUL ), /* Latin Extended-B */ - AF_UNIRANGE_REC( 0x0250UL, 0x02AFUL ), /* IPA Extensions */ - AF_UNIRANGE_REC( 0x02B0UL, 0x02FFUL ), /* Spacing Modifier Letters */ - AF_UNIRANGE_REC( 0x0300UL, 0x036FUL ), /* Combining Diacritical Marks */ - AF_UNIRANGE_REC( 0x1D00UL, 0x1D7FUL ), /* Phonetic Extensions */ - AF_UNIRANGE_REC( 0x1D80UL, 0x1DBFUL ), /* Phonetic Extensions Supplement */ + AF_UNIRANGE_REC( 0x0020UL, 0x007FUL ), /* Basic Latin (no control chars) */ + AF_UNIRANGE_REC( 0x00A0UL, 0x00FFUL ), /* Latin-1 Supplement (no control chars) */ + AF_UNIRANGE_REC( 0x0100UL, 0x017FUL ), /* Latin Extended-A */ + AF_UNIRANGE_REC( 0x0180UL, 0x024FUL ), /* Latin Extended-B */ + AF_UNIRANGE_REC( 0x0250UL, 0x02AFUL ), /* IPA Extensions */ + AF_UNIRANGE_REC( 0x02B0UL, 0x02FFUL ), /* Spacing Modifier Letters */ + AF_UNIRANGE_REC( 0x0300UL, 0x036FUL ), /* Combining Diacritical Marks */ + AF_UNIRANGE_REC( 0x1D00UL, 0x1D7FUL ), /* Phonetic Extensions */ + AF_UNIRANGE_REC( 0x1D80UL, 0x1DBFUL ), /* Phonetic Extensions Supplement */ AF_UNIRANGE_REC( 0x1DC0UL, 0x1DFFUL ), /* Combining Diacritical Marks Supplement */ - AF_UNIRANGE_REC( 0x1E00UL, 0x1EFFUL ), /* Latin Extended Additional */ - AF_UNIRANGE_REC( 0x2000UL, 0x206FUL ), /* General Punctuation */ - AF_UNIRANGE_REC( 0x2070UL, 0x209FUL ), /* Superscripts and Subscripts */ - AF_UNIRANGE_REC( 0x20A0UL, 0x20CFUL ), /* Currency Symbols */ - AF_UNIRANGE_REC( 0x2150UL, 0x218FUL ), /* Number Forms */ - AF_UNIRANGE_REC( 0x2460UL, 0x24FFUL ), /* Enclosed Alphanumerics */ - AF_UNIRANGE_REC( 0x2C60UL, 0x2C7FUL ), /* Latin Extended-C */ - AF_UNIRANGE_REC( 0x2E00UL, 0x2E7FUL ), /* Supplemental Punctuation */ - AF_UNIRANGE_REC( 0xA720UL, 0xA7FFUL ), /* Latin Extended-D */ - AF_UNIRANGE_REC( 0xFB00UL, 0xFB06UL ), /* Alphab. Present. Forms (Latin Ligs) */ - AF_UNIRANGE_REC( 0x1D400UL, 0x1D7FFUL ), /* Mathematical Alphanumeric Symbols */ - AF_UNIRANGE_REC( 0x1F100UL, 0x1F1FFUL ), /* Enclosed Alphanumeric Supplement */ + AF_UNIRANGE_REC( 0x1E00UL, 0x1EFFUL ), /* Latin Extended Additional */ + AF_UNIRANGE_REC( 0x2000UL, 0x206FUL ), /* General Punctuation */ + AF_UNIRANGE_REC( 0x2070UL, 0x209FUL ), /* Superscripts and Subscripts */ + AF_UNIRANGE_REC( 0x20A0UL, 0x20B8UL ), /* Currency Symbols ... */ + AF_UNIRANGE_REC( 0x20BAUL, 0x20CFUL ), /* ... except new Rupee sign */ + AF_UNIRANGE_REC( 0x2150UL, 0x218FUL ), /* Number Forms */ + AF_UNIRANGE_REC( 0x2460UL, 0x24FFUL ), /* Enclosed Alphanumerics */ + AF_UNIRANGE_REC( 0x2C60UL, 0x2C7FUL ), /* Latin Extended-C */ + AF_UNIRANGE_REC( 0x2E00UL, 0x2E7FUL ), /* Supplemental Punctuation */ + AF_UNIRANGE_REC( 0xA720UL, 0xA7FFUL ), /* Latin Extended-D */ + AF_UNIRANGE_REC( 0xFB00UL, 0xFB06UL ), /* Alphab. Present. Forms (Latin Ligs) */ + AF_UNIRANGE_REC( 0x1D400UL, 0x1D7FFUL ), /* Mathematical Alphanumeric Symbols */ + AF_UNIRANGE_REC( 0x1F100UL, 0x1F1FFUL ), /* Enclosed Alphanumeric Supplement */ AF_UNIRANGE_REC( 0UL, 0UL ) }; @@ -82,12 +90,6 @@ AF_UNIRANGE_REC( 0UL, 0UL ) }; - const AF_Script_UniRangeRec af_deva_uniranges[] = - { - AF_UNIRANGE_REC( 0x0900UL, 0x097FUL ), /* Devanagari */ - AF_UNIRANGE_REC( 0UL, 0UL ) - }; - const AF_Script_UniRangeRec af_gujr_uniranges[] = { AF_UNIRANGE_REC( 0x0A80UL, 0x0AFFUL ), /* Gujarati */ diff --git a/src/autofit/afscript.h b/src/autofit/afscript.h index ae20932..a418b05 100644 --- a/src/autofit/afscript.h +++ b/src/autofit/afscript.h @@ -31,6 +31,11 @@ HB_SCRIPT_CYRILLIC, 0x43E, 0x41E, 0x0 ) /* оО */ + SCRIPT( deva, DEVA, + "Devanagari", + HB_SCRIPT_DEVANAGARI, + 0x920, 0x935, 0x91F ) /* ठ व ट */ + SCRIPT( grek, GREK, "Greek", HB_SCRIPT_GREEK, @@ -58,11 +63,6 @@ HB_SCRIPT_BENGALI, 'o', 0x0, 0x0 ) /* XXX */ - SCRIPT( deva, DEVA, - "Devanagari", - HB_SCRIPT_DEVANAGARI, - 'o', 0x0, 0x0 ) /* XXX */ - SCRIPT( gujr, GUJR, "Gujarati", HB_SCRIPT_GUJARATI, diff --git a/src/autofit/afstyles.h b/src/autofit/afstyles.h index 429da76..27fdd2e 100644 --- a/src/autofit/afstyles.h +++ b/src/autofit/afstyles.h @@ -81,7 +81,9 @@ DEFAULT ) META_STYLE_LATIN( cyrl, CYRL, "Cyrillic" ) + META_STYLE_LATIN( grek, GREK, "Greek" ) + STYLE( hebr_dflt, HEBR_DFLT, "Hebrew default style", AF_WRITING_SYSTEM_LATIN, @@ -90,6 +92,13 @@ AF_COVERAGE_DEFAULT ) META_STYLE_LATIN( latn, LATN, "Latin" ) + STYLE( deva_dflt, DEVA_DFLT, + "Devanagari default style", + AF_WRITING_SYSTEM_LATIN, + AF_SCRIPT_DEVA, + AF_BLUE_STRINGSET_DEVA, + AF_COVERAGE_DEFAULT ) + #ifdef FT_OPTION_AUTOFIT2 STYLE( ltn2_dflt, LTN2_DFLT, "Latin 2 default style", @@ -119,7 +128,6 @@ AF_COVERAGE_DEFAULT ) STYLE_DEFAULT_INDIC( beng, BENG, "Bengali" ) - STYLE_DEFAULT_INDIC( deva, DEVA, "Devanagari" ) STYLE_DEFAULT_INDIC( gujr, GUJR, "Gujarati" ) STYLE_DEFAULT_INDIC( guru, GURU, "Gurmukhi" ) STYLE_DEFAULT_INDIC( knda, KNDA, "Kannada" ) diff --git a/src/autofit/hbshim.c b/src/autofit/hbshim.c index 11fb743..cc04815 100644 --- a/src/autofit/hbshim.c +++ b/src/autofit/hbshim.c @@ -247,6 +247,7 @@ * (this is, not a single character is covered), we skip this coverage. * */ + if ( style_class->coverage != AF_COVERAGE_DEFAULT ) { AF_Blue_Stringset bss = style_class->blue_stringset; const AF_Blue_StringRec* bs = &af_blue_stringsets[bss]; @@ -328,8 +329,15 @@ * out whether a glyph gets shifted vertically, but this is something I * would like to avoid if not really necessary. * + * Note that we don't follow this logic for the default coverage. + * Complex scripts like Devanagari have mandatory GPOS features to + * position many glyph elements, using mark-to-base or mark-to-ligature + * tables; the number of glyphs missed due to condition (b) would be far + * too large. + * */ - hb_set_subtract( gsub_glyphs, gpos_glyphs ); + if ( style_class->coverage != AF_COVERAGE_DEFAULT ) + hb_set_subtract( gsub_glyphs, gpos_glyphs ); #ifdef FT_DEBUG_LEVEL_TRACE FT_TRACE4(( " glyphs without GPOS data (`*' means already assigned)" )); @@ -347,6 +355,12 @@ count++; #endif + /* glyph indices returned by `hb_ot_layout_lookup_collect_glyphs' */ + /* can be arbitrary: some fonts use fake indices for processing */ + /* internal to GSUB or GPOS, which is fully valid */ + if ( idx >= (hb_codepoint_t)globals->glyph_count ) + continue; + if ( gstyles[idx] == AF_STYLE_UNASSIGNED ) gstyles[idx] = (FT_Byte)style_class->style; #ifdef FT_DEBUG_LEVEL_TRACE diff --git a/src/base/ftbbox.c b/src/base/ftbbox.c index 8d3f383..349cb95 100644 --- a/src/base/ftbbox.c +++ b/src/base/ftbbox.c @@ -203,15 +203,48 @@ /* max :: The address of the current maximum. */ /* */ static FT_Pos - update_cubic_max( FT_Pos q1, - FT_Pos q2, - FT_Pos q3, - FT_Pos q4, - FT_Pos max ) + cubic_peak( FT_Pos q1, + FT_Pos q2, + FT_Pos q3, + FT_Pos q4 ) { - /* for a cubic segment to possibly reach new maximum, at least */ - /* one of its off-points must stay above the current value */ - while ( q2 > max || q3 > max ) + FT_Pos peak = 0; + FT_Int shift; + + /* This function finds a peak of a cubic segment if it is above 0 */ + /* using iterative bisection of the segment, or returns 0. */ + /* The fixed-point arithmetic of bisection is inherently stable */ + /* but may loose accuracy in the two lowest bits. To compensate, */ + /* we upscale the segment if there is room. Large values may need */ + /* to be downscaled to avoid overflows during bisection. */ + /* It is called with either q2 or q3 positive, which is necessary */ + /* for the peak to exist and avoids undefined FT_MSB. */ + + shift = 27 - + FT_MSB( FT_ABS( q1 ) | FT_ABS( q2 ) | FT_ABS( q3 ) | FT_ABS( q4 ) ); + + if ( shift > 0 ) + { + /* upscaling too much just wastes time */ + if ( shift > 2 ) + shift = 2; + + q1 <<= shift; + q2 <<= shift; + q3 <<= shift; + q4 <<= shift; + } + else + { + q1 >>= -shift; + q2 >>= -shift; + q3 >>= -shift; + q4 >>= -shift; + } + + /* for a peak to exist above 0, the cubic segment must have */ + /* at least one of its control off-points above 0. */ + while ( q2 > 0 || q3 > 0 ) { /* determine which half contains the maximum and split */ if ( q1 + q2 > q3 + q4 ) /* first half */ @@ -240,17 +273,22 @@ /* check whether either end reached the maximum */ if ( q1 == q2 && q1 >= q3 ) { - max = q1; + peak = q1; break; } if ( q3 == q4 && q2 <= q4 ) { - max = q4; + peak = q4; break; } } - return max; + if ( shift > 0 ) + peak >>= shift; + else + peak <<= -shift; + + return peak; } @@ -262,65 +300,17 @@ FT_Pos* min, FT_Pos* max ) { - FT_Pos nmin, nmax; - FT_Int shift; - - /* This function is only called when a control off-point is outside */ - /* the bbox that contains all on-points. It finds a local extremum */ - /* within the segment using iterative bisection of the segment. */ - /* The fixed-point arithmetic of bisection is inherently stable */ - /* but may loose accuracy in the two lowest bits. To compensate, */ - /* we upscale the segment if there is room. Large values may need */ - /* to be downscaled to avoid overflows during bisection. */ - /* The control off-point outside the bbox is likely to have the top */ - /* absolute value among arguments. */ - - shift = 27 - FT_MSB( FT_ABS( p2 ) | FT_ABS( p3 ) ); - - if ( shift > 0 ) - { - /* upscaling too much just wastes time */ - if ( shift > 2 ) - shift = 2; - - p1 <<= shift; - p2 <<= shift; - p3 <<= shift; - p4 <<= shift; - nmin = *min << shift; - nmax = *max << shift; - } - else - { - p1 >>= -shift; - p2 >>= -shift; - p3 >>= -shift; - p4 >>= -shift; - nmin = *min >> -shift; - nmax = *max >> -shift; - } + /* the bbox that contains all on-points. So at least one of the */ + /* conditions below holds and cubic_peak is called with at least one */ + /* non-zero argument. */ - nmax = update_cubic_max( p1, p2, p3, p4, nmax ); + if ( p2 > *max || p3 > *max ) + *max += cubic_peak( p1 - *max, p2 - *max, p3 - *max, p4 - *max ); /* now flip the signs to update the minimum */ - nmin = -update_cubic_max( -p1, -p2, -p3, -p4, -nmin ); - - if ( shift > 0 ) - { - nmin >>= shift; - nmax >>= shift; - } - else - { - nmin <<= -shift; - nmax <<= -shift; - } - - if ( nmin < *min ) - *min = nmin; - if ( nmax > *max ) - *max = nmax; + if ( p2 < *min || p3 < *min ) + *min -= cubic_peak( *min - p1, *min - p2, *min - p3, *min - p4 ); } diff --git a/src/base/ftbitmap.c b/src/base/ftbitmap.c index 5606745..158a428 100644 --- a/src/base/ftbitmap.c +++ b/src/base/ftbitmap.c @@ -378,11 +378,8 @@ static FT_Byte ft_gray_for_premultiplied_srgb_bgra( const FT_Byte* bgra ) { - FT_Long a = bgra[3]; - FT_Long b = bgra[0]; - FT_Long g = bgra[1]; - FT_Long r = bgra[2]; - FT_Long l; + FT_UInt a = bgra[3]; + FT_UInt l; /* Short-circuit transparent color to avoid div-by-zero. */ @@ -397,38 +394,30 @@ * * http://accessibility.kde.org/hsl-adjusted.php * - * We do the computation with integers only. + * We do the computation with integers only, applying a gamma of 2.0. + * We guarantee 32-bit arithmetic to avoid overflow but the resulting + * luminosity fits into 16 bits. + * */ - /* Undo premultification, get the number in a 16.16 form. */ - b = FT_MulDiv( b, 65536, a ); - g = FT_MulDiv( g, 65536, a ); - r = FT_MulDiv( r, 65536, a ); - a = a * 256; - - /* Apply gamma of 2.0 instead of 2.2. */ - b = FT_MulFix( b, b ); - g = FT_MulFix( g, g ); - r = FT_MulFix( r, r ); - - /* Apply coefficients. */ - b = FT_MulFix( b, 4731 /* 0.0722 * 65536 */ ); - g = FT_MulFix( g, 46871 /* 0.7152 * 65536 */ ); - r = FT_MulFix( r, 13933 /* 0.2126 * 65536 */ ); - - l = r + g + b; + l = ( 4732UL /* 0.0722 * 65536 */ * bgra[0] * bgra[0] + + 46871UL /* 0.7152 * 65536 */ * bgra[1] * bgra[1] + + 13933UL /* 0.2126 * 65536 */ * bgra[2] * bgra[2] ) >> 16; /* - * Final transparency can be determined this way: + * Final transparency can be determined as follows. * * - If alpha is zero, we want 0. * - If alpha is zero and luminosity is zero, we want 255. * - If alpha is zero and luminosity is one, we want 0. * - * So the formula is a * (1 - l). + * So the formula is a * (1 - l) = a - l * a. + * + * We still need to undo premultiplication by dividing l by a*a. + * */ - return (FT_Byte)( FT_MulFix( 65535 - l, a ) >> 8 ); + return (FT_Byte)( a - l / a ); } diff --git a/src/base/ftcalc.c b/src/base/ftcalc.c index 6e65583..d0c43e0 100644 --- a/src/base/ftcalc.c +++ b/src/base/ftcalc.c @@ -39,7 +39,8 @@ #include FT_INTERNAL_DEBUG_H #include FT_INTERNAL_OBJECTS_H -#ifdef FT_MULFIX_INLINED + +#ifdef FT_MULFIX_ASSEMBLER #undef FT_MulFix #endif @@ -67,6 +68,16 @@ #define FT_COMPONENT trace_calc + /* transfer sign leaving a positive number */ +#define FT_MOVE_SIGN( x, s ) \ + FT_BEGIN_STMNT \ + if ( x < 0 ) \ + { \ + x = -x; \ + s = -s; \ + } \ + FT_END_STMNT + /* The following three functions are available regardless of whether */ /* FT_LONG64 is defined. */ @@ -99,6 +110,7 @@ : -((-a) & ~0xFFFFL ); } +#ifndef FT_MSB FT_BASE_DEF ( FT_Int ) FT_MSB( FT_UInt32 z ) @@ -106,27 +118,27 @@ FT_Int shift = 0; /* determine msb bit index in `shift' */ - if ( z >= ( 1L << 16 ) ) + if ( z & 0xFFFF0000U ) { z >>= 16; shift += 16; } - if ( z >= ( 1L << 8 ) ) + if ( z & 0x0000FF00U ) { z >>= 8; shift += 8; } - if ( z >= ( 1L << 4 ) ) + if ( z & 0x000000F0U ) { z >>= 4; shift += 4; } - if ( z >= ( 1L << 2 ) ) + if ( z & 0x0000000CU ) { z >>= 2; shift += 2; } - if ( z >= ( 1L << 1 ) ) + if ( z & 0x00000002U ) { /* z >>= 1; */ shift += 1; @@ -135,6 +147,8 @@ return shift; } +#endif /* !FT_MSB */ + /* documentation is in ftcalc.h */ @@ -162,14 +176,13 @@ FT_Long b, FT_Long c ) { - FT_Int s; + FT_Int s = 1; FT_Long d; - s = 1; - if ( a < 0 ) { a = -a; s = -1; } - if ( b < 0 ) { b = -b; s = -s; } - if ( c < 0 ) { c = -c; s = -s; } + FT_MOVE_SIGN( a, s ); + FT_MOVE_SIGN( b, s ); + FT_MOVE_SIGN( c, s ); d = (FT_Long)( c > 0 ? ( (FT_Int64)a * b + ( c >> 1 ) ) / c : 0x7FFFFFFFL ); @@ -185,14 +198,13 @@ FT_Long b, FT_Long c ) { - FT_Int s; + FT_Int s = 1; FT_Long d; - s = 1; - if ( a < 0 ) { a = -a; s = -1; } - if ( b < 0 ) { b = -b; s = -s; } - if ( c < 0 ) { c = -c; s = -s; } + FT_MOVE_SIGN( a, s ); + FT_MOVE_SIGN( b, s ); + FT_MOVE_SIGN( c, s ); d = (FT_Long)( c > 0 ? (FT_Int64)a * b / c : 0x7FFFFFFFL ); @@ -217,17 +229,8 @@ FT_Long c; - if ( a < 0 ) - { - a = -a; - s = -1; - } - - if ( b < 0 ) - { - b = -b; - s = -s; - } + FT_MOVE_SIGN( a, s ); + FT_MOVE_SIGN( b, s ); c = (FT_Long)( ( (FT_Int64)a * b + 0x8000L ) >> 16 ); @@ -243,30 +246,17 @@ FT_DivFix( FT_Long a, FT_Long b ) { - FT_Int32 s; - FT_UInt32 q; + FT_Int s = 1; + FT_Long q; - s = 1; - if ( a < 0 ) - { - a = -a; - s = -1; - } - if ( b < 0 ) - { - b = -b; - s = -s; - } + FT_MOVE_SIGN( a, s ); + FT_MOVE_SIGN( b, s ); - if ( b == 0 ) - /* check for division by 0 */ - q = 0x7FFFFFFFL; - else - /* compute result directly */ - q = (FT_UInt32)( ( ( (FT_UInt64)a << 16 ) + ( b >> 1 ) ) / b ); + q = (FT_Long)( b > 0 ? ( ( (FT_UInt64)a << 16 ) + ( b >> 1 ) ) / b + : 0x7FFFFFFFL ); - return ( s < 0 ? -(FT_Long)q : (FT_Long)q ); + return ( s < 0 ? -q : q ); } @@ -314,25 +304,30 @@ FT_Int i; - q = 0; - r = hi; - - if ( r >= y ) + if ( hi >= y ) return (FT_UInt32)0x7FFFFFFFL; - i = 32; + /* We shift as many bits as we can into the high register, perform */ + /* 32-bit division with modulo there, then work through the remaining */ + /* bits with long division. This optimization is especially noticeable */ + /* for smaller dividends that barely use the high register. */ + + i = 31 - FT_MSB( hi ); + r = ( hi << i ) | ( lo >> ( 32 - i ) ); lo <<= i; /* left 64-bit shift */ + q = r / y; + r -= q * y; /* remainder */ + + i = 32 - i; /* bits remaining in low register */ do { - r <<= 1; q <<= 1; - r |= lo >> 31; + r = ( r << 1 ) | ( lo >> 31 ); lo <<= 1; if ( r >= y ) { r -= y; q |= 1; } - lo <<= 1; } while ( --i ); return q; @@ -344,7 +339,7 @@ FT_Int64* y, FT_Int64 *z ) { - register FT_UInt32 lo, hi; + FT_UInt32 lo, hi; lo = x->lo + y->lo; @@ -355,58 +350,93 @@ } - /* documentation is in freetype.h */ - - /* The FT_MulDiv function has been optimized thanks to ideas from */ - /* Graham Asher. The trick is to optimize computation when everything */ - /* fits within 32-bits (a rather common case). */ + /* The FT_MulDiv function has been optimized thanks to ideas from */ + /* Graham Asher and Alexei Podtelezhnikov. The trick is to optimize */ + /* a rather common case when everything fits within 32-bits. */ + /* */ + /* We compute 'a*b+c/2', then divide it by 'c' (all positive values). */ + /* */ + /* The product of two positive numbers never exceeds the square of */ + /* its mean values. Therefore, we always avoid the overflow by */ + /* imposing */ + /* */ + /* (a + b) / 2 <= sqrt(X - c/2) , */ /* */ - /* we compute 'a*b+c/2', then divide it by 'c'. (positive values) */ + /* where X = 2^32 - 1, the maximum unsigned 32-bit value, and using */ + /* unsigned arithmetic. Now we replace `sqrt' with a linear function */ + /* that is smaller or equal for all values of c in the interval */ + /* [0;X/2]; it should be equal to sqrt(X) and sqrt(3X/4) at the */ + /* endpoints. Substituting the linear solution and explicit numbers */ + /* we get */ /* */ - /* 46340 is FLOOR(SQRT(2^31-1)). */ + /* a + b <= 131071.99 - c / 122291.84 . */ /* */ - /* if ( a <= 46340 && b <= 46340 ) then ( a*b <= 0x7FFEA810 ) */ + /* In practice, we should use a faster and even stronger inequality */ /* */ - /* 0x7FFFFFFF - 0x7FFEA810 = 0x157F0 */ + /* a + b <= 131071 - (c >> 16) */ /* */ - /* if ( c < 0x157F0*2 ) then ( a*b+c/2 <= 0x7FFFFFFF ) */ + /* or, alternatively, */ /* */ - /* and 2*0x157F0 = 176096 */ + /* a + b <= 129894 - (c >> 17) . */ /* */ + /* FT_MulFix, on the other hand, is optimized for a small value of */ + /* the first argument, when the second argument can be much larger. */ + /* This can be achieved by scaling the second argument and the limit */ + /* in the above inequalities. For example, */ + /* */ + /* a + (b >> 8) <= (131071 >> 4) */ + /* */ + /* covers the practical range of use. The actual test below is a bit */ + /* tighter to avoid the border case overflows. */ + /* */ + /* In the case of FT_DivFix, the exact overflow check */ + /* */ + /* a << 16 <= X - c/2 */ + /* */ + /* is scaled down by 2^16 and we use */ + /* */ + /* a <= 65535 - (c >> 17) . */ + + /* documentation is in freetype.h */ FT_EXPORT_DEF( FT_Long ) FT_MulDiv( FT_Long a, FT_Long b, FT_Long c ) { - long s; + FT_Int s = 1; /* XXX: this function does not allow 64-bit arguments */ if ( a == 0 || b == c ) return a; - s = a; a = FT_ABS( a ); - s ^= b; b = FT_ABS( b ); - s ^= c; c = FT_ABS( c ); + FT_MOVE_SIGN( a, s ); + FT_MOVE_SIGN( b, s ); + FT_MOVE_SIGN( c, s ); - if ( a <= 46340L && b <= 46340L && c <= 176095L && c > 0 ) - a = ( a * b + ( c >> 1 ) ) / c; + if ( c == 0 ) + a = 0x7FFFFFFFL; + + else if ( (FT_ULong)a + b <= 129894UL - ( c >> 17 ) ) + a = ( (FT_ULong)a * b + ( c >> 1 ) ) / c; - else if ( (FT_Int32)c > 0 ) + else { FT_Int64 temp, temp2; - ft_multo64( (FT_Int32)a, (FT_Int32)b, &temp ); + ft_multo64( a, b, &temp ); temp2.hi = 0; - temp2.lo = (FT_UInt32)(c >> 1); + temp2.lo = c >> 1; + FT_Add64( &temp, &temp2, &temp ); - a = ft_div64by32( temp.hi, temp.lo, (FT_Int32)c ); + + /* last attempt to ditch long division */ + a = temp.hi == 0 ? temp.lo / c + : ft_div64by32( temp.hi, temp.lo, c ); } - else - a = 0x7FFFFFFFL; return ( s < 0 ? -a : a ); } @@ -417,29 +447,33 @@ FT_Long b, FT_Long c ) { - long s; + FT_Int s = 1; if ( a == 0 || b == c ) return a; - s = a; a = FT_ABS( a ); - s ^= b; b = FT_ABS( b ); - s ^= c; c = FT_ABS( c ); + FT_MOVE_SIGN( a, s ); + FT_MOVE_SIGN( b, s ); + FT_MOVE_SIGN( c, s ); - if ( a <= 46340L && b <= 46340L && c > 0 ) - a = a * b / c; + if ( c == 0 ) + a = 0x7FFFFFFFL; + + else if ( (FT_ULong)a + b <= 131071UL ) + a = (FT_ULong)a * b / c; - else if ( (FT_Int32)c > 0 ) + else { FT_Int64 temp; - ft_multo64( (FT_Int32)a, (FT_Int32)b, &temp ); - a = ft_div64by32( temp.hi, temp.lo, (FT_Int32)c ); + 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 ); } - else - a = 0x7FFFFFFFL; return ( s < 0 ? -a : a ); } @@ -497,7 +531,7 @@ ua = (FT_ULong)a; ub = (FT_ULong)b; - if ( ua <= 2048 && ub <= 1048576L ) + if ( ua + ( ub >> 8 ) <= 8190UL ) ua = ( ua * ub + 0x8000U ) >> 16; else { @@ -515,20 +549,20 @@ #else /* 0 */ - FT_Long s; + FT_Int s = 1; FT_ULong ua, ub; if ( a == 0 || b == 0x10000L ) return a; - s = a; a = FT_ABS( a ); - s ^= b; b = FT_ABS( b ); + FT_MOVE_SIGN( a, s ); + FT_MOVE_SIGN( b, s ); ua = (FT_ULong)a; ub = (FT_ULong)b; - if ( ua <= 2048 && ub <= 1048576L ) + if ( ua + ( ub >> 8 ) <= 8190UL ) ua = ( ua * ub + 0x8000UL ) >> 16; else { @@ -552,23 +586,24 @@ FT_DivFix( FT_Long a, FT_Long b ) { - FT_Int32 s; - FT_UInt32 q; + FT_Int s = 1; + FT_Long q; /* XXX: this function does not allow 64-bit arguments */ - s = (FT_Int32)a; a = FT_ABS( a ); - s ^= (FT_Int32)b; b = FT_ABS( b ); - if ( (FT_UInt32)b == 0 ) + FT_MOVE_SIGN( a, s ); + FT_MOVE_SIGN( b, s ); + + if ( b == 0 ) { /* check for division by 0 */ - q = (FT_UInt32)0x7FFFFFFFL; + q = 0x7FFFFFFFL; } - else if ( ( a >> 16 ) == 0 ) + else if ( a <= 65535L - ( b >> 17 ) ) { /* compute result directly */ - q = (FT_UInt32)( ( (FT_ULong)a << 16 ) + ( b >> 1 ) ) / (FT_UInt32)b; + q = (FT_Long)( ( ( (FT_ULong)a << 16 ) + ( b >> 1 ) ) / b ); } else { @@ -576,138 +611,18 @@ FT_Int64 temp, temp2; - temp.hi = (FT_Int32)( a >> 16 ); - temp.lo = (FT_UInt32)a << 16; + temp.hi = a >> 16; + temp.lo = a << 16; temp2.hi = 0; - temp2.lo = (FT_UInt32)( b >> 1 ); - FT_Add64( &temp, &temp2, &temp ); - q = ft_div64by32( temp.hi, temp.lo, (FT_Int32)b ); - } - - return ( s < 0 ? -(FT_Int32)q : (FT_Int32)q ); - } + temp2.lo = b >> 1; - -#if 0 - - /* documentation is in ftcalc.h */ - - FT_EXPORT_DEF( void ) - FT_MulTo64( FT_Int32 x, - FT_Int32 y, - FT_Int64 *z ) - { - FT_Int32 s; - - - s = x; x = FT_ABS( x ); - s ^= y; y = FT_ABS( y ); - - ft_multo64( x, y, z ); - - if ( s < 0 ) - { - z->lo = (FT_UInt32)-(FT_Int32)z->lo; - z->hi = ~z->hi + !( z->lo ); - } - } - - - /* apparently, the second version of this code is not compiled correctly */ - /* on Mac machines with the MPW C compiler.. tsk, tsk, tsk... */ - -#if 1 - - FT_EXPORT_DEF( FT_Int32 ) - FT_Div64by32( FT_Int64* x, - FT_Int32 y ) - { - FT_Int32 s; - FT_UInt32 q, r, i, lo; - - - s = x->hi; - if ( s < 0 ) - { - x->lo = (FT_UInt32)-(FT_Int32)x->lo; - x->hi = ~x->hi + !x->lo; - } - s ^= y; y = FT_ABS( y ); - - /* Shortcut */ - if ( x->hi == 0 ) - { - if ( y > 0 ) - q = x->lo / y; - else - q = 0x7FFFFFFFL; - - return ( s < 0 ? -(FT_Int32)q : (FT_Int32)q ); - } - - r = x->hi; - lo = x->lo; - - if ( r >= (FT_UInt32)y ) /* we know y is to be treated as unsigned here */ - return ( s < 0 ? 0x80000001UL : 0x7FFFFFFFUL ); - /* Return Max/Min Int32 if division overflow. */ - /* This includes division by zero! */ - q = 0; - for ( i = 0; i < 32; i++ ) - { - r <<= 1; - q <<= 1; - r |= lo >> 31; - - if ( r >= (FT_UInt32)y ) - { - r -= y; - q |= 1; - } - lo <<= 1; - } - - return ( s < 0 ? -(FT_Int32)q : (FT_Int32)q ); - } - -#else /* 0 */ - - FT_EXPORT_DEF( FT_Int32 ) - FT_Div64by32( FT_Int64* x, - FT_Int32 y ) - { - FT_Int32 s; - FT_UInt32 q; - - - s = x->hi; - if ( s < 0 ) - { - x->lo = (FT_UInt32)-(FT_Int32)x->lo; - x->hi = ~x->hi + !x->lo; - } - s ^= y; y = FT_ABS( y ); - - /* Shortcut */ - if ( x->hi == 0 ) - { - if ( y > 0 ) - q = ( x->lo + ( y >> 1 ) ) / y; - else - q = 0x7FFFFFFFL; - - return ( s < 0 ? -(FT_Int32)q : (FT_Int32)q ); + FT_Add64( &temp, &temp2, &temp ); + q = (FT_Long)ft_div64by32( temp.hi, temp.lo, b ); } - q = ft_div64by32( x->hi, x->lo, y ); - - return ( s < 0 ? -(FT_Int32)q : (FT_Int32)q ); + return ( s < 0 ? -q : q ); } -#endif /* 0 */ - -#endif /* 0 */ - #endif /* FT_LONG64 */ diff --git a/src/base/ftlcdfil.c b/src/base/ftlcdfil.c index 852fb32..4aefb68 100644 --- a/src/base/ftlcdfil.c +++ b/src/base/ftlcdfil.c @@ -4,7 +4,7 @@ /* */ /* FreeType API for color filtering of subpixel bitmap glyphs (body). */ /* */ -/* Copyright 2006, 2008-2010, 2013 by */ +/* Copyright 2006, 2008-2010, 2013, 2014 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -46,9 +46,12 @@ FT_Byte* line = bitmap->buffer; + /* `fir' and `pix' must be at least 32 bit wide, since the sum of */ + /* the values in `weights' can exceed 0xFF */ + for ( ; height > 0; height--, line += bitmap->pitch ) { - FT_UInt fir[5]; + FT_UInt fir[4]; /* below, `pix' is used as the 5th element */ FT_UInt val1, xx; @@ -57,7 +60,6 @@ fir[1] = weights[3] * val1; fir[2] = weights[4] * val1; fir[3] = 0; - fir[4] = 0; val1 = line[1]; fir[0] += weights[1] * val1; @@ -78,7 +80,7 @@ fir[3] = weights[4] * val; pix >>= 8; - pix |= -( pix >> 8 ); + pix |= (FT_UInt)-(FT_Int)( pix >> 8 ); line[xx - 2] = (FT_Byte)pix; } @@ -87,11 +89,11 @@ pix = fir[0] >> 8; - pix |= -( pix >> 8 ); + pix |= (FT_UInt)-(FT_Int)( pix >> 8 ); line[xx - 2] = (FT_Byte)pix; pix = fir[1] >> 8; - pix |= -( pix >> 8 ); + pix |= (FT_UInt)-(FT_Int)( pix >> 8 ); line[xx - 1] = (FT_Byte)pix; } } @@ -107,7 +109,7 @@ for ( ; width > 0; width--, column++ ) { FT_Byte* col = column; - FT_UInt fir[5]; + FT_UInt fir[4]; /* below, `pix' is used as the 5th element */ FT_UInt val1, yy; @@ -116,7 +118,6 @@ fir[1] = weights[3] * val1; fir[2] = weights[4] * val1; fir[3] = 0; - fir[4] = 0; col += pitch; val1 = col[0]; @@ -139,7 +140,7 @@ fir[3] = weights[4] * val; pix >>= 8; - pix |= -( pix >> 8 ); + pix |= (FT_UInt)-(FT_Int)( pix >> 8 ); col[-2 * pitch] = (FT_Byte)pix; col += pitch; } @@ -149,11 +150,11 @@ pix = fir[0] >> 8; - pix |= -( pix >> 8 ); + pix |= (FT_UInt)-(FT_Int)( pix >> 8 ); col[-2 * pitch] = (FT_Byte)pix; pix = fir[1] >> 8; - pix |= -( pix >> 8 ); + pix |= (FT_UInt)-(FT_Int)( pix >> 8 ); col[-pitch] = (FT_Byte)pix; } } diff --git a/src/base/ftobjs.c b/src/base/ftobjs.c index 6f32336..cc56105 100644 --- a/src/base/ftobjs.c +++ b/src/base/ftobjs.c @@ -4881,6 +4881,8 @@ *p_arg1 = subg->arg1; *p_arg2 = subg->arg2; *p_transform = subg->transform; + + error = FT_Err_Ok; } return error; diff --git a/src/base/ftoutln.c b/src/base/ftoutln.c index 4a39dcd..632b6d2 100644 --- a/src/base/ftoutln.c +++ b/src/base/ftoutln.c @@ -1045,6 +1045,10 @@ FT_Outline_Get_CBox( outline, &cbox ); + /* Handle collapsed outlines to avoid undefined FT_MSB. */ + if ( cbox.xMin == cbox.xMax || cbox.yMin == cbox.yMax ) + return FT_ORIENTATION_NONE; + xshift = FT_MSB( FT_ABS( cbox.xMax ) | FT_ABS( cbox.xMin ) ) - 14; xshift = FT_MAX( xshift, 0 ); diff --git a/src/base/fttrigon.c b/src/base/fttrigon.c index 4ffdcb7..e3ce8a6 100644 --- a/src/base/fttrigon.c +++ b/src/base/fttrigon.c @@ -111,6 +111,7 @@ #endif /* !FT_LONG64 */ + /* undefined and never called for zero vector */ static FT_Int ft_trig_prenorm( FT_Vector* vec ) { diff --git a/src/base/ftutil.c b/src/base/ftutil.c index 879d027..9f37189 100644 --- a/src/base/ftutil.c +++ b/src/base/ftutil.c @@ -411,26 +411,4 @@ } - FT_BASE_DEF( FT_UInt32 ) - ft_highpow2( FT_UInt32 value ) - { - FT_UInt32 value2; - - - /* - * We simply clear the lowest bit in each iteration. When - * we reach 0, we know that the previous value was our result. - */ - for ( ;; ) - { - value2 = value & (value - 1); /* clear lowest bit */ - if ( value2 == 0 ) - break; - - value = value2; - } - return value; - } - - /* END */ diff --git a/src/bdf/bdfdrivr.c b/src/bdf/bdfdrivr.c index 5a1c296..d7649ab 100644 --- a/src/bdf/bdfdrivr.c +++ b/src/bdf/bdfdrivr.c @@ -182,7 +182,7 @@ THE SOFTWARE. } - FT_CALLBACK_TABLE_DEF + static const FT_CMap_ClassRec bdf_cmap_class = { sizeof ( BDF_CMapRec ), diff --git a/src/cache/ftcbasic.c b/src/cache/ftcbasic.c index 84d336d..01be88c 100644 --- a/src/cache/ftcbasic.c +++ b/src/cache/ftcbasic.c @@ -4,7 +4,7 @@ /* */ /* The FreeType basic cache interface (body). */ /* */ -/* Copyright 2003-2007, 2009-2011, 2013 by */ +/* Copyright 2003-2007, 2009-2011, 2013, 2014 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -229,7 +229,7 @@ * */ - FT_CALLBACK_TABLE_DEF + static const FTC_IFamilyClassRec ftc_basic_image_family_class = { { @@ -243,7 +243,7 @@ }; - FT_CALLBACK_TABLE_DEF + static const FTC_GCacheClassRec ftc_basic_image_cache_class = { { @@ -415,7 +415,7 @@ * */ - FT_CALLBACK_TABLE_DEF + static const FTC_SFamilyClassRec ftc_basic_sbit_family_class = { { @@ -430,7 +430,7 @@ }; - FT_CALLBACK_TABLE_DEF + static const FTC_GCacheClassRec ftc_basic_sbit_cache_class = { { diff --git a/src/cache/ftccmap.c b/src/cache/ftccmap.c index 848349b..b2e9609 100644 --- a/src/cache/ftccmap.c +++ b/src/cache/ftccmap.c @@ -4,7 +4,7 @@ /* */ /* FreeType CharMap cache (body) */ /* */ -/* Copyright 2000-2013 by */ +/* Copyright 2000-2014 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -202,7 +202,7 @@ /*************************************************************************/ - FT_CALLBACK_TABLE_DEF + static const FTC_CacheClassRec ftc_cmap_cache_class = { ftc_cmap_node_new, diff --git a/src/cache/ftcmanag.c b/src/cache/ftcmanag.c index 4eb2c5b..a65f94d 100644 --- a/src/cache/ftcmanag.c +++ b/src/cache/ftcmanag.c @@ -4,7 +4,7 @@ /* */ /* FreeType Cache Manager (body). */ /* */ -/* Copyright 2000-2006, 2008-2010, 2013 by */ +/* Copyright 2000-2006, 2008-2010, 2013, 2014 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -151,7 +151,7 @@ } - FT_CALLBACK_TABLE_DEF + static const FTC_MruListClassRec ftc_size_list_class = { sizeof ( FTC_SizeNodeRec ), @@ -290,7 +290,7 @@ } - FT_CALLBACK_TABLE_DEF + static const FTC_MruListClassRec ftc_face_list_class = { sizeof ( FTC_FaceNodeRec), diff --git a/src/cff/cf2font.c b/src/cff/cf2font.c index 6e99dc2..3d2c22a 100644 --- a/src/cff/cf2font.c +++ b/src/cff/cf2font.c @@ -105,6 +105,7 @@ /* adjusting for emRatio converts darkenAmount to character */ /* space (font units). */ CF2_Fixed stemWidthPer1000, scaledStem; + FT_Int logBase2; *darkenAmount = 0; @@ -131,26 +132,33 @@ /* convert from true character space to 1000 unit character space; */ /* add synthetic emboldening effect */ - /* we have to assure that the computation of `scaledStem' */ - /* and `stemWidthPer1000' don't overflow */ + /* `stemWidthPer1000' will not overflow for a legitimate font */ stemWidthPer1000 = FT_MulFix( stemWidth + boldenAmount, emRatio ); - if ( emRatio > CF2_FIXED_ONE && - stemWidthPer1000 <= ( stemWidth + boldenAmount ) ) - { - stemWidthPer1000 = 0; /* to pacify compiler */ - scaledStem = cf2_intToFixed( x4 ); - } + /* `scaledStem' can easily overflow, so we must clamp its maximum */ + /* value; the test doesn't need to be precise, but must be */ + /* conservative. The clamp value (default 2333) where */ + /* `darkenAmount' is zero is well below the overflow value of */ + /* 32767. */ + /* */ + /* FT_MSB computes the integer part of the base 2 logarithm. The */ + /* number of bits for the product is 1 or 2 more than the sum of */ + /* logarithms; remembering that the 16 lowest bits of the fraction */ + /* are dropped this is correct to within a factor of almost 4. */ + /* For example, 0x80.0000 * 0x80.0000 = 0x4000.0000 is 23+23 and */ + /* is flagged as possible overflow because 0xff.ffff * 0xff.ffff = */ + /* 0xffff.fe00 is also 23+23. */ + + logBase2 = FT_MSB( (FT_UInt32)stemWidthPer1000 ) + + FT_MSB( (FT_UInt32)ppem ); + + if ( logBase2 >= 46 ) + /* possible overflow */ + scaledStem = cf2_intToFixed( x4 ); else - { scaledStem = FT_MulFix( stemWidthPer1000, ppem ); - if ( ppem > CF2_FIXED_ONE && - scaledStem <= stemWidthPer1000 ) - scaledStem = cf2_intToFixed( x4 ); - } - /* now apply the darkening parameters */ if ( scaledStem < cf2_intToFixed( x1 ) ) diff --git a/src/cff/cf2hints.c b/src/cff/cf2hints.c index 5853d77..81049f4 100644 --- a/src/cff/cf2hints.c +++ b/src/cff/cf2hints.c @@ -1560,7 +1560,7 @@ { /* -y */ *x = -glyphpath->xOffset; - *y = glyphpath->xOffset; + *y = glyphpath->yOffset; } else { diff --git a/src/gzip/inftrees.c b/src/gzip/inftrees.c index ef53652..56f52b1 100644 --- a/src/gzip/inftrees.c +++ b/src/gzip/inftrees.c @@ -115,16 +115,16 @@ uIntf *v /* working area: values in order of bit length */ uInt f; /* i repeats in table every f entries */ int g; /* maximum code length */ int h; /* table level */ - register uInt i; /* counter, current code */ - register uInt j; /* counter */ - register int k; /* number of bits in current code */ + uInt i; /* counter, current code */ + uInt j; /* counter */ + int k; /* number of bits in current code */ int l; /* bits per table (returned in m) */ uInt mask; /* (1 << w) - 1, to avoid cc -O bug on HP */ - register uIntf *p; /* pointer into c[], b[], or v[] */ + uIntf *p; /* pointer into c[], b[], or v[] */ inflate_huft *q; /* points to current table */ struct inflate_huft_s r; /* table entry for structure assignment */ inflate_huft *u[BMAX]; /* table stack */ - register int w; /* bits before this table == (l * h) */ + int w; /* bits before this table == (l * h) */ uInt x[BMAX+1]; /* bit offsets, then code stack */ uIntf *xp; /* pointer into x */ int y; /* number of dummy codes added */ diff --git a/src/pcf/pcfdrivr.c b/src/pcf/pcfdrivr.c index 748cbca..5183f6f 100644 --- a/src/pcf/pcfdrivr.c +++ b/src/pcf/pcfdrivr.c @@ -2,7 +2,7 @@ FreeType font driver for pcf files - Copyright (C) 2000-2004, 2006-2011, 2013 by + Copyright (C) 2000-2004, 2006-2011, 2013, 2014 by Francesco Zappa Nardelli Permission is hereby granted, free of charge, to any person obtaining a copy @@ -189,7 +189,7 @@ THE SOFTWARE. } - FT_CALLBACK_TABLE_DEF + static const FT_CMap_ClassRec pcf_cmap_class = { sizeof ( PCF_CMapRec ), diff --git a/src/pfr/pfrdrivr.c b/src/pfr/pfrdrivr.c index 4c43947..188aa0d 100644 --- a/src/pfr/pfrdrivr.c +++ b/src/pfr/pfrdrivr.c @@ -4,7 +4,7 @@ /* */ /* FreeType PFR driver interface (body). */ /* */ -/* Copyright 2002-2004, 2006, 2008, 2010, 2011, 2013 by */ +/* Copyright 2002-2004, 2006, 2008, 2010, 2011, 2013, 2014 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -134,7 +134,7 @@ } - FT_CALLBACK_TABLE_DEF + static const FT_Service_PfrMetricsRec pfr_metrics_service_rec = { pfr_get_metrics, diff --git a/src/pfr/pfrobjs.c b/src/pfr/pfrobjs.c index 194d2df..0c89242 100644 --- a/src/pfr/pfrobjs.c +++ b/src/pfr/pfrobjs.c @@ -4,7 +4,7 @@ /* */ /* FreeType PFR object methods (body). */ /* */ -/* Copyright 2002-2008, 2010-2011, 2013 by */ +/* Copyright 2002-2008, 2010-2011, 2013, 2014 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -23,6 +23,7 @@ #include "pfrsbit.h" #include FT_OUTLINE_H #include FT_INTERNAL_DEBUG_H +#include FT_INTERNAL_CALC_H #include FT_TRUETYPE_IDS_H #include "pfrerror.h" @@ -515,7 +516,7 @@ { FT_UInt count = item->pair_count; FT_UInt size = item->pair_size; - FT_UInt power = (FT_UInt)ft_highpow2( (FT_UInt32)count ); + FT_UInt power = 1 << FT_MSB( count ); FT_UInt probe = power * size; FT_UInt extra = count - power; FT_Byte* base = stream->cursor; diff --git a/src/psaux/psconv.c b/src/psaux/psconv.c index d0d8861..7792a62 100644 --- a/src/psaux/psconv.c +++ b/src/psaux/psconv.c @@ -250,7 +250,8 @@ if ( c < 0 || c >= 10 ) break; - if ( decimal < 0xCCCCCCCL ) + /* only add digit if we don't overflow */ + if ( divider < 0xCCCCCCCL && decimal < 0xCCCCCCCL ) { decimal = decimal * 10 + c; diff --git a/src/raster/ftraster.c b/src/raster/ftraster.c index ddecc80..abbecb7 100644 --- a/src/raster/ftraster.c +++ b/src/raster/ftraster.c @@ -2284,6 +2284,8 @@ Long e1, e2; Byte* target; + Int dropOutControl = left->flags & 7; + FT_UNUSED( y ); FT_UNUSED( left ); FT_UNUSED( right ); @@ -2293,7 +2295,8 @@ e1 = TRUNC( CEILING( x1 ) ); - if ( x2 - x1 - ras.precision <= ras.precision_jitter ) + if ( dropOutControl != 2 && + x2 - x1 - ras.precision <= ras.precision_jitter ) e2 = e1; else e2 = TRUNC( FLOOR( x2 ) ); diff --git a/src/sfnt/pngshim.c b/src/sfnt/pngshim.c index 878de1f..9afbe5a 100644 --- a/src/sfnt/pngshim.c +++ b/src/sfnt/pngshim.c @@ -4,7 +4,7 @@ /* */ /* PNG Bitmap glyph support. */ /* */ -/* Copyright 2013 by Google, Inc. */ +/* Copyright 2013, 2014 by Google, Inc. */ /* Written by Stuart Gill and Behdad Esfahbod. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -129,7 +129,7 @@ *error = FT_THROW( Out_Of_Memory ); #ifdef PNG_SETJMP_SUPPORTED - longjmp( png_jmpbuf( png ), 1 ); + ft_longjmp( png_jmpbuf( png ), 1 ); #endif /* if we get here, then we have no choice but to abort ... */ } diff --git a/src/sfnt/sfobjs.c b/src/sfnt/sfobjs.c index a31c77c..44aa467 100644 --- a/src/sfnt/sfobjs.c +++ b/src/sfnt/sfobjs.c @@ -4,7 +4,7 @@ /* */ /* SFNT object management (base). */ /* */ -/* Copyright 1996-2008, 2010-2013 by */ +/* Copyright 1996-2008, 2010-2014 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -348,29 +348,22 @@ } -#define WRITE_BYTE( p, v ) \ - do \ - { \ - *(p)++ = (v) >> 0; \ - \ +#define WRITE_USHORT( p, v ) \ + do \ + { \ + *(p)++ = (FT_Byte)( (v) >> 8 ); \ + *(p)++ = (FT_Byte)( (v) >> 0 ); \ + \ } while ( 0 ) -#define WRITE_USHORT( p, v ) \ - do \ - { \ - *(p)++ = (v) >> 8; \ - *(p)++ = (v) >> 0; \ - \ - } while ( 0 ) - -#define WRITE_ULONG( p, v ) \ - do \ - { \ - *(p)++ = (v) >> 24; \ - *(p)++ = (v) >> 16; \ - *(p)++ = (v) >> 8; \ - *(p)++ = (v) >> 0; \ - \ +#define WRITE_ULONG( p, v ) \ + do \ + { \ + *(p)++ = (FT_Byte)( (v) >> 24 ); \ + *(p)++ = (FT_Byte)( (v) >> 16 ); \ + *(p)++ = (FT_Byte)( (v) >> 8 ); \ + *(p)++ = (FT_Byte)( (v) >> 0 ); \ + \ } while ( 0 ) @@ -661,6 +654,8 @@ } else { +#ifdef FT_CONFIG_OPTION_USE_ZLIB + /* Uncompress with zlib. */ FT_ULong output_len = table->OrigLength; @@ -675,6 +670,13 @@ error = FT_THROW( Invalid_Table ); goto Exit; } + +#else /* !FT_CONFIG_OPTION_USE_ZLIB */ + + error = FT_THROW( Unimplemented_Feature ); + goto Exit; + +#endif /* !FT_CONFIG_OPTION_USE_ZLIB */ } FT_FRAME_EXIT(); @@ -717,7 +719,6 @@ } -#undef WRITE_BYTE #undef WRITE_USHORT #undef WRITE_ULONG diff --git a/src/sfnt/ttcmap.c b/src/sfnt/ttcmap.c index c717f5f..f9acf5d 100644 --- a/src/sfnt/ttcmap.c +++ b/src/sfnt/ttcmap.c @@ -3473,10 +3473,9 @@ /* only recognize format 0 */ if ( TT_NEXT_USHORT( p ) != 0 ) { - p -= 2; FT_ERROR(( "tt_face_build_cmaps:" " unsupported `cmap' table format = %d\n", - TT_PEEK_USHORT( p ) )); + TT_PEEK_USHORT( p - 2) )); return FT_THROW( Invalid_Table ); } diff --git a/src/sfnt/ttpost.c b/src/sfnt/ttpost.c index 47a85c0..99d8005 100644 --- a/src/sfnt/ttpost.c +++ b/src/sfnt/ttpost.c @@ -5,7 +5,7 @@ /* Postcript name table processing for TrueType and OpenType fonts */ /* (body). */ /* */ -/* Copyright 1996-2003, 2006-2010, 2013 by */ +/* Copyright 1996-2003, 2006-2010, 2013, 2014 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -64,12 +64,12 @@ #define MAC_NAME( x ) ( (FT_String*)tt_post_default_names[x] ) - /* the 258 default Mac PS glyph names */ + /* the 258 default Mac PS glyph names; see file `tools/glnames.py' */ static const FT_String* const tt_post_default_names[258] = { /* 0 */ - ".notdef", ".null", "CR", "space", "exclam", + ".notdef", ".null", "nonmarkingreturn", "space", "exclam", "quotedbl", "numbersign", "dollar", "percent", "ampersand", /* 10 */ "quotesingle", "parenleft", "parenright", "asterisk", "plus", @@ -120,7 +120,7 @@ "ae", "oslash", "questiondown", "exclamdown", "logicalnot", "radical", "florin", "approxequal", "Delta", "guillemotleft", /* 170 */ - "guillemotright", "ellipsis", "nbspace", "Agrave", "Atilde", + "guillemotright", "ellipsis", "nonbreakingspace", "Agrave", "Atilde", "Otilde", "OE", "oe", "endash", "emdash", /* 180 */ "quotedblleft", "quotedblright", "quoteleft", "quoteright", "divide", @@ -144,8 +144,8 @@ "multiply", "onesuperior", "twosuperior", "threesuperior", "onehalf", "onequarter", "threequarters", "franc", "Gbreve", "gbreve", /* 250 */ - "Idot", "Scedilla", "scedilla", "Cacute", "cacute", - "Ccaron", "ccaron", "dmacron", + "Idotaccent", "Scedilla", "scedilla", "Cacute", "cacute", + "Ccaron", "ccaron", "dcroat", }; diff --git a/src/sfnt/ttsbit.c b/src/sfnt/ttsbit.c index 8ff7b9d..180d559 100644 --- a/src/sfnt/ttsbit.c +++ b/src/sfnt/ttsbit.c @@ -256,7 +256,8 @@ case TT_SBIT_TABLE_TYPE_SBIX: { FT_Stream stream = face->root.stream; - FT_UInt offset, ppem, resolution, upem; + FT_UInt offset, upem; + FT_UShort ppem, resolution; TT_HoriHeader *hori; FT_ULong table_size; @@ -800,12 +801,12 @@ FT_Error error = FT_Err_Ok; FT_UInt num_components, nn; - FT_Char horiBearingX = decoder->metrics->horiBearingX; - FT_Char horiBearingY = decoder->metrics->horiBearingY; - FT_Byte horiAdvance = decoder->metrics->horiAdvance; - FT_Char vertBearingX = decoder->metrics->vertBearingX; - FT_Char vertBearingY = decoder->metrics->vertBearingY; - FT_Byte vertAdvance = decoder->metrics->vertAdvance; + FT_Char horiBearingX = (FT_Char)decoder->metrics->horiBearingX; + FT_Char horiBearingY = (FT_Char)decoder->metrics->horiBearingY; + FT_Byte horiAdvance = (FT_Byte)decoder->metrics->horiAdvance; + FT_Char vertBearingX = (FT_Char)decoder->metrics->vertBearingX; + FT_Char vertBearingY = (FT_Char)decoder->metrics->vertBearingY; + FT_Byte vertAdvance = (FT_Byte)decoder->metrics->vertAdvance; if ( p + 2 > limit ) @@ -1352,10 +1353,11 @@ tt_face_get_metrics( face, FALSE, glyph_index, &abearing, &aadvance ); - metrics->horiBearingX = originOffsetX; - metrics->horiBearingY = -originOffsetY + metrics->height; - metrics->horiAdvance = aadvance * face->root.size->metrics.x_ppem / - face->header.Units_Per_EM; + metrics->horiBearingX = (FT_Short)originOffsetX; + metrics->horiBearingY = (FT_Short)( -originOffsetY + metrics->height ); + metrics->horiAdvance = (FT_Short)( aadvance * + face->root.size->metrics.x_ppem / + face->header.Units_Per_EM ); } return error; diff --git a/src/smooth/ftgrays.c b/src/smooth/ftgrays.c index 425911a..27be966 100644 --- a/src/smooth/ftgrays.c +++ b/src/smooth/ftgrays.c @@ -98,6 +98,9 @@ #define FT_ERR_XCAT( x, y ) x ## y #define FT_ERR_CAT( x, y ) FT_ERR_XCAT( x, y ) +#define FT_BEGIN_STMNT do { +#define FT_END_STMNT } while ( 0 ) + /* define this to dump debugging information */ /* #define FT_DEBUG_LEVEL_TRACE */ diff --git a/src/tools/afblue.pl b/src/tools/afblue.pl index 58aa2a0..60fe696 100644 --- a/src/tools/afblue.pl +++ b/src/tools/afblue.pl @@ -63,8 +63,8 @@ my $enum_element_re = qr/ ^ \s* ( [A-Za-z0-9_]+ ) \s* $ /x; # '#' '\n' my $preprocessor_re = qr/ ^ \# /x; -# '/' '/' '\n' -my $comment_re = qr| ^ // |x; +# [] '/' '/' '\n' +my $comment_re = qr| ^ \s* // |x; # empty line my $whitespace_only_re = qr/ ^ \s* $ /x; @@ -159,6 +159,9 @@ sub convert_ascii_chars # A series of ASCII characters in the printable range. my $s = shift; + # We ignore spaces. + $s =~ s/ //g; + my $count = $s =~ s/\G(.)/'$1', /g; $curr_offset += $count; $curr_elem_size += $count; diff --git a/src/truetype/ttgload.c b/src/truetype/ttgload.c index 5f676a2..ff2b339 100644 --- a/src/truetype/ttgload.c +++ b/src/truetype/ttgload.c @@ -4,7 +4,7 @@ /* */ /* TrueType Glyph Loader (body). */ /* */ -/* Copyright 1996-2013 */ +/* Copyright 1996-2014 */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -99,13 +99,13 @@ else if ( face->os2.version != 0xFFFFU ) { - *tsb = face->os2.sTypoAscender - yMax; + *tsb = (FT_Short)( face->os2.sTypoAscender - yMax ); *ah = face->os2.sTypoAscender - face->os2.sTypoDescender; } else { - *tsb = face->horizontal.Ascender - yMax; + *tsb = (FT_Short)( face->horizontal.Ascender - yMax ); *ah = face->horizontal.Ascender - face->horizontal.Descender; } @@ -2120,7 +2120,7 @@ FT_Bool reexecute = FALSE; - if ( !size->cvt_ready ) + if ( size->bytecode_ready < 0 || size->cvt_ready < 0 ) { FT_Error error = tt_size_ready_bytecode( size, pedantic ); @@ -2128,6 +2128,10 @@ if ( error ) return error; } + else if ( size->bytecode_ready ) + return size->bytecode_ready; + else if ( size->cvt_ready ) + return size->cvt_ready; /* query new execution context */ exec = size->debug ? size->context @@ -2238,12 +2242,15 @@ if ( reexecute ) { - FT_UInt i; + FT_UInt i; + FT_Error error; for ( i = 0; i < size->cvt_size; i++ ) size->cvt[i] = FT_MulFix( face->cvt[i], size->ttmetrics.scale ); - tt_size_run_prep( size, pedantic ); + error = tt_size_run_prep( size, pedantic ); + if ( error ) + return error; } /* see whether the cvt program has disabled hinting */ diff --git a/src/truetype/ttinterp.c b/src/truetype/ttinterp.c index 56e8fa7..7d0248b 100644 --- a/src/truetype/ttinterp.c +++ b/src/truetype/ttinterp.c @@ -172,6 +172,9 @@ #define CUR_Func_round( d, c ) \ CUR.func_round( EXEC_ARG_ d, c ) +#define CUR_Func_cur_ppem() \ + CUR.func_cur_ppem( EXEC_ARG ) + #define CUR_Func_read_cvt( index ) \ CUR.func_read_cvt( EXEC_ARG_ index ) @@ -184,12 +187,6 @@ #define CURRENT_Ratio() \ Current_Ratio( EXEC_ARG ) -#define CURRENT_Ppem() \ - Current_Ppem( EXEC_ARG ) - -#define CUR_Ppem() \ - Cur_PPEM( EXEC_ARG ) - #define INS_SxVTL( a, b, c, d ) \ Ins_SxVTL( EXEC_ARG_ a, b, c, d ) @@ -1446,7 +1443,7 @@ TT_MulFix14_arm( FT_Int32 a, FT_Int b ) { - register FT_Int32 t, t2; + FT_Int32 t, t2; #if defined( __CC_ARM ) || defined( __ARMCC__ ) @@ -1706,9 +1703,16 @@ } - static FT_Long + FT_CALLBACK_DEF( FT_Long ) Current_Ppem( EXEC_OP ) { + return CUR.tt_metrics.ppem; + } + + + FT_CALLBACK_DEF( FT_Long ) + Current_Ppem_Stretched( EXEC_OP ) + { return FT_MulFix( CUR.tt_metrics.ppem, CURRENT_Ratio() ); } @@ -3089,7 +3093,7 @@ #define DO_MPPEM \ - args[0] = CURRENT_Ppem(); + args[0] = CUR_Func_cur_ppem(); /* Note: The pointSize should be irrelevant in a given font program; */ @@ -3102,7 +3106,7 @@ #else #define DO_MPS \ - args[0] = CURRENT_Ppem(); + args[0] = CUR_Func_cur_ppem(); #endif /* 0 */ @@ -7487,9 +7491,9 @@ static void Ins_DELTAP( INS_ARG ) { - FT_ULong k, nump; + FT_ULong nump, k; FT_UShort A; - FT_ULong C; + FT_ULong C, P; FT_Long B; #ifdef TT_CONFIG_OPTION_SUBPIXEL_HINTING FT_UShort B1, B2; @@ -7523,6 +7527,7 @@ } #endif + P = (FT_ULong)CUR_Func_cur_ppem(); nump = (FT_ULong)args[0]; /* some points theoretically may occur more than once, thus UShort isn't enough */ @@ -7567,7 +7572,7 @@ C += CUR.GS.delta_base; - if ( CURRENT_Ppem() == (FT_Long)C ) + if ( P == C ) { B = ( (FT_ULong)B & 0xF ) - 8; if ( B >= 0 ) @@ -7596,9 +7601,9 @@ else if ( CUR.ignore_x_mode ) { if ( CUR.GS.freeVector.y != 0 ) - B1 = CUR.zp0.cur[A].y; + B1 = (FT_UShort)CUR.zp0.cur[A].y; else - B1 = CUR.zp0.cur[A].x; + B1 = (FT_UShort)CUR.zp0.cur[A].x; #if 0 /* Standard Subpixel Hinting: Allow y move. */ @@ -7615,7 +7620,7 @@ !( CUR.sph_tweak_flags & SPH_TWEAK_ALWAYS_SKIP_DELTAP ) ) { /* save the y value of the point now; compare after move */ - B1 = CUR.zp0.cur[A].y; + B1 = (FT_UShort)CUR.zp0.cur[A].y; if ( CUR.sph_tweak_flags & SPH_TWEAK_ROUND_NONPIXEL_Y_MOVES ) B = FT_PIX_ROUND( B1 + B ) - B1; @@ -7627,7 +7632,7 @@ CUR_Func_move( &CUR.zp0, A, B ); } - B2 = CUR.zp0.cur[A].y; + B2 = (FT_UShort)CUR.zp0.cur[A].y; /* Reverse this move if it results in a disallowed move */ if ( CUR.GS.freeVector.y != 0 && @@ -7667,7 +7672,7 @@ Ins_DELTAC( INS_ARG ) { FT_ULong nump, k; - FT_ULong A, C; + FT_ULong A, C, P; FT_Long B; @@ -7691,6 +7696,7 @@ } #endif + P = (FT_ULong)CUR_Func_cur_ppem(); nump = (FT_ULong)args[0]; for ( k = 1; k <= nump; k++ ) @@ -7736,7 +7742,7 @@ C += CUR.GS.delta_base; - if ( CURRENT_Ppem() == (FT_Long)C ) + if ( P == C ) { B = ( (FT_ULong)B & 0xF ) - 8; if ( B >= 0 ) @@ -8269,11 +8275,12 @@ CUR.iup_called = FALSE; #endif /* TT_CONFIG_OPTION_SUBPIXEL_HINTING */ - /* set CVT functions */ + /* set PPEM and CVT functions */ CUR.tt_metrics.ratio = 0; if ( CUR.metrics.x_ppem != CUR.metrics.y_ppem ) { /* non-square pixels, use the stretched routines */ + CUR.func_cur_ppem = Current_Ppem_Stretched; CUR.func_read_cvt = Read_CVT_Stretched; CUR.func_write_cvt = Write_CVT_Stretched; CUR.func_move_cvt = Move_CVT_Stretched; @@ -8281,6 +8288,7 @@ else { /* square pixels, use normal routines */ + CUR.func_cur_ppem = Current_Ppem; CUR.func_read_cvt = Read_CVT; CUR.func_write_cvt = Write_CVT; CUR.func_move_cvt = Move_CVT; @@ -9035,10 +9043,13 @@ /* If any errors have occurred, function tables may be broken. */ /* Force a re-execution of `prep' and `fpgm' tables if no */ /* bytecode debugger is run. */ - if ( CUR.error && !CUR.instruction_trap ) + if ( CUR.error + && !CUR.instruction_trap + && CUR.curRange == tt_coderange_glyph ) { FT_TRACE1(( " The interpreter returned error 0x%x\n", CUR.error )); - exc->size->cvt_ready = FALSE; + exc->size->bytecode_ready = -1; + exc->size->cvt_ready = -1; } return CUR.error; diff --git a/src/truetype/ttinterp.h b/src/truetype/ttinterp.h index 1d8825d..3cfc859 100644 --- a/src/truetype/ttinterp.h +++ b/src/truetype/ttinterp.h @@ -4,7 +4,7 @@ /* */ /* TrueType bytecode interpreter (specification). */ /* */ -/* Copyright 1996-2007, 2010, 2012-2013 by */ +/* Copyright 1996-2007, 2010, 2012-2014 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -81,6 +81,10 @@ FT_BEGIN_HEADER (*TT_Project_Func)( EXEC_OP_ FT_Pos dx, FT_Pos dy ); + /* getting current ppem. Take care of non-square pixels if necessary */ + typedef FT_Long + (*TT_Cur_Ppem_Func)( EXEC_OP ); + /* reading a cvt value. Take care of non-square pixels if necessary */ typedef FT_F26Dot6 (*TT_Get_CVT_Func)( EXEC_OP_ FT_ULong idx ); @@ -228,11 +232,6 @@ FT_BEGIN_HEADER FT_F26Dot6 phase; /* `SuperRounding' */ FT_F26Dot6 threshold; -#if 0 - /* this seems to be unused */ - FT_Int cur_ppem; /* ppem along the current proj vector */ -#endif - FT_Bool instruction_trap; /* If `True', the interpreter will */ /* exit after each instruction */ @@ -254,6 +253,8 @@ FT_BEGIN_HEADER TT_Move_Func func_move; /* current point move function */ TT_Move_Func func_move_orig; /* move original position function */ + TT_Cur_Ppem_Func func_cur_ppem; /* get current proj. ppem value */ + TT_Get_CVT_Func func_read_cvt; /* read a cvt entry */ TT_Set_CVT_Func func_write_cvt; /* write a cvt entry (in pixels) */ TT_Set_CVT_Func func_move_cvt; /* incr a cvt entry (in pixels) */ diff --git a/src/truetype/ttobjs.c b/src/truetype/ttobjs.c index 4adba58..05a121c 100644 --- a/src/truetype/ttobjs.c +++ b/src/truetype/ttobjs.c @@ -813,6 +813,8 @@ else error = FT_Err_Ok; + size->bytecode_ready = error; + if ( !error ) TT_Save_Context( exec, size ); @@ -884,6 +886,8 @@ else error = FT_Err_Ok; + size->cvt_ready = error; + /* UNDOCUMENTED! The MS rasterizer doesn't allow the following */ /* graphics state variables to be modified by the CVT program. */ @@ -912,10 +916,6 @@ return error; } -#endif /* TT_USE_BYTECODE_INTERPRETER */ - - -#ifdef TT_USE_BYTECODE_INTERPRETER static void tt_size_done_bytecode( FT_Size ftsize ) @@ -953,8 +953,8 @@ size->max_func = 0; size->max_ins = 0; - size->bytecode_ready = 0; - size->cvt_ready = 0; + size->bytecode_ready = -1; + size->cvt_ready = -1; } @@ -974,8 +974,8 @@ TT_MaxProfile* maxp = &face->max_profile; - size->bytecode_ready = 1; - size->cvt_ready = 0; + size->bytecode_ready = -1; + size->cvt_ready = -1; size->max_function_defs = maxp->maxFunctionDefs; size->max_instruction_defs = maxp->maxInstructionDefs; @@ -1052,15 +1052,14 @@ FT_Error error = FT_Err_Ok; - if ( !size->bytecode_ready ) - { + if ( size->bytecode_ready < 0 ) error = tt_size_init_bytecode( (FT_Size)size, pedantic ); - if ( error ) - goto Exit; - } + + if ( error || size->bytecode_ready ) + goto Exit; /* rescale CVT when needed */ - if ( !size->cvt_ready ) + if ( size->cvt_ready < 0 ) { FT_UInt i; TT_Face face = (TT_Face)size->root.face; @@ -1087,8 +1086,6 @@ size->GS = tt_default_graphics_state; error = tt_size_run_prep( size, pedantic ); - if ( !error ) - size->cvt_ready = 1; } Exit: @@ -1119,8 +1116,8 @@ FT_Error error = FT_Err_Ok; #ifdef TT_USE_BYTECODE_INTERPRETER - size->bytecode_ready = 0; - size->cvt_ready = 0; + size->bytecode_ready = -1; + size->cvt_ready = -1; #endif size->ttmetrics.valid = FALSE; @@ -1148,7 +1145,7 @@ #ifdef TT_USE_BYTECODE_INTERPRETER - if ( size->bytecode_ready ) + if ( size->bytecode_ready >= 0 ) tt_size_done_bytecode( ttsize ); #endif @@ -1229,7 +1226,7 @@ } #ifdef TT_USE_BYTECODE_INTERPRETER - size->cvt_ready = 0; + size->cvt_ready = -1; #endif /* TT_USE_BYTECODE_INTERPRETER */ if ( !error ) diff --git a/src/truetype/ttobjs.h b/src/truetype/ttobjs.h index a11dd37..47d50d9 100644 --- a/src/truetype/ttobjs.h +++ b/src/truetype/ttobjs.h @@ -4,7 +4,7 @@ /* */ /* Objects manager (specification). */ /* */ -/* Copyright 1996-2009, 2011-2013 by */ +/* Copyright 1996-2009, 2011-2014 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -333,8 +333,10 @@ FT_BEGIN_HEADER FT_Bool debug; TT_ExecContext context; - FT_Bool bytecode_ready; - FT_Bool cvt_ready; + /* if negative, `fpgm' (resp. `prep'), wasn't executed yet; */ + /* otherwise it is the returned error code */ + FT_Error bytecode_ready; + FT_Error cvt_ready; #endif /* TT_USE_BYTECODE_INTERPRETER */ diff --git a/src/truetype/ttsubpix.c b/src/truetype/ttsubpix.c index 28470ad..9871994 100644 --- a/src/truetype/ttsubpix.c +++ b/src/truetype/ttsubpix.c @@ -956,7 +956,7 @@ if ( loader->exec->rasterizer_version != TT_INTERPRETER_VERSION_35 ) { loader->exec->rasterizer_version = TT_INTERPRETER_VERSION_35; - loader->exec->size->cvt_ready = FALSE; + loader->exec->size->cvt_ready = -1; tt_size_ready_bytecode( loader->exec->size, @@ -971,7 +971,7 @@ SPH_OPTION_SET_RASTERIZER_VERSION ) { loader->exec->rasterizer_version = SPH_OPTION_SET_RASTERIZER_VERSION; - loader->exec->size->cvt_ready = FALSE; + loader->exec->size->cvt_ready = -1; tt_size_ready_bytecode( loader->exec->size, diff --git a/src/type1/t1driver.c b/src/type1/t1driver.c index 697288d..2602bdb 100644 --- a/src/type1/t1driver.c +++ b/src/type1/t1driver.c @@ -4,7 +4,7 @@ /* */ /* Type 1 driver interface (body). */ /* */ -/* Copyright 1996-2004, 2006, 2007, 2009, 2011, 2013 by */ +/* Copyright 1996-2004, 2006, 2007, 2009, 2011, 2013, 2014 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -557,9 +557,6 @@ if ( value && value_len >= retval ) *((FT_Long *)value) = type1->font_info.italic_angle; break; - - default: - break; } return retval;