Previously the code had stipulation for using a per-TT_Size exec
context if `size->debug' was true. But there was no way that
`size->debug' could *ever* be true. As such, the code was always
using the singleton `TT_ExecContext' that was stored in `TT_Driver'.
This was, clearly, not threadsafe.
With this patch, loading glyphs from different faces from different
threads doesn't crash in the bytecode loader code.
* src/truetype/ttobjs.h (TT_SizeRec): Remove `debug' member.
(TT_DriverRec): Remove `context' member.
* src/truetype/ttobjs.c (tt_size_run_fpgm, tt_size_run_prep): Remove
`TT_ExecContext' code related to a global `TT_Driver' object.
(tt_driver_done): Don't remove `TT_ExecContext' object here but ...
(tt_size_done_bytecode): ... here.
(tt_driver_init): Don't create `TT_ExecContext' object here but ...
(tt_size_init_bytecode): ... here, only on demand.
* src/truetype/ttinterp.c (TT_Run_Context): Remove defunct debug
code.
(TT_New_Context): Remove `TT_ExecContext' code related to a global
`TT_Driver' object.
* src/truetype/ttinterp.h: Updated.
* src/truetype/ttgload.c (TT_Hint_Glyph, tt_loader_init): Updated.
Assure that FreeType's internal include directories are found before
`CPPFLAGS' (which might be set by the user in the environment), and
`CPPFLAGS' before `CFLAGS'.
* builds/freetype.mk (FT_CFLAGS): Don't add `INCLUDE_FLAGS'.
(FT_COMPILE): Make this a special variable for compiling only the
files handled in `freetype.mk'.
(.c.$O): Removed, unused.
* src/*/rules.mk (*_COMPILE): Fix order of include directories.
Based on a patch from Behdad.
* src/truetype/ttinterp.c (DO_*): Expand macros into corresponding
`Ins_*' functions.
(TT_RunIns): Replace `DO_*' macros with `Ins_*' function calls.
(ARRAY_BOUND_ERROR): Remove second definition, which is no longer
needed.
(Ins_SVTCA, Ins_SPVTCA, Ins_SFVTCA): Replaced with...
(Ins_SxyTCA): New function.
This is a follow-up patch.
* src/truetype/ttinterp.c, src/truetype/ttinterp.h
[TT_CONFIG_OPTION_STATIC_INTERPRETER,
TT_CONFIG_OPTION_STATIC_RASTER]: Remove macros and related code.
`API functions' are functions tagged with `FT_EXPORT_DEF'.
Besides trivial fixes, the following changes are included, too.
* src/base/ftbdf.c (FT_Get_BDF_Charset_ID, FT_Get_BDF_Property): Set
error code if no service is available.
* src/base/ftinit.c (FT_Done_FreeType): Change return value for
invalid `library' parameter to `Invalid_Library_Handle'.
* src/base/ftobjs.c (FT_New_Size): Change return value for invalid
`asize' parameter to `Invalid_Argument'.
* src/base/ftoutln.c (FT_Outline_Copy): Change return value for
invalid `source' and `target' parameters to `Invalid_Outline'.
(FT_Outline_Done_Internal): Change return value for invalid
`outline' parameter to `Invalid_Outline'.
The functions in this patch *do* return non-trivial errors that must
be taken care of.
* src/autofit/afloader.c (af_loader_load_g), src/base/ftobjs.c
(FT_Render_Glyph_Internal), src/base/ftoutln.c (FT_Outline_Render),
src/cff/cffgload.c (cff_decoder_parse_charstrings) <cff_op_endchar>,
src/psaux/psobjs.c (ps_parser_load_field_table), src/psaux/t1decode
(t1_decoder_parse_charstrings) <op_endchar>, src/truetype/ttgload.c
(load_truetype_glyph <subglyph loop>, tt_loader_init,
TT_Load_Glyph), src/truetype/ttgxvar.c (TT_Set_MM_Blend),
src/truetype/ttobjs.c (tt_size_run_fpgm, tt_size_run_prep): Do it.
We use a cast to indicate that we intentionally ignore a function's
return value. However, this doesn't apply to API functions where
errors can only happen for trivially invalid input.
* src/base/ftstroke.c (FT_Glyph_Stroke, FT_Glyph_StrokeBorder),
src/base/ftsynth.c (FT_GlyphSlot_Embolden), src/cff/cffgload.c
(cff_slot_load), src/pfr/pfrdrivr.c (pfr_get_kerning),
src/type1/t1load.c (parse_encoding), src/type42/t42parse.c
(t42_parse_encoding): Do it.
Before this patch, it was impossible to ever call DELTAP[123] in
subpixel hinting mode as described in the ClearType whitepaper; it
only worked if in `compatibility mode'. However, compatibility mode
essentially disables SHPIX, completely ruining hinting of
ttfautohint output, for example.
We now follow the whitepaper more closely so that DELTAP[123]
instructions for touched points in the non-subpixel direction are
executed.
Zero distance does not have to be treated specially if you follow
specifications and check the sign as the very last step of rounding.
* src/truetype/ttinterp.c (Round_None, Round_To_Grid,
Round_Down_To_Grid, Round_Up_To_Grid, Round_To_Double_Grid): Use
macros when available, do not check for non-zero distance.
(Round_To_Half_Grid, Round_Super, Round_Super_45): Ditto, return phase
if sign changed.
Suggested by Doug Felt <dougfelt@gmail.com>.
* src/sfnt/ttsbit.c (tt_sbit_decoder_load_metrics): Set
`vertAdvance' to zero...
* src/truetype/ttgload.c (TT_Load_Glyph): ... and set here a default
value for `vertAdvance' based on `linearVertAdvance' in case
`vertAdvance' is zero. Note that the previous computed ad-hoc value
for `linearVertAdvance' was apparently not tested in a real-life
situation.
The legal range for delta shift is zero through six. Negative values
are illegal according to
https://developer.apple.com/fonts/TrueType-Reference-Manual/RM04/Chap4.html#delta%20shift
* src/truetype/ttobjs.h (delta_shift, delta_base): Make unsigned.
* src/truetype/ttinterp.h (DO_SDS): Throw an error if delta_shift
out of range.
(Ins_DELTAP, Ins_DELTAC): Optimize for legal delta_shift.
* src/truetype/ttinterp.h (TT_ExecContextRec): New field
`cur_ppem_func' with a function pointer.
* src/truetype/ttinterp.c (TT_RunIns): Initialize `cur_ppem_func'
depending on the pixel geometry to either...
(Current_Ppem_Stretched): ... this for stretched pixels.
(Current_Ppem): ... or this for square pixels.
(DO_MPPEM, DO_MPS, Ins_DELTAP, Ins_DELTAC): Use `cur_ppem_func'.
In case of an error in the `prep' table, no longer try to execute it
again and again. This makes FreeType handle endless loops in buggy
fonts much faster.
* src/truetype/ttobjs.h (TT_SizeRec): The fields `bytecode_ready'
and `cvt_ready' are now negative if not initialized yet, otherwise
they indicate the error code of the last run.
* src/truetype/ttobjs.c (tt_size_run_fpgm, tt_size_run_prep,
tt_size_done_bytecode, tt_size_init_bytecode,
tt_size_ready_bytecode, tt_size_init, tt_size_done, tt_size_reset):
Updated.
* src/truetype/ttgload.c (tt_loader_init): Updated.
* src/truetype/ttinterp.c (TT_RunIns): Force reexecution of `fpgm'
and `prep' only if we are in the `glyf' table.
This patch unifies the subpixel and non-subpixel cases.
* src/truetype/ttinterp.h (TT_ExecContextRec): Remove
`grayscale_hinting'; all code should refer to `grayscale' instead.
Remove unused `native_hinting' member.
Rename `subpixel_hinting' member to `subpixel.
* src/truetype/ttgload.c (TT_LOADER_SET_PP): Updated.
(tt_loader_init): Updated.
* src/truetype/ttinterp.c (Ins_GETINFO): Simplify.
Updated.
Problem reported by Nigel Tao <nigeltao@golang.org>.
* src/truetype/ttgload.c (TT_Hint_Glyph): Remove code that shifts
the glyph (component) by a fractional value computed from the LSB
phantom point. This is wrong, since the horizontal phantom points
get rounded horizontally later on.
Greg Hitchcock provided very interesting insights into the
complicated history of the horizontal positions of the TSB and BSB
phantom points.
* src/truetype/ttgload.c (TT_LOADER_SET_PP)
[TT_CONFIG_OPTION_SUBPIXEL_HINTING]: Use `subpixel_hinting' and
`grayscale_hinting' flags as conditionals for the x position of TSB
and BSB.