Spec: https://github.com/harfbuzz/boring-expansion-spec/pull/175
Offset-base erratum: https://github.com/harfbuzz/boring-expansion-spec/issues/177
* src/truetype/ttvarc.c (tt_varc_evaluate_region, tt_varc_get_item_deltas):
Read the sparse-region count as uint32, resolve each sparse axis through a
region-relative Offset32, and follow the Offset32 to the delta-set INDEX.
Bound the new offset fields and count arrays before dereferencing them.
* tests/varc/main.c (test_variation_store): New function to check
translated outlines at default, midpoint, and peak coordinates.
(main): Updated.
* tests/data/varc-null-condition.ttf, tests/data/varc-value-conditions.ttf:
Updated to migrate the existing affected fixture without changing its
logical contents or non-VARC tables.
* tests/data/varc-variation-store.ttf: New test file.
Tests: full Meson regression suite (3 passed).
Assisted-by: OpenAI Codex
Condition format 2 tests whether default plus interpolated delta is
positive. Rounding the delta to an integer first loses small positive
fractions and incorrectly hides components.
* src/truetype/ttvarc.c (tt_varc_get_item_deltas): Add argument
`condition_defaults`.
(tt_varc_get_item_deltas, tt_varc_eval_condition): Allow the
MultiItemVariationStore evaluator to initialize condition accumulators
from their defaults and return the unrounded sign. Compare in the
existing 64-bit representation, including the emulated path, so large
int32 deltas need not fit in a signed 16.16 `FT_Long`.
Use ULABS for unsigned magnitudes in emulated multiplication, avoiding
MSVC's warning about unsigned unary negation (see
https://gitlab.freedesktop.org/freetype/freetype/-/merge_requests/458#note_3692404).
Cast to `FT_UInt32` after obtaining the magnitude; no additional
absolute-value helper is needed.
(tt_varc_apply_axis_deltas, tt_varc_apply_transform_deltas): Updated.
* tests/data/varc-value-conditions.ttf: New test font.
* tests/varc/main.c (test_value_conditions): New function, adding a small
fixture and 80 direct/negated condition checks covering positive, zero,
negative, and fractional values.
(main): Updated.
All three Meson targets and the forced-emulated VARC tests pass. All 40
cross-library diagnostic cases and 115 native/emulated arithmetic
comparisons agree. MSVC itself was not available locally.
Assisted-by: OpenAI Codex <codex@openai.com>
The OpenType condition rules define an offset of zero as the true
condition. Recognize that value both in the top-level ConditionList and
in nested AND, OR, and NOT conditions.
Add a VARC regression font covering all four cases.
* src/truetype/ttvarc.c (tt_varc_eval_condition): Handle zero offsets.
* tests/data/varc-null-condition.ttf: New test font.
* tests/varc/main.c: Test it.
Assisted-by: OpenAI Codex <codex@openai.com>
OFF permits trailing glyphs to be provided entirely by VARC. Preserve the
SFNT glyph count for CFF2 fonts with VARC, and dispatch those glyphs to VARC
before checking the CFF2 fallback CharString range.
Add a short-CharStrings fixture and verify its glyph count and outline. All
three Meson tests pass.
Assisted-by: OpenAI Codex <noreply@openai.com>
* src/cff/cffgload.c (cff_slot_load): Check agains correct `num_glyphs`
values.
* src/cff/cffobjs.c (cff_face_init) [TT_CONFIG_OPTION_VARC]: Conditionalize
update of `cffface->num_glyphs`.
* tests/varc/main.c (TestFont): New field `glyph_count`.
(test_font): Check number of glyphs.
(main): Updated.
* tests/data/var/short-cff2.otf: New test font.
* src/truetype/ttvarc.c (tt_face_load_varc_glyph): `RESET_UNSPECIFIED_AXES`
also applies to components with no `HAVE_AXES` payload. Previously these
components inherited the parent coordinates because the reset path
required at least one axis value.
* tests/varc/main.c (test_reset_without_axes): Enter the coordinate override
path for reset-only components, restoring the font's current instance
before loading their leaves.
Add a nested VARC regression at default and non-default font coordinates.
(main): Updated.
* tests/data/varc-reset-only.ttf: New test font.
Tests: all three Meson targets pass. Generated reset, explicit-axis, and
inheritance comparisons agree with HarfBuzz and FontTools.
Assisted-by: OpenAI Codex <noreply@openai.com>
The VARC draft permits static fonts without a 'fvar' table to retain 'gvar'
or 'CFF2' variation data for component-internal coordinates. Initialize a
private blend from the relevant variation store without exposing those axes
through the public MM API.
Also add TrueType and CFF2 regression fonts.
* src/truetype/ttvarc.c (tt_face_init_varc_axes): New function.
(tt_face_load_varc_glyph): Handle static VARC fonts.
* src/tyuetype/ttvarc.h: Updated.
* src/cff/cffdrivr.c (cff_varc_init_axes): New function.
(cff_varc_load_glyph): Use it.
(cff_service_varc): Updated.
* src/truetype/ttgxvar.c (ft_var_load_gvar, TT_Get_MM_Var): Handle static
VARC fonts.
(tt_var_init_gvar, tt_var_init_blend): New functions.
(tt_done_blend): Updated.
* src/truetype/ttgxvar.h: Updated.
* src/truetype/ttdriver.c (tt_service_varc): Updated.
* include/freetype/internal/services/svvarc.h (FT_VARC_Init_Axes_Func): New
typedef.
(FT_ServiceVARC): Updated.
* tests/data/varc-static-gvar.ttf, tests/data/varc-static-cff2.otf: New test
fonts.
* tests/varc/main.c: Updated.