Website: http://www.geocities.com/dborca/opengl/tc.html
Title: FreeType
-Used Version: 2.6.3
+Used Version: 2.6.4
Website: http://www.freetype.org
Title: Mesa3D
+2016-07-05 Werner Lemberg <wl@gnu.org>
+
+ * Version 2.6.4 released.
+ =========================
+
+
+ Tag sources with `VER-2-6-4'.
+
+ * docs/VERSION.TXT: Update documentation and bump version number to
+ 2.6.4.
+
+ * README, Jamfile (RefDoc), builds/windows/vc2005/freetype.vcproj,
+ builds/windows/vc2005/index.html,
+ builds/windows/vc2008/freetype.vcproj,
+ builds/windows/vc2008/index.html,
+ builds/windows/vc2010/freetype.vcxproj,
+ builds/windows/vc2010/index.html,
+ builds/windows/visualc/freetype.dsp,
+ builds/windows/visualc/freetype.vcproj,
+ builds/windows/visualc/index.html,
+ builds/windows/visualce/freetype.dsp,
+ builds/windows/visualce/freetype.vcproj,
+ builds/windows/visualce/index.html,
+ builds/wince/vc2005-ce/freetype.vcproj,
+ builds/wince/vc2005-ce/index.html,
+ builds/wince/vc2008-ce/freetype.vcproj,
+ builds/wince/vc2008-ce/index.html: s/2.6.3/2.6.4/, s/263/264/.
+
+ * include/freetype/freetype.h (FREETYPE_PATCH): Set to 4.
+
+ * builds/unix/configure.raw (version_info): Set to 18:4:12.
+ * CMakeLists.txt (VERSION_PATCH): Set to 4.
+
+ * docs/CHANGES: Updated.
+
+2016-07-05 Werner Lemberg <wl@gnu.org>
+
+ * src/pfr/pfrsbit.c (pfr_lookup_bitmap_data): Fix compiler warning.
+
+2016-07-04 Alexei Podtelezhnikov <apodtele@gmail.com>
+
+ [smooth] Variable type revision (part 2).
+
+ * src/smooth/ftgrays.c (TArea): Restore original definition as `int'.
+ (gray_render_line) [FT_LONG64]: Updated.
+ (gray_convert_glyph): 32-bit band bisection stack should be 32 bands.
+ (gray_convert_glyph_inner): Trace successes and failures.
+
+2016-07-04 Werner Lemberg <wl@gnu.org>
+
+ [autofit] Handle single-point contours as segments.
+
+ Doing so allows us to link them to edges \96 some fonts like
+ `NotoSansGurmukhi-Regular' have such isolated points sitting exactly
+ on other outlines.
+
+ * src/autofit/aflatin.c (af_latin_hints_compute_segments): Don't
+ ignore one-point contours but handle them specially as one-point
+ segments.
+ (af_latin_hints_compute_edges): Append one-point segments to edges
+ if possible.
+
+2016-07-02 Werner Lemberg <wl@gnu.org>
+
+ [autofit] Remove unused structure members.
+
+ * src/autofit/afhints.h (AF_SegmentRec, AF_EdgeRec): Remove
+ `num_linked'.
+
+ * src/autofit/afcjk.c (af_cjk_hints_link_segments): Updated.
+
+2016-07-02 Werner Lemberg <wl@gnu.org>
+
+ [autofit] Update to Unicode 9.0.0.
+
+ * src/autofit/afranges.c (af_arab_nonbase_uniranges,
+ af_cyrl_uniranges): Add new data.
+
+2016-07-01 Alexei Podtelezhnikov <apodtele@gmail.com>
+
+ [smooth] Variable type revision (part 1).
+
+ This patch restores original `TCoord' definition as `int' so that the
+ rendering pool is used more efficiently on LP64 platforms (unix).
+
+ * src/smooth/ftgrays.c (gray_TWorker, TCell, gray_TBand): Switch some
+ fields to `TCoord'.
+ (gray_find_cell, gray_render_scanline, gray_render_line, gray_hline,
+ gray_sweep, gray_convert_glyph): Updated.
+
+2016-06-28 Alexei Podtelezhnikov <apodtele@gmail.com>
+
+ [smooth] Minor clean-ups.
+
+ * src/smooth/ftgrays.c (gray_TWorker): Remove redundant `ycount'.
+ (gray_sweep, gray_convert_glyph, gray_dump_cells): Updated.
+
+2016-06-27 Alexei Podtelezhnikov <apodtele@gmail.com>
+
+ [smooth] Minor clean-ups.
+
+ * src/smooth/ftgrays.c (gray_convert_glyph): Do not use volatile
+ qualifier.
+ (gray_raster_render): Move span initializations from here.
+ (gray_sweep): ... to here and remove unused `target' argument.
+
+2016-06-26 Alexei Podtelezhnikov <apodtele@gmail.com>
+
+ [pcf] Fix handling of very large fonts (#47708).
+
+ * src/pcf/pcfread.c (pcf_get_encodings): Make `encodingOffset' an
+ unsigned short.
+ Only reject `0xFFFF' as an invalid encoding offset.
+
+2016-06-25 Werner Lemberg <wl@gnu.org>
+
+ [truetype] Really fix deallocation in case of error (#47726).
+
+ * src/truetype/ttgload.c (load_truetype_glyph): Thinko; initialize
+ `outline.points' also.
+
+2016-06-23 Alexei Podtelezhnikov <apodtele@gmail.com>
+
+ [smooth] Consolidate memory management.
+
+ * src/smooth/ftgrays.c (gray_init_cells): Remove function.
+ (gray_TWorker): Remove fields that become local variables.
+ (gray_raster_render): Move rendering buffer declaration from here.
+ (gray_convert_glyph): ... to here and update accordingly.
+
+2016-06-22 Alexei Podtelezhnikov <apodtele@gmail.com>
+
+ [smooth] Consolidate boundary checks.
+
+ Removing the checks from `gray_hline' shaves 1% off rendering speed.
+
+ * src/smooth/ftgrays.c [STANDALONE_]: Duplicate `FT_MIN' and `FT_MAX'.
+ (gray_TWorker): No need to store `clip_box'.
+ (gray_hline): Remove unnecessary boundary checks.
+ (gray_convert_glyph): Move boundary checks from here.
+ (gray_raster_render): ... to here and consolidate.
+
+2016-06-21 Alexei Podtelezhnikov <apodtele@gmail.com>
+
+ [smooth] Use `FT_Outline_Get_CBox'.
+
+ * src/smooth/ftgrays.c [STANDALONE_]: Duplicate `FT_Outline_Get_CBox'.
+ (gray_compute_cbox): Remove this function.
+ (gray_convert_glyph): Update to use `FT_Outline_Get_CBox'.
+
+2016-06-20 Werner Lemberg <wl@gnu.org>
+
+ [smooth] Remove compiler warnings.
+
+ * src/smooth/ftgrays.c (gray_convert_glyph): Fix reports from clang.
+
+2016-06-20 Alexei Podtelezhnikov <apodtele@gmail.com>
+
+ [smooth] Sanitize memory managenent.
+
+ * src/smooth/ftgrays.c (gray_convert_glyph): Cleaned up.
+
+2016-06-18 Alexei Podtelezhnikov <apodtele@gmail.com>
+
+ [smooth] Remove `band_shoot' that never worked.
+
+ * src/smooth/ftgrays.c (gray_TWorker): Remove `band_shoot'.
+ (gray_convert_glyph): Updated.
+
+2016-06-17 Alexei Podtelezhnikov <apodtele@gmail.com>
+
+ [raster, smooth] Handle FT_RENDER_POOL_SIZE better.
+
+ * src/raster/ftraster.c (FT_MAX_BLACK_POOL): New macro.
+ (ft_black_render): Updated.
+ * src/smooth/ftgrays.c (FT_MAX_GRAY_POOL): New macro.
+ (gray_raster_render): Updated.
+
+2016-06-16 Werner Lemberg <wl@gnu.org>
+
+ * src/base/md5.c: Updated to recent version.
+
+2016-06-14 Alexei Podtelezhnikov <apodtele@gmail.com>
+
+ * src/smooth/ftgrays.c (gray_hline): Optimize if-condition.
+
+2016-06-13 Werner Lemberg <wl@gnu.org>
+
+ [autofit] Add support for Cherokee script.
+
+ * src/autofit/afblue.dat: Add blue zone data for Cherokee.
+
+ * src/autofit/afblue.c, src/autofit/afblue.h: Regenerated.
+
+ * src/autofit/afscript.h: Add Cherokee standard characters.
+
+ * src/autofit/afranges.c: Add Cherokee data.
+
+ * src/autofit/afstyles.h: Add Cherokee data.
+
+2016-06-09 David Capello <davidcapello@gmail.com>
+
+ [cmake] Avoid modifying `ftconfig.h' and `ftoption.h' files.
+
+ * CMakeLists.txt: Each time cmake is run those files are
+ modified and the whole FreeType library is recompiled. With this
+ change we change the files only if there are real modifications, so
+ we can avoid recompilations.
+
+2016-06-09 Werner Lemberg <wl@gnu.org>
+
+ [bdf] Check number of properties (#48166).
+
+ * src/bdf/bdflib.c (_bdf_parse_start): Implement.
+
+2016-06-08 Alexei Podtelezhnikov <apodtele@gmail.com>
+
+ [smooth] Re-enable new line renderer on 64-bit archs.
+
+ * src/smooth/ftgrays.c (gray_render_line): Conditionally re-enable new
+ implementation, where it is safe from overflows.
+
+2016-06-08 Alexei Podtelezhnikov <apodtele@gmail.com>
+
+ [smooth] Minor clean-ups.
+
+ * src/smooth/ftgrays.c (gray_dump_cells): Move out of the way.
+ (gray_render_span): Remove spurious casts and streamline.
+
+2016-06-07 Werner Lemberg <wl@gnu.org>
+
+ [autofit] Add support for Ethiopic script.
+
+ * src/autofit/afblue.dat: Add blue zone data for Ethiopic.
+
+ * src/autofit/afblue.c, src/autofit/afblue.h: Regenerated.
+
+ * src/autofit/afscript.h: Add Ethiopic standard characters.
+
+ * src/autofit/afranges.c: Add Ethiopic data.
+
+ * src/autofit/afstyles.h: Add Ethiopic data.
+
+2016-06-07 Werner Lemberg <wl@gnu.org>
+
+ [autofit] Fix compilation with VS2016 (#48126).
+
+ This compiler doesn't recognize the end-of-comment sequence `*/' if
+ it immediately follows non-ASCII characters.
+
+ * src/autofit/afscript.h: Ensure whitespace before `*/'.
+
+2016-06-04 Werner Lemberg <wl@gnu.org>
+
+ Fix a test for named instances (#48122).
+
+ This was missed while giving negative face indices an extended
+ meaning.
+
+ * src/base/ftobjs.c (Mac_Read_sfnt_Resource): Implement.
+
+2016-05-31 Nikolaus Waxweiler <madigens@gmail.com>
+
+ [truetype] Let SHPIX move points in the twilight zone in v40.
+
+ * src/truetype/ttinterp.c (Ins_SHPIX): Allow SHPIX to move points in
+ the twilight zone. Otherwise, treat SHPIX the same as DELTAP.
+ Unbreaks various fonts such as older versions of Rokkitt and DTL
+ Argo T Light that would glitch severly after calling ALIGNRP after a
+ blocked SHPIX.
+
+2016-05-30 Werner Lemberg <wl@gnu.org>
+
+ [type42] Support `CharStrings' entry format as created by LilyPond.
+
+ * src/type42/t42parse.c (t42_parse_charstrings): Handle entries
+ having the format
+
+ (foo) cvn 12345 def
+
+2016-05-28 Werner Lemberg <wl@gnu.org>
+
+ * src/autofit/afranges.c: Remove `UL' postfix from hex numbers.
+
+ Suggested by Alexei. `UL' is only needed for 16bit compilers, but
+ it seems noone is using this anymore (and we no longer test whether
+ FreeType compiles in such an environment). Otherwise, it is easy to
+ add the postfix to the `AF_UNICODE_RANGE' macro.
+
+2016-05-26 Alexei Podtelezhnikov <apodtele@gmail.com>
+
+ [smooth] Shrink bisection stack.
+
+ The convergence of Bézier flatteners is fast with the deviation
+ from straight line being assymptotically cut 4-fold on each bisection.
+ This justifies smaller bisection stack size.
+
+ * src/smooth/ftgrays.c (gray_TWorker): Remove common `bez_stack'.
+ (gray_render_conic): Create and use conic `bez_stack'. Move back the
+ band analysis from...
+ (gray_conic_to): ... here.
+ (gray_render_cubic): Create and use cubic `bez_stack'. Move back the
+ band analysis from...
+ (gray_cubic_to): ... here.
+ (gray_move_to): Updated.
+
+2016-05-25 Werner Lemberg <wl@gnu.org>
+
+ [autofit] Fixes for Armenian and Gujarati ranges.
+
+ * src/autofit/afranges.c (af_armn_uniranges): Corrected.
+ (af_guru_nonbase_uniranges): Make U+0A3E a base character.
+
+2016-05-24 Werner Lemberg <wl@gnu.org>
+
+ [autofit] Add support for Armenian script.
+
+ * src/autofit/afblue.dat: Add blue zone data for Armenian.
+
+ * src/autofit/afblue.c, src/autofit/afblue.h: Regenerated.
+
+ * src/autofit/afscript.h: Add Armenian standard characters.
+
+ * src/autofit/afranges.c: Add Armenian data.
+
+ * src/autofit/afstyles.h: Add Armenian data.
+
+2016-05-23 Werner Lemberg <wl@gnu.org>
+
+ * builds/unix/unix-cc.in (LINK_LIBRARY): Use `-export-symbols'.
+
+ This was commented about 10 years ago \96 I think the reason then to
+ disable libtool's `-export-symbols' option was to give some badly
+ programmed applications access to internal FreeType functions.
+
+ I believe that we should no longer take care of such programs; the
+ number of symbols exported should be rather restricted as much as
+ possible.
+
+2016-05-22 Werner Lemberg <wl@gnu.org>
+
+ [autofit] Add blue-zone support for Gurmukhi script.
+
+ This essentially moves the Gurmukhi script from the `Indic' hinter to
+ the `Latin' hinter.
+
+ * src/autofit/afblue.dat: Add blue zone data for Gurmukhi.
+
+ * src/autofit/afblue.c, src/autofit/afblue.h: Regenerated.
+
+ * src/autofit/afscript.h: Add Gurmukhi standard characters and move
+ data out of AF_CONFIG_OPTION_INDIC block.
+
+ * src/autofit/afranges.c: Move Gurmukhi data out of
+ AF_CONFIG_OPTION_INDIC block.
+
+ * src/autofit/afstyles.h: Update Gurmukhi data; in particular, use
+ AF_WRITING_SYSTEM_LATIN.
+
+2016-05-21 Werner Lemberg <wl@gnu.org>
+
+ Minor clang++ fixes.
+
+ * src/base/ftobjs.c (FT_Add_Module), src/psaux/psobjs.c
+ (ps_parser_load_field), src/type1/t1load.c (parse_subrs): Add
+ initializer.
+
+ * src/cache/ftccache.h (FTC_CACHE_TRYLOOP_END): Avoid implicit
+ conversion from NULL to boolean.
+
+2016-05-21 Werner Lemberg <wl@gnu.org>
+
+ Work around a bug of the C 8.0.0.1 compiler on AIX 5.3 (#47955).
+
+ * include/freetype/internal/ftmemory.h (cplusplus_typeof): Use
+ braces for `extern "C++"'.
+
+2016-05-17 Nikolaus Waxweiler <madigens@gmail.com>
+
+ [truetype] Make TT_LOADER_SET_PP support subpixel hinting [3/3].
+
+ * src/truetype/ttgload.c (TT_LOADER_SET_PP): Replace macro with...
+ (tt_loader_set_pp): ... this new function.
+ Update all callers.
+
+2016-05-17 Nikolaus Waxweiler <madigens@gmail.com>
+
+ [truetype] New implementation of v38 bytecode interpreter [2/3].
+
+ This patch actually modifies the bytecode interpreter.
+
+ See added comments in `ttinterp.h' for more information on this and
+ the following commit in the series.
+
+ * src/truetype/ttinterp.c (SUBPIXEL_HINTING): Replaced by...
+ (NO_SUBPIXEL_HINTING, SUBPIXEL_HINTING_INFINALITY,
+ SUBPIXEL_HINTING_MINIMAL): ...new macros.
+ (Direct_Move, Direct_Move_X, Direct_Move_Y): Handle backwards
+ compatibility.
+ Updated.
+ (Ins_RS, Ins_FDEF, Ins_ENDF, Ins_CALL, Ins_LOOPCALL, Ins_MD):
+ Updated.
+ (Ins_INSTCTRL): Handle native ClearType mode flag.
+ Updated.
+ (Ins_FLIPPT, Ins_FLIPRGON, Ins_FLIPRGOFF): Handle backwards
+ compatibility.
+ (Move_Zp2_Point): Ditto.
+ (Ins_SHP): Updated.
+ (Ins_SHPIX): Handle backwards compatibility.
+ Updated.
+ (Ins_MSIRP, Ins_MDAP, Ins_MIAP, Ins_MDRP, Ins_MIRP): Updated.
+ (Ins_ALIGNRP): Updated.
+ (Ins_IUP, Ins_DELTAP): Handle backwards compatibility.
+ Updated.
+ (Ins_GETINFO): Handle v38 flags.
+ Updated.
+ (TT_RunIns): Handle backwards compatibility mode.
+ Updated.
+
+2016-05-17 Nikolaus Waxweiler <madigens@gmail.com>
+
+ [truetype] New implementation of v38 bytecode interpreter [1/3].
+
+ This patch prepares data structures and the like.
+
+ See added comments in `ttinterp.h' for more information on this and
+ the following commits in the series.
+
+ * devel/ftoption.h, include/freetype/config/ftoption.h
+ (TT_CONFIG_OPTION_SUBPIXEL_HINTING): Assign values to differentiate
+ between subpixel versions.
+ (TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY,
+ TT_SUPPORT_SUBPIXEL_HINTING_MINIMAL): New macros.
+
+ * include/freetype/ftttdrv.h (TT_INTERPRETER_VERSION_40): New macro.
+
+ * include/freetype/internal/tttypes.h (TT_FaceRec): Updated.
+
+ * src/truetype/ttinterp.h (TT_ExecContextRec): Define new fields
+ `subpixel_hinting_lean', `vertical_lcd_lean',
+ `backwards_compatibility', `iupx_called', iupy_called', and
+ `grayscale_cleartype' for new hinting mode.
+
+ * src/truetype/ttdriver.c (tt_property_set): Handle v38 and v40
+ interpreters conditionally.
+
+ * src/truetype/ttgload.c (TT_Hint_Glyph): Save phantom points unless
+ in v38 backwards compatibility mode.
+ Updated.
+ (compute_glyph_metrics): Add v38 backwards compatibility mode
+ constraint for adjusting advance widths.
+ Updated.
+ (tt_loader_init): Handle new flags `subpixel_hinting_lean',
+ `grayscale_cleartype', and `vertical_lcd_lean'.
+ Updated.
+ (tt_get_metrics, TT_Process_Simple_Glyph, TT_LOADER_SET_PP):
+ Updated.
+
+ * src/truetype/ttobjs.c (tt_driver_init): Conditionally set
+ default interpreter version number.
+
+ * src/truetype/ttsubpix.c, src/truetype/ttsubpix.h: Updated.
+
+2016-05-17 Werner Lemberg <wl@gnu.org>
+
+ [cff] Fix matrix scaling (#47848).
+
+ * include/freetype/config/ftstdlib.h (FT_LONG_MIN): New macro.
+
+ * src/cff/cffparse.c (cff_parse_font_matrix): Use largest scaling
+ value of all matrix coefficients to scale matrix.
+
+ * src/cff/cffobjs.c (cff_face_init): Use `matrix->yx' member for
+ matrix normalization if `matrix->yy' is zero.
+
+2016-05-16 Werner Lemberg <wl@gnu.org>
+
+ [base] Reject invalid sfnt Mac resource (#47891).
+
+ * src/base/ftobjs.c (open_face_PS_from_sfnt_stream): Check validity
+ of `CID ' and `TYPE1' table offset and length.
+
+2016-05-16 Werner Lemberg <wl@gnu.org>
+
+ [cid] Fix scanning for `StartData' and `/sfnts' (#47892).
+
+ * src/cid/cidparse.c (STARTDATA, STARTDATA_LEN, SFNTS, SFNTS_LEN):
+ New macros.
+ (cid_parser_new): Fix and document algorithm.
+
+2016-05-16 suzuki toshiya <mpsuzuki@hiroshima-u.ac.jp>
+
+ [truetype] Improve the recursive reference detector.
+
+ The previous fix for #46372 misunderstood a composite glyph referring
+ same component twice as a recursive reference. See the discussion
+
+ http://lists.gnu.org/archive/html/freetype/2016-05/msg00000.html
+
+ Thanks to Khaled Hosny for finding this issue.
+
+ * src/truetype/ttgload.c (ft_list_get_node_at): A function to get
+ the i-th node from FT_List.
+ (load_truetype_glyph): In the traversal scan of the reference tree
+ in the composite glyph, we clear the nodes filled by previous
+ sibling chain.
+
+2016-05-07 Werner Lemberg <wl@gnu.org>
+
+ [cache] Allow value 0 for face ID.
+
+ We never dereference `face_id', and some implementations might use a
+ running number instead of a pointer. Additionally, disallowing
+ value zero was undocumented.
+
+ * src/cache/ftccmap.c (FTC_CMapCache_Lookup), src/cache/ftcmanag.c
+ (FTC_Manager_LookupFace, FTC_Manager_RemoveFaceID): Remove test for
+ `face_id'.
+
+2016-05-05 Alexei Podtelezhnikov <apodtele@gmail.com>
+
+ [smooth] More efficient accounting of conic splits and draws.
+
+ A single decrement counter of segments to draw, instead of an array,
+ contains all the information necessary to decide when to split and
+ when to draw a conic segment. The number of splits before each draw is
+ equal to the number of trailing zeros in the counter.
+
+ * src/smooth/ftgrays.c (gray_TWorker): Remove `lev_stack'.
+ (gray_render_conic): Updated to use decrement counter of segments.
+
+2016-05-05 Werner Lemberg <wl@gnu.org>
+
+ [cff, truetype] Fix logic for `FT_Property_Set'.
+
+ Otherwise some properties could be set to arbitrary values, which is
+ harmless, but querying could give wrong positive results.
+
+ * src/cff/cffdrivr.c (cff_property_set) [hinting-engine],
+ * src/truetype/ttdriver.c (tt_property_set) [interpreter-version]:
+ Only allow defined values.
+
+2016-04-25 Werner Lemberg <wl@gnu.org>
+
+ [autofit] Add blue-zone support for Gujarati script.
+
+ This essentially moves the Gujarati script from the `Indic' hinter to
+ the `Latin' hinter.
+
+ * src/autofit/afblue.dat: Add blue zone data for Gujarati.
+
+ * src/autofit/afblue.c, src/autofit/afblue.h: Regenerated.
+
+ * src/autofit/afscript.h: Add Gujarati standard characters and move
+ data out of AF_CONFIG_OPTION_INDIC block.
+
+ * src/autofit/afranges.c: Move Gujarati data out of
+ AF_CONFIG_OPTION_INDIC block.
+
+ * src/autofit/afstyles.h: Update Gujarati data; in particular, use
+ AF_WRITING_SYSTEM_LATIN.
+
+2016-04-24 Werner Lemberg <wl@gnu.org>
+
+ Minor.
+
+ * include/freetype/freetype.h (FT_HAS_*, FT_IS_*): Protect macro
+ argument with parentheses.
+
+2016-04-24 Werner Lemberg <wl@gnu.org>
+
+ [truetype] Fix deallocation in case of error (#47726).
+
+ * src/truetype/ttgload.c (load_truetype_glyph): Initialize fields in
+ `outline' that are going to be deallocated in case of error.
+
+2016-04-23 Werner Lemberg <wl@gnu.org>
+
+ [autofit] Improve Georgian blue zone characters.
+
+ Suggested by Akaki Razmadze <razmadzekoko@gmail.com>.
+
+ * src/autofit/afblue.dat (AF_BLUE_STRING_GEORGIAN_MKHEDRULI_BOTTOM):
+ Updated.
+
+ * src/autofit/afblue.c: Regenerated.
+
+2016-04-16 David Capello <davidcapello@gmail.com>
+
+ [cmake] Honor SKIP_INSTALL_* settings (as used in zlib).
+
+ As FreeType depends on zlib, if we don't install zlib (e.g., because
+ we defined SKIP_INSTALL_ALL), FreeType cannot be installed, too
+ (cmake triggers an error saying that FreeType cannot be installed
+ because zlib target isn't in the export set).
+
+ * CMakeLists.txt: Honor `SKIP_INSTALL_HEADERS',
+ `SKIP_INSTALL_LIBRARIES', and `SKIP_INSTALL_ALL' settings.
+
+2016-04-16 Behdad Esfahbod <behdad@behdad.org>
+
+ [truetype] Another fix for non-intermediate GX tuples.
+
+ * src/truetype/ttgxvar.c (ft_var_apply_tuple): Add some missing
+ cases.
+
+2016-04-12 Alexei Podtelezhnikov <apodtele@gmail.com>
+
+ Remove forgotten macro.
+
+ * include/freetype/internal/internal.h
+ [FT_INTERNAL_POSTSCRIPT_GLOBALS_H]: Remove.
+
+2016-04-09 Werner Lemberg <wl@gnu.org>
+
+ [autofit] Add support for Georgian scripts.
+
+ Georgian is problematic, since `uppercase' forms of Mkhedruli
+ (called Mtavruli) are not yet defined in Unicode, which means that
+ proper blue zones can't be defined. However, there is already a
+ proposal submitted to Unicode; see
+
+ http://www.unicode.org/L2/L2016/16034-n4707-georgian.pdf
+
+ Additionally, due to historical reasons, Unicode treats Khutsuri as
+ the same script as Mkhedruli, and so does OpenType. However, since
+ the two scripts have completely different shapes it can happen that
+ blue zones differ considerably. The tag `geok' used here (derived
+ from ISO 15924) to differentiate the two scripts is not an OpenType
+ tag in use. If we now have a font that contains both glyphs for
+ Mkhedruli and Khutsuri, and it uses OpenType features for both also,
+ HarfBuzz unavoidably treats all glyphs as `geor'. As a consequence,
+ blue zones for `geok' are not used for glyphs involved in the
+ OpenType features.
+
+ An issue not yet resolved is which OpenType feature should be used
+ to access Mtavruli glyph shapes; right now, FreeType doesn't set up
+ support for them, but it is easy to add them later on as soon as
+ more information is available.
+
+ * src/autofit/afblue.dat: Add blue zone data for Georgian.
+
+ * src/autofit/afblue.c, src/autofit/afblue.h: Regenerated.
+
+ * src/autofit/afscript.h: Add Georgian standard characters.
+
+ * src/autofit/afranges.c: Add Georgian data.
+
+ * src/autofit/afstyles.h: Add Georgian data.
+
+2016-04-05 Werner Lemberg <wl@gnu.org>
+
+ [autofit] Provide dummy blue zone for pseudo script `none'.
+
+ Even if the dummy hinter is used as the handler for `none' (which
+ doesn't use blue zones), it is more consistent than the old value
+ (which was 0), pointing to Arabic...
+
+ * src/autofit/afblue.dat: Add `AF_BLUE_STRINGSET_NONE'.
+ * src/autofit/afblue.c, src/autofit/afblue.h: Regenerated.
+
+ * src/autofit/afstyles.h (none_dflt): Use AF_BLUE_STRINGSET_NONE.
+
+2016-03-30 Werner Lemberg <wl@gnu.org>
+
+ * src/pfr/pfrload.c (pfr_aux_name_load): Thinko (#47567).
+
+2016-03-30 Werner Lemberg <wl@gnu.org>
+
+ * src/pfr/pfrload.c (pfr_log_font_count): Better font size estimate.
+
+2016-03-30 Werner Lemberg <wl@gnu.org>
+
+ * src/pfr/pfrload.c (pfr_aux_name_load): Fix memory leak (#47567).
+
+2016-03-29 Werner Lemberg <wl@gnu.org>
+
+ * src/base/ftadvanc.c (FT_Get_Advances): Fix invalid left shift.
+
+2016-03-29 Werner Lemberg <wl@gnu.org>
+
+ [pfr] Fix binary search (#47514).
+
+ * src/pfr/pfrsbit.c (pfr_lookup_bitmap_data): Handle border
+ conditions correctly.
+
+2016-03-29 Werner Lemberg <wl@gnu.org>
+
+ [pfr] Minor.
+
+ * src/pfr/pfrsbit.c (pfr_lookup_bitmap_data): Replace `left',
+ `right', and `middle' with `min', `max', and `mid' as used in other
+ FreeType binary search code.
+ (pfr_load_bitmap_metrics): Fix invalid left shift.
+
+2016-03-29 Werner Lemberg <wl@gnu.org>
+
+ * src/pfr/pfrtypes.h: Replace all enums with macros.
+
+ We need `~FOO' to unset bits, and only with unsigned values (which
+ `enum' isn't normally) this works cleanly.
+
+2016-03-26 Werner Lemberg <wl@gnu.org>
+
+ [pfr] Robustify bitmap strike handling (#47514).
+
+ We did a binary search for a charcode without ensuring that the
+ searched data is ordered. Validating the order is now done lazily,
+ this is, the first access to a bitmap glyph triggers the order check
+ in the corresponding bitmap strike.
+
+ * src/pfr/pfrtypes.h (PFR_BitmapFlags): New values
+ `PFR_BITMAP_VALID_CHARCODES' and `PFR_BITMAP_CHARCODES_VALIDATED'.
+
+ * src/pfr/pfrsbit.c (pfr_lookup_bitmap_data): Make `flags' argument
+ a pointer. Handle new PFR_BITMAP_XXX flags.
+ (pfr_slot_load_bitmap): Updated.
+
+2016-03-26 Werner Lemberg <wl@gnu.org>
+
+ [pfr] Fix handling of compound glyphs.
+
+ Extra items are indicated with different bit positions.
+
+ * src/pfr/pfrtypes.h (PFR_GlyphFlags): Replace
+ `PFR_GLYPH_EXTRA_ITEMS' with `PFR_GLYPH_SIMPLE_EXTRA_ITEMS' and
+ `PFR_GLYPH_COMPOUND_EXTRA_ITEMS'.
+
+ * src/pfr/pfrgload.c (pfr_glyph_load_simple,
+ pfr_glyph_load_compound): Use them.
+
+2016-03-25 Werner Lemberg <wl@gnu.org>
+
+ [pfr] Minor.
+
+ * src/pfr/pfrsbit.c, src/pfr/pfrobjs.c: Use flag names instead of
+ bare numbers.
+
+2016-03-25 Werner Lemberg <wl@gnu.org>
+
+ [pfr] Various clang sanitizer fixes.
+
+ * src/pfr/pfrsbit.c (pfr_load_bitmap_metrics): Correctly handle
+ signed nibbles.
+ (pfr_slot_load_bitmap): Correctly exit frame in case of error.
+ Fix invalid left shifts.
+
+2016-03-23 Werner Lemberg <wl@gnu.org>
+
+ Rename `VERSION.DLL' (#47472).
+
+ * docs/VERSION.DLL: Renamed to...
+ * docs/VERSIONS.TXT: ...this.
+
+2016-03-23 Werner Lemberg <wl@gnu.org>
+
+ [raster, smooth] Directly test outline size (#47500).
+
+ This improves stand-alone compilation.
+
+ * src/base/ftoutln.c (FT_Outline_Render): Move cbox size test to...
+
+ * src/raster/ftraster.c (ft_black_render), src/smooth/ftgrays.c
+ (gray_raster_render): ...these functions.
+
+2016-03-23 Werner Lemberg <wl@gnu.org>
+
+ [raster, smooth] Fix some clang sanitizer runtime issues.
+
+ * src/raster/ftraster.c (ft_black_reset, ft_black_set_mode,
+ ft_black_render): Harmonize signatures with `ftimage.h'.
+
+ * src/smooth/ftgrays.c (gray_raster_render, gray_raster_reset):
+ Ditto.
+
+2016-03-22 Werner Lemberg <wl@gnu.org>
+
+ * src/truetype/ttgload.c (TT_Load_Simple_Glyph): Minor.
+
+ This fixes an AddressSanitizer issue:
+
+ ttgload.c:430:7: runtime error: null pointer passed as argument 1,
+ which is declared to never be null
+
+2016-03-21 Werner Lemberg <wl@gnu.org>
+
+ * src/autofit/afhints.c (af_glyph_hints_reload): Thinko.
+
+ This fixes the previous commit to this file.
+
+2016-03-21 Alexei Podtelezhnikov <apodtele@gmail.com>
+
+ [smooth] Partly revert recent changes.
+
+ * src/smooth/ftgrays.c (gray_conic_to, gray_cubic_to): Rework
+ conditions to fix rendering issues.
+
+2016-03-20 Werner Lemberg <wl@gnu.org>
+
+ [autofit] Show `near' points in tracing.
+
+ * src/autofit/afhints.h (AF_FLAG_NEAR): New macro.
+
+ * src/autofit/afhints.c (af_glyph_hints_dump_points): Implement it.
+ (af_glyph_hints_reload): Handle AF_FLAG_NEAR.
+
+2016-03-18 Alexei Podtelezhnikov <apodtele@gmail.com>
+
+ [smooth] Minor refactoring and microoptimizations.
+
+ * src/smooth/ftgrays.c (gray_render_conic, gray_render_cubic): Move
+ band clipping from here.
+ (gray_conic_to, gray_cubic_to): ... to here.
+ (gray_rander_line, gray_render_scanline): Initialize variables closer
+ to their use.
+
+2016-03-17 Alexei Podtelezhnikov <apodtele@gmail.com>
+
+ [smooth] Minor refactoring.
+
+ * src/smooth/ftgrays.c (gray_render_conic, gray_render_cubic): Move
+ upscaling from here.
+ (gray_conic_to, gray_cubic_to): ... to here.
+
+2016-03-15 Werner Lemberg <wl@gnu.org>
+
+ * src/autofit/aflatin.c (af_latin_compute_stem_width): Optimize.
+
+2016-03-14 Alexei Podtelezhnikov <apodtele@gmail.com>
+
+ [smooth] Temporarily revert 6eb6158dd787 (#47114).
+
+ * src/smooth/ftgrays.c (gray_render_line): Old implementation.
+
+2016-03-12 Werner Lemberg <wl@gnu.org>
+
+ [ftfuzzer] Improve coverage of rasterfuzzer.
+
+ * src/tools/ftfuzzer/rasterfuzzer.cc (LLVMFuzzerTestOneInput): Use
+ input data for `tags' array also.
+ Trim input data to get more positive hits.
+
+2016-03-11 Pavlo Denysov <paul.kiev+savannah@gmail.com>
+
+ Fix CMake issues for iOS (patch #8941).
+
+ * CMakeLists.txt (CMAKE_TOOLCHAIN_FILE): Fix directory.
+ * builds/cmake/iOS.cmake: No longer enforce gcc.
+
+2016-03-09 Behdad Esfahbod <behdad@behdad.org>
+
+ [truetype] Fix handling of non-intermediate GX tuples.
+
+ We probably did not notice this as all fonts we tested had only
+ tuple_coords[i] be +1 or -1 for non-intermediate tuples.
+
+ * src/truetype/ttgxvar.c (ft_var_apply_tuple): Implement it.
+
+2016-03-06 Alexei Podtelezhnikov <apodtele@gmail.com>
+
+ [base] Refuse to render enormous outlines (#47114).
+
+ The goal is to avoid integer overflows in the rendering algorithms.
+ The limit is chosen arbitrarily at some 2^18 pixels, which should be
+ enough for modern devices including printers.
+
+ * src/base/ftoutln.c (FT_Outline_Render): Check CBox and reject
+ enormous outlines.
+
+2016-03-06 Alexei Podtelezhnikov <apodtele@gmail.com>
+
+ [smooth] Replace left shifts with multiplications (#47114).
+
+ * src/smooth/ftgrays.c (SUBPIXELS, UPSCALE, DOWNSCALE): Do it.
+
+2016-03-05 Werner Lemberg <wl@gnu.org>
+
+ [autofit] Avoid excessive stem length rounding (#25392).
+
+ * src/autofit/aflatin.c (af_latin_compute_stem_width): Add argument
+ to pass difference between hinted and unhinted position of base
+ point; use this to adjust the stem width depending on the PPEM so
+ that it doesn't become too large under certain circumstances.
+ Update all callers using value 0 for this argument except...
+ (af_latin_align_linked_edge): Pass position delta of base point to
+ `af_latin_compute_stem_width'.
+
+2016-03-05 J Raynor <jxraynor@gmail.com>
+
+ Make FreeType compile on AIX out of the box.
+
+ * builds/unix/configure.raw (XX_ANSIFLAGS): Don't use `-ansi' on
+ AIX.
+
+2016-03-01 Werner Lemberg <wl@gnu.org>
+ Kostya Serebryany <kcc@google.com>
+
+ [ftfuzzer] Add unit for testing smooth and black rasterizers.
+
+ * src/tools/ftfuzzer/rasterfuzzer.cc: New file.
+
+2016-03-01 Werner Lemberg <wl@gnu.org>
+
+ [autofit] Fix reallocation error introduced in 2016-02-27 (#47310).
+
+ * src/autofit/aflatin.c (af_latin_hints_compute_segments): Reassign
+ `prev_segment' after reallocation.
+
+2016-03-01 Werner Lemberg <wl@gnu.org>
+
+ Fix clang warnings.
+
+ * src/autofit/aflatin.c (af_latin_hints_compute_segments): Use
+ FT_UShort for `min_flags' and `max_flags'.
+ Initialize `prev_*' variables.
+
+ * src/cff/cffobjs.c (cff_face_init) [FT_DEBUG_LEVEL_TRACE]: Fix
+ types of local variables.
+
+ * src/smooth/ftgrays.c (gray_dump_cells) [FT_DEBUG_LEVEL_TRACE]:
+ Update `printf' format string.
+
+ * src/tools/ftfuzzer/ftfuzzer.cc (setIntermediateAxis): Add cast.
+ (LLVMFuzzerTestOneInput): Fix loop type.
+
+2016-02-29 Werner Lemberg <wl@gnu.org>
+
+ [autofit] Add blue-zone support for Sinhala script.
+
+ This essentially moves the Sinhala script from the `Indic' hinter to
+ the `Latin' hinter.
+
+ * src/autofit/afblue.dat: Add blue zone data for Sinhala.
+
+ * src/autofit/afblue.c, src/autofit/afblue.h: Regenerated.
+
+ * src/autofit/afscript.h: Add Sinhala standard character and move data
+ out of AF_CONFIG_OPTION_INDIC block.
+
+ * src/autofit/afranges.c: Move Sinhala data out of
+ AF_CONFIG_OPTION_INDIC block.
+
+ * src/autofit/afstyles.h: Update Sinhala data; in particular, use
+ AF_WRITING_SYSTEM_LATIN.
+
+2016-02-27 Werner Lemberg <wl@gnu.org>
+
+ [autofit] Properly handle spikes pointing to the x-axis.
+
+ An example that gets better rendered is glyph `uusignTaml' (glyph
+ index 2286) in font `FreeSerif.ttf' (Version 0412.2263) at 22ppem.
+
+ * src/autofit/aflatin.c (af_latin_hints_compute_segments): Properly
+ handle segments where the last point of the first segment is
+ identical to the first point in the second one. This can happen for
+ malformed fonts or spikes. We either merge the new segment with the
+ previous one (both segments point into the same direction), or we
+ discard the shorter segment if they point into different directions.
+
+2016-02-27 Werner Lemberg <wl@gnu.org>
+
+ [autofit] Minor code clean-up.
+
+ * src/autofit/aflatin.c (af_latin_hints_compute_segments): Change
+ some local variable names to better differentiate between values
+ along a segment and values orthogonal to it.
+
+2016-02-26 Werner Lemberg <wl@gnu.org>
+
+ [autofit] Improve BOUND action.
+
+ In complex glyph shapes, the original logic was too simple to cater
+ for situations that would actually need something similar to PS Hint
+ masks. This fix should alleviate the worst cases.
+
+ * src/autofit/aflatin.c (af_latin_hint_edges): Don't allow
+ complete disappearance of stems.
+
+2016-02-25 Werner Lemberg <wl@gnu.org>
+
+ [autofit] Add blue-zone support for Tamil script.
+
+ This essentially moves the Tamil script from the `Indic' hinter to
+ the `Latin' hinter.
+
+ * src/autofit/afblue.dat: Add blue zone data for Tamil.
+
+ * src/autofit/afblue.c, src/autofit/afblue.h: Regenerated.
+
+ * src/autofit/afscript.h: Add Tamil standard character and move data
+ out of AF_CONFIG_OPTION_INDIC block.
+
+ * src/autofit/afranges.c: Move Tamil data out of
+ AF_CONFIG_OPTION_INDIC block.
+
+ * src/autofit/afstyles.h: Update Tamil data; in particular, use
+ AF_WRITING_SYSTEM_LATIN.
+
+2016-02-18 Werner Lemberg <wl@gnu.org>
+
+ [autofit] Add blue-zone support for Malayalam script.
+
+ This essentially moves the Malayalam script from the `Indic' hinter
+ to the `Latin' hinter.
+
+ * src/autofit/afblue.dat: Add blue zone data for Malayalam.
+
+ * src/autofit/afblue.c, src/autofit/afblue.h: Regenerated.
+
+ * src/autofit/afscript.h: Add Malayalam standard characters and move
+ data out of AF_CONFIG_OPTION_INDIC block.
+
+ * src/autofit/afranges.c: Move Malayalam data out of
+ AF_CONFIG_OPTION_INDIC block.
+
+ * src/autofit/afstyles.h: Update Malayalam data; in particular, use
+ AF_WRITING_SYSTEM_LATIN.
+
+2016-02-16 Alexei Podtelezhnikov <apodtele@gmail.com>
+
+ [smooth] Fix integer overflow (#47114).
+
+ * src/smooth/ftgrays.c (TArea): Make it unconditionally `long'.
+
+2016-02-15 Werner Lemberg <wl@gnu.org>
+
+ * src/cff/cffparse.c (cff_parse_multiple_master): Improve tracing.
+
+2016-02-15 Werner Lemberg <wl@gnu.org>
+
+ [cff] Handle T2 operator only with old CFF engine (#47157).
+
+ * src/cff/cffparse.c (cff_parser_run) <opcode 31>: Enclose with
+ #ifdef CFF_CONFIG_OPTION_OLD_ENGINE...#endif.
+
+2016-02-15 Werner Lemberg <wl@gnu.org>
+
+ [cff] Partially handle `load' and `store' ops in old CFF engine.
+
+ Now all glyphs of MM CFFs like `ITCGaramondMM-It.otf' can be
+ displayed.
+
+ * src/cff/cffgload.c (cff_decoder_parse_charstrings) <cff_op_store,
+ cff_op_load>: Partially implement it.
+
+ * src/cff/cffparse.c (cff_parser_init): Add new parameter to pass
+ the number of Multiple Master axes.
+ Update all callers.
+ (cff_parse_multiple_master): Get number of axes.
+ (cff_parser_run) <opcode 31>: Updated.
+ * src/cff/cffparse.h: Updated.
+ (CFF_ParserRec): Add `num_axes' field.
+
+ * src/cff/cffload.c: Updated.
+
+ * src/cff/cfftypes.h (CFF_FontRecDictRec): Add `num_axes' field.
+
+2016-02-15 Werner Lemberg <wl@gnu.org>
+
+ [cff] Correctly trace SIDs that contain NULL bytes.
+
+ We need this to properly trace Multiple Master CFFs, which contain
+ two SIDs that are charstrings.
+
+ This commit makes FreeType also show the last SID, omitted
+ previously due to a bug.
+
+ * src/cff/cfftypes.h (CFF_FontRec): Add `string_pool_size' field.
+
+ * src/cff/cffload.c (cff_index_get_pointers): Add argument to return
+ the pool size.
+ Update all callers.
+
+ * src/cff/cffobjs.c (cff_face_init) [FT_DEBUG_LEVEL_TRACE]: Directly
+ access `cff->strings' to display the non-default strings.
+
+2016-02-14 Werner Lemberg <wl@gnu.org>
+
+ * src/base/fthash.c: Include FT_INTERNAL_MEMORY_H.
+
+2016-02-14 Werner Lemberg <wl@gnu.org>
+
+ * src/cff/cffparse.c: Include `cffgload.h'.
+
+ Problem reported by Colin Walters <walters@verbum.org>.
+
+2016-02-14 Werner Lemberg <wl@gnu.org>
+
+ [cff] Make old CFF engine show MM CFFs (without variations).
+
+ The new code only displays the first master in the font.
+
+ * src/cff/cffgload.c (cff_decode_parse_charstrings): Add new
+ parameter to allow function calls from dictionaries also.
+ <cff_op_blend>: Partially implement it.
+ Update all callers.
+ * src/cff/cffgload.h: Updated.
+
+ * src/cff/cffparse.c (cff_parser_init): Add new parameter to pass the
+ number of Multiple Master designs.
+ Update all callers.
+ (cff_parse_multiple_master): New function to rudimentarily parse
+ operator.
+ (cff_parser_run): Handle `T2' operator.
+ * src/cff/cffparse.h: Updated.
+ (CFF_ParserRec): Add `num_designs' field.
+
+ * src/cff/cffload.c: Updated.
+
+ * src/cff/cfftoken.h: Handle `MultipleMaster' operator.
+
+ * src/cff/cfftypes.h (CFF_FontRecDictRec): Add `num_designs' field.
+
+ * src/sfnt/sfobjs.c (sfnt_init_face): Don't handle `fvar' table for
+ MM CFFs.
+
+2016-02-09 Werner Lemberg <wl@gnu.org>
+
+ [docmaker] Don't emit trailing newlines.
+
+ * src/tools/docmaker/tohtml.py (HtmlFormatter::make_html_code):
+ Use `rstrip'.
+
2016-02-07 Werner Lemberg <wl@gnu.org>
* Version 2.6.3 released.
* include/freetype/freetype.h (FREETYPE_PATCH): Set to 3.
* builds/unix/configure.raw (version_info): Set to 18:3:12.
- * CMakeLists.txt (VERSION_PATCH): Set to 2.
+ * CMakeLists.txt (VERSION_PATCH): Set to 3.
* docs/CHANGES: Updated.
* src/autofit/afscript.h: Add another parameter to `SCRIPT',
specifying hinting direction.
- * src/autofit/afglobal.c, scr/autofit/afglobal.h,
+ * src/autofit/afglobal.c, src/autofit/afglobal.h,
src/autofit/afpic.c, src/autofit/afranges.h, src/autofit/afshaper.c,
src/autofit/aftypes.h: Extend `SCRIPT' definitions.
[bdf] Remove dead code (#46625).
The BDF specification only allows decimal numbers, no octal or
- hexidecimal decoding is needed.
+ hexadecimal decoding is needed.
* src/bdf/bdflib.c (_bdf_atoul, _bdf_atol, _bdf_atous,
_bdf_atos): Remove unused code and parameters.
* src/base/ftobjs.c (Mac_Read_sfnt_Resource, FT_Open_Face): Set
`error'.
-2015-12-14 Ben Wagner <bungeman@gmail.com>
+2015-12-14 Ben Wagner <bungeman@gmail.com>
[base] Check error when seeking to data supplied offset (#46635).
* src/base/ftobjs.c (open_face_PS_from_sfnt_stream):
- `ft_lookup_PS_in_sfnt_stream' returns offset and and length from
+ `ft_lookup_PS_in_sfnt_stream' returns offset and length from
user supplied data. Use of this these values must be checked.
2015-12-13 Werner Lemberg <wl@gnu.org>
* src/autofit/afglobal.c: s/hbshim.h/afshaper.h/.
(af_face_globals_compute_style_coverage): Updated.
- * src/autofit/afglocal.h: s/hbshim.h/afshaper.h/.
+ * src/autofit/afglobal.h: s/hbshim.h/afshaper.h/.
* src/autofit/autofit.c: s/hbshim.c/afshaper.c/.
2015-11-27 Tamas Kenez <tamas.kenez@adasworks.com>
- [cmake] Make `FindHarfbuzz' observe the REQUIRED option.
+ [cmake] Make `FindHarfBuzz' observe the REQUIRED option.
* builds/cmake/FindHarfBuzz.cmake: Implement it.
2015-10-04 Werner Lemberg <wl@gnu.org>
- [bzip2, gzip] Avoid access of unitialized memory (#46109).
+ [bzip2, gzip] Avoid access of uninitialized memory (#46109).
* src/bzip2/ftbzip2.c (ft_bzip2_file_fill_input), src/gzip/ftgzip.c
(ft_gzip_file_fill_input): In case of an error, adjust the limit to
2015-10-03 Werner Lemberg <wl@gnu.org>
- [bzip2, gzip] Avoid access of unitialized memory (#46109).
+ [bzip2, gzip] Avoid access of uninitialized memory (#46109).
* src/bzip2/ftbzip2.c (ft_bzip2_file_fill_output), src/gzip/ftgzip.c
(ft_gzip_file_fill_output): In case of an error, adjust the limit to
[raster,smooth] Microoptimizations.
* src/raster/ftraster.c (Insert_Y_Turn, Finalize_Profile_Table,
- Beziier_Up, ): Use do-while loops.
+ Bezier_Up, ): Use do-while loops.
* src/smooth/ftgrays.c (gray_render_scanline, gray_render_line,
gray_convert_glyph): Ditto.
[base] Improve emboldener (#45596).
* src/base/ftoutln.c (FT_Outline_EmboldenXY): Correct displacement
- of zero-lenght segments.
+ of zero-length segments.
2015-08-16 Alexei Podtelezhnikov <apodtele@gmail.com>
* src/type1/t1gload.c (T1_Load_Glyph): Directly modify advances only
if font matrix is not trivial.
* src/cff/cffgload.c (cff_slot_load): Ditto.
- * sff/cid/cidgload.c (cid_slot_load_glyph): Ditto for advances and the
+ * src/cid/cidgload.c (cid_slot_load_glyph): Ditto for advances and the
entire outline.
2015-08-11 Werner Lemberg <wl@gnu.org>
* src/autofit/aftypes.h [FT_DEBUG_AUTOFIT]: Include
FT_CONFIG_STANDARD_LIBRARY_H earlier.
- * src/truetype/ttpic.h: Include FT_INTERNL_PIC_H.
+ * src/truetype/ttpic.h: Include FT_INTERNAL_PIC_H.
2015-07-07 Werner Lemberg <wl@gnu.org>
(load_truetype_glyph), src/truetype/ttgxvar.c (tt_handle_deltas),
src/truetype/ttinterp.c (Ins_INSTCTRL): Fix signedness issues.
-2015-06-29 Alexei Podtelezhnikov <apodtele@gmail.com>
+2015-06-29 Alexei Podtelezhnikov <apodtele@gmail.com>
[truetype] Speed up bytecode interpreter.
* src/truetype/ttinterp.c (Normalize): Use `FT_Vector_NormLen'.
-2015-06-29 Alexei Podtelezhnikov <apodtele@gmail.com>
+2015-06-29 Alexei Podtelezhnikov <apodtele@gmail.com>
[base] Speed up emboldening.
* src/base/ftoutln.c (FT_Outline_EmboldenXY): Use
`FT_Vector_NormLen'.
-2015-06-29 Alexei Podtelezhnikov <apodtele@gmail.com>
+2015-06-29 Alexei Podtelezhnikov <apodtele@gmail.com>
[base] Implement fast vector normalization.
* docs/*: Updated.
-2015-06-24 Alexei Podtelezhnikov <apodtele@gmail.com>
+2015-06-24 Alexei Podtelezhnikov <apodtele@gmail.com>
* src/bdf/bdflib.c (_bdf_parse_start): Disallow 0 bpp.
-2015-06-24 Alexei Podtelezhnikov <apodtele@gmail.com>
+2015-06-24 Alexei Podtelezhnikov <apodtele@gmail.com>
* src/bdf/bdflib.c (_bdf_parse_start): Simplify bpp parsing.
incremental interface callback to apply the encoding to raw
character index (as it was in the previous code).
-2015-04-29 Alexei Podtelezhnikov <apodtele@gmail.com>
+2015-04-29 Alexei Podtelezhnikov <apodtele@gmail.com>
[autofit] Speed up IUP.
* src/cff/cffdrivr.c (cff_get_ps_name): Use the `sfnt' service if we
have an SFNT.
-2015-04-27 Alexei Podtelezhnikov <apodtele@gmail.com>
+2015-04-27 Alexei Podtelezhnikov <apodtele@gmail.com>
[truetype] Speed up IUP.
* src/autofit/afhints.h (AF_HINTS_DO_WARP): New macro.
- * src/autofi/aflatin.c (af_latin_hints_apply)
+ * src/autofit/aflatin.c (af_latin_hints_apply)
[AF_CONFIG_OPTION_USE_WARPER]: Use `AF_HINTS_DO_WARP' to control use
of warper.
* src/cff/cffgload.c (cff_slot_load): Use advance width and side
bearing values from `hmtx' table if present.
-2015-04-03 Alexei Podtelezhnikov <apodtele@gmail.com>
+2015-04-03 Alexei Podtelezhnikov <apodtele@gmail.com>
* src/autofit/afhints.c (af_glyph_hints_reload): Use do-while loop.
-2015-04-02 Alexei Podtelezhnikov <apodtele@gmail.com>
+2015-04-02 Alexei Podtelezhnikov <apodtele@gmail.com>
* src/autofit/aflatin.c (af_latin_hint_edges): Reduce logic.
-2015-04-01 Alexei Podtelezhnikov <apodtele@gmail.com>
+2015-04-01 Alexei Podtelezhnikov <apodtele@gmail.com>
[autofit] Finish the thought.
* src/cff/cffgload.c (cff_decoder_parse_charstrings)
<cff_op_callsubr, cff_op_callgsubr, cff_op_return>: Ditto.
-2015-03-21 Alexei Podtelezhnikov <apodtele@gmail.com>
+2015-03-21 Alexei Podtelezhnikov <apodtele@gmail.com>
[base] Optimize `FT_Angle_Diff'.
single-element runs. Cf. glyph `Q' in Skia.ttf with weights larger
than the default.
-2015-03-20 Alexei Podtelezhnikov <apodtele@gmail.com>
+2015-03-20 Alexei Podtelezhnikov <apodtele@gmail.com>
* src/base/fttrigon.c (FT_Vector_Rotate): Minor refactoring.
-2015-03-17 Alexei Podtelezhnikov <apodtele@gmail.com>
+2015-03-17 Alexei Podtelezhnikov <apodtele@gmail.com>
Fix Savannah bug #44412 (part 2).
include/config/ftheader.h, include/ftfntfmt.h, modules.cfg,
src/base/ftfntfmt.c, vms_make.com: Updated.
-2015-03-10 Alexei Podtelezhnikov <apodtele@gmail.com>
+2015-03-10 Alexei Podtelezhnikov <apodtele@gmail.com>
Fix Savannah bug #44412 (part 1).
Found by Alexei.
-2015-03-05 Alexei Podtelezhnikov <apodtele@gmail.com>
+2015-03-05 Alexei Podtelezhnikov <apodtele@gmail.com>
* src/base/ftstroke.c: Simplify.
* src/pfr/pfrload.c (pfr_extra_item_load_font_id): Ditto.
* src/psaux/psobjs.c (ps_table_add), src/psaux/psobjs.h: Ditto.
* src/type1/t1load.c (parse_blend_axis_types, parse_encoding,
- parse_chharstrings, parse_dict): Ditto.
+ parse_charstrings, parse_dict): Ditto.
* src/type42/t42parse.c (t42_parse_encoding, t42_parse_charstrings,
t42_parse_dict): Ditto.
* include/internal/ftstream.h (FT_Stream_Pos): Return `FT_ULong'.
* src/base/ftoutln.c, src/base/ftrfork.c, src/base/ftstream.c:
- Signedess fixes.
+ Signedness fixes.
2015-02-16 Werner Lemberg <wl@gnu.org>
2015-01-11 Werner Lemberg <wl@gnu.org>
- [truetype] Prettyfing.
+ [truetype] Prettifying.
* src/truetype/ttinterp.c (project, dualproj, fast_project,
fast_dualproj): Rename to...
[truetype] More macro expansions.
* src/truetype/ttinterp.c (INS_ARG): Remove macro by expansion,
- adjusting funtion calls where necessary.
+ adjusting function calls where necessary.
(FT_UNUSED_ARG): Removed, no longer needed.
2015-01-10 Werner Lemberg <wl@gnu.org>
- FreeType 2.6.3
+ FreeType 2.6.4
==============
Homepage: http://www.freetype.org
and download one of the following files.
- freetype-doc-2.6.3.tar.bz2
- freetype-doc-2.6.3.tar.gz
- ftdoc263.zip
+ freetype-doc-2.6.4.tar.bz2
+ freetype-doc-2.6.4.tar.gz
+ ftdoc264.zip
To view the documentation online, go to
/*************************************************************************/
/* */
/* Define TT_CONFIG_OPTION_SUBPIXEL_HINTING if you want to compile */
- /* EXPERIMENTAL subpixel hinting support into the TrueType driver. This */
- /* replaces the native TrueType hinting mechanism when anything but */
- /* FT_RENDER_MODE_MONO is requested. */
+ /* subpixel hinting support into the TrueType driver. This modifies the */
+ /* TrueType hinting mechanism when anything but FT_RENDER_MODE_MONO is */
+ /* requested. */
/* */
- /* Enabling this causes the TrueType driver to ignore instructions under */
- /* certain conditions. This is done in accordance with the guide here, */
- /* with some minor differences: */
+ /* In particular, it modifies the bytecode interpreter to interpret (or */
+ /* not) instructions in a certain way so that all TrueType fonts look */
+ /* like they do in a Windows ClearType (DirectWrite) environment. See */
+ /* [1] for a technical overview on what this means. See `ttinterp.h' */
+ /* for more details on the LEAN option. */
/* */
- /* http://www.microsoft.com/typography/cleartype/truetypecleartype.aspx */
+ /* There are three options. */
/* */
- /* By undefining this, you only compile the code necessary to hint */
- /* TrueType glyphs with native TT hinting. */
+ /* 1. This option is associated with the `Infinality' moniker. */
+ /* Contributed by an individual nicknamed Infinality with the goal of */
+ /* making TrueType fonts render better than on Windows. A high */
+ /* amount of configurability and flexibility, down to rules for */
+ /* single glyphs in fonts, but also very slow. Its experimental and */
+ /* slow nature and the original developer losing interest meant that */
+ /* this option was never enabled in default builds. */
/* */
- /* This option requires TT_CONFIG_OPTION_BYTECODE_INTERPRETER to be */
- /* defined. */
+ /* 2. The new default mode for the TrueType driver. The Infinality code */
+ /* base was stripped to the bare minimum and all configurability */
+ /* removed in the name of speed and simplicity. The configurability */
+ /* was mainly aimed at legacy fonts like Arial, Times New Roman, or */
+ /* Courier. Legacy fonts are fonts that modify vertical stems to */
+ /* achieve clean black-and-white bitmaps. The new mode focuses on */
+ /* applying a minimal set of rules to all fonts indiscriminately so */
+ /* that modern and web fonts render well while legacy fonts render */
+ /* okay. */
/* */
-#define TT_CONFIG_OPTION_SUBPIXEL_HINTING
+ /* 3. Compile both. */
+ /* */
+ /* By undefining these, you get rendering behavior like on Windows */
+ /* without ClearType, i.e., Windows XP without ClearType enabled and */
+ /* Win9x (interpreter version v35). Or not, depending on how much */
+ /* hinting blood and testing tears the font designer put into a given */
+ /* font. If you define one or both subpixel hinting options, you can */
+ /* switch between between v35 and the ones you define. */
+ /* */
+ /* This option requires TT_CONFIG_OPTION_BYTECODE_INTERPRETER to be */
+ /* defined. */
+ /* */
+ /* [1] http://www.microsoft.com/typography/cleartype/truetypecleartype.aspx */
+ /* */
+/* #define TT_CONFIG_OPTION_SUBPIXEL_HINTING 1 */
+/* #define TT_CONFIG_OPTION_SUBPIXEL_HINTING 2 */
+#define TT_CONFIG_OPTION_SUBPIXEL_HINTING ( 1 | 2 )
/*************************************************************************/
*/
#ifdef TT_CONFIG_OPTION_BYTECODE_INTERPRETER
#define TT_USE_BYTECODE_INTERPRETER
+
+#if TT_CONFIG_OPTION_SUBPIXEL_HINTING & 1
+#define TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY
+#endif
+
+#if TT_CONFIG_OPTION_SUBPIXEL_HINTING & 2
+#define TT_SUPPORT_SUBPIXEL_HINTING_MINIMAL
+#endif
#endif
/*************************************************************************/
/* */
/* Define TT_CONFIG_OPTION_SUBPIXEL_HINTING if you want to compile */
- /* EXPERIMENTAL subpixel hinting support into the TrueType driver. This */
- /* replaces the native TrueType hinting mechanism when anything but */
- /* FT_RENDER_MODE_MONO is requested. */
+ /* subpixel hinting support into the TrueType driver. This modifies the */
+ /* TrueType hinting mechanism when anything but FT_RENDER_MODE_MONO is */
+ /* requested. */
/* */
- /* Enabling this causes the TrueType driver to ignore instructions under */
- /* certain conditions. This is done in accordance with the guide here, */
- /* with some minor differences: */
+ /* In particular, it modifies the bytecode interpreter to interpret (or */
+ /* not) instructions in a certain way so that all TrueType fonts look */
+ /* like they do in a Windows ClearType (DirectWrite) environment. See */
+ /* [1] for a technical overview on what this means. See `ttinterp.h' */
+ /* for more details on the LEAN option. */
/* */
- /* http://www.microsoft.com/typography/cleartype/truetypecleartype.aspx */
+ /* There are three options. */
/* */
- /* By undefining this, you only compile the code necessary to hint */
- /* TrueType glyphs with native TT hinting. */
+ /* 1. This option is associated with the `Infinality' moniker. */
+ /* Contributed by an individual nicknamed Infinality with the goal of */
+ /* making TrueType fonts render better than on Windows. A high */
+ /* amount of configurability and flexibility, down to rules for */
+ /* single glyphs in fonts, but also very slow. Its experimental and */
+ /* slow nature and the original developer losing interest meant that */
+ /* this option was never enabled in default builds. */
/* */
- /* This option requires TT_CONFIG_OPTION_BYTECODE_INTERPRETER to be */
- /* defined. */
+ /* 2. The new default mode for the TrueType driver. The Infinality code */
+ /* base was stripped to the bare minimum and all configurability */
+ /* removed in the name of speed and simplicity. The configurability */
+ /* was mainly aimed at legacy fonts like Arial, Times New Roman, or */
+ /* Courier. Legacy fonts are fonts that modify vertical stems to */
+ /* achieve clean black-and-white bitmaps. The new mode focuses on */
+ /* applying a minimal set of rules to all fonts indiscriminately so */
+ /* that modern and web fonts render well while legacy fonts render */
+ /* okay. */
/* */
-/* #define TT_CONFIG_OPTION_SUBPIXEL_HINTING */
+ /* 3. Compile both. */
+ /* */
+ /* By undefining these, you get rendering behavior like on Windows */
+ /* without ClearType, i.e., Windows XP without ClearType enabled and */
+ /* Win9x (interpreter version v35). Or not, depending on how much */
+ /* hinting blood and testing tears the font designer put into a given */
+ /* font. If you define one or both subpixel hinting options, you can */
+ /* switch between between v35 and the ones you define. */
+ /* */
+ /* This option requires TT_CONFIG_OPTION_BYTECODE_INTERPRETER to be */
+ /* defined. */
+ /* */
+ /* [1] http://www.microsoft.com/typography/cleartype/truetypecleartype.aspx */
+ /* */
+/* #define TT_CONFIG_OPTION_SUBPIXEL_HINTING 1 */
+#define TT_CONFIG_OPTION_SUBPIXEL_HINTING 2
+/* #define TT_CONFIG_OPTION_SUBPIXEL_HINTING ( 1 | 2 ) */
/*************************************************************************/
*/
#ifdef TT_CONFIG_OPTION_BYTECODE_INTERPRETER
#define TT_USE_BYTECODE_INTERPRETER
+
+#if TT_CONFIG_OPTION_SUBPIXEL_HINTING & 1
+#define TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY
+#endif
+
+#if TT_CONFIG_OPTION_SUBPIXEL_HINTING & 2
+#define TT_SUPPORT_SUBPIXEL_HINTING_MINIMAL
+#endif
#endif
#define FT_INT_MAX INT_MAX
#define FT_INT_MIN INT_MIN
#define FT_UINT_MAX UINT_MAX
+#define FT_LONG_MIN LONG_MIN
#define FT_LONG_MAX LONG_MAX
#define FT_ULONG_MAX ULONG_MAX
/* */
/* FT_ENCODING_SJIS :: */
/* Corresponds to Japanese SJIS encoding. More info at */
- /* at `http://en.wikipedia.org/wiki/Shift_JIS'. */
+ /* `http://en.wikipedia.org/wiki/Shift_JIS'. */
/* See note on multi-byte encodings below. */
/* */
/* FT_ENCODING_GB2312 :: */
- /* Corresponds to an encoding system for Simplified Chinese as used */
+ /* Corresponds to an encoding system for Simplified Chinese as */
/* used in mainland China. */
/* */
/* FT_ENCODING_BIG5 :: */
/* FT_FACE_FLAG_SCALABLE :: */
/* Indicates that the face contains outline glyphs. This doesn't */
/* prevent bitmap strikes, i.e., a face can have both this and */
- /* and @FT_FACE_FLAG_FIXED_SIZES set. */
+ /* @FT_FACE_FLAG_FIXED_SIZES set. */
/* */
/* FT_FACE_FLAG_FIXED_SIZES :: */
/* Indicates that the face contains bitmap strikes. See also the */
*
*/
#define FT_HAS_HORIZONTAL( face ) \
- ( face->face_flags & FT_FACE_FLAG_HORIZONTAL )
+ ( (face)->face_flags & FT_FACE_FLAG_HORIZONTAL )
/*************************************************************************
*
*/
#define FT_HAS_VERTICAL( face ) \
- ( face->face_flags & FT_FACE_FLAG_VERTICAL )
+ ( (face)->face_flags & FT_FACE_FLAG_VERTICAL )
/*************************************************************************
*
*/
#define FT_HAS_KERNING( face ) \
- ( face->face_flags & FT_FACE_FLAG_KERNING )
+ ( (face)->face_flags & FT_FACE_FLAG_KERNING )
/*************************************************************************
*
*/
#define FT_IS_SCALABLE( face ) \
- ( face->face_flags & FT_FACE_FLAG_SCALABLE )
+ ( (face)->face_flags & FT_FACE_FLAG_SCALABLE )
/*************************************************************************
*
*/
#define FT_IS_SFNT( face ) \
- ( face->face_flags & FT_FACE_FLAG_SFNT )
+ ( (face)->face_flags & FT_FACE_FLAG_SFNT )
/*************************************************************************
*
*/
#define FT_IS_FIXED_WIDTH( face ) \
- ( face->face_flags & FT_FACE_FLAG_FIXED_WIDTH )
+ ( (face)->face_flags & FT_FACE_FLAG_FIXED_WIDTH )
/*************************************************************************
*
*/
#define FT_HAS_FIXED_SIZES( face ) \
- ( face->face_flags & FT_FACE_FLAG_FIXED_SIZES )
+ ( (face)->face_flags & FT_FACE_FLAG_FIXED_SIZES )
/*************************************************************************
*
*/
#define FT_HAS_GLYPH_NAMES( face ) \
- ( face->face_flags & FT_FACE_FLAG_GLYPH_NAMES )
+ ( (face)->face_flags & FT_FACE_FLAG_GLYPH_NAMES )
/*************************************************************************
*
*/
#define FT_HAS_MULTIPLE_MASTERS( face ) \
- ( face->face_flags & FT_FACE_FLAG_MULTIPLE_MASTERS )
+ ( (face)->face_flags & FT_FACE_FLAG_MULTIPLE_MASTERS )
/*************************************************************************
*
*/
#define FT_IS_CID_KEYED( face ) \
- ( face->face_flags & FT_FACE_FLAG_CID_KEYED )
+ ( (face)->face_flags & FT_FACE_FLAG_CID_KEYED )
/*************************************************************************
*
*/
#define FT_IS_TRICKY( face ) \
- ( face->face_flags & FT_FACE_FLAG_TRICKY )
+ ( (face)->face_flags & FT_FACE_FLAG_TRICKY )
/*************************************************************************
*
*/
#define FT_HAS_COLOR( face ) \
- ( face->face_flags & FT_FACE_FLAG_COLOR )
+ ( (face)->face_flags & FT_FACE_FLAG_COLOR )
/*************************************************************************/
/* */
/* If the @FT_OPEN_MEMORY bit is set, assume that this is a */
/* memory file of `memory_size' bytes, located at `memory_address'. */
- /* The data are are not copied, and the client is responsible for */
+ /* The data are not copied, and the client is responsible for */
/* releasing and destroying them _after_ the corresponding call to */
/* @FT_Done_Face. */
/* */
/* used to determine both scaling values. */
/* */
/* FT_SIZE_REQUEST_TYPE_REAL_DIM :: */
- /* The real dimension. The sum of the the `ascender' and (minus */
- /* of) the `descender' fields of @FT_FaceRec are used to determine */
- /* both scaling values. */
+ /* The real dimension. The sum of the `ascender' and (minus of) */
+ /* the `descender' fields of @FT_FaceRec are used to determine both */
+ /* scaling values. */
/* */
/* FT_SIZE_REQUEST_TYPE_BBOX :: */
/* The font bounding box. The width and height of the `bbox' field */
/* don't have a corresponding glyph in the font). See the discussion */
/* of the @FT_FACE_FLAG_CID_KEYED flag for more details. */
/* */
+ /* If you receive `FT_Err_Glyph_Too_Big', try getting the glyph */
+ /* outline at EM size, then scale it manually and fill it as a */
+ /* graphics operation. */
+ /* */
FT_EXPORT( FT_Error )
FT_Load_Glyph( FT_Face face,
FT_UInt glyph_index,
*
* If @FT_LOAD_RENDER is also set, the glyph is rendered in the
* corresponding mode (i.e., the mode that matches the used algorithm
- * best). An exeption is FT_LOAD_TARGET_MONO since it implies
+ * best). An exception is FT_LOAD_TARGET_MONO since it implies
* @FT_LOAD_MONOCHROME.
*
* You can use a hinting algorithm that doesn't correspond to the same
/* `.notdef'). */
/* */
/* This function always returns an error if the config macro */
- /* `FT_CONFIG_OPTION_NO_GLYPH_NAMES' is not defined in `ftoptions.h'. */
+ /* `FT_CONFIG_OPTION_NO_GLYPH_NAMES' is not defined in `ftoption.h'. */
/* */
FT_EXPORT( FT_Error )
FT_Get_Glyph_Name( FT_Face face,
*/
#define FREETYPE_MAJOR 2
#define FREETYPE_MINOR 6
-#define FREETYPE_PATCH 3
+#define FREETYPE_PATCH 4
/*************************************************************************/
* U+0F00 - U+0FFF // Tibetan
* U+1900 - U+194F // Limbu
* U+1B80 - U+1BBF // Sundanese
- * U+1C80 - U+1CDF // Meetei Mayak
* U+A800 - U+A82F // Syloti Nagri
+ * U+ABC0 - U+ABFF // Meetei Mayek
* U+11800 - U+118DF // Sharada
* }
*
/* aglyph :: The corresponding @FT_Glyph object. 0~in case of */
/* failure. */
/* */
- /* anode :: Used to return the address of of the corresponding cache */
+ /* anode :: Used to return the address of the corresponding cache */
/* node after incrementing its reference count (see note */
/* below). */
/* */
/* aglyph :: The corresponding @FT_Glyph object. 0~in case of */
/* failure. */
/* */
- /* anode :: Used to return the address of of the corresponding */
+ /* anode :: Used to return the address of the corresponding */
/* cache node after incrementing its reference count */
/* (see note below). */
/* */
/* <Output> */
/* sbit :: A handle to a small bitmap descriptor. */
/* */
- /* anode :: Used to return the address of of the corresponding cache */
+ /* anode :: Used to return the address of the corresponding cache */
/* node after incrementing its reference count (see note */
/* below). */
/* */
/* <Output> */
/* sbit :: A handle to a small bitmap descriptor. */
/* */
- /* anode :: Used to return the address of of the corresponding */
+ /* anode :: Used to return the address of the corresponding */
/* cache node after incrementing its reference count */
/* (see note below). */
/* */
* features preserve the design's weight and spacing much better than
* aliased type would.
*
- * 2) Aligment in the vertical direction: Weights and spacing along the
+ * 2) Alignment in the vertical direction: Weights and spacing along the
* y~axis are less critical; what is much more important is the visual
* alignment of related features (like cap-height and x-height). The
* sense of alignment for these is enhanced by the sharpness of grid-fit
* to minimize distortion.
*
* @order:
- * hinting-engine
+ * hinting-engine[cff]
* no-stem-darkening[cff]
* darkening-parameters[cff]
*
/**************************************************************************
*
* @property:
- * hinting-engine
+ * hinting-engine[cff]
*
* @description:
* Thanks to Adobe, which contributed a new hinting (and parsing)
* FT_CFF_HINTING_XXX
*
* @description:
- * A list of constants used for the @hinting-engine property to select
- * the hinting engine for CFF fonts.
+ * A list of constants used for the @hinting-engine[cff] property to
+ * select the hinting engine for CFF fonts.
*
* @values:
* FT_CFF_HINTING_FREETYPE ::
*
* @description:
* Retrieve the type of the input face, CID keyed or not. In
- * constrast to the @FT_IS_CID_KEYED macro this function returns
- * successfully also for CID-keyed fonts in an SNFT wrapper.
+ * contrast to the @FT_IS_CID_KEYED macro this function returns
+ * successfully also for CID-keyed fonts in an SFNT wrapper.
*
* @input:
* face ::
*
* @inout:
* output_len ::
- * Before calling the function, this is the the total size of the
- * output buffer, which must be large enough to hold the entire
- * uncompressed data (so the size of the uncompressed data must be
- * known in advance). After calling the function, `output_len' is the
- * size of the used data in `output'.
+ * Before calling the function, this is the total size of the output
+ * buffer, which must be large enough to hold the entire uncompressed
+ * data (so the size of the uncompressed data must be known in
+ * advance). After calling the function, `output_len' is the size of
+ * the used data in `output'.
*
* @return:
* FreeType error code. 0~means success.
/*************************************************************************/
/* */
/* A raster is a scan converter, in charge of rendering an outline into */
- /* a a bitmap. This section contains the public API for rasters. */
+ /* a bitmap. This section contains the public API for rasters. */
/* */
/* Note that in FreeType 2, all rasters are now encapsulated within */
/* specific modules called `renderers'. See `ftrender.h' for more */
#define FT_VALIDATE_JSTF 0x1000
#define FT_VALIDATE_MATH 0x2000
-#define FT_VALIDATE_OT FT_VALIDATE_BASE | \
- FT_VALIDATE_GDEF | \
- FT_VALIDATE_GPOS | \
- FT_VALIDATE_GSUB | \
- FT_VALIDATE_JSTF | \
- FT_VALIDATE_MATH
+#define FT_VALIDATE_OT ( FT_VALIDATE_BASE | \
+ FT_VALIDATE_GDEF | \
+ FT_VALIDATE_GPOS | \
+ FT_VALIDATE_GSUB | \
+ FT_VALIDATE_JSTF | \
+ FT_VALIDATE_MATH )
/**********************************************************************
*
* The stream size in bytes.
*
* In case of compressed streams where the size is unknown before
- * actually doing the decompression, the value is set to 0x7FFFFFFF.
+ * actually doing the decompression, the value is set to 0x7FFFFFFF.
* (Note that this size value can occur for normal streams also; it is
* thus just a hint.)
*
* interpreter-version
*
* @description:
- * Currently, two versions are available, representing the bytecode
- * interpreter with and without subpixel hinting support,
- * respectively. The default is subpixel support if
- * TT_CONFIG_OPTION_SUBPIXEL_HINTING is defined, and no subpixel
- * support otherwise (since it isn't available then).
+
+ * Currently, three versions are available, two representing the
+ * bytecode interpreter with subpixel hinting support (old `Infinality'
+ * code and new stripped-down and higher performance `minimal' code) and
+ * one without, respectively. The default is subpixel support if
+ * TT_CONFIG_OPTION_SUBPIXEL_HINTING is defined, and no subpixel support
+ * otherwise (since it isn't available then).
*
* If subpixel hinting is on, many TrueType bytecode instructions behave
* differently compared to B/W or grayscale rendering (except if `native
- * ClearType' is selected by the font). The main idea is to render at a
- * much increased horizontal resolution, then sampling down the created
- * output to subpixel precision. However, many older fonts are not
- * suited to this and must be specially taken care of by applying
- * (hardcoded) font-specific tweaks.
+ * ClearType' is selected by the font). Microsoft's main idea is to
+ * render at a much increased horizontal resolution, then sampling down
+ * the created output to subpixel precision. However, many older fonts
+ * are not suited to this and must be specially taken care of by
+ * applying (hardcoded) tweaks in Microsoft's interpreter.
*
* Details on subpixel hinting and some of the necessary tweaks can be
* found in Greg Hitchcock's whitepaper at
- * `http://www.microsoft.com/typography/cleartype/truetypecleartype.aspx'.
+ * `http://www.microsoft.com/typography/cleartype/truetypecleartype.aspx'.
+ * Note that FreeType currently doesn't really `subpixel hint' (6x1, 6x2,
+ * or 6x5 supersampling) like discussed in the paper. Depending on the
+ * chosen interpreter, it simply ignores instructions on vertical stems
+ * to arrive at very similar results.
*
- * The following example code demonstrates how to activate subpixel
+ * The following example code demonstrates how to deactivate subpixel
* hinting (omitting the error handling).
*
* {
* FT_Library library;
* FT_Face face;
- * FT_UInt interpreter_version = TT_INTERPRETER_VERSION_38;
+ * FT_UInt interpreter_version = TT_INTERPRETER_VERSION_35;
*
*
* FT_Init_FreeType( &library );
*
* TT_INTERPRETER_VERSION_38 ::
* Version~38 corresponds to MS rasterizer v.1.9; it is roughly
- * equivalent to the hinting provided by DirectWrite ClearType (as
- * can be found, for example, in the Internet Explorer~9 running on
- * Windows~7).
+ * equivalent to the hinting provided by DirectWrite ClearType (as can
+ * be found, for example, in the Internet Explorer~9 running on
+ * Windows~7). It is used in FreeType to select the `Infinality'
+ * subpixel hinting code. The code may be removed in a future
+ * version.
+ *
+ * TT_INTERPRETER_VERSION_40 ::
+ * Version~40 corresponds to MS rasterizer v.2.1; it is roughly
+ * equivalent to the hinting provided by DirectWrite ClearType (as can
+ * be found, for example, in Microsoft's Edge Browser on Windows~10).
+ * It is used in FreeType to select the `minimal' subpixel hinting
+ * code, a stripped-down and higher performance version of the
+ * `Infinality' code.
*
* @note:
* This property controls the behaviour of the bytecode interpreter
* get rasterized! In particular, it does not control subpixel color
* filtering.
*
- * If FreeType has not been compiled with configuration option
- * FT_CONFIG_OPTION_SUBPIXEL_HINTING, selecting version~38 causes an
- * `FT_Err_Unimplemented_Feature' error.
+ * If FreeType has not been compiled with the configuration option
+ * FT_CONFIG_OPTION_SUBPIXEL_HINTING, selecting version~38 or~40 causes
+ * an `FT_Err_Unimplemented_Feature' error.
*
* Depending on the graphics framework, Microsoft uses different
* bytecode and rendering engines. As a consequence, the version
* the version~1 gasp table exclusively (like Color ClearType), while
* v1.6 only respects the values of version~0 (bits 0 and~1).
*
- * FreeType doesn't provide all capabilities of the most recent
- * ClearType incarnation, thus we identify our subpixel support as
- * version~38.
+ * Keep in mind that the features of the above interpreter versions
+ * might not map exactly to FreeType features or behavior because it is
+ * a fundamentally different library with different internals.
*
*/
#define TT_INTERPRETER_VERSION_35 35
#define TT_INTERPRETER_VERSION_38 38
+#define TT_INTERPRETER_VERSION_40 40
/* */
/* And when it is no longer needed a `destroy' function needs to be */
/* called to release that allocation. */
/* */
- /* `fcinit.c' (ft_create_default_module_classes) already contains a */
+ /* `ftinit.c' (ft_create_default_module_classes) already contains a */
/* mechanism to call these functions for the default modules */
/* described in `ftmodule.h'. */
/* */
#ifdef __cplusplus
- extern "C++"
+extern "C++"
+{
template <typename T> inline T*
cplusplus_typeof( T*,
void *v )
{
return static_cast <T*> ( v );
}
+}
#define FT_ASSIGNP( p, val ) (p) = cplusplus_typeof( (p), (val) )
/* filtering callback function. */
/* */
/* pic_container :: Contains global structs and tables, instead */
- /* of defining them globallly. */
+ /* of defining them globally. */
/* */
/* refcount :: A counter initialized to~1 at the time an */
/* @FT_Library structure is created. */
/* */
/* <Description> */
/* Used to initialize an instance of FT_Outline_Funcs struct. */
- /* When FT_CONFIG_OPTION_PIC is defined an init funtion will need to */
- /* be called with a pre-allocated structure to be filled. */
+ /* When FT_CONFIG_OPTION_PIC is defined an init function will need */
+ /* to be called with a pre-allocated structure to be filled. */
/* When FT_CONFIG_OPTION_PIC is not defined the struct will be */
/* allocated in the global scope (or the scope where the macro */
/* is used). */
/* */
/* <Description> */
/* Used to initialize an instance of FT_Raster_Funcs struct. */
- /* When FT_CONFIG_OPTION_PIC is defined an init funtion will need to */
- /* be called with a pre-allocated structure to be filled. */
+ /* When FT_CONFIG_OPTION_PIC is defined an init function will need */
+ /* to be called with a pre-allocated structure to be filled. */
/* When FT_CONFIG_OPTION_PIC is not defined the struct will be */
/* allocated in the global scope (or the scope where the macro */
/* is used). */
/* */
/* <Description> */
/* Used to initialize an instance of FT_Glyph_Class struct. */
- /* When FT_CONFIG_OPTION_PIC is defined an init funtion will need to */
- /* be called with a pre-allocated stcture to be filled. */
+ /* When FT_CONFIG_OPTION_PIC is defined an init function will need */
+ /* to be called with a pre-allocated structure to be filled. */
/* When FT_CONFIG_OPTION_PIC is not defined the struct will be */
/* allocated in the global scope (or the scope where the macro */
/* is used). */
/* <Description> */
/* Used to initialize an instance of FT_Renderer_Class struct. */
/* */
- /* When FT_CONFIG_OPTION_PIC is defined a `create' funtion will need */
- /* to be called with a pointer where the allocated structure is */
+ /* When FT_CONFIG_OPTION_PIC is defined a `create' function will */
+ /* need to be called with a pointer where the allocated structure is */
/* returned. And when it is no longer needed a `destroy' function */
/* needs to be called to release that allocation. */
- /* `fcinit.c' (ft_create_default_module_classes) already contains */
+ /* `ftinit.c' (ft_create_default_module_classes) already contains */
/* a mechanism to call these functions for the default modules */
/* described in `ftmodule.h'. */
/* */
/* <Description> */
/* Used to initialize an instance of an FT_Module_Class struct. */
/* */
- /* When FT_CONFIG_OPTION_PIC is defined a `create' funtion needs to */
- /* be called with a pointer where the allocated structure is */
+ /* When FT_CONFIG_OPTION_PIC is defined a `create' function needs */
+ /* to be called with a pointer where the allocated structure is */
/* returned. And when it is no longer needed a `destroy' function */
/* needs to be called to release that allocation. */
- /* `fcinit.c' (ft_create_default_module_classes) already contains */
+ /* `ftinit.c' (ft_create_default_module_classes) already contains */
/* a mechanism to call these functions for the default modules */
/* described in `ftmodule.h'. */
/* */
/* sort_by_res_id :: */
/* A Boolean to sort the fragmented resource by their ids. */
/* The fragmented resources for `POST' resource should be sorted */
- /* to restore Type1 font properly. For `snft' resources, sorting */
+ /* to restore Type1 font properly. For `sfnt' resources, sorting */
/* may induce a different order of the faces in comparison to that */
/* by QuickDraw API. */
/* */
#define FT_INTERNAL_POSTSCRIPT_AUX_H <freetype/internal/psaux.h>
#define FT_INTERNAL_POSTSCRIPT_HINTS_H <freetype/internal/pshints.h>
-#define FT_INTERNAL_POSTSCRIPT_GLOBALS_H <freetype/internal/psglobal.h>
#define FT_INTERNAL_AUTOHINT_H <freetype/internal/autohint.h>
/* */
/* CompLength :: Compressed table length (in bytes). */
/* */
- /* OrigLength :: Unompressed table length (in bytes). */
+ /* OrigLength :: Uncompressed table length (in bytes). */
/* */
/* CheckSum :: The table checksum. This value can be ignored. */
/* */
FT_ULong horz_metrics_offset;
FT_ULong vert_metrics_offset;
-#ifdef TT_CONFIG_OPTION_SUBPIXEL_HINTING
+#ifdef TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY
/* since 2.4.12 */
FT_ULong sph_found_func_flags; /* special functions found */
/* for this face */
FT_Bool sph_compatibility_mode;
-#endif /* TT_CONFIG_OPTION_SUBPIXEL_HINTING */
+#endif /* TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY */
} TT_FaceRec;
/* */
/* FT_SFNT_HHEA :: To access the font's @TT_HoriHeader structure. */
/* */
- /* FT_SFNT_VHEA :: To access the font's @TT_VertHeader struture. */
+ /* FT_SFNT_VHEA :: To access the font's @TT_VertHeader structure. */
/* */
/* FT_SFNT_POST :: To access the font's @TT_Postscript structure. */
/* */
'\0',
'\xD9', '\x80', /* ـ */
'\0',
+ '\xD4', '\xB1', ' ', '\xD5', '\x84', ' ', '\xD5', '\x92', ' ', '\xD5', '\x93', ' ', '\xD4', '\xB2', ' ', '\xD4', '\xB3', ' ', '\xD4', '\xB4', ' ', '\xD5', '\x95', /* Ա Մ Ւ Փ Բ Գ Դ Օ */
+ '\0',
+ '\xD5', '\x92', ' ', '\xD5', '\x88', ' ', '\xD5', '\x93', ' ', '\xD5', '\x83', ' ', '\xD5', '\x87', ' ', '\xD5', '\x8D', ' ', '\xD5', '\x8F', ' ', '\xD5', '\x95', /* Ւ Ո Փ Ճ Շ Ս Տ Օ */
+ '\0',
+ '\xD5', '\xA5', ' ', '\xD5', '\xA7', ' ', '\xD5', '\xAB', ' ', '\xD5', '\xB4', ' ', '\xD5', '\xBE', ' ', '\xD6', '\x83', ' ', '\xD6', '\x86', ' ', '\xD6', '\x83', /* ե է ի մ վ փ ֆ փ */
+ '\0',
+ '\xD5', '\xA1', ' ', '\xD5', '\xB5', ' ', '\xD6', '\x82', ' ', '\xD5', '\xBD', ' ', '\xD5', '\xA3', ' ', '\xD5', '\xBB', ' ', '\xD6', '\x80', ' ', '\xD6', '\x85', /* ա յ ւ ս գ ջ ր օ */
+ '\0',
+ '\xD5', '\xB0', ' ', '\xD5', '\xB8', ' ', '\xD5', '\xB3', ' ', '\xD5', '\xA1', ' ', '\xD5', '\xA5', ' ', '\xD5', '\xAE', ' ', '\xD5', '\xBD', ' ', '\xD6', '\x85', /* հ ո ճ ա ե ծ ս օ */
+ '\0',
+ '\xD5', '\xA2', ' ', '\xD5', '\xA8', ' ', '\xD5', '\xAB', ' ', '\xD5', '\xAC', ' ', '\xD5', '\xB2', ' ', '\xD5', '\xBA', ' ', '\xD6', '\x83', ' ', '\xD6', '\x81', /* բ ը ի լ ղ պ փ ց */
+ '\0',
'\xE0', '\xA6', '\x85', ' ', '\xE0', '\xA6', '\xA1', ' ', '\xE0', '\xA6', '\xA4', ' ', '\xE0', '\xA6', '\xA8', ' ', '\xE0', '\xA6', '\xAC', ' ', '\xE0', '\xA6', '\xAD', ' ', '\xE0', '\xA6', '\xB2', ' ', '\xE0', '\xA6', '\x95', /* অ ড ত ন ব ভ ল ক */
'\0',
'\xE0', '\xA6', '\x87', ' ', '\xE0', '\xA6', '\x9F', ' ', '\xE0', '\xA6', '\xA0', ' ', '\xE0', '\xA6', '\xBF', ' ', '\xE0', '\xA7', '\x80', ' ', '\xE0', '\xA7', '\x88', ' ', '\xE0', '\xA7', '\x97', /* ই ট ঠ ি ী ৈ ৗ */
'\0',
'\xE0', '\xA6', '\x93', ' ', '\xE0', '\xA6', '\x8F', ' ', '\xE0', '\xA6', '\xA1', ' ', '\xE0', '\xA6', '\xA4', ' ', '\xE0', '\xA6', '\xA8', ' ', '\xE0', '\xA6', '\xAC', ' ', '\xE0', '\xA6', '\xB2', ' ', '\xE0', '\xA6', '\x95', /* ও এ ড ত ন ব ল ক */
'\0',
+ '\xE1', '\x8F', '\x86', ' ', '\xE1', '\x8E', '\xBB', ' ', '\xE1', '\x8E', '\xAC', ' ', '\xE1', '\x8F', '\x83', ' ', '\xE1', '\x8E', '\xA4', ' ', '\xE1', '\x8F', '\xA3', ' ', '\xE1', '\x8E', '\xA6', ' ', '\xE1', '\x8F', '\x95', /* Ꮖ Ꮋ Ꭼ Ꮓ Ꭴ Ꮳ Ꭶ Ꮥ */
+ '\0',
+ '\xEA', '\xAE', '\x92', ' ', '\xEA', '\xAE', '\xA4', ' ', '\xEA', '\xAE', '\xB6', ' ', '\xEA', '\xAD', '\xB4', ' ', '\xEA', '\xAD', '\xBE', ' ', '\xEA', '\xAE', '\x97', ' ', '\xEA', '\xAE', '\x9D', ' ', '\xEA', '\xAE', '\xBF', /* ꮒ ꮤ ꮶ ꭴ ꭾ ꮗ ꮝ ꮿ */
+ '\0',
+ '\xEA', '\xAE', '\x96', ' ', '\xEA', '\xAD', '\xBC', ' ', '\xEA', '\xAE', '\x93', ' ', '\xEA', '\xAE', '\xA0', ' ', '\xEA', '\xAE', '\xB3', ' ', '\xEA', '\xAD', '\xB6', ' ', '\xEA', '\xAE', '\xA5', ' ', '\xEA', '\xAE', '\xBB', /* ꮖ ꭼ ꮓ ꮠ ꮳ ꭶ ꮥ ꮻ */
+ '\0',
+ '\xE1', '\x8F', '\xB8', ' ', '\xEA', '\xAE', '\x90', ' ', '\xEA', '\xAD', '\xB9', ' ', '\xEA', '\xAD', '\xBB', /* ᏸ ꮐ ꭹ ꭻ */
+ '\0',
'\xD0', '\x91', ' ', '\xD0', '\x92', ' ', '\xD0', '\x95', ' ', '\xD0', '\x9F', ' ', '\xD0', '\x97', ' ', '\xD0', '\x9E', ' ', '\xD0', '\xA1', ' ', '\xD0', '\xAD', /* Б В Е П З О С Э */
'\0',
'\xD0', '\x91', ' ', '\xD0', '\x92', ' ', '\xD0', '\x95', ' ', '\xD0', '\xA8', ' ', '\xD0', '\x97', ' ', '\xD0', '\x9E', ' ', '\xD0', '\xA1', ' ', '\xD0', '\xAD', /* Б В Е Ш З О С Э */
'\0',
'\xE0', '\xA5', '\x81', ' ', '\xE0', '\xA5', '\x83', /* ु ृ */
'\0',
+ '\xE1', '\x88', '\x80', ' ', '\xE1', '\x88', '\x83', ' ', '\xE1', '\x8B', '\x98', ' ', '\xE1', '\x8D', '\x90', ' ', '\xE1', '\x88', '\x9B', ' ', '\xE1', '\x89', '\xA0', ' ', '\xE1', '\x8B', '\x8B', ' ', '\xE1', '\x8B', '\x90', /* ሀ ሃ ዘ ፐ ማ በ ዋ ዐ */
+ '\0',
+ '\xE1', '\x88', '\x88', ' ', '\xE1', '\x88', '\x90', ' ', '\xE1', '\x89', '\xA0', ' ', '\xE1', '\x8B', '\x98', ' ', '\xE1', '\x88', '\x80', ' ', '\xE1', '\x88', '\xAA', ' ', '\xE1', '\x8B', '\x90', ' ', '\xE1', '\x8C', '\xA8', /* ለ ሐ በ ዘ ሀ ሪ ዐ ጨ */
+ '\0',
+ '\xE1', '\x83', '\x92', ' ', '\xE1', '\x83', '\x93', ' ', '\xE1', '\x83', '\x94', ' ', '\xE1', '\x83', '\x95', ' ', '\xE1', '\x83', '\x97', ' ', '\xE1', '\x83', '\x98', ' ', '\xE1', '\x83', '\x9D', ' ', '\xE1', '\x83', '\xA6', /* გ დ ე ვ თ ი ო ღ */
+ '\0',
+ '\xE1', '\x83', '\x90', ' ', '\xE1', '\x83', '\x96', ' ', '\xE1', '\x83', '\x9B', ' ', '\xE1', '\x83', '\xA1', ' ', '\xE1', '\x83', '\xA8', ' ', '\xE1', '\x83', '\xAB', ' ', '\xE1', '\x83', '\xAE', ' ', '\xE1', '\x83', '\x9E', /* ა ზ მ ს შ ძ ხ პ */
+ '\0',
+ '\xE1', '\x83', '\xA1', ' ', '\xE1', '\x83', '\xAE', ' ', '\xE1', '\x83', '\xA5', ' ', '\xE1', '\x83', '\x96', ' ', '\xE1', '\x83', '\x9B', ' ', '\xE1', '\x83', '\xA8', ' ', '\xE1', '\x83', '\xA9', ' ', '\xE1', '\x83', '\xAC', /* ს ხ ქ ზ მ შ ჩ წ */
+ '\0',
+ '\xE1', '\x83', '\x94', ' ', '\xE1', '\x83', '\x95', ' ', '\xE1', '\x83', '\x9F', ' ', '\xE1', '\x83', '\xA2', ' ', '\xE1', '\x83', '\xA3', ' ', '\xE1', '\x83', '\xA4', ' ', '\xE1', '\x83', '\xA5', ' ', '\xE1', '\x83', '\xA7', /* ე ვ ჟ ტ უ ფ ქ ყ */
+ '\0',
+ '\xE1', '\x82', '\xB1', ' ', '\xE1', '\x82', '\xA7', ' ', '\xE1', '\x82', '\xB9', ' ', '\xE1', '\x82', '\xBC', ' ', '\xE1', '\x82', '\xA4', ' ', '\xE1', '\x82', '\xA5', ' ', '\xE1', '\x82', '\xB3', ' ', '\xE1', '\x82', '\xBA', /* Ⴑ Ⴇ Ⴙ Ⴜ Ⴄ Ⴅ Ⴓ Ⴚ */
+ '\0',
+ '\xE1', '\x82', '\xA4', ' ', '\xE1', '\x82', '\xA5', ' ', '\xE1', '\x82', '\xA7', ' ', '\xE1', '\x82', '\xA8', ' ', '\xE1', '\x82', '\xA6', ' ', '\xE1', '\x82', '\xB1', ' ', '\xE1', '\x82', '\xAA', ' ', '\xE1', '\x82', '\xAB', /* Ⴄ Ⴅ Ⴇ Ⴈ Ⴆ Ⴑ Ⴊ Ⴋ */
+ '\0',
+ '\xE2', '\xB4', '\x81', ' ', '\xE2', '\xB4', '\x97', ' ', '\xE2', '\xB4', '\x82', ' ', '\xE2', '\xB4', '\x84', ' ', '\xE2', '\xB4', '\x85', ' ', '\xE2', '\xB4', '\x87', ' ', '\xE2', '\xB4', '\x94', ' ', '\xE2', '\xB4', '\x96', /* ⴁ ⴗ ⴂ ⴄ ⴅ ⴇ ⴔ ⴖ */
+ '\0',
+ '\xE2', '\xB4', '\x88', ' ', '\xE2', '\xB4', '\x8C', ' ', '\xE2', '\xB4', '\x96', ' ', '\xE2', '\xB4', '\x8E', ' ', '\xE2', '\xB4', '\x83', ' ', '\xE2', '\xB4', '\x86', ' ', '\xE2', '\xB4', '\x8B', ' ', '\xE2', '\xB4', '\xA2', /* ⴈ ⴌ ⴖ ⴎ ⴃ ⴆ ⴋ ⴢ */
+ '\0',
+ '\xE2', '\xB4', '\x90', ' ', '\xE2', '\xB4', '\x91', ' ', '\xE2', '\xB4', '\x93', ' ', '\xE2', '\xB4', '\x95', ' ', '\xE2', '\xB4', '\x99', ' ', '\xE2', '\xB4', '\x9B', ' ', '\xE2', '\xB4', '\xA1', ' ', '\xE2', '\xB4', '\xA3', /* ⴐ ⴑ ⴓ ⴕ ⴙ ⴛ ⴡ ⴣ */
+ '\0',
+ '\xE2', '\xB4', '\x84', ' ', '\xE2', '\xB4', '\x85', ' ', '\xE2', '\xB4', '\x94', ' ', '\xE2', '\xB4', '\x95', ' ', '\xE2', '\xB4', '\x81', ' ', '\xE2', '\xB4', '\x82', ' ', '\xE2', '\xB4', '\x98', ' ', '\xE2', '\xB4', '\x9D', /* ⴄ ⴅ ⴔ ⴕ ⴁ ⴂ ⴘ ⴝ */
+ '\0',
'\xCE', '\x93', ' ', '\xCE', '\x92', ' ', '\xCE', '\x95', ' ', '\xCE', '\x96', ' ', '\xCE', '\x98', ' ', '\xCE', '\x9F', ' ', '\xCE', '\xA9', /* Γ Β Ε Ζ Θ Ο Ω */
'\0',
'\xCE', '\x92', ' ', '\xCE', '\x94', ' ', '\xCE', '\x96', ' ', '\xCE', '\x9E', ' ', '\xCE', '\x98', ' ', '\xCE', '\x9F', /* Β Δ Ζ Ξ Θ Ο */
'\0',
'\xCE', '\xB2', ' ', '\xCE', '\xB3', ' ', '\xCE', '\xB7', ' ', '\xCE', '\xBC', ' ', '\xCF', '\x81', ' ', '\xCF', '\x86', ' ', '\xCF', '\x87', ' ', '\xCF', '\x88', /* β γ η μ ρ φ χ ψ */
'\0',
+ '\xE0', '\xAA', '\xA4', ' ', '\xE0', '\xAA', '\xA8', ' ', '\xE0', '\xAA', '\x8B', ' ', '\xE0', '\xAA', '\x8C', ' ', '\xE0', '\xAA', '\x9B', ' ', '\xE0', '\xAA', '\x9F', ' ', '\xE0', '\xAA', '\xB0', ' ', '\xE0', '\xAB', '\xA6', /* ત ન ઋ ઌ છ ટ ર ૦ */
+ '\0',
+ '\xE0', '\xAA', '\x96', ' ', '\xE0', '\xAA', '\x97', ' ', '\xE0', '\xAA', '\x98', ' ', '\xE0', '\xAA', '\x9E', ' ', '\xE0', '\xAA', '\x87', ' ', '\xE0', '\xAA', '\x88', ' ', '\xE0', '\xAA', '\xA0', ' ', '\xE0', '\xAA', '\x9C', /* ખ ગ ઘ ઞ ઇ ઈ ઠ જ */
+ '\0',
+ '\xE0', '\xAA', '\x88', ' ', '\xE0', '\xAA', '\x8A', ' ', '\xE0', '\xAA', '\xBF', ' ', '\xE0', '\xAB', '\x80', ' ', '\xE0', '\xAA', '\xB2', '\xE0', '\xAB', '\x80', ' ', '\xE0', '\xAA', '\xB6', '\xE0', '\xAB', '\x8D', '\xE0', '\xAA', '\x9A', '\xE0', '\xAA', '\xBF', ' ', '\xE0', '\xAA', '\x9C', '\xE0', '\xAA', '\xBF', ' ', '\xE0', '\xAA', '\xB8', '\xE0', '\xAB', '\x80', /* ઈ ઊ િ ી લી શ્ચિ જિ સી */
+ '\0',
+ '\xE0', '\xAB', '\x81', ' ', '\xE0', '\xAB', '\x83', ' ', '\xE0', '\xAB', '\x84', ' ', '\xE0', '\xAA', '\x96', '\xE0', '\xAB', '\x81', ' ', '\xE0', '\xAA', '\x9B', '\xE0', '\xAB', '\x83', ' ', '\xE0', '\xAA', '\x9B', '\xE0', '\xAB', '\x84', /* ુ ૃ ૄ ખુ છૃ છૄ */
+ '\0',
+ '\xE0', '\xAB', '\xA6', ' ', '\xE0', '\xAB', '\xA7', ' ', '\xE0', '\xAB', '\xA8', ' ', '\xE0', '\xAB', '\xA9', ' ', '\xE0', '\xAB', '\xAD', /* ૦ ૧ ૨ ૩ ૭ */
+ '\0',
+ '\xE0', '\xA8', '\x95', ' ', '\xE0', '\xA8', '\x97', ' ', '\xE0', '\xA8', '\x99', ' ', '\xE0', '\xA8', '\x9A', ' ', '\xE0', '\xA8', '\x9C', ' ', '\xE0', '\xA8', '\xA4', ' ', '\xE0', '\xA8', '\xA7', ' ', '\xE0', '\xA8', '\xB8', /* ਕ ਗ ਙ ਚ ਜ ਤ ਧ ਸ */
+ '\0',
+ '\xE0', '\xA8', '\x95', ' ', '\xE0', '\xA8', '\x97', ' ', '\xE0', '\xA8', '\x99', ' ', '\xE0', '\xA8', '\x9A', ' ', '\xE0', '\xA8', '\x9C', ' ', '\xE0', '\xA8', '\xA4', ' ', '\xE0', '\xA8', '\xA7', ' ', '\xE0', '\xA8', '\xB8', /* ਕ ਗ ਙ ਚ ਜ ਤ ਧ ਸ */
+ '\0',
+ '\xE0', '\xA8', '\x87', ' ', '\xE0', '\xA8', '\x88', ' ', '\xE0', '\xA8', '\x89', ' ', '\xE0', '\xA8', '\x8F', ' ', '\xE0', '\xA8', '\x93', ' ', '\xE0', '\xA9', '\xB3', ' ', '\xE0', '\xA8', '\xBF', ' ', '\xE0', '\xA9', '\x80', /* ਇ ਈ ਉ ਏ ਓ ੳ ਿ ੀ */
+ '\0',
+ '\xE0', '\xA8', '\x85', ' ', '\xE0', '\xA8', '\x8F', ' ', '\xE0', '\xA8', '\x93', ' ', '\xE0', '\xA8', '\x97', ' ', '\xE0', '\xA8', '\x9C', ' ', '\xE0', '\xA8', '\xA0', ' ', '\xE0', '\xA8', '\xB0', ' ', '\xE0', '\xA8', '\xB8', /* ਅ ਏ ਓ ਗ ਜ ਠ ਰ ਸ */
+ '\0',
+ '\xE0', '\xA9', '\xA6', ' ', '\xE0', '\xA9', '\xA7', ' ', '\xE0', '\xA9', '\xA8', ' ', '\xE0', '\xA9', '\xA9', ' ', '\xE0', '\xA9', '\xAD', /* ੦ ੧ ੨ ੩ ੭ */
+ '\0',
'\xD7', '\x91', ' ', '\xD7', '\x93', ' ', '\xD7', '\x94', ' ', '\xD7', '\x97', ' ', '\xD7', '\x9A', ' ', '\xD7', '\x9B', ' ', '\xD7', '\x9D', ' ', '\xD7', '\xA1', /* ב ד ה ח ך כ ם ס */
'\0',
'\xD7', '\x91', ' ', '\xD7', '\x98', ' ', '\xD7', '\x9B', ' ', '\xD7', '\x9D', ' ', '\xD7', '\xA1', ' ', '\xD7', '\xA6', /* ב ט כ ם ס צ */
'\0',
'\xE1', '\xB5', '\x96', ' ', '\xCA', '\xB8', ' ', '\xE1', '\xB5', '\x8D', /* ᵖ ʸ ᵍ */
'\0',
+ '\xE0', '\xB4', '\x92', ' ', '\xE0', '\xB4', '\x9F', ' ', '\xE0', '\xB4', '\xA0', ' ', '\xE0', '\xB4', '\xB1', ' ', '\xE0', '\xB4', '\x9A', ' ', '\xE0', '\xB4', '\xAA', ' ', '\xE0', '\xB4', '\x9A', '\xE0', '\xB5', '\x8D', '\xE0', '\xB4', '\x9A', ' ', '\xE0', '\xB4', '\xAA', '\xE0', '\xB5', '\x8D', '\xE0', '\xB4', '\xAA', /* ഒ ട ഠ റ ച പ ച്ച പ്പ */
+ '\0',
+ '\xE0', '\xB4', '\x9F', ' ', '\xE0', '\xB4', '\xA0', ' ', '\xE0', '\xB4', '\xA7', ' ', '\xE0', '\xB4', '\xB6', ' ', '\xE0', '\xB4', '\x98', ' ', '\xE0', '\xB4', '\x9A', ' ', '\xE0', '\xB4', '\xA5', ' ', '\xE0', '\xB4', '\xB2', /* ട ഠ ധ ശ ഘ ച ഥ ല */
+ '\0',
'\xE1', '\x80', '\x81', ' ', '\xE1', '\x80', '\x82', ' ', '\xE1', '\x80', '\x84', ' ', '\xE1', '\x80', '\x92', ' ', '\xE1', '\x80', '\x9D', ' ', '\xE1', '\x81', '\xA5', ' ', '\xE1', '\x81', '\x8A', ' ', '\xE1', '\x81', '\x8B', /* ခ ဂ င ဒ ဝ ၥ ၊ ။ */
'\0',
'\xE1', '\x80', '\x84', ' ', '\xE1', '\x80', '\x8E', ' ', '\xE1', '\x80', '\x92', ' ', '\xE1', '\x80', '\x95', ' ', '\xE1', '\x80', '\x97', ' ', '\xE1', '\x80', '\x9D', ' ', '\xE1', '\x81', '\x8A', ' ', '\xE1', '\x81', '\x8B', /* င ဎ ဒ ပ ဗ ဝ ၊ ။ */
'\0',
'\xE1', '\x80', '\x89', ' ', '\xE1', '\x80', '\x8A', ' ', '\xE1', '\x80', '\xA5', ' ', '\xE1', '\x80', '\xA9', ' ', '\xE1', '\x80', '\xA8', ' ', '\xE1', '\x81', '\x82', ' ', '\xE1', '\x81', '\x85', ' ', '\xE1', '\x81', '\x89', /* ဉ ည ဥ ဩ ဨ ၂ ၅ ၉ */
'\0',
+ '\xE0', '\xB6', '\x89', ' ', '\xE0', '\xB6', '\x9A', ' ', '\xE0', '\xB6', '\x9D', ' ', '\xE0', '\xB6', '\xB3', ' ', '\xE0', '\xB6', '\xB4', ' ', '\xE0', '\xB6', '\xBA', ' ', '\xE0', '\xB6', '\xBD', ' ', '\xE0', '\xB7', '\x86', /* ඉ ක ඝ ඳ ප ය ල ෆ */
+ '\0',
+ '\xE0', '\xB6', '\x91', ' ', '\xE0', '\xB6', '\x94', ' ', '\xE0', '\xB6', '\x9D', ' ', '\xE0', '\xB6', '\xA2', ' ', '\xE0', '\xB6', '\xA7', ' ', '\xE0', '\xB6', '\xAE', ' ', '\xE0', '\xB6', '\xB0', ' ', '\xE0', '\xB6', '\xBB', /* එ ඔ ඝ ජ ට ථ ධ ර */
+ '\0',
+ '\xE0', '\xB6', '\xAF', ' ', '\xE0', '\xB6', '\xB3', ' ', '\xE0', '\xB6', '\x8B', ' ', '\xE0', '\xB6', '\xBD', ' ', '\xE0', '\xB6', '\xAD', '\xE0', '\xB7', '\x96', ' ', '\xE0', '\xB6', '\xAD', '\xE0', '\xB7', '\x94', ' ', '\xE0', '\xB6', '\xB6', '\xE0', '\xB7', '\x94', ' ', '\xE0', '\xB6', '\xAF', '\xE0', '\xB7', '\x94', /* ද ඳ උ ල තූ තු බු දු */
+ '\0',
+ '\xE0', '\xAE', '\x89', ' ', '\xE0', '\xAE', '\x92', ' ', '\xE0', '\xAE', '\x93', ' ', '\xE0', '\xAE', '\xB1', ' ', '\xE0', '\xAE', '\x88', ' ', '\xE0', '\xAE', '\x95', ' ', '\xE0', '\xAE', '\x99', ' ', '\xE0', '\xAE', '\x9A', /* உ ஒ ஓ ற ஈ க ங ச */
+ '\0',
+ '\xE0', '\xAE', '\x95', ' ', '\xE0', '\xAE', '\x9A', ' ', '\xE0', '\xAE', '\xB2', ' ', '\xE0', '\xAE', '\xB6', ' ', '\xE0', '\xAE', '\x89', ' ', '\xE0', '\xAE', '\x99', ' ', '\xE0', '\xAE', '\x9F', ' ', '\xE0', '\xAE', '\xAA', /* க ச ல ஶ உ ங ட ப */
+ '\0',
'\xE0', '\xB0', '\x87', ' ', '\xE0', '\xB0', '\x8C', ' ', '\xE0', '\xB0', '\x99', ' ', '\xE0', '\xB0', '\x9E', ' ', '\xE0', '\xB0', '\xA3', ' ', '\xE0', '\xB0', '\xB1', ' ', '\xE0', '\xB1', '\xAF', /* ఇ ఌ ఙ ఞ ణ ఱ ౯ */
'\0',
'\xE0', '\xB0', '\x85', ' ', '\xE0', '\xB0', '\x95', ' ', '\xE0', '\xB0', '\x9A', ' ', '\xE0', '\xB0', '\xB0', ' ', '\xE0', '\xB0', '\xBD', ' ', '\xE0', '\xB1', '\xA8', ' ', '\xE0', '\xB1', '\xAC', /* అ క చ ర ఽ ౨ ౬ */
{ AF_BLUE_STRING_ARABIC_BOTTOM, 0 },
{ AF_BLUE_STRING_ARABIC_JOIN, AF_BLUE_PROPERTY_LATIN_NEUTRAL },
{ AF_BLUE_STRING_MAX, 0 },
- { AF_BLUE_STRING_BENGALI_TOP, AF_BLUE_PROPERTY_LATIN_TOP },
- { AF_BLUE_STRING_BENGALI_HEAD, AF_BLUE_PROPERTY_LATIN_TOP },
- { AF_BLUE_STRING_BENGALI_BASE, AF_BLUE_PROPERTY_LATIN_TOP |
- AF_BLUE_PROPERTY_LATIN_NEUTRAL |
- AF_BLUE_PROPERTY_LATIN_X_HEIGHT },
- { AF_BLUE_STRING_BENGALI_BASE, 0 },
- { AF_BLUE_STRING_MAX, 0 },
+ { AF_BLUE_STRING_ARMENIAN_CAPITAL_TOP, AF_BLUE_PROPERTY_LATIN_TOP },
+ { AF_BLUE_STRING_ARMENIAN_CAPITAL_BOTTOM, 0 },
+ { AF_BLUE_STRING_ARMENIAN_SMALL_ASCENDER, AF_BLUE_PROPERTY_LATIN_TOP },
+ { AF_BLUE_STRING_ARMENIAN_SMALL_TOP, AF_BLUE_PROPERTY_LATIN_TOP |
+ AF_BLUE_PROPERTY_LATIN_X_HEIGHT },
+ { AF_BLUE_STRING_ARMENIAN_SMALL_BOTTOM, 0 },
+ { AF_BLUE_STRING_ARMENIAN_SMALL_DESCENDER, 0 },
+ { AF_BLUE_STRING_MAX, 0 },
+ { AF_BLUE_STRING_BENGALI_TOP, AF_BLUE_PROPERTY_LATIN_TOP },
+ { AF_BLUE_STRING_BENGALI_HEAD, AF_BLUE_PROPERTY_LATIN_TOP },
+ { AF_BLUE_STRING_BENGALI_BASE, AF_BLUE_PROPERTY_LATIN_TOP |
+ AF_BLUE_PROPERTY_LATIN_NEUTRAL |
+ AF_BLUE_PROPERTY_LATIN_X_HEIGHT },
+ { AF_BLUE_STRING_BENGALI_BASE, 0 },
+ { AF_BLUE_STRING_MAX, 0 },
+ { AF_BLUE_STRING_CHEROKEE_CAPITAL, AF_BLUE_PROPERTY_LATIN_TOP },
+ { AF_BLUE_STRING_CHEROKEE_CAPITAL, 0 },
+ { AF_BLUE_STRING_CHEROKEE_SMALL_ASCENDER, AF_BLUE_PROPERTY_LATIN_TOP },
+ { AF_BLUE_STRING_CHEROKEE_SMALL, AF_BLUE_PROPERTY_LATIN_TOP |
+ AF_BLUE_PROPERTY_LATIN_X_HEIGHT },
+ { AF_BLUE_STRING_CHEROKEE_SMALL, 0 },
+ { AF_BLUE_STRING_CHEROKEE_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_STRING_DEVANAGARI_BASE, 0 },
{ AF_BLUE_STRING_DEVANAGARI_BOTTOM, 0 },
{ AF_BLUE_STRING_MAX, 0 },
+ { AF_BLUE_STRING_ETHIOPIC_TOP, AF_BLUE_PROPERTY_LATIN_TOP },
+ { AF_BLUE_STRING_ETHIOPIC_BOTTOM, 0 },
+ { AF_BLUE_STRING_MAX, 0 },
+ { AF_BLUE_STRING_GEORGIAN_MKHEDRULI_TOP, AF_BLUE_PROPERTY_LATIN_TOP |
+ AF_BLUE_PROPERTY_LATIN_X_HEIGHT },
+ { AF_BLUE_STRING_GEORGIAN_MKHEDRULI_BOTTOM, 0 },
+ { AF_BLUE_STRING_GEORGIAN_MKHEDRULI_ASCENDER, AF_BLUE_PROPERTY_LATIN_TOP },
+ { AF_BLUE_STRING_GEORGIAN_MKHEDRULI_DESCENDER, 0 },
+ { AF_BLUE_STRING_MAX, 0 },
+ { AF_BLUE_STRING_GEORGIAN_ASOMTAVRULI_TOP, AF_BLUE_PROPERTY_LATIN_TOP },
+ { AF_BLUE_STRING_GEORGIAN_ASOMTAVRULI_BOTTOM, 0 },
+ { AF_BLUE_STRING_GEORGIAN_NUSKHURI_TOP, AF_BLUE_PROPERTY_LATIN_TOP |
+ AF_BLUE_PROPERTY_LATIN_X_HEIGHT },
+ { AF_BLUE_STRING_GEORGIAN_NUSKHURI_BOTTOM, 0 },
+ { AF_BLUE_STRING_GEORGIAN_NUSKHURI_ASCENDER, AF_BLUE_PROPERTY_LATIN_TOP },
+ { AF_BLUE_STRING_GEORGIAN_NUSKHURI_DESCENDER, 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 },
{ AF_BLUE_STRING_GREEK_SMALL, 0 },
{ AF_BLUE_STRING_GREEK_SMALL_DESCENDER, 0 },
{ AF_BLUE_STRING_MAX, 0 },
+ { AF_BLUE_STRING_GUJARATI_TOP, AF_BLUE_PROPERTY_LATIN_TOP |
+ AF_BLUE_PROPERTY_LATIN_X_HEIGHT },
+ { AF_BLUE_STRING_GUJARATI_BOTTOM, 0 },
+ { AF_BLUE_STRING_GUJARATI_ASCENDER, AF_BLUE_PROPERTY_LATIN_TOP },
+ { AF_BLUE_STRING_GUJARATI_DESCENDER, 0 },
+ { AF_BLUE_STRING_GUJARATI_DIGIT_TOP, AF_BLUE_PROPERTY_LATIN_TOP },
+ { AF_BLUE_STRING_MAX, 0 },
+ { AF_BLUE_STRING_GURMUKHI_TOP, AF_BLUE_PROPERTY_LATIN_TOP },
+ { AF_BLUE_STRING_GURMUKHI_HEAD, AF_BLUE_PROPERTY_LATIN_TOP },
+ { AF_BLUE_STRING_GURMUKHI_BASE, AF_BLUE_PROPERTY_LATIN_TOP |
+ AF_BLUE_PROPERTY_LATIN_NEUTRAL |
+ AF_BLUE_PROPERTY_LATIN_X_HEIGHT },
+ { AF_BLUE_STRING_GURMUKHI_BOTTOM, 0 },
+ { AF_BLUE_STRING_GURMUKHI_DIGIT_TOP, AF_BLUE_PROPERTY_LATIN_TOP },
+ { 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_PROPERTY_LATIN_X_HEIGHT },
{ AF_BLUE_STRING_KHMER_SYMBOLS_WANING_BOTTOM, 0 },
{ AF_BLUE_STRING_MAX, 0 },
- { AF_BLUE_STRING_LAO_TOP, AF_BLUE_PROPERTY_LATIN_TOP |
- AF_BLUE_PROPERTY_LATIN_X_HEIGHT },
- { AF_BLUE_STRING_LAO_BOTTOM, 0 },
- { AF_BLUE_STRING_LAO_ASCENDER, AF_BLUE_PROPERTY_LATIN_TOP },
- { AF_BLUE_STRING_LAO_LARGE_ASCENDER, AF_BLUE_PROPERTY_LATIN_TOP },
- { AF_BLUE_STRING_LAO_DESCENDER, 0 },
- { AF_BLUE_STRING_MAX, 0 },
+ { AF_BLUE_STRING_LAO_TOP, AF_BLUE_PROPERTY_LATIN_TOP |
+ AF_BLUE_PROPERTY_LATIN_X_HEIGHT },
+ { AF_BLUE_STRING_LAO_BOTTOM, 0 },
+ { AF_BLUE_STRING_LAO_ASCENDER, AF_BLUE_PROPERTY_LATIN_TOP },
+ { AF_BLUE_STRING_LAO_LARGE_ASCENDER, AF_BLUE_PROPERTY_LATIN_TOP },
+ { AF_BLUE_STRING_LAO_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_SUPS_SMALL, 0 },
{ AF_BLUE_STRING_LATIN_SUPS_SMALL_DESCENDER, 0 },
{ AF_BLUE_STRING_MAX, 0 },
+ { AF_BLUE_STRING_MALAYALAM_TOP, AF_BLUE_PROPERTY_LATIN_TOP },
+ { AF_BLUE_STRING_MALAYALAM_BOTTOM, 0 },
+ { AF_BLUE_STRING_MAX, 0 },
{ AF_BLUE_STRING_MYANMAR_TOP, AF_BLUE_PROPERTY_LATIN_TOP |
AF_BLUE_PROPERTY_LATIN_X_HEIGHT },
{ AF_BLUE_STRING_MYANMAR_BOTTOM, 0 },
{ AF_BLUE_STRING_MYANMAR_ASCENDER, AF_BLUE_PROPERTY_LATIN_TOP },
{ AF_BLUE_STRING_MYANMAR_DESCENDER, 0 },
{ AF_BLUE_STRING_MAX, 0 },
+ { AF_BLUE_STRING_MAX, 0 },
+ { AF_BLUE_STRING_SINHALA_TOP, AF_BLUE_PROPERTY_LATIN_TOP },
+ { AF_BLUE_STRING_SINHALA_BOTTOM, 0 },
+ { AF_BLUE_STRING_SINHALA_DESCENDER, 0 },
+ { AF_BLUE_STRING_MAX, 0 },
+ { AF_BLUE_STRING_TAMIL_TOP, AF_BLUE_PROPERTY_LATIN_TOP },
+ { AF_BLUE_STRING_TAMIL_BOTTOM, 0 },
+ { AF_BLUE_STRING_MAX, 0 },
{ AF_BLUE_STRING_TELUGU_TOP, AF_BLUE_PROPERTY_LATIN_TOP },
{ AF_BLUE_STRING_TELUGU_BOTTOM, 0 },
{ AF_BLUE_STRING_MAX, 0 },
// values; this essentially means that the maximum values can easily be too
// large. Given that the purpose of those values is to create local
// fixed-size arrays at compile time for further processing of the blue zone
-// data, this isn't a problem. Note the the final zero byte of a string is
-// not counted. Note also that the count holds the number of UTF-8 encoded
+// data, this isn't a problem. Note the final zero byte of a string is not
+// counted. Note also that the count holds the number of UTF-8 encoded
// characters, not bytes.
AF_BLUE_STRING_ARABIC_JOIN
"ـ"
+ AF_BLUE_STRING_ARMENIAN_CAPITAL_TOP
+ "Ա Մ Ւ Փ Բ Գ Դ Օ"
+ AF_BLUE_STRING_ARMENIAN_CAPITAL_BOTTOM
+ "Ւ Ո Փ Ճ Շ Ս Տ Օ"
+ AF_BLUE_STRING_ARMENIAN_SMALL_ASCENDER
+ "ե է ի մ վ փ ֆ փ"
+ AF_BLUE_STRING_ARMENIAN_SMALL_TOP
+ "ա յ ւ ս գ ջ ր օ"
+ AF_BLUE_STRING_ARMENIAN_SMALL_BOTTOM
+ "հ ո ճ ա ե ծ ս օ"
+ AF_BLUE_STRING_ARMENIAN_SMALL_DESCENDER
+ "բ ը ի լ ղ պ փ ց"
+
AF_BLUE_STRING_BENGALI_BASE
"অ ড ত ন ব ভ ল ক"
AF_BLUE_STRING_BENGALI_TOP
AF_BLUE_STRING_BENGALI_HEAD
"ও এ ড ত ন ব ল ক"
+ AF_BLUE_STRING_CHEROKEE_CAPITAL
+ "Ꮖ Ꮋ Ꭼ Ꮓ Ꭴ Ꮳ Ꭶ Ꮥ"
+ AF_BLUE_STRING_CHEROKEE_SMALL_ASCENDER
+ "ꮒ ꮤ ꮶ ꭴ ꭾ ꮗ ꮝ ꮿ"
+ AF_BLUE_STRING_CHEROKEE_SMALL
+ "ꮖ ꭼ ꮓ ꮠ ꮳ ꭶ ꮥ ꮻ"
+ AF_BLUE_STRING_CHEROKEE_SMALL_DESCENDER
+ "ᏸ ꮐ ꭹ ꭻ"
+
AF_BLUE_STRING_CYRILLIC_CAPITAL_TOP
"Б В Е П З О С Э"
AF_BLUE_STRING_CYRILLIC_CAPITAL_BOTTOM
AF_BLUE_STRING_DEVANAGARI_BOTTOM
"ु ृ"
+ AF_BLUE_STRING_ETHIOPIC_TOP
+ "ሀ ሃ ዘ ፐ ማ በ ዋ ዐ"
+ AF_BLUE_STRING_ETHIOPIC_BOTTOM
+ "ለ ሐ በ ዘ ሀ ሪ ዐ ጨ"
+
+ AF_BLUE_STRING_GEORGIAN_MKHEDRULI_TOP
+ "გ დ ე ვ თ ი ო ღ"
+ AF_BLUE_STRING_GEORGIAN_MKHEDRULI_BOTTOM
+ "ა ზ მ ს შ ძ ხ პ"
+ AF_BLUE_STRING_GEORGIAN_MKHEDRULI_ASCENDER
+ "ს ხ ქ ზ მ შ ჩ წ"
+ AF_BLUE_STRING_GEORGIAN_MKHEDRULI_DESCENDER
+ "ე ვ ჟ ტ უ ფ ქ ყ"
+
+ AF_BLUE_STRING_GEORGIAN_ASOMTAVRULI_TOP
+ "Ⴑ Ⴇ Ⴙ Ⴜ Ⴄ Ⴅ Ⴓ Ⴚ"
+ AF_BLUE_STRING_GEORGIAN_ASOMTAVRULI_BOTTOM
+ "Ⴄ Ⴅ Ⴇ Ⴈ Ⴆ Ⴑ Ⴊ Ⴋ"
+
+ AF_BLUE_STRING_GEORGIAN_NUSKHURI_TOP
+ "ⴁ ⴗ ⴂ ⴄ ⴅ ⴇ ⴔ ⴖ"
+ AF_BLUE_STRING_GEORGIAN_NUSKHURI_BOTTOM
+ "ⴈ ⴌ ⴖ ⴎ ⴃ ⴆ ⴋ ⴢ"
+ AF_BLUE_STRING_GEORGIAN_NUSKHURI_ASCENDER
+ "ⴐ ⴑ ⴓ ⴕ ⴙ ⴛ ⴡ ⴣ"
+ AF_BLUE_STRING_GEORGIAN_NUSKHURI_DESCENDER
+ "ⴄ ⴅ ⴔ ⴕ ⴁ ⴂ ⴘ ⴝ"
+
AF_BLUE_STRING_GREEK_CAPITAL_TOP
"Γ Β Ε Ζ Θ Ο Ω"
AF_BLUE_STRING_GREEK_CAPITAL_BOTTOM
AF_BLUE_STRING_GREEK_SMALL_DESCENDER
"β γ η μ ρ φ χ ψ"
+ AF_BLUE_STRING_GUJARATI_TOP
+ "ત ન ઋ ઌ છ ટ ર ૦"
+ AF_BLUE_STRING_GUJARATI_BOTTOM
+ "ખ ગ ઘ ઞ ઇ ઈ ઠ જ"
+ AF_BLUE_STRING_GUJARATI_ASCENDER
+ "ઈ ઊ િ ી લી શ્ચિ જિ સી"
+ AF_BLUE_STRING_GUJARATI_DESCENDER
+ "ુ ૃ ૄ ખુ છૃ છૄ"
+ AF_BLUE_STRING_GUJARATI_DIGIT_TOP
+ "૦ ૧ ૨ ૩ ૭"
+
+ AF_BLUE_STRING_GURMUKHI_BASE
+ "ਕ ਗ ਙ ਚ ਜ ਤ ਧ ਸ"
+ AF_BLUE_STRING_GURMUKHI_HEAD
+ "ਕ ਗ ਙ ਚ ਜ ਤ ਧ ਸ"
+ AF_BLUE_STRING_GURMUKHI_TOP
+ "ਇ ਈ ਉ ਏ ਓ ੳ ਿ ੀ"
+ AF_BLUE_STRING_GURMUKHI_BOTTOM
+ "ਅ ਏ ਓ ਗ ਜ ਠ ਰ ਸ"
+ AF_BLUE_STRING_GURMUKHI_DIGIT_TOP
+ "੦ ੧ ੨ ੩ ੭"
+
AF_BLUE_STRING_HEBREW_TOP
"ב ד ה ח ך כ ם ס"
AF_BLUE_STRING_HEBREW_BOTTOM
AF_BLUE_STRING_LATIN_SUPS_SMALL_DESCENDER
"ᵖ ʸ ᵍ"
+ AF_BLUE_STRING_MALAYALAM_TOP
+ "ഒ ട ഠ റ ച പ ച്ച പ്പ"
+ AF_BLUE_STRING_MALAYALAM_BOTTOM
+ "ട ഠ ധ ശ ഘ ച ഥ ല"
+
AF_BLUE_STRING_MYANMAR_TOP
"ခ ဂ င ဒ ဝ ၥ ၊ ။"
AF_BLUE_STRING_MYANMAR_BOTTOM
AF_BLUE_STRING_MYANMAR_DESCENDER
"ဉ ည ဥ ဩ ဨ ၂ ၅ ၉"
+ AF_BLUE_STRING_SINHALA_TOP
+ "ඉ ක ඝ ඳ ප ය ල ෆ"
+ AF_BLUE_STRING_SINHALA_BOTTOM
+ "එ ඔ ඝ ජ ට ථ ධ ර"
+ AF_BLUE_STRING_SINHALA_DESCENDER
+ "ද ඳ උ ල තූ තු බු දු"
+
+ AF_BLUE_STRING_TAMIL_TOP
+ "உ ஒ ஓ ற ஈ க ங ச"
+ AF_BLUE_STRING_TAMIL_BOTTOM
+ "க ச ல ஶ உ ங ட ப"
+
AF_BLUE_STRING_TELUGU_TOP
"ఇ ఌ ఙ ఞ ణ ఱ ౯"
AF_BLUE_STRING_TELUGU_BOTTOM
{ AF_BLUE_STRING_ARABIC_JOIN, AF_BLUE_PROPERTY_LATIN_NEUTRAL }
{ AF_BLUE_STRING_MAX, 0 }
+ AF_BLUE_STRINGSET_ARMN
+ { AF_BLUE_STRING_ARMENIAN_CAPITAL_TOP, AF_BLUE_PROPERTY_LATIN_TOP }
+ { AF_BLUE_STRING_ARMENIAN_CAPITAL_BOTTOM, 0 }
+ { AF_BLUE_STRING_ARMENIAN_SMALL_ASCENDER, AF_BLUE_PROPERTY_LATIN_TOP }
+ { AF_BLUE_STRING_ARMENIAN_SMALL_TOP, AF_BLUE_PROPERTY_LATIN_TOP |
+ AF_BLUE_PROPERTY_LATIN_X_HEIGHT }
+ { AF_BLUE_STRING_ARMENIAN_SMALL_BOTTOM, 0 }
+ { AF_BLUE_STRING_ARMENIAN_SMALL_DESCENDER, 0 }
+ { AF_BLUE_STRING_MAX, 0 }
+
AF_BLUE_STRINGSET_BENG
- { AF_BLUE_STRING_BENGALI_TOP, AF_BLUE_PROPERTY_LATIN_TOP }
- { AF_BLUE_STRING_BENGALI_HEAD, AF_BLUE_PROPERTY_LATIN_TOP }
- { AF_BLUE_STRING_BENGALI_BASE, AF_BLUE_PROPERTY_LATIN_TOP |
- AF_BLUE_PROPERTY_LATIN_NEUTRAL |
- AF_BLUE_PROPERTY_LATIN_X_HEIGHT }
- { AF_BLUE_STRING_BENGALI_BASE, 0 }
- { AF_BLUE_STRING_MAX, 0 }
+ { AF_BLUE_STRING_BENGALI_TOP, AF_BLUE_PROPERTY_LATIN_TOP }
+ { AF_BLUE_STRING_BENGALI_HEAD, AF_BLUE_PROPERTY_LATIN_TOP }
+ { AF_BLUE_STRING_BENGALI_BASE, AF_BLUE_PROPERTY_LATIN_TOP |
+ AF_BLUE_PROPERTY_LATIN_NEUTRAL |
+ AF_BLUE_PROPERTY_LATIN_X_HEIGHT }
+ { AF_BLUE_STRING_BENGALI_BASE, 0 }
+ { AF_BLUE_STRING_MAX, 0 }
+
+ AF_BLUE_STRINGSET_CHER
+ { AF_BLUE_STRING_CHEROKEE_CAPITAL, AF_BLUE_PROPERTY_LATIN_TOP }
+ { AF_BLUE_STRING_CHEROKEE_CAPITAL, 0 }
+ { AF_BLUE_STRING_CHEROKEE_SMALL_ASCENDER, AF_BLUE_PROPERTY_LATIN_TOP }
+ { AF_BLUE_STRING_CHEROKEE_SMALL, AF_BLUE_PROPERTY_LATIN_TOP |
+ AF_BLUE_PROPERTY_LATIN_X_HEIGHT }
+ { AF_BLUE_STRING_CHEROKEE_SMALL, 0 }
+ { AF_BLUE_STRING_CHEROKEE_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_DEVANAGARI_BOTTOM, 0 }
{ AF_BLUE_STRING_MAX, 0 }
+ AF_BLUE_STRINGSET_ETHI
+ { AF_BLUE_STRING_ETHIOPIC_TOP, AF_BLUE_PROPERTY_LATIN_TOP }
+ { AF_BLUE_STRING_ETHIOPIC_BOTTOM, 0 }
+ { AF_BLUE_STRING_MAX, 0 }
+
+ // blue zones for Mtavruli are missing (not yet defined in Unicode)
+ AF_BLUE_STRINGSET_GEOR
+ { AF_BLUE_STRING_GEORGIAN_MKHEDRULI_TOP, AF_BLUE_PROPERTY_LATIN_TOP |
+ AF_BLUE_PROPERTY_LATIN_X_HEIGHT }
+ { AF_BLUE_STRING_GEORGIAN_MKHEDRULI_BOTTOM, 0 }
+ { AF_BLUE_STRING_GEORGIAN_MKHEDRULI_ASCENDER, AF_BLUE_PROPERTY_LATIN_TOP }
+ { AF_BLUE_STRING_GEORGIAN_MKHEDRULI_DESCENDER, 0 }
+ { AF_BLUE_STRING_MAX, 0 }
+
+ AF_BLUE_STRINGSET_GEOK
+ { AF_BLUE_STRING_GEORGIAN_ASOMTAVRULI_TOP, AF_BLUE_PROPERTY_LATIN_TOP }
+ { AF_BLUE_STRING_GEORGIAN_ASOMTAVRULI_BOTTOM, 0 }
+ { AF_BLUE_STRING_GEORGIAN_NUSKHURI_TOP, AF_BLUE_PROPERTY_LATIN_TOP |
+ AF_BLUE_PROPERTY_LATIN_X_HEIGHT }
+ { AF_BLUE_STRING_GEORGIAN_NUSKHURI_BOTTOM, 0 }
+ { AF_BLUE_STRING_GEORGIAN_NUSKHURI_ASCENDER, AF_BLUE_PROPERTY_LATIN_TOP }
+ { AF_BLUE_STRING_GEORGIAN_NUSKHURI_DESCENDER, 0 }
+ { AF_BLUE_STRING_MAX, 0 }
+
AF_BLUE_STRINGSET_GREK
{ AF_BLUE_STRING_GREEK_CAPITAL_TOP, AF_BLUE_PROPERTY_LATIN_TOP }
{ AF_BLUE_STRING_GREEK_CAPITAL_BOTTOM, 0 }
{ AF_BLUE_STRING_GREEK_SMALL_DESCENDER, 0 }
{ AF_BLUE_STRING_MAX, 0 }
+ AF_BLUE_STRINGSET_GUJR
+ { AF_BLUE_STRING_GUJARATI_TOP, AF_BLUE_PROPERTY_LATIN_TOP |
+ AF_BLUE_PROPERTY_LATIN_X_HEIGHT }
+ { AF_BLUE_STRING_GUJARATI_BOTTOM, 0 }
+ { AF_BLUE_STRING_GUJARATI_ASCENDER, AF_BLUE_PROPERTY_LATIN_TOP }
+ { AF_BLUE_STRING_GUJARATI_DESCENDER, 0 }
+ { AF_BLUE_STRING_GUJARATI_DIGIT_TOP, AF_BLUE_PROPERTY_LATIN_TOP }
+ { AF_BLUE_STRING_MAX, 0 }
+
+ AF_BLUE_STRINGSET_GURU
+ { AF_BLUE_STRING_GURMUKHI_TOP, AF_BLUE_PROPERTY_LATIN_TOP }
+ { AF_BLUE_STRING_GURMUKHI_HEAD, AF_BLUE_PROPERTY_LATIN_TOP }
+ { AF_BLUE_STRING_GURMUKHI_BASE, AF_BLUE_PROPERTY_LATIN_TOP |
+ AF_BLUE_PROPERTY_LATIN_NEUTRAL |
+ AF_BLUE_PROPERTY_LATIN_X_HEIGHT }
+ { AF_BLUE_STRING_GURMUKHI_BOTTOM, 0 }
+ { AF_BLUE_STRING_GURMUKHI_DIGIT_TOP, AF_BLUE_PROPERTY_LATIN_TOP }
+ { AF_BLUE_STRING_MAX, 0 }
+
AF_BLUE_STRINGSET_HEBR
{ AF_BLUE_STRING_HEBREW_TOP, AF_BLUE_PROPERTY_LATIN_TOP |
AF_BLUE_PROPERTY_LATIN_LONG }
{ AF_BLUE_STRING_MAX, 0 }
AF_BLUE_STRINGSET_LAO
- { AF_BLUE_STRING_LAO_TOP, AF_BLUE_PROPERTY_LATIN_TOP |
- AF_BLUE_PROPERTY_LATIN_X_HEIGHT }
- { AF_BLUE_STRING_LAO_BOTTOM, 0 }
- { AF_BLUE_STRING_LAO_ASCENDER, AF_BLUE_PROPERTY_LATIN_TOP }
- { AF_BLUE_STRING_LAO_LARGE_ASCENDER, AF_BLUE_PROPERTY_LATIN_TOP }
- { AF_BLUE_STRING_LAO_DESCENDER, 0 }
- { AF_BLUE_STRING_MAX, 0 }
+ { AF_BLUE_STRING_LAO_TOP, AF_BLUE_PROPERTY_LATIN_TOP |
+ AF_BLUE_PROPERTY_LATIN_X_HEIGHT }
+ { AF_BLUE_STRING_LAO_BOTTOM, 0 }
+ { AF_BLUE_STRING_LAO_ASCENDER, AF_BLUE_PROPERTY_LATIN_TOP }
+ { AF_BLUE_STRING_LAO_LARGE_ASCENDER, AF_BLUE_PROPERTY_LATIN_TOP }
+ { AF_BLUE_STRING_LAO_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_SUPS_SMALL_DESCENDER, 0 }
{ AF_BLUE_STRING_MAX, 0 }
+ AF_BLUE_STRINGSET_MLYM
+ { AF_BLUE_STRING_MALAYALAM_TOP, AF_BLUE_PROPERTY_LATIN_TOP }
+ { AF_BLUE_STRING_MALAYALAM_BOTTOM, 0 }
+ { AF_BLUE_STRING_MAX, 0 }
+
AF_BLUE_STRINGSET_MYMR
{ AF_BLUE_STRING_MYANMAR_TOP, AF_BLUE_PROPERTY_LATIN_TOP |
AF_BLUE_PROPERTY_LATIN_X_HEIGHT }
{ AF_BLUE_STRING_MYANMAR_DESCENDER, 0 }
{ AF_BLUE_STRING_MAX, 0 }
+ AF_BLUE_STRINGSET_NONE
+ { AF_BLUE_STRING_MAX, 0 }
+
+ AF_BLUE_STRINGSET_SINH
+ { AF_BLUE_STRING_SINHALA_TOP, AF_BLUE_PROPERTY_LATIN_TOP }
+ { AF_BLUE_STRING_SINHALA_BOTTOM, 0 }
+ { AF_BLUE_STRING_SINHALA_DESCENDER, 0 }
+ { AF_BLUE_STRING_MAX, 0 }
+
+ AF_BLUE_STRINGSET_TAML
+ { AF_BLUE_STRING_TAMIL_TOP, AF_BLUE_PROPERTY_LATIN_TOP }
+ { AF_BLUE_STRING_TAMIL_BOTTOM, 0 }
+ { AF_BLUE_STRING_MAX, 0 }
+
AF_BLUE_STRINGSET_TELU
{ AF_BLUE_STRING_TELUGU_TOP, AF_BLUE_PROPERTY_LATIN_TOP }
{ AF_BLUE_STRING_TELUGU_BOTTOM, 0 }
AF_BLUE_STRING_ARABIC_TOP = 0,
AF_BLUE_STRING_ARABIC_BOTTOM = 18,
AF_BLUE_STRING_ARABIC_JOIN = 33,
- AF_BLUE_STRING_BENGALI_BASE = 36,
- AF_BLUE_STRING_BENGALI_TOP = 68,
- AF_BLUE_STRING_BENGALI_HEAD = 96,
- AF_BLUE_STRING_CYRILLIC_CAPITAL_TOP = 128,
- AF_BLUE_STRING_CYRILLIC_CAPITAL_BOTTOM = 152,
- AF_BLUE_STRING_CYRILLIC_SMALL = 176,
- AF_BLUE_STRING_CYRILLIC_SMALL_DESCENDER = 200,
- AF_BLUE_STRING_DEVANAGARI_BASE = 209,
- AF_BLUE_STRING_DEVANAGARI_TOP = 241,
- AF_BLUE_STRING_DEVANAGARI_HEAD = 273,
- AF_BLUE_STRING_DEVANAGARI_BOTTOM = 305,
- AF_BLUE_STRING_GREEK_CAPITAL_TOP = 313,
- AF_BLUE_STRING_GREEK_CAPITAL_BOTTOM = 334,
- AF_BLUE_STRING_GREEK_SMALL_BETA_TOP = 352,
- AF_BLUE_STRING_GREEK_SMALL = 370,
- AF_BLUE_STRING_GREEK_SMALL_DESCENDER = 394,
- AF_BLUE_STRING_HEBREW_TOP = 418,
- AF_BLUE_STRING_HEBREW_BOTTOM = 442,
- AF_BLUE_STRING_HEBREW_DESCENDER = 460,
- AF_BLUE_STRING_KANNADA_TOP = 475,
- AF_BLUE_STRING_KANNADA_BOTTOM = 519,
- AF_BLUE_STRING_KHMER_TOP = 551,
- AF_BLUE_STRING_KHMER_SUBSCRIPT_TOP = 575,
- AF_BLUE_STRING_KHMER_BOTTOM = 615,
- AF_BLUE_STRING_KHMER_DESCENDER = 647,
- AF_BLUE_STRING_KHMER_LARGE_DESCENDER = 681,
- AF_BLUE_STRING_KHMER_SYMBOLS_WAXING_TOP = 768,
- AF_BLUE_STRING_KHMER_SYMBOLS_WANING_BOTTOM = 776,
- AF_BLUE_STRING_LAO_TOP = 784,
- AF_BLUE_STRING_LAO_BOTTOM = 816,
- AF_BLUE_STRING_LAO_ASCENDER = 848,
- AF_BLUE_STRING_LAO_LARGE_ASCENDER = 864,
- AF_BLUE_STRING_LAO_DESCENDER = 876,
- AF_BLUE_STRING_LATIN_CAPITAL_TOP = 900,
- AF_BLUE_STRING_LATIN_CAPITAL_BOTTOM = 916,
- AF_BLUE_STRING_LATIN_SMALL_F_TOP = 932,
- AF_BLUE_STRING_LATIN_SMALL = 946,
- AF_BLUE_STRING_LATIN_SMALL_DESCENDER = 960,
- AF_BLUE_STRING_LATIN_SUBS_CAPITAL_TOP = 970,
- AF_BLUE_STRING_LATIN_SUBS_CAPITAL_BOTTOM = 990,
- AF_BLUE_STRING_LATIN_SUBS_SMALL_F_TOP = 1010,
- AF_BLUE_STRING_LATIN_SUBS_SMALL = 1030,
- AF_BLUE_STRING_LATIN_SUBS_SMALL_DESCENDER = 1066,
- AF_BLUE_STRING_LATIN_SUPS_CAPITAL_TOP = 1086,
- AF_BLUE_STRING_LATIN_SUPS_CAPITAL_BOTTOM = 1117,
- AF_BLUE_STRING_LATIN_SUPS_SMALL_F_TOP = 1146,
- AF_BLUE_STRING_LATIN_SUPS_SMALL = 1172,
- AF_BLUE_STRING_LATIN_SUPS_SMALL_DESCENDER = 1197,
- AF_BLUE_STRING_MYANMAR_TOP = 1208,
- AF_BLUE_STRING_MYANMAR_BOTTOM = 1240,
- AF_BLUE_STRING_MYANMAR_ASCENDER = 1272,
- AF_BLUE_STRING_MYANMAR_DESCENDER = 1300,
- AF_BLUE_STRING_TELUGU_TOP = 1332,
- AF_BLUE_STRING_TELUGU_BOTTOM = 1360,
- AF_BLUE_STRING_THAI_TOP = 1388,
- AF_BLUE_STRING_THAI_BOTTOM = 1412,
- AF_BLUE_STRING_THAI_ASCENDER = 1440,
- AF_BLUE_STRING_THAI_LARGE_ASCENDER = 1452,
- AF_BLUE_STRING_THAI_DESCENDER = 1464,
- AF_BLUE_STRING_THAI_LARGE_DESCENDER = 1480,
- AF_BLUE_STRING_THAI_DIGIT_TOP = 1488,
- af_blue_1_1 = 1499,
+ AF_BLUE_STRING_ARMENIAN_CAPITAL_TOP = 36,
+ AF_BLUE_STRING_ARMENIAN_CAPITAL_BOTTOM = 60,
+ AF_BLUE_STRING_ARMENIAN_SMALL_ASCENDER = 84,
+ AF_BLUE_STRING_ARMENIAN_SMALL_TOP = 108,
+ AF_BLUE_STRING_ARMENIAN_SMALL_BOTTOM = 132,
+ AF_BLUE_STRING_ARMENIAN_SMALL_DESCENDER = 156,
+ AF_BLUE_STRING_BENGALI_BASE = 180,
+ AF_BLUE_STRING_BENGALI_TOP = 212,
+ AF_BLUE_STRING_BENGALI_HEAD = 240,
+ AF_BLUE_STRING_CHEROKEE_CAPITAL = 272,
+ AF_BLUE_STRING_CHEROKEE_SMALL_ASCENDER = 304,
+ AF_BLUE_STRING_CHEROKEE_SMALL = 336,
+ AF_BLUE_STRING_CHEROKEE_SMALL_DESCENDER = 368,
+ AF_BLUE_STRING_CYRILLIC_CAPITAL_TOP = 384,
+ AF_BLUE_STRING_CYRILLIC_CAPITAL_BOTTOM = 408,
+ AF_BLUE_STRING_CYRILLIC_SMALL = 432,
+ AF_BLUE_STRING_CYRILLIC_SMALL_DESCENDER = 456,
+ AF_BLUE_STRING_DEVANAGARI_BASE = 465,
+ AF_BLUE_STRING_DEVANAGARI_TOP = 497,
+ AF_BLUE_STRING_DEVANAGARI_HEAD = 529,
+ AF_BLUE_STRING_DEVANAGARI_BOTTOM = 561,
+ AF_BLUE_STRING_ETHIOPIC_TOP = 569,
+ AF_BLUE_STRING_ETHIOPIC_BOTTOM = 601,
+ AF_BLUE_STRING_GEORGIAN_MKHEDRULI_TOP = 633,
+ AF_BLUE_STRING_GEORGIAN_MKHEDRULI_BOTTOM = 665,
+ AF_BLUE_STRING_GEORGIAN_MKHEDRULI_ASCENDER = 697,
+ AF_BLUE_STRING_GEORGIAN_MKHEDRULI_DESCENDER = 729,
+ AF_BLUE_STRING_GEORGIAN_ASOMTAVRULI_TOP = 761,
+ AF_BLUE_STRING_GEORGIAN_ASOMTAVRULI_BOTTOM = 793,
+ AF_BLUE_STRING_GEORGIAN_NUSKHURI_TOP = 825,
+ AF_BLUE_STRING_GEORGIAN_NUSKHURI_BOTTOM = 857,
+ AF_BLUE_STRING_GEORGIAN_NUSKHURI_ASCENDER = 889,
+ AF_BLUE_STRING_GEORGIAN_NUSKHURI_DESCENDER = 921,
+ AF_BLUE_STRING_GREEK_CAPITAL_TOP = 953,
+ AF_BLUE_STRING_GREEK_CAPITAL_BOTTOM = 974,
+ AF_BLUE_STRING_GREEK_SMALL_BETA_TOP = 992,
+ AF_BLUE_STRING_GREEK_SMALL = 1010,
+ AF_BLUE_STRING_GREEK_SMALL_DESCENDER = 1034,
+ AF_BLUE_STRING_GUJARATI_TOP = 1058,
+ AF_BLUE_STRING_GUJARATI_BOTTOM = 1090,
+ AF_BLUE_STRING_GUJARATI_ASCENDER = 1122,
+ AF_BLUE_STRING_GUJARATI_DESCENDER = 1172,
+ AF_BLUE_STRING_GUJARATI_DIGIT_TOP = 1205,
+ AF_BLUE_STRING_GURMUKHI_BASE = 1225,
+ AF_BLUE_STRING_GURMUKHI_HEAD = 1257,
+ AF_BLUE_STRING_GURMUKHI_TOP = 1289,
+ AF_BLUE_STRING_GURMUKHI_BOTTOM = 1321,
+ AF_BLUE_STRING_GURMUKHI_DIGIT_TOP = 1353,
+ AF_BLUE_STRING_HEBREW_TOP = 1373,
+ AF_BLUE_STRING_HEBREW_BOTTOM = 1397,
+ AF_BLUE_STRING_HEBREW_DESCENDER = 1415,
+ AF_BLUE_STRING_KANNADA_TOP = 1430,
+ AF_BLUE_STRING_KANNADA_BOTTOM = 1474,
+ AF_BLUE_STRING_KHMER_TOP = 1506,
+ AF_BLUE_STRING_KHMER_SUBSCRIPT_TOP = 1530,
+ AF_BLUE_STRING_KHMER_BOTTOM = 1570,
+ AF_BLUE_STRING_KHMER_DESCENDER = 1602,
+ AF_BLUE_STRING_KHMER_LARGE_DESCENDER = 1636,
+ AF_BLUE_STRING_KHMER_SYMBOLS_WAXING_TOP = 1723,
+ AF_BLUE_STRING_KHMER_SYMBOLS_WANING_BOTTOM = 1731,
+ AF_BLUE_STRING_LAO_TOP = 1739,
+ AF_BLUE_STRING_LAO_BOTTOM = 1771,
+ AF_BLUE_STRING_LAO_ASCENDER = 1803,
+ AF_BLUE_STRING_LAO_LARGE_ASCENDER = 1819,
+ AF_BLUE_STRING_LAO_DESCENDER = 1831,
+ AF_BLUE_STRING_LATIN_CAPITAL_TOP = 1855,
+ AF_BLUE_STRING_LATIN_CAPITAL_BOTTOM = 1871,
+ AF_BLUE_STRING_LATIN_SMALL_F_TOP = 1887,
+ AF_BLUE_STRING_LATIN_SMALL = 1901,
+ AF_BLUE_STRING_LATIN_SMALL_DESCENDER = 1915,
+ AF_BLUE_STRING_LATIN_SUBS_CAPITAL_TOP = 1925,
+ AF_BLUE_STRING_LATIN_SUBS_CAPITAL_BOTTOM = 1945,
+ AF_BLUE_STRING_LATIN_SUBS_SMALL_F_TOP = 1965,
+ AF_BLUE_STRING_LATIN_SUBS_SMALL = 1985,
+ AF_BLUE_STRING_LATIN_SUBS_SMALL_DESCENDER = 2021,
+ AF_BLUE_STRING_LATIN_SUPS_CAPITAL_TOP = 2041,
+ AF_BLUE_STRING_LATIN_SUPS_CAPITAL_BOTTOM = 2072,
+ AF_BLUE_STRING_LATIN_SUPS_SMALL_F_TOP = 2101,
+ AF_BLUE_STRING_LATIN_SUPS_SMALL = 2127,
+ AF_BLUE_STRING_LATIN_SUPS_SMALL_DESCENDER = 2152,
+ AF_BLUE_STRING_MALAYALAM_TOP = 2163,
+ AF_BLUE_STRING_MALAYALAM_BOTTOM = 2207,
+ AF_BLUE_STRING_MYANMAR_TOP = 2239,
+ AF_BLUE_STRING_MYANMAR_BOTTOM = 2271,
+ AF_BLUE_STRING_MYANMAR_ASCENDER = 2303,
+ AF_BLUE_STRING_MYANMAR_DESCENDER = 2331,
+ AF_BLUE_STRING_SINHALA_TOP = 2363,
+ AF_BLUE_STRING_SINHALA_BOTTOM = 2395,
+ AF_BLUE_STRING_SINHALA_DESCENDER = 2427,
+ AF_BLUE_STRING_TAMIL_TOP = 2471,
+ AF_BLUE_STRING_TAMIL_BOTTOM = 2503,
+ AF_BLUE_STRING_TELUGU_TOP = 2535,
+ AF_BLUE_STRING_TELUGU_BOTTOM = 2563,
+ AF_BLUE_STRING_THAI_TOP = 2591,
+ AF_BLUE_STRING_THAI_BOTTOM = 2615,
+ AF_BLUE_STRING_THAI_ASCENDER = 2643,
+ AF_BLUE_STRING_THAI_LARGE_ASCENDER = 2655,
+ AF_BLUE_STRING_THAI_DESCENDER = 2667,
+ AF_BLUE_STRING_THAI_LARGE_DESCENDER = 2683,
+ AF_BLUE_STRING_THAI_DIGIT_TOP = 2691,
+ af_blue_1_1 = 2702,
#ifdef AF_CONFIG_OPTION_CJK
AF_BLUE_STRING_CJK_TOP = af_blue_1_1 + 1,
AF_BLUE_STRING_CJK_BOTTOM = af_blue_1_1 + 203,
typedef enum AF_Blue_Stringset_
{
AF_BLUE_STRINGSET_ARAB = 0,
- AF_BLUE_STRINGSET_BENG = 4,
- AF_BLUE_STRINGSET_CYRL = 9,
- AF_BLUE_STRINGSET_DEVA = 15,
- AF_BLUE_STRINGSET_GREK = 21,
- AF_BLUE_STRINGSET_HEBR = 28,
- AF_BLUE_STRINGSET_KNDA = 32,
- AF_BLUE_STRINGSET_KHMR = 35,
- AF_BLUE_STRINGSET_KHMS = 41,
- AF_BLUE_STRINGSET_LAO = 44,
- AF_BLUE_STRINGSET_LATN = 50,
- AF_BLUE_STRINGSET_LATB = 57,
- AF_BLUE_STRINGSET_LATP = 64,
- AF_BLUE_STRINGSET_MYMR = 71,
- AF_BLUE_STRINGSET_TELU = 76,
- AF_BLUE_STRINGSET_THAI = 79,
- af_blue_2_1 = 87,
+ AF_BLUE_STRINGSET_ARMN = 4,
+ AF_BLUE_STRINGSET_BENG = 11,
+ AF_BLUE_STRINGSET_CHER = 16,
+ AF_BLUE_STRINGSET_CYRL = 23,
+ AF_BLUE_STRINGSET_DEVA = 29,
+ AF_BLUE_STRINGSET_ETHI = 35,
+ AF_BLUE_STRINGSET_GEOR = 38,
+ AF_BLUE_STRINGSET_GEOK = 43,
+ AF_BLUE_STRINGSET_GREK = 50,
+ AF_BLUE_STRINGSET_GUJR = 57,
+ AF_BLUE_STRINGSET_GURU = 63,
+ AF_BLUE_STRINGSET_HEBR = 69,
+ AF_BLUE_STRINGSET_KNDA = 73,
+ AF_BLUE_STRINGSET_KHMR = 76,
+ AF_BLUE_STRINGSET_KHMS = 82,
+ AF_BLUE_STRINGSET_LAO = 85,
+ AF_BLUE_STRINGSET_LATN = 91,
+ AF_BLUE_STRINGSET_LATB = 98,
+ AF_BLUE_STRINGSET_LATP = 105,
+ AF_BLUE_STRINGSET_MLYM = 112,
+ AF_BLUE_STRINGSET_MYMR = 115,
+ AF_BLUE_STRINGSET_NONE = 120,
+ AF_BLUE_STRINGSET_SINH = 121,
+ AF_BLUE_STRINGSET_TAML = 125,
+ AF_BLUE_STRINGSET_TELU = 128,
+ AF_BLUE_STRINGSET_THAI = 131,
+ af_blue_2_1 = 139,
#ifdef AF_CONFIG_OPTION_CJK
AF_BLUE_STRINGSET_HANI = af_blue_2_1 + 0,
af_blue_2_1_1 = af_blue_2_1 + 2,
if ( seg2 )
{
- seg2->num_linked++;
if ( seg2->link != seg1 )
{
seg1->link = NULL;
if ( seg2->score < dist_threshold || seg1->score < seg2->score * 4 )
seg1->serif = seg2->link;
- else
- seg2->num_linked--;
}
}
}
}
if ( dist < 54 )
- dist += ( 54 - dist ) / 2 ;
+ dist += ( 54 - dist ) / 2;
else if ( dist < 3 * 64 )
{
FT_Pos delta;
AF_DUMP(( "Table of points:\n" ));
if ( hints->num_points )
- AF_DUMP(( " index hedge hseg vedge vseg flags"
+ AF_DUMP(( " index hedge hseg vedge vseg flags "
" xorg yorg xscale yscale xfit yfit" ));
else
AF_DUMP(( " (none)\n" ));
contour++;
}
- AF_DUMP(( " %5d %5s %5s %5s %5s %s "
+ AF_DUMP(( " %5d %5s %5s %5s %5s %s"
" %5d %5d %7.2f %7.2f %7.2f %7.2f\n",
point_idx,
af_print_idx( buf1,
af_print_idx( buf3,
af_get_edge_index( hints, segment_idx_0, 0 ) ),
af_print_idx( buf4, segment_idx_0 ),
- ( point->flags & AF_FLAG_WEAK_INTERPOLATION ) ? "weak"
- : " -- ",
+ ( point->flags & AF_FLAG_NEAR )
+ ? " near "
+ : ( point->flags & AF_FLAG_WEAK_INTERPOLATION )
+ ? " weak "
+ : "strong",
point->fx,
point->fy,
AF_Point point;
AF_Point point_limit = points + hints->num_points;
+ /* 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;
+
/* compute coordinates & Bezier flags, next and prev */
{
FT_Vector* vec = outline->points;
char* tag = outline->tags;
- AF_Point end = points + outline->contours[0];
+ FT_Short endpoint = outline->contours[0];
+ AF_Point end = points + endpoint;
AF_Point prev = end;
FT_Int contour_index = 0;
for ( point = points; point < point_limit; point++, vec++, tag++ )
{
+ FT_Pos out_x, out_y;
+
+
point->in_dir = (FT_Char)AF_DIR_NONE;
point->out_dir = (FT_Char)AF_DIR_NONE;
point->ox = point->x = FT_MulFix( vec->x, x_scale ) + x_delta;
point->oy = point->y = FT_MulFix( vec->y, y_scale ) + y_delta;
+ end->fx = (FT_Short)outline->points[endpoint].x;
+ end->fy = (FT_Short)outline->points[endpoint].y;
+
switch ( FT_CURVE_TAG( *tag ) )
{
case FT_CURVE_TAG_CONIC:
point->flags = AF_FLAG_NONE;
}
+ out_x = point->fx - prev->fx;
+ out_y = point->fy - prev->fy;
+
+ if ( FT_ABS( out_x ) + FT_ABS( out_y ) < near_limit )
+ prev->flags |= AF_FLAG_NEAR;
+
point->prev = prev;
prev->next = point;
prev = point;
{
if ( ++contour_index < outline->n_contours )
{
- end = points + outline->contours[contour_index];
- prev = end;
+ endpoint = outline->contours[contour_index];
+ end = points + endpoint;
+ prev = end;
}
}
}
* 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
+ * other are accumulated. In other words, the auto-hinter either
* 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.
+ * non-near vector, or the sum of small vector lengths exceeds a
+ * threshold, thus `grouping' the small vectors. 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;
+ FT_Int near_limit2 = 2 * near_limit - 1;
AF_Point* contour;
AF_Point* contour_limit = hints->contours + hints->num_contours;
/* now loop over all points of the contour to get */
/* `in' and `out' vector directions */
- curr = first;
+ curr = first;
/*
* We abuse the `u' and `v' fields to store index deltas to the
point = next;
- next = point->next;
+ next = point->next;
out_x += next->fx - point->fx;
out_y += next->fy - point->fy;
/* candidates for weak interpolation have this flag set */
#define AF_FLAG_WEAK_INTERPOLATION ( 1U << 4 )
+ /* the distance to the next point is very small */
+#define AF_FLAG_NEAR ( 1U << 5 )
+
/* edge hint flags */
#define AF_EDGE_NORMAL 0
AF_Segment link; /* (stem) link segment */
AF_Segment serif; /* primary segment for serifs */
- FT_Pos num_linked; /* number of linked segments */
FT_Pos score; /* used during stem matching */
FT_Pos len; /* used during stem matching */
AF_Width blue_edge; /* non-NULL if this is a blue edge */
AF_Edge link; /* link edge */
AF_Edge serif; /* primary edge for serifs */
- FT_Short num_linked; /* number of linked edges */
FT_Int score; /* used during stem matching */
AF_Segment first; /* first segment in edge */
/* do each contour separately */
for ( ; contour < contour_limit; contour++ )
{
- AF_Point point = contour[0];
- AF_Point last = point->prev;
- int on_edge = 0;
- FT_Pos min_pos = 32000; /* minimum segment pos != min_coord */
- FT_Pos max_pos = -32000; /* maximum segment pos != max_coord */
- FT_Pos min_on_pos = 32000;
- FT_Pos max_on_pos = -32000;
- FT_Bool passed;
+ AF_Point point = contour[0];
+ AF_Point last = point->prev;
+ int on_edge = 0;
+
+ /* we call values measured along a segment (point->v) */
+ /* `coordinates', and values orthogonal to it (point->u) */
+ /* `positions' */
+ FT_Pos min_pos = 32000;
+ FT_Pos max_pos = -32000;
+ FT_Pos min_coord = 32000;
+ FT_Pos max_coord = -32000;
+ FT_UShort min_flags = AF_FLAG_NONE;
+ FT_UShort max_flags = AF_FLAG_NONE;
+ FT_Pos min_on_coord = 32000;
+ FT_Pos max_on_coord = -32000;
+
+ FT_Bool passed;
+
+ AF_Segment prev_segment = NULL;
+
+ FT_Pos prev_min_pos = min_pos;
+ FT_Pos prev_max_pos = max_pos;
+ FT_Pos prev_min_coord = min_coord;
+ FT_Pos prev_max_coord = max_coord;
+ FT_UShort prev_min_flags = min_flags;
+ FT_UShort prev_max_flags = max_flags;
+ FT_Pos prev_min_on_coord = min_on_coord;
+ FT_Pos prev_max_on_coord = max_on_coord;
- if ( point == last ) /* skip singletons -- just in case */
- continue;
-
if ( FT_ABS( last->out_dir ) == major_dir &&
FT_ABS( point->out_dir ) == major_dir )
{
if ( on_edge )
{
+ /* get minimum and maximum position */
u = point->u;
if ( u < min_pos )
min_pos = u;
if ( u > max_pos )
max_pos = u;
- /* get minimum and maximum coordinate of on points */
+ /* get minimum and maximum coordinate together with flags */
+ v = point->v;
+ if ( v < min_coord )
+ {
+ min_coord = v;
+ min_flags = point->flags;
+ }
+ if ( v > max_coord )
+ {
+ max_coord = v;
+ max_flags = point->flags;
+ }
+
+ /* get minimum and maximum coordinate of `on' points */
if ( !( point->flags & AF_FLAG_CONTROL ) )
{
v = point->v;
- if ( v < min_on_pos )
- min_on_pos = v;
- if ( v > max_on_pos )
- max_on_pos = v;
+ if ( v < min_on_coord )
+ min_on_coord = v;
+ if ( v > max_on_coord )
+ max_on_coord = v;
}
if ( point->out_dir != segment_dir || point == last )
{
- /* we are just leaving an edge; record a new segment! */
- segment->last = point;
- segment->pos = (FT_Short)( ( min_pos + max_pos ) >> 1 );
-
- /* a segment is round if either its first or last point */
- /* is a control point, and the length of the on points */
- /* inbetween doesn't exceed a heuristic limit */
- if ( ( segment->first->flags | point->flags ) & AF_FLAG_CONTROL &&
- ( max_on_pos - min_on_pos ) < flat_threshold )
- segment->flags |= AF_EDGE_ROUND;
+ /* check whether the new segment's start point is identical to */
+ /* the previous segment's end point; for example, this might */
+ /* happen for spikes */
- /* compute segment size */
- min_pos = max_pos = point->v;
+ if ( !prev_segment || segment->first != prev_segment->last )
+ {
+ /* points are different: we are just leaving an edge, thus */
+ /* record a new segment */
+
+ segment->last = point;
+ segment->pos = (FT_Short)( ( min_pos + max_pos ) >> 1 );
+
+ /* a segment is round if either its first or last point */
+ /* is a control point, and the length of the on points */
+ /* inbetween doesn't exceed a heuristic limit */
+ if ( ( min_flags | max_flags ) & AF_FLAG_CONTROL &&
+ ( max_on_coord - min_on_coord ) < flat_threshold )
+ segment->flags |= AF_EDGE_ROUND;
+
+ segment->min_coord = (FT_Short)min_coord;
+ segment->max_coord = (FT_Short)max_coord;
+ segment->height = segment->max_coord - segment->min_coord;
+
+ prev_segment = segment;
+ prev_min_pos = min_pos;
+ prev_max_pos = max_pos;
+ prev_min_coord = min_coord;
+ prev_max_coord = max_coord;
+ prev_min_flags = min_flags;
+ prev_max_flags = max_flags;
+ prev_min_on_coord = min_on_coord;
+ prev_max_on_coord = max_on_coord;
+ }
+ else
+ {
+ /* points are the same: we don't create a new segment but */
+ /* merge the current segment with the previous one */
- v = segment->first->v;
- if ( v < min_pos )
- min_pos = v;
- if ( v > max_pos )
- max_pos = v;
+ if ( prev_segment->last->in_dir == point->in_dir )
+ {
+ /* we have identical directions (this can happen for */
+ /* degenerate outlines that move zig-zag along the main */
+ /* axis without changing the coordinate value of the other */
+ /* axis, and where the segments have just been merged): */
+ /* unify segments */
- segment->min_coord = (FT_Short)min_pos;
- segment->max_coord = (FT_Short)max_pos;
- segment->height = (FT_Short)( segment->max_coord -
- segment->min_coord );
+ /* update constraints */
+
+ if ( prev_min_pos < min_pos )
+ min_pos = prev_min_pos;
+ if ( prev_max_pos > max_pos )
+ max_pos = prev_max_pos;
+
+ if ( prev_min_coord < min_coord )
+ {
+ min_coord = prev_min_coord;
+ min_flags = prev_min_flags;
+ }
+ if ( prev_max_coord > max_coord )
+ {
+ max_coord = prev_max_coord;
+ max_flags = prev_max_flags;
+ }
+
+ if ( prev_min_on_coord < min_on_coord )
+ min_on_coord = prev_min_on_coord;
+ if ( prev_max_on_coord > max_on_coord )
+ max_on_coord = prev_max_on_coord;
+
+ prev_segment->last = point;
+ prev_segment->pos = (FT_Short)( ( min_pos +
+ max_pos ) >> 1 );
+
+ if ( ( min_flags | max_flags ) & AF_FLAG_CONTROL &&
+ ( max_on_coord - min_on_coord ) < flat_threshold )
+ prev_segment->flags |= AF_EDGE_ROUND;
+ else
+ prev_segment->flags &= ~AF_EDGE_ROUND;
+
+ prev_segment->min_coord = (FT_Short)min_coord;
+ prev_segment->max_coord = (FT_Short)max_coord;
+ prev_segment->height = prev_segment->max_coord -
+ prev_segment->min_coord;
+ }
+ else
+ {
+ /* we have different directions; use the properties of the */
+ /* longer segment and discard the other one */
+
+ if ( FT_ABS( prev_max_coord - prev_min_coord ) >
+ FT_ABS( max_coord - min_coord ) )
+ {
+ /* discard current segment */
+
+ if ( min_pos < prev_min_pos )
+ prev_min_pos = min_pos;
+ if ( max_pos > prev_max_pos )
+ prev_max_pos = max_pos;
+
+ prev_segment->last = point;
+ prev_segment->pos = (FT_Short)( ( prev_min_pos +
+ prev_max_pos ) >> 1 );
+ }
+ else
+ {
+ /* discard previous segment */
+
+ if ( prev_min_pos < min_pos )
+ min_pos = prev_min_pos;
+ if ( prev_max_pos > max_pos )
+ max_pos = prev_max_pos;
+
+ segment->last = point;
+ segment->pos = (FT_Short)( ( min_pos + max_pos ) >> 1 );
+
+ if ( ( min_flags | max_flags ) & AF_FLAG_CONTROL &&
+ ( max_on_coord - min_on_coord ) < flat_threshold )
+ segment->flags |= AF_EDGE_ROUND;
+
+ segment->min_coord = (FT_Short)min_coord;
+ segment->max_coord = (FT_Short)max_coord;
+ segment->height = segment->max_coord -
+ segment->min_coord;
+
+ *prev_segment = *segment;
+
+ prev_min_pos = min_pos;
+ prev_max_pos = max_pos;
+ prev_min_coord = min_coord;
+ prev_max_coord = max_coord;
+ prev_min_flags = min_flags;
+ prev_max_flags = max_flags;
+ prev_min_on_coord = min_on_coord;
+ prev_max_on_coord = max_on_coord;
+ }
+ }
+
+ axis->num_segments--;
+ }
on_edge = 0;
segment = NULL;
+
/* fall through */
}
}
passed = 1;
}
- if ( !on_edge && FT_ABS( point->out_dir ) == major_dir )
+ /* if we are not on an edge, check whether the major direction */
+ /* coincides with the current point's `out' direction, or */
+ /* whether we have a single-point contour */
+ if ( !on_edge &&
+ ( FT_ABS( point->out_dir ) == major_dir ||
+ point == point->prev ) )
{
/* this is the start of a new segment! */
segment_dir = (AF_Direction)point->out_dir;
segment->first = point;
segment->last = point;
- min_pos = max_pos = point->u;
+ /* `af_axis_hints_new_segment' reallocates memory, */
+ /* thus we have to refresh the `prev_segment' pointer */
+ if ( prev_segment )
+ prev_segment = segment - 1;
+
+ min_pos = max_pos = point->u;
+ min_coord = max_coord = point->v;
+ min_flags = max_flags = point->flags;
if ( point->flags & AF_FLAG_CONTROL )
{
- min_on_pos = 32000;
- max_on_pos = -32000;
+ min_on_coord = 32000;
+ max_on_coord = -32000;
}
else
- min_on_pos = max_on_pos = point->v;
+ min_on_coord = max_on_coord = point->v;
on_edge = 1;
+
+ if ( point == point->prev )
+ {
+ /* we have a one-point segment: this is a one-point */
+ /* contour with `in' and `out' direction set to */
+ /* AF_DIR_NONE */
+ segment->pos = (FT_Short)min_pos;
+
+ if (point->flags & AF_FLAG_CONTROL)
+ segment->flags |= AF_EDGE_ROUND;
+
+ segment->min_coord = (FT_Short)point->v;
+ segment->max_coord = (FT_Short)point->v;
+ segment->height = 0;
+
+ on_edge = 0;
+ segment = NULL;
+ }
}
point = point->next;
FT_Int ee;
- if ( seg->height < segment_length_threshold )
+ /* ignore too short segments and, in this loop, */
+ /* one-point segments without a direction */
+ if ( seg->height < segment_length_threshold ||
+ seg->dir == AF_DIR_NONE )
continue;
/* A special case for serif edges: If they are smaller than */
}
}
+ /* we loop again over all segments to catch one-point segments */
+ /* without a direction: if possible, link them to existing edges */
+ for ( seg = segments; seg < segment_limit; seg++ )
+ {
+ AF_Edge found = NULL;
+ FT_Int ee;
+
+
+ if ( seg->dir != AF_DIR_NONE )
+ continue;
+
+ /* look for an edge corresponding to the segment */
+ for ( ee = 0; ee < axis->num_edges; ee++ )
+ {
+ AF_Edge edge = axis->edges + ee;
+ FT_Pos dist;
+
+
+ dist = seg->pos - edge->fpos;
+ if ( dist < 0 )
+ dist = -dist;
+
+ if ( dist < edge_distance_threshold )
+ {
+ found = edge;
+ break;
+ }
+ }
+
+ /* one-point segments without a match are ignored */
+ if ( found )
+ {
+ seg->edge_next = found->first;
+ found->last->edge_next = seg;
+ found->last = seg;
+ }
+ }
+
/******************************************************************/
/* */
af_latin_compute_stem_width( AF_GlyphHints hints,
AF_Dimension dim,
FT_Pos width,
+ FT_Pos base_delta,
FT_UInt base_flags,
FT_UInt stem_flags )
{
dist += delta;
}
else
- dist = ( dist + 32 ) & ~63;
+ {
+ /* A stem's end position depends on two values: the start */
+ /* position and the stem length. The former gets usually */
+ /* rounded to the grid, while the latter gets rounded also if it */
+ /* exceeds a certain length (see below in this function). This */
+ /* `double rounding' can lead to a great difference to the */
+ /* original, unhinted position; this normally doesn't matter for */
+ /* large PPEM values, but for small sizes it can easily make */
+ /* outlines collide. For this reason, we adjust the stem length */
+ /* by a small amount depending on the PPEM value in case the */
+ /* former and latter rounding both point into the same */
+ /* direction. */
+
+ FT_Pos bdelta = 0;
+
+
+ if ( ( ( width > 0 ) && ( base_delta > 0 ) ) ||
+ ( ( width < 0 ) && ( base_delta < 0 ) ) )
+ {
+ FT_UInt ppem = metrics->root.scaler.face->size->metrics.x_ppem;
+
+
+ if ( ppem < 10 )
+ bdelta = base_delta;
+ else if ( ppem < 30 )
+ bdelta = ( base_delta * (FT_Pos)( 30 - ppem ) ) / 20;
+
+ if ( bdelta < 0 )
+ bdelta = -bdelta;
+ }
+
+ dist = ( dist - bdelta + 32 ) & ~63;
+ }
}
}
else
AF_Edge base_edge,
AF_Edge stem_edge )
{
- FT_Pos dist = stem_edge->opos - base_edge->opos;
+ FT_Pos dist, base_delta;
+ FT_Pos fitted_width;
+
+
+ dist = stem_edge->opos - base_edge->opos;
+ base_delta = base_edge->pos - base_edge->opos;
- FT_Pos fitted_width = af_latin_compute_stem_width( hints, dim, dist,
- base_edge->flags,
- stem_edge->flags );
+ fitted_width = af_latin_compute_stem_width( hints, dim,
+ dist, base_delta,
+ base_edge->flags,
+ stem_edge->flags );
stem_edge->pos = base_edge->pos + fitted_width;
org_len = edge2->opos - edge->opos;
- cur_len = af_latin_compute_stem_width( hints, dim, org_len,
+ cur_len = af_latin_compute_stem_width( hints, dim,
+ org_len, 0,
edge->flags,
edge2->flags );
org_len = edge2->opos - edge->opos;
org_center = org_pos + ( org_len >> 1 );
- cur_len = af_latin_compute_stem_width( hints, dim, org_len,
+ cur_len = af_latin_compute_stem_width( hints, dim,
+ org_len, 0,
edge->flags,
edge2->flags );
org_len = edge2->opos - edge->opos;
org_center = org_pos + ( org_len >> 1 );
- cur_len = af_latin_compute_stem_width( hints, dim, org_len,
+ cur_len = af_latin_compute_stem_width( hints, dim,
+ org_len, 0,
edge->flags,
edge2->flags );
( top_to_bottom_hinting ? ( edge->pos > edge[-1].pos )
: ( edge->pos < edge[-1].pos ) ) )
{
+ /* don't move if stem would (almost) disappear otherwise; */
+ /* the ad-hoc value 16 corresponds to 1/4px */
+ if ( edge->link && FT_ABS( edge->link->pos - edge[-1].pos ) > 16 )
+ {
#ifdef FT_DEBUG_LEVEL_TRACE
- FT_TRACE5(( " BOUND: edge %d (pos=%.2f) moved to %.2f\n",
- edge - edges, edge->pos / 64.0, edge[-1].pos / 64.0 ));
+ FT_TRACE5(( " BOUND: edge %d (pos=%.2f) moved to %.2f\n",
+ edge - edges,
+ edge->pos / 64.0,
+ edge[-1].pos / 64.0 ));
- num_actions++;
+ num_actions++;
#endif
- edge->pos = edge[-1].pos;
+ edge->pos = edge[-1].pos;
+ }
}
}
}
( top_to_bottom_hinting ? ( edge->pos > edge[-1].pos )
: ( edge->pos < edge[-1].pos ) ) )
{
+ /* don't move if stem would (almost) disappear otherwise; */
+ /* the ad-hoc value 16 corresponds to 1/4px */
+ if ( edge->link && FT_ABS( edge->link->pos - edge[-1].pos ) > 16 )
+ {
#ifdef FT_DEBUG_LEVEL_TRACE
- FT_TRACE5(( " BOUND: edge %d (pos=%.2f) moved to %.2f\n",
- edge - edges, edge->pos / 64.0, edge[-1].pos / 64.0 ));
+ FT_TRACE5(( " BOUND: edge %d (pos=%.2f) moved to %.2f\n",
+ edge - edges,
+ edge->pos / 64.0,
+ edge[-1].pos / 64.0 ));
- num_actions++;
+ num_actions++;
#endif
- edge->pos = edge[-1].pos;
+ edge->pos = edge[-1].pos;
+ }
}
if ( edge + 1 < edge_limit &&
( top_to_bottom_hinting ? ( edge->pos < edge[1].pos )
: ( edge->pos > edge[1].pos ) ) )
{
+ /* don't move if stem would (almost) disappear otherwise; */
+ /* the ad-hoc value 16 corresponds to 1/4px */
+ if ( edge->link && FT_ABS( edge->link->pos - edge[-1].pos ) > 16 )
+ {
#ifdef FT_DEBUG_LEVEL_TRACE
- FT_TRACE5(( " BOUND: edge %d (pos=%.2f) moved to %.2f\n",
- edge - edges, edge->pos / 64.0, edge[1].pos / 64.0 ));
+ FT_TRACE5(( " BOUND: edge %d (pos=%.2f) moved to %.2f\n",
+ edge - edges,
+ edge->pos / 64.0,
+ edge[1].pos / 64.0 ));
- num_actions++;
+ num_actions++;
#endif
- edge->pos = edge[1].pos;
+ edge->pos = edge[1].pos;
+ }
}
}
}
+/* ATTENTION: This file doesn't compile. It is only here as a reference */
+/* of an alternative latin hinting algorithm that was always */
+/* marked as experimental. */
+
+
/***************************************************************************/
/* */
/* aflatin2.c */
+/* ATTENTION: This file doesn't compile. It is only here as a reference */
+/* of an alternative latin hinting algorithm that was always */
+/* marked as experimental. */
+
+
/***************************************************************************/
/* */
/* aflatin2.h */
const AF_Script_UniRangeRec af_arab_uniranges[] =
{
- AF_UNIRANGE_REC( 0x0600UL, 0x06FFUL ), /* Arabic */
- AF_UNIRANGE_REC( 0x0750UL, 0x07FFUL ), /* Arabic Supplement */
- AF_UNIRANGE_REC( 0x08A0UL, 0x08FFUL ), /* Arabic Extended-A */
- AF_UNIRANGE_REC( 0xFB50UL, 0xFDFFUL ), /* Arabic Presentation Forms-A */
- AF_UNIRANGE_REC( 0xFE70UL, 0xFEFFUL ), /* Arabic Presentation Forms-B */
- AF_UNIRANGE_REC( 0x1EE00UL, 0x1EEFFUL ), /* Arabic Mathematical Alphabetic Symbols */
- AF_UNIRANGE_REC( 0UL, 0UL )
+ AF_UNIRANGE_REC( 0x0600, 0x06FF ), /* Arabic */
+ AF_UNIRANGE_REC( 0x0750, 0x07FF ), /* Arabic Supplement */
+ AF_UNIRANGE_REC( 0x08A0, 0x08FF ), /* Arabic Extended-A */
+ AF_UNIRANGE_REC( 0xFB50, 0xFDFF ), /* Arabic Presentation Forms-A */
+ AF_UNIRANGE_REC( 0xFE70, 0xFEFF ), /* Arabic Presentation Forms-B */
+ AF_UNIRANGE_REC( 0x1EE00, 0x1EEFF ), /* Arabic Mathematical Alphabetic Symbols */
+ AF_UNIRANGE_REC( 0, 0 )
};
const AF_Script_UniRangeRec af_arab_nonbase_uniranges[] =
{
- AF_UNIRANGE_REC( 0x0600UL, 0x0605UL ),
- AF_UNIRANGE_REC( 0x0610UL, 0x061AUL ),
- AF_UNIRANGE_REC( 0x064BUL, 0x065FUL ),
- AF_UNIRANGE_REC( 0x0670UL, 0x0670UL ),
- AF_UNIRANGE_REC( 0x06D6UL, 0x06DCUL ),
- AF_UNIRANGE_REC( 0x06DFUL, 0x06E4UL ),
- AF_UNIRANGE_REC( 0x06E7UL, 0x06E8UL ),
- AF_UNIRANGE_REC( 0x06EAUL, 0x06EDUL ),
- AF_UNIRANGE_REC( 0x08E3UL, 0x08FFUL ),
- AF_UNIRANGE_REC( 0xFBB2UL, 0xFBC1UL ),
- AF_UNIRANGE_REC( 0xFE70UL, 0xFE70UL ),
- AF_UNIRANGE_REC( 0xFE72UL, 0xFE72UL ),
- AF_UNIRANGE_REC( 0xFE74UL, 0xFE74UL ),
- AF_UNIRANGE_REC( 0xFE76UL, 0xFE76UL ),
- AF_UNIRANGE_REC( 0xFE78UL, 0xFE78UL ),
- AF_UNIRANGE_REC( 0xFE7AUL, 0xFE7AUL ),
- AF_UNIRANGE_REC( 0xFE7CUL, 0xFE7CUL ),
- AF_UNIRANGE_REC( 0xFE7EUL, 0xFE7EUL ),
- AF_UNIRANGE_REC( 0UL, 0UL )
+ AF_UNIRANGE_REC( 0x0600, 0x0605 ),
+ AF_UNIRANGE_REC( 0x0610, 0x061A ),
+ AF_UNIRANGE_REC( 0x064B, 0x065F ),
+ AF_UNIRANGE_REC( 0x0670, 0x0670 ),
+ AF_UNIRANGE_REC( 0x06D6, 0x06DC ),
+ AF_UNIRANGE_REC( 0x06DF, 0x06E4 ),
+ AF_UNIRANGE_REC( 0x06E7, 0x06E8 ),
+ AF_UNIRANGE_REC( 0x06EA, 0x06ED ),
+ AF_UNIRANGE_REC( 0x08D4, 0x08E1 ),
+ AF_UNIRANGE_REC( 0x08E3, 0x08FF ),
+ AF_UNIRANGE_REC( 0xFBB2, 0xFBC1 ),
+ AF_UNIRANGE_REC( 0xFE70, 0xFE70 ),
+ AF_UNIRANGE_REC( 0xFE72, 0xFE72 ),
+ AF_UNIRANGE_REC( 0xFE74, 0xFE74 ),
+ AF_UNIRANGE_REC( 0xFE76, 0xFE76 ),
+ AF_UNIRANGE_REC( 0xFE78, 0xFE78 ),
+ AF_UNIRANGE_REC( 0xFE7A, 0xFE7A ),
+ AF_UNIRANGE_REC( 0xFE7C, 0xFE7C ),
+ AF_UNIRANGE_REC( 0xFE7E, 0xFE7E ),
+ AF_UNIRANGE_REC( 0, 0 )
+ };
+
+
+ const AF_Script_UniRangeRec af_armn_uniranges[] =
+ {
+ AF_UNIRANGE_REC( 0x0530, 0x058F ), /* Armenian */
+ AF_UNIRANGE_REC( 0xFB13, 0xFB17 ), /* Alphab. Present. Forms (Armenian) */
+ AF_UNIRANGE_REC( 0, 0 )
+ };
+
+ const AF_Script_UniRangeRec af_armn_nonbase_uniranges[] =
+ {
+ AF_UNIRANGE_REC( 0x0559, 0x055F ),
+ AF_UNIRANGE_REC( 0, 0 )
};
const AF_Script_UniRangeRec af_beng_uniranges[] =
{
- AF_UNIRANGE_REC( 0x0980UL, 0x09FFUL ), /* Bengali */
- AF_UNIRANGE_REC( 0UL, 0UL )
+ AF_UNIRANGE_REC( 0x0980, 0x09FF ), /* Bengali */
+ AF_UNIRANGE_REC( 0, 0 )
};
const AF_Script_UniRangeRec af_beng_nonbase_uniranges[] =
{
- AF_UNIRANGE_REC( 0x0981UL, 0x0981UL ),
- AF_UNIRANGE_REC( 0x09BCUL, 0x09BCUL ),
- AF_UNIRANGE_REC( 0x09C1UL, 0x09C4UL ),
- AF_UNIRANGE_REC( 0x09CDUL, 0x09CDUL ),
- AF_UNIRANGE_REC( 0x09E2UL, 0x09E3UL ),
- AF_UNIRANGE_REC( 0UL, 0UL )
+ AF_UNIRANGE_REC( 0x0981, 0x0981 ),
+ AF_UNIRANGE_REC( 0x09BC, 0x09BC ),
+ AF_UNIRANGE_REC( 0x09C1, 0x09C4 ),
+ AF_UNIRANGE_REC( 0x09CD, 0x09CD ),
+ AF_UNIRANGE_REC( 0x09E2, 0x09E3 ),
+ AF_UNIRANGE_REC( 0, 0 )
+ };
+
+
+ const AF_Script_UniRangeRec af_cher_uniranges[] =
+ {
+ AF_UNIRANGE_REC( 0x13A0, 0x13FF ), /* Cherokee */
+ AF_UNIRANGE_REC( 0xAB70, 0xABBF ), /* Cherokee Supplement */
+ AF_UNIRANGE_REC( 0, 0 )
+ };
+
+ const AF_Script_UniRangeRec af_cher_nonbase_uniranges[] =
+ {
+ AF_UNIRANGE_REC( 0, 0 )
};
const AF_Script_UniRangeRec af_cyrl_uniranges[] =
{
- 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 )
+ AF_UNIRANGE_REC( 0x0400, 0x04FF ), /* Cyrillic */
+ AF_UNIRANGE_REC( 0x0500, 0x052F ), /* Cyrillic Supplement */
+ AF_UNIRANGE_REC( 0x2DE0, 0x2DFF ), /* Cyrillic Extended-A */
+ AF_UNIRANGE_REC( 0xA640, 0xA69F ), /* Cyrillic Extended-B */
+ AF_UNIRANGE_REC( 0x1C80, 0x1C8F ), /* Cyrillic Extended-C */
+ AF_UNIRANGE_REC( 0, 0 )
};
const AF_Script_UniRangeRec af_cyrl_nonbase_uniranges[] =
{
- AF_UNIRANGE_REC( 0x0483UL, 0x0489UL ),
- AF_UNIRANGE_REC( 0x2DE0UL, 0x2DFFUL ),
- AF_UNIRANGE_REC( 0xA66FUL, 0xA67FUL ),
- AF_UNIRANGE_REC( 0xA69EUL, 0xA69FUL ),
- AF_UNIRANGE_REC( 0UL, 0UL )
+ AF_UNIRANGE_REC( 0x0483, 0x0489 ),
+ AF_UNIRANGE_REC( 0x2DE0, 0x2DFF ),
+ AF_UNIRANGE_REC( 0xA66F, 0xA67F ),
+ AF_UNIRANGE_REC( 0xA69E, 0xA69F ),
+ AF_UNIRANGE_REC( 0, 0 )
};
const AF_Script_UniRangeRec af_deva_uniranges[] =
{
- AF_UNIRANGE_REC( 0x0900UL, 0x093BUL ), /* Devanagari */
+ AF_UNIRANGE_REC( 0x0900, 0x093B ), /* Devanagari */
/* omitting U+093C nukta */
- AF_UNIRANGE_REC( 0x093DUL, 0x0950UL ), /* ... continued */
+ AF_UNIRANGE_REC( 0x093D, 0x0950 ), /* ... continued */
/* omitting U+0951 udatta, U+0952 anudatta */
- AF_UNIRANGE_REC( 0x0953UL, 0x0963UL ), /* ... continued */
+ AF_UNIRANGE_REC( 0x0953, 0x0963 ), /* ... continued */
/* omitting U+0964 danda, U+0965 double danda */
- AF_UNIRANGE_REC( 0x0966UL, 0x097FUL ), /* ... continued */
- AF_UNIRANGE_REC( 0x20B9UL, 0x20B9UL ), /* (new) Rupee sign */
- AF_UNIRANGE_REC( 0xA8E0UL, 0xA8FFUL ), /* Devanagari Extended */
- AF_UNIRANGE_REC( 0UL, 0UL )
+ AF_UNIRANGE_REC( 0x0966, 0x097F ), /* ... continued */
+ AF_UNIRANGE_REC( 0x20B9, 0x20B9 ), /* (new) Rupee sign */
+ AF_UNIRANGE_REC( 0xA8E0, 0xA8FF ), /* Devanagari Extended */
+ AF_UNIRANGE_REC( 0, 0 )
};
const AF_Script_UniRangeRec af_deva_nonbase_uniranges[] =
{
- AF_UNIRANGE_REC( 0x0900UL, 0x0902UL ),
- AF_UNIRANGE_REC( 0x093AUL, 0x093AUL ),
- AF_UNIRANGE_REC( 0x0941UL, 0x0948UL ),
- AF_UNIRANGE_REC( 0x094DUL, 0x094DUL ),
- AF_UNIRANGE_REC( 0x0953UL, 0x0957UL ),
- AF_UNIRANGE_REC( 0x0962UL, 0x0963UL ),
- AF_UNIRANGE_REC( 0xA8E0UL, 0xA8F1UL ),
- AF_UNIRANGE_REC( 0UL, 0UL )
+ AF_UNIRANGE_REC( 0x0900, 0x0902 ),
+ AF_UNIRANGE_REC( 0x093A, 0x093A ),
+ AF_UNIRANGE_REC( 0x0941, 0x0948 ),
+ AF_UNIRANGE_REC( 0x094D, 0x094D ),
+ AF_UNIRANGE_REC( 0x0953, 0x0957 ),
+ AF_UNIRANGE_REC( 0x0962, 0x0963 ),
+ AF_UNIRANGE_REC( 0xA8E0, 0xA8F1 ),
+ AF_UNIRANGE_REC( 0, 0 )
+ };
+
+
+ const AF_Script_UniRangeRec af_ethi_uniranges[] =
+ {
+ AF_UNIRANGE_REC( 0x1200, 0x137F ), /* Ethiopic */
+ AF_UNIRANGE_REC( 0x1380, 0x139F ), /* Ethiopic Supplement */
+ AF_UNIRANGE_REC( 0x2D80, 0x2DDF ), /* Ethiopic Extended */
+ AF_UNIRANGE_REC( 0xAB00, 0xAB2F ), /* Ethiopic Extended-A */
+ AF_UNIRANGE_REC( 0, 0 )
+ };
+
+ const AF_Script_UniRangeRec af_ethi_nonbase_uniranges[] =
+ {
+ AF_UNIRANGE_REC( 0x135D, 0x135F ),
+ AF_UNIRANGE_REC( 0, 0 )
+ };
+
+
+ const AF_Script_UniRangeRec af_geor_uniranges[] =
+ {
+ AF_UNIRANGE_REC( 0x10D0, 0x10FF ), /* Georgian (Mkhedruli) */
+#if 0
+ /* the following range is proposed for inclusion in Unicode */
+ AF_UNIRANGE_REC( 0x1C90, 0x1CBF ), /* Georgian (Mtavruli) */
+#endif
+ AF_UNIRANGE_REC( 0, 0 )
+ };
+
+ const AF_Script_UniRangeRec af_geor_nonbase_uniranges[] =
+ {
+ AF_UNIRANGE_REC( 0, 0 )
+ };
+
+
+ const AF_Script_UniRangeRec af_geok_uniranges[] =
+ {
+ /* Khutsuri */
+ AF_UNIRANGE_REC( 0x10A0, 0x10CD ), /* Georgian (Asomtavruli) */
+ AF_UNIRANGE_REC( 0x2D00, 0x2D2D ), /* Georgian (Nuskhuri) */
+ AF_UNIRANGE_REC( 0, 0 )
+ };
+
+ const AF_Script_UniRangeRec af_geok_nonbase_uniranges[] =
+ {
+ AF_UNIRANGE_REC( 0, 0 )
};
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( 0UL, 0UL )
+ AF_UNIRANGE_REC( 0x0370, 0x03FF ), /* Greek and Coptic */
+ AF_UNIRANGE_REC( 0x1F00, 0x1FFF ), /* Greek Extended */
+ AF_UNIRANGE_REC( 0, 0 )
};
const AF_Script_UniRangeRec af_grek_nonbase_uniranges[] =
{
- AF_UNIRANGE_REC( 0x037AUL, 0x037AUL ),
- AF_UNIRANGE_REC( 0x0384UL, 0x0385UL ),
- AF_UNIRANGE_REC( 0x1FBDUL, 0x1FC1UL ),
- AF_UNIRANGE_REC( 0x1FCDUL, 0x1FCFUL ),
- AF_UNIRANGE_REC( 0x1FDDUL, 0x1FDFUL ),
- AF_UNIRANGE_REC( 0x1FEDUL, 0x1FEFUL ),
- AF_UNIRANGE_REC( 0x1FFDUL, 0x1FFEUL ),
- AF_UNIRANGE_REC( 0UL, 0UL )
+ AF_UNIRANGE_REC( 0x037A, 0x037A ),
+ AF_UNIRANGE_REC( 0x0384, 0x0385 ),
+ AF_UNIRANGE_REC( 0x1FBD, 0x1FC1 ),
+ AF_UNIRANGE_REC( 0x1FCD, 0x1FCF ),
+ AF_UNIRANGE_REC( 0x1FDD, 0x1FDF ),
+ AF_UNIRANGE_REC( 0x1FED, 0x1FEF ),
+ AF_UNIRANGE_REC( 0x1FFD, 0x1FFE ),
+ AF_UNIRANGE_REC( 0, 0 )
+ };
+
+
+ const AF_Script_UniRangeRec af_gujr_uniranges[] =
+ {
+ AF_UNIRANGE_REC( 0x0A80, 0x0AFF ), /* Gujarati */
+ AF_UNIRANGE_REC( 0, 0 )
+ };
+
+ const AF_Script_UniRangeRec af_gujr_nonbase_uniranges[] =
+ {
+ AF_UNIRANGE_REC( 0x0A81, 0x0A82 ),
+ AF_UNIRANGE_REC( 0x0ABC, 0x0ABC ),
+ AF_UNIRANGE_REC( 0x0AC1, 0x0AC8 ),
+ AF_UNIRANGE_REC( 0x0ACD, 0x0ACD ),
+ AF_UNIRANGE_REC( 0x0AE2, 0x0AE3 ),
+ AF_UNIRANGE_REC( 0, 0 )
+ };
+
+
+ const AF_Script_UniRangeRec af_guru_uniranges[] =
+ {
+ AF_UNIRANGE_REC( 0x0A00, 0x0A7F ), /* Gurmukhi */
+ AF_UNIRANGE_REC( 0, 0 )
+ };
+
+ const AF_Script_UniRangeRec af_guru_nonbase_uniranges[] =
+ {
+ AF_UNIRANGE_REC( 0x0A01, 0x0A02 ),
+ AF_UNIRANGE_REC( 0x0A3C, 0x0A3C ),
+ AF_UNIRANGE_REC( 0x0A41, 0x0A51 ),
+ AF_UNIRANGE_REC( 0x0A70, 0x0A71 ),
+ AF_UNIRANGE_REC( 0x0A75, 0x0A75 ),
+ AF_UNIRANGE_REC( 0, 0 )
};
const AF_Script_UniRangeRec af_hebr_uniranges[] =
{
- AF_UNIRANGE_REC( 0x0590UL, 0x05FFUL ), /* Hebrew */
- AF_UNIRANGE_REC( 0xFB1DUL, 0xFB4FUL ), /* Alphab. Present. Forms (Hebrew) */
- AF_UNIRANGE_REC( 0UL, 0UL )
+ AF_UNIRANGE_REC( 0x0590, 0x05FF ), /* Hebrew */
+ AF_UNIRANGE_REC( 0xFB1D, 0xFB4F ), /* Alphab. Present. Forms (Hebrew) */
+ AF_UNIRANGE_REC( 0, 0 )
};
const AF_Script_UniRangeRec af_hebr_nonbase_uniranges[] =
{
- AF_UNIRANGE_REC( 0x0591UL, 0x05BFUL ),
- AF_UNIRANGE_REC( 0x05C1UL, 0x05C2UL ),
- AF_UNIRANGE_REC( 0x05C4UL, 0x05C5UL ),
- AF_UNIRANGE_REC( 0x05C7UL, 0x05C7UL ),
- AF_UNIRANGE_REC( 0xFB1EUL, 0xFB1EUL ),
- AF_UNIRANGE_REC( 0UL, 0UL )
+ AF_UNIRANGE_REC( 0x0591, 0x05BF ),
+ AF_UNIRANGE_REC( 0x05C1, 0x05C2 ),
+ AF_UNIRANGE_REC( 0x05C4, 0x05C5 ),
+ AF_UNIRANGE_REC( 0x05C7, 0x05C7 ),
+ AF_UNIRANGE_REC( 0xFB1E, 0xFB1E ),
+ AF_UNIRANGE_REC( 0, 0 )
};
const AF_Script_UniRangeRec af_knda_uniranges[] =
{
- AF_UNIRANGE_REC( 0x0C80UL, 0x0CFFUL ), /* Kannada */
- AF_UNIRANGE_REC( 0UL, 0UL )
+ AF_UNIRANGE_REC( 0x0C80, 0x0CFF ), /* Kannada */
+ AF_UNIRANGE_REC( 0, 0 )
};
const AF_Script_UniRangeRec af_knda_nonbase_uniranges[] =
{
- AF_UNIRANGE_REC( 0x0C81UL, 0x0C81UL ),
- AF_UNIRANGE_REC( 0x0CBCUL, 0x0CBCUL ),
- AF_UNIRANGE_REC( 0x0CBFUL, 0x0CBFUL ),
- AF_UNIRANGE_REC( 0x0CC6UL, 0x0CC6UL ),
- AF_UNIRANGE_REC( 0x0CCCUL, 0x0CCDUL ),
- AF_UNIRANGE_REC( 0x0CE2UL, 0x0CE3UL ),
- AF_UNIRANGE_REC( 0UL, 0UL )
+ AF_UNIRANGE_REC( 0x0C81, 0x0C81 ),
+ AF_UNIRANGE_REC( 0x0CBC, 0x0CBC ),
+ AF_UNIRANGE_REC( 0x0CBF, 0x0CBF ),
+ AF_UNIRANGE_REC( 0x0CC6, 0x0CC6 ),
+ AF_UNIRANGE_REC( 0x0CCC, 0x0CCD ),
+ AF_UNIRANGE_REC( 0x0CE2, 0x0CE3 ),
+ AF_UNIRANGE_REC( 0, 0 )
};
const AF_Script_UniRangeRec af_khmr_uniranges[] =
{
- AF_UNIRANGE_REC( 0x1780UL, 0x17FFUL ), /* Khmer */
- AF_UNIRANGE_REC( 0UL, 0UL )
+ AF_UNIRANGE_REC( 0x1780, 0x17FF ), /* Khmer */
+ AF_UNIRANGE_REC( 0, 0 )
};
const AF_Script_UniRangeRec af_khmr_nonbase_uniranges[] =
{
- AF_UNIRANGE_REC( 0x17B7UL, 0x17BDUL ),
- AF_UNIRANGE_REC( 0x17C6UL, 0x17C6UL ),
- AF_UNIRANGE_REC( 0x17C9UL, 0x17D3UL ),
- AF_UNIRANGE_REC( 0x17DDUL, 0x17DDUL ),
- AF_UNIRANGE_REC( 0UL, 0UL )
+ AF_UNIRANGE_REC( 0x17B7, 0x17BD ),
+ AF_UNIRANGE_REC( 0x17C6, 0x17C6 ),
+ AF_UNIRANGE_REC( 0x17C9, 0x17D3 ),
+ AF_UNIRANGE_REC( 0x17DD, 0x17DD ),
+ AF_UNIRANGE_REC( 0, 0 )
};
const AF_Script_UniRangeRec af_khms_uniranges[] =
{
- AF_UNIRANGE_REC( 0x19E0UL, 0x19FFUL ), /* Khmer Symbols */
- AF_UNIRANGE_REC( 0UL, 0UL )
+ AF_UNIRANGE_REC( 0x19E0, 0x19FF ), /* Khmer Symbols */
+ AF_UNIRANGE_REC( 0, 0 )
};
const AF_Script_UniRangeRec af_khms_nonbase_uniranges[] =
{
- AF_UNIRANGE_REC( 0UL, 0UL )
+ AF_UNIRANGE_REC( 0, 0 )
};
const AF_Script_UniRangeRec af_lao_uniranges[] =
{
- AF_UNIRANGE_REC( 0x0E80UL, 0x0EFFUL ), /* Lao */
- AF_UNIRANGE_REC( 0UL, 0UL )
+ AF_UNIRANGE_REC( 0x0E80, 0x0EFF ), /* Lao */
+ AF_UNIRANGE_REC( 0, 0 )
};
const AF_Script_UniRangeRec af_lao_nonbase_uniranges[] =
{
- AF_UNIRANGE_REC( 0x0EB1UL, 0x0EB1UL ),
- AF_UNIRANGE_REC( 0x0EB4UL, 0x0EBCUL ),
- AF_UNIRANGE_REC( 0x0EC8UL, 0x0ECDUL ),
- AF_UNIRANGE_REC( 0UL, 0UL )
+ AF_UNIRANGE_REC( 0x0EB1, 0x0EB1 ),
+ AF_UNIRANGE_REC( 0x0EB4, 0x0EBC ),
+ AF_UNIRANGE_REC( 0x0EC8, 0x0ECD ),
+ AF_UNIRANGE_REC( 0, 0 )
};
const AF_Script_UniRangeRec af_latn_uniranges[] =
{
- AF_UNIRANGE_REC( 0x0020UL, 0x007FUL ), /* Basic Latin (no control chars) */
- AF_UNIRANGE_REC( 0x00A0UL, 0x00A9UL ), /* Latin-1 Supplement (no control chars) */
- AF_UNIRANGE_REC( 0x00ABUL, 0x00B1UL ), /* ... continued */
- AF_UNIRANGE_REC( 0x00B4UL, 0x00B8UL ), /* ... continued */
- AF_UNIRANGE_REC( 0x00BBUL, 0x00FFUL ), /* ... continued */
- 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( 0x02B9UL, 0x02DFUL ), /* Spacing Modifier Letters */
- AF_UNIRANGE_REC( 0x02E5UL, 0x02FFUL ), /* ... continued */
- AF_UNIRANGE_REC( 0x0300UL, 0x036FUL ), /* Combining Diacritical Marks */
- AF_UNIRANGE_REC( 0x1AB0UL, 0x1ABEUL ), /* Combining Diacritical Marks Extended */
- AF_UNIRANGE_REC( 0x1D00UL, 0x1D2BUL ), /* Phonetic Extensions */
- AF_UNIRANGE_REC( 0x1D6BUL, 0x1D77UL ), /* ... continued */
- AF_UNIRANGE_REC( 0x1D79UL, 0x1D7FUL ), /* ... continued */
- AF_UNIRANGE_REC( 0x1D80UL, 0x1D9AUL ), /* 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( 0x20A0UL, 0x20B8UL ), /* Currency Symbols ... */
- AF_UNIRANGE_REC( 0x20BAUL, 0x20CFUL ), /* ... except new Rupee sign */
- AF_UNIRANGE_REC( 0x2150UL, 0x218FUL ), /* Number Forms */
- AF_UNIRANGE_REC( 0x2C60UL, 0x2C7BUL ), /* Latin Extended-C */
- AF_UNIRANGE_REC( 0x2C7EUL, 0x2C7FUL ), /* ... continued */
- AF_UNIRANGE_REC( 0x2E00UL, 0x2E7FUL ), /* Supplemental Punctuation */
- AF_UNIRANGE_REC( 0xA720UL, 0xA76FUL ), /* Latin Extended-D */
- AF_UNIRANGE_REC( 0xA771UL, 0xA7F7UL ), /* ... continued */
- AF_UNIRANGE_REC( 0xA7FAUL, 0xA7FFUL ), /* ... continued */
- AF_UNIRANGE_REC( 0xAB30UL, 0xAB5BUL ), /* Latin Extended-E */
- AF_UNIRANGE_REC( 0xAB60UL, 0xAB6FUL ), /* ... continued */
- AF_UNIRANGE_REC( 0xFB00UL, 0xFB06UL ), /* Alphab. Present. Forms (Latin Ligs) */
- AF_UNIRANGE_REC( 0x1D400UL, 0x1D7FFUL ), /* Mathematical Alphanumeric Symbols */
- AF_UNIRANGE_REC( 0UL, 0UL )
+ AF_UNIRANGE_REC( 0x0020, 0x007F ), /* Basic Latin (no control chars) */
+ AF_UNIRANGE_REC( 0x00A0, 0x00A9 ), /* Latin-1 Supplement (no control chars) */
+ AF_UNIRANGE_REC( 0x00AB, 0x00B1 ), /* ... continued */
+ AF_UNIRANGE_REC( 0x00B4, 0x00B8 ), /* ... continued */
+ AF_UNIRANGE_REC( 0x00BB, 0x00FF ), /* ... continued */
+ AF_UNIRANGE_REC( 0x0100, 0x017F ), /* Latin Extended-A */
+ AF_UNIRANGE_REC( 0x0180, 0x024F ), /* Latin Extended-B */
+ AF_UNIRANGE_REC( 0x0250, 0x02AF ), /* IPA Extensions */
+ AF_UNIRANGE_REC( 0x02B9, 0x02DF ), /* Spacing Modifier Letters */
+ AF_UNIRANGE_REC( 0x02E5, 0x02FF ), /* ... continued */
+ AF_UNIRANGE_REC( 0x0300, 0x036F ), /* Combining Diacritical Marks */
+ AF_UNIRANGE_REC( 0x1AB0, 0x1ABE ), /* Combining Diacritical Marks Extended */
+ AF_UNIRANGE_REC( 0x1D00, 0x1D2B ), /* Phonetic Extensions */
+ AF_UNIRANGE_REC( 0x1D6B, 0x1D77 ), /* ... continued */
+ AF_UNIRANGE_REC( 0x1D79, 0x1D7F ), /* ... continued */
+ AF_UNIRANGE_REC( 0x1D80, 0x1D9A ), /* Phonetic Extensions Supplement */
+ AF_UNIRANGE_REC( 0x1DC0, 0x1DFF ), /* Combining Diacritical Marks Supplement */
+ AF_UNIRANGE_REC( 0x1E00, 0x1EFF ), /* Latin Extended Additional */
+ AF_UNIRANGE_REC( 0x2000, 0x206F ), /* General Punctuation */
+ AF_UNIRANGE_REC( 0x20A0, 0x20B8 ), /* Currency Symbols ... */
+ AF_UNIRANGE_REC( 0x20BA, 0x20CF ), /* ... except new Rupee sign */
+ AF_UNIRANGE_REC( 0x2150, 0x218F ), /* Number Forms */
+ AF_UNIRANGE_REC( 0x2C60, 0x2C7B ), /* Latin Extended-C */
+ AF_UNIRANGE_REC( 0x2C7E, 0x2C7F ), /* ... continued */
+ AF_UNIRANGE_REC( 0x2E00, 0x2E7F ), /* Supplemental Punctuation */
+ AF_UNIRANGE_REC( 0xA720, 0xA76F ), /* Latin Extended-D */
+ AF_UNIRANGE_REC( 0xA771, 0xA7F7 ), /* ... continued */
+ AF_UNIRANGE_REC( 0xA7FA, 0xA7FF ), /* ... continued */
+ AF_UNIRANGE_REC( 0xAB30, 0xAB5B ), /* Latin Extended-E */
+ AF_UNIRANGE_REC( 0xAB60, 0xAB6F ), /* ... continued */
+ AF_UNIRANGE_REC( 0xFB00, 0xFB06 ), /* Alphab. Present. Forms (Latin Ligs) */
+ AF_UNIRANGE_REC( 0x1D400, 0x1D7FF ), /* Mathematical Alphanumeric Symbols */
+ AF_UNIRANGE_REC( 0, 0 )
};
const AF_Script_UniRangeRec af_latn_nonbase_uniranges[] =
{
- AF_UNIRANGE_REC( 0x005EUL, 0x0060UL ),
- AF_UNIRANGE_REC( 0x007EUL, 0x007EUL ),
- AF_UNIRANGE_REC( 0x00A8UL, 0x00A9UL ),
- AF_UNIRANGE_REC( 0x00AEUL, 0x00B0UL ),
- AF_UNIRANGE_REC( 0x00B4UL, 0x00B4UL ),
- AF_UNIRANGE_REC( 0x00B8UL, 0x00B8UL ),
- AF_UNIRANGE_REC( 0x00BCUL, 0x00BEUL ),
- AF_UNIRANGE_REC( 0x02B9UL, 0x02DFUL ),
- AF_UNIRANGE_REC( 0x02E5UL, 0x02FFUL ),
- AF_UNIRANGE_REC( 0x0300UL, 0x036FUL ),
- AF_UNIRANGE_REC( 0x1AB0UL, 0x1ABEUL ),
- AF_UNIRANGE_REC( 0x1DC0UL, 0x1DFFUL ),
- AF_UNIRANGE_REC( 0x2017UL, 0x2017UL ),
- AF_UNIRANGE_REC( 0x203EUL, 0x203EUL ),
- AF_UNIRANGE_REC( 0xA788UL, 0xA788UL ),
- AF_UNIRANGE_REC( 0xA7F8UL, 0xA7FAUL ),
- AF_UNIRANGE_REC( 0UL, 0UL )
+ AF_UNIRANGE_REC( 0x005E, 0x0060 ),
+ AF_UNIRANGE_REC( 0x007E, 0x007E ),
+ AF_UNIRANGE_REC( 0x00A8, 0x00A9 ),
+ AF_UNIRANGE_REC( 0x00AE, 0x00B0 ),
+ AF_UNIRANGE_REC( 0x00B4, 0x00B4 ),
+ AF_UNIRANGE_REC( 0x00B8, 0x00B8 ),
+ AF_UNIRANGE_REC( 0x00BC, 0x00BE ),
+ AF_UNIRANGE_REC( 0x02B9, 0x02DF ),
+ AF_UNIRANGE_REC( 0x02E5, 0x02FF ),
+ AF_UNIRANGE_REC( 0x0300, 0x036F ),
+ AF_UNIRANGE_REC( 0x1AB0, 0x1ABE ),
+ AF_UNIRANGE_REC( 0x1DC0, 0x1DFF ),
+ AF_UNIRANGE_REC( 0x2017, 0x2017 ),
+ AF_UNIRANGE_REC( 0x203E, 0x203E ),
+ AF_UNIRANGE_REC( 0xA788, 0xA788 ),
+ AF_UNIRANGE_REC( 0xA7F8, 0xA7FA ),
+ AF_UNIRANGE_REC( 0, 0 )
};
const AF_Script_UniRangeRec af_latb_uniranges[] =
{
- AF_UNIRANGE_REC( 0x1D62UL, 0x1D6AUL ), /* some small subscript letters */
- AF_UNIRANGE_REC( 0x2080UL, 0x209CUL ), /* subscript digits and letters */
- AF_UNIRANGE_REC( 0x2C7CUL, 0x2C7CUL ), /* latin subscript small letter j */
- AF_UNIRANGE_REC( 0UL, 0UL )
+ AF_UNIRANGE_REC( 0x1D62, 0x1D6A ), /* some small subscript letters */
+ AF_UNIRANGE_REC( 0x2080, 0x209C ), /* subscript digits and letters */
+ AF_UNIRANGE_REC( 0x2C7C, 0x2C7C ), /* latin subscript small letter j */
+ AF_UNIRANGE_REC( 0, 0 )
};
const AF_Script_UniRangeRec af_latb_nonbase_uniranges[] =
{
- AF_UNIRANGE_REC( 0UL, 0UL )
+ AF_UNIRANGE_REC( 0, 0 )
};
const AF_Script_UniRangeRec af_latp_uniranges[] =
{
- AF_UNIRANGE_REC( 0x00AAUL, 0x00AAUL ), /* feminine ordinal indicator */
- AF_UNIRANGE_REC( 0x00B2UL, 0x00B3UL ), /* superscript two and three */
- AF_UNIRANGE_REC( 0x00B9UL, 0x00BAUL ), /* superscript one, masc. ord. indic. */
- AF_UNIRANGE_REC( 0x02B0UL, 0x02B8UL ), /* some latin superscript mod. letters */
- AF_UNIRANGE_REC( 0x02E0UL, 0x02E4UL ), /* some IPA modifier letters */
- AF_UNIRANGE_REC( 0x1D2CUL, 0x1D61UL ), /* latin superscript modifier letters */
- AF_UNIRANGE_REC( 0x1D78UL, 0x1D78UL ), /* modifier letter cyrillic en */
- AF_UNIRANGE_REC( 0x1D9BUL, 0x1DBFUL ), /* more modifier letters */
- AF_UNIRANGE_REC( 0x2070UL, 0x207FUL ), /* superscript digits and letters */
- AF_UNIRANGE_REC( 0x2C7DUL, 0x2C7DUL ), /* modifier letter capital v */
- AF_UNIRANGE_REC( 0xA770UL, 0xA770UL ), /* modifier letter us */
- AF_UNIRANGE_REC( 0xA7F8UL, 0xA7F9UL ), /* more modifier letters */
- AF_UNIRANGE_REC( 0xAB5CUL, 0xAB5FUL ), /* more modifier letters */
- AF_UNIRANGE_REC( 0UL, 0UL )
+ AF_UNIRANGE_REC( 0x00AA, 0x00AA ), /* feminine ordinal indicator */
+ AF_UNIRANGE_REC( 0x00B2, 0x00B3 ), /* superscript two and three */
+ AF_UNIRANGE_REC( 0x00B9, 0x00BA ), /* superscript one, masc. ord. indic. */
+ AF_UNIRANGE_REC( 0x02B0, 0x02B8 ), /* some latin superscript mod. letters */
+ AF_UNIRANGE_REC( 0x02E0, 0x02E4 ), /* some IPA modifier letters */
+ AF_UNIRANGE_REC( 0x1D2C, 0x1D61 ), /* latin superscript modifier letters */
+ AF_UNIRANGE_REC( 0x1D78, 0x1D78 ), /* modifier letter cyrillic en */
+ AF_UNIRANGE_REC( 0x1D9B, 0x1DBF ), /* more modifier letters */
+ AF_UNIRANGE_REC( 0x2070, 0x207F ), /* superscript digits and letters */
+ AF_UNIRANGE_REC( 0x2C7D, 0x2C7D ), /* modifier letter capital v */
+ AF_UNIRANGE_REC( 0xA770, 0xA770 ), /* modifier letter us */
+ AF_UNIRANGE_REC( 0xA7F8, 0xA7F9 ), /* more modifier letters */
+ AF_UNIRANGE_REC( 0xAB5C, 0xAB5F ), /* more modifier letters */
+ AF_UNIRANGE_REC( 0, 0 )
};
const AF_Script_UniRangeRec af_latp_nonbase_uniranges[] =
{
- AF_UNIRANGE_REC( 0UL, 0UL )
+ AF_UNIRANGE_REC( 0, 0 )
};
- const AF_Script_UniRangeRec af_mymr_uniranges[] =
+ const AF_Script_UniRangeRec af_mlym_uniranges[] =
{
- AF_UNIRANGE_REC( 0x1000UL, 0x109FUL ), /* Myanmar */
- AF_UNIRANGE_REC( 0xA9E0UL, 0xA9FFUL ), /* Myanmar Extended-B */
- AF_UNIRANGE_REC( 0xAA60UL, 0xAA7FUL ), /* Myanmar Extended-A */
- AF_UNIRANGE_REC( 0UL, 0UL )
+ AF_UNIRANGE_REC( 0x0D00, 0x0D7F ), /* Malayalam */
+ AF_UNIRANGE_REC( 0, 0 )
};
- const AF_Script_UniRangeRec af_mymr_nonbase_uniranges[] =
+ const AF_Script_UniRangeRec af_mlym_nonbase_uniranges[] =
{
- AF_UNIRANGE_REC( 0x102DUL, 0x1030UL ),
- AF_UNIRANGE_REC( 0x1032UL, 0x1037UL ),
- AF_UNIRANGE_REC( 0x103AUL, 0x103AUL ),
- AF_UNIRANGE_REC( 0x103DUL, 0x103EUL ),
- AF_UNIRANGE_REC( 0x1058UL, 0x1059UL ),
- AF_UNIRANGE_REC( 0x105EUL, 0x1060UL ),
- AF_UNIRANGE_REC( 0x1071UL, 0x1074UL ),
- AF_UNIRANGE_REC( 0x1082UL, 0x1082UL ),
- AF_UNIRANGE_REC( 0x1085UL, 0x1086UL ),
- AF_UNIRANGE_REC( 0x108DUL, 0x108DUL ),
- AF_UNIRANGE_REC( 0xA9E5UL, 0xA9E5UL ),
- AF_UNIRANGE_REC( 0xAA7CUL, 0xAA7CUL ),
- AF_UNIRANGE_REC( 0UL, 0UL )
+ AF_UNIRANGE_REC( 0x0D01, 0x0D01 ),
+ AF_UNIRANGE_REC( 0x0D4D, 0x0D4E ),
+ AF_UNIRANGE_REC( 0x0D62, 0x0D63 ),
+ AF_UNIRANGE_REC( 0, 0 )
};
- const AF_Script_UniRangeRec af_none_uniranges[] =
+ const AF_Script_UniRangeRec af_mymr_uniranges[] =
{
- AF_UNIRANGE_REC( 0UL, 0UL )
+ AF_UNIRANGE_REC( 0x1000, 0x109F ), /* Myanmar */
+ AF_UNIRANGE_REC( 0xA9E0, 0xA9FF ), /* Myanmar Extended-B */
+ AF_UNIRANGE_REC( 0xAA60, 0xAA7F ), /* Myanmar Extended-A */
+ AF_UNIRANGE_REC( 0, 0 )
};
- const AF_Script_UniRangeRec af_none_nonbase_uniranges[] =
+ const AF_Script_UniRangeRec af_mymr_nonbase_uniranges[] =
{
- AF_UNIRANGE_REC( 0UL, 0UL )
+ AF_UNIRANGE_REC( 0x102D, 0x1030 ),
+ AF_UNIRANGE_REC( 0x1032, 0x1037 ),
+ AF_UNIRANGE_REC( 0x103A, 0x103A ),
+ AF_UNIRANGE_REC( 0x103D, 0x103E ),
+ AF_UNIRANGE_REC( 0x1058, 0x1059 ),
+ AF_UNIRANGE_REC( 0x105E, 0x1060 ),
+ AF_UNIRANGE_REC( 0x1071, 0x1074 ),
+ AF_UNIRANGE_REC( 0x1082, 0x1082 ),
+ AF_UNIRANGE_REC( 0x1085, 0x1086 ),
+ AF_UNIRANGE_REC( 0x108D, 0x108D ),
+ AF_UNIRANGE_REC( 0xA9E5, 0xA9E5 ),
+ AF_UNIRANGE_REC( 0xAA7C, 0xAA7C ),
+ AF_UNIRANGE_REC( 0, 0 )
};
- const AF_Script_UniRangeRec af_telu_uniranges[] =
+ const AF_Script_UniRangeRec af_none_uniranges[] =
{
- AF_UNIRANGE_REC( 0x0C00UL, 0x0C7FUL ), /* Telugu */
- AF_UNIRANGE_REC( 0UL, 0UL )
+ AF_UNIRANGE_REC( 0, 0 )
};
- const AF_Script_UniRangeRec af_telu_nonbase_uniranges[] =
+ const AF_Script_UniRangeRec af_none_nonbase_uniranges[] =
{
- AF_UNIRANGE_REC( 0x0C00UL, 0x0C00UL ),
- AF_UNIRANGE_REC( 0x0C3EUL, 0x0C40UL ),
- AF_UNIRANGE_REC( 0x0C46UL, 0x0C56UL ),
- AF_UNIRANGE_REC( 0x0C62UL, 0x0C63UL ),
- AF_UNIRANGE_REC( 0UL, 0UL )
+ AF_UNIRANGE_REC( 0, 0 )
};
- const AF_Script_UniRangeRec af_thai_uniranges[] =
+ const AF_Script_UniRangeRec af_sinh_uniranges[] =
{
- AF_UNIRANGE_REC( 0x0E00UL, 0x0E7FUL ), /* Thai */
- AF_UNIRANGE_REC( 0UL, 0UL )
+ AF_UNIRANGE_REC( 0x0D80, 0x0DFF ), /* Sinhala */
+ AF_UNIRANGE_REC( 0, 0 )
};
- const AF_Script_UniRangeRec af_thai_nonbase_uniranges[] =
+ const AF_Script_UniRangeRec af_sinh_nonbase_uniranges[] =
{
- AF_UNIRANGE_REC( 0x0E31UL, 0x0E31UL ),
- AF_UNIRANGE_REC( 0x0E34UL, 0x0E3AUL ),
- AF_UNIRANGE_REC( 0x0E47UL, 0x0E4EUL ),
- AF_UNIRANGE_REC( 0UL, 0UL )
+ AF_UNIRANGE_REC( 0x0DCA, 0x0DCA ),
+ AF_UNIRANGE_REC( 0x0DD2, 0x0DD6 ),
+ AF_UNIRANGE_REC( 0, 0 )
};
-#ifdef AF_CONFIG_OPTION_INDIC
-
- const AF_Script_UniRangeRec af_gujr_uniranges[] =
+ const AF_Script_UniRangeRec af_taml_uniranges[] =
{
- AF_UNIRANGE_REC( 0x0A80UL, 0x0AFFUL ), /* Gujarati */
- AF_UNIRANGE_REC( 0UL, 0UL )
+ AF_UNIRANGE_REC( 0x0B80, 0x0BFF ), /* Tamil */
+ AF_UNIRANGE_REC( 0, 0 )
};
- const AF_Script_UniRangeRec af_gujr_nonbase_uniranges[] =
+ const AF_Script_UniRangeRec af_taml_nonbase_uniranges[] =
{
- AF_UNIRANGE_REC( 0x0A81UL, 0x0A82UL ),
- AF_UNIRANGE_REC( 0x0ABCUL, 0x0ABCUL ),
- AF_UNIRANGE_REC( 0x0AC1UL, 0x0AC8UL ),
- AF_UNIRANGE_REC( 0x0ACDUL, 0x0ACDUL ),
- AF_UNIRANGE_REC( 0x0AE2UL, 0x0AE3UL ),
- AF_UNIRANGE_REC( 0UL, 0UL )
+ AF_UNIRANGE_REC( 0x0B82, 0x0B82 ),
+ AF_UNIRANGE_REC( 0x0BC0, 0x0BC2 ),
+ AF_UNIRANGE_REC( 0x0BCD, 0x0BCD ),
+ AF_UNIRANGE_REC( 0, 0 )
};
- const AF_Script_UniRangeRec af_guru_uniranges[] =
+ const AF_Script_UniRangeRec af_telu_uniranges[] =
{
- AF_UNIRANGE_REC( 0x0A00UL, 0x0A7FUL ), /* Gurmukhi */
- AF_UNIRANGE_REC( 0UL, 0UL )
+ AF_UNIRANGE_REC( 0x0C00, 0x0C7F ), /* Telugu */
+ AF_UNIRANGE_REC( 0, 0 )
};
- const AF_Script_UniRangeRec af_guru_nonbase_uniranges[] =
+ const AF_Script_UniRangeRec af_telu_nonbase_uniranges[] =
{
- AF_UNIRANGE_REC( 0x0A01UL, 0x0A02UL ),
- AF_UNIRANGE_REC( 0x0A3CUL, 0x0A3EUL ),
- AF_UNIRANGE_REC( 0x0A41UL, 0x0A51UL ),
- AF_UNIRANGE_REC( 0x0A70UL, 0x0A71UL ),
- AF_UNIRANGE_REC( 0x0A75UL, 0x0A75UL ),
- AF_UNIRANGE_REC( 0UL, 0UL )
+ AF_UNIRANGE_REC( 0x0C00, 0x0C00 ),
+ AF_UNIRANGE_REC( 0x0C3E, 0x0C40 ),
+ AF_UNIRANGE_REC( 0x0C46, 0x0C56 ),
+ AF_UNIRANGE_REC( 0x0C62, 0x0C63 ),
+ AF_UNIRANGE_REC( 0, 0 )
};
- const AF_Script_UniRangeRec af_limb_uniranges[] =
+ const AF_Script_UniRangeRec af_thai_uniranges[] =
{
- AF_UNIRANGE_REC( 0x1900UL, 0x194FUL ), /* Limbu */
- AF_UNIRANGE_REC( 0UL, 0UL )
+ AF_UNIRANGE_REC( 0x0E00, 0x0E7F ), /* Thai */
+ AF_UNIRANGE_REC( 0, 0 )
};
- const AF_Script_UniRangeRec af_limb_nonbase_uniranges[] =
+ const AF_Script_UniRangeRec af_thai_nonbase_uniranges[] =
{
- AF_UNIRANGE_REC( 0x1920UL, 0x1922UL ),
- AF_UNIRANGE_REC( 0x1927UL, 0x1934UL ),
- AF_UNIRANGE_REC( 0x1937UL, 0x193BUL ),
- AF_UNIRANGE_REC( 0UL, 0UL )
+ AF_UNIRANGE_REC( 0x0E31, 0x0E31 ),
+ AF_UNIRANGE_REC( 0x0E34, 0x0E3A ),
+ AF_UNIRANGE_REC( 0x0E47, 0x0E4E ),
+ AF_UNIRANGE_REC( 0, 0 )
};
- const AF_Script_UniRangeRec af_mlym_uniranges[] =
+#ifdef AF_CONFIG_OPTION_INDIC
+
+ const AF_Script_UniRangeRec af_limb_uniranges[] =
{
- AF_UNIRANGE_REC( 0x0D00UL, 0x0D7FUL ), /* Malayalam */
- AF_UNIRANGE_REC( 0UL, 0UL )
+ AF_UNIRANGE_REC( 0x1900, 0x194F ), /* Limbu */
+ AF_UNIRANGE_REC( 0, 0 )
};
- const AF_Script_UniRangeRec af_mlym_nonbase_uniranges[] =
+ const AF_Script_UniRangeRec af_limb_nonbase_uniranges[] =
{
- AF_UNIRANGE_REC( 0x0D01UL, 0x0D01UL ),
- AF_UNIRANGE_REC( 0x0D4DUL, 0x0D4EUL ),
- AF_UNIRANGE_REC( 0x0D62UL, 0x0D63UL ),
- AF_UNIRANGE_REC( 0UL, 0UL )
+ AF_UNIRANGE_REC( 0x1920, 0x1922 ),
+ AF_UNIRANGE_REC( 0x1927, 0x1934 ),
+ AF_UNIRANGE_REC( 0x1937, 0x193B ),
+ AF_UNIRANGE_REC( 0, 0 )
};
const AF_Script_UniRangeRec af_orya_uniranges[] =
{
- AF_UNIRANGE_REC( 0x0B00UL, 0x0B7FUL ), /* Oriya */
- AF_UNIRANGE_REC( 0UL, 0UL )
+ AF_UNIRANGE_REC( 0x0B00, 0x0B7F ), /* Oriya */
+ AF_UNIRANGE_REC( 0, 0 )
};
const AF_Script_UniRangeRec af_orya_nonbase_uniranges[] =
{
- AF_UNIRANGE_REC( 0x0B01UL, 0x0B02UL ),
- AF_UNIRANGE_REC( 0x0B3CUL, 0x0B3CUL ),
- AF_UNIRANGE_REC( 0x0B3FUL, 0x0B3FUL ),
- AF_UNIRANGE_REC( 0x0B41UL, 0x0B44UL ),
- AF_UNIRANGE_REC( 0x0B4DUL, 0x0B56UL ),
- AF_UNIRANGE_REC( 0x0B62UL, 0x0B63UL ),
- AF_UNIRANGE_REC( 0UL, 0UL )
- };
-
-
- const AF_Script_UniRangeRec af_sinh_uniranges[] =
- {
- AF_UNIRANGE_REC( 0x0D80UL, 0x0DFFUL ), /* Sinhala */
- AF_UNIRANGE_REC( 0UL, 0UL )
- };
-
- const AF_Script_UniRangeRec af_sinh_nonbase_uniranges[] =
- {
- AF_UNIRANGE_REC( 0x0DCAUL, 0x0DCAUL ),
- AF_UNIRANGE_REC( 0x0DD2UL, 0x0DD6UL ),
- AF_UNIRANGE_REC( 0UL, 0UL )
+ AF_UNIRANGE_REC( 0x0B01, 0x0B02 ),
+ AF_UNIRANGE_REC( 0x0B3C, 0x0B3C ),
+ AF_UNIRANGE_REC( 0x0B3F, 0x0B3F ),
+ AF_UNIRANGE_REC( 0x0B41, 0x0B44 ),
+ AF_UNIRANGE_REC( 0x0B4D, 0x0B56 ),
+ AF_UNIRANGE_REC( 0x0B62, 0x0B63 ),
+ AF_UNIRANGE_REC( 0, 0 )
};
const AF_Script_UniRangeRec af_sund_uniranges[] =
{
- AF_UNIRANGE_REC( 0x1B80UL, 0x1BBFUL ), /* Sundanese */
- AF_UNIRANGE_REC( 0x1CC0UL, 0x1CCFUL ), /* Sundanese Supplement */
- AF_UNIRANGE_REC( 0UL, 0UL )
+ AF_UNIRANGE_REC( 0x1B80, 0x1BBF ), /* Sundanese */
+ AF_UNIRANGE_REC( 0x1CC0, 0x1CCF ), /* Sundanese Supplement */
+ AF_UNIRANGE_REC( 0, 0 )
};
const AF_Script_UniRangeRec af_sund_nonbase_uniranges[] =
{
- AF_UNIRANGE_REC( 0x1B80UL, 0x1B82UL ),
- AF_UNIRANGE_REC( 0x1BA1UL, 0x1BADUL ),
- AF_UNIRANGE_REC( 0UL, 0UL )
+ AF_UNIRANGE_REC( 0x1B80, 0x1B82 ),
+ AF_UNIRANGE_REC( 0x1BA1, 0x1BAD ),
+ AF_UNIRANGE_REC( 0, 0 )
};
const AF_Script_UniRangeRec af_sylo_uniranges[] =
{
- AF_UNIRANGE_REC( 0xA800UL, 0xA82FUL ), /* Syloti Nagri */
- AF_UNIRANGE_REC( 0UL, 0UL )
+ AF_UNIRANGE_REC( 0xA800, 0xA82F ), /* Syloti Nagri */
+ AF_UNIRANGE_REC( 0, 0 )
};
const AF_Script_UniRangeRec af_sylo_nonbase_uniranges[] =
{
- AF_UNIRANGE_REC( 0xA802UL, 0xA802UL ),
- AF_UNIRANGE_REC( 0xA806UL, 0xA806UL ),
- AF_UNIRANGE_REC( 0xA80BUL, 0xA80BUL ),
- AF_UNIRANGE_REC( 0xA825UL, 0xA826UL ),
- AF_UNIRANGE_REC( 0UL, 0UL )
- };
-
-
- const AF_Script_UniRangeRec af_taml_uniranges[] =
- {
- AF_UNIRANGE_REC( 0x0B80UL, 0x0BFFUL ), /* Tamil */
- AF_UNIRANGE_REC( 0UL, 0UL )
- };
-
- const AF_Script_UniRangeRec af_taml_nonbase_uniranges[] =
- {
- AF_UNIRANGE_REC( 0x0B82UL, 0x0B82UL ),
- AF_UNIRANGE_REC( 0x0BC0UL, 0x0BC2UL ),
- AF_UNIRANGE_REC( 0x0BCDUL, 0x0BCDUL ),
- AF_UNIRANGE_REC( 0UL, 0UL )
+ AF_UNIRANGE_REC( 0xA802, 0xA802 ),
+ AF_UNIRANGE_REC( 0xA806, 0xA806 ),
+ AF_UNIRANGE_REC( 0xA80B, 0xA80B ),
+ AF_UNIRANGE_REC( 0xA825, 0xA826 ),
+ AF_UNIRANGE_REC( 0, 0 )
};
const AF_Script_UniRangeRec af_tibt_uniranges[] =
{
- AF_UNIRANGE_REC( 0x0F00UL, 0x0FFFUL ), /* Tibetan */
- AF_UNIRANGE_REC( 0UL, 0UL )
+ AF_UNIRANGE_REC( 0x0F00, 0x0FFF ), /* Tibetan */
+ AF_UNIRANGE_REC( 0, 0 )
};
const AF_Script_UniRangeRec af_tibt_nonbase_uniranges[] =
{
- AF_UNIRANGE_REC( 0x0F18UL, 0x0F19UL ),
- AF_UNIRANGE_REC( 0x0F35UL, 0x0F35UL ),
- AF_UNIRANGE_REC( 0x0F37UL, 0x0F37UL ),
- AF_UNIRANGE_REC( 0x0F39UL, 0x0F39UL ),
- AF_UNIRANGE_REC( 0x0F3EUL, 0x0F3FUL ),
- AF_UNIRANGE_REC( 0x0F71UL, 0x0F7EUL ),
- AF_UNIRANGE_REC( 0x0F80UL, 0x0F84UL ),
- AF_UNIRANGE_REC( 0x0F86UL, 0x0F87UL ),
- AF_UNIRANGE_REC( 0x0F8DUL, 0x0FBCUL ),
- AF_UNIRANGE_REC( 0UL, 0UL )
+ AF_UNIRANGE_REC( 0x0F18, 0x0F19 ),
+ AF_UNIRANGE_REC( 0x0F35, 0x0F35 ),
+ AF_UNIRANGE_REC( 0x0F37, 0x0F37 ),
+ AF_UNIRANGE_REC( 0x0F39, 0x0F39 ),
+ AF_UNIRANGE_REC( 0x0F3E, 0x0F3F ),
+ AF_UNIRANGE_REC( 0x0F71, 0x0F7E ),
+ AF_UNIRANGE_REC( 0x0F80, 0x0F84 ),
+ AF_UNIRANGE_REC( 0x0F86, 0x0F87 ),
+ AF_UNIRANGE_REC( 0x0F8D, 0x0FBC ),
+ AF_UNIRANGE_REC( 0, 0 )
};
#endif /* !AF_CONFIG_OPTION_INDIC */
const AF_Script_UniRangeRec af_hani_uniranges[] =
{
- AF_UNIRANGE_REC( 0x1100UL, 0x11FFUL ), /* Hangul Jamo */
- AF_UNIRANGE_REC( 0x2E80UL, 0x2EFFUL ), /* CJK Radicals Supplement */
- AF_UNIRANGE_REC( 0x2F00UL, 0x2FDFUL ), /* Kangxi Radicals */
- AF_UNIRANGE_REC( 0x2FF0UL, 0x2FFFUL ), /* Ideographic Description Characters */
- AF_UNIRANGE_REC( 0x3000UL, 0x303FUL ), /* CJK Symbols and Punctuation */
- AF_UNIRANGE_REC( 0x3040UL, 0x309FUL ), /* Hiragana */
- AF_UNIRANGE_REC( 0x30A0UL, 0x30FFUL ), /* Katakana */
- AF_UNIRANGE_REC( 0x3100UL, 0x312FUL ), /* Bopomofo */
- AF_UNIRANGE_REC( 0x3130UL, 0x318FUL ), /* Hangul Compatibility Jamo */
- AF_UNIRANGE_REC( 0x3190UL, 0x319FUL ), /* Kanbun */
- AF_UNIRANGE_REC( 0x31A0UL, 0x31BFUL ), /* Bopomofo Extended */
- AF_UNIRANGE_REC( 0x31C0UL, 0x31EFUL ), /* CJK Strokes */
- AF_UNIRANGE_REC( 0x31F0UL, 0x31FFUL ), /* Katakana Phonetic Extensions */
- AF_UNIRANGE_REC( 0x3300UL, 0x33FFUL ), /* CJK Compatibility */
- AF_UNIRANGE_REC( 0x3400UL, 0x4DBFUL ), /* CJK Unified Ideographs Extension A */
- AF_UNIRANGE_REC( 0x4DC0UL, 0x4DFFUL ), /* Yijing Hexagram Symbols */
- AF_UNIRANGE_REC( 0x4E00UL, 0x9FFFUL ), /* CJK Unified Ideographs */
- AF_UNIRANGE_REC( 0xA960UL, 0xA97FUL ), /* Hangul Jamo Extended-A */
- AF_UNIRANGE_REC( 0xAC00UL, 0xD7AFUL ), /* Hangul Syllables */
- AF_UNIRANGE_REC( 0xD7B0UL, 0xD7FFUL ), /* Hangul Jamo Extended-B */
- AF_UNIRANGE_REC( 0xF900UL, 0xFAFFUL ), /* CJK Compatibility Ideographs */
- AF_UNIRANGE_REC( 0xFE10UL, 0xFE1FUL ), /* Vertical forms */
- AF_UNIRANGE_REC( 0xFE30UL, 0xFE4FUL ), /* CJK Compatibility Forms */
- AF_UNIRANGE_REC( 0xFF00UL, 0xFFEFUL ), /* Halfwidth and Fullwidth Forms */
- AF_UNIRANGE_REC( 0x1B000UL, 0x1B0FFUL ), /* Kana Supplement */
- AF_UNIRANGE_REC( 0x1D300UL, 0x1D35FUL ), /* Tai Xuan Hing Symbols */
- AF_UNIRANGE_REC( 0x20000UL, 0x2A6DFUL ), /* CJK Unified Ideographs Extension B */
- AF_UNIRANGE_REC( 0x2A700UL, 0x2B73FUL ), /* CJK Unified Ideographs Extension C */
- AF_UNIRANGE_REC( 0x2B740UL, 0x2B81FUL ), /* CJK Unified Ideographs Extension D */
- AF_UNIRANGE_REC( 0x2F800UL, 0x2FA1FUL ), /* CJK Compatibility Ideographs Supplement */
- AF_UNIRANGE_REC( 0UL, 0UL )
+ AF_UNIRANGE_REC( 0x1100, 0x11FF ), /* Hangul Jamo */
+ AF_UNIRANGE_REC( 0x2E80, 0x2EFF ), /* CJK Radicals Supplement */
+ AF_UNIRANGE_REC( 0x2F00, 0x2FDF ), /* Kangxi Radicals */
+ AF_UNIRANGE_REC( 0x2FF0, 0x2FFF ), /* Ideographic Description Characters */
+ AF_UNIRANGE_REC( 0x3000, 0x303F ), /* CJK Symbols and Punctuation */
+ AF_UNIRANGE_REC( 0x3040, 0x309F ), /* Hiragana */
+ AF_UNIRANGE_REC( 0x30A0, 0x30FF ), /* Katakana */
+ AF_UNIRANGE_REC( 0x3100, 0x312F ), /* Bopomofo */
+ AF_UNIRANGE_REC( 0x3130, 0x318F ), /* Hangul Compatibility Jamo */
+ AF_UNIRANGE_REC( 0x3190, 0x319F ), /* Kanbun */
+ AF_UNIRANGE_REC( 0x31A0, 0x31BF ), /* Bopomofo Extended */
+ AF_UNIRANGE_REC( 0x31C0, 0x31EF ), /* CJK Strokes */
+ AF_UNIRANGE_REC( 0x31F0, 0x31FF ), /* Katakana Phonetic Extensions */
+ AF_UNIRANGE_REC( 0x3300, 0x33FF ), /* CJK Compatibility */
+ AF_UNIRANGE_REC( 0x3400, 0x4DBF ), /* CJK Unified Ideographs Extension A */
+ AF_UNIRANGE_REC( 0x4DC0, 0x4DFF ), /* Yijing Hexagram Symbols */
+ AF_UNIRANGE_REC( 0x4E00, 0x9FFF ), /* CJK Unified Ideographs */
+ AF_UNIRANGE_REC( 0xA960, 0xA97F ), /* Hangul Jamo Extended-A */
+ AF_UNIRANGE_REC( 0xAC00, 0xD7AF ), /* Hangul Syllables */
+ AF_UNIRANGE_REC( 0xD7B0, 0xD7FF ), /* Hangul Jamo Extended-B */
+ AF_UNIRANGE_REC( 0xF900, 0xFAFF ), /* CJK Compatibility Ideographs */
+ AF_UNIRANGE_REC( 0xFE10, 0xFE1F ), /* Vertical forms */
+ AF_UNIRANGE_REC( 0xFE30, 0xFE4F ), /* CJK Compatibility Forms */
+ AF_UNIRANGE_REC( 0xFF00, 0xFFEF ), /* Halfwidth and Fullwidth Forms */
+ AF_UNIRANGE_REC( 0x1B000, 0x1B0FF ), /* Kana Supplement */
+ AF_UNIRANGE_REC( 0x1D300, 0x1D35F ), /* Tai Xuan Hing Symbols */
+ AF_UNIRANGE_REC( 0x20000, 0x2A6DF ), /* CJK Unified Ideographs Extension B */
+ AF_UNIRANGE_REC( 0x2A700, 0x2B73F ), /* CJK Unified Ideographs Extension C */
+ AF_UNIRANGE_REC( 0x2B740, 0x2B81F ), /* CJK Unified Ideographs Extension D */
+ AF_UNIRANGE_REC( 0x2F800, 0x2FA1F ), /* CJK Compatibility Ideographs Supplement */
+ AF_UNIRANGE_REC( 0, 0 )
};
const AF_Script_UniRangeRec af_hani_nonbase_uniranges[] =
{
- AF_UNIRANGE_REC( 0x302AUL, 0x302FUL ),
- AF_UNIRANGE_REC( 0x3190UL, 0x319FUL ),
- AF_UNIRANGE_REC( 0UL, 0UL )
+ AF_UNIRANGE_REC( 0x302A, 0x302F ),
+ AF_UNIRANGE_REC( 0x3190, 0x319F ),
+ AF_UNIRANGE_REC( 0, 0 )
};
#endif /* !AF_CONFIG_OPTION_CJK */
HINTING_BOTTOM_TO_TOP,
"\xD9\x84 \xD8\xAD \xD9\x80" ) /* ل ح ـ */
+ SCRIPT( armn, ARMN,
+ "Armenian",
+ HB_SCRIPT_ARMENIAN,
+ HINTING_BOTTOM_TO_TOP,
+ "\xD6\x85 \xD5\x95" ) /* օ Օ */
+
/* there are no simple forms for letters; we thus use two digit shapes */
SCRIPT( beng, BENG,
"Bengali",
HB_SCRIPT_BENGALI,
HINTING_TOP_TO_BOTTOM,
- "\xE0\xA7\xA6 \xE0\xA7\xAA" ) /* ০ ৪*/
+ "\xE0\xA7\xA6 \xE0\xA7\xAA" ) /* ০ ৪ */
+
+ SCRIPT( cher, CHER,
+ "Cherokee",
+ HB_SCRIPT_CHEROKEE,
+ HINTING_BOTTOM_TO_TOP,
+ "\xE1\x8E\xA4 \xE1\x8F\x85 \xEA\xAE\x95" ) /* Ꭴ Ꮕ ꮕ */
SCRIPT( cyrl, CYRL,
"Cyrillic",
HINTING_TOP_TO_BOTTOM,
"\xE0\xA4\xA0 \xE0\xA4\xB5 \xE0\xA4\x9F" ) /* ठ व ट */
+ SCRIPT( ethi, ETHI,
+ "Ethiopic",
+ HB_SCRIPT_ETHIOPIC,
+ HINTING_BOTTOM_TO_TOP,
+ "\xE1\x8B\x90" ) /* ዐ */
+
+ SCRIPT( geor, GEOR,
+ "Georgian (Mkhedruli)",
+ HB_SCRIPT_GEORGIAN,
+ HINTING_BOTTOM_TO_TOP,
+ "\xE1\x83\x98 \xE1\x83\x94 \xE1\x83\x90" ) /* ი ე ა */
+
+ SCRIPT( geok, GEOK,
+ "Georgian (Khutsuri)",
+ HB_SCRIPT_INVALID,
+ HINTING_BOTTOM_TO_TOP,
+ "\xE1\x82\xB6 \xE1\x82\xB1 \xE2\xB4\x99" ) /* Ⴖ Ⴑ ⴙ */
+
SCRIPT( grek, GREK,
"Greek",
HB_SCRIPT_GREEK,
HINTING_BOTTOM_TO_TOP,
"\xCE\xBF \xCE\x9F" ) /* ο Ο */
+ SCRIPT( gujr, GUJR,
+ "Gujarati",
+ HB_SCRIPT_GUJARATI,
+ HINTING_BOTTOM_TO_TOP,
+ "\xE0\xAA\x9F \xE0\xAB\xA6" ) /* ટ ૦ */
+
+ SCRIPT( guru, GURU,
+ "Gurmukhi",
+ HB_SCRIPT_GURMUKHI,
+ HINTING_TOP_TO_BOTTOM,
+ "\xE0\xA8\xA0 \xE0\xA8\xB0 \xE0\xA9\xA6" ) /* ਠ ਰ ੦ */
+
SCRIPT( hebr, HEBR,
"Hebrew",
HB_SCRIPT_HEBREW,
HINTING_BOTTOM_TO_TOP,
"\xE1\xB5\x92 \xE1\xB4\xBC \xE2\x81\xB0" ) /* ᵒ ᴼ ⁰ */
+ SCRIPT( mlym, MLYM,
+ "Malayalam",
+ HB_SCRIPT_MALAYALAM,
+ HINTING_BOTTOM_TO_TOP,
+ "\xE0\xB4\xA0 \xE0\xB4\xB1" ) /* ഠ റ */
+
SCRIPT( mymr, MYMR,
"Myanmar",
HB_SCRIPT_MYANMAR,
HINTING_BOTTOM_TO_TOP,
"" )
+ SCRIPT( sinh, SINH,
+ "Sinhala",
+ HB_SCRIPT_SINHALA,
+ HINTING_BOTTOM_TO_TOP,
+ "\xE0\xB6\xA7" ) /* ට */
+
+ /* only digit zero has a simple (round) shape in the Tamil script */
+ SCRIPT( taml, TAML,
+ "Tamil",
+ HB_SCRIPT_TAMIL,
+ HINTING_BOTTOM_TO_TOP,
+ "\xE0\xAF\xA6" ) /* ௦ */
+
/* there are no simple forms for letters; we thus use two digit shapes */
SCRIPT( telu, TELU,
"Telugu",
#ifdef AF_CONFIG_OPTION_INDIC
- SCRIPT( gujr, GUJR,
- "Gujarati",
- HB_SCRIPT_GUJARATI,
- HINTING_BOTTOM_TO_TOP,
- "o" ) /* XXX */
-
- SCRIPT( guru, GURU,
- "Gurmukhi",
- HB_SCRIPT_GURMUKHI,
- HINTING_BOTTOM_TO_TOP,
- "o" ) /* XXX */
-
SCRIPT( limb, LIMB,
"Limbu",
HB_SCRIPT_LIMBU,
HINTING_BOTTOM_TO_TOP,
"o" ) /* XXX */
- SCRIPT( mlym, MLYM,
- "Malayalam",
- HB_SCRIPT_MALAYALAM,
- HINTING_BOTTOM_TO_TOP,
- "o" ) /* XXX */
-
SCRIPT( orya, ORYA,
"Oriya",
HB_SCRIPT_ORIYA,
HINTING_BOTTOM_TO_TOP,
"o" ) /* XXX */
- SCRIPT( sinh, SINH,
- "Sinhala",
- HB_SCRIPT_SINHALA,
- HINTING_BOTTOM_TO_TOP,
- "o" ) /* XXX */
-
SCRIPT( sund, SUND,
"Sundanese",
HB_SCRIPT_SUNDANESE,
HINTING_BOTTOM_TO_TOP,
"o" ) /* XXX */
- SCRIPT( taml, TAML,
- "Tamil",
- HB_SCRIPT_TAMIL,
- HINTING_BOTTOM_TO_TOP,
- "o" ) /* XXX */
-
SCRIPT( tibt, TIBT,
"Tibetan",
HB_SCRIPT_TIBETAN,
#undef META_STYLE_LATIN
#define META_STYLE_LATIN( s, S, ds ) \
STYLE_LATIN( s, S, c2cp, C2CP, ds, \
- "petite capticals from capitals", \
+ "petite capitals from capitals", \
PETITE_CAPITALS_FROM_CAPITALS ) \
STYLE_LATIN( s, S, c2sc, C2SC, ds, \
- "small capticals from capitals", \
+ "small capitals from capitals", \
SMALL_CAPITALS_FROM_CAPITALS ) \
STYLE_LATIN( s, S, ordn, ORDN, ds, \
"ordinals", \
AF_BLUE_STRINGSET_ARAB,
AF_COVERAGE_DEFAULT )
+ STYLE( armn_dflt, ARMN_DFLT,
+ "Armenian default style",
+ AF_WRITING_SYSTEM_LATIN,
+ AF_SCRIPT_ARMN,
+ AF_BLUE_STRINGSET_ARMN,
+ AF_COVERAGE_DEFAULT )
+
STYLE( beng_dflt, BENG_DFLT,
"Bengali default style",
AF_WRITING_SYSTEM_LATIN,
AF_BLUE_STRINGSET_BENG,
AF_COVERAGE_DEFAULT )
+ STYLE( cher_dflt, CHER_DFLT,
+ "Cherokee default style",
+ AF_WRITING_SYSTEM_LATIN,
+ AF_SCRIPT_CHER,
+ AF_BLUE_STRINGSET_CHER,
+ AF_COVERAGE_DEFAULT )
+
META_STYLE_LATIN( cyrl, CYRL, "Cyrillic" )
STYLE( deva_dflt, DEVA_DFLT,
AF_BLUE_STRINGSET_DEVA,
AF_COVERAGE_DEFAULT )
+ STYLE( ethi_dflt, ETHI_DFLT,
+ "Ethiopic default style",
+ AF_WRITING_SYSTEM_LATIN,
+ AF_SCRIPT_ETHI,
+ AF_BLUE_STRINGSET_ETHI,
+ AF_COVERAGE_DEFAULT )
+
+ STYLE( geor_dflt, GEOR_DFLT,
+ "Georgian (Mkhedruli) default style",
+ AF_WRITING_SYSTEM_LATIN,
+ AF_SCRIPT_GEOR,
+ AF_BLUE_STRINGSET_GEOR,
+ AF_COVERAGE_DEFAULT )
+
+ STYLE( geok_dflt, GEOK_DFLT,
+ "Georgian (Khutsuri) default style",
+ AF_WRITING_SYSTEM_LATIN,
+ AF_SCRIPT_GEOK,
+ AF_BLUE_STRINGSET_GEOK,
+ AF_COVERAGE_DEFAULT )
+
META_STYLE_LATIN( grek, GREK, "Greek" )
+ STYLE( gujr_dflt, GUJR_DFLT,
+ "Gujarati default style",
+ AF_WRITING_SYSTEM_LATIN,
+ AF_SCRIPT_GUJR,
+ AF_BLUE_STRINGSET_GUJR,
+ AF_COVERAGE_DEFAULT )
+
+ STYLE( guru_dflt, GURU_DFLT,
+ "Gurmukhi default style",
+ AF_WRITING_SYSTEM_LATIN,
+ AF_SCRIPT_GURU,
+ AF_BLUE_STRINGSET_GURU,
+ AF_COVERAGE_DEFAULT )
+
STYLE( hebr_dflt, HEBR_DFLT,
"Hebrew default style",
AF_WRITING_SYSTEM_LATIN,
AF_COVERAGE_DEFAULT )
#endif
+ STYLE( mlym_dflt, MLYM_DFLT,
+ "Malayalam default style",
+ AF_WRITING_SYSTEM_LATIN,
+ AF_SCRIPT_MLYM,
+ AF_BLUE_STRINGSET_MLYM,
+ AF_COVERAGE_DEFAULT )
+
STYLE( mymr_dflt, MYMR_DFLT,
"Myanmar default style",
AF_WRITING_SYSTEM_LATIN,
"no style",
AF_WRITING_SYSTEM_DUMMY,
AF_SCRIPT_NONE,
- (AF_Blue_Stringset)0,
+ AF_BLUE_STRINGSET_NONE,
+ AF_COVERAGE_DEFAULT )
+
+ STYLE( sinh_dflt, SINH_DFLT,
+ "Sinhala default style",
+ AF_WRITING_SYSTEM_LATIN,
+ AF_SCRIPT_SINH,
+ AF_BLUE_STRINGSET_SINH,
+ AF_COVERAGE_DEFAULT )
+
+ STYLE( taml_dflt, TAML_DFLT,
+ "Tamil default style",
+ AF_WRITING_SYSTEM_LATIN,
+ AF_SCRIPT_TAML,
+ AF_BLUE_STRINGSET_TAML,
AF_COVERAGE_DEFAULT )
STYLE( telu_dflt, TELU_DFLT,
(AF_Blue_Stringset)0, \
AF_COVERAGE_DEFAULT )
- STYLE_DEFAULT_INDIC( gujr, GUJR, "Gujarati" )
- STYLE_DEFAULT_INDIC( guru, GURU, "Gurmukhi" )
STYLE_DEFAULT_INDIC( limb, LIMB, "Limbu" )
- STYLE_DEFAULT_INDIC( mlym, MLYM, "Malayalam" )
STYLE_DEFAULT_INDIC( orya, ORYA, "Oriya" )
- STYLE_DEFAULT_INDIC( sinh, SINH, "Sinhala" )
STYLE_DEFAULT_INDIC( sund, SUND, "Sundanese" )
STYLE_DEFAULT_INDIC( sylo, SYLO, "Syloti Nagri" )
- STYLE_DEFAULT_INDIC( taml, TAML, "Tamil" )
STYLE_DEFAULT_INDIC( tibt, TIBT, "Tibetan" )
#endif /* AF_CONFIG_OPTION_INDIC */
* Its main feature is the ability to differentiate between different
* writing systems and scripts in order to apply specific rules.
*
- * The code has also been compartmentized into several entities that
+ * The code has also been compartmentalized into several entities that
* should make algorithmic experimentation easier than with the old
* code.
*
/* scale from 26.6 to 16.16 */
padvances[nn] = ( flags & FT_LOAD_VERTICAL_LAYOUT )
- ? face->glyph->advance.y << 10
- : face->glyph->advance.x << 10;
+ ? face->glyph->advance.y * 1024
+ : face->glyph->advance.x * 1024;
}
return error;
}
/* for each row */
- for ( y = 0; y < bitmap->rows ; y++ )
+ for ( y = 0; y < bitmap->rows; y++ )
{
/*
* Horizontally:
if ( !fontName || !face_index )
- return FT_THROW( Invalid_Argument) ;
+ return FT_THROW( Invalid_Argument);
err = FT_GetFileRef_From_Mac_ATS_Name( fontName, &ref, face_index );
if ( err )
/* Type 1 and CID-keyed font drivers should recognize sfnt-wrapped */
/* format too. Here, since we can't expect that the TrueType font */
- /* driver is loaded unconditially, we must parse the font by */
+ /* driver is loaded unconditionally, we must parse the font by */
/* ourselves. We are only interested in the name of the table and */
/* the offset. */
if ( face_index >= 0 && pstable_index == face_index )
return FT_Err_Ok;
}
+
return FT_THROW( Table_Missing );
}
if ( error )
goto Exit;
+ if ( offset > stream->size )
+ {
+ FT_TRACE2(( "open_face_PS_from_sfnt_stream: invalid table offset\n" ));
+ error = FT_THROW( Invalid_Table );
+ goto Exit;
+ }
+ else if ( length > stream->size - offset )
+ {
+ FT_TRACE2(( "open_face_PS_from_sfnt_stream: invalid table length\n" ));
+ error = FT_THROW( Invalid_Table );
+ goto Exit;
+ }
+
error = FT_Stream_Seek( stream, pos + offset );
if ( error )
goto Exit;
goto Exit;
error = FT_Stream_Read( stream, (FT_Byte *)sfnt_ps, length );
- if ( error ) {
+ if ( error )
+ {
FT_FREE( sfnt_ps );
goto Exit;
}
FT_Long face_index_in_resource = 0;
- if ( face_index == -1 )
- face_index = 0;
+ if ( face_index < 0 )
+ face_index = -face_index - 1;
if ( face_index >= resource_cnt )
return FT_THROW( Cannot_Open_Resource );
{
FT_Error error;
FT_Memory memory;
- FT_Module module;
+ FT_Module module = NULL;
FT_UInt nn;
static
- const FT_Outline null_outline = { 0, 0, 0, 0, 0, 0 };
+ const FT_Outline null_outline = { 0, 0, NULL, NULL, NULL, 0 };
/* documentation is in ftoutln.h */
errors[i] = FT_Err_Ok;
if ( errors[i] )
- continue ;
+ continue;
errors[i] = (FT_RACCESS_GUESS_TABLE_GET[i].func)( library,
stream, base_name,
case ft_frame_short_be:
case ft_frame_ushort_be: /* read a 2-byte big-endian short */
- value = FT_NEXT_USHORT( cursor) ;
+ value = FT_NEXT_USHORT( cursor );
sign_shift = 16;
break;
(a) += (b);
/*
- * SET reads 4 input bytes in little-endian byte order and stores them
- * in a properly aligned word in host byte order.
+ * SET reads 4 input bytes in little-endian byte order and stores them in a
+ * properly aligned word in host byte order.
*
- * The check for little-endian architectures that tolerate unaligned
- * memory accesses is just an optimization. Nothing will break if it
- * doesn't work.
+ * The check for little-endian architectures that tolerate unaligned memory
+ * accesses is just an optimization. Nothing will break if it fails to detect
+ * a suitable architecture.
+ *
+ * Unfortunately, this optimization may be a C strict aliasing rules violation
+ * if the caller's data buffer has effective type that cannot be aliased by
+ * MD5_u32plus. In practice, this problem may occur if these MD5 routines are
+ * inlined into a calling function, or with future and dangerously advanced
+ * link-time optimizations. For the time being, keeping these MD5 routines in
+ * their own translation unit avoids the problem.
*/
#if defined(__i386__) || defined(__x86_64__) || defined(__vax__)
#define SET(n) \
#endif
/*
- * This processes one or more 64-byte data blocks, but does NOT update
- * the bit counters. There are no alignment requirements.
+ * This processes one or more 64-byte data blocks, but does NOT update the bit
+ * counters. There are no alignment requirements.
*/
static const void *body(MD5_CTX *ctx, const void *data, unsigned long size)
{
memcpy(ctx->buffer, data, size);
}
+#define OUT(dst, src) \
+ (dst)[0] = (unsigned char)(src); \
+ (dst)[1] = (unsigned char)((src) >> 8); \
+ (dst)[2] = (unsigned char)((src) >> 16); \
+ (dst)[3] = (unsigned char)((src) >> 24);
+
void MD5_Final(unsigned char *result, MD5_CTX *ctx)
{
unsigned long used, available;
memset(&ctx->buffer[used], 0, available - 8);
ctx->lo <<= 3;
- ctx->buffer[56] = ctx->lo;
- ctx->buffer[57] = ctx->lo >> 8;
- ctx->buffer[58] = ctx->lo >> 16;
- ctx->buffer[59] = ctx->lo >> 24;
- ctx->buffer[60] = ctx->hi;
- ctx->buffer[61] = ctx->hi >> 8;
- ctx->buffer[62] = ctx->hi >> 16;
- ctx->buffer[63] = ctx->hi >> 24;
+ OUT(&ctx->buffer[56], ctx->lo)
+ OUT(&ctx->buffer[60], ctx->hi)
body(ctx, ctx->buffer, 64);
- result[0] = ctx->a;
- result[1] = ctx->a >> 8;
- result[2] = ctx->a >> 16;
- result[3] = ctx->a >> 24;
- result[4] = ctx->b;
- result[5] = ctx->b >> 8;
- result[6] = ctx->b >> 16;
- result[7] = ctx->b >> 24;
- result[8] = ctx->c;
- result[9] = ctx->c >> 8;
- result[10] = ctx->c >> 16;
- result[11] = ctx->c >> 24;
- result[12] = ctx->d;
- result[13] = ctx->d >> 8;
- result[14] = ctx->d >> 16;
- result[15] = ctx->d >> 24;
+ OUT(&result[0], ctx->a)
+ OUT(&result[4], ctx->b)
+ OUT(&result[8], ctx->c)
+ OUT(&result[12], ctx->d)
memset(ctx, 0, sizeof(*ctx));
}
propid = ft_hash_str_lookup( name, &(font->proptbl) );
}
- /* Allocate another property if this is overflow. */
+ /* Allocate another property if this is overflowing. */
if ( font->props_used == font->props_size )
{
if ( font->props_size == 0 )
error = _bdf_list_split( &p->list, (char *)" +", line, linelen );
if ( error )
goto Exit;
+
/* at this point, `p->font' can't be NULL */
p->cnt = p->font->props_size = _bdf_atoul( p->list.field[1] );
+ /* We need at least 4 bytes per property. */
+ if ( p->cnt > p->size / 4 )
+ {
+ p->font->props_size = 0;
+
+ FT_ERROR(( "_bdf_parse_glyphs: " ERRMSG5, lineno, "STARTPROPERTIES" ));
+ error = FT_THROW( Invalid_Argument );
+ goto Exit;
+ }
if ( FT_NEW_ARRAY( p->font->props, p->cnt ) )
{
break; \
\
_try_done = FTC_Manager_FlushN( _try_manager, _try_count ); \
- if ( _try_done > 0 && ( list_changed ) ) \
+ if ( _try_done > 0 && ( list_changed != NULL ) ) \
*(FT_Bool*)( list_changed ) = TRUE; \
\
if ( _try_done == 0 ) \
return 0;
}
- if ( !face_id )
- return 0;
-
query.face_id = face_id;
query.cmap_index = (FT_UInt)cmap_index;
query.char_code = char_code;
FTC_MruNode mrunode;
- if ( !aface || !face_id )
+ if ( !aface )
return FT_THROW( Invalid_Argument );
*aface = NULL;
FT_UInt nn;
- if ( !manager || !face_id )
+ if ( !manager )
return;
/* this will remove all FTC_SizeNode that correspond to
} \
_node = _node->next; \
\
- } while ( _node != _first) ; \
+ } while ( _node != _first); \
} \
\
error = FTC_MruList_New( (list), (key), (FTC_MruNode*)(void*)&(node) ); \
* Upon a function call if the error code is anything other than
* `FT_Err_Ok', which is guaranteed to be zero, we
* will return without altering that error. This will allow the
- * error to propogate and be handled at the appropriate location in
+ * error to propagate and be handled at the appropriate location in
* the code.
*
* This allows a style of code where the error code is initialized
/* character space miter limit threshold */
CF2_Fixed miterLimit;
- /* vertical/horzizontal snap distance in character space */
+ /* vertical/horizontal snap distance in character space */
CF2_Fixed snapThreshold;
FT_Vector offsetStart0; /* first and second points of first */
FT_UInt* hinting_engine = (FT_UInt*)value;
-#ifndef CFF_CONFIG_OPTION_OLD_ENGINE
- if ( *hinting_engine != FT_CFF_HINTING_ADOBE )
- error = FT_ERR( Unimplemented_Feature );
- else
+ if ( *hinting_engine == FT_CFF_HINTING_ADOBE
+#ifdef CFF_CONFIG_OPTION_OLD_ENGINE
+ || *hinting_engine == FT_CFF_HINTING_FREETYPE
#endif
+ )
driver->hinting_engine = *hinting_engine;
+ else
+ error = FT_ERR( Unimplemented_Feature );
return error;
}
#endif /* FT_CONFIG_OPTION_INCREMENTAL */
{
- CFF_Font cff = (CFF_Font)(face->extra.data);
+ CFF_Font cff = (CFF_Font)(face->extra.data);
return cff_index_access_element( &cff->charstrings_index, glyph_index,
/* the seac operator must not be nested */
decoder->seac = TRUE;
error = cff_decoder_parse_charstrings( decoder, charstring,
- charstring_len );
+ charstring_len, 0 );
decoder->seac = FALSE;
cff_free_glyph_data( face, &charstring, charstring_len );
/* the seac operator must not be nested */
decoder->seac = TRUE;
error = cff_decoder_parse_charstrings( decoder, charstring,
- charstring_len );
+ charstring_len, 0 );
decoder->seac = FALSE;
cff_free_glyph_data( face, &charstring, charstring_len );
/* */
/* charstring_len :: The length in bytes of the charstring stream. */
/* */
+ /* in_dict :: Set to 1 if function is called from top or */
+ /* private DICT (needed for Multiple Master CFFs). */
+ /* */
/* <Return> */
/* FreeType error code. 0 means success. */
/* */
FT_LOCAL_DEF( FT_Error )
cff_decoder_parse_charstrings( CFF_Decoder* decoder,
FT_Byte* charstring_base,
- FT_ULong charstring_len )
+ FT_ULong charstring_len,
+ FT_Bool in_dict )
{
FT_Error error;
CFF_Decoder_Zone* zone;
FT_Fixed* stack;
FT_Int charstring_type =
decoder->cff->top_font.font_dict.charstring_type;
+ FT_UShort num_designs =
+ decoder->cff->top_font.font_dict.num_designs;
+ FT_UShort num_axes =
+ decoder->cff->top_font.font_dict.num_axes;
T2_Hints_Funcs hinter;
if ( op == cff_op_unknown )
continue;
+ /* in Multiple Master CFFs, T2 charstrings can appear in */
+ /* dictionaries, but some operators are prohibited */
+ if ( in_dict )
+ {
+ switch ( op )
+ {
+ case cff_op_hstem:
+ case cff_op_vstem:
+ case cff_op_vmoveto:
+ case cff_op_rlineto:
+ case cff_op_hlineto:
+ case cff_op_vlineto:
+ case cff_op_rrcurveto:
+ case cff_op_hstemhm:
+ case cff_op_hintmask:
+ case cff_op_cntrmask:
+ case cff_op_rmoveto:
+ case cff_op_hmoveto:
+ case cff_op_vstemhm:
+ case cff_op_rcurveline:
+ case cff_op_rlinecurve:
+ case cff_op_vvcurveto:
+ case cff_op_hhcurveto:
+ case cff_op_vhcurveto:
+ case cff_op_hvcurveto:
+ case cff_op_hflex:
+ case cff_op_flex:
+ case cff_op_hflex1:
+ case cff_op_flex1:
+ case cff_op_callsubr:
+ case cff_op_callgsubr:
+ goto MM_Error;
+
+ default:
+ break;
+ }
+ }
+
/* check arguments */
req_args = cff_argument_counts[op];
if ( req_args & CFF_COUNT_CHECK_WIDTH )
case cff_op_endchar:
/* If there is a width specified for endchar, we either have */
/* 1 argument or 5 arguments. We like to argue. */
- set_width_ok = ( num_args == 5 ) || ( num_args == 1 );
+ set_width_ok = in_dict
+ ? 0
+ : ( ( num_args == 5 ) || ( num_args == 1 ) );
break;
default:
return error;
case cff_op_endchar:
+ /* in dictionaries, `endchar' simply indicates end of data */
+ if ( in_dict )
+ return error;
+
FT_TRACE4(( " endchar\n" ));
/* We are going to emulate the seac operator. */
FT_TRACE4(( " put\n" ));
+ /* the Type2 specification before version 16-March-2000 */
+ /* didn't give a hard-coded size limit of the temporary */
+ /* storage array; instead, an argument of the */
+ /* `MultipleMaster' operator set the size */
if ( idx >= 0 && idx < CFF_MAX_TRANS_ELEMENTS )
decoder->buildchar[idx] = val;
}
case cff_op_store:
/* this operator was removed from the Type2 specification */
/* in version 16-March-2000 */
- FT_TRACE4(( " store\n"));
- goto Unimplemented;
+ /* since we currently don't handle interpolation of multiple */
+ /* master fonts, this is a no-op */
+ FT_TRACE4(( " store\n"));
+ break;
case cff_op_load:
/* this operator was removed from the Type2 specification */
/* in version 16-March-2000 */
- FT_TRACE4(( " load\n" ));
+ {
+ FT_Int reg_idx = (FT_Int)args[0];
+ FT_Int idx = (FT_Int)args[1];
+ FT_Int count = (FT_Int)args[2];
+
+
+ FT_TRACE4(( " load\n" ));
+
+ /* since we currently don't handle interpolation of multiple */
+ /* master fonts, we store a vector [1 0 0 ...] in the */
+ /* temporary storage array regardless of the Registry index */
+ if ( reg_idx >= 0 && reg_idx <= 2 &&
+ idx >= 0 && idx < CFF_MAX_TRANS_ELEMENTS &&
+ count >= 0 && count <= num_axes )
+ {
+ FT_Int end, i;
+
- goto Unimplemented;
+ end = FT_MIN( idx + count, CFF_MAX_TRANS_ELEMENTS );
+
+ if ( idx < end )
+ decoder->buildchar[idx] = 1 << 16;
+
+ for ( i = idx + 1; i < end; i++ )
+ decoder->buildchar[i] = 0;
+ }
+ }
+ break;
case cff_op_blend:
/* this operator was removed from the Type2 specification */
/* in version 16-March-2000 */
- FT_TRACE4(( " blend\n" ));
+ {
+ FT_Int num_results = (FT_Int)( args[0] >> 16 );
+
+
+ FT_TRACE4(( " blend\n" ));
+
+ if ( num_results < 0 )
+ goto Syntax_Error;
+
+ if ( num_results * (FT_Int)num_designs > num_args )
+ goto Stack_Underflow;
- goto Unimplemented;
+ /* since we currently don't handle interpolation of multiple */
+ /* master fonts, return the `num_results' values of the */
+ /* first master */
+ args -= num_results * ( num_designs - 1 );
+ num_args -= num_results * ( num_designs - 1 );
+ }
+ break;
case cff_op_dotsection:
/* this operator is deprecated and ignored by the parser */
break;
default:
- Unimplemented:
FT_ERROR(( "Unimplemented opcode: %d", ip[-1] ));
if ( ip[-1] == 12 )
Fail:
return error;
+ MM_Error:
+ FT_TRACE4(( "cff_decoder_parse_charstrings:"
+ " invalid opcode found in top DICT charstring\n"));
+ return FT_THROW( Invalid_File_Format );
+
Syntax_Error:
FT_TRACE4(( "cff_decoder_parse_charstrings: syntax error\n" ));
return FT_THROW( Invalid_File_Format );
if ( !error )
error = cff_decoder_parse_charstrings( &decoder,
charstring,
- charstring_len );
+ charstring_len,
+ 0 );
cff_free_glyph_data( face, &charstring, &charstring_len );
}
if ( driver->hinting_engine == FT_CFF_HINTING_FREETYPE )
error = cff_decoder_parse_charstrings( &decoder,
charstring,
- charstring_len );
+ charstring_len,
+ 0 );
else
#endif
{
FT_LOCAL( FT_Error )
cff_decoder_parse_charstrings( CFF_Decoder* decoder,
FT_Byte* charstring_base,
- FT_ULong charstring_len );
+ FT_ULong charstring_len,
+ FT_Bool in_dict );
#endif
FT_LOCAL( FT_Error )
static FT_Error
cff_index_get_pointers( CFF_Index idx,
FT_Byte*** table,
- FT_Byte** pool )
+ FT_Byte** pool,
+ FT_ULong* pool_size )
{
FT_Error error = FT_Err_Ok;
FT_Memory memory = idx->stream->memory;
FT_Byte** t = NULL;
FT_Byte* new_bytes = NULL;
+ FT_ULong new_size;
*table = NULL;
goto Exit;
}
- if ( idx->count > 0 &&
- !FT_NEW_ARRAY( t, idx->count + 1 ) &&
- ( !pool || !FT_ALLOC( new_bytes,
- idx->data_size + idx->count ) ) )
+ new_size = idx->data_size + idx->count;
+
+ if ( idx->count > 0 &&
+ !FT_NEW_ARRAY( t, idx->count + 1 ) &&
+ ( !pool || !FT_ALLOC( new_bytes, new_size ) ) )
{
FT_ULong n, cur_offset;
FT_ULong extra = 0;
if ( pool )
*pool = new_bytes;
+ if ( pool_size )
+ *pool_size = new_size;
}
Exit:
/* When multiple GIDs map to the same CID, we choose the lowest */
/* GID. This is not described in any spec, but it matches the */
/* behaviour of recent Acroread versions. */
- for ( j = (FT_Long)num_glyphs - 1; j >= 0 ; j-- )
+ for ( j = (FT_Long)num_glyphs - 1; j >= 0; j-- )
charset->cids[charset->sids[j]] = (FT_UShort)j;
charset->max_cid = max_cid;
FT_UShort glyph_sid;
- /* If the the offset is greater than 2, we have to parse the */
- /* charset table. */
+ /* If the offset is greater than 2, we have to parse the charset */
+ /* table. */
if ( offset > 2 )
{
FT_UInt j;
CFF_Private priv = &font->private_dict;
- cff_parser_init( &parser, CFF_CODE_TOPDICT, &font->font_dict, library );
+ cff_parser_init( &parser,
+ CFF_CODE_TOPDICT,
+ &font->font_dict,
+ library,
+ 0,
+ 0 );
/* set defaults */
FT_MEM_ZERO( top, sizeof ( *top ) );
priv->expansion_factor = (FT_Fixed)( 0.06 * 0x10000L );
priv->blue_scale = (FT_Fixed)( 0.039625 * 0x10000L * 1000 );
- cff_parser_init( &parser, CFF_CODE_PRIVATE, priv, library );
+ cff_parser_init( &parser,
+ CFF_CODE_PRIVATE,
+ priv,
+ library,
+ top->num_designs,
+ top->num_axes );
if ( FT_STREAM_SEEK( base_offset + font->font_dict.private_offset ) ||
FT_FRAME_ENTER( font->font_dict.private_size ) )
goto Exit;
error = cff_index_get_pointers( &font->local_subrs_index,
- &font->local_subrs, NULL );
+ &font->local_subrs, NULL, NULL );
if ( error )
goto Exit;
}
/* read the name, top dict, string and global subrs index */
if ( FT_SET_ERROR( cff_index_init( &font->name_index,
- stream, 0 ) ) ||
+ stream, 0 ) ) ||
FT_SET_ERROR( cff_index_init( &font->font_dict_index,
- stream, 0 ) ) ||
+ stream, 0 ) ) ||
FT_SET_ERROR( cff_index_init( &string_index,
- stream, 1 ) ) ||
+ stream, 1 ) ) ||
FT_SET_ERROR( cff_index_init( &font->global_subrs_index,
- stream, 1 ) ) ||
+ stream, 1 ) ) ||
FT_SET_ERROR( cff_index_get_pointers( &string_index,
&font->strings,
- &font->string_pool ) ) )
+ &font->string_pool,
+ &font->string_pool_size ) ) )
goto Exit;
font->num_strings = string_index.count;
font->num_glyphs = font->charstrings_index.count;
error = cff_index_get_pointers( &font->global_subrs_index,
- &font->global_subrs, NULL );
+ &font->global_subrs, NULL, NULL );
if ( error )
goto Exit;
FT_TRACE4(( "SIDs\n" ));
/* dump string index, including default strings for convenience */
- for ( idx = 0; idx < cff->num_strings + 390; idx++ )
+ for ( idx = 0; idx <= 390; idx++ )
{
s = cff_index_get_sid_string( cff, idx );
if ( s )
- FT_TRACE4((" %5d %s\n", idx, s ));
+ FT_TRACE4(( " %5d %s\n", idx, s ));
+ }
+
+ /* In Multiple Master CFFs, two SIDs hold the Normalize Design */
+ /* Vector (NDV) and Convert Design Vector (CDV) charstrings, */
+ /* which may contain NULL bytes in the middle of the data, too. */
+ /* We thus access `cff->strings' directly. */
+ for ( idx = 1; idx < cff->num_strings; idx++ )
+ {
+ FT_Byte* s1 = cff->strings[idx - 1];
+ FT_Byte* s2 = cff->strings[idx];
+ FT_PtrDist s1len = s2 - s1 - 1; /* without the final NULL byte */
+ FT_PtrDist l;
+
+
+ FT_TRACE4(( " %5d ", idx + 390 ));
+ for ( l = 0; l < s1len; l++ )
+ FT_TRACE4(( "%c", s1[l] ));
+ FT_TRACE4(( "\n" ));
+ }
+
+ /* print last element */
+ if ( cff->num_strings )
+ {
+ FT_Byte* s1 = cff->strings[cff->num_strings - 1];
+ FT_Byte* s2 = cff->string_pool + cff->string_pool_size;
+ FT_PtrDist s1len = s2 - s1 - 1;
+ FT_PtrDist l;
+
+
+ FT_TRACE4(( " %5d ", cff->num_strings + 390 ));
+ for ( l = 0; l < s1len; l++ )
+ FT_TRACE4(( "%c", s1[l] ));
+ FT_TRACE4(( "\n" ));
}
}
#endif /* FT_DEBUG_LEVEL_TRACE */
if ( !dict->has_font_matrix )
dict->units_per_em = pure_cff ? 1000 : face->root.units_per_EM;
- /* Normalize the font matrix so that `matrix->yy' is 1; the */
- /* scaling is done with `units_per_em' then (at this point, */
- /* it already contains the scaling factor, but without */
- /* normalization of the matrix). */
+ /* Normalize the font matrix so that `matrix->yy' is 1; if */
+ /* it is zero, we use `matrix->yx' instead. The scaling is */
+ /* done with `units_per_em' then (at this point, it already */
+ /* contains the scaling factor, but without normalization */
+ /* of the matrix). */
/* */
/* Note that the offsets must be expressed in integer font */
/* units. */
FT_Matrix* matrix = &dict->font_matrix;
FT_Vector* offset = &dict->font_offset;
FT_ULong* upm = &dict->units_per_em;
- FT_Fixed temp = FT_ABS( matrix->yy );
+ FT_Fixed temp;
+ temp = matrix->yy ? FT_ABS( matrix->yy )
+ : FT_ABS( matrix->yx );
+
if ( temp != 0x10000L )
{
*upm = (FT_ULong)FT_DivFix( (FT_Long)*upm, temp );
matrix = &sub->font_matrix;
offset = &sub->font_offset;
upm = &sub->units_per_em;
- temp = FT_ABS( matrix->yy );
+
+ temp = matrix->yy ? FT_ABS( matrix->yy )
+ : FT_ABS( matrix->yx );
+
if ( temp != 0x10000L )
{
#include "cfferrs.h"
#include "cffpic.h"
+#include "cffgload.h"
/*************************************************************************/
cff_parser_init( CFF_Parser parser,
FT_UInt code,
void* object,
- FT_Library library)
+ FT_Library library,
+ FT_UShort num_designs,
+ FT_UShort num_axes )
{
FT_MEM_ZERO( parser, sizeof ( *parser ) );
parser->object_code = code;
parser->object = object;
parser->library = library;
+ parser->num_designs = num_designs;
+ parser->num_axes = num_axes;
}
if ( parser->top >= parser->stack + 6 )
{
- FT_Long scaling;
+ FT_Fixed values[6];
+ FT_Long scalings[6];
+
+ FT_Long min_scaling, max_scaling;
+ int i;
error = FT_Err_Ok;
/* We expect a well-formed font matrix, this is, the matrix elements */
/* `xx' and `yy' are of approximately the same magnitude. To avoid */
- /* loss of precision, we use the magnitude of element `xx' to scale */
- /* all other elements. The scaling factor is then contained in the */
- /* `units_per_em' value. */
+ /* loss of precision, we use the magnitude of the largest matrix */
+ /* element to scale all other elements. The scaling factor is then */
+ /* contained in the `units_per_em' value. */
- matrix->xx = cff_parse_fixed_dynamic( data++, &scaling );
+ max_scaling = FT_LONG_MIN;
+ min_scaling = FT_LONG_MAX;
- scaling = -scaling;
+ for ( i = 0; i < 6; i++ )
+ {
+ values[i] = cff_parse_fixed_dynamic( data++, &scalings[i] );
+ if ( values[i] )
+ {
+ if ( scalings[i] > max_scaling )
+ max_scaling = scalings[i];
+ if ( scalings[i] < min_scaling )
+ min_scaling = scalings[i];
+ }
+ }
- if ( scaling < 0 || scaling > 9 )
+ if ( max_scaling < -9 ||
+ max_scaling > 0 ||
+ ( max_scaling - min_scaling ) < 0 ||
+ ( max_scaling - min_scaling ) > 9 )
{
/* Return default matrix in case of unlikely values. */
FT_TRACE1(( "cff_parse_font_matrix:"
- " strange scaling value for xx element (%d),\n"
+ " strange scaling values (minimum %d, maximum %d),\n"
" "
- " using default matrix\n", scaling ));
+ " using default matrix\n", min_scaling, max_scaling ));
matrix->xx = 0x10000L;
matrix->yx = 0;
goto Exit;
}
- matrix->yx = cff_parse_fixed_scaled( data++, scaling );
- matrix->xy = cff_parse_fixed_scaled( data++, scaling );
- matrix->yy = cff_parse_fixed_scaled( data++, scaling );
- offset->x = cff_parse_fixed_scaled( data++, scaling );
- offset->y = cff_parse_fixed_scaled( data, scaling );
+ for ( i = 0; i < 6; i++ )
+ {
+ FT_Fixed value = values[i];
+ FT_Long divisor, half_divisor;
+
+
+ if ( !value )
+ continue;
+
+ divisor = power_tens[max_scaling - scalings[i]];
+ half_divisor = divisor >> 1;
+
+ if ( value < 0 )
+ {
+ if ( FT_LONG_MIN + half_divisor < value )
+ values[i] = ( value - half_divisor ) / divisor;
+ else
+ values[i] = FT_LONG_MIN / divisor;
+ }
+ else
+ {
+ if ( FT_LONG_MAX - half_divisor > value )
+ values[i] = ( value + half_divisor ) / divisor;
+ else
+ values[i] = FT_LONG_MAX / divisor;
+ }
+ }
+
+ matrix->xx = values[0];
+ matrix->yx = values[1];
+ matrix->xy = values[2];
+ matrix->yy = values[3];
+ offset->x = values[4];
+ offset->y = values[5];
- *upm = (FT_ULong)power_tens[scaling];
+ *upm = (FT_ULong)power_tens[-max_scaling];
FT_TRACE4(( " [%f %f %f %f %f %f]\n",
(double)matrix->xx / *upm / 65536,
}
+ /* The `MultipleMaster' operator comes before any */
+ /* top DICT operators that contain T2 charstrings. */
+
+ static FT_Error
+ cff_parse_multiple_master( CFF_Parser parser )
+ {
+ CFF_FontRecDict dict = (CFF_FontRecDict)parser->object;
+ FT_Error error;
+
+
+#ifdef FT_DEBUG_LEVEL_TRACE
+ /* beautify tracing message */
+ if ( ft_trace_levels[FT_COMPONENT] < 4 )
+ FT_TRACE1(( "Multiple Master CFFs not supported yet,"
+ " handling first master design only\n" ));
+ else
+ FT_TRACE1(( " (not supported yet,"
+ " handling first master design only)\n" ));
+#endif
+
+ error = FT_ERR( Stack_Underflow );
+
+ /* currently, we handle only the first argument */
+ if ( parser->top >= parser->stack + 5 )
+ {
+ FT_Long num_designs = cff_parse_num( parser->stack );
+
+
+ if ( num_designs > 16 || num_designs < 2 )
+ {
+ FT_ERROR(( "cff_parse_multiple_master:"
+ " Invalid number of designs\n" ));
+ error = FT_THROW( Invalid_File_Format );
+ }
+ else
+ {
+ dict->num_designs = (FT_UShort)num_designs;
+ dict->num_axes = (FT_UShort)( parser->top - parser->stack - 4 );
+
+ parser->num_designs = dict->num_designs;
+ parser->num_axes = dict->num_axes;
+
+ error = FT_Err_Ok;
+ }
+ }
+
+ return error;
+ }
+
+
static FT_Error
cff_parse_cid_ros( CFF_Parser parser )
{
if ( parser->top - parser->stack >= CFF_MAX_STACK_DEPTH )
goto Stack_Overflow;
- *parser->top ++ = p;
+ *parser->top++ = p;
/* now, skip it */
if ( v == 30 )
else if ( v > 246 )
p += 1;
}
+#ifdef CFF_CONFIG_OPTION_OLD_ENGINE
+ else if ( v == 31 )
+ {
+ /* a Type 2 charstring */
+
+ CFF_Decoder decoder;
+ CFF_FontRec cff_rec;
+ FT_Byte* charstring_base;
+ FT_ULong charstring_len;
+
+ FT_Fixed* stack;
+ FT_Byte* q;
+
+
+ charstring_base = ++p;
+
+ /* search `endchar' operator */
+ for (;;)
+ {
+ if ( p >= limit )
+ goto Exit;
+ if ( *p == 14 )
+ break;
+ p++;
+ }
+
+ charstring_len = (FT_ULong)( p - charstring_base ) + 1;
+
+ /* construct CFF_Decoder object */
+ FT_MEM_ZERO( &decoder, sizeof ( decoder ) );
+ FT_MEM_ZERO( &cff_rec, sizeof ( cff_rec ) );
+
+ cff_rec.top_font.font_dict.num_designs = parser->num_designs;
+ cff_rec.top_font.font_dict.num_axes = parser->num_axes;
+ decoder.cff = &cff_rec;
+
+ error = cff_decoder_parse_charstrings( &decoder,
+ charstring_base,
+ charstring_len,
+ 1 );
+
+ /* Now copy the stack data in the temporary decoder object, */
+ /* converting it back to charstring number representations */
+ /* (this is ugly, I know). */
+ /* */
+ /* We overwrite the original top DICT charstring under the */
+ /* assumption that the charstring representation of the result */
+ /* of `cff_decoder_parse_charstrings' is shorter, which should */
+ /* be always true. */
+
+ q = charstring_base - 1;
+ stack = decoder.stack;
+
+ while ( stack < decoder.top )
+ {
+ FT_ULong num;
+ FT_Bool neg;
+
+
+ if ( parser->top - parser->stack >= CFF_MAX_STACK_DEPTH )
+ goto Stack_Overflow;
+
+ *parser->top++ = q;
+
+ if ( *stack < 0 )
+ {
+ num = (FT_ULong)-*stack;
+ neg = 1;
+ }
+ else
+ {
+ num = (FT_ULong)*stack;
+ neg = 0;
+ }
+
+ if ( num & 0xFFFFU )
+ {
+ if ( neg )
+ num = (FT_ULong)-num;
+
+ *q++ = 255;
+ *q++ = ( num & 0xFF000000U ) >> 24;
+ *q++ = ( num & 0x00FF0000U ) >> 16;
+ *q++ = ( num & 0x0000FF00U ) >> 8;
+ *q++ = num & 0x000000FFU;
+ }
+ else
+ {
+ num >>= 16;
+
+ if ( neg )
+ {
+ if ( num <= 107 )
+ *q++ = (FT_Byte)( 139 - num );
+ else if ( num <= 1131 )
+ {
+ *q++ = (FT_Byte)( ( ( num - 108 ) >> 8 ) + 251 );
+ *q++ = (FT_Byte)( ( num - 108 ) & 0xFF );
+ }
+ else
+ {
+ num = (FT_ULong)-num;
+
+ *q++ = 28;
+ *q++ = (FT_Byte)( num >> 8 );
+ *q++ = (FT_Byte)( num & 0xFF );
+ }
+ }
+ else
+ {
+ if ( num <= 107 )
+ *q++ = (FT_Byte)( num + 139 );
+ else if ( num <= 1131 )
+ {
+ *q++ = (FT_Byte)( ( ( num - 108 ) >> 8 ) + 247 );
+ *q++ = (FT_Byte)( ( num - 108 ) & 0xFF );
+ }
+ else
+ {
+ *q++ = 28;
+ *q++ = (FT_Byte)( num >> 8 );
+ *q++ = (FT_Byte)( num & 0xFF );
+ }
+ }
+ }
+
+ stack++;
+ }
+ }
+#endif /* CFF_CONFIG_OPTION_OLD_ENGINE */
else
{
/* This is not a number, hence it's an operator. Compute its code */
typedef struct CFF_ParserRec_
{
- FT_Library library;
- FT_Byte* start;
- FT_Byte* limit;
- FT_Byte* cursor;
+ FT_Library library;
+ FT_Byte* start;
+ FT_Byte* limit;
+ FT_Byte* cursor;
- FT_Byte* stack[CFF_MAX_STACK_DEPTH + 1];
- FT_Byte** top;
+ FT_Byte* stack[CFF_MAX_STACK_DEPTH + 1];
+ FT_Byte** top;
- FT_UInt object_code;
- void* object;
+ FT_UInt object_code;
+ void* object;
+
+ FT_UShort num_designs; /* a copy of `CFF_FontRecDict->num_designs' */
+ FT_UShort num_axes; /* a copy of `CFF_FontRecDict->num_axes' */
} CFF_ParserRec, *CFF_Parser;
cff_parser_init( CFF_Parser parser,
FT_UInt code,
void* object,
- FT_Library library);
+ FT_Library library,
+ FT_UShort num_designs,
+ FT_UShort num_axes );
FT_LOCAL( FT_Error )
cff_parser_run( CFF_Parser parser,
CFF_FIELD_NUM ( 13, unique_id, "UniqueID" )
CFF_FIELD_CALLBACK( 5, font_bbox, "FontBBox" )
CFF_FIELD_NUM ( 0x108, stroke_width, "StrokeWidth" )
+#if 0
+ CFF_FIELD_DELTA ( 14, xuid, 16, "XUID" )
+#endif
CFF_FIELD_NUM ( 15, charset_offset, "charset" )
CFF_FIELD_NUM ( 16, encoding_offset, "Encoding" )
CFF_FIELD_NUM ( 17, charstrings_offset, "CharStrings" )
#if 0
CFF_FIELD_STRING ( 0x116, base_font_name, "BaseFontName" )
CFF_FIELD_DELTA ( 0x117, base_font_blend, 16, "BaseFontBlend" )
+#endif
+
+ /* the next two operators were removed from the Type2 specification */
+ /* in version 16-March-2000 */
CFF_FIELD_CALLBACK( 0x118, multiple_master, "MultipleMaster" )
- CFF_FIELD_CALLBACK( 0x119, blend_axis_types, "BlendAxisTypes" )
+#if 0
+ CFF_FIELD_CALLBACK( 0x11A, blend_axis_types, "BlendAxisTypes" )
#endif
CFF_FIELD_CALLBACK( 0x11E, cid_ros, "ROS" )
FT_ULong cid_fd_select_offset;
FT_UInt cid_font_name;
+ /* the next fields come from the data of the deprecated */
+ /* `MultipleMaster' operator; they are needed to parse the (also */
+ /* deprecated) `blend' operator in Type 2 charstrings */
+ FT_UShort num_designs;
+ FT_UShort num_axes;
+
} CFF_FontRecDictRec, *CFF_FontRecDict;
FT_UInt num_strings;
FT_Byte** strings;
FT_Byte* string_pool;
+ FT_ULong string_pool_size;
CFF_SubFontRec top_font;
FT_UInt num_subfonts;
/*************************************************************************/
+#define STARTDATA "StartData"
+#define STARTDATA_LEN ( sizeof ( STARTDATA ) - 1 )
+#define SFNTS "/sfnts"
+#define SFNTS_LEN ( sizeof ( SFNTS ) - 1 )
+
+
FT_LOCAL_DEF( FT_Error )
cid_parser_new( CID_Parser* parser,
FT_Stream stream,
/* now, read the rest of the file until we find */
/* `StartData' or `/sfnts' */
{
- FT_Byte buffer[256 + 10];
- FT_ULong read_len = 256 + 10;
- FT_Byte* p = buffer;
+ /*
+ * The algorithm is as follows (omitting the case with less than 256
+ * bytes to fill for simplicity).
+ *
+ * 1. Fill the buffer with 256 + STARTDATA_LEN bytes.
+ *
+ * 2. Search for the STARTDATA and SFNTS strings at positions
+ * buffer[0], buffer[1], ...,
+ * buffer[255 + STARTDATA_LEN - SFNTS_LEN].
+ *
+ * 3. Move the last STARTDATA_LEN bytes to buffer[0].
+ *
+ * 4. Fill the buffer with 256 bytes, starting at STARTDATA_LEN.
+ *
+ * 5. Repeat with step 2.
+ *
+ */
+ FT_Byte buffer[256 + STARTDATA_LEN + 1];
+
+ /* values for the first loop */
+ FT_ULong read_len = 256 + STARTDATA_LEN;
+ FT_ULong read_offset = 0;
+ FT_Byte* p = buffer;
for ( offset = FT_STREAM_POS(); ; offset += 256 )
stream_len = stream->size - FT_STREAM_POS();
- if ( stream_len == 0 )
- {
- FT_TRACE2(( "cid_parser_new: no `StartData' keyword found\n" ));
- error = FT_THROW( Invalid_File_Format );
- goto Exit;
- }
read_len = FT_MIN( read_len, stream_len );
if ( FT_STREAM_READ( p, read_len ) )
goto Exit;
- if ( read_len < 256 )
- p[read_len] = '\0';
+ /* ensure that we do not compare with data beyond the buffer */
+ p[read_len] = '\0';
- limit = p + read_len - 10;
+ limit = p + read_len - SFNTS_LEN;
for ( p = buffer; p < limit; p++ )
{
- if ( p[0] == 'S' && ft_strncmp( (char*)p, "StartData", 9 ) == 0 )
+ if ( p[0] == 'S' &&
+ ft_strncmp( (char*)p, STARTDATA, STARTDATA_LEN ) == 0 )
{
/* save offset of binary data after `StartData' */
- offset += (FT_ULong)( p - buffer + 10 );
+ offset += (FT_ULong)( p - buffer ) + STARTDATA_LEN;
goto Found;
}
- else if ( p[1] == 's' && ft_strncmp( (char*)p, "/sfnts", 6 ) == 0 )
+ else if ( p[1] == 's' &&
+ ft_strncmp( (char*)p, SFNTS, SFNTS_LEN ) == 0 )
{
- offset += (FT_ULong)( p - buffer + 7 );
+ offset += (FT_ULong)( p - buffer ) + SFNTS_LEN;
goto Found;
}
}
- FT_MEM_MOVE( buffer, p, 10 );
- read_len = 256;
- p = buffer + 10;
+ if ( read_offset + read_len < STARTDATA_LEN )
+ {
+ FT_TRACE2(( "cid_parser_new: no `StartData' keyword found\n" ));
+ error = FT_THROW( Invalid_File_Format );
+ goto Exit;
+ }
+
+ FT_MEM_MOVE( buffer,
+ buffer + read_offset + read_len - STARTDATA_LEN,
+ STARTDATA_LEN );
+
+ /* values for the next loop */
+ read_len = 256;
+ read_offset = STARTDATA_LEN;
+ p = buffer + read_offset;
}
}
limit = parser->root.limit;
cur = parser->root.cursor;
- while ( cur < limit )
+ while ( cur < limit - SFNTS_LEN )
{
if ( parser->root.error )
{
goto Exit;
}
- if ( cur[0] == 'S' && ft_strncmp( (char*)cur, "StartData", 9 ) == 0 )
+ if ( cur[0] == 'S' &&
+ cur < limit - STARTDATA_LEN &&
+ ft_strncmp( (char*)cur, STARTDATA, STARTDATA_LEN ) == 0 )
{
if ( ft_strncmp( (char*)arg1, "(Hex)", 5 ) == 0 )
{
goto Exit;
}
- else if ( cur[1] == 's' && ft_strncmp( (char*)cur, "/sfnts", 6 ) == 0 )
+ else if ( cur[1] == 's' &&
+ ft_strncmp( (char*)cur, SFNTS, SFNTS_LEN ) == 0 )
{
FT_TRACE2(( "cid_parser_new: cannot handle Type 11 fonts\n" ));
error = FT_THROW( Unknown_File_Format );
}
+#undef STARTDATA
+#undef STARTDATA_LEN
+#undef SFNTS
+#undef SFNTS_LEN
+
+
FT_LOCAL_DEF( void )
cid_parser_done( CID_Parser* parser )
{
for ( i = 0; i < nnames; i++ )
{
if ( FT_Get_Sfnt_Name( gxvalid->face, i, &name ) != FT_Err_Ok )
- continue ;
+ continue;
if ( name.name_id == name_index )
goto Out;
if ( ( p + ( maxEntry + 1 ) * entrySize ) > limit )
FT_INVALID_TOO_SHORT;
- for (entry = 0; entry <= maxEntry ; entry++ )
+ for (entry = 0; entry <= maxEntry; entry++ )
{
FT_UShort newState_idx;
FT_UShort flags;
\
\
for ( b = p; b < (FT_Bytes)p + len; b++ ) \
- FT_TRACE1(("\\x%02x", *b)) ; \
+ FT_TRACE1(("\\x%02x", *b)); \
} \
FT_END_STMNT
\
for ( b = p; b < (FT_Bytes)p + len; b++ ) \
if ( 0x40 < *b && *b < 0x7E ) \
- FT_TRACE1(("%c", *b)) ; \
+ FT_TRACE1(("%c", *b)); \
else \
- FT_TRACE1(("\\x%02x", *b)) ; \
+ FT_TRACE1(("\\x%02x", *b)); \
} \
FT_END_STMNT
FT_Bytes limit,
GXV_Validator gxvalid )
{
- FT_Bytes p = table ;
+ FT_Bytes p = table;
FT_Bytes wdc_end = table + GXV_JUST_DATA( wdc_offset_max );
FT_UInt i;
GXV_NAME_ENTER( "validating coverage" );
- GXV_TRACE(( "interprete coverage 0x%04x by Apple style\n", coverage ));
+ GXV_TRACE(( "interpret coverage 0x%04x by Apple style\n", coverage ));
if ( KERN_IS_NEW( gxvalid ) )
{
}
}
- GXV_TRACE(( "cannot interprete coverage, broken kern subtable\n" ));
+ GXV_TRACE(( "cannot interpret coverage, broken kern subtable\n" ));
Exit:
GXV_EXIT;
+------ lcar --------------------+
| |
| +===============+ |
- | | looup header | |
+ | | lookup header | |
| +===============+ |
| | BinSrchHeader | |
| +===============+ |
GXV_NAME_ENTER( "validating contents of substitutionTable" );
- for ( i = 0; i < num_gids ; i ++ )
+ for ( i = 0; i < num_gids; i++ )
{
FT_UShort dst_gid;
GXV_LIMIT_CHECK( nTracks * ( 4 + 2 + 2 ) );
- for ( i = 0; i < nTracks; i ++ )
+ for ( i = 0; i < nTracks; i++ )
{
p = table + i * ( 4 + 2 + 2 );
track = FT_NEXT_LONG( p );
gxv_sfntName_validate( nameIndex, 256, 32767, gxvalid );
- for ( j = i; j < nTracks; j ++ )
+ for ( j = i; j < nTracks; j++ )
{
p = table + j * ( 4 + 2 + 2 );
t = FT_NEXT_LONG( p );
/* original ZLib. */
#ifndef USE_ZLIB_ZCALLOC
-#define MY_ZCALLOC /* prevent all zcalloc() & zfree() in zutils.c */
+#define MY_ZCALLOC /* prevent all zcalloc() & zfree() in zutil.c */
#endif
#include "zlib.h"
inflateSync returns Z_OK if a full flush point has been found, Z_BUF_ERROR
if no more input was provided, Z_DATA_ERROR if no flush point has been found,
or Z_STREAM_ERROR if the stream structure was inconsistent. In the success
- case, the application may save the current current value of total_in which
+ case, the application may save the current value of total_in which
indicates where valid compressed data was found. In the error case, the
application may repeatedly call inflateSync, providing more input each time,
until success or end of the input data.
FT_Int isItalic )
{
FT_Bytes p = table;
- FT_UInt i, cnt, table_size ;
+ FT_UInt i, cnt, table_size;
OTV_OPTIONAL_TABLE( Coverage );
OTV_OPTIONAL_TABLE( DeviceTableOffset );
int i;
- for ( i = 0 ; i < face->nprops && !found; i++ )
+ for ( i = 0; i < face->nprops && !found; i++ )
{
if ( !ft_strcmp( properties[i].name, prop ) )
found = 1;
int firstCol, lastCol;
int firstRow, lastRow;
FT_ULong nencoding;
- int encodingOffset;
+ FT_UShort encodingOffset;
int i, j;
FT_ULong k;
PCF_Encoding encoding = NULL;
{
for ( j = firstCol; j <= lastCol; j++ )
{
+ /* X11's reference implementation uses the equivalent to */
+ /* `FT_GET_SHORT', however PCF fonts with more than 32768 */
+ /* characters (e.g. `unifont.pcf') clearly show that an */
+ /* unsigned value is needed. */
if ( PCF_BYTE_ORDER( format ) == MSBFirst )
- encodingOffset = FT_GET_SHORT();
+ encodingOffset = FT_GET_USHORT();
else
- encodingOffset = FT_GET_SHORT_LE();
+ encodingOffset = FT_GET_USHORT_LE();
- if ( encodingOffset > -1 )
+ if ( encodingOffset != 0xFFFFU )
{
encoding[k].enc = i * 256 + j;
- encoding[k].glyph = (FT_UShort)encodingOffset;
+ encoding[k].glyph = encodingOffset;
FT_TRACE5(( " code %d (0x%04X): idx %d\n",
encoding[k].enc, encoding[k].enc, encoding[k].glyph ));
/* XXX: we ignore the secondary stroke and edge definitions */
/* since we don't support native PFR hinting */
/* */
- if ( flags & PFR_GLYPH_EXTRA_ITEMS )
+ if ( flags & PFR_GLYPH_SINGLE_EXTRA_ITEMS )
{
error = pfr_extra_items_skip( &p, limit );
if ( error )
/* ignore extra items when present */
/* */
- if ( flags & PFR_GLYPH_EXTRA_ITEMS )
+ if ( flags & PFR_GLYPH_COMPOUND_EXTRA_ITEMS )
{
error = pfr_extra_items_skip( &p, limit );
if ( error )
FT_READ_USHORT( count ) )
goto Exit;
- /* check maximum value and a rough minimum size */
+ /* check maximum value and a rough minimum size: */
+ /* - no more than 13106 log fonts */
+ /* - we need 5 bytes for a log header record */
+ /* - we need at least 18 bytes for a log font record */
+ /* - the overall size is at least 95 bytes plus the */
+ /* log header and log font records */
if ( count > ( ( 1 << 16 ) - 2 ) / 5 ||
- 2 + count * 5 >= stream->size - section_offset )
+ 2 + count * 5 >= stream->size - section_offset ||
+ 95 + count * ( 5 + 18 ) >= stream->size )
{
FT_ERROR(( "pfr_log_font_count:"
" invalid number of logical fonts\n" ));
if ( flags & PFR_LOG_2BYTE_STROKE )
local++;
- if ( (flags & PFR_LINE_JOIN_MASK) == PFR_LINE_JOIN_MITER )
+ if ( ( flags & PFR_LINE_JOIN_MASK ) == PFR_LINE_JOIN_MITER )
local += 3;
}
if ( flags & PFR_LOG_BOLD )
Too_Short:
error = FT_THROW( Invalid_Table );
- FT_ERROR(( "pfr_exta_item_load_stem_snaps:"
+ FT_ERROR(( "pfr_extra_item_load_stem_snaps:"
" invalid stem snaps table\n" ));
goto Exit;
}
FT_UInt n, ok;
+ if ( *astring )
+ FT_FREE( *astring );
+
if ( len > 0 && p[len - 1] == 0 )
len--;
- /* check that each character is ASCII for making sure not to
- load garbage
- */
+ /* check that each character is ASCII */
+ /* for making sure not to load garbage */
ok = ( len > 0 );
for ( n = 0; n < len; n++ )
if ( p[n] < 32 || p[n] > 127 )
FT_MEM_COPY( result, p, len );
result[len] = 0;
}
+
Exit:
*astring = result;
return error;
FT_UInt probe = power * size;
FT_UInt extra = count - power;
FT_Byte* base = stream->cursor;
- FT_Bool twobytes = FT_BOOL( item->flags & 1 );
- FT_Bool twobyte_adj = FT_BOOL( item->flags & 2 );
+ FT_Bool twobytes = FT_BOOL( item->flags & PFR_KERN_2BYTE_CHAR );
+ FT_Bool twobyte_adj = FT_BOOL( item->flags & PFR_KERN_2BYTE_ADJ );
FT_Byte* p;
FT_UInt32 cpair;
pfr_lookup_bitmap_data( FT_Byte* base,
FT_Byte* limit,
FT_UInt count,
- FT_UInt flags,
+ FT_UInt* flags,
FT_UInt char_code,
FT_ULong* found_offset,
FT_ULong* found_size )
{
- FT_UInt left, right, char_len;
- FT_Bool two = FT_BOOL( flags & 1 );
+ FT_UInt min, max, char_len;
+ FT_Bool two = FT_BOOL( *flags & PFR_BITMAP_2BYTE_CHARCODE );
FT_Byte* buff;
char_len = 4;
- if ( two ) char_len += 1;
- if ( flags & 2 ) char_len += 1;
- if ( flags & 4 ) char_len += 1;
+ if ( two )
+ char_len += 1;
+ if ( *flags & PFR_BITMAP_2BYTE_SIZE )
+ char_len += 1;
+ if ( *flags & PFR_BITMAP_3BYTE_OFFSET )
+ char_len += 1;
+
+ if ( !( *flags & PFR_BITMAP_CHARCODES_VALIDATED ) )
+ {
+ FT_Byte* p;
+ FT_Byte* lim;
+ FT_UInt code;
+ FT_Long prev_code;
- left = 0;
- right = count;
- while ( left < right )
- {
- FT_UInt middle, code;
+ *flags |= PFR_BITMAP_VALID_CHARCODES;
+ prev_code = -1;
+ lim = base + count * char_len;
+ if ( lim > limit )
+ {
+ FT_TRACE0(( "pfr_lookup_bitmap_data:"
+ " number of bitmap records too large,\n"
+ " "
+ " thus ignoring all bitmaps in this strike\n" ));
+ *flags &= ~PFR_BITMAP_VALID_CHARCODES;
+ }
+ else
+ {
+ /* check whether records are sorted by code */
+ for ( p = base; p < lim; p += char_len )
+ {
+ if ( two )
+ code = FT_PEEK_USHORT( p );
+ else
+ code = *p;
- middle = ( left + right ) >> 1;
- buff = base + middle * char_len;
+ if ( (FT_Long)code <= prev_code )
+ {
+ FT_TRACE0(( "pfr_lookup_bitmap_data:"
+ " bitmap records are not sorted,\n"
+ " "
+ " thus ignoring all bitmaps in this strike\n" ));
+ *flags &= ~PFR_BITMAP_VALID_CHARCODES;
+ break;
+ }
- /* check that we are not outside of the table -- */
- /* this is possible with broken fonts... */
- if ( buff + char_len > limit )
- goto Fail;
+ prev_code = code;
+ }
+ }
+
+ *flags |= PFR_BITMAP_CHARCODES_VALIDATED;
+ }
+
+ /* ignore bitmaps in case table is not valid */
+ /* (this might be sanitized, but PFR is dead...) */
+ if ( !( *flags & PFR_BITMAP_VALID_CHARCODES ) )
+ goto Fail;
+
+ min = 0;
+ max = count;
+
+ /* binary search */
+ while ( min < max )
+ {
+ FT_UInt mid, code;
+
+
+ mid = ( min + max ) >> 1;
+ buff = base + mid * char_len;
if ( two )
code = PFR_NEXT_USHORT( buff );
else
code = PFR_NEXT_BYTE( buff );
- if ( code == char_code )
- goto Found_It;
-
- if ( code < char_code )
- left = middle;
+ if ( char_code < code )
+ max = mid;
+ else if ( char_code > code )
+ min = mid + 1;
else
- right = middle;
+ goto Found_It;
}
Fail:
return;
Found_It:
- if ( flags & 2 )
+ if ( *flags & PFR_BITMAP_2BYTE_SIZE )
*found_size = PFR_NEXT_USHORT( buff );
else
*found_size = PFR_NEXT_BYTE( buff );
- if ( flags & 4 )
+ if ( *flags & PFR_BITMAP_3BYTE_OFFSET )
*found_offset = PFR_NEXT_ULONG( buff );
else
*found_offset = PFR_NEXT_USHORT( buff );
{
FT_Error error = FT_Err_Ok;
FT_Byte flags;
- FT_Char c;
FT_Byte b;
FT_Byte* p = *pdata;
FT_Long xpos, ypos, advance;
{
case 0:
PFR_CHECK( 1 );
- c = PFR_NEXT_INT8( p );
- xpos = c >> 4;
- ypos = ( (FT_Char)( c << 4 ) ) >> 4;
+ b = PFR_NEXT_BYTE( p );
+ xpos = (FT_Char)b >> 4;
+ ypos = ( (FT_Char)( b << 4 ) ) >> 4;
break;
case 1:
case 1:
PFR_CHECK( 1 );
- advance = PFR_NEXT_INT8( p ) << 8;
+ advance = PFR_NEXT_INT8( p ) * 256;
break;
case 2:
char_len = 4;
- if ( strike->flags & 1 ) char_len += 1;
- if ( strike->flags & 2 ) char_len += 1;
- if ( strike->flags & 4 ) char_len += 1;
+ if ( strike->flags & PFR_BITMAP_2BYTE_CHARCODE )
+ char_len += 1;
+ if ( strike->flags & PFR_BITMAP_2BYTE_SIZE )
+ char_len += 1;
+ if ( strike->flags & PFR_BITMAP_3BYTE_OFFSET )
+ char_len += 1;
/* access data directly in the frame to speed lookups */
if ( FT_STREAM_SEEK( phys->bct_offset + strike->bct_offset ) ||
pfr_lookup_bitmap_data( stream->cursor,
stream->limit,
strike->num_bitmaps,
- strike->flags,
+ &strike->flags,
character->char_code,
&gps_offset,
&gps_size );
&xpos, &ypos,
&xsize, &ysize,
&advance, &format );
+ if ( error )
+ goto Exit1;
/*
* Before allocating the target bitmap, we check whether the given
{
if ( FT_ERR_EQ( error, Invalid_Table ) )
FT_ERROR(( "pfr_slot_load_bitmap: invalid bitmap dimensions\n" ));
- goto Exit;
+ goto Exit1;
}
/*
/* XXX: needs casts to fit FT_Glyph_Metrics.{width|height} */
glyph->root.metrics.width = (FT_Pos)xsize << 6;
glyph->root.metrics.height = (FT_Pos)ysize << 6;
- glyph->root.metrics.horiBearingX = xpos << 6;
- glyph->root.metrics.horiBearingY = ypos << 6;
+ glyph->root.metrics.horiBearingX = xpos * 64;
+ glyph->root.metrics.horiBearingY = ypos * 64;
glyph->root.metrics.horiAdvance = FT_PIX_ROUND( ( advance >> 2 ) );
glyph->root.metrics.vertBearingX = - glyph->root.metrics.width >> 1;
glyph->root.metrics.vertBearingY = 0;
p,
stream->limit,
format,
- FT_BOOL(face->header.color_flags & 2),
+ FT_BOOL( face->header.color_flags &
+ PFR_FLAG_INVERT_BITMAP ),
&glyph->root.bitmap );
}
}
+ Exit1:
FT_FRAME_EXIT();
}
/* used in `color_flags' field of the PFR_Header */
- typedef enum PFR_HeaderFlags_
- {
- PFR_FLAG_BLACK_PIXEL = 1,
- PFR_FLAG_INVERT_BITMAP = 2
-
- } PFR_HeaderFlags;
+#define PFR_FLAG_BLACK_PIXEL 0x01U
+#define PFR_FLAG_INVERT_BITMAP 0x02U
/************************************************************************/
} PFR_LogFontRec, *PFR_LogFont;
- typedef enum PFR_LogFlags_
- {
- PFR_LOG_EXTRA_ITEMS = 0x40,
- PFR_LOG_2BYTE_BOLD = 0x20,
- PFR_LOG_BOLD = 0x10,
- PFR_LOG_2BYTE_STROKE = 8,
- PFR_LOG_STROKE = 4,
- PFR_LINE_JOIN_MASK = 3
+#define PFR_LINE_JOIN_MITER 0x00U
+#define PFR_LINE_JOIN_ROUND 0x01U
+#define PFR_LINE_JOIN_BEVEL 0x02U
+#define PFR_LINE_JOIN_MASK ( PFR_LINE_JOIN_ROUND | PFR_LINE_JOIN_BEVEL )
- } PFR_LogFlags;
-
-
- typedef enum PFR_LineJoinFlags_
- {
- PFR_LINE_JOIN_MITER = 0,
- PFR_LINE_JOIN_ROUND = 1,
- PFR_LINE_JOIN_BEVEL = 2
-
- } PFR_LineJoinFlags;
+#define PFR_LOG_STROKE 0x04U
+#define PFR_LOG_2BYTE_STROKE 0x08U
+#define PFR_LOG_BOLD 0x10U
+#define PFR_LOG_2BYTE_BOLD 0x20U
+#define PFR_LOG_EXTRA_ITEMS 0x40U
/************************************************************************/
- typedef enum PFR_BitmapFlags_
- {
- PFR_BITMAP_3BYTE_OFFSET = 4,
- PFR_BITMAP_2BYTE_SIZE = 2,
- PFR_BITMAP_2BYTE_CHARCODE = 1
+#define PFR_BITMAP_2BYTE_CHARCODE 0x01U
+#define PFR_BITMAP_2BYTE_SIZE 0x02U
+#define PFR_BITMAP_3BYTE_OFFSET 0x04U
- } PFR_BitmapFlags;
+ /*not part of the specification but used for implementation */
+#define PFR_BITMAP_CHARCODES_VALIDATED 0x40U
+#define PFR_BITMAP_VALID_CHARCODES 0x80U
typedef struct PFR_BitmapCharRec_
} PFR_BitmapCharRec, *PFR_BitmapChar;
- typedef enum PFR_StrikeFlags_
- {
- PFR_STRIKE_2BYTE_COUNT = 0x10,
- PFR_STRIKE_3BYTE_OFFSET = 0x08,
- PFR_STRIKE_3BYTE_SIZE = 0x04,
- PFR_STRIKE_2BYTE_YPPM = 0x02,
- PFR_STRIKE_2BYTE_XPPM = 0x01
-
- } PFR_StrikeFlags;
+#define PFR_STRIKE_2BYTE_XPPM 0x01U
+#define PFR_STRIKE_2BYTE_YPPM 0x02U
+#define PFR_STRIKE_3BYTE_SIZE 0x04U
+#define PFR_STRIKE_3BYTE_OFFSET 0x08U
+#define PFR_STRIKE_2BYTE_COUNT 0x10U
typedef struct PFR_StrikeRec_
} PFR_PhyFontRec, *PFR_PhyFont;
- typedef enum PFR_PhyFlags_
- {
- PFR_PHY_EXTRA_ITEMS = 0x80,
- PFR_PHY_3BYTE_GPS_OFFSET = 0x20,
- PFR_PHY_2BYTE_GPS_SIZE = 0x10,
- PFR_PHY_ASCII_CODE = 0x08,
- PFR_PHY_PROPORTIONAL = 0x04,
- PFR_PHY_2BYTE_CHARCODE = 0x02,
- PFR_PHY_VERTICAL = 0x01
-
- } PFR_PhyFlags;
+#define PFR_PHY_VERTICAL 0x01U
+#define PFR_PHY_2BYTE_CHARCODE 0x02U
+#define PFR_PHY_PROPORTIONAL 0x04U
+#define PFR_PHY_ASCII_CODE 0x08U
+#define PFR_PHY_2BYTE_GPS_SIZE 0x10U
+#define PFR_PHY_3BYTE_GPS_OFFSET 0x20U
+#define PFR_PHY_EXTRA_ITEMS 0x80U
- typedef enum PFR_KernFlags_
- {
- PFR_KERN_2BYTE_CHAR = 0x01,
- PFR_KERN_2BYTE_ADJ = 0x02
-
- } PFR_KernFlags;
+#define PFR_KERN_2BYTE_CHAR 0x01U
+#define PFR_KERN_2BYTE_ADJ 0x02U
/************************************************************************/
- typedef enum PFR_GlyphFlags_
- {
- PFR_GLYPH_IS_COMPOUND = 0x80,
- PFR_GLYPH_EXTRA_ITEMS = 0x08,
- PFR_GLYPH_1BYTE_XYCOUNT = 0x04,
- PFR_GLYPH_XCOUNT = 0x02,
- PFR_GLYPH_YCOUNT = 0x01
+#define PFR_GLYPH_YCOUNT 0x01U
+#define PFR_GLYPH_XCOUNT 0x02U
+#define PFR_GLYPH_1BYTE_XYCOUNT 0x04U
+
+#define PFR_GLYPH_SINGLE_EXTRA_ITEMS 0x08U
+#define PFR_GLYPH_COMPOUND_EXTRA_ITEMS 0x40U
- } PFR_GlyphFlags;
+#define PFR_GLYPH_IS_COMPOUND 0x80U
/* controlled coordinate */
} PFR_SubGlyphRec, *PFR_SubGlyph;
- typedef enum PFR_SubgGlyphFlags_
- {
- PFR_SUBGLYPH_3BYTE_OFFSET = 0x80,
- PFR_SUBGLYPH_2BYTE_SIZE = 0x40,
- PFR_SUBGLYPH_YSCALE = 0x20,
- PFR_SUBGLYPH_XSCALE = 0x10
-
- } PFR_SubGlyphFlags;
+#define PFR_SUBGLYPH_XSCALE 0x10U
+#define PFR_SUBGLYPH_YSCALE 0x20U
+#define PFR_SUBGLYPH_2BYTE_SIZE 0x40U
+#define PFR_SUBGLYPH_3BYTE_OFFSET 0x80U
typedef struct PFR_GlyphRec_
for ( ; count > 0; count--, idx++ )
{
- FT_Byte* q = (FT_Byte*)objects[idx] + field->offset;
+ FT_Byte* q = (FT_Byte*)objects[idx] + field->offset;
FT_Long val;
- FT_String* string;
+ FT_String* string = NULL;
skip_spaces( &cur, limit );
case T1_FIELD_TYPE_MM_BBOX:
{
FT_Memory memory = parser->memory;
- FT_Fixed* temp;
+ FT_Fixed* temp = NULL;
FT_Int result;
FT_UInt i;
* It turns out though that minimizing the total number of lit
* pixels is also important, so position C), with one edge
* aligned with a pixel boundary is actually preferable
- * to A). There are also more possibile positions for C) than
+ * to A). There are also more possible positions for C) than
* for A) or B), so it involves less distortion of the overall
* character shape.
*/
}
/* We choose between B) and C) above based on the amount
- * of fractinal stem width; for small amounts, choose
+ * of fractional stem width; for small amounts, choose
* C) always, for large amounts, B) always, and inbetween,
* pick whichever one involves less stem movement.
*/
#if 0
- /* org_width is is font units, result in device pixels, 26.6 format */
+ /* org_width is in font units, result in device pixels, 26.6 format */
FT_LOCAL_DEF( FT_Pos )
psh_dimension_snap_width( PSH_Dimension dimension,
FT_Int org_width )
#define FT_ERR_XCAT( x, y ) x ## y
#define FT_ERR_CAT( x, y ) FT_ERR_XCAT( x, y )
-#define FT_MAX( a, b ) ( (a) > (b) ? (a) : (b) )
-
/* This macro is used to indicate that a function parameter is unused. */
/* Its purpose is simply to reduce compiler warnings. Note also that */
/* simply defining it as `(void)x' doesn't avoid warnings with certain */
#define IS_TOP_OVERSHOOT( x ) \
(Bool)( x - FLOOR( x ) >= ras.precision_half )
+#if FT_RENDER_POOL_SIZE > 2048
+#define FT_MAX_BLACK_POOL ( FT_RENDER_POOL_SIZE / sizeof ( Long ) )
+#else
+#define FT_MAX_BLACK_POOL ( 2048 / sizeof ( Long ) )
+#endif
+
/* The most used variables are positioned at the top of the structure. */
/* Thus, their offset can be coded with less opcodes, resulting in a */
/* smaller executable. */
static void
- ft_black_reset( black_PRaster raster,
- char* pool_base,
- Long pool_size )
+ ft_black_reset( FT_Raster raster,
+ PByte pool_base,
+ ULong pool_size )
{
FT_UNUSED( raster );
FT_UNUSED( pool_base );
static int
- ft_black_set_mode( black_PRaster raster,
- ULong mode,
- const char* palette )
+ ft_black_set_mode( FT_Raster raster,
+ ULong mode,
+ void* args )
{
FT_UNUSED( raster );
FT_UNUSED( mode );
- FT_UNUSED( palette );
+ FT_UNUSED( args );
return 0;
}
static int
- ft_black_render( black_PRaster raster,
+ ft_black_render( FT_Raster raster,
const FT_Raster_Params* params )
{
const FT_Outline* outline = (const FT_Outline*)params->source;
#else
black_TWorker worker[1];
- Long buffer[FT_MAX( FT_RENDER_POOL_SIZE, 2048 ) / sizeof ( Long )];
+ Long buffer[FT_MAX_BLACK_POOL];
#endif
if ( !target_map->buffer )
return FT_THROW( Invalid );
+ /* reject too large outline coordinates */
+ {
+ FT_Vector* vec = outline->points;
+ FT_Vector* limit = vec + outline->n_points;
+
+
+ for ( ; vec < limit; vec++ )
+ {
+ if ( vec->x < -0x1000000L || vec->x > 0x1000000L ||
+ vec->y < -0x1000000L || vec->y > 0x1000000L )
+ return FT_THROW( Invalid );
+ }
+ }
+
#ifdef __REACTOS__
worker = malloc(sizeof(black_TWorker));
buffer = malloc(FT_MAX(FT_RENDER_POOL_SIZE, 2048));
worker->buff = buffer;
#ifdef __REACTOS__
- worker->sizeBuff = buffer + (FT_MAX(FT_RENDER_POOL_SIZE, 2048) / sizeof(Long));
+ worker->sizeBuff = buffer + FT_MAX_BLACK_POOL;
#else
worker->sizeBuff = (&buffer)[1]; /* Points to right after buffer. */
#endif
instance_size * num_instances > fvar_len )
num_instances = 0;
+ /* we don't support Multiple Master CFFs yet */
+ if ( !face->goto_table( face, TTAG_CFF, stream, 0 ) )
+ num_instances = 0;
+
/* we support at most 2^15 - 1 instances */
if ( num_instances >= ( 1U << 15 ) - 1 )
{
mid = max + 1;
/* search in segments before the current segment */
- for ( i = max ; i > 0; i-- )
+ for ( i = max; i > 0; i-- )
{
FT_UInt prev_end;
FT_Byte* old_p;
if ( char_code < start )
max = mid;
- else if ( char_code > start+cnt )
+ else if ( char_code > start + cnt )
min = mid + 1;
else
return TRUE;
/* */
/* ttpost.c */
/* */
-/* Postcript name table processing for TrueType and OpenType fonts */
+/* PostScript name table processing for TrueType and OpenType fonts */
/* (body). */
/* */
/* Copyright 1996-2016 by */
/* */
/* ttpost.h */
/* */
-/* Postcript name table processing for TrueType and OpenType fonts */
+/* PostScript name table processing for TrueType and OpenType fonts */
/* (specification). */
/* */
/* Copyright 1996-2016 by */
#define FT_BEGIN_STMNT do {
#define FT_END_STMNT } while ( 0 )
+#define FT_MIN( a, b ) ( (a) < (b) ? (a) : (b) )
#define FT_MAX( a, b ) ( (a) > (b) ? (a) : (b) )
#define FT_ABS( a ) ( (a) < 0 ? -(a) : (a) )
#else /* FT_STATIC_RASTER */
-#define RAS_ARG /* empty */
+#define RAS_ARG void
#define RAS_ARG_ /* empty */
#define RAS_VAR /* empty */
#define RAS_VAR_ /* empty */
#undef TRUNC
#undef SCALED
-#define ONE_PIXEL ( 1L << PIXEL_BITS )
+#define ONE_PIXEL ( 1 << PIXEL_BITS )
#define TRUNC( x ) ( (TCoord)( (x) >> PIXEL_BITS ) )
-#define SUBPIXELS( x ) ( (TPos)(x) << PIXEL_BITS )
+#define SUBPIXELS( x ) ( (TPos)(x) * ONE_PIXEL )
#define FLOOR( x ) ( (x) & -ONE_PIXEL )
#define CEILING( x ) ( ( (x) + ONE_PIXEL - 1 ) & -ONE_PIXEL )
#define ROUND( x ) ( ( (x) + ONE_PIXEL / 2 ) & -ONE_PIXEL )
#if PIXEL_BITS >= 6
-#define UPSCALE( x ) ( (x) << ( PIXEL_BITS - 6 ) )
+#define UPSCALE( x ) ( (x) * ( ONE_PIXEL >> 6 ) )
#define DOWNSCALE( x ) ( (x) >> ( PIXEL_BITS - 6 ) )
#else
#define UPSCALE( x ) ( (x) >> ( 6 - PIXEL_BITS ) )
-#define DOWNSCALE( x ) ( (x) << ( 6 - PIXEL_BITS ) )
+#define DOWNSCALE( x ) ( (x) * ( 64 >> PIXEL_BITS ) )
#endif
/* These macros speed up repetitive divisions by replacing them */
- /* with multiplications and right shifts. */
+ /* with multiplications and right shifts. */
#define FT_UDIVPREP( b ) \
long b ## _r = (long)( FT_ULONG_MAX >> PIXEL_BITS ) / ( b )
#define FT_UDIV( a, b ) \
/* need to define them to "float" or "double" when experimenting with */
/* new algorithms */
- typedef long TCoord; /* integer scanline/pixel coordinate */
typedef long TPos; /* sub-pixel coordinate */
-
- /* determine the type used to store cell areas. This normally takes at */
- /* least PIXEL_BITS*2 + 1 bits. On 16-bit systems, we need to use */
- /* `long' instead of `int', otherwise bad things happen */
-
-#if PIXEL_BITS <= 7
-
- typedef int TArea;
-
-#else /* PIXEL_BITS >= 8 */
-
- /* approximately determine the size of integers using an ANSI-C header */
-#if FT_UINT_MAX == 0xFFFFU
- typedef long TArea;
-#else
- typedef int TArea;
-#endif
-
-#endif /* PIXEL_BITS >= 8 */
-
-
- /* maximum number of gray spans in a call to the span callback */
-#define FT_MAX_GRAY_SPANS 32
+ typedef int TCoord; /* integer scanline/pixel coordinate */
+ typedef int TArea; /* cell areas, coordinate products */
typedef struct TCell_* PCell;
typedef struct TCell_
{
- TPos x; /* same with gray_TWorker.ex */
+ TCoord x; /* same with gray_TWorker.ex */
TCoord cover; /* same with gray_TWorker.cover */
TArea area;
PCell next;
} TCell;
+ /* maximum number of gray spans in a call to the span callback */
+#define FT_MAX_GRAY_SPANS 32
+
+ /* maximum number of gray cells in the buffer */
+#if FT_RENDER_POOL_SIZE > 2048
+#define FT_MAX_GRAY_POOL ( FT_RENDER_POOL_SIZE / sizeof ( TCell ) )
+#else
+#define FT_MAX_GRAY_POOL ( 2048 / sizeof ( TCell ) )
+#endif
+
+
#if defined( _MSC_VER ) /* Visual C++ (and Intel C++) */
/* We disable the warning `structure was padded due to */
/* __declspec(align())' in order to compile cleanly with */
ft_jmp_buf jump_buffer;
TCoord ex, ey;
- TPos min_ex, max_ex;
- TPos min_ey, max_ey;
- TPos count_ex, count_ey;
+ TCoord min_ex, max_ex;
+ TCoord min_ey, max_ey;
+ TCoord count_ex, count_ey;
TArea area;
TCoord cover;
TPos x, y;
- FT_Vector bez_stack[32 * 3 + 1];
- int lev_stack[32];
-
FT_Outline outline;
FT_Bitmap target;
- FT_BBox clip_box;
FT_Span gray_spans[FT_MAX_GRAY_SPANS];
int num_gray_spans;
void* render_span_data;
int span_y;
- int band_size;
- int band_shoot;
-
- void* buffer;
- long buffer_size;
-
PCell* ycells;
- TPos ycount;
} gray_TWorker, *gray_PWorker;
} gray_TRaster, *gray_PRaster;
+#ifdef FT_DEBUG_LEVEL_TRACE
- /*************************************************************************/
- /* */
- /* Initialize the cells table. */
- /* */
- static void
- gray_init_cells( RAS_ARG_ void* buffer,
- long byte_size )
- {
- ras.buffer = buffer;
- ras.buffer_size = byte_size;
-
- ras.ycells = (PCell*) buffer;
- ras.cells = NULL;
- ras.max_cells = 0;
- ras.num_cells = 0;
- ras.area = 0;
- ras.cover = 0;
- ras.invalid = 1;
- }
-
-
- /*************************************************************************/
- /* */
- /* Compute the outline bounding box. */
- /* */
+ /* to be called while in the debugger -- */
+ /* this function causes a compiler warning since it is unused otherwise */
static void
- gray_compute_cbox( RAS_ARG )
+ gray_dump_cells( RAS_ARG )
{
- FT_Outline* outline = &ras.outline;
- FT_Vector* vec = outline->points;
- FT_Vector* limit = vec + outline->n_points;
+ int yindex;
- if ( outline->n_points <= 0 )
+ for ( yindex = 0; yindex < ras.count_ey; yindex++ )
{
- ras.min_ex = ras.max_ex = 0;
- ras.min_ey = ras.max_ey = 0;
- return;
- }
-
- ras.min_ex = ras.max_ex = vec->x;
- ras.min_ey = ras.max_ey = vec->y;
-
- vec++;
+ PCell cell;
- for ( ; vec < limit; vec++ )
- {
- TPos x = vec->x;
- TPos y = vec->y;
+ printf( "%3d:", yindex );
- if ( x < ras.min_ex ) ras.min_ex = x;
- if ( x > ras.max_ex ) ras.max_ex = x;
- if ( y < ras.min_ey ) ras.min_ey = y;
- if ( y > ras.max_ey ) ras.max_ey = y;
+ for ( cell = ras.ycells[yindex]; cell != NULL; cell = cell->next )
+ printf( " (%3d, c:%4d, a:%6d)",
+ cell->x, cell->cover, cell->area );
+ printf( "\n" );
}
-
- /* truncate the bounding box to integer pixels */
- ras.min_ex = ras.min_ex >> 6;
- ras.min_ey = ras.min_ey >> 6;
- ras.max_ex = ( ras.max_ex + 63 ) >> 6;
- ras.max_ey = ( ras.max_ey + 63 ) >> 6;
}
+#endif /* FT_DEBUG_LEVEL_TRACE */
+
/*************************************************************************/
/* */
gray_find_cell( RAS_ARG )
{
PCell *pcell, cell;
- TPos x = ras.ex;
+ TCoord x = ras.ex;
if ( x > ras.count_ex )
TCoord ey )
{
if ( ex > ras.max_ex )
- ex = (TCoord)( ras.max_ex );
+ ex = ras.max_ex;
if ( ex < ras.min_ex )
- ex = (TCoord)( ras.min_ex - 1 );
+ ex = ras.min_ex - 1;
ras.area = 0;
ras.cover = 0;
gray_set_cell( RAS_VAR_ ex, ey );
}
-#if 0
+#ifndef FT_LONG64
/*************************************************************************/
/* */
TPos x2,
TCoord y2 )
{
- TCoord ex1, ex2, fx1, fx2, delta, mod;
- long p, first, dx;
+ TCoord ex1, ex2, fx1, fx2, first, delta, mod;
+ TPos p, dx;
int incr;
- dx = x2 - x1;
-
ex1 = TRUNC( x1 );
ex2 = TRUNC( x2 );
- fx1 = (TCoord)( x1 - SUBPIXELS( ex1 ) );
- fx2 = (TCoord)( x2 - SUBPIXELS( ex2 ) );
/* trivial case. Happens often */
if ( y1 == y2 )
return;
}
+ fx1 = (TCoord)( x1 - SUBPIXELS( ex1 ) );
+ fx2 = (TCoord)( x2 - SUBPIXELS( ex2 ) );
+
/* everything is located in a single cell. That is easy! */
/* */
if ( ex1 == ex2 )
p = ( ONE_PIXEL - fx1 ) * ( y2 - y1 );
first = ONE_PIXEL;
incr = 1;
+ dx = x2 - x1;
if ( dx < 0 )
{
gray_render_line( RAS_ARG_ TPos to_x,
TPos to_y )
{
- TCoord ey1, ey2, fy1, fy2, mod;
- TPos dx, dy, x, x2;
- long p, first;
- int delta, rem, lift, incr;
+ TCoord ey1, ey2, fy1, fy2, first, delta, mod;
+ TPos p, dx, dy, x, x2;
+ int incr;
ey1 = TRUNC( ras.y );
ey2 = TRUNC( to_y ); /* if (ey2 >= ras.max_ey) ey2 = ras.max_ey-1; */
- fy1 = (TCoord)( ras.y - SUBPIXELS( ey1 ) );
- fy2 = (TCoord)( to_y - SUBPIXELS( ey2 ) );
-
- dx = to_x - ras.x;
- dy = to_y - ras.y;
/* perform vertical clipping */
if ( ( ey1 >= ras.max_ey && ey2 >= ras.max_ey ) ||
( ey1 < ras.min_ey && ey2 < ras.min_ey ) )
goto End;
+ fy1 = (TCoord)( ras.y - SUBPIXELS( ey1 ) );
+ fy2 = (TCoord)( to_y - SUBPIXELS( ey2 ) );
+
/* everything is on a single scanline */
if ( ey1 == ey2 )
{
goto End;
}
+ dx = to_x - ras.x;
+ dy = to_y - ras.y;
+
/* vertical line - avoid calling gray_render_scanline */
incr = 1;
incr = -1;
}
- delta = (int)( first - fy1 );
+ delta = first - fy1;
ras.area += (TArea)two_fx * delta;
ras.cover += delta;
ey1 += incr;
gray_set_cell( RAS_VAR_ ex, ey1 );
- delta = (int)( first + first - ONE_PIXEL );
+ delta = first + first - ONE_PIXEL;
area = (TArea)two_fx * delta;
while ( ey1 != ey2 )
{
gray_set_cell( RAS_VAR_ ex, ey1 );
}
- delta = (int)( fy2 - ONE_PIXEL + first );
+ delta = fy2 - ONE_PIXEL + first;
ras.area += (TArea)two_fx * delta;
ras.cover += delta;
dy = -dy;
}
- FT_DIV_MOD( int, p, dy, delta, mod );
+ FT_DIV_MOD( TCoord, p, dy, delta, mod );
x = ras.x + delta;
- gray_render_scanline( RAS_VAR_ ey1, ras.x, fy1, x, (TCoord)first );
+ gray_render_scanline( RAS_VAR_ ey1, ras.x, fy1, x, first );
ey1 += incr;
gray_set_cell( RAS_VAR_ TRUNC( x ), ey1 );
if ( ey1 != ey2 )
{
- p = ONE_PIXEL * dx;
- FT_DIV_MOD( int, p, dy, lift, rem );
- mod -= (int)dy;
+ TCoord lift, rem;
+
+
+ p = ONE_PIXEL * dx;
+ FT_DIV_MOD( TCoord, p, dy, lift, rem );
+ mod -= (TCoord)dy;
do
{
mod += rem;
if ( mod >= 0 )
{
- mod -= (int)dy;
+ mod -= (TCoord)dy;
delta++;
}
x2 = x + delta;
- gray_render_scanline( RAS_VAR_ ey1, x,
- (TCoord)( ONE_PIXEL - first ), x2,
- (TCoord)first );
+ gray_render_scanline( RAS_VAR_ ey1,
+ x, ONE_PIXEL - first,
+ x2, first );
x = x2;
ey1 += incr;
} while ( ey1 != ey2 );
}
- gray_render_scanline( RAS_VAR_ ey1, x,
- (TCoord)( ONE_PIXEL - first ), to_x,
- fy2 );
+ gray_render_scanline( RAS_VAR_ ey1,
+ x, ONE_PIXEL - first,
+ to_x, fy2 );
End:
ras.x = to_x;
TCoord ex1, ex2, ey1, ey2;
- ex1 = TRUNC( ras.x );
- ex2 = TRUNC( to_x );
ey1 = TRUNC( ras.y );
ey2 = TRUNC( to_y );
( ey1 < ras.min_ey && ey2 < ras.min_ey ) )
goto End;
- dx = to_x - ras.x;
- dy = to_y - ras.y;
+ ex1 = TRUNC( ras.x );
+ ex2 = TRUNC( to_x );
fx1 = ras.x - SUBPIXELS( ex1 );
fy1 = ras.y - SUBPIXELS( ey1 );
+ dx = to_x - ras.x;
+ dy = to_y - ras.y;
+
if ( ex1 == ex2 && ey1 == ey2 ) /* inside one cell */
;
else if ( dy == 0 ) /* ex1 != ex2 */ /* any horizontal line */
}
else /* any other line */
{
- TArea prod = dx * fy1 - dy * fx1;
+ TPos prod = dx * fy1 - dy * fx1;
FT_UDIVPREP( dx );
FT_UDIVPREP( dy );
gray_render_conic( RAS_ARG_ const FT_Vector* control,
const FT_Vector* to )
{
+ FT_Vector bez_stack[16 * 2 + 1]; /* enough to accommodate bisections */
+ FT_Vector* arc = bez_stack;
TPos dx, dy;
- TPos min, max, y;
- int top, level;
- int* levels;
- FT_Vector* arc;
+ int draw, split;
- levels = ras.lev_stack;
-
- arc = ras.bez_stack;
arc[0].x = UPSCALE( to->x );
arc[0].y = UPSCALE( to->y );
arc[1].x = UPSCALE( control->x );
arc[1].y = UPSCALE( control->y );
arc[2].x = ras.x;
arc[2].y = ras.y;
- top = 0;
+
+ /* short-cut the arc that crosses the current band */
+ if ( ( TRUNC( arc[0].y ) >= ras.max_ey &&
+ TRUNC( arc[1].y ) >= ras.max_ey &&
+ TRUNC( arc[2].y ) >= ras.max_ey ) ||
+ ( TRUNC( arc[0].y ) < ras.min_ey &&
+ TRUNC( arc[1].y ) < ras.min_ey &&
+ TRUNC( arc[2].y ) < ras.min_ey ) )
+ {
+ ras.x = arc[0].x;
+ ras.y = arc[0].y;
+ return;
+ }
dx = FT_ABS( arc[2].x + arc[0].x - 2 * arc[1].x );
dy = FT_ABS( arc[2].y + arc[0].y - 2 * arc[1].y );
if ( dx < dy )
dx = dy;
- if ( dx < ONE_PIXEL / 4 )
- goto Draw;
-
- /* short-cut the arc that crosses the current band */
- min = max = arc[0].y;
-
- y = arc[1].y;
- if ( y < min ) min = y;
- if ( y > max ) max = y;
-
- y = arc[2].y;
- if ( y < min ) min = y;
- if ( y > max ) max = y;
-
- if ( TRUNC( min ) >= ras.max_ey || TRUNC( max ) < ras.min_ey )
- goto Draw;
-
- level = 0;
- do
+ /* We can calculate the number of necessary bisections because */
+ /* each bisection predictably reduces deviation exactly 4-fold. */
+ /* Even 32-bit deviation would vanish after 16 bisections. */
+ draw = 1;
+ while ( dx > ONE_PIXEL / 4 )
{
- dx >>= 2;
- level++;
- } while ( dx > ONE_PIXEL / 4 );
-
- levels[0] = level;
+ dx >>= 2;
+ draw <<= 1;
+ }
+ /* We use decrement counter to count the total number of segments */
+ /* to draw starting from 2^level. Before each draw we split as */
+ /* many times as there are trailing zeros in the counter. */
do
{
- level = levels[top];
- if ( level > 0 )
+ split = 1;
+ while ( ( draw & split ) == 0 )
{
gray_split_conic( arc );
arc += 2;
- top++;
- levels[top] = levels[top - 1] = level - 1;
- continue;
+ split <<= 1;
}
- Draw:
gray_render_line( RAS_VAR_ arc[0].x, arc[0].y );
- top--;
arc -= 2;
- } while ( top >= 0 );
+ } while ( --draw );
}
const FT_Vector* control2,
const FT_Vector* to )
{
- FT_Vector* arc;
- TPos min, max, y;
+ FT_Vector bez_stack[16 * 3 + 1]; /* enough to accommodate bisections */
+ FT_Vector* arc = bez_stack;
+ TPos dx, dy, dx_, dy_;
+ TPos dx1, dy1, dx2, dy2;
+ TPos L, s, s_limit;
- arc = ras.bez_stack;
arc[0].x = UPSCALE( to->x );
arc[0].y = UPSCALE( to->y );
arc[1].x = UPSCALE( control2->x );
arc[3].x = ras.x;
arc[3].y = ras.y;
- /* Short-cut the arc that crosses the current band. */
- min = max = arc[0].y;
-
- y = arc[1].y;
- if ( y < min )
- min = y;
- if ( y > max )
- max = y;
-
- y = arc[2].y;
- if ( y < min )
- min = y;
- if ( y > max )
- max = y;
-
- y = arc[3].y;
- if ( y < min )
- min = y;
- if ( y > max )
- max = y;
-
- if ( TRUNC( min ) >= ras.max_ey || TRUNC( max ) < ras.min_ey )
- goto Draw;
+ /* short-cut the arc that crosses the current band */
+ if ( ( TRUNC( arc[0].y ) >= ras.max_ey &&
+ TRUNC( arc[1].y ) >= ras.max_ey &&
+ TRUNC( arc[2].y ) >= ras.max_ey &&
+ TRUNC( arc[3].y ) >= ras.max_ey ) ||
+ ( TRUNC( arc[0].y ) < ras.min_ey &&
+ TRUNC( arc[1].y ) < ras.min_ey &&
+ TRUNC( arc[2].y ) < ras.min_ey &&
+ TRUNC( arc[3].y ) < ras.min_ey ) )
+ {
+ ras.x = arc[0].x;
+ ras.y = arc[0].y;
+ return;
+ }
for (;;)
{
/* F. Hain, at */
/* http://www.cis.southalabama.edu/~hain/general/Publications/Bezier/Camera-ready%20CISST02%202.pdf */
- {
- TPos dx, dy, dx_, dy_;
- TPos dx1, dy1, dx2, dy2;
- TPos L, s, s_limit;
+ /* dx and dy are x and y components of the P0-P3 chord vector. */
+ dx = dx_ = arc[3].x - arc[0].x;
+ dy = dy_ = arc[3].y - arc[0].y;
+ L = FT_HYPOT( dx_, dy_ );
- /* dx and dy are x and y components of the P0-P3 chord vector. */
- dx = dx_ = arc[3].x - arc[0].x;
- dy = dy_ = arc[3].y - arc[0].y;
+ /* Avoid possible arithmetic overflow below by splitting. */
+ if ( L > 32767 )
+ goto Split;
- L = FT_HYPOT( dx_, dy_ );
+ /* Max deviation may be as much as (s/L) * 3/4 (if Hain's v = 1). */
+ s_limit = L * (TPos)( ONE_PIXEL / 6 );
- /* Avoid possible arithmetic overflow below by splitting. */
- if ( L > 32767 )
- goto Split;
+ /* s is L * the perpendicular distance from P1 to the line P0-P3. */
+ dx1 = arc[1].x - arc[0].x;
+ dy1 = arc[1].y - arc[0].y;
+ s = FT_ABS( dy * dx1 - dx * dy1 );
- /* Max deviation may be as much as (s/L) * 3/4 (if Hain's v = 1). */
- s_limit = L * (TPos)( ONE_PIXEL / 6 );
+ if ( s > s_limit )
+ goto Split;
- /* s is L * the perpendicular distance from P1 to the line P0-P3. */
- dx1 = arc[1].x - arc[0].x;
- dy1 = arc[1].y - arc[0].y;
- s = FT_ABS( dy * dx1 - dx * dy1 );
+ /* s is L * the perpendicular distance from P2 to the line P0-P3. */
+ dx2 = arc[2].x - arc[0].x;
+ dy2 = arc[2].y - arc[0].y;
+ s = FT_ABS( dy * dx2 - dx * dy2 );
- if ( s > s_limit )
- goto Split;
+ if ( s > s_limit )
+ goto Split;
- /* s is L * the perpendicular distance from P2 to the line P0-P3. */
- dx2 = arc[2].x - arc[0].x;
- dy2 = arc[2].y - arc[0].y;
- s = FT_ABS( dy * dx2 - dx * dy2 );
+ /* Split super curvy segments where the off points are so far
+ from the chord that the angles P0-P1-P3 or P0-P2-P3 become
+ acute as detected by appropriate dot products. */
+ if ( dx1 * ( dx1 - dx ) + dy1 * ( dy1 - dy ) > 0 ||
+ dx2 * ( dx2 - dx ) + dy2 * ( dy2 - dy ) > 0 )
+ goto Split;
- if ( s > s_limit )
- goto Split;
+ gray_render_line( RAS_VAR_ arc[0].x, arc[0].y );
- /* Split super curvy segments where the off points are so far
- from the chord that the angles P0-P1-P3 or P0-P2-P3 become
- acute as detected by appropriate dot products. */
- if ( dx1 * ( dx1 - dx ) + dy1 * ( dy1 - dy ) > 0 ||
- dx2 * ( dx2 - dx ) + dy2 * ( dy2 - dy ) > 0 )
- goto Split;
+ if ( arc == bez_stack )
+ return;
- /* No reason to split. */
- goto Draw;
- }
+ arc -= 3;
+ continue;
Split:
gray_split_cubic( arc );
arc += 3;
- continue;
-
- Draw:
- gray_render_line( RAS_VAR_ arc[0].x, arc[0].y );
-
- if ( arc == ras.bez_stack )
- return;
-
- arc -= 3;
}
}
gray_start_cell( RAS_VAR_ TRUNC( x ), TRUNC( y ) );
- worker->x = x;
- worker->y = y;
+ ras.x = x;
+ ras.y = y;
return 0;
}
if ( coverage )
{
+ unsigned char* q = p + spans->x;
+
+
/* For small-spans it is faster to do it by ourselves than
* calling `memset'. This is mainly due to the cost of the
* function call.
*/
- if ( spans->len >= 8 )
- FT_MEM_SET( p + spans->x, (unsigned char)coverage, spans->len );
- else
+ switch ( spans->len )
{
- unsigned char* q = p + spans->x;
-
-
- switch ( spans->len )
- {
- case 7: *q++ = (unsigned char)coverage;
- case 6: *q++ = (unsigned char)coverage;
- case 5: *q++ = (unsigned char)coverage;
- case 4: *q++ = (unsigned char)coverage;
- case 3: *q++ = (unsigned char)coverage;
- case 2: *q++ = (unsigned char)coverage;
- case 1: *q = (unsigned char)coverage;
- default:
- ;
- }
+ case 7: *q++ = coverage;
+ case 6: *q++ = coverage;
+ case 5: *q++ = coverage;
+ case 4: *q++ = coverage;
+ case 3: *q++ = coverage;
+ case 2: *q++ = coverage;
+ case 1: *q = coverage;
+ case 0: break;
+ default:
+ FT_MEM_SET( q, coverage, spans->len );
}
}
}
static void
gray_hline( RAS_ARG_ TCoord x,
TCoord y,
- TPos area,
+ TArea area,
TCoord acount )
{
int coverage;
coverage = 255;
}
- y += (TCoord)ras.min_ey;
- x += (TCoord)ras.min_ex;
-
- /* FT_Span.x is a 16-bit short, so limit our coordinates appropriately */
- if ( x >= 32767 )
- x = 32767;
-
- /* FT_Span.y is an integer, so limit our coordinates appropriately */
- if ( y >= FT_INT_MAX )
- y = FT_INT_MAX;
+ y += ras.min_ey;
+ x += ras.min_ex;
if ( coverage )
{
/* see whether we can add this span to the current list */
count = ras.num_gray_spans;
span = ras.gray_spans + count - 1;
- if ( count > 0 &&
- ras.span_y == y &&
- (int)span->x + span->len == (int)x &&
- span->coverage == coverage )
+ if ( span->coverage == coverage &&
+ span->x + span->len == x &&
+ ras.span_y == y &&
+ count > 0 )
{
span->len = (unsigned short)( span->len + acount );
return;
}
-#ifdef FT_DEBUG_LEVEL_TRACE
-
- /* to be called while in the debugger -- */
- /* this function causes a compiler warning since it is unused otherwise */
static void
- gray_dump_cells( RAS_ARG )
+ gray_sweep( RAS_ARG )
{
int yindex;
- for ( yindex = 0; yindex < ras.ycount; yindex++ )
- {
- PCell cell;
-
-
- printf( "%3d:", yindex );
-
- for ( cell = ras.ycells[yindex]; cell != NULL; cell = cell->next )
- printf( " (%3ld, c:%4ld, a:%6d)", cell->x, cell->cover, cell->area );
- printf( "\n" );
- }
- }
-
-#endif /* FT_DEBUG_LEVEL_TRACE */
-
-
- static void
- gray_sweep( RAS_ARG_ const FT_Bitmap* target )
- {
- int yindex;
-
- FT_UNUSED( target );
-
-
if ( ras.num_cells == 0 )
return;
ras.num_gray_spans = 0;
+ ras.span_y = 0;
FT_TRACE7(( "gray_sweep: start\n" ));
- for ( yindex = 0; yindex < ras.ycount; yindex++ )
+ for ( yindex = 0; yindex < ras.count_ey; yindex++ )
{
PCell cell = ras.ycells[yindex];
TCoord cover = 0;
for ( ; cell != NULL; cell = cell->next )
{
- TPos area;
+ TArea area;
if ( cell->x > x && cover != 0 )
- gray_hline( RAS_VAR_ x, yindex, cover * ( ONE_PIXEL * 2 ),
+ gray_hline( RAS_VAR_ x, yindex, (TArea)cover * ( ONE_PIXEL * 2 ),
cell->x - x );
cover += cell->cover;
- area = cover * ( ONE_PIXEL * 2 ) - cell->area;
+ area = (TArea)cover * ( ONE_PIXEL * 2 ) - cell->area;
if ( area != 0 && cell->x >= 0 )
gray_hline( RAS_VAR_ cell->x, yindex, area, 1 );
}
if ( cover != 0 )
- gray_hline( RAS_VAR_ x, yindex, cover * ( ONE_PIXEL * 2 ),
+ gray_hline( RAS_VAR_ x, yindex, (TArea)cover * ( ONE_PIXEL * 2 ),
ras.count_ex - x );
}
/*************************************************************************/
/* */
- /* The following function should only compile in stand-alone mode, */
+ /* The following functions should only compile in stand-alone mode, */
/* i.e., when building this component without the rest of FreeType. */
/* */
/*************************************************************************/
return FT_THROW( Invalid_Outline );
}
+
+ /*************************************************************************/
+ /* */
+ /* <Function> */
+ /* FT_Outline_Get_CBox */
+ /* */
+ /* <Description> */
+ /* Return an outline's `control box'. The control box encloses all */
+ /* the outline's points, including Bézier control points. Though it */
+ /* coincides with the exact bounding box for most glyphs, it can be */
+ /* slightly larger in some situations (like when rotating an outline */
+ /* that contains Bézier outside arcs). */
+ /* */
+ /* Computing the control box is very fast, while getting the bounding */
+ /* box can take much more time as it needs to walk over all segments */
+ /* and arcs in the outline. To get the latter, you can use the */
+ /* `ftbbox' component, which is dedicated to this single task. */
+ /* */
+ /* <Input> */
+ /* outline :: A pointer to the source outline descriptor. */
+ /* */
+ /* <Output> */
+ /* acbox :: The outline's control box. */
+ /* */
+ /* <Note> */
+ /* See @FT_Glyph_Get_CBox for a discussion of tricky fonts. */
+ /* */
+
+ static void
+ FT_Outline_Get_CBox( const FT_Outline* outline,
+ FT_BBox *acbox )
+ {
+ TPos xMin, yMin, xMax, yMax;
+
+
+ if ( outline && acbox )
+ {
+ if ( outline->n_points == 0 )
+ {
+ xMin = 0;
+ yMin = 0;
+ xMax = 0;
+ yMax = 0;
+ }
+ else
+ {
+ FT_Vector* vec = outline->points;
+ FT_Vector* limit = vec + outline->n_points;
+
+
+ xMin = xMax = vec->x;
+ yMin = yMax = vec->y;
+ vec++;
+
+ for ( ; vec < limit; vec++ )
+ {
+ TPos x, y;
+
+
+ x = vec->x;
+ if ( x < xMin ) xMin = x;
+ if ( x > xMax ) xMax = x;
+
+ y = vec->y;
+ if ( y < yMin ) yMin = y;
+ if ( y > yMax ) yMax = y;
+ }
+ }
+ acbox->xMin = xMin;
+ acbox->xMax = xMax;
+ acbox->yMin = yMin;
+ acbox->yMax = yMax;
+ }
+ }
+
#endif /* STANDALONE_ */
typedef struct gray_TBand_
{
- TPos min, max;
+ TCoord min, max;
} gray_TBand;
error = FT_Outline_Decompose( &ras.outline, &func_interface, &ras );
if ( !ras.invalid )
gray_record_cell( RAS_VAR );
+
+ FT_TRACE7(( "band [%d..%d]: %d cells\n",
+ ras.min_ey, ras.max_ey, ras.num_cells ));
}
else
+ {
error = FT_THROW( Memory_Overflow );
+ FT_TRACE7(( "band [%d..%d]: to be bisected\n",
+ ras.min_ey, ras.max_ey ));
+ }
+
return error;
}
static int
gray_convert_glyph( RAS_ARG )
{
- gray_TBand bands[40];
- gray_TBand* volatile band;
- int volatile n, num_bands;
- TPos volatile min, max, max_y;
- FT_BBox* clip;
-
-
- /* Set up state in the raster object */
- gray_compute_cbox( RAS_VAR );
-
- /* clip to target bitmap, exit if nothing to do */
- clip = &ras.clip_box;
-
- if ( ras.max_ex <= clip->xMin || ras.min_ex >= clip->xMax ||
- ras.max_ey <= clip->yMin || ras.min_ey >= clip->yMax )
- return 0;
-
- if ( ras.min_ex < clip->xMin ) ras.min_ex = clip->xMin;
- if ( ras.min_ey < clip->yMin ) ras.min_ey = clip->yMin;
-
- if ( ras.max_ex > clip->xMax ) ras.max_ex = clip->xMax;
- if ( ras.max_ey > clip->yMax ) ras.max_ey = clip->yMax;
+#ifdef __REACTOS__
+ TCell *buffer;
+#else
+ TCell buffer[FT_MAX_GRAY_POOL];
+#endif
+ const int band_size = FT_MAX_GRAY_POOL / 8;
+ gray_TBand bands[32];
+ gray_TBand* band;
+ int n, num_bands;
+ TCoord min, max, max_y;
- ras.count_ex = ras.max_ex - ras.min_ex;
- ras.count_ey = ras.max_ey - ras.min_ey;
+#ifdef __REACTOS__
+ buffer = malloc(FT_MAX(FT_RENDER_POOL_SIZE, 2048));
+#endif
/* set up vertical bands */
- num_bands = (int)( ( ras.max_ey - ras.min_ey ) / ras.band_size );
+ num_bands = (int)( ( ras.max_ey - ras.min_ey ) / band_size );
if ( num_bands == 0 )
num_bands = 1;
if ( num_bands >= 39 )
num_bands = 39;
- ras.band_shoot = 0;
-
min = ras.min_ey;
max_y = ras.max_ey;
for ( n = 0; n < num_bands; n++, min = max )
{
- max = min + ras.band_size;
+ max = min + band_size;
if ( n == num_bands - 1 || max > max_y )
max = max_y;
do
{
- TPos bottom, top, middle;
- int error;
+ TCoord bottom, top, middle;
+ int error;
- {
- PCell cells_max;
- int yindex;
- long cell_start, cell_end, cell_mod;
+ /* memory management */
+ {
+ size_t ycount = (size_t)( band->max - band->min );
+ size_t cell_start;
- ras.ycells = (PCell*)ras.buffer;
- ras.ycount = band->max - band->min;
-
- cell_start = (long)sizeof ( PCell ) * ras.ycount;
- cell_mod = cell_start % (long)sizeof ( TCell );
- if ( cell_mod > 0 )
- cell_start += (long)sizeof ( TCell ) - cell_mod;
- cell_end = ras.buffer_size;
- cell_end -= cell_end % (long)sizeof ( TCell );
+ cell_start = ( ycount * sizeof ( PCell ) + sizeof ( TCell ) - 1 ) /
+ sizeof ( TCell );
- cells_max = (PCell)( (char*)ras.buffer + cell_end );
- ras.cells = (PCell)( (char*)ras.buffer + cell_start );
- if ( ras.cells >= cells_max )
+ if ( FT_MAX_GRAY_POOL - cell_start < 2 )
goto ReduceBands;
- ras.max_cells = cells_max - ras.cells;
- if ( ras.max_cells < 2 )
- goto ReduceBands;
+ ras.cells = buffer + cell_start;
+ ras.max_cells = (FT_PtrDist)( FT_MAX_GRAY_POOL - cell_start );
- for ( yindex = 0; yindex < ras.ycount; yindex++ )
- ras.ycells[yindex] = NULL;
+ ras.ycells = (PCell*)buffer;
+ while ( ycount )
+ ras.ycells[--ycount] = NULL;
}
ras.num_cells = 0;
if ( !error )
{
- gray_sweep( RAS_VAR_ &ras.target );
+ gray_sweep( RAS_VAR );
band--;
continue;
}
else if ( error != ErrRaster_Memory_Overflow )
+ {
+#ifdef __REACTOS__
+ free(buffer);
+#endif
return 1;
+ }
ReduceBands:
/* render pool overflow; we will reduce the render band by half */
/* be some problems. */
if ( middle == bottom )
{
-#ifdef FT_DEBUG_LEVEL_TRACE
FT_TRACE7(( "gray_convert_glyph: rotten glyph\n" ));
+#ifdef __REACTOS__
+ free(buffer);
#endif
return 1;
}
- if ( bottom-top >= ras.band_size )
- ras.band_shoot++;
-
band[1].min = bottom;
band[1].max = middle;
band[0].min = middle;
} while ( band >= bands );
}
- if ( ras.band_shoot > 8 && ras.band_size > 16 )
- ras.band_size = ras.band_size / 2;
+#ifdef __REACTOS__
+ free(buffer);
+#endif
return 0;
}
static int
- gray_raster_render( gray_PRaster raster,
+ gray_raster_render( FT_Raster raster,
const FT_Raster_Params* params )
{
const FT_Outline* outline = (const FT_Outline*)params->source;
const FT_Bitmap* target_map = params->target;
+ FT_BBox cbox, clip;
-#ifdef __REACTOS__
- gray_TWorker *worker;
- int ret;
- TCell *buffer;
- long buffer_size = FT_MAX(FT_RENDER_POOL_SIZE, 2048);
-#else
gray_TWorker worker[1];
- TCell buffer[FT_MAX( FT_RENDER_POOL_SIZE, 2048 ) / sizeof ( TCell )];
- long buffer_size = sizeof ( buffer );
-#endif
- int band_size = (int)( buffer_size /
- (long)( sizeof ( TCell ) * 8 ) );
-
if ( !raster )
return FT_THROW( Invalid_Argument );
if ( !( params->flags & FT_RASTER_FLAG_AA ) )
return FT_THROW( Invalid_Mode );
-#ifdef __REACTOS__
- worker = malloc(sizeof(gray_TWorker));
-#endif
+ FT_Outline_Get_CBox( outline, &cbox );
+
+ /* reject too large outline coordinates */
+ if ( cbox.xMin < -0x1000000L || cbox.xMax > 0x1000000L ||
+ cbox.yMin < -0x1000000L || cbox.yMax > 0x1000000L )
+ return FT_THROW( Invalid_Outline );
+
+ /* truncate the bounding box to integer pixels */
+ cbox.xMin = cbox.xMin >> 6;
+ cbox.yMin = cbox.yMin >> 6;
+ cbox.xMax = ( cbox.xMax + 63 ) >> 6;
+ cbox.yMax = ( cbox.yMax + 63 ) >> 6;
/* compute clipping box */
if ( !( params->flags & FT_RASTER_FLAG_DIRECT ) )
{
/* compute clip box from target pixmap */
- ras.clip_box.xMin = 0;
- ras.clip_box.yMin = 0;
- ras.clip_box.xMax = (FT_Pos)target_map->width;
- ras.clip_box.yMax = (FT_Pos)target_map->rows;
+ clip.xMin = 0;
+ clip.yMin = 0;
+ clip.xMax = (FT_Pos)target_map->width;
+ clip.yMax = (FT_Pos)target_map->rows;
}
else if ( params->flags & FT_RASTER_FLAG_CLIP )
- ras.clip_box = params->clip_box;
+ clip = params->clip_box;
else
{
- ras.clip_box.xMin = -32768L;
- ras.clip_box.yMin = -32768L;
- ras.clip_box.xMax = 32767L;
- ras.clip_box.yMax = 32767L;
+ clip.xMin = -32768L;
+ clip.yMin = -32768L;
+ clip.xMax = 32767L;
+ clip.yMax = 32767L;
}
-#ifdef __REACTOS__
- buffer = malloc(buffer_size);
-#endif
+ /* clip to target bitmap, exit if nothing to do */
+ ras.min_ex = FT_MAX( cbox.xMin, clip.xMin );
+ ras.min_ey = FT_MAX( cbox.yMin, clip.yMin );
+ ras.max_ex = FT_MIN( cbox.xMax, clip.xMax );
+ ras.max_ey = FT_MIN( cbox.yMax, clip.yMax );
- gray_init_cells( RAS_VAR_ buffer, buffer_size );
+ if ( ras.max_ex <= ras.min_ex || ras.max_ey <= ras.min_ey )
+ return 0;
+
+ ras.count_ex = ras.max_ex - ras.min_ex;
+ ras.count_ey = ras.max_ey - ras.min_ey;
ras.outline = *outline;
- ras.num_cells = 0;
- ras.invalid = 1;
- ras.band_size = band_size;
- ras.num_gray_spans = 0;
- ras.span_y = 0;
if ( params->flags & FT_RASTER_FLAG_DIRECT )
{
ras.render_span_data = &ras;
}
-#ifdef __REACTOS__
- ret = gray_convert_glyph(RAS_VAR);
- free(worker);
- free(buffer);
- return ret;
-#else
return gray_convert_glyph( RAS_VAR );
-#endif
}
static void
- gray_raster_reset( FT_Raster raster,
- char* pool_base,
- long pool_size )
+ gray_raster_reset( FT_Raster raster,
+ unsigned char* pool_base,
+ unsigned long pool_size )
{
FT_UNUSED( raster );
FT_UNUSED( pool_base );
"""Convert a code sequence to HTML."""
line = code_header + '\n'
for l in lines:
- line = line + html_quote( l ) + '\n'
+ line = line + html_quote( l ).rstrip() + '\n'
return line + code_footer
FT_UInt* interpreter_version = (FT_UInt*)value;
-#ifndef TT_CONFIG_OPTION_SUBPIXEL_HINTING
- if ( *interpreter_version != TT_INTERPRETER_VERSION_35 )
- error = FT_ERR( Unimplemented_Feature );
- else
+ if ( *interpreter_version == TT_INTERPRETER_VERSION_35
+#ifdef TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY
+ || *interpreter_version == TT_INTERPRETER_VERSION_38
+#endif
+#ifdef TT_SUPPORT_SUBPIXEL_HINTING_MINIMAL
+ || *interpreter_version == TT_INTERPRETER_VERSION_40
#endif
+ )
driver->interpreter_version = *interpreter_version;
+ else
+ error = FT_ERR( Unimplemented_Feature );
return error;
}
FT_UInt glyph_index )
{
TT_Face face = loader->face;
-#ifdef TT_CONFIG_OPTION_SUBPIXEL_HINTING
+#ifdef TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY
TT_Driver driver = (TT_Driver)FT_FACE_DRIVER( face );
#endif
loader->top_bearing = top_bearing;
loader->vadvance = advance_height;
-#ifdef TT_CONFIG_OPTION_SUBPIXEL_HINTING
+#ifdef TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY
if ( driver->interpreter_version == TT_INTERPRETER_VERSION_38 &&
loader->exec )
{
/* backwards compatibility mode on and off. */
sph_set_tweaks( loader, glyph_index );
}
-#endif /* TT_CONFIG_OPTION_SUBPIXEL_HINTING */
+#endif /* TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY */
if ( !loader->linear_def )
{
load->glyph->control_len = n_ins;
load->glyph->control_data = load->exec->glyphIns;
- FT_MEM_COPY( load->exec->glyphIns, p, (FT_Long)n_ins );
+ if ( n_ins )
+ FT_MEM_COPY( load->exec->glyphIns, p, (FT_Long)n_ins );
}
#endif /* TT_USE_BYTECODE_INTERPRETER */
TT_Hint_Glyph( TT_Loader loader,
FT_Bool is_composite )
{
-#ifdef TT_CONFIG_OPTION_SUBPIXEL_HINTING
+#if defined TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY || \
+ defined TT_SUPPORT_SUBPIXEL_HINTING_MINIMAL
TT_Face face = loader->face;
TT_Driver driver = (TT_Driver)FT_FACE_DRIVER( face );
#endif
#endif
- /* save glyph phantom points */
- loader->pp1 = zone->cur[zone->n_points - 4];
- loader->pp2 = zone->cur[zone->n_points - 3];
- loader->pp3 = zone->cur[zone->n_points - 2];
- loader->pp4 = zone->cur[zone->n_points - 1];
+#ifdef TT_SUPPORT_SUBPIXEL_HINTING_MINIMAL
+ /* Save possibly modified glyph phantom points unless in v40 backwards */
+ /* compatibility mode, where no movement on the x axis means no reason */
+ /* to change bearings or advance widths. */
+ if ( !( driver->interpreter_version == TT_INTERPRETER_VERSION_40 &&
+ !loader->exec->backwards_compatibility ) )
+ {
+#endif
+ loader->pp1 = zone->cur[zone->n_points - 4];
+ loader->pp2 = zone->cur[zone->n_points - 3];
+ loader->pp3 = zone->cur[zone->n_points - 2];
+ loader->pp4 = zone->cur[zone->n_points - 1];
+#ifdef TT_SUPPORT_SUBPIXEL_HINTING_MINIMAL
+ }
+#endif
-#ifdef TT_CONFIG_OPTION_SUBPIXEL_HINTING
+#ifdef TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY
if ( driver->interpreter_version == TT_INTERPRETER_VERSION_38 )
{
if ( loader->exec->sph_tweak_flags & SPH_TWEAK_DEEMBOLDEN )
else if ( loader->exec->sph_tweak_flags & SPH_TWEAK_EMBOLDEN )
FT_Outline_EmboldenXY( &loader->gloader->current.outline, 24, 0 );
}
-#endif /* TT_CONFIG_OPTION_SUBPIXEL_HINTING */
+#endif /* TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY */
return FT_Err_Ok;
}
}
{
-#ifdef TT_CONFIG_OPTION_SUBPIXEL_HINTING
+#ifdef TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY
TT_Face face = loader->face;
TT_Driver driver = (TT_Driver)FT_FACE_DRIVER( face );
FT_Bool do_scale = FALSE;
-#ifdef TT_CONFIG_OPTION_SUBPIXEL_HINTING
+#ifdef TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY
if ( driver->interpreter_version == TT_INTERPRETER_VERSION_38 )
{
}
else
-#endif /* TT_CONFIG_OPTION_SUBPIXEL_HINTING */
+#endif /* TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY */
{
/* scale the glyph */
: -subglyph->transform.yx;
int c = subglyph->transform.xy > 0 ? subglyph->transform.xy
: -subglyph->transform.xy;
- int d = subglyph->transform.yy > 0 ? subglyph->transform.yy
+ int d = subglyph->transform.yy > 0 ? subglyph->transform.yy
: -subglyph->transform.yy;
int m = a > b ? a : b;
int n = c > d ? c : d;
* (3) for everything else.
*
*/
+ static void
+ tt_loader_set_pp( TT_Loader loader )
+ {
+ FT_Bool subpixel_hinting = 0;
+ FT_Bool grayscale = 0;
+ FT_Bool use_aw_2 = 0;
+
#ifdef TT_CONFIG_OPTION_SUBPIXEL_HINTING
+ TT_Driver driver = (TT_Driver)FT_FACE_DRIVER( loader->face );
+#endif
+
+#ifdef TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY
+ if ( driver->interpreter_version == TT_INTERPRETER_VERSION_38 )
+ {
+ subpixel_hinting = loader->exec ? loader->exec->subpixel_hinting
+ : 0;
+ grayscale = loader->exec ? loader->exec->grayscale
+ : 0;
+ }
+#endif
+#ifdef TT_SUPPORT_SUBPIXEL_HINTING_MINIMAL
+ if ( driver->interpreter_version == TT_INTERPRETER_VERSION_40 )
+ {
+ subpixel_hinting = loader->exec ? loader->exec->subpixel_hinting_lean
+ : 0;
+ grayscale = loader->exec ? loader->exec->grayscale_cleartype
+ : 0;
+ }
+#endif
+
+ use_aw_2 = (FT_Bool)( subpixel_hinting && grayscale );
+
+ loader->pp1.x = loader->bbox.xMin - loader->left_bearing;
+ loader->pp1.y = 0;
+ loader->pp2.x = loader->pp1.x + loader->advance;
+ loader->pp2.y = 0;
+
+ loader->pp3.x = use_aw_2 ? loader->advance / 2 : 0;
+ loader->pp3.y = loader->bbox.yMax + loader->top_bearing;
+ loader->pp4.x = use_aw_2 ? loader->advance / 2 : 0;
+ loader->pp4.y = loader->pp3.y - loader->vadvance;
+ }
+
+
+ /* a utility function to retrieve i-th node from given FT_List */
+ static FT_ListNode
+ ft_list_get_node_at( FT_List list,
+ FT_UInt index )
+ {
+ FT_ListNode cur;
+
-#define TT_LOADER_SET_PP( loader ) \
- do \
- { \
- FT_Bool subpixel_hinting_ = loader->exec \
- ? loader->exec->subpixel_hinting \
- : 0; \
- FT_Bool grayscale_ = loader->exec \
- ? loader->exec->grayscale \
- : 0; \
- FT_Bool use_aw_2_ = (FT_Bool)( subpixel_hinting_ && \
- grayscale_ ); \
- \
- \
- (loader)->pp1.x = (loader)->bbox.xMin - (loader)->left_bearing; \
- (loader)->pp1.y = 0; \
- (loader)->pp2.x = (loader)->pp1.x + (loader)->advance; \
- (loader)->pp2.y = 0; \
- \
- (loader)->pp3.x = use_aw_2_ ? (loader)->advance / 2 : 0; \
- (loader)->pp3.y = (loader)->bbox.yMax + (loader)->top_bearing; \
- (loader)->pp4.x = use_aw_2_ ? (loader)->advance / 2 : 0; \
- (loader)->pp4.y = (loader)->pp3.y - (loader)->vadvance; \
- } while ( 0 )
-
-#else /* !TT_CONFIG_OPTION_SUBPIXEL_HINTING */
-
-#define TT_LOADER_SET_PP( loader ) \
- do \
- { \
- (loader)->pp1.x = (loader)->bbox.xMin - (loader)->left_bearing; \
- (loader)->pp1.y = 0; \
- (loader)->pp2.x = (loader)->pp1.x + (loader)->advance; \
- (loader)->pp2.y = 0; \
- \
- (loader)->pp3.x = 0; \
- (loader)->pp3.y = (loader)->bbox.yMax + (loader)->top_bearing; \
- (loader)->pp4.x = 0; \
- (loader)->pp4.y = (loader)->pp3.y - (loader)->vadvance; \
- } while ( 0 )
-
-#endif /* !TT_CONFIG_OPTION_SUBPIXEL_HINTING */
+ if ( !list )
+ return NULL;
+
+ for ( cur = list->head; cur; cur = cur->next )
+ {
+ if ( !index )
+ return cur;
+
+ index--;
+ }
+
+ return NULL;
+ }
/*************************************************************************/
/* must initialize points before (possibly) overriding */
/* glyph metrics from the incremental interface */
- TT_LOADER_SET_PP( loader );
+ tt_loader_set_pp( loader );
#ifdef FT_CONFIG_OPTION_INCREMENTAL
tt_get_metrics_incr_overrides( loader, glyph_index );
/* must initialize phantom points before (possibly) overriding */
/* glyph metrics from the incremental interface */
- TT_LOADER_SET_PP( loader );
+ tt_loader_set_pp( loader );
#ifdef FT_CONFIG_OPTION_INCREMENTAL
tt_get_metrics_incr_overrides( loader, glyph_index );
FT_UInt start_contour;
FT_ULong ins_pos; /* position of composite instructions, if any */
+ FT_ListNode node, node2;
+
/*
* We store the glyph index directly in the `node->data' pointer,
* pointers with a width of at least 32 bits.
*/
+
+ /* clear the nodes filled by sibling chains */
+ node = ft_list_get_node_at( &loader->composites, recurse_count );
+ for ( node2 = node; node2; node2 = node2->next )
+ node2->data = (void*)ULONG_MAX;
+
/* check whether we already have a composite glyph with this index */
if ( FT_List_Find( &loader->composites,
(void*)(unsigned long)glyph_index ) )
error = FT_THROW( Invalid_Composite );
goto Exit;
}
- else
- {
- FT_ListNode node = NULL;
+ else if ( node )
+ node->data = (void*)(unsigned long)glyph_index;
+ else
+ {
if ( FT_NEW( node ) )
goto Exit;
node->data = (void*)(unsigned long)glyph_index;
outline.n_points = (short)( gloader->current.num_subglyphs + 4 );
outline.n_contours = outline.n_points;
+ outline.points = NULL;
+ outline.tags = NULL;
+ outline.contours = NULL;
+
if ( FT_NEW_ARRAY( points, outline.n_points ) ||
FT_NEW_ARRAY( tags, outline.n_points ) ||
FT_NEW_ARRAY( contours, outline.n_points ) )
FT_UInt glyph_index )
{
TT_Face face = loader->face;
-#ifdef TT_CONFIG_OPTION_SUBPIXEL_HINTING
+#if defined TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY || \
+ defined TT_SUPPORT_SUBPIXEL_HINTING_MINIMAL
TT_Driver driver = (TT_Driver)FT_FACE_DRIVER( face );
#endif
glyph->metrics.horiBearingY = bbox.yMax;
glyph->metrics.horiAdvance = loader->pp2.x - loader->pp1.x;
- /* adjust advance width to the value contained in the hdmx table */
- /* unless FT_LOAD_COMPUTE_METRICS is set */
- if ( !face->postscript.isFixedPitch &&
- IS_HINTED( loader->load_flags ) &&
- !( loader->load_flags & FT_LOAD_COMPUTE_METRICS ) )
+ /* Adjust advance width to the value contained in the hdmx table */
+ /* unless FT_LOAD_COMPUTE_METRICS is set or backwards compatibility */
+ /* mode of the v40 interpreter is active. See `ttinterp.h' for */
+ /* details on backwards compatibility mode. */
+ if (
+#ifdef TT_SUPPORT_SUBPIXEL_HINTING_MINIMAL
+ !( driver->interpreter_version == TT_INTERPRETER_VERSION_40 &&
+ ( loader->exec && loader->exec->backwards_compatibility ) ) &&
+#endif
+ !face->postscript.isFixedPitch &&
+ IS_HINTED( loader->load_flags ) &&
+ !( loader->load_flags & FT_LOAD_COMPUTE_METRICS ) )
{
FT_Byte* widthp;
size->root.metrics.x_ppem,
glyph_index );
-#ifdef TT_CONFIG_OPTION_SUBPIXEL_HINTING
+#ifdef TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY
if ( driver->interpreter_version == TT_INTERPRETER_VERSION_38 )
{
}
else
-#endif /* TT_CONFIG_OPTION_SUBPIXEL_HINTING */
+#endif /* TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY */
{
if ( widthp )
#ifdef TT_USE_BYTECODE_INTERPRETER
FT_Bool pedantic = FT_BOOL( load_flags & FT_LOAD_PEDANTIC );
#endif
+#if defined TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY || \
+ defined TT_SUPPORT_SUBPIXEL_HINTING_MINIMAL
+ TT_Driver driver = (TT_Driver)FT_FACE_DRIVER( (TT_Face)glyph->face );
+#endif
face = (TT_Face)glyph->face;
if ( IS_HINTED( load_flags ) && !glyf_table_only )
{
TT_ExecContext exec;
- FT_Bool grayscale;
-
-#ifdef TT_CONFIG_OPTION_SUBPIXEL_HINTING
- TT_Driver driver = (TT_Driver)FT_FACE_DRIVER( face );
+ FT_Bool grayscale = TRUE;
+#ifdef TT_SUPPORT_SUBPIXEL_HINTING_MINIMAL
+ FT_Bool subpixel_hinting_lean;
+ FT_Bool grayscale_cleartype;
+#endif
+#ifdef TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY
FT_Bool subpixel_hinting = FALSE;
#if 0
FT_Bool subpixel_positioned;
FT_Bool gray_cleartype;
#endif
-#endif /* TT_CONFIG_OPTION_SUBPIXEL_HINTING */
+#endif /* TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY */
FT_Bool reexecute = FALSE;
if ( !exec )
return FT_THROW( Could_Not_Find_Context );
-#ifdef TT_CONFIG_OPTION_SUBPIXEL_HINTING
+#ifdef TT_SUPPORT_SUBPIXEL_HINTING_MINIMAL
+ if ( driver->interpreter_version == TT_INTERPRETER_VERSION_40 )
+ {
+ subpixel_hinting_lean = TRUE;
+ grayscale_cleartype = !FT_BOOL( load_flags &
+ FT_LOAD_TARGET_LCD ||
+ load_flags &
+ FT_LOAD_TARGET_LCD_V );
+ exec->vertical_lcd_lean = FT_BOOL( load_flags &
+ FT_LOAD_TARGET_LCD_V );
+ }
+ else
+ {
+ subpixel_hinting_lean = FALSE;
+ grayscale_cleartype = FALSE;
+ exec->vertical_lcd_lean = FALSE;
+ }
+#endif
+
+#ifdef TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY
if ( driver->interpreter_version == TT_INTERPRETER_VERSION_38 )
{
}
else
-#endif /* TT_CONFIG_OPTION_SUBPIXEL_HINTING */
+#endif /* TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY */
- {
+#ifdef TT_SUPPORT_SUBPIXEL_HINTING_MINIMAL
+ if ( driver->interpreter_version == TT_INTERPRETER_VERSION_40 )
+ grayscale = FT_BOOL( !subpixel_hinting_lean &&
+ FT_LOAD_TARGET_MODE( load_flags ) !=
+ FT_RENDER_MODE_MONO );
+ else
+#endif
grayscale = FT_BOOL( FT_LOAD_TARGET_MODE( load_flags ) !=
- FT_RENDER_MODE_MONO );
- }
+ FT_RENDER_MODE_MONO );
error = TT_Load_Context( exec, face, size );
if ( error )
return error;
-#ifdef TT_CONFIG_OPTION_SUBPIXEL_HINTING
+#ifdef TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY
if ( driver->interpreter_version == TT_INTERPRETER_VERSION_38 )
{
}
else
-#endif /* TT_CONFIG_OPTION_SUBPIXEL_HINTING */
+#endif /* TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY */
{
+
+#ifdef TT_SUPPORT_SUBPIXEL_HINTING_MINIMAL
+ if ( driver->interpreter_version == TT_INTERPRETER_VERSION_40 )
+ {
+ /* a change from mono to subpixel rendering (and vice versa) */
+ /* requires a re-execution of the CVT program */
+ if ( subpixel_hinting_lean != exec->subpixel_hinting_lean )
+ {
+ FT_TRACE4(( "tt_loader_init: subpixel hinting change,"
+ " re-executing `prep' table\n" ));
+
+ exec->subpixel_hinting_lean = subpixel_hinting_lean;
+ reexecute = TRUE;
+ }
+
+ /* a change from colored to grayscale subpixel rendering (and */
+ /* vice versa) requires a re-execution of the CVT program */
+ if ( grayscale_cleartype != exec->grayscale_cleartype )
+ {
+ FT_TRACE4(( "tt_loader_init: grayscale subpixel hinting change,"
+ " re-executing `prep' table\n" ));
+
+ exec->grayscale_cleartype = grayscale_cleartype;
+ reexecute = TRUE;
+ }
+ }
+#endif
+
/* a change from mono to grayscale rendering (and vice versa) */
/* requires a re-execution of the CVT program */
if ( grayscale != exec->grayscale )
if ( exec->GS.instruct_control & 2 )
exec->GS = tt_default_graphics_state;
-#ifdef TT_CONFIG_OPTION_SUBPIXEL_HINTING
+#ifdef TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY
/* check whether we have a font hinted for ClearType -- */
/* note that this flag can also be modified in a glyph's bytecode */
- if ( exec->GS.instruct_control & 4 )
+ if ( driver->interpreter_version == TT_INTERPRETER_VERSION_38 &&
+ exec->GS.instruct_control & 4 )
exec->ignore_x_mode = 0;
#endif
for ( i = 0; i < blend->tuplecount; i++ )
{
FT_TRACE5(( " [ " ));
- for ( j = 0 ; j < (FT_UInt)gvar_head.axisCount; j++ )
+ for ( j = 0; j < (FT_UInt)gvar_head.axisCount; j++ )
{
blend->tuplecoords[i * gvar_head.axisCount + j] =
FT_GET_SHORT() * 4; /* convert to FT_Fixed */
{
FT_TRACE6(( " axis coordinate %d (%.4f):\n",
i, blend->normalizedcoords[i] / 65536.0 ));
+ if ( !( tupleIndex & GX_TI_INTERMEDIATE_TUPLE ) )
+ FT_TRACE6(( " intermediate coordinates %d (%.4f, %.4f):\n",
+ i,
+ im_start_coords[i] / 65536.0,
+ im_end_coords[i] / 65536.0 ));
/* It's not clear why (for intermediate tuples) we don't need */
/* to check against start/end -- the documentation says we don't. */
continue;
}
- else if ( blend->normalizedcoords[i] == 0 )
+ if ( blend->normalizedcoords[i] == 0 )
{
FT_TRACE6(( " axis coordinate is zero, stop\n" ));
apply = 0;
break;
}
- else if ( ( blend->normalizedcoords[i] < 0 && tuple_coords[i] > 0 ) ||
- ( blend->normalizedcoords[i] > 0 && tuple_coords[i] < 0 ) )
+ if ( blend->normalizedcoords[i] == tuple_coords[i] )
{
- FT_TRACE6(( " tuple coordinate value %.4f is exceeded, stop\n",
+ FT_TRACE6(( " tuple coordinate value %.4f fits perfectly\n",
tuple_coords[i] / 65536.0 ));
- apply = 0;
- break;
+ /* `apply' does not change */
+ continue;
}
- else if ( !( tupleIndex & GX_TI_INTERMEDIATE_TUPLE ) )
+ if ( !( tupleIndex & GX_TI_INTERMEDIATE_TUPLE ) )
{
- FT_TRACE6(( " tuple coordinate value %.4f fits\n",
- tuple_coords[i] / 65536.0 ));
/* not an intermediate tuple */
- apply = FT_MulFix( apply,
- blend->normalizedcoords[i] > 0
- ? blend->normalizedcoords[i]
- : -blend->normalizedcoords[i] );
- }
- else if ( blend->normalizedcoords[i] < im_start_coords[i] ||
- blend->normalizedcoords[i] > im_end_coords[i] )
- {
- FT_TRACE6(( " intermediate tuple range [%.4f;%.4f] is exceeded,"
- " stop\n",
- im_start_coords[i] / 65536.0,
- im_end_coords[i] / 65536.0 ));
- apply = 0;
- break;
- }
+ if ( blend->normalizedcoords[i] < FT_MIN( 0, tuple_coords[i] ) ||
+ blend->normalizedcoords[i] > FT_MAX( 0, tuple_coords[i] ) )
+ {
+ FT_TRACE6(( " tuple coordinate value %.4f is exceeded, stop\n",
+ tuple_coords[i] / 65536.0 ));
+ apply = 0;
+ break;
+ }
- else if ( blend->normalizedcoords[i] < tuple_coords[i] )
- {
- FT_TRACE6(( " intermediate tuple range [%.4f;%.4f] fits\n",
- im_start_coords[i] / 65536.0,
- im_end_coords[i] / 65536.0 ));
+ FT_TRACE6(( " tuple coordinate value %.4f fits\n",
+ tuple_coords[i] / 65536.0 ));
apply = FT_MulDiv( apply,
- blend->normalizedcoords[i] - im_start_coords[i],
- tuple_coords[i] - im_start_coords[i] );
+ blend->normalizedcoords[i],
+ tuple_coords[i] );
}
-
else
{
- FT_TRACE6(( " intermediate tuple range [%.4f;%.4f] fits\n",
- im_start_coords[i] / 65536.0,
- im_end_coords[i] / 65536.0 ));
- apply = FT_MulDiv( apply,
- im_end_coords[i] - blend->normalizedcoords[i],
- im_end_coords[i] - tuple_coords[i] );
+ /* intermediate tuple */
+
+ if ( blend->normalizedcoords[i] < im_start_coords[i] ||
+ blend->normalizedcoords[i] > im_end_coords[i] )
+ {
+ FT_TRACE6(( " intermediate tuple range [%.4f;%.4f] is exceeded,"
+ " stop\n",
+ im_start_coords[i] / 65536.0,
+ im_end_coords[i] / 65536.0 ));
+ apply = 0;
+ break;
+ }
+
+ else if ( blend->normalizedcoords[i] < tuple_coords[i] )
+ {
+ FT_TRACE6(( " intermediate tuple range [%.4f;%.4f] fits\n",
+ im_start_coords[i] / 65536.0,
+ im_end_coords[i] / 65536.0 ));
+ apply = FT_MulDiv( apply,
+ blend->normalizedcoords[i] - im_start_coords[i],
+ tuple_coords[i] - im_start_coords[i] );
+ }
+
+ else
+ {
+ FT_TRACE6(( " intermediate tuple range [%.4f;%.4f] fits\n",
+ im_start_coords[i] / 65536.0,
+ im_end_coords[i] / 65536.0 ));
+ apply = FT_MulDiv( apply,
+ im_end_coords[i] - blend->normalizedcoords[i],
+ im_end_coords[i] - tuple_coords[i] );
+ }
}
}
#define FT_COMPONENT trace_ttinterp
-#define SUBPIXEL_HINTING \
+#define NO_SUBPIXEL_HINTING \
+ ( ((TT_Driver)FT_FACE_DRIVER( exc->face ))->interpreter_version == \
+ TT_INTERPRETER_VERSION_35 )
+
+#ifdef TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY
+#define SUBPIXEL_HINTING_INFINALITY \
( ((TT_Driver)FT_FACE_DRIVER( exc->face ))->interpreter_version == \
TT_INTERPRETER_VERSION_38 )
+#endif
+#ifdef TT_SUPPORT_SUBPIXEL_HINTING_MINIMAL
+#define SUBPIXEL_HINTING_MINIMAL \
+ ( ((TT_Driver)FT_FACE_DRIVER( exc->face ))->interpreter_version == \
+ TT_INTERPRETER_VERSION_40 )
+#endif
#define PROJECT( v1, v2 ) \
exc->func_project( exc, (v1)->x - (v2)->x, (v1)->y - (v2)->y )
exec->stackSize = 0;
exec->glyphSize = 0;
- exec->stack = NULL;
- exec->glyphIns = NULL;
+ exec->stack = NULL;
+ exec->glyphIns = NULL;
exec->face = NULL;
exec->size = NULL;
static FT_Short
GetShortIns( TT_ExecContext exc )
{
- /* Reading a byte stream so there is no endianess (DaveP) */
+ /* Reading a byte stream so there is no endianness (DaveP) */
exc->IP += 2;
return (FT_Short)( ( exc->code[exc->IP - 2] << 8 ) +
exc->code[exc->IP - 1] );
/* <InOut> */
/* zone :: The affected glyph zone. */
/* */
+ /* <Note> */
+ /* See `ttinterp.h' for details on backwards compatibility mode. */
+ /* `Touches' the point. */
+ /* */
static void
Direct_Move( TT_ExecContext exc,
TT_GlyphZone zone,
if ( v != 0 )
{
-#ifdef TT_CONFIG_OPTION_SUBPIXEL_HINTING
- if ( !SUBPIXEL_HINTING ||
+#ifdef TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY
+ if ( SUBPIXEL_HINTING_INFINALITY &&
( !exc->ignore_x_mode ||
( exc->sph_tweak_flags & SPH_TWEAK_ALLOW_X_DMOVE ) ) )
-#endif /* TT_CONFIG_OPTION_SUBPIXEL_HINTING */
+ zone->cur[point].x += FT_MulDiv( distance, v, exc->F_dot_P );
+ else
+#endif /* TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY */
+
+#ifdef TT_SUPPORT_SUBPIXEL_HINTING_MINIMAL
+ /* Exception to the post-IUP curfew: Allow the x component of */
+ /* diagonal moves, but only post-IUP. DejaVu tries to adjust */
+ /* diagonal stems like on `Z' and `z' post-IUP. */
+ if ( SUBPIXEL_HINTING_MINIMAL && !exc->backwards_compatibility )
+ zone->cur[point].x += FT_MulDiv( distance, v, exc->F_dot_P );
+ else
+#endif
+
+ if ( NO_SUBPIXEL_HINTING )
zone->cur[point].x += FT_MulDiv( distance, v, exc->F_dot_P );
zone->tags[point] |= FT_CURVE_TAG_TOUCH_X;
if ( v != 0 )
{
- zone->cur[point].y += FT_MulDiv( distance, v, exc->F_dot_P );
+#ifdef TT_SUPPORT_SUBPIXEL_HINTING_MINIMAL
+ if ( !( SUBPIXEL_HINTING_MINIMAL &&
+ exc->backwards_compatibility &&
+ exc->iupx_called &&
+ exc->iupy_called ) )
+#endif
+ zone->cur[point].y += FT_MulDiv( distance, v, exc->F_dot_P );
zone->tags[point] |= FT_CURVE_TAG_TOUCH_Y;
}
/* */
/* The following versions are used whenever both vectors are both */
/* along one of the coordinate unit vectors, i.e. in 90% of the cases. */
+ /* See `ttinterp.h' for details on backwards compatibility mode. */
/* */
/*************************************************************************/
FT_UShort point,
FT_F26Dot6 distance )
{
- FT_UNUSED( exc );
+#ifdef TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY
+ if ( SUBPIXEL_HINTING_INFINALITY && !exc->ignore_x_mode )
+ zone->cur[point].x += distance;
+ else
+#endif /* TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY */
+
+#ifdef TT_SUPPORT_SUBPIXEL_HINTING_MINIMAL
+ if ( SUBPIXEL_HINTING_MINIMAL && !exc->backwards_compatibility )
+ zone->cur[point].x += distance;
+ else
+#endif
-#ifdef TT_CONFIG_OPTION_SUBPIXEL_HINTING
- if ( !SUBPIXEL_HINTING ||
- !exc->ignore_x_mode )
-#endif /* TT_CONFIG_OPTION_SUBPIXEL_HINTING */
+ if ( NO_SUBPIXEL_HINTING )
zone->cur[point].x += distance;
zone->tags[point] |= FT_CURVE_TAG_TOUCH_X;
{
FT_UNUSED( exc );
- zone->cur[point].y += distance;
- zone->tags[point] |= FT_CURVE_TAG_TOUCH_Y;
+#ifdef TT_SUPPORT_SUBPIXEL_HINTING_MINIMAL
+ if ( !( SUBPIXEL_HINTING_MINIMAL &&
+ exc->backwards_compatibility &&
+ exc->iupx_called && exc->iupy_called ) )
+#endif
+ zone->cur[point].y += distance;
+
+ zone->tags[point] |= FT_CURVE_TAG_TOUCH_Y;
}
FT_F26Dot6 distance,
FT_F26Dot6 compensation )
{
- FT_F26Dot6 val;
+ FT_F26Dot6 val;
FT_UNUSED( exc );
/* Rounded distance. */
/* */
/* <Note> */
- /* The TrueType specification says very few about the relationship */
+ /* The TrueType specification says very little about the relationship */
/* between rounding and engine compensation. However, it seems from */
/* the description of super round that we should add the compensation */
/* before rounding. */
Ins_RS( TT_ExecContext exc,
FT_Long* args )
{
-#ifdef TT_CONFIG_OPTION_SUBPIXEL_HINTING
-
FT_ULong I = (FT_ULong)args[0];
}
else
{
+#ifdef TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY
/* subpixel hinting - avoid Typeman Dstroke and */
/* IStroke and Vacuform rounds */
- if ( SUBPIXEL_HINTING &&
+ if ( SUBPIXEL_HINTING_INFINALITY &&
exc->ignore_x_mode &&
( ( I == 24 &&
( exc->face->sph_found_func_flags &
exc->iup_called ) ) )
args[0] = 0;
else
+#endif /* TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY */
args[0] = exc->storage[I];
}
-
-#else /* !TT_CONFIG_OPTION_SUBPIXEL_HINTING */
-
- FT_ULong I = (FT_ULong)args[0];
-
-
- if ( BOUNDSL( I, exc->storeSize ) )
- {
- if ( exc->pedantic_hinting )
- ARRAY_BOUND_ERROR;
- else
- args[0] = 0;
- }
- else
- args[0] = exc->storage[I];
-
-#endif /* !TT_CONFIG_OPTION_SUBPIXEL_HINTING */
}
TT_DefRecord* rec;
TT_DefRecord* limit;
-#ifdef TT_CONFIG_OPTION_SUBPIXEL_HINTING
+#ifdef TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY
/* arguments to opcodes are skipped by `SKIP_Code' */
FT_Byte opcode_pattern[9][12] = {
/* #0 inline delta function 1 */
FT_UShort opcode_pointer[9] = { 0, 0, 0, 0, 0, 0, 0, 0, 0 };
FT_UShort opcode_size[9] = { 12, 8, 8, 6, 7, 4, 5, 4, 2 };
FT_UShort i;
-#endif /* TT_CONFIG_OPTION_SUBPIXEL_HINTING */
+#endif /* TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY */
/* some font programs are broken enough to redefine functions! */
if ( n > exc->maxFunc )
exc->maxFunc = (FT_UInt16)n;
-#ifdef TT_CONFIG_OPTION_SUBPIXEL_HINTING
+#ifdef TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY
/* We don't know for sure these are typeman functions, */
/* however they are only active when RS 22 is called */
if ( n >= 64 && n <= 66 )
while ( SkipCode( exc ) == SUCCESS )
{
-#ifdef TT_CONFIG_OPTION_SUBPIXEL_HINTING
+#ifdef TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY
- if ( SUBPIXEL_HINTING )
+ if ( SUBPIXEL_HINTING_INFINALITY )
{
for ( i = 0; i < opcode_patterns; i++ )
{
( exc->face->sph_found_func_flags & SPH_FDEF_INLINE_DELTA_2 ) );
}
-#endif /* TT_CONFIG_OPTION_SUBPIXEL_HINTING */
+#endif /* TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY */
switch ( exc->opcode )
{
TT_CallRec* pRec;
-#ifdef TT_CONFIG_OPTION_SUBPIXEL_HINTING
+#ifdef TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY
exc->sph_in_func_flags = 0x0000;
-#endif /* TT_CONFIG_OPTION_SUBPIXEL_HINTING */
+#endif /* TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY */
if ( exc->callTop <= 0 ) /* We encountered an ENDF without a call */
{
if ( !def->active )
goto Fail;
-#ifdef TT_CONFIG_OPTION_SUBPIXEL_HINTING
- if ( SUBPIXEL_HINTING &&
+#ifdef TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY
+ if ( SUBPIXEL_HINTING_INFINALITY &&
exc->ignore_x_mode &&
( ( exc->iup_called &&
( exc->sph_tweak_flags & SPH_TWEAK_NO_CALL_AFTER_IUP ) ) ||
goto Fail;
else
exc->sph_in_func_flags = def->sph_fdef_flags;
-#endif /* TT_CONFIG_OPTION_SUBPIXEL_HINTING */
+#endif /* TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY */
/* check the call stack */
if ( exc->callTop >= exc->callSize )
if ( !def->active )
goto Fail;
-#ifdef TT_CONFIG_OPTION_SUBPIXEL_HINTING
- if ( SUBPIXEL_HINTING &&
+#ifdef TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY
+ if ( SUBPIXEL_HINTING_INFINALITY &&
exc->ignore_x_mode &&
( def->sph_fdef_flags & SPH_FDEF_VACUFORM_ROUND_1 ) )
goto Fail;
else
exc->sph_in_func_flags = def->sph_fdef_flags;
-#endif /* TT_CONFIG_OPTION_SUBPIXEL_HINTING */
+#endif /* TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY */
/* check stack */
if ( exc->callTop >= exc->callSize )
}
}
-#ifdef TT_CONFIG_OPTION_SUBPIXEL_HINTING
+#ifdef TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY
/* Disable Type 2 Vacuform Rounds - e.g. Arial Narrow */
- if ( SUBPIXEL_HINTING &&
- exc->ignore_x_mode &&
- FT_ABS( D ) == 64 )
+ if ( SUBPIXEL_HINTING_INFINALITY &&
+ exc->ignore_x_mode &&
+ FT_ABS( D ) == 64 )
D += 1;
-#endif /* TT_CONFIG_OPTION_SUBPIXEL_HINTING */
+#endif /* TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY */
args[0] = D;
}
exc->GS.instruct_control &= ~(FT_Byte)Kf;
exc->GS.instruct_control |= (FT_Byte)L;
-#ifdef TT_CONFIG_OPTION_SUBPIXEL_HINTING
- /* INSTCTRL modifying flag 3 also has an effect */
- /* outside of the CVT program */
if ( K == 3 )
- exc->ignore_x_mode = FT_BOOL( L == 4 );
+ {
+#ifdef TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY
+ /* INSTCTRL modifying flag 3 also has an effect */
+ /* outside of the CVT program */
+ if ( SUBPIXEL_HINTING_INFINALITY )
+ exc->ignore_x_mode = FT_BOOL( L == 4 );
+#endif
+
+#ifdef TT_SUPPORT_SUBPIXEL_HINTING_MINIMAL
+ /* Native ClearType fonts sign a waiver that turns off all backwards */
+ /* compatibility hacks and lets them program points to the grid like */
+ /* it's 1996. They might sign a waiver for just one glyph, though. */
+ if ( SUBPIXEL_HINTING_MINIMAL )
+ exc->backwards_compatibility = !FT_BOOL( L == 4 );
#endif
+ }
}
FT_UShort point;
+#ifdef TT_SUPPORT_SUBPIXEL_HINTING_MINIMAL
+ /* See `ttinterp.h' for details on backwards compatibility mode. */
+ if ( SUBPIXEL_HINTING_MINIMAL &&
+ exc->backwards_compatibility &&
+ exc->iupx_called &&
+ exc->iupy_called )
+ goto Fail;
+#endif
+
if ( exc->top < exc->GS.loop )
{
if ( exc->pedantic_hinting )
FT_UShort I, K, L;
+#ifdef TT_SUPPORT_SUBPIXEL_HINTING_MINIMAL
+ /* See `ttinterp.h' for details on backwards compatibility mode. */
+ if ( SUBPIXEL_HINTING_MINIMAL &&
+ exc->backwards_compatibility &&
+ exc->iupx_called &&
+ exc->iupy_called )
+ return;
+#endif
+
K = (FT_UShort)args[1];
L = (FT_UShort)args[0];
FT_UShort I, K, L;
+#ifdef TT_SUPPORT_SUBPIXEL_HINTING_MINIMAL
+ /* See `ttinterp.h' for details on backwards compatibility mode. */
+ if ( SUBPIXEL_HINTING_MINIMAL &&
+ exc->backwards_compatibility &&
+ exc->iupx_called &&
+ exc->iupy_called )
+ return;
+#endif
+
K = (FT_UShort)args[1];
L = (FT_UShort)args[0];
}
+ /* See `ttinterp.h' for details on backwards compatibility mode. */
static void
Move_Zp2_Point( TT_ExecContext exc,
FT_UShort point,
{
if ( exc->GS.freeVector.x != 0 )
{
- exc->zp2.cur[point].x += dx;
+#ifdef TT_SUPPORT_SUBPIXEL_HINTING_MINIMAL
+ if ( !( SUBPIXEL_HINTING_MINIMAL &&
+ exc->backwards_compatibility ) )
+#endif
+ exc->zp2.cur[point].x += dx;
+
if ( touch )
exc->zp2.tags[point] |= FT_CURVE_TAG_TOUCH_X;
}
if ( exc->GS.freeVector.y != 0 )
{
- exc->zp2.cur[point].y += dy;
+#ifdef TT_SUPPORT_SUBPIXEL_HINTING_MINIMAL
+ if ( !( SUBPIXEL_HINTING_MINIMAL &&
+ exc->backwards_compatibility &&
+ exc->iupx_called &&
+ exc->iupy_called ) )
+#endif
+ exc->zp2.cur[point].y += dy;
+
if ( touch )
exc->zp2.tags[point] |= FT_CURVE_TAG_TOUCH_Y;
}
}
}
else
-#ifdef TT_CONFIG_OPTION_SUBPIXEL_HINTING
+#ifdef TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY
/* doesn't follow Cleartype spec but produces better result */
- if ( SUBPIXEL_HINTING &&
- exc->ignore_x_mode )
+ if ( SUBPIXEL_HINTING_INFINALITY && exc->ignore_x_mode )
Move_Zp2_Point( exc, point, 0, dy, TRUE );
else
-#endif /* TT_CONFIG_OPTION_SUBPIXEL_HINTING */
+#endif /* TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY */
Move_Zp2_Point( exc, point, dx, dy, TRUE );
exc->GS.loop--;
{
FT_F26Dot6 dx, dy;
FT_UShort point;
-#ifdef TT_CONFIG_OPTION_SUBPIXEL_HINTING
+#ifdef TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY
FT_Int B1, B2;
#endif
+#ifdef TT_SUPPORT_SUBPIXEL_HINTING_MINIMAL
+ FT_Bool in_twilight = exc->GS.gep0 == 0 || \
+ exc->GS.gep1 == 0 || \
+ exc->GS.gep2 == 0;
+#endif
+
if ( exc->top < exc->GS.loop + 1 )
}
}
else
-#ifdef TT_CONFIG_OPTION_SUBPIXEL_HINTING
+#ifdef TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY
+ if ( SUBPIXEL_HINTING_INFINALITY )
{
/* If not using ignore_x_mode rendering, allow ZP2 move. */
/* If inline deltas aren't allowed, skip ZP2 move. */
/* - the glyph is specifically set to allow SHPIX moves */
/* - the move is on a previously Y-touched point */
- if ( SUBPIXEL_HINTING &&
- exc->ignore_x_mode )
+ if ( exc->ignore_x_mode )
{
/* save point for later comparison */
if ( exc->GS.freeVector.y != 0 )
else
Move_Zp2_Point( exc, point, dx, dy, TRUE );
}
+ else
+#endif
+#ifdef TT_SUPPORT_SUBPIXEL_HINTING_MINIMAL
+ if ( SUBPIXEL_HINTING_MINIMAL &&
+ exc->backwards_compatibility )
+ {
+ /* Special case: allow SHPIX to move points in the twilight zone. */
+ /* Otherwise, treat SHPIX the same as DELTAP. Unbreaks various */
+ /* fonts such as older versions of Rokkitt and DTL Argo T Light */
+ /* that would glitch severly after calling ALIGNRP after a blocked */
+ /* SHPIX. */
+ if ( in_twilight ||
+ ( !( exc->iupx_called && exc->iupy_called ) &&
+ ( ( exc->is_composite && exc->GS.freeVector.y != 0 ) ||
+ ( exc->zp2.tags[point] & FT_CURVE_TAG_TOUCH_Y ) ) ) )
+ Move_Zp2_Point( exc, point, 0, dy, TRUE );
+ }
+ else
+#endif
+ Move_Zp2_Point( exc, point, dx, dy, TRUE );
+#ifdef TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY
Skip:
-
-#else /* !TT_CONFIG_OPTION_SUBPIXEL_HINTING */
-
- Move_Zp2_Point( exc, point, dx, dy, TRUE );
-
-#endif /* !TT_CONFIG_OPTION_SUBPIXEL_HINTING */
-
+#endif
exc->GS.loop--;
}
Ins_MSIRP( TT_ExecContext exc,
FT_Long* args )
{
- FT_UShort point;
+ FT_UShort point = 0;
FT_F26Dot6 distance;
-
-#ifdef TT_CONFIG_OPTION_SUBPIXEL_HINTING
- FT_F26Dot6 control_value_cutin = 0; /* pacify compiler */
+#ifdef TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY
+ FT_F26Dot6 control_value_cutin = 0;
- if ( SUBPIXEL_HINTING )
+ if ( SUBPIXEL_HINTING_INFINALITY )
{
control_value_cutin = exc->GS.control_value_cutin;
!( exc->sph_tweak_flags & SPH_TWEAK_NORMAL_ROUND ) )
control_value_cutin = 0;
}
-
-#endif /* TT_CONFIG_OPTION_SUBPIXEL_HINTING */
+#endif /* TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY */
point = (FT_UShort)args[0];
distance = PROJECT( exc->zp1.cur + point, exc->zp0.cur + exc->GS.rp0 );
-#ifdef TT_CONFIG_OPTION_SUBPIXEL_HINTING
+#ifdef TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY
/* subpixel hinting - make MSIRP respect CVT cut-in; */
- if ( SUBPIXEL_HINTING &&
+ if ( SUBPIXEL_HINTING_INFINALITY &&
exc->ignore_x_mode &&
exc->GS.freeVector.x != 0 &&
FT_ABS( distance - args[1] ) >= control_value_cutin )
distance = args[1];
-#endif /* TT_CONFIG_OPTION_SUBPIXEL_HINTING */
+#endif /* TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY */
exc->func_move( exc, &exc->zp1, point, args[1] - distance );
if ( ( exc->opcode & 1 ) != 0 )
{
cur_dist = FAST_PROJECT( &exc->zp0.cur[point] );
-#ifdef TT_CONFIG_OPTION_SUBPIXEL_HINTING
- if ( SUBPIXEL_HINTING &&
- exc->ignore_x_mode &&
- exc->GS.freeVector.x != 0 )
+#ifdef TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY
+ if ( SUBPIXEL_HINTING_INFINALITY &&
+ exc->ignore_x_mode &&
+ exc->GS.freeVector.x != 0 )
distance = Round_None(
exc,
cur_dist,
cvtEntry = (FT_ULong)args[1];
point = (FT_UShort)args[0];
-#ifdef TT_CONFIG_OPTION_SUBPIXEL_HINTING
- if ( SUBPIXEL_HINTING &&
+#ifdef TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY
+ if ( SUBPIXEL_HINTING_INFINALITY &&
exc->ignore_x_mode &&
exc->GS.freeVector.x != 0 &&
exc->GS.freeVector.y == 0 &&
!( exc->sph_tweak_flags & SPH_TWEAK_NORMAL_ROUND ) )
control_value_cutin = 0;
-#endif /* TT_CONFIG_OPTION_SUBPIXEL_HINTING */
+#endif /* TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY */
if ( BOUNDS( point, exc->zp0.n_points ) ||
BOUNDSL( cvtEntry, exc->cvtSize ) )
if ( exc->GS.gep0 == 0 ) /* If in twilight zone */
{
-#ifdef TT_CONFIG_OPTION_SUBPIXEL_HINTING
+#ifdef TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY
/* Only adjust if not in sph_compatibility_mode or ignore_x_mode. */
/* Determined via experimentation and may be incorrect... */
- if ( !SUBPIXEL_HINTING ||
- ( !exc->ignore_x_mode ||
- !exc->face->sph_compatibility_mode ) )
-#endif /* TT_CONFIG_OPTION_SUBPIXEL_HINTING */
+ if ( !( SUBPIXEL_HINTING_INFINALITY &&
+ ( exc->ignore_x_mode &&
+ exc->face->sph_compatibility_mode ) ) )
+#endif /* TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY */
exc->zp0.org[point].x = TT_MulFix14( distance,
exc->GS.freeVector.x );
exc->zp0.org[point].y = TT_MulFix14( distance,
exc->GS.freeVector.y ),
exc->zp0.cur[point] = exc->zp0.org[point];
}
-#ifdef TT_CONFIG_OPTION_SUBPIXEL_HINTING
- if ( SUBPIXEL_HINTING &&
+#ifdef TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY
+ if ( SUBPIXEL_HINTING_INFINALITY &&
exc->ignore_x_mode &&
( exc->sph_tweak_flags & SPH_TWEAK_MIAP_HACK ) &&
distance > 0 &&
exc->GS.freeVector.y != 0 )
distance = 0;
-#endif /* TT_CONFIG_OPTION_SUBPIXEL_HINTING */
+#endif /* TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY */
org_dist = FAST_PROJECT( &exc->zp0.cur[point] );
if ( FT_ABS( distance - org_dist ) > control_value_cutin )
distance = org_dist;
-#ifdef TT_CONFIG_OPTION_SUBPIXEL_HINTING
- if ( SUBPIXEL_HINTING &&
- exc->ignore_x_mode &&
- exc->GS.freeVector.x != 0 )
+#ifdef TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY
+ if ( SUBPIXEL_HINTING_INFINALITY &&
+ exc->ignore_x_mode &&
+ exc->GS.freeVector.x != 0 )
distance = Round_None( exc,
distance,
exc->tt_metrics.compensations[0] );
Ins_MDRP( TT_ExecContext exc,
FT_Long* args )
{
- FT_UShort point;
+ FT_UShort point = 0;
FT_F26Dot6 org_dist, distance, minimum_distance;
minimum_distance = exc->GS.minimum_distance;
-#ifdef TT_CONFIG_OPTION_SUBPIXEL_HINTING
- if ( SUBPIXEL_HINTING &&
+#ifdef TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY
+ if ( SUBPIXEL_HINTING_INFINALITY &&
exc->ignore_x_mode &&
exc->GS.freeVector.x != 0 &&
!( exc->sph_tweak_flags & SPH_TWEAK_NORMAL_ROUND ) )
minimum_distance = 0;
-#endif /* TT_CONFIG_OPTION_SUBPIXEL_HINTING */
+#endif /* TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY */
point = (FT_UShort)args[0];
if ( ( exc->opcode & 4 ) != 0 )
{
-#ifdef TT_CONFIG_OPTION_SUBPIXEL_HINTING
- if ( SUBPIXEL_HINTING &&
- exc->ignore_x_mode &&
- exc->GS.freeVector.x != 0 )
+#ifdef TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY
+ if ( SUBPIXEL_HINTING_INFINALITY &&
+ exc->ignore_x_mode &&
+ exc->GS.freeVector.x != 0 )
distance = Round_None(
exc,
org_dist,
org_dist,
control_value_cutin,
minimum_distance;
-#ifdef TT_CONFIG_OPTION_SUBPIXEL_HINTING
+#ifdef TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY
FT_Int B1 = 0; /* pacify compiler */
FT_Int B2 = 0;
FT_Bool reverse_move = FALSE;
-#endif /* TT_CONFIG_OPTION_SUBPIXEL_HINTING */
+#endif /* TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY */
minimum_distance = exc->GS.minimum_distance;
point = (FT_UShort)args[0];
cvtEntry = (FT_ULong)( args[1] + 1 );
-#ifdef TT_CONFIG_OPTION_SUBPIXEL_HINTING
- if ( SUBPIXEL_HINTING &&
+#ifdef TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY
+ if ( SUBPIXEL_HINTING_INFINALITY &&
exc->ignore_x_mode &&
exc->GS.freeVector.x != 0 &&
!( exc->sph_tweak_flags & SPH_TWEAK_NORMAL_ROUND ) )
control_value_cutin = minimum_distance = 0;
-#endif /* TT_CONFIG_OPTION_SUBPIXEL_HINTING */
+ else
+#endif /* TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY */
/* XXX: UNDOCUMENTED! cvt[-1] = 0 always */
cvt_dist = -cvt_dist;
}
-#ifdef TT_CONFIG_OPTION_SUBPIXEL_HINTING
- if ( SUBPIXEL_HINTING &&
+#ifdef TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY
+ if ( SUBPIXEL_HINTING_INFINALITY &&
exc->ignore_x_mode &&
exc->GS.freeVector.y != 0 &&
( exc->sph_tweak_flags & SPH_TWEAK_TIMES_NEW_ROMAN_HACK ) )
else if ( cur_dist > 64 && cur_dist < 84 )
cvt_dist += 32;
}
-#endif /* TT_CONFIG_OPTION_SUBPIXEL_HINTING */
+#endif /* TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY */
/* control value cut-in and round */
else
{
-#ifdef TT_CONFIG_OPTION_SUBPIXEL_HINTING
+#ifdef TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY
/* do cvt cut-in always in MIRP for sph */
- if ( SUBPIXEL_HINTING &&
+ if ( SUBPIXEL_HINTING_INFINALITY &&
exc->ignore_x_mode &&
exc->GS.gep0 == exc->GS.gep1 )
{
if ( FT_ABS( cvt_dist - org_dist ) > control_value_cutin )
cvt_dist = org_dist;
}
-#endif /* TT_CONFIG_OPTION_SUBPIXEL_HINTING */
+#endif /* TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY */
distance = Round_None(
exc,
}
}
-#ifdef TT_CONFIG_OPTION_SUBPIXEL_HINTING
- if ( SUBPIXEL_HINTING )
+#ifdef TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY
+ if ( SUBPIXEL_HINTING_INFINALITY )
{
B1 = exc->zp1.cur[point].y;
( exc->sph_tweak_flags & SPH_TWEAK_COURIER_NEW_2_HACK ) )
distance += 64;
}
-#endif /* TT_CONFIG_OPTION_SUBPIXEL_HINTING */
+#endif /* TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY */
exc->func_move( exc, &exc->zp1, point, distance - cur_dist );
-#ifdef TT_CONFIG_OPTION_SUBPIXEL_HINTING
- if ( SUBPIXEL_HINTING )
+#ifdef TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY
+ if ( SUBPIXEL_HINTING_INFINALITY )
{
B2 = exc->zp1.cur[point].y;
exc->func_move( exc, &exc->zp1, point, -( distance - cur_dist ) );
}
-#endif /* TT_CONFIG_OPTION_SUBPIXEL_HINTING */
+#endif /* TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY */
Fail:
exc->GS.rp1 = exc->GS.rp0;
FT_F26Dot6 distance;
-#ifdef TT_CONFIG_OPTION_SUBPIXEL_HINTING
- if ( SUBPIXEL_HINTING &&
+#ifdef TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY
+ if ( SUBPIXEL_HINTING_INFINALITY &&
exc->ignore_x_mode &&
exc->iup_called &&
( exc->sph_tweak_flags & SPH_TWEAK_NO_ALIGNRP_AFTER_IUP ) )
exc->error = FT_THROW( Invalid_Reference );
goto Fail;
}
-#endif /* TT_CONFIG_OPTION_SUBPIXEL_HINTING */
+#endif /* TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY */
if ( exc->top < exc->GS.loop ||
BOUNDS( exc->GS.rp0, exc->zp0.n_points ) )
R.x = FT_MulDiv( val, dax, discriminant );
R.y = FT_MulDiv( val, day, discriminant );
+ /* XXX: Block in backwards_compatibility and/or post-IUP? */
exc->zp2.cur[point].x = exc->zp1.cur[a0].x + R.x;
exc->zp2.cur[point].y = exc->zp1.cur[a0].y + R.y;
}
{
/* else, take the middle of the middles of A and B */
+ /* XXX: Block in backwards_compatibility and/or post-IUP? */
exc->zp2.cur[point].x = ( exc->zp1.cur[a0].x +
exc->zp1.cur[a1].x +
exc->zp0.cur[b0].x +
FT_Short contour; /* current contour */
+#ifdef TT_SUPPORT_SUBPIXEL_HINTING_MINIMAL
+ /* See `ttinterp.h' for details on backwards compatibility mode. */
+ /* Allow IUP until it has been called on both axes. Immediately */
+ /* return on subsequent ones. */
+ if ( SUBPIXEL_HINTING_MINIMAL &&
+ exc->backwards_compatibility )
+ {
+ if ( exc->iupx_called && exc->iupy_called )
+ return;
+
+ if ( exc->opcode & 1 )
+ exc->iupx_called = TRUE;
+ else
+ exc->iupy_called = TRUE;
+ }
+#endif
+
/* ignore empty outlines */
if ( exc->pts.n_contours == 0 )
return;
contour = 0;
point = 0;
-#ifdef TT_CONFIG_OPTION_SUBPIXEL_HINTING
- if ( SUBPIXEL_HINTING &&
- exc->ignore_x_mode )
+#ifdef TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY
+ if ( SUBPIXEL_HINTING_INFINALITY &&
+ exc->ignore_x_mode )
{
exc->iup_called = TRUE;
if ( exc->sph_tweak_flags & SPH_TWEAK_SKIP_IUP )
return;
}
-#endif /* TT_CONFIG_OPTION_SUBPIXEL_HINTING */
+#endif /* TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY */
do
{
FT_UShort A;
FT_ULong C, P;
FT_Long B;
-#ifdef TT_CONFIG_OPTION_SUBPIXEL_HINTING
+#ifdef TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY
FT_UShort B1, B2;
- if ( SUBPIXEL_HINTING &&
+ if ( SUBPIXEL_HINTING_INFINALITY &&
exc->ignore_x_mode &&
exc->iup_called &&
( exc->sph_tweak_flags & SPH_TWEAK_NO_DELTAP_AFTER_IUP ) )
goto Fail;
-#endif /* TT_CONFIG_OPTION_SUBPIXEL_HINTING */
+#endif /* TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY */
P = (FT_ULong)exc->func_cur_ppem( exc );
nump = (FT_ULong)args[0]; /* some points theoretically may occur more
B++;
B *= 1L << ( 6 - exc->GS.delta_shift );
-#ifdef TT_CONFIG_OPTION_SUBPIXEL_HINTING
+#ifdef TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY
- if ( SUBPIXEL_HINTING )
+ if ( SUBPIXEL_HINTING_INFINALITY )
{
/*
* Allow delta move if
}
}
else
-#endif /* TT_CONFIG_OPTION_SUBPIXEL_HINTING */
+#endif /* TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY */
- exc->func_move( exc, &exc->zp0, A, B );
+ {
+
+#ifdef TT_SUPPORT_SUBPIXEL_HINTING_MINIMAL
+ /* See `ttinterp.h' for details on backwards compatibility */
+ /* mode. */
+ if ( SUBPIXEL_HINTING_MINIMAL &&
+ exc->backwards_compatibility )
+ {
+ if ( !( exc->iupx_called && exc->iupy_called ) &&
+ ( ( exc->is_composite && exc->GS.freeVector.y != 0 ) ||
+ ( exc->zp0.tags[A] & FT_CURVE_TAG_TOUCH_Y ) ) )
+ exc->func_move( exc, &exc->zp0, A, B );
+ }
+ else
+#endif
+ exc->func_move( exc, &exc->zp0, A, B );
+ }
}
}
else
Ins_GETINFO( TT_ExecContext exc,
FT_Long* args )
{
- FT_Long K;
+ FT_Long K;
+ TT_Driver driver = (TT_Driver)FT_FACE_DRIVER( exc->face );
K = 0;
-#ifdef TT_CONFIG_OPTION_SUBPIXEL_HINTING
+#ifdef TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY
/********************************/
/* RASTERIZER VERSION */
/* Selector Bit: 0 */
/* Return Bit(s): 0-7 */
/* */
- if ( SUBPIXEL_HINTING &&
- ( args[0] & 1 ) != 0 &&
- exc->subpixel_hinting )
+ if ( SUBPIXEL_HINTING_INFINALITY &&
+ ( args[0] & 1 ) != 0 &&
+ exc->subpixel_hinting )
{
if ( exc->ignore_x_mode )
{
K = TT_INTERPRETER_VERSION_38;
}
else
-#endif /* TT_CONFIG_OPTION_SUBPIXEL_HINTING */
+#endif /* TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY */
if ( ( args[0] & 1 ) != 0 )
- K = TT_INTERPRETER_VERSION_35;
+ K = driver->interpreter_version;
/********************************/
/* GLYPH ROTATED */
K |= 1 << 8;
/********************************/
- /* HINTING FOR GRAYSCALE */
+ /* BI-LEVEL HINTING AND */
+ /* GRAYSCALE RENDERING */
/* Selector Bit: 5 */
/* Return Bit(s): 12 */
/* */
if ( ( args[0] & 32 ) != 0 && exc->grayscale )
K |= 1 << 12;
-#ifdef TT_CONFIG_OPTION_SUBPIXEL_HINTING
+#ifdef TT_SUPPORT_SUBPIXEL_HINTING_MINIMAL
+ if ( SUBPIXEL_HINTING_MINIMAL )
+ {
+ /********************************/
+ /* HINTING FOR SUBPIXEL */
+ /* Selector Bit: 6 */
+ /* Return Bit(s): 13 */
+ /* */
+ /* v40 does subpixel hinting by default. */
+ if ( ( args[0] & 64 ) != 0 )
+ K |= 1 << 13;
+
+ /********************************/
+ /* VERTICAL LCD SUBPIXELS? */
+ /* Selector Bit: 8 */
+ /* Return Bit(s): 15 */
+ /* */
+ if ( ( args[0] & 256 ) != 0 && exc->vertical_lcd_lean )
+ K |= 1 << 15;
+
+ /********************************/
+ /* SUBPIXEL POSITIONED? */
+ /* Selector Bit: 10 */
+ /* Return Bit(s): 17 */
+ /* */
+ /* XXX: FreeType supports it, dependent on what client does? */
+ if ( ( args[0] & 1024 ) != 0 )
+ K |= 1 << 17;
+
+ /********************************/
+ /* SYMMETRICAL SMOOTHING */
+ /* Selector Bit: 11 */
+ /* Return Bit(s): 18 */
+ /* */
+ /* The only smoothing method FreeType supports unless someone sets */
+ /* FT_LOAD_TARGET_MONO. */
+ if ( ( args[0] & 2048 ) != 0 )
+ K |= 1 << 18;
+
+ /********************************/
+ /* CLEARTYPE HINTING AND */
+ /* GRAYSCALE RENDERING */
+ /* Selector Bit: 12 */
+ /* Return Bit(s): 19 */
+ /* */
+ /* Grayscale rendering is what FreeType does anyway unless someone */
+ /* sets FT_LOAD_TARGET_MONO or FT_LOAD_TARGET_LCD(_V) */
+ if ( ( args[0] & 4096 ) != 0 && exc->grayscale_cleartype )
+ K |= 1 << 19;
+ }
+#endif
+
+#ifdef TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY
- if ( SUBPIXEL_HINTING &&
+ if ( SUBPIXEL_HINTING_INFINALITY &&
exc->rasterizer_version >= TT_INTERPRETER_VERSION_35 )
{
}
}
-#endif /* TT_CONFIG_OPTION_SUBPIXEL_HINTING */
+#endif /* TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY */
args[0] = K;
}
FT_Long ins_counter = 0; /* executed instructions counter */
FT_UShort i;
-#ifdef TT_CONFIG_OPTION_SUBPIXEL_HINTING
+#ifdef TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY
FT_Byte opcode_pattern[1][2] = {
/* #8 TypeMan Talk Align */
{
FT_UShort opcode_patterns = 1;
FT_UShort opcode_pointer[1] = { 0 };
FT_UShort opcode_size[1] = { 1 };
-#endif /* TT_CONFIG_OPTION_SUBPIXEL_HINTING */
+#endif /* TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY */
-#ifdef TT_CONFIG_OPTION_SUBPIXEL_HINTING
+#ifdef TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY
exc->iup_called = FALSE;
-#endif /* TT_CONFIG_OPTION_SUBPIXEL_HINTING */
+#endif /* TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY */
+
+#ifdef TT_SUPPORT_SUBPIXEL_HINTING_MINIMAL
+ /* Toggle backwards compatibility according to what font says, except */
+ /* when it's a `tricky' font that heavily relies on the interpreter to */
+ /* render glyphs correctly, e.g. DFKai-SB. Backwards compatibility */
+ /* hacks may break it. */
+ if ( SUBPIXEL_HINTING_MINIMAL &&
+ !FT_IS_TRICKY( &exc->face->root ) )
+ exc->backwards_compatibility = !( exc->GS.instruct_control & 4 );
+ else
+ exc->backwards_compatibility = FALSE;
+
+ exc->iupx_called = FALSE;
+ exc->iupy_called = FALSE;
+#endif
/* set PPEM and CVT functions */
exc->tt_metrics.ratio = 0;
exc->step_ins = TRUE;
exc->error = FT_Err_Ok;
-#ifdef TT_CONFIG_OPTION_SUBPIXEL_HINTING
+#ifdef TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY
- if ( SUBPIXEL_HINTING )
+ if ( SUBPIXEL_HINTING_INFINALITY )
{
for ( i = 0; i < opcode_patterns; i++ )
{
}
}
-#endif /* TT_CONFIG_OPTION_SUBPIXEL_HINTING */
+#endif /* TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY */
{
FT_Long* args = exc->stack + exc->args;
} TT_CallRec, *TT_CallStack;
-#ifdef TT_CONFIG_OPTION_SUBPIXEL_HINTING
+#ifdef TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY
/*************************************************************************/
/* */
} SPH_Font_Class;
-#endif /* TT_CONFIG_OPTION_SUBPIXEL_HINTING */
+#endif /* TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY */
/*************************************************************************/
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) */
- FT_Bool grayscale; /* are we hinting for grayscale? */
-
-#ifdef TT_CONFIG_OPTION_SUBPIXEL_HINTING
+ FT_Bool grayscale; /* bi-level hinting and */
+ /* grayscale rendering */
+
+#ifdef TT_SUPPORT_SUBPIXEL_HINTING_MINIMAL
+ /*
+ * Modern TrueType fonts are usually rendered through Microsoft's
+ * collection of rendering techniques called ClearType (e.g., subpixel
+ * rendering and subpixel hinting). When ClearType was introduced, most
+ * fonts were not ready. Microsoft decided to implement a backwards
+ * compatibility mode that employed several simple to complicated
+ * assumptions and tricks that modified the interpretation of the
+ * bytecode contained in these fonts to make them look ClearType-y
+ * somehow. Most (web)fonts that were released since then have come to
+ * rely on these hacks to render correctly, even some of Microsoft's
+ * flagship ClearType fonts (Calibri, Cambria, Segoe UI).
+ *
+ * The minimal subpixel hinting code (interpreter version 40) employs a
+ * small list of font-agnostic hacks to bludgeon non-native-ClearType
+ * fonts (except tricky ones[1]) into submission. It will not try to
+ * toggle hacks for specific fonts for performance and complexity
+ * reasons. The focus is on modern (web)fonts rather than legacy fonts
+ * that were made for black-and-white rendering.
+ *
+ * Major hacks
+ *
+ * - Any point movement on the x axis is ignored (cf. `Direct_Move' and
+ * `Direct_Move_X'). This has the smallest code footprint and single
+ * biggest effect. The ClearType way to increase resolution is
+ * supersampling the x axis, the FreeType way is ignoring instructions
+ * on the x axis, which gives the same result in the majority of
+ * cases.
+ *
+ * - Points are not moved post-IUP (neither on the x nor on the y axis),
+ * except the x component of diagonal moves post-IUP (cf.
+ * `Direct_Move', `Direct_Move_Y', `Move_Zp2_Point'). Post-IUP
+ * changes are commonly used to `fix' pixel patterns which has little
+ * use outside monochrome rendering.
+ *
+ * - SHPIX and DELTAP don't execute unless moving a composite on the
+ * y axis or moving a previously y touched point. SHPIX additionally
+ * denies movement on the x axis (cf. `Ins_SHPIX' and `Ins_DELTAP').
+ * Both instructions are commonly used to `fix' pixel patterns for
+ * monochrome or Windows's GDI rendering but make little sense for
+ * FreeType rendering. Both can distort the outline. See [2] for
+ * details.
+ *
+ * - The hdmx table and modifications to phantom points are ignored.
+ * Bearings and advance widths remain unchanged (except rounding them
+ * outside the interpreter!), cf. `compute_glyph_metrics' and
+ * `TT_Hint_Glyph'. Letting non-native-ClearType fonts modify spacing
+ * might mess up spacing.
+ *
+ * Minor hacks
+ *
+ * - FLIPRGON, FLIPRGOFF, and FLIPPT don't execute post-IUP. This
+ * prevents dents in e.g. Arial-Regular's `D' and `G' glyphs at
+ * various sizes.
+ *
+ * (Post-IUP is the state after both IUP[x] and IUP[y] have been
+ * executed.)
+ *
+ * The best results are achieved for fonts that were from the outset
+ * designed with ClearType in mind, meaning they leave the x axis mostly
+ * alone and don't mess with the `final' outline to produce more
+ * pleasing pixel patterns. The harder the designer tried to produce
+ * very specific patterns (`superhinting') for pre-ClearType-displays,
+ * the worse the results.
+ *
+ * Microsoft defines a way to turn off backwards compatibility and
+ * interpret instructions as before (called `native ClearType')[2][3].
+ * The font designer then regains full control and is responsible for
+ * making the font work correctly with ClearType without any
+ * hand-holding by the interpreter or rasterizer[4]. The v40
+ * interpreter assumes backwards compatibility by default, which can be
+ * turned off the same way by executing the following in the control
+ * program (cf. `Ins_INSTCTRL').
+ *
+ * #PUSH 4,3
+ * INSTCTRL[]
+ *
+ * [1] Tricky fonts as FreeType defines them rely on the bytecode
+ * interpreter to display correctly. Hacks can interfere with them,
+ * so they get treated like native ClearType fonts (v40 with
+ * backwards compatibility turned off). Cf. `TT_RunIns'.
+ *
+ * [2] Proposed by Microsoft's Greg Hitchcock in
+ * https://www.microsoft.com/typography/cleartype/truetypecleartype.aspx
+ *
+ * [3] Beat Stamm describes it in more detail:
+ * http://www.beatstamm.com/typography/RTRCh4.htm#Sec12
+ *
+ * [4] The list of `native ClearType' fonts is small at the time of this
+ * writing; I found the following on a Windows 10 Update 1511
+ * installation: Constantia, Corbel, Sitka, Malgun Gothic, Microsoft
+ * JhengHei (Bold and UI Bold), Microsoft YaHei (Bold and UI Bold),
+ * SimSun, NSimSun, and Yu Gothic.
+ *
+ */
+
+ /* Using v40 implies subpixel hinting. Used to detect interpreter */
+ /* version switches. `_lean' to differentiate from the Infinality */
+ /* `subpixel_hinting', which is managed differently. */
+ FT_Bool subpixel_hinting_lean;
+
+ /* Long side of a LCD subpixel is vertical (e.g., screen is rotated). */
+ /* `_lean' to differentiate from the Infinality `vertical_lcd', which */
+ /* is managed differently. */
+ FT_Bool vertical_lcd_lean;
+
+ /* Default to backwards compatibility mode in v40 interpreter. If */
+ /* this is false, it implies the interpreter is in v35 or in native */
+ /* ClearType mode. */
+ FT_Bool backwards_compatibility;
+
+ /* Useful for detecting and denying post-IUP trickery that is usually */
+ /* used to fix pixel patterns (`superhinting'). */
+ FT_Bool iupx_called;
+ FT_Bool iupy_called;
+
+ /* ClearType hinting and grayscale rendering, as used by Universal */
+ /* Windows Platform apps (Windows 8 and above). Like the standard */
+ /* colorful ClearType mode, it utilizes a vastly increased virtual */
+ /* resolution on the x axis. Different from bi-level hinting and */
+ /* grayscale rendering, the old mode from Win9x days that roughly */
+ /* adheres to the physical pixel grid on both axes. */
+ FT_Bool grayscale_cleartype;
+#endif /* TT_SUPPORT_SUBPIXEL_HINTING_MINIMAL */
+
+#ifdef TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY
TT_Round_Func func_round_sphn; /* subpixel rounding function */
FT_Bool subpixel_hinting; /* Using subpixel hinting? */
FT_ULong sph_in_func_flags; /* flags to indicate if in */
/* special functions */
-#endif /* TT_CONFIG_OPTION_SUBPIXEL_HINTING */
+#endif /* TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY */
} TT_ExecContextRec;
for ( j = 0; j < TRICK_SFNT_IDS_NUM_FACES; j++ )
{
if ( !has_cvt && !sfnt_id[j][TRICK_SFNT_ID_cvt].Length )
- num_matched_ids[j] ++;
+ num_matched_ids[j]++;
if ( !has_fpgm && !sfnt_id[j][TRICK_SFNT_ID_fpgm].Length )
- num_matched_ids[j] ++;
+ num_matched_ids[j]++;
if ( !has_prep && !sfnt_id[j][TRICK_SFNT_ID_prep].Length )
- num_matched_ids[j] ++;
+ num_matched_ids[j]++;
if ( num_matched_ids[j] == TRICK_SFNT_IDS_PER_FACE )
return TRUE;
}
TT_Driver driver = (TT_Driver)ttdriver;
-#ifdef TT_CONFIG_OPTION_SUBPIXEL_HINTING
- driver->interpreter_version = TT_INTERPRETER_VERSION_38;
-#else
driver->interpreter_version = TT_INTERPRETER_VERSION_35;
+#ifdef TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY
+ driver->interpreter_version = TT_INTERPRETER_VERSION_38;
+#endif
+#ifdef TT_SUPPORT_SUBPIXEL_HINTING_MINIMAL
+ driver->interpreter_version = TT_INTERPRETER_VERSION_40;
#endif
#else /* !TT_USE_BYTECODE_INTERPRETER */
#include "ttsubpix.h"
-#ifdef TT_CONFIG_OPTION_SUBPIXEL_HINTING
+#ifdef TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY
/*************************************************************************/
/* */
}
}
-#else /* !TT_CONFIG_OPTION_SUBPIXEL_HINTING */
+#else /* !TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY */
/* ANSI C doesn't like empty source files */
typedef int _tt_subpix_dummy;
-#endif /* !TT_CONFIG_OPTION_SUBPIXEL_HINTING */
+#endif /* !TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY */
/* END */
FT_BEGIN_HEADER
-#ifdef TT_CONFIG_OPTION_SUBPIXEL_HINTING
+#ifdef TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY
/*************************************************************************/
/* */
#define SPH_OPTION_SET_COMPATIBLE_WIDTHS FALSE
#define SPH_OPTION_SET_RASTERIZER_VERSION 38
-#endif /* TT_CONFIG_OPTION_SUBPIXEL_HINTING */
+#endif /* TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY */
FT_END_HEADER
/* encoding of first glyph (1 byte) */
/* encoding of second glyph (1 byte) */
/* offset (little-endian short) */
- for ( ; p < limit ; p += 4 )
+ for ( ; p < limit; p += 4 )
{
kp->index1 = FT_Get_Char_Index( t1_face, p[0] );
kp->index2 = FT_Get_Char_Index( t1_face, p[1] );
/* Point to axes after MM_Var struct */
mmvar->namedstyle = NULL;
- for ( i = 0 ; i < mmaster.num_axis; ++i )
+ for ( i = 0; i < mmaster.num_axis; ++i )
{
mmvar->axis[i].name = mmaster.axis[i].name;
mmvar->axis[i].minimum = INT_TO_FIXED( mmaster.axis[i].minimum);
/* */
if ( face->type1.private_dict.lenIV >= 0 )
{
- FT_Byte* temp;
+ FT_Byte* temp = NULL;
/* some fonts define empty subr records -- this is not totally */
if ( face->type1.private_dict.lenIV >= 0 &&
n < num_glyphs + TABLE_EXTEND )
{
- FT_Byte* temp;
+ FT_Byte* temp = NULL;
if ( size <= (FT_ULong)face->type1.private_dict.lenIV )
"pshinter" );
return ( module && pshinter && pshinter->get_globals_funcs )
? pshinter->get_globals_funcs( module )
- : 0 ;
+ : 0;
}
for (;;)
{
- /* The format is simple: */
- /* `/glyphname' + index [+ def] */
+ /* We support two formats. */
+ /* */
+ /* `/glyphname' + index [+ `def'] */
+ /* `(glyphname)' [+ `cvn'] + index [+ `def'] */
+ /* */
+ /* The latter format gets created by the */
+ /* LilyPond typesetting program. */
T1_Skip_Spaces( parser );
if ( parser->root.error )
return;
- if ( *cur == '/' )
+ if ( *cur == '/' || *cur == '(' )
{
FT_UInt len;
+ FT_Bool have_literal = ( *cur == '(' );
- if ( cur + 2 >= limit )
+ if ( cur + ( have_literal ? 3 : 2 ) >= limit )
{
FT_ERROR(( "t42_parse_charstrings: out of bounds\n" ));
error = FT_THROW( Invalid_File_Format );
cur++; /* skip `/' */
len = (FT_UInt)( parser->root.cursor - cur );
+ if ( have_literal )
+ len--;
error = T1_Add_Table( name_table, n, cur, len + 1 );
if ( error )
T1_Skip_Spaces( parser );
+ if ( have_literal )
+ T1_Skip_PS_Token( parser );
+
cur = parser->root.cursor;
(void)T1_ToInt( parser );