Compare commits

...

55 Commits

Author SHA1 Message Date
Dominik Röttsches 275b116b40 [sfnt] Support variable 'COLR' v1 `PaintVarSkew*`.
* src/sfnt/ttcolr.c (FT_PaintFormat_Internal): New enumeration values
`FT_COLR_PAINTFORMAT_INTERNAL_VAR_SKEW`,
`FT_COLR_PAINTFORMAT_INTERNAL_SKEW_CENTER`, and
`FT_COLR_PAINTFORMAT_INTERNAL_VAR_SKEW_CENTER`.
(read_paint): Handle new enumeration values.
2022-07-09 05:59:45 +02:00
Dominik Röttsches 44fd524ee4 [sfnt] Support variable 'COLR' v1 `PaintVarRotate*`.
* src/sfnt/ttcolr.c (FT_PaintFormat_Internal): New enumeration values
`FT_COLR_PAINTFORMAT_INTERNAL_VAR_ROTATE` and
`FT_COLR_PAINTFORMAT_INTERNAL_VAR_ROTATE_CENTER`.
(read_paint): Handle new enumeration values.
2022-07-09 05:59:45 +02:00
Dominik Röttsches 603fef28a6 [sfnt] Support 'COLR' v1 variable `PaintVarScale*`.
* src/sfnt/ttcolr.c: (FT_PaintFormatInternal): New enumeration values
`FT_COLR_PAINTFORMAT_INTERNAL_VAR_SCALE`,
`FT_COLR_PAINTFORMAT_INTERNAL_VAR_SCALE_CENTER`,
`FT_COLR_PAINTFORMAT_INTERNAL_VAR_SCALE_UNIFORM`, and
`FT_COLR_PAINTFORMAT_INTERNAL_VAR_SCALE_UNIFORM_CENTER`.
(read_paint): Handle new enumeration values.
2022-07-09 05:59:41 +02:00
Dominik Röttsches d134b9e37b [sfnt] Support for 'COLR' v1 variable translate.
* src/sfnt/ttcolr.c (FT_PaintFormat_Internal): New enumeration value
`FT_COLR_PAINTFORMAT_INTERNAL_VAR_TRANSLATE`.
(read_paint): Handle new enumeration value.
2022-07-09 05:44:58 +02:00
Dominik Röttsches 8ec531c26c [sfnt] Support for 'COLR' v1 variable transforms.
* src/sfnt/ttcolr.c (FT_PaintFormat_Internal): New enumeration value
`FT_COLR_PAINTFORMAT_INTERNAL_VAR_TRANSFORM`.
(read_paint): Handle new enumeration value.
2022-07-09 05:43:28 +02:00
Dominik Röttsches 9c4ad2a901 [sfnt] Deltas for 'COLR' v1 gradient coordinates.
* src/sfnt/ttcolr.c (read_paint) [TT_CONFIG_OPTION_GX_VAR_SUPPORT]: Read and
apply deltas to radial, linear, and sweep gradient coordinates such as 'p0',
'p1', 'p2', 'center', 'radii', and 'angles'.
2022-07-09 05:41:27 +02:00
Dominik Röttsches 3414fef74f [sfnt] Support variable 'COLR' v1 color lines.
* include/freetype/ftcolor.h (FT_ColorStopIterator): Add field
`read_variable` to indicate whether a variation index base should be read.

* src/sfnt/ttcolr.c: (FT_PaintFormat_Internal): New enumerations
`FT_COLR_PAINTFORMAT_INTERNAL_VAR_LINEAR_GRADIENT`
`FT_COLR_PAINTFORMAT_INTERNAL_VAR_RADIAL_GRADIENT`, and
`FT_COLR_PAINTFORMAT_INTERNAL_VAR_SWEEP_GRADIENT`.
(read_color_line): New parameter `read_variable`; update callers.
(read_paint): Handle new enumerations.
2022-07-08 11:51:07 +02:00
Dominik Röttsches 7c151abb69 [sfnt] Apply variation deltas to `PaintVarSolid`.
* src/sfnt/ttcolr.c (FT_PaintFormat_Internal_): New enumeration
`FT_COLR_PAINTFORMAT_INTERNAL_VAR_SOLID`.

(get_deltas_for_var_index_base) [TT_CONFIG_OPTION_GX_VAR_SUPPORT]: New
function to retrieve an array of delta values, which will be used for most
of 'COLR' v1 variation formats (in follow-up commits).

(read_paint): Add `face` parameter; update caller.
Handle `FT_COLR_PAINTFORMAT_INTERNAL_VAR_SOLID`.
2022-07-07 19:48:19 +02:00
Dominik Röttsches 8a9192f68e [sfnt] Check safety of cast to `TT_Driver` before accessing member.
* src/sfnt/ttcolr.c (VARIABLE_COLRV1_ENABLED): Access
`enable_variable_colrv1` only if driver class matches.
2022-07-07 19:36:49 +02:00
Stephen Holdaway d5d048bbfe doc: Clarify description of `FT_Stream_IoFunc`.
The existing documentation comments on `FT_Stream_IoFunc` hinted at the dual
seek/read behavior required for custom stream implementations to work, but
it didn't explicitly explain it.  Without looking at the internals of
FreeType, it was easy for someone to assume their implementation should
handle both seek and read operations all the time.  If this is done, you get
a variety of errors, but mostly just `Unknown_File_Format` (error code
0x02).
2022-07-06 12:55:40 +02:00
Dominik Röttsches 31b14fd4dc [sfnt] Load variation store for 'COLR' v1.
* src/sfnt/ttcolr.c: Include `ttobjs.h` temporarily.
(VARIABLE_COLRV1_ENABLED): New temporary macro to detect whether variable
COLRv1 is enabled.
(Colr): New fields `var_store` and `delta_set_idx_map`.
(tt_face_load_colr, tt_face_free_colr) [VARIABLE_COLRV1_ENABLED]: Load and
free variation store data using the functions from the Multiple Masters
service.
2022-07-04 16:34:02 +02:00
Chris Liddell 1a242558be [base] Improve error handling in `FT_GlyphLoader_CheckPoints`.
If `FT_GlyphLoader_CreateExtra` returns an error (and a couple of other
places), `FT_GlyphLoader_CheckPoints` would propagate the error immediately,
rather than cleaning up the partially set up `FT_GlyphLoader`.  As a
consequence, a subsequent attempt to create a glyph could result in a crash.

* src/base/ftgloadr.c (FT_GlyphLoader_CheckPoints): Ensure all the error
conditions exits are consistent, eventually calling `FT_GlyphLoader_Reset`.
2022-07-03 06:58:23 +02:00
Thomas Sondergaard 55a97b0cb1 CMakeLists.txt: Provide both 'freetype' and 'Freetype::Freetype' targets.
FreeType can be located by consuming projects that use
`find_package(Freetype)` either via the old `MODULE` path (which uses
`FindFreetype.cmake` supplied by CMake), or via the new `CONFIG` path (which
uses `freetype-config.cmake` as supplied by this project).  Up to this point
the CMake module has supplied the target `Freetype::Freetype` and the config
file provided by this project the target `freetype`.  Now we supply both
`freetype` and `Freetype::Freetype` so that consuming projects can always
use the target `Freetype::Freetype` regardless of what path was taken by
`find_package(Freetype)`.

Fixes #1165.
2022-07-03 06:48:15 +02:00
Werner Lemberg 31005d98a4 include/freetype/ftmm.h: Improve documentation. 2022-07-02 09:34:13 +02:00
Dominik Röttsches bec4ef415e [base] Round values in `FT_MulAdd_Fix`.
This avoids regressing Blink layout tests and makes `FT_MulAdd_Fix` delta
retrieval implementation consistent with the previous implementation, which
used `FT_fixedToInt` and included rounding.

* src/base/ftcalc.c (FT_MulAdd_Fix): Implement it.
Also fix remaining `temp` initialization compilation issue.

Fixes #1169.
2022-07-01 14:01:08 +02:00
Werner Lemberg de27955c2a Minor formatting. 2022-07-01 06:33:50 +02:00
Dominik Röttsches 0607e0e959 Fix initialisation of temp variable in new FT_MulAddFix
src/truetype/ttgxvar.c (FT_MulAddFix): Initialise `temp`.
2022-06-30 10:55:50 +03:00
Dominik Röttsches dece953516 [truetype] Perform variation store delta computation with 64-bit precision.
* include/freetype/internal/ftmmtypes.h (FT_ItemVarDelta): Make type
explicitly 32-bit.
* include/freetype/internal/services/svmm.h
(FT_Var_Get_Item_Delta_Func): Change return type to `FT_ItemVarDelta`
* truetype/ttgxvar.h (tt_var_get_item_delta): Change return type to
`FT_ItemVarDelta`.
* truetype/ttgxvar.c (tt_var_get_item_delta): Store scalars and deltas
to intermediate array, perform computation using new method
`FT_MulAddFix`.
2022-06-29 20:27:11 +02:00
Dominik Röttsches 15fef219d6 New function `FT_MulAddFix` to compute the sum of fixed-point products.
This function, based on the code of `FT_MulFix`, uses 64-bit precision
internally for intermediate computations.

* include/freetype/internal/ftcalc.h, base/ftcalc.c (FT_MulAddFix):
Implement it.
2022-06-29 20:12:04 +02:00
Werner Lemberg 2db58e061e CMakeLists.txt: Move inclusion of `FindPkgConfig` down.
It must come after `CMAKE_TOOLCHAIN_FILE`.

Fixes #1167.
2022-06-22 12:16:00 +02:00
Dominik Röttsches 117df36b4c [sfnt] Upgrade stop_offset to FT_Fixed from FT_F2Dot14 2022-06-22 09:33:20 +00:00
Alexei Podtelezhnikov 5e48c88d57 * docs/CHANGES: Announce impending Infinality removal. 2022-06-21 17:34:29 +00:00
Alexei Podtelezhnikov 9006ff7d10 * ttgload.c (TT_Process_Composite_Glyph): Fix a signedness warning. 2022-06-21 17:10:56 +00:00
Werner Lemberg 2848378be5 s/fixed point/fixed-point/ 2022-06-21 17:08:04 +02:00
Werner Lemberg 40c6f97326 .gitlab-ci.yml: Correctly upgrade `meson`. 2022-06-21 14:45:42 +02:00
Dominik Röttsches 4b6f92e6b3 Proposal: Feature control for variable COLRv1
* include/freetype/ftdriver.h (variable-color-v1 property): Add documentation
for variable-colr-v1 property.
* src/truetype/ttdriver.c (tt_property_set): Ingest variable-control property
when called, set to enable_variable_colrv1 driver flag.
* src/truetype/ttobjs.h (TT_DriverRec): Add enable_variable_colrv1 flag.
2022-06-21 12:25:46 +03:00
Xavier Claessens b861b24157 [meson] Disable FreeType in HarfBuzz fallback.
This avoids cyclic subproject configuration when the 'harfbuzz' feature is
enabled, or `--wrap-mode=forcefallback` is used, but HarfBuzz is built as a
subproject.  HarfBuzz does the same and disables HarfBuzz support when
configuring FreeType as a subproject.

* meson.build (harfbuzz_dep): Implement it.

* subprojects/harfbuzz.wrap: New file.

* .gitlab-ci.yml [windows meson]: Use latest version of the meson 0.59
  series, which has a necessary bug fix to make CI work.
2022-06-21 08:09:16 +02:00
Alexei Podtelezhnikov 47103b2f19 [truetype] Clean up phantom point accounting.
This formalizes that the phantom points appended in the outline
do not increase its point count, nor are they tagged or included
in any additional contours.  Only their coordinates are stored.
They are counted in the glyph zone, however.

* src/truetype/ttgxvar.c (TT_Vary_Apply_Glyph_Deltas): Infer `n_points`
from the outline size plus four phantom points.
* src/truetype/ttgxvar.h (TT_Vary_Apply_Glyph_Deltas): Remove this
argument.
* src/truetype/ttgload.c (tt_prepare_zone): Add phantom four.
(TT_Process_Simple_Glyph, load_truetype_glyph): Update all callers.
2022-06-18 23:09:17 -04:00
Alexei Podtelezhnikov 705f416184 [truetype/GX] Clean up phantom point adjustment.
This moves phantom point and advance variation adjustment next to
calculations. The logic stays the same, HVAR and VVAR take priority.

* src/truetype/ttgload.c (load_truetype_glyph): Move it from here...
* src/truetype/ttgxvar.c (TT_Vary_Apply_Glyph_Deltas): ... to here
and check for HVAR and VVAR presence outside the main loop.
2022-06-18 23:02:26 -04:00
Ben Wagner f7daf9d293 [stream] Fix reading s32 when long is s64
`FT_READ_LONG`, `FT_GET_LONG`, and related macros did not return
negative values when `long` is more than 32 bits. `FT_Stream_ReadULong`
would read four bytes into the LSB of an `FT_ULong` and return that.
Since this can never set the MSb of the `FT_ULong` when `FT_ULong` is
more than 32 bits the cast to `FT_Long` never resulted in a negative
value.

Fix this by modifying `FT_Stream_Read*` to return a type of the same
size as the bytes it is reading and changing the `FT_READ_*` and
`FT_GET_*` macros to cast to the same type returned by `FT_Stream_Read*`
but with the correctly signed type (instead of casting to what is
assumed to be the type of `var` which will happen automatically anyway).

There exist a few cases like with the `OFF3` variants where there isn't
generally a type with the correct size. `FT_PEEK_OFF3` works around this
loading the bytes into the three most significant bits and then doing a
signed shift down. `FT_NEXT_OFF3` also already worked correctly by
casting this signed value to another signed type. `FT_Stream_GetUOffset`
works correctly but one must be careful not to attempt to cast the
returned value to a signed type. Fortunately there is only
`FT_GET_UOFF3` and no `FT_GET_OFF3`.

All of these cases are handled correctly when reading values through
`FT_Stream_ReadFields` since it generically computes the signed value
through an `FT_Int32`. This change is essentially doing the same for
these macros.

* include/freetype/internal/ftstream.h (FT_NEXT_*, FT_GET_*, FT_READ*):
Update macros and return types to use fixed size types for fixed size
values.

* src/base/ftstream.c (FT_StreamGet*, FT_StreamRead*): Dito.

Issue: #1161
2022-06-18 12:58:23 -04:00
Alexei Podtelezhnikov d9b8a69e9a [truetype/GX] Fix an old typo.
* src/truetype/ttgxvar.c (TT_Vary_Apply_Glyph_Deltas): Vertical
advance is measured along y-coordinate.
2022-06-16 22:13:25 -04:00
Alexei Podtelezhnikov 9c706dcca7 [truetype/GX] Clean up advance adjustment (Brrr).
* src/truetype/ttgload.c (load_truetype_glyph): Remove remaining code.
2022-06-16 16:11:51 +00:00
Ben Wagner 9079521002 [type1] Directly search for eexec in private dict
This code originally just searched for `eexec`. This was later modified
to check that the `eexec` found is valid (not in a string or comment).
This was done by searching for `eexec` as before and then, for each
`eexec` found, searching from the beginning using the correct parsing to
see if the `eexec` was still found. If the private dictionary is large
and contains many copies of `eexec` which are not valid, the initial
part of the private dictionary is scanned once for each, potentially
leading to n^2 parsing time.

Instead of finding an initial `eexec` and then re-parsing to discover if
it is valid, drop the initial search for `eexec` and just parse to find
a valid `eexec`. This is strictly faster since the validation must
happen anyway and avoids restarting from the beginning each time an
`eexec` is found in the data.

* src/type1/t1parse.c (T1_Get_Private_Dict): avoid n^2 parsing

Bug: https://bugs.chromium.org/p/chromium/issues/detail?id=1328883
2022-06-16 14:51:57 +00:00
Alexei Podtelezhnikov d6fc8c6ba0 [truetype/GX] Clean up advance adjustment.
* src/truetype/ttgload.c (TT_Process_Simple_Glyph, load_truetype_glyph):
Move the advance adjustment from here...
* src/truetype/ttgxvar.c (TT_Vary_Apply_Glyph_Deltas): ... to here and
simplify arguments.
* src/truetype/ttgxvar.h (TT_Vary_Apply_Glyph_Deltas): Update prototype
with fewer arguments.
2022-06-15 18:28:50 -04:00
Ben Wagner 8bb7722a53 [gzip] Handle inflate returning Z_NEED_DICT
When `inflate` returns `Z_NEED_DICT` this is currently not reported as
an error and callers may assume that the decompression succeeded when it
did not. In particular, a compressed table in a woff file may not
actually be decompressed and written as expected, leaving the backing
memory for the expanded table uninitialized.

* src/gzlip/ftgzip.c (FT_Gzip_Uncompress): treat `Z_NEED_DICT` as
indicating invalid data since there is no means to provide a dictionary.

Bug: https://bugs.chromium.org/p/chromium/issues/detail?id=1335712
2022-06-14 04:49:29 +00:00
Ben Wagner 58395dd200 [woff] Don't allocate table entries until needed
* src/sfnt/sfwoff.c (woff_open_font): delay allocating space for the
table entries until they are actually written out with the data.
2022-06-13 15:32:28 -04:00
Alexei Podtelezhnikov 8b6bcc92c5 * src/sfnt/sfwoff2.c (woff2_open_font): Partial revert.
Fixes https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=47981.
2022-06-12 09:04:13 -04:00
Alexei Podtelezhnikov e7482ff4c2 * src/lzw/ftzopen.c (ft_lzwstate_stack_grow): Cosmetic macro change. 2022-06-11 23:47:19 -04:00
Alexei Podtelezhnikov 73631b9530 [woff, woff2] Avoid buffer zeroing.
* src/sfnt/sfwoff.c (woff_open_font): Use Q-macros.
* src/sfnt/sfwoff2.c: Ditto.
(reconstruct_font): Allocate table_entry on stack.
2022-06-11 16:10:40 -04:00
Alexei Podtelezhnikov 4fef1fcede [smooth] Fix GCC LTO crashes on Windows.
Fixes #1164 by using a volatile variable around `setjmp`.  It is hard to
say how this fixes crashes related to certain link-time optimizations.
This does not decrease the rendering performance.

* src/smooth/ftgrays.c (gray_convert_glyph_inner): Use volatile `error`.
2022-06-10 11:34:56 -04:00
bruvzg 9acefc4f51 * src/smooth/ftgrays.c [FT_STATIC_RASTER]: Fix compilation. 2022-06-09 10:51:07 -04:00
Ben Wagner b11074cf6d [svg] Set linear advances when loading SVG glyphs
* include/freetype/freetype.h (FT_GlyphSlotRec_): update doc
* src/cff/cffgload.c (cff_slot_load): do it
* src/truetype/ttgload.c (TT_Load_Glyph): do it

Fixes: #1156
2022-06-06 16:55:17 -04:00
Ben Wagner c26872ed59 [svg] Clear correct flags for doc ownership
This issue was discovered with an SVG based font with some documents
compressed and other uncompressed. After loading the first compressed
document the ownership flag on the glyph slot was set to true but never
set to false. As a result after loading a compressed document a glyph
from an uncompressed document would load fine, but when this glyph slot
was cleared it would try to free its document resulting in a wild free.

* src/base/ftobjs.c (ft_glyphslot_clear): clear correct flags

Fixes: #1162
2022-06-01 17:27:38 +00:00
Alexei Podtelezhnikov d685798123 [docs] Correct favicon. 2022-05-31 22:40:55 -04:00
Alexei Podtelezhnikov 8addad6065 [docs] Use hinted favicon. 2022-05-31 22:38:24 -04:00
Alexei Podtelezhnikov c26f0d0d7e [docs] Update favicon. 2022-05-26 23:48:26 -04:00
Behdad Esfahbod (بهداد اسفهبد) b98dd169a1 * src/sfnt/ttmtx.c (tt_face_get_metrics): Apply variations unconditionally.
This causes a speed-up of approx. 20% for getting advance widths.
2022-05-25 14:49:37 +02:00
Dominik Röttsches 7838c78f53 [truetype] Support reading 32bit/16bit VarStore deltas
* include/freetype/internal/ftmmtypes.h (FT_ItemVarDelta): Define type
to be used for delta arrays, upgrade to FT_long.
* src/truetype/ttgxvar.c: Adhere to long_words bit and read either
Short/Byte pairs or Long/Short pairs, as defined by spec. For better
readability, define macro for repetitive read code.
2022-05-23 16:18:28 +03:00
Dominik Röttsches 9aa99f2262 [truetype] Handle 0xFFFF special value inside delta retrieval function
* truetype/ttgxvar.c (tt_hvadvance_adjust, tt_apply_mvar,
tt_var_get_item_delta): Remove special 0xFFFF handling in favor of less
redundant handling inside the tt_var_get_item_delta function, as it is
equivalent to returning a 0 delta. Avoids code-duplication checking for
special value 0xFFFF.
2022-05-20 17:20:08 +03:00
Dominik Röttsches a4c4566b6d [truetype, snft] Add service methods for `DeltaSetIdxMap` and `VarStore`.
This will be needed for 'COLR' v1 variation support.

* src/truetype/ttgxvar.h (GX_ItemVarData, GX_AxisCoords, GX_VarRegion,
GX_VarItemStore, GX_DeltaSetIdxMap): Move structures to...
* include/freetype/internal/ftmmtypes.h: ... this new file.

* include/freetype/internal/service/svmm.h (MultiMasters): Include
`ftmmtypes.h`.
(FT_Var_Load_Delta_Set_Idx_Map_Func, FT_Var_Load_Item_Var_Store_Func,
FT_Var_Get_Item_Delta_Func, FT_Var_Done_Item_Var_Store_Func,
FT_Var_Done_Delta_Set_Idx_Map_Func): New function typedefs.
(MultiMasters): Add them.
(FT_DEFINE_SERVICE_MULTIMASTERSREC): Updated.

* src/cff/cffdrivr.c (cff_load_item_variation_store,
cff_load_delta_set_index_mapping, cff_get_item_delta,
cff_done_item_variation_store, cff_done_delta_set_index_map): New wrapper
methods calling into mm service.
(cff_service_multi_masters): Updated.

* src/truetype/ttgxvar.c (ft_var_load_item_variation_store,
ft_var_load_delta_set_index_mapping, ft_var_get_item_delta,
ft_var_done_item_variation_store, ft_var_done_delta_set_index_map): Renamed
to ...
(tt_var_load_item_variation_store, tt_var_load_delta_set_index_mapping,
tt_var_get_item_delta, tt_var_done_item_variation_store,
tt_var_done_delta_set_index_map): ... this for consistency.
Mark them as non-static.
* src/truetype/ttgxvar.h: Add corresponding prototypes.

* src/truetype/ttdriver.c (tt_service_gx_multi_masters): Updated.

* src/type1/t1driver.c (t1_service_multi_masters): Updated.
2022-05-19 07:14:05 +02:00
Dominik Röttsches 5f19f49c81 [truetype] Move deallocation of `DeltaSetIdxMap` into own function.
This is a preparation for handling `DeltaSetIdxMap` and `VarStore` as a
FreeType service.

* src/truetype/ttgxvar.c (ft_var_done_delta_set_index_map): New function.
(tt_done_blend): Use it.
2022-05-19 06:09:17 +02:00
Werner Lemberg e3ac7bb64a * builds/toplevel.mk (do-dist): Don't remove meson wrap files.
Fixes #1157.
2022-05-18 16:12:19 +02:00
Werner Lemberg b4b7c3f607 * subprojects/zlib.wrap: Update to zlib version 1.2.12. 2022-05-18 16:02:21 +02:00
Werner Lemberg c8a9c88975 REAMDE: Mention that gitlab's 'download' button doesn't work.
This is because the `git archive` command doesn't preserve submodules.

Note that currently there is no support for disabling the 'download' button
in gitlab (https://gitlab.com/gitlab-org/gitlab/-/issues/17032).

Fixes issue #1158.
2022-05-18 07:06:58 +02:00
Werner Lemberg 5d49473f85 [truetype] Handle inner/outer index values 0xFFFF/0xFFFF.
This was introduced in OpenType 1.8.4.

* src/truetype/ttgxvar.c (ft_var_load_delta_set_index_mapping,
tt_hvadvance_adjust, ft_var_load_mvar, tt_apply_mvar): Handle special
inner/outer index values.
(ft_var_load_item_variation_store): Add test.

Fixes #1154.
2022-05-11 18:15:02 +02:00
51 changed files with 1510 additions and 681 deletions

View File

@ -47,7 +47,7 @@ variables:
- Import-Certificate -CertStoreLocation "Cert:\LocalMachine\Root" "C:\roots.sst"
# Make sure meson is up to date so we don't need to rebuild the image
# with each release.
- pip3 install meson==0.59.1
- pip3 install -U 'meson==0.59.*'
- pip3 install --upgrade certifi
- pip3 install -U ninja

View File

@ -121,7 +121,6 @@ endif ()
include(CheckIncludeFile)
include(CMakeDependentOption)
include(FindPkgConfig)
# CMAKE_TOOLCHAIN_FILE must be set before `project' is called, which
# configures the base build environment and references the toolchain file
@ -245,6 +244,8 @@ endif ()
# Find dependencies
include(FindPkgConfig)
if (NOT FT_DISABLE_HARFBUZZ)
set(HARFBUZZ_MIN_VERSION "2.0.0")
if (FT_REQUIRE_HARFBUZZ)
@ -497,6 +498,13 @@ if (BUILD_FRAMEWORK)
)
endif ()
# 'freetype-interface' is an interface library, to be accessed with
# `EXPORT_NAME Freetype::Freetype`. This is the target name provided by
# CMake's `FindFreetype.cmake`, so we provide it for compatibility.
add_library(freetype-interface INTERFACE)
set_target_properties(freetype-interface PROPERTIES
EXPORT_NAME Freetype::Freetype
INTERFACE_LINK_LIBRARIES freetype)
set(PKGCONFIG_REQUIRES "")
set(PKGCONFIG_REQUIRES_PRIVATE "")
@ -614,7 +622,7 @@ if (NOT SKIP_INSTALL_LIBRARIES AND NOT SKIP_INSTALL_ALL)
COMPATIBILITY SameMajorVersion)
install(
TARGETS freetype
TARGETS freetype freetype-interface
EXPORT freetype-targets
LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}
ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR}

4
README
View File

@ -16,7 +16,9 @@ Read the files `docs/INSTALL*` for installation instructions; see the
file `docs/LICENSE.TXT` for the available licenses.
For using FreeType's git repository instead of a distribution bundle,
please read file `README.git`.
please read file `README.git`. Note that you have to actually clone
the repository; using a snapshot will not work (in other words, don't
use gitlab's 'Download' button).
The FreeType 2 API reference is located in directory `docs/reference`;
use the file `index.html` as the top entry point. [Please note that

View File

@ -317,6 +317,6 @@ do-dist: distclean refdoc
rm -f docs/mkdocs.yml
@# Remove more stuff related to git.
rm -rf subprojects
rm -rf subprojects/dlg
# EOF

View File

@ -1,3 +1,19 @@
CHANGES BETWEEN 2.12.1 and 2.12.2
I. IMPORTANT BUG FIXES
II. MISCELLANEOUS
- TrueType interpreter version 38 (aka Infinality) that was first
introduced about 10 years ago in FreeType 2.4.11 is now deprecated
and slated to be removed in the next version. TrueType interpreter
version 40 has been FreeType default version for 6 years now and
provides an excelent alternative. This is the last FreeType version
with TT_INTERPRETER_VERSION_38 and TT_INTERPRETER_VERSION_40 treated
differently.
======================================================================
CHANGES BETWEEN 2.12.0 and 2.12.1
I. IMPORTANT BUG FIXES

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.1 KiB

After

Width:  |  Height:  |  Size: 5.3 KiB

View File

@ -2411,9 +2411,9 @@
units per em (e.g. Inter). This patch fixes it.
The return value of af_loader_compute_darkening was also changed to
use 16.16 fixed point to get rid of a redundant truncation operation.
use 16.16 fixed-point to get rid of a redundant truncation operation.
This should slightly improve the precision, although it's still
bottlenecked by the emboldening function, which uses 26.6 fixed point.
bottlenecked by the emboldening function, which uses 26.6 fixed-point.
* src/autofit/afloader.[ch]
(af_loader_compute_darkening): Return FT_Fixed.

View File

@ -707,7 +707,7 @@
[base] Fix integer overflow.
* src/base/ftoutln.c (FT_Outline_EmboldenXY): Normalize incoming and
outgoing vectors and use fixed point arithmetic.
outgoing vectors and use fixed-point arithmetic.
2013-01-23 Alexei Podtelezhnikov <apodtele@gmail.com>

View File

@ -1892,13 +1892,13 @@ FT_BEGIN_HEADER
* The advance width of the unhinted glyph. Its value is expressed in
* 16.16 fractional pixels, unless @FT_LOAD_LINEAR_DESIGN is set when
* loading the glyph. This field can be important to perform correct
* WYSIWYG layout. Only relevant for outline glyphs.
* WYSIWYG layout. Only relevant for scalable glyphs.
*
* linearVertAdvance ::
* The advance height of the unhinted glyph. Its value is expressed in
* 16.16 fractional pixels, unless @FT_LOAD_LINEAR_DESIGN is set when
* loading the glyph. This field can be important to perform correct
* WYSIWYG layout. Only relevant for outline glyphs.
* WYSIWYG layout. Only relevant for scalable glyphs.
*
* advance ::
* This shorthand is, depending on @FT_LOAD_IGNORE_TRANSFORM, the

View File

@ -521,9 +521,10 @@ FT_BEGIN_HEADER
*
* @description:
* This iterator object is needed for @FT_Get_Colorline_Stops. It keeps
* state while iterating over the stops of an @FT_ColorLine,
* representing the `ColorLine` struct of the v1 extensions to 'COLR',
* see 'https://github.com/googlefonts/colr-gradients-spec'.
* state while iterating over the stops of an @FT_ColorLine, representing
* the `ColorLine` struct of the v1 extensions to 'COLR', see
* 'https://github.com/googlefonts/colr-gradients-spec'. Do not manually
* modify fields of this iterator.
*
* @fields:
* num_color_stops ::
@ -537,6 +538,10 @@ FT_BEGIN_HEADER
* An opaque pointer into 'COLR' table data. Set by @FT_Get_Paint.
* Updated by @FT_Get_Colorline_Stops.
*
* read_variable ::
* A boolean keeping track of whether variable color lines are to be
* read. Set by @FT_Get_Paint.
*
* @since:
* 2.11 -- **currently experimental only!** There might be changes
* without retaining backward compatibility of both the API and ABI.
@ -549,6 +554,8 @@ FT_BEGIN_HEADER
FT_Byte* p;
FT_Bool read_variable;
} FT_ColorStopIterator;
@ -592,7 +599,8 @@ FT_BEGIN_HEADER
*
* @fields:
* stop_offset ::
* The stop offset between 0 and 1 along the gradient.
* The stop offset along the gradient, expressed as a 16.16 fixed-point
* coordinate.
*
* color ::
* The color information for this stop, see @FT_ColorIndex.
@ -604,7 +612,7 @@ FT_BEGIN_HEADER
*/
typedef struct FT_ColorStop_
{
FT_F2Dot14 stop_offset;
FT_Fixed stop_offset;
FT_ColorIndex color;
} FT_ColorStop;

View File

@ -214,9 +214,9 @@ FT_BEGIN_HEADER
* itself, it is possible to control its behaviour with @FT_Property_Set
* and @FT_Property_Get.
*
* The TrueType driver's module name is 'truetype'; a single property
* @interpreter-version is available, as documented in the @properties
* section.
* The TrueType driver's module name is 'truetype'; two properties are
* available, @interpreter-version and @TEMPORARY-enable-variable-colrv1, as
* documented in the @properties section.
*
* To help understand the differences between interpreter versions, we
* introduce a list of definitions, kindly provided by Greg Hitchcock.
@ -820,6 +820,48 @@ FT_BEGIN_HEADER
* 2.5
*/
/**************************************************************************
*
* @property:
* TEMPORARY-enable-variable-colrv1
*
* @description:
* Controls experimental support of variable COLRv1 and whether the COLRv1
* implementation should take into account variation deltas. This tells the
* COLRv1 API methods whether they should read from the font and apply
* variable deltas to COLRv1 properties. The feature is default off. When
* on, variable COLRv1 deltas are applied for COLRv1 features for which they
* are already implemented. When off, variable deltas are ignored even if
* the respective PaintVar* table may already be understood.
*
* WARNING: Temporary flag during development of variable COLRv1. This flag
* will be removed, do not rely on it. Full variable COLRv1 support will be
* announced separately.
*
* @note:
* This property cannot be set via the `FREETYPE_PROPERTIES` environment
* variable.
*
* @example:
* The following example code demonstrates how to enable variable
* COLRv1.
*
* ```
* FT_Library library;
* FT_Face face;
* FT_Bool variable_colrv1 = TRUE;
*
*
* FT_Init_FreeType( &library );
*
* FT_Property_Set( library, "truetype",
* "TEMPORARY-enable-variable-colrv1",
* &variable_colr_v1 );
* ```
*
* @since:
* 2.12.2
*/
/**************************************************************************
*

View File

@ -398,6 +398,10 @@ FT_BEGIN_HEADER
* FreeType error code. 0~means success.
*
* @note:
* The design coordinates are 16.16 fractional values for TrueType GX and
* OpenType variation fonts. For Adobe MM fonts, the values are
* integers.
*
* [Since 2.8.1] To reset all axes to the default values, call the
* function with `num_coords` set to zero and `coords` set to `NULL`.
* [Since 2.9] 'Default values' means the currently selected named
@ -440,6 +444,11 @@ FT_BEGIN_HEADER
* @return:
* FreeType error code. 0~means success.
*
* @note:
* The design coordinates are 16.16 fractional values for TrueType GX and
* OpenType variation fonts. For Adobe MM fonts, the values are
* integers.
*
* @since:
* 2.7.1
*/
@ -471,9 +480,9 @@ FT_BEGIN_HEADER
* the number of axes, use default values for the remaining axes.
*
* coords ::
* The design coordinates array (each element must be between 0 and 1.0
* for Adobe MM fonts, and between -1.0 and 1.0 for TrueType GX and
* OpenType variation fonts).
* The design coordinates array. Each element is a 16.16 fractional
* value and must be between 0 and 1.0 for Adobe MM fonts, and between
* -1.0 and 1.0 for TrueType GX and OpenType variation fonts.
*
* @return:
* FreeType error code. 0~means success.
@ -518,7 +527,7 @@ FT_BEGIN_HEADER
*
* @output:
* coords ::
* The normalized blend coordinates array.
* The normalized blend coordinates array (as 16.16 fractional values).
*
* @return:
* FreeType error code. 0~means success.

View File

@ -293,7 +293,7 @@ FT_BEGIN_HEADER
*
* miter_limit ::
* The maximum reciprocal sine of half-angle at the miter join,
* expressed as 16.16 fixed point value.
* expressed as 16.16 fixed-point value.
*
* @note:
* The `radius` is expressed in the same units as the outline

View File

@ -229,7 +229,8 @@ FT_BEGIN_HEADER
* A handle to the source stream.
*
* offset ::
* The offset of read in stream (always from start).
* The offset from the start of the stream to seek to if this is a seek
* operation (see note).
*
* buffer ::
* The address of the read buffer.
@ -241,8 +242,13 @@ FT_BEGIN_HEADER
* The number of bytes effectively read by the stream.
*
* @note:
* This function might be called to perform a seek or skip operation with
* a `count` of~0. A non-zero return value then indicates an error.
* This function performs a seek *or* a read operation depending on the
* argument values. If `count` is zero, the operation is a seek to
* `offset` bytes. If `count` is >~0, the operation is a read of `count`
* bytes from the current position in the stream, and the `offset` value
* should be ignored.
*
* For seek operations, a non-zero return value indicates an error.
*
*/
typedef unsigned long

View File

@ -315,7 +315,7 @@ FT_BEGIN_HEADER
/* The normal stack then points to these values instead of the DICT */
/* because all other operators in Private DICT clear the stack. */
/* `blend_stack' could be cleared at each operator other than blend. */
/* Blended values are stored as 5-byte fixed point values. */
/* Blended values are stored as 5-byte fixed-point values. */
FT_Byte* blend_stack; /* base of stack allocation */
FT_Byte* blend_top; /* first empty slot */

View File

@ -278,6 +278,40 @@ FT_BEGIN_HEADER
FT_Long c );
/**************************************************************************
*
* @function:
* FT_MulAddFix
*
* @description:
* Compute `(s[0] * f[0] + s[1] * f[1] + ...) / 0x10000`, where `s[n]` is
* usually a 16.16 scalar.
*
* @input:
* s ::
* The array of scalars.
* f ::
* The array of factors.
* count ::
* The number of entries in the array.
*
* @return:
* The result of `(s[0] * f[0] + s[1] * f[1] + ...) / 0x10000`.
*
* @note:
* This function is currently used for the scaled delta computation of
* variation stores. It internally uses 64-bit data types when
* available, otherwise it emulates 64-bit math by using 32-bit
* operations, which produce a correct result but most likely at a slower
* performance in comparison to the implementation base on `int64_t`.
*
*/
FT_BASE( FT_Int32 )
FT_MulAddFix( FT_Fixed* s,
FT_Int32* f,
FT_UInt count );
/*
* A variant of FT_Matrix_Multiply which scales its result afterwards. The
* idea is that both `a' and `b' are scaled by factors of 10 so that the

View File

@ -0,0 +1,85 @@
/****************************************************************************
*
* ftmmtypes.h
*
* OpenType Variations type definitions for internal use
* with the multi-masters service (specification).
*
* Copyright (C) 2022 by
* David Turner, Robert Wilhelm, Werner Lemberg, George Williams, and
* Dominik Röttsches.
*
* This file is part of the FreeType project, and may only be used,
* modified, and distributed under the terms of the FreeType project
* license, LICENSE.TXT. By continuing to use, modify, or distribute
* this file you indicate that you have read the license and
* understand and accept it fully.
*
*/
#ifndef FTMMTYPES_H_
#define FTMMTYPES_H_
FT_BEGIN_HEADER
typedef FT_Int32 FT_ItemVarDelta;
typedef struct GX_ItemVarDataRec_
{
FT_UInt itemCount; /* number of delta sets per item */
FT_UInt regionIdxCount; /* number of region indices */
FT_UInt* regionIndices; /* array of `regionCount' indices; */
/* these index `varRegionList' */
FT_ItemVarDelta* deltaSet; /* array of `itemCount' deltas */
/* use `innerIndex' for this array */
} GX_ItemVarDataRec, *GX_ItemVarData;
/* contribution of one axis to a region */
typedef struct GX_AxisCoordsRec_
{
FT_Fixed startCoord;
FT_Fixed peakCoord; /* zero means no effect (factor = 1) */
FT_Fixed endCoord;
} GX_AxisCoordsRec, *GX_AxisCoords;
typedef struct GX_VarRegionRec_
{
GX_AxisCoords axisList; /* array of axisCount records */
} GX_VarRegionRec, *GX_VarRegion;
/* item variation store */
typedef struct GX_ItemVarStoreRec_
{
FT_UInt dataCount;
GX_ItemVarData varData; /* array of dataCount records; */
/* use `outerIndex' for this array */
FT_UShort axisCount;
FT_UInt regionCount; /* total number of regions defined */
GX_VarRegion varRegionList;
} GX_ItemVarStoreRec, *GX_ItemVarStore;
typedef struct GX_DeltaSetIdxMapRec_
{
FT_ULong mapCount;
FT_UInt* outerIndex; /* indices to item var data */
FT_UInt* innerIndex; /* indices to delta set */
} GX_DeltaSetIdxMapRec, *GX_DeltaSetIdxMap;
FT_END_HEADER
#endif /* FTMMTYPES_H_ */
/* END */

View File

@ -238,42 +238,42 @@ FT_BEGIN_HEADER
#define FT_NEXT_BYTE( buffer ) \
( (unsigned char)*buffer++ )
#define FT_NEXT_SHORT( buffer ) \
( (short)( buffer += 2, FT_PEEK_SHORT( buffer - 2 ) ) )
#define FT_NEXT_SHORT( buffer ) \
( buffer += 2, FT_PEEK_SHORT( buffer - 2 ) )
#define FT_NEXT_USHORT( buffer ) \
( (unsigned short)( buffer += 2, FT_PEEK_USHORT( buffer - 2 ) ) )
#define FT_NEXT_USHORT( buffer ) \
( buffer += 2, FT_PEEK_USHORT( buffer - 2 ) )
#define FT_NEXT_OFF3( buffer ) \
( (long)( buffer += 3, FT_PEEK_OFF3( buffer - 3 ) ) )
#define FT_NEXT_OFF3( buffer ) \
( buffer += 3, FT_PEEK_OFF3( buffer - 3 ) )
#define FT_NEXT_UOFF3( buffer ) \
( (unsigned long)( buffer += 3, FT_PEEK_UOFF3( buffer - 3 ) ) )
#define FT_NEXT_UOFF3( buffer ) \
( buffer += 3, FT_PEEK_UOFF3( buffer - 3 ) )
#define FT_NEXT_LONG( buffer ) \
( (long)( buffer += 4, FT_PEEK_LONG( buffer - 4 ) ) )
#define FT_NEXT_LONG( buffer ) \
( buffer += 4, FT_PEEK_LONG( buffer - 4 ) )
#define FT_NEXT_ULONG( buffer ) \
( (unsigned long)( buffer += 4, FT_PEEK_ULONG( buffer - 4 ) ) )
#define FT_NEXT_ULONG( buffer ) \
( buffer += 4, FT_PEEK_ULONG( buffer - 4 ) )
#define FT_NEXT_SHORT_LE( buffer ) \
( (short)( buffer += 2, FT_PEEK_SHORT_LE( buffer - 2 ) ) )
#define FT_NEXT_SHORT_LE( buffer ) \
( buffer += 2, FT_PEEK_SHORT_LE( buffer - 2 ) )
#define FT_NEXT_USHORT_LE( buffer ) \
( (unsigned short)( buffer += 2, FT_PEEK_USHORT_LE( buffer - 2 ) ) )
#define FT_NEXT_USHORT_LE( buffer ) \
( buffer += 2, FT_PEEK_USHORT_LE( buffer - 2 ) )
#define FT_NEXT_OFF3_LE( buffer ) \
( (long)( buffer += 3, FT_PEEK_OFF3_LE( buffer - 3 ) ) )
#define FT_NEXT_OFF3_LE( buffer ) \
( buffer += 3, FT_PEEK_OFF3_LE( buffer - 3 ) )
#define FT_NEXT_UOFF3_LE( buffer ) \
( (unsigned long)( buffer += 3, FT_PEEK_UOFF3_LE( buffer - 3 ) ) )
#define FT_NEXT_UOFF3_LE( buffer ) \
( buffer += 3, FT_PEEK_UOFF3_LE( buffer - 3 ) )
#define FT_NEXT_LONG_LE( buffer ) \
( (long)( buffer += 4, FT_PEEK_LONG_LE( buffer - 4 ) ) )
#define FT_NEXT_LONG_LE( buffer ) \
( buffer += 4, FT_PEEK_LONG_LE( buffer - 4 ) )
#define FT_NEXT_ULONG_LE( buffer ) \
( (unsigned long)( buffer += 4, FT_PEEK_ULONG_LE( buffer - 4 ) ) )
#define FT_NEXT_ULONG_LE( buffer ) \
( buffer += 4, FT_PEEK_ULONG_LE( buffer - 4 ) )
/**************************************************************************
@ -307,17 +307,17 @@ FT_BEGIN_HEADER
#define FT_GET_CHAR() FT_GET_MACRO( FT_Stream_GetByte, FT_Char )
#define FT_GET_BYTE() FT_GET_MACRO( FT_Stream_GetByte, FT_Byte )
#define FT_GET_SHORT() FT_GET_MACRO( FT_Stream_GetUShort, FT_Short )
#define FT_GET_USHORT() FT_GET_MACRO( FT_Stream_GetUShort, FT_UShort )
#define FT_GET_UOFF3() FT_GET_MACRO( FT_Stream_GetUOffset, FT_ULong )
#define FT_GET_LONG() FT_GET_MACRO( FT_Stream_GetULong, FT_Long )
#define FT_GET_ULONG() FT_GET_MACRO( FT_Stream_GetULong, FT_ULong )
#define FT_GET_TAG4() FT_GET_MACRO( FT_Stream_GetULong, FT_ULong )
#define FT_GET_SHORT() FT_GET_MACRO( FT_Stream_GetUShort, FT_Int16 )
#define FT_GET_USHORT() FT_GET_MACRO( FT_Stream_GetUShort, FT_UInt16 )
#define FT_GET_UOFF3() FT_GET_MACRO( FT_Stream_GetUOffset, FT_UInt32 )
#define FT_GET_LONG() FT_GET_MACRO( FT_Stream_GetULong, FT_Int32 )
#define FT_GET_ULONG() FT_GET_MACRO( FT_Stream_GetULong, FT_UInt32 )
#define FT_GET_TAG4() FT_GET_MACRO( FT_Stream_GetULong, FT_UInt32 )
#define FT_GET_SHORT_LE() FT_GET_MACRO( FT_Stream_GetUShortLE, FT_Short )
#define FT_GET_USHORT_LE() FT_GET_MACRO( FT_Stream_GetUShortLE, FT_UShort )
#define FT_GET_LONG_LE() FT_GET_MACRO( FT_Stream_GetULongLE, FT_Long )
#define FT_GET_ULONG_LE() FT_GET_MACRO( FT_Stream_GetULongLE, FT_ULong )
#define FT_GET_SHORT_LE() FT_GET_MACRO( FT_Stream_GetUShortLE, FT_Int32 )
#define FT_GET_USHORT_LE() FT_GET_MACRO( FT_Stream_GetUShortLE, FT_UInt32 )
#define FT_GET_LONG_LE() FT_GET_MACRO( FT_Stream_GetULongLE, FT_Int32 )
#define FT_GET_ULONG_LE() FT_GET_MACRO( FT_Stream_GetULongLE, FT_UInt32 )
#endif
@ -334,16 +334,16 @@ FT_BEGIN_HEADER
*/
#define FT_READ_BYTE( var ) FT_READ_MACRO( FT_Stream_ReadByte, FT_Byte, var )
#define FT_READ_CHAR( var ) FT_READ_MACRO( FT_Stream_ReadByte, FT_Char, var )
#define FT_READ_SHORT( var ) FT_READ_MACRO( FT_Stream_ReadUShort, FT_Short, var )
#define FT_READ_USHORT( var ) FT_READ_MACRO( FT_Stream_ReadUShort, FT_UShort, var )
#define FT_READ_UOFF3( var ) FT_READ_MACRO( FT_Stream_ReadUOffset, FT_ULong, var )
#define FT_READ_LONG( var ) FT_READ_MACRO( FT_Stream_ReadULong, FT_Long, var )
#define FT_READ_ULONG( var ) FT_READ_MACRO( FT_Stream_ReadULong, FT_ULong, var )
#define FT_READ_SHORT( var ) FT_READ_MACRO( FT_Stream_ReadUShort, FT_Int16, var )
#define FT_READ_USHORT( var ) FT_READ_MACRO( FT_Stream_ReadUShort, FT_UInt16, var )
#define FT_READ_UOFF3( var ) FT_READ_MACRO( FT_Stream_ReadUOffset, FT_UInt32, var )
#define FT_READ_LONG( var ) FT_READ_MACRO( FT_Stream_ReadULong, FT_Int32, var )
#define FT_READ_ULONG( var ) FT_READ_MACRO( FT_Stream_ReadULong, FT_UInt32, var )
#define FT_READ_SHORT_LE( var ) FT_READ_MACRO( FT_Stream_ReadUShortLE, FT_Short, var )
#define FT_READ_USHORT_LE( var ) FT_READ_MACRO( FT_Stream_ReadUShortLE, FT_UShort, var )
#define FT_READ_LONG_LE( var ) FT_READ_MACRO( FT_Stream_ReadULongLE, FT_Long, var )
#define FT_READ_ULONG_LE( var ) FT_READ_MACRO( FT_Stream_ReadULongLE, FT_ULong, var )
#define FT_READ_SHORT_LE( var ) FT_READ_MACRO( FT_Stream_ReadUShortLE, FT_Int16, var )
#define FT_READ_USHORT_LE( var ) FT_READ_MACRO( FT_Stream_ReadUShortLE, FT_UInt16, var )
#define FT_READ_LONG_LE( var ) FT_READ_MACRO( FT_Stream_ReadULongLE, FT_Int32, var )
#define FT_READ_ULONG_LE( var ) FT_READ_MACRO( FT_Stream_ReadULongLE, FT_UInt32, var )
#ifndef FT_CONFIG_OPTION_NO_DEFAULT_SYSTEM
@ -459,23 +459,23 @@ FT_BEGIN_HEADER
FT_Stream_GetByte( FT_Stream stream );
/* read a 16-bit big-endian unsigned integer from an entered frame */
FT_BASE( FT_UShort )
FT_BASE( FT_UInt16 )
FT_Stream_GetUShort( FT_Stream stream );
/* read a 24-bit big-endian unsigned integer from an entered frame */
FT_BASE( FT_ULong )
FT_BASE( FT_UInt32 )
FT_Stream_GetUOffset( FT_Stream stream );
/* read a 32-bit big-endian unsigned integer from an entered frame */
FT_BASE( FT_ULong )
FT_BASE( FT_UInt32 )
FT_Stream_GetULong( FT_Stream stream );
/* read a 16-bit little-endian unsigned integer from an entered frame */
FT_BASE( FT_UShort )
FT_BASE( FT_UInt16 )
FT_Stream_GetUShortLE( FT_Stream stream );
/* read a 32-bit little-endian unsigned integer from an entered frame */
FT_BASE( FT_ULong )
FT_BASE( FT_UInt32 )
FT_Stream_GetULongLE( FT_Stream stream );
@ -485,7 +485,7 @@ FT_BEGIN_HEADER
FT_Error* error );
/* read a 16-bit big-endian unsigned integer from a stream */
FT_BASE( FT_UShort )
FT_BASE( FT_UInt16 )
FT_Stream_ReadUShort( FT_Stream stream,
FT_Error* error );
@ -495,17 +495,17 @@ FT_BEGIN_HEADER
FT_Error* error );
/* read a 32-bit big-endian integer from a stream */
FT_BASE( FT_ULong )
FT_BASE( FT_UInt32 )
FT_Stream_ReadULong( FT_Stream stream,
FT_Error* error );
/* read a 16-bit little-endian unsigned integer from a stream */
FT_BASE( FT_UShort )
FT_BASE( FT_UInt16 )
FT_Stream_ReadUShortLE( FT_Stream stream,
FT_Error* error );
/* read a 32-bit little-endian unsigned integer from a stream */
FT_BASE( FT_ULong )
FT_BASE( FT_UInt32 )
FT_Stream_ReadULongLE( FT_Stream stream,
FT_Error* error );

View File

@ -5,7 +5,7 @@
* The FreeType Multiple Masters and GX var services (specification).
*
* Copyright (C) 2003-2022 by
* David Turner, Robert Wilhelm, and Werner Lemberg.
* David Turner, Robert Wilhelm, Werner Lemberg, and Dominik Röttsches.
*
* This file is part of the FreeType project, and may only be used,
* modified, and distributed under the terms of the FreeType project
@ -20,6 +20,7 @@
#define SVMM_H_
#include <freetype/internal/ftserv.h>
#include <freetype/internal/ftmmtypes.h>
FT_BEGIN_HEADER
@ -96,53 +97,94 @@ FT_BEGIN_HEADER
FT_UInt* len,
FT_Fixed* weight_vector );
typedef FT_Error
(*FT_Var_Load_Delta_Set_Idx_Map_Func)( FT_Face face,
FT_ULong offset,
GX_DeltaSetIdxMap map,
GX_ItemVarStore itemStore,
FT_ULong table_len );
typedef FT_Error
(*FT_Var_Load_Item_Var_Store_Func)( FT_Face face,
FT_ULong offset,
GX_ItemVarStore itemStore );
typedef FT_ItemVarDelta
(*FT_Var_Get_Item_Delta_Func)( FT_Face face,
GX_ItemVarStore itemStore,
FT_UInt outerIndex,
FT_UInt innerIndex );
typedef void
(*FT_Var_Done_Item_Var_Store_Func)( FT_Face face,
GX_ItemVarStore itemStore );
typedef void
(*FT_Var_Done_Delta_Set_Idx_Map_Func)( FT_Face face,
GX_DeltaSetIdxMap deltaSetIdxMap );
FT_DEFINE_SERVICE( MultiMasters )
{
FT_Get_MM_Func get_mm;
FT_Set_MM_Design_Func set_mm_design;
FT_Set_MM_Blend_Func set_mm_blend;
FT_Get_MM_Blend_Func get_mm_blend;
FT_Get_MM_Var_Func get_mm_var;
FT_Set_Var_Design_Func set_var_design;
FT_Get_Var_Design_Func get_var_design;
FT_Set_Instance_Func set_instance;
FT_Set_MM_WeightVector_Func set_mm_weightvector;
FT_Get_MM_WeightVector_Func get_mm_weightvector;
FT_Get_MM_Func get_mm;
FT_Set_MM_Design_Func set_mm_design;
FT_Set_MM_Blend_Func set_mm_blend;
FT_Get_MM_Blend_Func get_mm_blend;
FT_Get_MM_Var_Func get_mm_var;
FT_Set_Var_Design_Func set_var_design;
FT_Get_Var_Design_Func get_var_design;
FT_Set_Instance_Func set_instance;
FT_Set_MM_WeightVector_Func set_mm_weightvector;
FT_Get_MM_WeightVector_Func get_mm_weightvector;
/* for internal use; only needed for code sharing between modules */
FT_Get_Var_Blend_Func get_var_blend;
FT_Done_Blend_Func done_blend;
FT_Var_Load_Delta_Set_Idx_Map_Func load_delta_set_idx_map;
FT_Var_Load_Item_Var_Store_Func load_item_var_store;
FT_Var_Get_Item_Delta_Func get_item_delta;
FT_Var_Done_Item_Var_Store_Func done_item_var_store;
FT_Var_Done_Delta_Set_Idx_Map_Func done_delta_set_idx_map;
FT_Get_Var_Blend_Func get_var_blend;
FT_Done_Blend_Func done_blend;
};
#define FT_DEFINE_SERVICE_MULTIMASTERSREC( class_, \
get_mm_, \
set_mm_design_, \
set_mm_blend_, \
get_mm_blend_, \
get_mm_var_, \
set_var_design_, \
get_var_design_, \
set_instance_, \
set_weightvector_, \
get_weightvector_, \
get_var_blend_, \
done_blend_ ) \
static const FT_Service_MultiMastersRec class_ = \
{ \
get_mm_, \
set_mm_design_, \
set_mm_blend_, \
get_mm_blend_, \
get_mm_var_, \
set_var_design_, \
get_var_design_, \
set_instance_, \
set_weightvector_, \
get_weightvector_, \
get_var_blend_, \
done_blend_ \
#define FT_DEFINE_SERVICE_MULTIMASTERSREC( class_, \
get_mm_, \
set_mm_design_, \
set_mm_blend_, \
get_mm_blend_, \
get_mm_var_, \
set_var_design_, \
get_var_design_, \
set_instance_, \
set_weightvector_, \
get_weightvector_, \
load_delta_set_idx_map_, \
load_item_var_store_, \
get_item_delta_, \
done_item_var_store_, \
done_delta_set_idx_map_, \
get_var_blend_, \
done_blend_ ) \
static const FT_Service_MultiMastersRec class_ = \
{ \
get_mm_, \
set_mm_design_, \
set_mm_blend_, \
get_mm_blend_, \
get_mm_var_, \
set_var_design_, \
get_var_design_, \
set_instance_, \
set_weightvector_, \
get_weightvector_, \
load_delta_set_idx_map_, \
load_item_var_store_, \
get_item_delta_, \
done_item_var_store_, \
done_delta_set_idx_map_, \
get_var_blend_, \
done_blend_ \
};
/* */

View File

@ -335,7 +335,8 @@ endif
# Harfbuzz support
harfbuzz_dep = dependency('harfbuzz',
version: '>= 2.0.0',
required: get_option('harfbuzz'))
required: get_option('harfbuzz'),
default_options: ['freetype=disabled'])
if harfbuzz_dep.found()
ftoption_command += ['--enable=FT_CONFIG_OPTION_USE_HARFBUZZ']

View File

@ -1085,4 +1085,71 @@
}
FT_BASE_DEF( FT_Int32 )
FT_MulAddFix( FT_Fixed* s,
FT_Int32* f,
FT_UInt count )
{
FT_UInt i;
FT_Int64 temp;
#ifndef FT_INT64
FT_Int64 halfUnit;
#endif
#ifdef FT_INT64
temp = 0;
for ( i = 0; i < count; ++i )
temp += (FT_Int64)s[i] * f[i];
return ( temp + 0x8000 ) >> 16;
#else
temp.hi = 0;
temp.lo = 0;
for ( i = 0; i < count; ++i )
{
FT_Int64 multResult;
FT_Int sign = 1;
FT_UInt32 carry = 0;
FT_UInt32 scalar;
FT_UInt32 factor;
scalar = (FT_UInt32)s[i];
factor = (FT_UInt32)f[i];
FT_MOVE_SIGN( s[i], scalar, sign );
FT_MOVE_SIGN( f[i], factor, sign );
ft_multo64( scalar, factor, &multResult );
if ( sign < 0 )
{
/* Emulated `FT_Int64` negation. */
carry = ( multResult.lo == 0 );
multResult.lo = ~multResult.lo + 1;
multResult.hi = ~multResult.hi + carry;
}
FT_Add64( &temp, &multResult, &temp );
}
/* Round value. */
halfUnit.hi = 0;
halfUnit.lo = 0x8000;
FT_Add64( &temp, &halfUnit, &temp );
return (FT_Int32)( ( (FT_Int32)( temp.hi & 0xFFFF ) << 16 ) |
( temp.lo >> 16 ) );
#endif /* !FT_INT64 */
}
/* END */

View File

@ -217,7 +217,7 @@
error = FT_GlyphLoader_CreateExtra( loader );
if ( error )
return error;
goto Exit;
/* check points & tags */
new_max = (FT_UInt)base->n_points + (FT_UInt)current->n_points +
@ -229,7 +229,10 @@
new_max = FT_PAD_CEIL( new_max, 8 );
if ( new_max > FT_OUTLINE_POINTS_MAX )
return FT_THROW( Array_Too_Large );
{
error = FT_THROW( Array_Too_Large );
goto Exit;
}
if ( FT_RENEW_ARRAY( base->points, old_max, new_max ) ||
FT_RENEW_ARRAY( base->tags, old_max, new_max ) )
@ -254,7 +257,7 @@
error = FT_GlyphLoader_CreateExtra( loader );
if ( error )
return error;
goto Exit;
/* check contours */
old_max = loader->max_contours;
@ -265,7 +268,10 @@
new_max = FT_PAD_CEIL( new_max, 4 );
if ( new_max > FT_OUTLINE_CONTOURS_MAX )
return FT_THROW( Array_Too_Large );
{
error = FT_THROW( Array_Too_Large );
goto Exit;
}
if ( FT_RENEW_ARRAY( base->contours, old_max, new_max ) )
goto Exit;

View File

@ -605,7 +605,7 @@
FT_FREE( doc->svg_document );
slot->internal->load_flags &= ~FT_GLYPH_OWN_GZIP_SVG;
slot->internal->flags &= ~FT_GLYPH_OWN_GZIP_SVG;
}
}
#endif
@ -2215,7 +2215,8 @@
if ( FT_QALLOC( sfnt_data, rlen ) )
return error;
error = FT_Stream_Read( stream, (FT_Byte *)sfnt_data, (FT_ULong)rlen );
if ( error ) {
if ( error )
{
FT_FREE( sfnt_data );
goto Exit;
}

View File

@ -363,11 +363,11 @@
}
FT_BASE_DEF( FT_UShort )
FT_BASE_DEF( FT_UInt16 )
FT_Stream_GetUShort( FT_Stream stream )
{
FT_Byte* p;
FT_UShort result;
FT_UInt16 result;
FT_ASSERT( stream && stream->cursor );
@ -382,11 +382,11 @@
}
FT_BASE_DEF( FT_UShort )
FT_BASE_DEF( FT_UInt16 )
FT_Stream_GetUShortLE( FT_Stream stream )
{
FT_Byte* p;
FT_UShort result;
FT_UInt16 result;
FT_ASSERT( stream && stream->cursor );
@ -401,11 +401,11 @@
}
FT_BASE_DEF( FT_ULong )
FT_BASE_DEF( FT_UInt32 )
FT_Stream_GetUOffset( FT_Stream stream )
{
FT_Byte* p;
FT_ULong result;
FT_UInt32 result;
FT_ASSERT( stream && stream->cursor );
@ -419,11 +419,11 @@
}
FT_BASE_DEF( FT_ULong )
FT_BASE_DEF( FT_UInt32 )
FT_Stream_GetULong( FT_Stream stream )
{
FT_Byte* p;
FT_ULong result;
FT_UInt32 result;
FT_ASSERT( stream && stream->cursor );
@ -437,11 +437,11 @@
}
FT_BASE_DEF( FT_ULong )
FT_BASE_DEF( FT_UInt32 )
FT_Stream_GetULongLE( FT_Stream stream )
{
FT_Byte* p;
FT_ULong result;
FT_UInt32 result;
FT_ASSERT( stream && stream->cursor );
@ -493,13 +493,13 @@
}
FT_BASE_DEF( FT_UShort )
FT_BASE_DEF( FT_UInt16 )
FT_Stream_ReadUShort( FT_Stream stream,
FT_Error* error )
{
FT_Byte reads[2];
FT_Byte* p;
FT_UShort result = 0;
FT_UInt16 result = 0;
FT_ASSERT( stream );
@ -538,13 +538,13 @@
}
FT_BASE_DEF( FT_UShort )
FT_BASE_DEF( FT_UInt16 )
FT_Stream_ReadUShortLE( FT_Stream stream,
FT_Error* error )
{
FT_Byte reads[2];
FT_Byte* p;
FT_UShort result = 0;
FT_UInt16 result = 0;
FT_ASSERT( stream );
@ -628,13 +628,13 @@
}
FT_BASE_DEF( FT_ULong )
FT_BASE_DEF( FT_UInt32 )
FT_Stream_ReadULong( FT_Stream stream,
FT_Error* error )
{
FT_Byte reads[4];
FT_Byte* p;
FT_ULong result = 0;
FT_UInt32 result = 0;
FT_ASSERT( stream );
@ -673,13 +673,13 @@
}
FT_BASE_DEF( FT_ULong )
FT_BASE_DEF( FT_UInt32 )
FT_Stream_ReadULongLE( FT_Stream stream,
FT_Error* error )
{
FT_Byte reads[4];
FT_Byte* p;
FT_ULong result = 0;
FT_UInt32 result = 0;
FT_ASSERT( stream );

View File

@ -5,7 +5,7 @@
* OpenType font driver implementation (body).
*
* Copyright (C) 1996-2022 by
* David Turner, Robert Wilhelm, and Werner Lemberg.
* David Turner, Robert Wilhelm, Werner Lemberg, and Dominik Röttsches.
*
* This file is part of the FreeType project, and may only be used,
* modified, and distributed under the terms of the FreeType project
@ -936,22 +936,103 @@
}
static FT_Error
cff_load_item_variation_store( CFF_Face face,
FT_ULong offset,
GX_ItemVarStore itemStore )
{
FT_Service_MultiMasters mm = (FT_Service_MultiMasters)face->mm;
return mm->load_item_var_store( FT_FACE(face), offset, itemStore );
}
static FT_Error
cff_load_delta_set_index_mapping( CFF_Face face,
FT_ULong offset,
GX_DeltaSetIdxMap map,
GX_ItemVarStore itemStore,
FT_ULong table_len )
{
FT_Service_MultiMasters mm = (FT_Service_MultiMasters)face->mm;
return mm->load_delta_set_idx_map( FT_FACE( face ), offset, map,
itemStore, table_len );
}
static FT_Int
cff_get_item_delta( CFF_Face face,
GX_ItemVarStore itemStore,
FT_UInt outerIndex,
FT_UInt innerIndex )
{
FT_Service_MultiMasters mm = (FT_Service_MultiMasters)face->mm;
return mm->get_item_delta( FT_FACE( face ), itemStore,
outerIndex, innerIndex );
}
static void
cff_done_item_variation_store( CFF_Face face,
GX_ItemVarStore itemStore )
{
FT_Service_MultiMasters mm = (FT_Service_MultiMasters)face->mm;
mm->done_item_var_store( FT_FACE( face ), itemStore );
}
static void
cff_done_delta_set_index_map( CFF_Face face,
GX_DeltaSetIdxMap deltaSetIdxMap )
{
FT_Service_MultiMasters mm = (FT_Service_MultiMasters)face->mm;
mm->done_delta_set_idx_map( FT_FACE ( face ), deltaSetIdxMap );
}
FT_DEFINE_SERVICE_MULTIMASTERSREC(
cff_service_multi_masters,
(FT_Get_MM_Func) NULL, /* get_mm */
(FT_Set_MM_Design_Func) NULL, /* set_mm_design */
(FT_Set_MM_Blend_Func) cff_set_mm_blend, /* set_mm_blend */
(FT_Get_MM_Blend_Func) cff_get_mm_blend, /* get_mm_blend */
(FT_Get_MM_Var_Func) cff_get_mm_var, /* get_mm_var */
(FT_Set_Var_Design_Func) cff_set_var_design, /* set_var_design */
(FT_Get_Var_Design_Func) cff_get_var_design, /* get_var_design */
(FT_Set_Instance_Func) cff_set_instance, /* set_instance */
(FT_Set_MM_WeightVector_Func)cff_set_mm_weightvector, /* set_mm_weightvector */
(FT_Get_MM_WeightVector_Func)cff_get_mm_weightvector, /* get_mm_weightvector */
(FT_Get_Var_Blend_Func) cff_get_var_blend, /* get_var_blend */
(FT_Done_Blend_Func) cff_done_blend /* done_blend */
(FT_Get_MM_Func) NULL, /* get_mm */
(FT_Set_MM_Design_Func) NULL, /* set_mm_design */
(FT_Set_MM_Blend_Func) cff_set_mm_blend, /* set_mm_blend */
(FT_Get_MM_Blend_Func) cff_get_mm_blend, /* get_mm_blend */
(FT_Get_MM_Var_Func) cff_get_mm_var, /* get_mm_var */
(FT_Set_Var_Design_Func)cff_set_var_design, /* set_var_design */
(FT_Get_Var_Design_Func)cff_get_var_design, /* get_var_design */
(FT_Set_Instance_Func) cff_set_instance, /* set_instance */
(FT_Set_MM_WeightVector_Func)
cff_set_mm_weightvector,
/* set_mm_weightvector */
(FT_Get_MM_WeightVector_Func)
cff_get_mm_weightvector,
/* get_mm_weightvector */
(FT_Var_Load_Delta_Set_Idx_Map_Func)
cff_load_delta_set_index_mapping,
/* load_delta_set_idx_map */
(FT_Var_Load_Item_Var_Store_Func)
cff_load_item_variation_store,
/* load_item_variation_store */
(FT_Var_Get_Item_Delta_Func)
cff_get_item_delta, /* get_item_delta */
(FT_Var_Done_Item_Var_Store_Func)
cff_done_item_variation_store,
/* done_item_variation_store */
(FT_Var_Done_Delta_Set_Idx_Map_Func)
cff_done_delta_set_index_map,
/* done_delta_set_index_map */
(FT_Get_Var_Blend_Func) cff_get_var_blend, /* get_var_blend */
(FT_Done_Blend_Func) cff_done_blend /* done_blend */
)

View File

@ -404,6 +404,9 @@
&dummy,
&advanceY );
glyph->root.linearHoriAdvance = advanceX;
glyph->root.linearVertAdvance = advanceY;
advanceX =
(FT_UShort)FT_MulDiv( advanceX,
glyph->root.face->size->metrics.x_ppem,

View File

@ -1288,7 +1288,7 @@
/* Blended values are written to a different buffer, */
/* using reserved operator 255. */
/* */
/* Blend calculation is done in 16.16 fixed point. */
/* Blend calculation is done in 16.16 fixed-point. */
FT_LOCAL_DEF( FT_Error )
cff_blend_doBlend( CFF_SubFont subFont,
CFF_Parser parser,
@ -1364,7 +1364,7 @@
FT_UInt32 sum;
/* convert inputs to 16.16 fixed point */
/* convert inputs to 16.16 fixed-point */
sum = cff_parse_num( parser, &parser->stack[i + base] ) * 0x10000;
for ( j = 1; j < blend->lenBV; j++ )
@ -1373,7 +1373,7 @@
/* point parser stack to new value on blend_stack */
parser->stack[i + base] = subFont->blend_top;
/* Push blended result as Type 2 5-byte fixed point number. This */
/* Push blended result as Type 2 5-byte fixed-point number. This */
/* will not conflict with actual DICTs because 255 is a reserved */
/* opcode in both CFF and CFF2 DICTs. See `cff_parse_num' for */
/* decode of this, which rounds to an integer. */

View File

@ -530,7 +530,7 @@
else if ( **d == 255 )
{
/* 16.16 fixed point is used internally for CFF2 blend results. */
/* 16.16 fixed-point is used internally for CFF2 blend results. */
/* Since these are trusted values, a limit check is not needed. */
/* After the 255, 4 bytes give the number. */

View File

@ -790,6 +790,9 @@
if ( err == Z_DATA_ERROR )
return FT_THROW( Invalid_Table );
if ( err == Z_NEED_DICT )
return FT_THROW( Invalid_Table );
return FT_Err_Ok;
}

View File

@ -143,7 +143,7 @@
return -1;
}
if ( FT_QRENEW_ARRAY( state->stack, old_size, new_size ) )
if ( FT_QREALLOC( state->stack, old_size, new_size ) )
return -1;
/* if relocating to heap */

View File

@ -2,7 +2,7 @@
*
* psfixed.h
*
* Adobe's code for Fixed Point Mathematics (specification only).
* Adobe's code for Fixed-Point Mathematics (specification only).
*
* Copyright 2007-2013 Adobe Systems Incorporated.
*
@ -43,10 +43,10 @@
FT_BEGIN_HEADER
/* rasterizer integer and fixed point arithmetic must be 32-bit */
/* rasterizer integer and fixed-point arithmetic must be 32-bit */
#define CF2_Fixed CF2_F16Dot16
typedef FT_Int32 CF2_Frac; /* 2.30 fixed point */
typedef FT_Int32 CF2_Frac; /* 2.30 fixed-point */
#define CF2_FIXED_MAX ( (CF2_Fixed)0x7FFFFFFFL )

View File

@ -72,7 +72,7 @@ FT_BEGIN_HEADER
} CF2_PathOp;
/* a matrix of fixed point values */
/* a matrix of fixed-point values */
typedef struct CF2_Matrix_
{
CF2_F16Dot16 a;

View File

@ -49,8 +49,8 @@ FT_BEGIN_HEADER
{
union
{
CF2_Fixed r; /* 16.16 fixed point */
CF2_Frac f; /* 2.30 fixed point (for font matrix) */
CF2_Fixed r; /* 16.16 fixed-point */
CF2_Frac f; /* 2.30 fixed-point (for font matrix) */
CF2_Int i;
} u;

View File

@ -1939,7 +1939,7 @@
/* now factor is 16.16 */
factor = FT_DivFix( factor, sq_line_length );
/* clamp the factor between 0.0 and 1.0 in fixed point */
/* clamp the factor between 0.0 and 1.0 in fixed-point */
if ( factor > FT_INT_16D16( 1 ) )
factor = FT_INT_16D16( 1 );
if ( factor < 0 )
@ -3164,7 +3164,7 @@
if ( min_dist.distance > sp_sq )
min_dist.distance = sp_sq;
/* square_root the values and fit in a 6.10 fixed point */
/* square_root the values and fit in a 6.10 fixed-point */
if ( USE_SQUARED_DISTANCES )
min_dist.distance = square_root( min_dist.distance );

View File

@ -33,7 +33,7 @@
*
* https://github.com/chmike/fpsqrt
*
* Use this to compute the square root of a 16.16 fixed point number.
* Use this to compute the square root of a 16.16 fixed-point number.
*/
FT_LOCAL_DEF( FT_16D16 )
square_root( FT_16D16 val )
@ -72,8 +72,8 @@
*/
/*
* Convert 16.16 fixed point values to the desired output format.
* In this case we reduce 16.16 fixed point values to normalized
* Convert 16.16 fixed-point values to the desired output format.
* In this case we reduce 16.16 fixed-point values to normalized
* 8-bit values.
*
* The `max_value` in the parameter is the maximum value in the

View File

@ -657,7 +657,7 @@
/*
* Find the shortest decimal representation of a 16.16 fixed point
* Find the shortest decimal representation of a 16.16 fixed-point
* number. The function fills `buf' with the result, returning a pointer
* to the position after the representation's last byte.
*/
@ -733,7 +733,7 @@
an equivalent representation of `fixed'.
The above FOR loop always finds the larger of the two values; I
verified this by iterating over all possible fixed point numbers.
verified this by iterating over all possible fixed-point numbers.
If the remainder is 17232*10, both values are equally good, and we
take the next even number (following IEEE 754's `round to nearest,
@ -741,7 +741,7 @@
If the remainder is smaller than 17232*10, the lower of the two
numbers is nearer to the exact result (values 17232 and 34480 were
also found by testing all possible fixed point values).
also found by testing all possible fixed-point values).
We use this to find a shorter decimal representation. If not ending
with digit zero, we take the representation with less error.

View File

@ -162,8 +162,7 @@
}
/* Don't trust `totalSfntSize' before thorough checks. */
if ( FT_QALLOC( sfnt, 12 + woff.num_tables * 16UL ) ||
FT_NEW( sfnt_stream ) )
if ( FT_QALLOC( sfnt, 12 ) || FT_NEW( sfnt_stream ) )
goto Exit;
sfnt_header = sfnt;
@ -196,8 +195,8 @@
/* tag value, the tables themselves are not. We thus have to */
/* sort them by offset and check that they don't overlap. */
if ( FT_NEW_ARRAY( tables, woff.num_tables ) ||
FT_NEW_ARRAY( indices, woff.num_tables ) )
if ( FT_QNEW_ARRAY( tables, woff.num_tables ) ||
FT_QNEW_ARRAY( indices, woff.num_tables ) )
goto Exit;
FT_TRACE2(( "\n" ));
@ -328,9 +327,7 @@
}
/* Now use `totalSfntSize'. */
if ( FT_REALLOC( sfnt,
12 + woff.num_tables * 16UL,
woff.totalSfntSize ) )
if ( FT_QREALLOC( sfnt, 12, woff.totalSfntSize ) )
goto Exit;
sfnt_header = sfnt + 12;

View File

@ -229,9 +229,9 @@
{
FT_TRACE6(( "Reallocating %lu to %lu.\n",
*dst_size, (*offset + size) ));
if ( FT_REALLOC( dst,
(FT_ULong)( *dst_size ),
(FT_ULong)( *offset + size ) ) )
if ( FT_QREALLOC( dst,
(FT_ULong)( *dst_size ),
(FT_ULong)( *offset + size ) ) )
goto Exit;
*dst_size = *offset + size;
@ -784,7 +784,7 @@
goto Fail;
loca_buf_size = loca_values_size * offset_size;
if ( FT_QNEW_ARRAY( loca_buf, loca_buf_size ) )
if ( FT_QALLOC( loca_buf, loca_buf_size ) )
goto Fail;
dst = loca_buf;
@ -863,7 +863,7 @@
WOFF2_Point points = NULL;
if ( FT_NEW_ARRAY( substreams, num_substreams ) )
if ( FT_QNEW_ARRAY( substreams, num_substreams ) )
goto Fail;
if ( FT_STREAM_SKIP( 2 ) )
@ -926,7 +926,7 @@
offset += overlap_bitmap_length;
}
if ( FT_NEW_ARRAY( loca_values, num_glyphs + 1 ) )
if ( FT_QNEW_ARRAY( loca_values, num_glyphs + 1 ) )
goto Fail;
points_size = 0;
@ -938,10 +938,10 @@
substreams[BBOX_STREAM].offset += bbox_bitmap_length;
glyph_buf_size = WOFF2_DEFAULT_GLYPH_BUF;
if ( FT_NEW_ARRAY( glyph_buf, glyph_buf_size ) )
if ( FT_QALLOC( glyph_buf, glyph_buf_size ) )
goto Fail;
if ( FT_NEW_ARRAY( info->x_mins, num_glyphs ) )
if ( FT_QNEW_ARRAY( info->x_mins, num_glyphs ) )
goto Fail;
for ( i = 0; i < num_glyphs; ++i )
@ -999,7 +999,7 @@
size_needed = 12 + composite_size + instruction_size;
if ( glyph_buf_size < size_needed )
{
if ( FT_RENEW_ARRAY( glyph_buf, glyph_buf_size, size_needed ) )
if ( FT_QREALLOC( glyph_buf, glyph_buf_size, size_needed ) )
goto Fail;
glyph_buf_size = size_needed;
}
@ -1075,7 +1075,7 @@
have_overlap = TRUE;
}
if ( FT_NEW_ARRAY( n_points_arr, n_contours ) )
if ( FT_QNEW_ARRAY( n_points_arr, n_contours ) )
goto Fail;
if ( FT_STREAM_SEEK( substreams[N_POINTS_STREAM].offset ) )
@ -1112,7 +1112,7 @@
/* Create array to store point information. */
points_size = total_n_points;
if ( FT_NEW_ARRAY( points, points_size ) )
if ( FT_QNEW_ARRAY( points, points_size ) )
goto Fail;
if ( triplet_decode( flags_buf,
@ -1141,7 +1141,7 @@
instruction_size;
if ( glyph_buf_size < size_needed )
{
if ( FT_RENEW_ARRAY( glyph_buf, glyph_buf_size, size_needed ) )
if ( FT_QREALLOC( glyph_buf, glyph_buf_size, size_needed ) )
goto Fail;
glyph_buf_size = size_needed;
}
@ -1226,8 +1226,7 @@
*glyf_checksum += compute_ULong_sum( glyph_buf, glyph_size );
/* Store x_mins, may be required to reconstruct `hmtx'. */
if ( n_contours > 0 )
info->x_mins[i] = (FT_Short)x_min;
info->x_mins[i] = (FT_Short)x_min;
}
info->glyf_table->dst_length = dest_offset - info->glyf_table->dst_offset;
@ -1344,7 +1343,7 @@
offset_size = index_format ? 4 : 2;
/* Create `x_mins' array. */
if ( FT_NEW_ARRAY( info->x_mins, num_glyphs ) )
if ( FT_QNEW_ARRAY( info->x_mins, num_glyphs ) )
return error;
loca_offset = info->loca_table->src_offset;
@ -1432,8 +1431,8 @@
if ( num_hmetrics < 1 )
goto Fail;
if ( FT_NEW_ARRAY( advance_widths, num_hmetrics ) ||
FT_NEW_ARRAY( lsbs, num_glyphs ) )
if ( FT_QNEW_ARRAY( advance_widths, num_hmetrics ) ||
FT_QNEW_ARRAY( lsbs, num_glyphs ) )
goto Fail;
/* Read `advanceWidth' stream. Always present. */
@ -1484,7 +1483,7 @@
/* Build the hmtx table. */
hmtx_table_size = 2 * num_hmetrics + 2 * num_glyphs;
if ( FT_NEW_ARRAY( hmtx_table, hmtx_table_size ) )
if ( FT_QALLOC( hmtx_table, hmtx_table_size ) )
goto Fail;
dst = hmtx_table;
@ -1541,10 +1540,10 @@
{
/* Memory management of `transformed_buf' is handled by the caller. */
FT_Error error = FT_Err_Ok;
FT_Stream stream = NULL;
FT_Byte* buf_cursor = NULL;
FT_Byte* table_entry = NULL;
FT_Error error = FT_Err_Ok;
FT_Stream stream = NULL;
FT_Byte* buf_cursor = NULL;
FT_Byte table_entry[16];
/* We are reallocating memory for `sfnt', so its pointer may change. */
FT_Byte* sfnt = *sfnt_bytes;
@ -1585,10 +1584,6 @@
}
}
/* Create buffer for table entries. */
if ( FT_NEW_ARRAY( table_entry, 16 ) )
goto Fail;
/* Create a stream for the uncompressed buffer. */
if ( FT_NEW( stream ) )
goto Fail;
@ -1751,7 +1746,6 @@
/* Set pointer of sfnt stream to its correct value. */
*sfnt_bytes = sfnt;
FT_FREE( table_entry );
FT_Stream_Close( stream );
FT_FREE( stream );
@ -1764,7 +1758,6 @@
/* Set pointer of sfnt stream to its correct value. */
*sfnt_bytes = sfnt;
FT_FREE( table_entry );
FT_Stream_Close( stream );
FT_FREE( stream );
@ -1877,8 +1870,8 @@
woff2.ttc_fonts = NULL;
/* Read table directory. */
if ( FT_NEW_ARRAY( tables, woff2.num_tables ) ||
FT_NEW_ARRAY( indices, woff2.num_tables ) )
if ( FT_QNEW_ARRAY( tables, woff2.num_tables ) ||
FT_QNEW_ARRAY( indices, woff2.num_tables ) )
goto Exit;
FT_TRACE2(( "\n" ));
@ -1949,10 +1942,11 @@
goto Exit;
}
table->flags = flags;
table->src_offset = src_offset;
table->src_length = table->TransformLength;
src_offset += table->TransformLength;
table->flags = flags;
table->dst_offset = 0;
FT_TRACE2(( " %c%c%c%c %08d %08d %08ld %08ld %08ld\n",
(FT_Char)( table->Tag >> 24 ),
@ -2010,6 +2004,7 @@
FT_TRACE4(( "Number of fonts in TTC: %d\n", woff2.num_fonts ));
/* pre-zero pointers within in case of failure */
if ( FT_NEW_ARRAY( woff2.ttc_fonts, woff2.num_fonts ) )
goto Exit;
@ -2023,7 +2018,7 @@
if ( FT_READ_ULONG( ttc_font->flavor ) )
goto Exit;
if ( FT_NEW_ARRAY( ttc_font->table_indices, ttc_font->num_tables ) )
if ( FT_QNEW_ARRAY( ttc_font->table_indices, ttc_font->num_tables ) )
goto Exit;
FT_TRACE5(( "Number of tables in font %d: %d\n",
@ -2302,9 +2297,9 @@
{
FT_TRACE5(( "Trimming sfnt stream from %lu to %lu.\n",
sfnt_size, woff2.actual_sfnt_size ));
if ( FT_REALLOC( sfnt,
(FT_ULong)( sfnt_size ),
(FT_ULong)( woff2.actual_sfnt_size ) ) )
if ( FT_QREALLOC( sfnt,
(FT_ULong)( sfnt_size ),
(FT_ULong)( woff2.actual_sfnt_size ) ) )
goto Exit;
}

View File

@ -30,10 +30,17 @@
#include <freetype/internal/ftcalc.h>
#include <freetype/internal/ftdebug.h>
#include <freetype/internal/ftstream.h>
#include <freetype/internal/services/svmm.h>
#include <freetype/tttags.h>
#include <freetype/ftcolor.h>
#include <freetype/config/integer-types.h>
/* the next two code lines are a temporary hack, to be removed together */
/* with `VARIABLE_COLRV1_ENABLED` and related code as soon as variable */
/* 'COLR' support is complete and tested */
#include "../truetype/ttobjs.h"
#include "../truetype/ttdriver.h"
#ifdef TT_CONFIG_OPTION_COLOR_LAYERS
@ -50,13 +57,33 @@
#define COLR_HEADER_SIZE 14U
#define VARIABLE_COLRV1_ENABLED \
( ((TT_Driver)FT_FACE_DRIVER( face ))->root.clazz == \
&tt_driver_class && \
((TT_Driver)FT_FACE_DRIVER( face ))->enable_variable_colrv1 )
typedef enum FT_PaintFormat_Internal_
{
FT_COLR_PAINTFORMAT_INTERNAL_SCALE_CENTER = 18,
FT_COLR_PAINTFORMAT_INTERNAL_SCALE_UNIFORM = 20,
FT_COLR_PAINTFORMAT_INTERNAL_SCALE_UNIFORM_CENTER = 22,
FT_COLR_PAINTFORMAT_INTERNAL_ROTATE_CENTER = 26,
FT_COLR_PAINTFORMAT_INTERNAL_SKEW_CENTER = 30
FT_COLR_PAINTFORMAT_INTERNAL_VAR_SOLID = 3,
FT_COLR_PAINTFORMAT_INTERNAL_VAR_LINEAR_GRADIENT = 5,
FT_COLR_PAINTFORMAT_INTERNAL_VAR_RADIAL_GRADIENT = 7,
FT_COLR_PAINTFORMAT_INTERNAL_VAR_SWEEP_GRADIENT = 9,
FT_COLR_PAINTFORMAT_INTERNAL_VAR_TRANSFORM = 13,
FT_COLR_PAINTFORMAT_INTERNAL_VAR_TRANSLATE = 15,
FT_COLR_PAINTFORMAT_INTERNAL_VAR_SCALE = 17,
FT_COLR_PAINTFORMAT_INTERNAL_SCALE_CENTER = 18,
FT_COLR_PAINTFORMAT_INTERNAL_VAR_SCALE_CENTER = 19,
FT_COLR_PAINTFORMAT_INTERNAL_SCALE_UNIFORM = 20,
FT_COLR_PAINTFORMAT_INTERNAL_VAR_SCALE_UNIFORM = 21,
FT_COLR_PAINTFORMAT_INTERNAL_SCALE_UNIFORM_CENTER = 22,
FT_COLR_PAINTFORMAT_INTERNAL_VAR_SCALE_UNIFORM_CENTER = 23,
FT_COLR_PAINTFORMAT_INTERNAL_VAR_ROTATE = 25,
FT_COLR_PAINTFORMAT_INTERNAL_ROTATE_CENTER = 26,
FT_COLR_PAINTFORMAT_INTERNAL_VAR_ROTATE_CENTER = 27,
FT_COLR_PAINTFORMAT_INTERNAL_VAR_SKEW = 29,
FT_COLR_PAINTFORMAT_INTERNAL_SKEW_CENTER = 30,
FT_COLR_PAINTFORMAT_INTERNAL_VAR_SKEW_CENTER = 31,
} FT_PaintFormat_Internal;
@ -104,6 +131,10 @@
*/
FT_Byte* paints_start_v1;
/* Item Variation Store for variable 'COLR' v1. */
GX_ItemVarStoreRec var_store;
GX_DeltaSetIdxMapRec delta_set_idx_map;
/* The memory that backs up the `COLR' table. */
void* table;
FT_ULong table_size;
@ -138,7 +169,9 @@
FT_ULong base_glyph_offset, layer_offset;
FT_ULong base_glyphs_offset_v1, num_base_glyphs_v1;
FT_ULong layer_offset_v1, num_layers_v1, clip_list_offset;
FT_ULong var_idx_map_offset, var_store_offset;
FT_ULong table_size;
FT_ULong colr_offset_in_stream;
/* `COLR' always needs `CPAL' */
@ -149,6 +182,8 @@
if ( error )
goto NoColr;
colr_offset_in_stream = FT_STREAM_POS();
if ( table_size < COLR_HEADER_SIZE )
goto InvalidTable;
@ -239,6 +274,64 @@
colr->clip_list = (FT_Byte*)( table + clip_list_offset );
else
colr->clip_list = 0;
colr->var_store.dataCount = 0;
colr->var_store.varData = NULL;
colr->var_store.axisCount = 0;
colr->var_store.regionCount = 0;
colr->var_store.varRegionList = 0;
colr->delta_set_idx_map.mapCount = 0;
colr->delta_set_idx_map.outerIndex = NULL;
colr->delta_set_idx_map.innerIndex = NULL;
#ifdef TT_CONFIG_OPTION_GX_VAR_SUPPORT
if ( face->variation_support & TT_FACE_FLAG_VAR_FVAR &&
VARIABLE_COLRV1_ENABLED )
{
FT_Service_MultiMasters mm = (FT_Service_MultiMasters)face->mm;
var_idx_map_offset = FT_NEXT_ULONG( p );
if ( var_idx_map_offset >= table_size )
goto InvalidTable;
var_store_offset = FT_NEXT_ULONG( p );
if ( var_store_offset >= table_size )
goto InvalidTable;
if ( var_store_offset )
{
/* If variation info has not been initialized yet, try doing so, */
/* otherwise loading the variation store will fail as it */
/* requires access to `blend` for checking the number of axes. */
if ( !face->blend )
if ( mm->get_mm_var( FT_FACE( face ), NULL ) )
goto InvalidTable;
/* Try loading `VarIdxMap` and `VarStore`. */
error = mm->load_item_var_store(
FT_FACE( face ),
colr_offset_in_stream + var_store_offset,
&colr->var_store );
if ( error != FT_Err_Ok )
goto InvalidTable;
}
if ( colr->var_store.axisCount && var_idx_map_offset )
{
error = mm->load_delta_set_idx_map(
FT_FACE( face ),
colr_offset_in_stream + var_idx_map_offset,
&colr->delta_set_idx_map,
&colr->var_store,
table_size );
if ( error != FT_Err_Ok )
goto InvalidTable;
}
}
#endif /* TT_CONFIG_OPTION_GX_VAR_SUPPORT */
}
colr->base_glyphs = (FT_Byte*)( table + base_glyph_offset );
@ -251,6 +344,19 @@
return FT_Err_Ok;
InvalidTable:
#ifdef TT_CONFIG_OPTION_GX_VAR_SUPPORT
if ( VARIABLE_COLRV1_ENABLED )
{
FT_Service_MultiMasters mm = (FT_Service_MultiMasters)face->mm;
mm->done_delta_set_idx_map( FT_FACE( face ),
&colr->delta_set_idx_map );
mm->done_item_var_store( FT_FACE( face ),
&colr->var_store );
}
#endif
error = FT_THROW( Invalid_Table );
NoColr:
@ -272,6 +378,18 @@
if ( colr )
{
#ifdef TT_CONFIG_OPTION_GX_VAR_SUPPORT
if ( VARIABLE_COLRV1_ENABLED )
{
FT_Service_MultiMasters mm = (FT_Service_MultiMasters)face->mm;
mm->done_delta_set_idx_map( FT_FACE( face ),
&colr->delta_set_idx_map );
mm->done_item_var_store( FT_FACE( face ),
&colr->var_store );
}
#endif
FT_FRAME_RELEASE( colr->table );
FT_FREE( colr );
}
@ -372,8 +490,9 @@
static FT_Bool
read_color_line( FT_Byte* color_line_p,
FT_ColorLine *colorline )
read_color_line( FT_Byte* color_line_p,
FT_ColorLine* colorline,
FT_Bool read_variable )
{
FT_Byte* p = color_line_p;
FT_PaintExtend paint_extend;
@ -388,6 +507,7 @@
colorline->color_stop_iterator.num_color_stops = FT_NEXT_USHORT( p );
colorline->color_stop_iterator.p = p;
colorline->color_stop_iterator.current_color_stop = 0;
colorline->color_stop_iterator.read_variable = read_variable;
return 1;
}
@ -428,13 +548,81 @@
}
#ifdef TT_CONFIG_OPTION_GX_VAR_SUPPORT
static FT_Bool
read_paint( Colr* colr,
get_deltas_for_var_index_base ( TT_Face face,
Colr* colr,
FT_ULong var_index_base,
FT_UInt num_deltas,
FT_ItemVarDelta* deltas )
{
FT_Error error = FT_Err_Ok;
FT_UInt outer_index = 0;
FT_UInt inner_index = 0;
FT_ULong loop_var_index = var_index_base;
FT_Service_MultiMasters mm = (FT_Service_MultiMasters)face->mm;
FT_UInt i = 0;
if ( !VARIABLE_COLRV1_ENABLED )
{
FT_ASSERT( 0 );
return 0;
}
if ( var_index_base == 0xFFFFFFFF )
{
for ( i = 0; i < num_deltas; ++i )
deltas[i] = 0;
return 1;
}
for ( i = 0; i < num_deltas; ++i )
{
loop_var_index = var_index_base + i;
if ( colr->delta_set_idx_map.innerIndex )
{
if ( loop_var_index >= colr->delta_set_idx_map.mapCount )
loop_var_index = colr->delta_set_idx_map.mapCount - 1;
outer_index = colr->delta_set_idx_map.outerIndex[loop_var_index];
inner_index = colr->delta_set_idx_map.innerIndex[loop_var_index];
}
else
{
/* TODO: Direct lookup case not implemented or tested yet. */
FT_ASSERT( 0 );
error = FT_THROW( Unimplemented_Feature );
return error;
}
deltas[i] = mm->get_item_delta( FT_FACE( face ), &colr->var_store,
outer_index, inner_index );
}
return 1;
}
#endif /* TT_CONFIG_OPTION_GX_VAR_SUPPORT */
static FT_Bool
read_paint( TT_Face face,
Colr* colr,
FT_Byte* p,
FT_COLR_Paint* apaint )
{
FT_Byte* paint_base = p;
FT_Byte* child_table_p = NULL;
FT_Byte* paint_base = p;
FT_Byte* child_table_p = NULL;
FT_Bool do_read_var = FALSE;
FT_ULong var_index_base = 0;
/* Longest varIndexBase offset is 5 in the spec. */
FT_ItemVarDelta item_deltas[6] = { 0, 0, 0, 0, 0, 0 };
if ( !p || !colr || !colr->table )
@ -475,11 +663,30 @@
return 1;
}
else if ( apaint->format == FT_COLR_PAINTFORMAT_SOLID )
else if ( apaint->format == FT_COLR_PAINTFORMAT_SOLID ||
(FT_PaintFormat_Internal)apaint->format ==
FT_COLR_PAINTFORMAT_INTERNAL_VAR_SOLID )
{
apaint->u.solid.color.palette_index = FT_NEXT_USHORT( p );
apaint->u.solid.color.alpha = FT_NEXT_SHORT( p );
#ifdef TT_CONFIG_OPTION_GX_VAR_SUPPORT
if ( (FT_PaintFormat_Internal)apaint->format ==
FT_COLR_PAINTFORMAT_INTERNAL_VAR_SOLID &&
VARIABLE_COLRV1_ENABLED )
{
var_index_base = FT_NEXT_ULONG( p );
if ( !get_deltas_for_var_index_base( face, colr, var_index_base, 1,
item_deltas ) )
return 0;
apaint->u.solid.color.alpha += item_deltas[0];
}
#endif
apaint->format = FT_COLR_PAINTFORMAT_SOLID;
return 1;
}
@ -500,10 +707,14 @@
if ( !get_child_table_pointer( colr, paint_base, &p, &child_table_p ) )
return 0;
if ( apaint->format == FT_COLR_PAINTFORMAT_LINEAR_GRADIENT )
if ( apaint->format == FT_COLR_PAINTFORMAT_LINEAR_GRADIENT ||
( do_read_var =
( (FT_PaintFormat_Internal)apaint->format ==
FT_COLR_PAINTFORMAT_INTERNAL_VAR_LINEAR_GRADIENT ) ) )
{
if ( !read_color_line( child_table_p,
&apaint->u.linear_gradient.colorline ) )
&apaint->u.linear_gradient.colorline,
do_read_var ) )
return 0;
/*
@ -517,16 +728,40 @@
apaint->u.linear_gradient.p2.x = INT_TO_FIXED( FT_NEXT_SHORT( p ) );
apaint->u.linear_gradient.p2.y = INT_TO_FIXED( FT_NEXT_SHORT( p ) );
#ifdef TT_CONFIG_OPTION_GX_VAR_SUPPORT
if ( do_read_var && VARIABLE_COLRV1_ENABLED )
{
var_index_base = FT_NEXT_ULONG ( p );
if ( !get_deltas_for_var_index_base( face, colr, var_index_base, 6,
item_deltas ) )
return 0;
apaint->u.linear_gradient.p0.x += INT_TO_FIXED( item_deltas[0] );
apaint->u.linear_gradient.p0.y += INT_TO_FIXED( item_deltas[1] );
apaint->u.linear_gradient.p1.x += INT_TO_FIXED( item_deltas[2] );
apaint->u.linear_gradient.p1.y += INT_TO_FIXED( item_deltas[3] );
apaint->u.linear_gradient.p2.x += INT_TO_FIXED( item_deltas[4] );
apaint->u.linear_gradient.p2.y += INT_TO_FIXED( item_deltas[5] );
}
#endif
apaint->format = FT_COLR_PAINTFORMAT_LINEAR_GRADIENT;
return 1;
}
else if ( apaint->format == FT_COLR_PAINTFORMAT_RADIAL_GRADIENT )
else if ( apaint->format == FT_COLR_PAINTFORMAT_RADIAL_GRADIENT ||
( do_read_var =
( (FT_PaintFormat_Internal)apaint->format ==
FT_COLR_PAINTFORMAT_INTERNAL_VAR_RADIAL_GRADIENT ) ) )
{
FT_Pos tmp;
if ( !read_color_line( child_table_p,
&apaint->u.radial_gradient.colorline ) )
&apaint->u.radial_gradient.colorline,
do_read_var ) )
return 0;
/* In the OpenType specification, `r0` and `r1` are defined as */
@ -546,13 +781,41 @@
tmp = INT_TO_FIXED( FT_NEXT_SHORT( p ) );
apaint->u.radial_gradient.r1 = tmp < 0 ? FT_INT_MAX : tmp;
#ifdef TT_CONFIG_OPTION_GX_VAR_SUPPORT
if ( do_read_var && VARIABLE_COLRV1_ENABLED )
{
var_index_base = FT_NEXT_ULONG ( p );
if ( !get_deltas_for_var_index_base( face, colr, var_index_base, 6,
item_deltas ) )
return 0;
apaint->u.radial_gradient.c0.x += INT_TO_FIXED( item_deltas[0] );
apaint->u.radial_gradient.c0.y += INT_TO_FIXED( item_deltas[1] );
// TODO: Anything to be done about UFWORD deltas here?
apaint->u.radial_gradient.r0 += INT_TO_FIXED( item_deltas[2] );
apaint->u.radial_gradient.c1.x += INT_TO_FIXED( item_deltas[3] );
apaint->u.radial_gradient.c1.y += INT_TO_FIXED( item_deltas[4] );
apaint->u.radial_gradient.r1 += INT_TO_FIXED( item_deltas[5] );
}
#endif
apaint->format = FT_COLR_PAINTFORMAT_RADIAL_GRADIENT;
return 1;
}
else if ( apaint->format == FT_COLR_PAINTFORMAT_SWEEP_GRADIENT )
else if ( apaint->format == FT_COLR_PAINTFORMAT_SWEEP_GRADIENT ||
( do_read_var =
( (FT_PaintFormat_Internal)apaint->format ==
FT_COLR_PAINTFORMAT_INTERNAL_VAR_SWEEP_GRADIENT ) ) )
{
if ( !read_color_line( child_table_p,
&apaint->u.sweep_gradient.colorline ) )
&apaint->u.sweep_gradient.colorline,
do_read_var) )
return 0;
apaint->u.sweep_gradient.center.x =
@ -565,6 +828,27 @@
apaint->u.sweep_gradient.end_angle =
F2DOT14_TO_FIXED( FT_NEXT_SHORT( p ) );
#ifdef TT_CONFIG_OPTION_GX_VAR_SUPPORT
if ( do_read_var && VARIABLE_COLRV1_ENABLED )
{
var_index_base = FT_NEXT_ULONG ( p );
if ( !get_deltas_for_var_index_base( face, colr, var_index_base, 4,
item_deltas ) )
return 0;
// TODO: Handle overflow?
apaint->u.sweep_gradient.center.x += INT_TO_FIXED( item_deltas[0] );
apaint->u.sweep_gradient.center.y += INT_TO_FIXED( item_deltas[1] );
apaint->u.sweep_gradient.start_angle +=
F2DOT14_TO_FIXED( item_deltas[2] );
apaint->u.sweep_gradient.end_angle +=
F2DOT14_TO_FIXED( item_deltas[3] );
}
#endif
apaint->format = FT_COLR_PAINTFORMAT_SWEEP_GRADIENT;
return 1;
}
@ -577,7 +861,9 @@
return 1;
}
else if ( apaint->format == FT_COLR_PAINTFORMAT_TRANSFORM )
else if ( apaint->format == FT_COLR_PAINTFORMAT_TRANSFORM ||
(FT_PaintFormat_Internal)apaint->format ==
FT_COLR_PAINTFORMAT_INTERNAL_VAR_TRANSFORM )
{
apaint->u.transform.paint.p = child_table_p;
apaint->u.transform.paint.insert_root_transform = 0;
@ -598,10 +884,34 @@
apaint->u.transform.affine.dx = FT_NEXT_LONG( p );
apaint->u.transform.affine.dy = FT_NEXT_LONG( p );
#ifdef TT_CONFIG_OPTION_GX_VAR_SUPPORT
if ( (FT_PaintFormat_Internal)apaint->format ==
FT_COLR_PAINTFORMAT_INTERNAL_VAR_TRANSFORM &&
VARIABLE_COLRV1_ENABLED )
{
var_index_base = FT_NEXT_ULONG( p );
if ( !get_deltas_for_var_index_base( face, colr, var_index_base, 6,
item_deltas ) )
return 0;
apaint->u.transform.affine.xx += (FT_Fixed)item_deltas[0];
apaint->u.transform.affine.yx += (FT_Fixed)item_deltas[1];
apaint->u.transform.affine.xy += (FT_Fixed)item_deltas[2];
apaint->u.transform.affine.yy += (FT_Fixed)item_deltas[3];
apaint->u.transform.affine.dx += (FT_Fixed)item_deltas[4];
apaint->u.transform.affine.dy += (FT_Fixed)item_deltas[5];
}
#endif
apaint->format = FT_COLR_PAINTFORMAT_TRANSFORM;
return 1;
}
else if ( apaint->format == FT_COLR_PAINTFORMAT_TRANSLATE )
else if ( apaint->format == FT_COLR_PAINTFORMAT_TRANSLATE ||
(FT_PaintFormat_Internal)apaint->format ==
FT_COLR_PAINTFORMAT_INTERNAL_VAR_TRANSLATE )
{
apaint->u.translate.paint.p = child_table_p;
apaint->u.translate.paint.insert_root_transform = 0;
@ -609,17 +919,30 @@
apaint->u.translate.dx = INT_TO_FIXED( FT_NEXT_SHORT( p ) );
apaint->u.translate.dy = INT_TO_FIXED( FT_NEXT_SHORT( p ) );
#ifdef TT_CONFIG_OPTION_GX_VAR_SUPPORT
if ( (FT_PaintFormat_Internal)apaint->format ==
FT_COLR_PAINTFORMAT_INTERNAL_VAR_TRANSLATE &&
VARIABLE_COLRV1_ENABLED )
{
var_index_base = FT_NEXT_ULONG( p );
if ( !get_deltas_for_var_index_base( face, colr, var_index_base, 2,
item_deltas ) )
return 0;
apaint->u.translate.dx += INT_TO_FIXED( item_deltas[0] );
apaint->u.translate.dy += INT_TO_FIXED( item_deltas[1] );
}
#endif
apaint->format = FT_COLR_PAINTFORMAT_TRANSLATE;
return 1;
}
else if ( apaint->format ==
FT_COLR_PAINTFORMAT_SCALE ||
(FT_PaintFormat_Internal)apaint->format ==
FT_COLR_PAINTFORMAT_INTERNAL_SCALE_CENTER ||
(FT_PaintFormat_Internal)apaint->format ==
FT_COLR_PAINTFORMAT_INTERNAL_SCALE_UNIFORM ||
(FT_PaintFormat_Internal)apaint->format ==
FT_COLR_PAINTFORMAT_INTERNAL_SCALE_UNIFORM_CENTER )
else if ( apaint->format >= FT_COLR_PAINTFORMAT_SCALE &&
(FT_PaintFormat_Internal)apaint->format <=
FT_COLR_PAINTFORMAT_INTERNAL_VAR_SCALE_UNIFORM_CENTER )
{
apaint->u.scale.paint.p = child_table_p;
apaint->u.scale.paint.insert_root_transform = 0;
@ -628,10 +951,13 @@
apaint->u.scale.scale_x = F2DOT14_TO_FIXED( FT_NEXT_SHORT( p ) );
/* Non-uniform ones read an extra y value. */
if ( apaint->format ==
FT_COLR_PAINTFORMAT_SCALE ||
if ( apaint->format == FT_COLR_PAINTFORMAT_SCALE ||
(FT_PaintFormat_Internal)apaint->format ==
FT_COLR_PAINTFORMAT_INTERNAL_SCALE_CENTER )
FT_COLR_PAINTFORMAT_INTERNAL_VAR_SCALE ||
(FT_PaintFormat_Internal)apaint->format ==
FT_COLR_PAINTFORMAT_INTERNAL_SCALE_CENTER ||
(FT_PaintFormat_Internal)apaint->format ==
FT_COLR_PAINTFORMAT_INTERNAL_VAR_SCALE_CENTER )
apaint->u.scale.scale_y = F2DOT14_TO_FIXED( FT_NEXT_SHORT( p ) );
else
apaint->u.scale.scale_y = apaint->u.scale.scale_x;
@ -639,9 +965,13 @@
/* Scale paints that have a center read center coordinates, */
/* otherwise the center is (0,0). */
if ( (FT_PaintFormat_Internal)apaint->format ==
FT_COLR_PAINTFORMAT_INTERNAL_SCALE_CENTER ||
FT_COLR_PAINTFORMAT_INTERNAL_SCALE_CENTER ||
(FT_PaintFormat_Internal)apaint->format ==
FT_COLR_PAINTFORMAT_INTERNAL_SCALE_UNIFORM_CENTER )
FT_COLR_PAINTFORMAT_INTERNAL_VAR_SCALE_CENTER ||
(FT_PaintFormat_Internal)apaint->format ==
FT_COLR_PAINTFORMAT_INTERNAL_SCALE_UNIFORM_CENTER ||
(FT_PaintFormat_Internal)apaint->format ==
FT_COLR_PAINTFORMAT_INTERNAL_VAR_SCALE_UNIFORM_CENTER )
{
apaint->u.scale.center_x = INT_TO_FIXED( FT_NEXT_SHORT ( p ) );
apaint->u.scale.center_y = INT_TO_FIXED( FT_NEXT_SHORT ( p ) );
@ -652,6 +982,71 @@
apaint->u.scale.center_y = 0;
}
/* Base values set, now handle variations. */
#ifdef TT_CONFIG_OPTION_GX_VAR_SUPPORT
if ( ( (FT_PaintFormat_Internal)apaint->format ==
FT_COLR_PAINTFORMAT_INTERNAL_VAR_SCALE ||
(FT_PaintFormat_Internal)apaint->format ==
FT_COLR_PAINTFORMAT_INTERNAL_VAR_SCALE_CENTER ||
(FT_PaintFormat_Internal)apaint->format ==
FT_COLR_PAINTFORMAT_INTERNAL_VAR_SCALE_UNIFORM ||
(FT_PaintFormat_Internal)apaint->format ==
FT_COLR_PAINTFORMAT_INTERNAL_VAR_SCALE_UNIFORM_CENTER ) &&
VARIABLE_COLRV1_ENABLED )
{
var_index_base = FT_NEXT_ULONG( p );
if ( (FT_PaintFormat_Internal)apaint->format ==
FT_COLR_PAINTFORMAT_INTERNAL_VAR_SCALE )
{
if ( !get_deltas_for_var_index_base( face, colr, var_index_base, 2,
item_deltas ) )
return 0;
apaint->u.scale.scale_x += F2DOT14_TO_FIXED( item_deltas[0] );
apaint->u.scale.scale_y += F2DOT14_TO_FIXED( item_deltas[1] );
}
if ( (FT_PaintFormat_Internal)apaint->format ==
FT_COLR_PAINTFORMAT_INTERNAL_VAR_SCALE_CENTER )
{
if ( !get_deltas_for_var_index_base( face, colr, var_index_base, 4,
item_deltas ) )
return 0;
apaint->u.scale.scale_x += F2DOT14_TO_FIXED( item_deltas[0] );
apaint->u.scale.scale_y += F2DOT14_TO_FIXED( item_deltas[1] );
apaint->u.scale.center_x += INT_TO_FIXED( item_deltas[2] );
apaint->u.scale.center_y += INT_TO_FIXED( item_deltas[3] );
}
if ( (FT_PaintFormat_Internal)apaint->format ==
FT_COLR_PAINTFORMAT_INTERNAL_VAR_SCALE_UNIFORM )
{
if ( !get_deltas_for_var_index_base( face, colr, var_index_base, 1,
item_deltas ) )
return 0;
apaint->u.scale.scale_x += F2DOT14_TO_FIXED( item_deltas[0] );
apaint->u.scale.scale_y += F2DOT14_TO_FIXED( item_deltas[0] );
}
if ( (FT_PaintFormat_Internal)apaint->format ==
FT_COLR_PAINTFORMAT_INTERNAL_VAR_SCALE_UNIFORM_CENTER )
{
if ( !get_deltas_for_var_index_base( face, colr, var_index_base, 3,
item_deltas ) )
return 0;
apaint->u.scale.scale_x += F2DOT14_TO_FIXED( item_deltas[0] );
apaint->u.scale.scale_y += F2DOT14_TO_FIXED( item_deltas[0] );
apaint->u.scale.center_x += INT_TO_FIXED( item_deltas[1] );
apaint->u.scale.center_y += INT_TO_FIXED( item_deltas[2] );
}
}
#endif
/* FT 'COLR' v1 API output format always returns fully defined */
/* structs; we thus set the format to the public API value. */
apaint->format = FT_COLR_PAINTFORMAT_SCALE;
@ -659,17 +1054,26 @@
return 1;
}
else if ( apaint->format == FT_COLR_PAINTFORMAT_ROTATE ||
else if ( apaint->format == FT_COLR_PAINTFORMAT_ROTATE ||
(FT_PaintFormat_Internal)apaint->format ==
FT_COLR_PAINTFORMAT_INTERNAL_ROTATE_CENTER )
FT_COLR_PAINTFORMAT_INTERNAL_ROTATE_CENTER ||
(FT_PaintFormat_Internal)apaint->format ==
FT_COLR_PAINTFORMAT_INTERNAL_VAR_ROTATE ||
(FT_PaintFormat_Internal)apaint->format ==
FT_COLR_PAINTFORMAT_INTERNAL_VAR_ROTATE_CENTER )
{
FT_UInt num_deltas = 0;
apaint->u.rotate.paint.p = child_table_p;
apaint->u.rotate.paint.insert_root_transform = 0;
apaint->u.rotate.angle = F2DOT14_TO_FIXED( FT_NEXT_SHORT( p ) );
if ( (FT_PaintFormat_Internal)apaint->format ==
FT_COLR_PAINTFORMAT_INTERNAL_ROTATE_CENTER )
FT_COLR_PAINTFORMAT_INTERNAL_ROTATE_CENTER ||
(FT_PaintFormat_Internal)apaint->format ==
FT_COLR_PAINTFORMAT_INTERNAL_VAR_ROTATE_CENTER )
{
apaint->u.rotate.center_x = INT_TO_FIXED( FT_NEXT_SHORT( p ) );
apaint->u.rotate.center_y = INT_TO_FIXED( FT_NEXT_SHORT( p ) );
@ -680,14 +1084,52 @@
apaint->u.rotate.center_y = 0;
}
#ifdef TT_CONFIG_OPTION_GX_VAR_SUPPORT
if ( ( (FT_PaintFormat_Internal)apaint->format ==
FT_COLR_PAINTFORMAT_INTERNAL_VAR_ROTATE ||
(FT_PaintFormat_Internal)apaint->format ==
FT_COLR_PAINTFORMAT_INTERNAL_VAR_ROTATE_CENTER ) &&
VARIABLE_COLRV1_ENABLED )
{
var_index_base = FT_NEXT_ULONG( p );
if ( (FT_PaintFormat_Internal)apaint->format ==
FT_COLR_PAINTFORMAT_INTERNAL_VAR_ROTATE_CENTER )
num_deltas = 3;
if ( (FT_PaintFormat_Internal)apaint->format ==
FT_COLR_PAINTFORMAT_INTERNAL_VAR_ROTATE )
num_deltas = 1;
if ( num_deltas > 0 )
{
if ( !get_deltas_for_var_index_base( face, colr, var_index_base,
num_deltas, item_deltas ) )
return 0;
apaint->u.rotate.angle += F2DOT14_TO_FIXED( item_deltas[0] );
if ( num_deltas == 3 )
{
apaint->u.rotate.center_x += INT_TO_FIXED( item_deltas[1] );
apaint->u.rotate.center_y += INT_TO_FIXED( item_deltas[2] );
}
}
}
#endif
apaint->format = FT_COLR_PAINTFORMAT_ROTATE;
return 1;
}
else if ( apaint->format == FT_COLR_PAINTFORMAT_SKEW ||
else if ( apaint->format == FT_COLR_PAINTFORMAT_SKEW ||
(FT_PaintFormat_Internal)apaint->format ==
FT_COLR_PAINTFORMAT_INTERNAL_SKEW_CENTER )
FT_COLR_PAINTFORMAT_INTERNAL_VAR_SKEW ||
(FT_PaintFormat_Internal)apaint->format ==
FT_COLR_PAINTFORMAT_INTERNAL_SKEW_CENTER ||
(FT_PaintFormat_Internal)apaint->format ==
FT_COLR_PAINTFORMAT_INTERNAL_VAR_SKEW_CENTER )
{
apaint->u.skew.paint.p = child_table_p;
apaint->u.skew.paint.insert_root_transform = 0;
@ -696,7 +1138,9 @@
apaint->u.skew.y_skew_angle = F2DOT14_TO_FIXED( FT_NEXT_SHORT( p ) );
if ( (FT_PaintFormat_Internal)apaint->format ==
FT_COLR_PAINTFORMAT_INTERNAL_SKEW_CENTER )
FT_COLR_PAINTFORMAT_INTERNAL_SKEW_CENTER ||
(FT_PaintFormat_Internal)apaint->format ==
FT_COLR_PAINTFORMAT_INTERNAL_VAR_SKEW_CENTER )
{
apaint->u.skew.center_x = INT_TO_FIXED( FT_NEXT_SHORT( p ) );
apaint->u.skew.center_y = INT_TO_FIXED( FT_NEXT_SHORT( p ) );
@ -707,6 +1151,42 @@
apaint->u.skew.center_y = 0;
}
#ifdef TT_CONFIG_OPTION_GX_VAR_SUPPORT
if ( ( (FT_PaintFormat_Internal)apaint->format ==
FT_COLR_PAINTFORMAT_INTERNAL_VAR_SKEW ||
(FT_PaintFormat_Internal)apaint->format ==
FT_COLR_PAINTFORMAT_INTERNAL_VAR_SKEW_CENTER ) &&
VARIABLE_COLRV1_ENABLED )
{
var_index_base = FT_NEXT_ULONG( p );
if ( (FT_PaintFormat_Internal)apaint->format ==
FT_COLR_PAINTFORMAT_INTERNAL_VAR_SKEW )
{
if ( !get_deltas_for_var_index_base( face, colr, var_index_base, 2,
item_deltas ) )
return 0;
apaint->u.skew.x_skew_angle += F2DOT14_TO_FIXED( item_deltas[0] );
apaint->u.skew.y_skew_angle += F2DOT14_TO_FIXED( item_deltas[1] );
}
if ( (FT_PaintFormat_Internal)apaint->format ==
FT_COLR_PAINTFORMAT_INTERNAL_VAR_SKEW_CENTER )
{
if ( !get_deltas_for_var_index_base( face, colr, var_index_base, 4,
item_deltas ) )
return 0;
apaint->u.skew.x_skew_angle += F2DOT14_TO_FIXED( item_deltas[0] );
apaint->u.skew.y_skew_angle += F2DOT14_TO_FIXED( item_deltas[1] );
apaint->u.skew.center_x += INT_TO_FIXED( item_deltas[2] );
apaint->u.skew.center_y += INT_TO_FIXED( item_deltas[3] );
}
}
#endif
apaint->format = FT_COLR_PAINTFORMAT_SKEW;
return 1;
@ -1037,6 +1517,8 @@
Colr* colr = (Colr*)face->colr;
FT_Byte* p;
FT_Long var_index_base;
FT_Int item_deltas[2];
if ( !colr || !colr->table )
@ -1054,12 +1536,34 @@
/* Iterator points at first `ColorStop` of `ColorLine`. */
p = iterator->p;
color_stop->stop_offset = FT_NEXT_SHORT( p );
color_stop->stop_offset = (FT_Fixed)FT_NEXT_SHORT( p ) << 2;
color_stop->color.palette_index = FT_NEXT_USHORT( p );
color_stop->color.alpha = FT_NEXT_SHORT( p );
if ( iterator->read_variable )
{
/* Pointer p needs to be advanced independently of whether we intend */
/* to take variable deltas into account or not. Otherwise iteration */
/* would fail due to wrong offsets. */
var_index_base = FT_NEXT_ULONG( p );
#ifdef TT_CONFIG_OPTION_GX_VAR_SUPPORT
if ( VARIABLE_COLRV1_ENABLED )
{
if ( !get_deltas_for_var_index_base( face, colr,
var_index_base,
2,
item_deltas ) )
return 0;
color_stop->stop_offset += (FT_Fixed)item_deltas[0] << 2;
color_stop->color.alpha += item_deltas[1];
}
#endif
}
iterator->p = p;
iterator->current_color_stop++;
@ -1139,7 +1643,7 @@
return 1;
}
return read_paint( colr, opaque_paint.p, paint );
return read_paint( face, colr, opaque_paint.p, paint );
}

View File

@ -306,7 +306,7 @@
}
#ifdef TT_CONFIG_OPTION_GX_VAR_SUPPORT
if ( var )
if ( var && face->blend )
{
FT_Face f = FT_FACE( face );
FT_Int a = (FT_Int)*aadvance;

View File

@ -1909,10 +1909,10 @@ typedef ptrdiff_t FT_PtrDist;
static int
gray_convert_glyph_inner( RAS_ARG,
gray_convert_glyph_inner( RAS_ARG_
int continued )
{
int error;
volatile int error;
if ( ft_setjmp( ras.jump_buffer ) == 0 )
@ -2004,7 +2004,7 @@ typedef ptrdiff_t FT_PtrDist;
ras.max_ey = band[0];
ras.count_ey = width;
error = gray_convert_glyph_inner( RAS_VAR, continued );
error = gray_convert_glyph_inner( RAS_VAR_ continued );
continued = 1;
if ( !error )

View File

@ -108,6 +108,23 @@
return error;
}
if ( !ft_strcmp( property_name, "TEMPORARY-enable-variable-colrv1" ) )
{
/* This flag is temporary and can't be set with environment variables. */
if ( !value_is_string )
{
FT_Bool* bv = (FT_Bool*)value;
if ( *bv == TRUE || *bv == FALSE)
driver->enable_variable_colrv1 = *bv;
else
error = FT_ERR( Unimplemented_Feature );
} else
error = FT_ERR( Invalid_Argument );
return error;
}
FT_TRACE2(( "tt_property_set: missing property `%s'\n",
property_name ));
return FT_THROW( Missing_Property );
@ -507,19 +524,34 @@
FT_DEFINE_SERVICE_MULTIMASTERSREC(
tt_service_gx_multi_masters,
(FT_Get_MM_Func) NULL, /* get_mm */
(FT_Set_MM_Design_Func) NULL, /* set_mm_design */
(FT_Set_MM_Blend_Func) TT_Set_MM_Blend, /* set_mm_blend */
(FT_Get_MM_Blend_Func) TT_Get_MM_Blend, /* get_mm_blend */
(FT_Get_MM_Var_Func) TT_Get_MM_Var, /* get_mm_var */
(FT_Set_Var_Design_Func) TT_Set_Var_Design, /* set_var_design */
(FT_Get_Var_Design_Func) TT_Get_Var_Design, /* get_var_design */
(FT_Set_Instance_Func) TT_Set_Named_Instance, /* set_instance */
(FT_Set_MM_WeightVector_Func)NULL, /* set_mm_weightvector */
(FT_Get_MM_WeightVector_Func)NULL, /* get_mm_weightvector */
(FT_Get_Var_Blend_Func) tt_get_var_blend, /* get_var_blend */
(FT_Done_Blend_Func) tt_done_blend /* done_blend */
(FT_Get_MM_Func) NULL, /* get_mm */
(FT_Set_MM_Design_Func) NULL, /* set_mm_design */
(FT_Set_MM_Blend_Func) TT_Set_MM_Blend, /* set_mm_blend */
(FT_Get_MM_Blend_Func) TT_Get_MM_Blend, /* get_mm_blend */
(FT_Get_MM_Var_Func) TT_Get_MM_Var, /* get_mm_var */
(FT_Set_Var_Design_Func)TT_Set_Var_Design, /* set_var_design */
(FT_Get_Var_Design_Func)TT_Get_Var_Design, /* get_var_design */
(FT_Set_Instance_Func) TT_Set_Named_Instance, /* set_instance */
(FT_Set_MM_WeightVector_Func)
NULL, /* set_mm_weightvector */
(FT_Get_MM_WeightVector_Func)
NULL, /* get_mm_weightvector */
(FT_Var_Load_Delta_Set_Idx_Map_Func)
tt_var_load_delta_set_index_mapping,
/* load_delta_set_idx_map */
(FT_Var_Load_Item_Var_Store_Func)
tt_var_load_item_variation_store,
/* load_item_variation_store */
(FT_Var_Get_Item_Delta_Func)
tt_var_get_item_delta, /* get_item_delta */
(FT_Var_Done_Item_Var_Store_Func)
tt_var_done_item_variation_store,
/* done_item_variation_store */
(FT_Var_Done_Delta_Set_Idx_Map_Func)
tt_var_done_delta_set_index_map,
/* done_delta_set_index_map */
(FT_Get_Var_Blend_Func) tt_get_var_blend, /* get_var_blend */
(FT_Done_Blend_Func) tt_done_blend /* done_blend */
)
FT_DEFINE_SERVICE_METRICSVARIATIONSREC(

View File

@ -801,7 +801,7 @@
FT_UInt start_point,
FT_UInt start_contour )
{
zone->n_points = (FT_UShort)load->outline.n_points -
zone->n_points = (FT_UShort)load->outline.n_points + 4 -
(FT_UShort)start_point;
zone->n_contours = load->outline.n_contours -
(FT_Short)start_contour;
@ -970,11 +970,6 @@
outline->points[n_points + 2] = loader->pp3;
outline->points[n_points + 3] = loader->pp4;
outline->tags[n_points ] = 0;
outline->tags[n_points + 1] = 0;
outline->tags[n_points + 2] = 0;
outline->tags[n_points + 3] = 0;
n_points += 4;
#ifdef TT_CONFIG_OPTION_GX_VAR_SUPPORT
@ -985,24 +980,9 @@
goto Exit;
/* Deltas apply to the unscaled data. */
error = TT_Vary_Apply_Glyph_Deltas( loader->face,
loader->glyph_index,
error = TT_Vary_Apply_Glyph_Deltas( loader,
outline,
unrounded,
(FT_UInt)n_points );
/* recalculate linear horizontal and vertical advances */
/* if we don't have HVAR and VVAR, respectively */
/* XXX: change all FreeType modules to store `linear' and `vadvance' */
/* in 26.6 format before the `base' module scales them to 16.16 */
if ( !( loader->face->variation_support & TT_FACE_FLAG_VAR_HADVANCE ) )
loader->linear = FT_PIX_ROUND( unrounded[n_points - 3].x -
unrounded[n_points - 4].x ) / 64;
if ( !( loader->face->variation_support & TT_FACE_FLAG_VAR_VADVANCE ) )
loader->vadvance = FT_PIX_ROUND( unrounded[n_points - 1].x -
unrounded[n_points - 2].x ) / 64;
unrounded );
if ( error )
goto Exit;
}
@ -1014,7 +994,7 @@
tt_prepare_zone( &loader->zone, &gloader->current, 0, 0 );
FT_ARRAY_COPY( loader->zone.orus, loader->zone.cur,
loader->zone.n_points + 4 );
loader->zone.n_points );
}
{
@ -1156,11 +1136,7 @@
}
if ( IS_HINTED( loader->load_flags ) )
{
loader->zone.n_points += 4;
error = TT_Hint_Glyph( loader, 0 );
}
#ifdef TT_CONFIG_OPTION_GX_VAR_SUPPORT
Exit:
@ -1373,11 +1349,6 @@
outline->points[outline->n_points + 2] = loader->pp3;
outline->points[outline->n_points + 3] = loader->pp4;
outline->tags[outline->n_points ] = 0;
outline->tags[outline->n_points + 1] = 0;
outline->tags[outline->n_points + 2] = 0;
outline->tags[outline->n_points + 3] = 0;
#ifdef TT_USE_BYTECODE_INTERPRETER
{
@ -1436,11 +1407,9 @@
/* Some points are likely touched during execution of */
/* instructions on components. So let's untouch them. */
for ( i = 0; i < loader->zone.n_points; i++ )
for ( i = 0; i < loader->zone.n_points - 4U; i++ )
loader->zone.tags[i] &= ~FT_CURVE_TAG_TOUCH_BOTH;
loader->zone.n_points += 4;
return TT_Hint_Glyph( loader, 1 );
}
@ -1761,57 +1730,29 @@
/* a small outline structure with four elements for */
/* communication with `TT_Vary_Apply_Glyph_Deltas' */
FT_Vector points[4];
char tags[4] = { 1, 1, 1, 1 };
short contours[4] = { 0, 1, 2, 3 };
FT_Outline outline;
/* unrounded values */
FT_Vector unrounded[4] = { {0, 0}, {0, 0}, {0, 0}, {0, 0} };
points[0].x = loader->pp1.x;
points[0].y = loader->pp1.y;
points[1].x = loader->pp2.x;
points[1].y = loader->pp2.y;
points[0] = loader->pp1;
points[1] = loader->pp2;
points[2] = loader->pp3;
points[3] = loader->pp4;
points[2].x = loader->pp3.x;
points[2].y = loader->pp3.y;
points[3].x = loader->pp4.x;
points[3].y = loader->pp4.y;
outline.n_points = 4;
outline.n_contours = 4;
outline.n_points = 0;
outline.n_contours = 0;
outline.points = points;
outline.tags = tags;
outline.contours = contours;
outline.tags = NULL;
outline.contours = NULL;
/* this must be done before scaling */
error = TT_Vary_Apply_Glyph_Deltas( loader->face,
glyph_index,
error = TT_Vary_Apply_Glyph_Deltas( loader,
&outline,
unrounded,
(FT_UInt)outline.n_points );
unrounded );
if ( error )
goto Exit;
loader->pp1.x = points[0].x;
loader->pp1.y = points[0].y;
loader->pp2.x = points[1].x;
loader->pp2.y = points[1].y;
loader->pp3.x = points[2].x;
loader->pp3.y = points[2].y;
loader->pp4.x = points[3].x;
loader->pp4.y = points[3].y;
/* recalculate linear horizontal and vertical advances */
/* if we don't have HVAR and VVAR, respectively */
if ( !( loader->face->variation_support & TT_FACE_FLAG_VAR_HADVANCE ) )
loader->linear = FT_PIX_ROUND( unrounded[1].x -
unrounded[0].x ) / 64;
if ( !( loader->face->variation_support & TT_FACE_FLAG_VAR_VADVANCE ) )
loader->vadvance = FT_PIX_ROUND( unrounded[3].x -
unrounded[2].x ) / 64;
}
#endif /* TT_CONFIG_OPTION_GX_VAR_SUPPORT */
@ -1959,17 +1900,16 @@
/* construct an outline structure for */
/* communication with `TT_Vary_Apply_Glyph_Deltas' */
outline.n_points = (short)( gloader->current.num_subglyphs + 4 );
outline.n_contours = outline.n_points;
outline.n_contours = outline.n_points = limit;
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_NEW_ARRAY( unrounded, outline.n_points ) )
if ( FT_NEW_ARRAY( points, limit + 4 ) ||
FT_NEW_ARRAY( tags, limit + 4 ) ||
FT_NEW_ARRAY( contours, limit + 4 ) ||
FT_NEW_ARRAY( unrounded, limit + 4 ) )
goto Exit1;
subglyph = gloader->current.subglyphs;
@ -1985,28 +1925,10 @@
contours[i] = i;
}
points[i].x = loader->pp1.x;
points[i].y = loader->pp1.y;
tags[i] = 1;
contours[i] = i;
i++;
points[i].x = loader->pp2.x;
points[i].y = loader->pp2.y;
tags[i] = 1;
contours[i] = i;
i++;
points[i].x = loader->pp3.x;
points[i].y = loader->pp3.y;
tags[i] = 1;
contours[i] = i;
i++;
points[i].x = loader->pp4.x;
points[i].y = loader->pp4.y;
tags[i] = 1;
contours[i] = i;
points[i++] = loader->pp1;
points[i++] = loader->pp2;
points[i++] = loader->pp3;
points[i ] = loader->pp4;
outline.points = points;
outline.tags = tags;
@ -2014,12 +1936,9 @@
/* this call provides additional offsets */
/* for each component's translation */
if ( FT_SET_ERROR( TT_Vary_Apply_Glyph_Deltas(
face,
glyph_index,
&outline,
unrounded,
(FT_UInt)outline.n_points ) ) )
if ( FT_SET_ERROR( TT_Vary_Apply_Glyph_Deltas( loader,
&outline,
unrounded ) ) )
goto Exit1;
subglyph = gloader->current.subglyphs;
@ -2033,27 +1952,6 @@
}
}
loader->pp1.x = points[i + 0].x;
loader->pp1.y = points[i + 0].y;
loader->pp2.x = points[i + 1].x;
loader->pp2.y = points[i + 1].y;
loader->pp3.x = points[i + 2].x;
loader->pp3.y = points[i + 2].y;
loader->pp4.x = points[i + 3].x;
loader->pp4.y = points[i + 3].y;
/* recalculate linear horizontal and vertical advances */
/* if we don't have HVAR and VVAR, respectively */
if ( !( face->variation_support & TT_FACE_FLAG_VAR_HADVANCE ) )
loader->linear =
FT_PIX_ROUND( unrounded[outline.n_points - 3].x -
unrounded[outline.n_points - 4].x ) / 64;
if ( !( face->variation_support & TT_FACE_FLAG_VAR_VADVANCE ) )
loader->vadvance =
FT_PIX_ROUND( unrounded[outline.n_points - 1].x -
unrounded[outline.n_points - 2].x ) / 64;
Exit1:
FT_FREE( outline.points );
FT_FREE( outline.tags );
@ -3005,6 +2903,9 @@
&topBearing,
&advanceY );
glyph->linearHoriAdvance = advanceX;
glyph->linearVertAdvance = advanceY;
advanceX = (FT_UShort)FT_MulDiv( advanceX,
glyph->face->size->metrics.x_ppem,
glyph->face->units_per_EM );

View File

@ -438,8 +438,8 @@
}
static FT_Error
ft_var_load_item_variation_store( TT_Face face,
FT_LOCAL_DEF( FT_Error )
tt_var_load_item_variation_store( TT_Face face,
FT_ULong offset,
GX_ItemVarStore itemStore )
{
@ -465,7 +465,7 @@
if ( format != 1 )
{
FT_TRACE2(( "ft_var_load_item_variation_store: bad store format %d\n",
FT_TRACE2(( "tt_var_load_item_variation_store: bad store format %d\n",
format ));
error = FT_THROW( Invalid_Table );
goto Exit;
@ -479,7 +479,17 @@
/* we need at least one entry in `itemStore->varData' */
if ( !itemStore->dataCount )
{
FT_TRACE2(( "ft_var_load_item_variation_store: missing varData\n" ));
FT_TRACE2(( "tt_var_load_item_variation_store: missing varData\n" ));
error = FT_THROW( Invalid_Table );
goto Exit;
}
/* new in OpenType 1.8.4: inner & outer index equal to 0xFFFF */
/* has a special meaning (i.e., no variation data for this item) */
if ( itemStore->dataCount == 0xFFFFU )
{
FT_TRACE2(( "ft_var_load_item_variation_store:"
" dataCount too large\n" ));
error = FT_THROW( Invalid_Table );
goto Exit;
}
@ -505,7 +515,7 @@
if ( itemStore->axisCount != (FT_Long)blend->mmvar->num_axis )
{
FT_TRACE2(( "ft_var_load_item_variation_store:"
FT_TRACE2(( "tt_var_load_item_variation_store:"
" number of axes in item variation store\n" ));
FT_TRACE2(( " "
" and `fvar' table are different\n" ));
@ -516,7 +526,7 @@
/* new constraint in OpenType 1.8.4 */
if ( itemStore->regionCount >= 32768U )
{
FT_TRACE2(( "ft_var_load_item_variation_store:"
FT_TRACE2(( "tt_var_load_item_variation_store:"
" too many variation region tables\n" ));
error = FT_THROW( Invalid_Table );
goto Exit;
@ -621,44 +631,25 @@
varData->regionIdxCount * varData->itemCount ) )
goto Exit;
/* the delta set is stored as a 2-dimensional array of shorts */
if ( long_words )
for ( j = 0; j < varData->itemCount * varData->regionIdxCount; )
{
/* new in OpenType 1.9, currently for 'COLR' table only; */
/* the deltas are interpreted as 16.16 fixed-point scaling values */
/* not supported yet */
error = FT_THROW( Invalid_Table );
goto Exit;
}
else
{
for ( j = 0; j < varData->itemCount * varData->regionIdxCount; )
if ( long_words )
{
for ( k = 0; k < wordDeltaCount; k++, j++ )
{
/* read the short deltas */
FT_Short delta;
if ( FT_READ_SHORT( delta ) )
if ( FT_READ_LONG( varData->deltaSet[j] ) )
goto Exit;
varData->deltaSet[j] = delta;
}
for ( ; k < varData->regionIdxCount; k++, j++ )
{
/* read the (signed) byte deltas */
FT_Char delta;
if ( FT_READ_CHAR( delta ) )
if ( FT_READ_SHORT( varData->deltaSet[j] ) )
goto Exit;
}
else
{
for ( k = 0; k < wordDeltaCount; k++, j++ )
if ( FT_READ_SHORT( varData->deltaSet[j] ) )
goto Exit;
for ( ; k < varData->regionIdxCount; k++, j++ )
if ( FT_READ_CHAR( varData->deltaSet[j] ) )
goto Exit;
varData->deltaSet[j] = delta;
}
}
}
}
@ -670,8 +661,8 @@
}
static FT_Error
ft_var_load_delta_set_index_mapping( TT_Face face,
FT_LOCAL_DEF( FT_Error )
tt_var_load_delta_set_index_mapping( TT_Face face,
FT_ULong offset,
GX_DeltaSetIdxMap map,
GX_ItemVarStore itemStore,
@ -728,7 +719,7 @@
/* rough sanity check */
if ( map->mapCount * entrySize > table_len )
{
FT_TRACE1(( "ft_var_load_delta_set_index_mapping:"
FT_TRACE1(( "tt_var_load_delta_set_index_mapping:"
" invalid number of delta-set index mappings\n" ));
error = FT_THROW( Invalid_Table );
goto Exit;
@ -758,6 +749,16 @@
mapData = ( mapData << 8 ) | data;
}
/* new in OpenType 1.8.4 */
if ( mapData == 0xFFFFFFFFUL )
{
/* no variation data for this item */
map->outerIndex[i] = 0xFFFFU;
map->innerIndex[i] = 0xFFFFU;
continue;
}
outerIndex = mapData >> innerBitCount;
if ( outerIndex >= itemStore->dataCount )
@ -887,7 +888,7 @@
table = blend->hvar_table;
}
error = ft_var_load_item_variation_store(
error = tt_var_load_item_variation_store(
face,
table_offset + store_offset,
&table->itemStore );
@ -896,7 +897,7 @@
if ( widthMap_offset )
{
error = ft_var_load_delta_set_index_mapping(
error = tt_var_load_delta_set_index_mapping(
face,
table_offset + widthMap_offset,
&table->widthMap,
@ -938,20 +939,28 @@
}
static FT_Int
ft_var_get_item_delta( TT_Face face,
FT_LOCAL_DEF( FT_ItemVarDelta )
tt_var_get_item_delta( TT_Face face,
GX_ItemVarStore itemStore,
FT_UInt outerIndex,
FT_UInt innerIndex )
{
GX_ItemVarData varData;
FT_Short* deltaSet;
FT_Stream stream = FT_FACE_STREAM( face );
FT_Memory memory = stream->memory;
FT_Error error = FT_Err_Ok;
FT_UInt master, j;
FT_Fixed netAdjustment = 0; /* accumulated adjustment */
FT_Fixed scaledDelta;
FT_Fixed delta;
GX_ItemVarData varData;
FT_ItemVarDelta* deltaSet;
FT_UInt master, j;
FT_Fixed* scalars;
FT_ItemVarDelta returnValue;
/* OpenType 1.8.4+: No variation data for this item
* as indices have special value 0xFFFF. */
if (outerIndex == 0xFFFF && innerIndex == 0xFFFF)
return 0;
/* See pseudo code from `Font Variations Overview' */
/* in the OpenType specification. */
@ -959,6 +968,9 @@
varData = &itemStore->varData[outerIndex];
deltaSet = &varData->deltaSet[varData->regionIdxCount * innerIndex];
if ( FT_QNEW_ARRAY( scalars, varData->regionIdxCount ) )
return 0;
/* outer loop steps through master designs to be blended */
for ( master = 0; master < varData->regionIdxCount; master++ )
{
@ -1008,18 +1020,33 @@
FT_MulDiv( scalar,
axis->endCoord - face->blend->normalizedcoords[j],
axis->endCoord - axis->peakCoord );
} /* per-axis loop */
/* get the scaled delta for this region */
delta = FT_intToFixed( deltaSet[master] );
scaledDelta = FT_MulFix( scalar, delta );
/* accumulate the adjustments from each region */
netAdjustment = netAdjustment + scaledDelta;
scalars[master] = scalar;
} /* per-region loop */
return FT_fixedToInt( netAdjustment );
/* Compute the scaled delta for this region.
*
* From: https://docs.microsoft.com/en-us/typography/opentype/spec/otvarcommonformats#item-variation-store-header-and-item-variation-data-subtables:
*
* `Fixed` is a 32-bit (16.16) type and, in the general case, requires
* 32-bit deltas. As described above, the `DeltaSet` record can
* accommodate deltas that are, logically, either 16-bit or 32-bit.
* When scaled deltas are applied to `Fixed` values, the `Fixed` value
* is treated like a 32-bit integer.
*
* `FT_MulAddFix` internally uses 64-bit precision; it thus can handle
* deltas ranging from small 8-bit to large 32-bit values that are
* applied to 16.16 `FT_Fixed` / OpenType `Fixed` values.
*/
returnValue = FT_MulAddFix( scalars, deltaSet, varData->regionIdxCount );
FT_FREE( scalars );
return returnValue;
}
@ -1128,19 +1155,22 @@
}
}
delta = ft_var_get_item_delta( face,
delta = tt_var_get_item_delta( face,
&table->itemStore,
outerIndex,
innerIndex );
FT_TRACE5(( "%s value %d adjusted by %d unit%s (%s)\n",
vertical ? "vertical height" : "horizontal width",
*avalue,
delta,
delta == 1 ? "" : "s",
vertical ? "VVAR" : "HVAR" ));
if ( delta )
{
FT_TRACE5(( "%s value %d adjusted by %d unit%s (%s)\n",
vertical ? "vertical height" : "horizontal width",
*avalue,
delta,
delta == 1 ? "" : "s",
vertical ? "VVAR" : "HVAR" ));
*avalue += delta;
*avalue += delta;
}
Exit:
return error;
@ -1307,7 +1337,7 @@
records_offset = FT_STREAM_POS();
error = ft_var_load_item_variation_store(
error = tt_var_load_item_variation_store(
face,
table_offset + store_offset,
&blend->mvar_table->itemStore );
@ -1332,6 +1362,13 @@
value->outerIndex = FT_GET_USHORT();
value->innerIndex = FT_GET_USHORT();
/* new in OpenType 1.8.4 */
if ( value->outerIndex == 0xFFFFU && value->innerIndex == 0xFFFFU )
{
/* no variation data for this item */
continue;
}
if ( value->outerIndex >= itemStore->dataCount ||
value->innerIndex >= itemStore->varData[value->outerIndex]
.itemCount )
@ -1422,12 +1459,12 @@
FT_Int delta;
delta = ft_var_get_item_delta( face,
delta = tt_var_get_item_delta( face,
&blend->mvar_table->itemStore,
value->outerIndex,
value->innerIndex );
if ( p )
if ( p && delta )
{
FT_TRACE5(( "value %c%c%c%c (%d unit%s) adjusted by %d unit%s (MVAR)\n",
(FT_Char)( value->tag >> 24 ),
@ -3813,20 +3850,12 @@
* @Description:
* Apply the appropriate deltas to the current glyph.
*
* @Input:
* face ::
* A handle to the target face object.
*
* glyph_index ::
* The index of the glyph being modified.
*
* n_points ::
* The number of the points in the glyph, including
* phantom points.
*
* @InOut:
* loader ::
* A handle to the loader object.
*
* outline ::
* The outline to change.
* The outline to change, with appended phantom points.
*
* @Output:
* unrounded ::
@ -3837,15 +3866,16 @@
* FreeType error code. 0 means success.
*/
FT_LOCAL_DEF( FT_Error )
TT_Vary_Apply_Glyph_Deltas( TT_Face face,
FT_UInt glyph_index,
TT_Vary_Apply_Glyph_Deltas( TT_Loader loader,
FT_Outline* outline,
FT_Vector* unrounded,
FT_UInt n_points )
FT_Vector* unrounded )
{
FT_Error error;
TT_Face face = loader->face;
FT_Stream stream = face->root.stream;
FT_Memory memory = stream->memory;
FT_UInt glyph_index = loader->glyph_index;
FT_UInt n_points = (FT_UInt)outline->n_points + 4;
FT_Vector* points_org = NULL; /* coordinates in 16.16 format */
FT_Vector* points_out = NULL; /* coordinates in 16.16 format */
@ -4063,36 +4093,8 @@
FT_Fixed point_delta_y = FT_MulFix( deltas_y[j], apply );
if ( j < n_points - 4 )
{
point_deltas_x[j] = old_point_delta_x + point_delta_x;
point_deltas_y[j] = old_point_delta_y + point_delta_y;
}
else
{
/* To avoid double adjustment of advance width or height, */
/* adjust phantom points only if there is no HVAR or VVAR */
/* support, respectively. */
if ( j == ( n_points - 4 ) &&
!( face->variation_support &
TT_FACE_FLAG_VAR_LSB ) )
point_deltas_x[j] = old_point_delta_x + point_delta_x;
else if ( j == ( n_points - 3 ) &&
!( face->variation_support &
TT_FACE_FLAG_VAR_HADVANCE ) )
point_deltas_x[j] = old_point_delta_x + point_delta_x;
else if ( j == ( n_points - 2 ) &&
!( face->variation_support &
TT_FACE_FLAG_VAR_TSB ) )
point_deltas_y[j] = old_point_delta_y + point_delta_y;
else if ( j == ( n_points - 1 ) &&
!( face->variation_support &
TT_FACE_FLAG_VAR_VADVANCE ) )
point_deltas_y[j] = old_point_delta_y + point_delta_y;
}
point_deltas_x[j] = old_point_delta_x + point_delta_x;
point_deltas_y[j] = old_point_delta_y + point_delta_y;
#ifdef FT_DEBUG_LEVEL_TRACE
if ( point_delta_x || point_delta_y )
@ -4165,36 +4167,8 @@
FT_Pos point_delta_y = points_out[j].y - points_org[j].y;
if ( j < n_points - 4 )
{
point_deltas_x[j] = old_point_delta_x + point_delta_x;
point_deltas_y[j] = old_point_delta_y + point_delta_y;
}
else
{
/* To avoid double adjustment of advance width or height, */
/* adjust phantom points only if there is no HVAR or VVAR */
/* support, respectively. */
if ( j == ( n_points - 4 ) &&
!( face->variation_support &
TT_FACE_FLAG_VAR_LSB ) )
point_deltas_x[j] = old_point_delta_x + point_delta_x;
else if ( j == ( n_points - 3 ) &&
!( face->variation_support &
TT_FACE_FLAG_VAR_HADVANCE ) )
point_deltas_x[j] = old_point_delta_x + point_delta_x;
else if ( j == ( n_points - 2 ) &&
!( face->variation_support &
TT_FACE_FLAG_VAR_TSB ) )
point_deltas_y[j] = old_point_delta_y + point_delta_y;
else if ( j == ( n_points - 1 ) &&
!( face->variation_support &
TT_FACE_FLAG_VAR_VADVANCE ) )
point_deltas_y[j] = old_point_delta_y + point_delta_y;
}
point_deltas_x[j] = old_point_delta_x + point_delta_x;
point_deltas_y[j] = old_point_delta_y + point_delta_y;
#ifdef FT_DEBUG_LEVEL_TRACE
if ( point_delta_x || point_delta_y )
@ -4232,6 +4206,24 @@
FT_TRACE5(( "\n" ));
/* To avoid double adjustment of advance width or height, */
/* do not move phantom points if there is HVAR or VVAR */
/* support, respectively. */
if ( face->variation_support & TT_FACE_FLAG_VAR_HADVANCE )
{
point_deltas_x[n_points - 4] = 0;
point_deltas_y[n_points - 4] = 0;
point_deltas_x[n_points - 3] = 0;
point_deltas_y[n_points - 3] = 0;
}
if ( face->variation_support & TT_FACE_FLAG_VAR_VADVANCE )
{
point_deltas_x[n_points - 2] = 0;
point_deltas_y[n_points - 2] = 0;
point_deltas_x[n_points - 1] = 0;
point_deltas_y[n_points - 1] = 0;
}
for ( i = 0; i < n_points; i++ )
{
unrounded[i].x += FT_fixedToFdot6( point_deltas_x[i] );
@ -4241,6 +4233,24 @@
outline->points[i].y += FT_fixedToInt( point_deltas_y[i] );
}
/* To avoid double adjustment of advance width or height, */
/* adjust phantom points only if there is no HVAR or VVAR */
/* support, respectively. */
if ( !( face->variation_support & TT_FACE_FLAG_VAR_HADVANCE ) )
{
loader->pp1 = outline->points[n_points - 4];
loader->pp2 = outline->points[n_points - 3];
loader->linear = FT_PIX_ROUND( unrounded[n_points - 3].x -
unrounded[n_points - 4].x ) / 64;
}
if ( !( face->variation_support & TT_FACE_FLAG_VAR_VADVANCE ) )
{
loader->pp3 = outline->points[n_points - 2];
loader->pp4 = outline->points[n_points - 1];
loader->vadvance = FT_PIX_ROUND( unrounded[n_points - 1].y -
unrounded[n_points - 2].y ) / 64;
}
Fail3:
FT_FREE( point_deltas_x );
FT_FREE( point_deltas_y );
@ -4305,8 +4315,8 @@
}
static void
ft_var_done_item_variation_store( TT_Face face,
FT_LOCAL_DEF( void )
tt_var_done_item_variation_store( TT_Face face,
GX_ItemVarStore itemStore )
{
FT_Memory memory = FT_FACE_MEMORY( face );
@ -4334,6 +4344,18 @@
}
FT_LOCAL_DEF( void )
tt_var_done_delta_set_index_map( TT_Face face,
GX_DeltaSetIdxMap deltaSetIdxMap )
{
FT_Memory memory = FT_FACE_MEMORY( face );
FT_FREE( deltaSetIdxMap->innerIndex );
FT_FREE( deltaSetIdxMap->outerIndex );
}
/**************************************************************************
*
* @Function:
@ -4371,27 +4393,27 @@
if ( blend->hvar_table )
{
ft_var_done_item_variation_store( face,
tt_var_done_item_variation_store( face,
&blend->hvar_table->itemStore );
FT_FREE( blend->hvar_table->widthMap.innerIndex );
FT_FREE( blend->hvar_table->widthMap.outerIndex );
tt_var_done_delta_set_index_map( face,
&blend->hvar_table->widthMap );
FT_FREE( blend->hvar_table );
}
if ( blend->vvar_table )
{
ft_var_done_item_variation_store( face,
tt_var_done_item_variation_store( face,
&blend->vvar_table->itemStore );
FT_FREE( blend->vvar_table->widthMap.innerIndex );
FT_FREE( blend->vvar_table->widthMap.outerIndex );
tt_var_done_delta_set_index_map( face,
&blend->vvar_table->widthMap );
FT_FREE( blend->vvar_table );
}
if ( blend->mvar_table )
{
ft_var_done_item_variation_store( face,
tt_var_done_item_variation_store( face,
&blend->mvar_table->itemStore );
FT_FREE( blend->mvar_table->values );

View File

@ -62,57 +62,6 @@ FT_BEGIN_HEADER
} GX_AVarSegmentRec, *GX_AVarSegment;
typedef struct GX_ItemVarDataRec_
{
FT_UInt itemCount; /* number of delta sets per item */
FT_UInt regionIdxCount; /* number of region indices in this data */
FT_UInt* regionIndices; /* array of `regionCount' indices; */
/* these index `varRegionList' */
FT_Short* deltaSet; /* array of `itemCount' deltas */
/* use `innerIndex' for this array */
} GX_ItemVarDataRec, *GX_ItemVarData;
/* contribution of one axis to a region */
typedef struct GX_AxisCoordsRec_
{
FT_Fixed startCoord;
FT_Fixed peakCoord; /* zero means no effect (factor = 1) */
FT_Fixed endCoord;
} GX_AxisCoordsRec, *GX_AxisCoords;
typedef struct GX_VarRegionRec_
{
GX_AxisCoords axisList; /* array of axisCount records */
} GX_VarRegionRec, *GX_VarRegion;
/* item variation store */
typedef struct GX_ItemVarStoreRec_
{
FT_UInt dataCount;
GX_ItemVarData varData; /* array of dataCount records; */
/* use `outerIndex' for this array */
FT_UShort axisCount;
FT_UInt regionCount; /* total number of regions defined */
GX_VarRegion varRegionList;
} GX_ItemVarStoreRec, *GX_ItemVarStore;
typedef struct GX_DeltaSetIdxMapRec_
{
FT_ULong mapCount;
FT_UInt* outerIndex; /* indices to item var data */
FT_UInt* innerIndex; /* indices to delta set */
} GX_DeltaSetIdxMapRec, *GX_DeltaSetIdxMap;
/**************************************************************************
*
* @Struct:
@ -412,11 +361,9 @@ FT_BEGIN_HEADER
FT_LOCAL( FT_Error )
TT_Vary_Apply_Glyph_Deltas( TT_Face face,
FT_UInt glyph_index,
TT_Vary_Apply_Glyph_Deltas( TT_Loader loader,
FT_Outline* outline,
FT_Vector* unrounded,
FT_UInt n_points );
FT_Vector* unrounded );
FT_LOCAL( FT_Error )
tt_hadvance_adjust( TT_Face face,
@ -431,6 +378,34 @@ FT_BEGIN_HEADER
FT_LOCAL( void )
tt_apply_mvar( TT_Face face );
FT_LOCAL( FT_Error )
tt_var_load_item_variation_store( TT_Face face,
FT_ULong offset,
GX_ItemVarStore itemStore );
FT_LOCAL( FT_Error )
tt_var_load_delta_set_index_mapping( TT_Face face,
FT_ULong offset,
GX_DeltaSetIdxMap map,
GX_ItemVarStore itemStore,
FT_ULong table_len );
FT_LOCAL( FT_ItemVarDelta )
tt_var_get_item_delta( TT_Face face,
GX_ItemVarStore itemStore,
FT_UInt outerIndex,
FT_UInt innerIndex );
FT_LOCAL( void )
tt_var_done_item_variation_store( TT_Face face,
GX_ItemVarStore itemStore );
FT_LOCAL( void )
tt_var_done_delta_set_index_map( TT_Face face,
GX_DeltaSetIdxMap deltaSetIdxMap );
FT_LOCAL( FT_Error )
tt_get_var_blend( TT_Face face,
FT_UInt *num_coords,

View File

@ -8570,7 +8570,8 @@
/* increment instruction counter and check if we didn't */
/* run this program for too long (e.g. infinite loops). */
if ( ++ins_counter > TT_CONFIG_OPTION_MAX_RUNNABLE_OPCODES ) {
if ( ++ins_counter > TT_CONFIG_OPTION_MAX_RUNNABLE_OPCODES )
{
exc->error = FT_THROW( Execution_Too_Long );
goto LErrorLabel_;
}

View File

@ -337,6 +337,8 @@ FT_BEGIN_HEADER
FT_UInt interpreter_version;
FT_Bool enable_variable_colrv1;
} TT_DriverRec;

View File

@ -121,19 +121,30 @@
#ifndef T1_CONFIG_OPTION_NO_MM_SUPPORT
static const FT_Service_MultiMastersRec t1_service_multi_masters =
{
(FT_Get_MM_Func) T1_Get_Multi_Master, /* get_mm */
(FT_Set_MM_Design_Func) T1_Set_MM_Design, /* set_mm_design */
(FT_Set_MM_Blend_Func) T1_Set_MM_Blend, /* set_mm_blend */
(FT_Get_MM_Blend_Func) T1_Get_MM_Blend, /* get_mm_blend */
(FT_Get_MM_Var_Func) T1_Get_MM_Var, /* get_mm_var */
(FT_Set_Var_Design_Func) T1_Set_Var_Design, /* set_var_design */
(FT_Get_Var_Design_Func) T1_Get_Var_Design, /* get_var_design */
(FT_Set_Instance_Func) T1_Reset_MM_Blend, /* set_instance */
(FT_Set_MM_WeightVector_Func)T1_Set_MM_WeightVector, /* set_mm_weightvector */
(FT_Get_MM_WeightVector_Func)T1_Get_MM_WeightVector, /* get_mm_weightvector */
(FT_Get_Var_Blend_Func) NULL, /* get_var_blend */
(FT_Done_Blend_Func) T1_Done_Blend /* done_blend */
(FT_Get_MM_Func) T1_Get_Multi_Master, /* get_mm */
(FT_Set_MM_Design_Func) T1_Set_MM_Design, /* set_mm_design */
(FT_Set_MM_Blend_Func) T1_Set_MM_Blend, /* set_mm_blend */
(FT_Get_MM_Blend_Func) T1_Get_MM_Blend, /* get_mm_blend */
(FT_Get_MM_Var_Func) T1_Get_MM_Var, /* get_mm_var */
(FT_Set_Var_Design_Func)T1_Set_Var_Design, /* set_var_design */
(FT_Get_Var_Design_Func)T1_Get_Var_Design, /* get_var_design */
(FT_Set_Instance_Func) T1_Reset_MM_Blend, /* set_instance */
(FT_Set_MM_WeightVector_Func)
T1_Set_MM_WeightVector, /* set_mm_weightvector */
(FT_Get_MM_WeightVector_Func)
T1_Get_MM_WeightVector, /* get_mm_weightvector */
(FT_Var_Load_Delta_Set_Idx_Map_Func)
NULL, /* load_delta_set_idx_map */
(FT_Var_Load_Item_Var_Store_Func)
NULL, /* load_item_variation_store */
(FT_Var_Get_Item_Delta_Func)
NULL, /* get_item_delta */
(FT_Var_Done_Item_Var_Store_Func)
NULL, /* done_item_variation_store */
(FT_Var_Done_Delta_Set_Idx_Map_Func)
NULL, /* done_delta_set_index_map */
(FT_Get_Var_Blend_Func) NULL, /* get_var_blend */
(FT_Done_Blend_Func) T1_Done_Blend /* done_blend */
};
#endif

View File

@ -330,50 +330,25 @@
/* the private dict. Otherwise, simply overwrite into the base */
/* dictionary block in the heap. */
/* first of all, look at the `eexec' keyword */
/* First look for the `eexec' keyword. Ensure `eexec' is real -- */
/* it could be in a comment or string (as e.g. in u003043t.gsf */
/* from ghostscript). */
FT_Byte* cur = parser->base_dict;
FT_Byte* limit = cur + parser->base_len;
FT_Pointer pos_lf;
FT_Bool test_cr;
Again:
for (;;)
{
if ( cur[0] == 'e' &&
cur + 9 < limit ) /* 9 = 5 letters for `eexec' + */
/* whitespace + 4 chars */
{
if ( cur[1] == 'e' &&
cur[2] == 'x' &&
cur[3] == 'e' &&
cur[4] == 'c' )
break;
}
cur++;
if ( cur >= limit )
{
FT_ERROR(( "T1_Get_Private_Dict:"
" could not find `eexec' keyword\n" ));
error = FT_THROW( Invalid_File_Format );
goto Exit;
}
}
/* check whether `eexec' was real -- it could be in a comment */
/* or string (as e.g. in u003043t.gsf from ghostscript) */
parser->root.cursor = parser->base_dict;
/* set limit to `eexec' + whitespace + 4 characters */
parser->root.limit = cur + 10;
parser->root.limit = parser->base_dict + parser->base_len;
cur = parser->root.cursor;
limit = parser->root.limit;
while ( cur < limit )
{
if ( cur[0] == 'e' &&
cur + 5 < limit )
/* 9 = 5 letters for `eexec' + whitespace + 4 chars */
if ( cur[0] == 'e' && cur + 9 < limit )
{
if ( cur[1] == 'e' &&
cur[2] == 'x' &&
@ -389,21 +364,9 @@
cur = parser->root.cursor;
}
/* we haven't found the correct `eexec'; go back and continue */
/* searching */
cur = limit;
limit = parser->base_dict + parser->base_len;
if ( cur >= limit )
{
FT_ERROR(( "T1_Get_Private_Dict:"
" premature end in private dictionary\n" ));
error = FT_THROW( Invalid_File_Format );
goto Exit;
}
goto Again;
FT_ERROR(( "T1_Get_Private_Dict: could not find `eexec' keyword\n" ));
error = FT_THROW( Invalid_File_Format );
goto Exit;
/* now determine where to write the _encrypted_ binary private */
/* dictionary. We overwrite the base dictionary for disk-based */

12
subprojects/harfbuzz.wrap Normal file
View File

@ -0,0 +1,12 @@
[wrap-file]
directory = harfbuzz-4.3.0
source_url = https://github.com/harfbuzz/harfbuzz/releases/download/4.3.0/harfbuzz-4.3.0.tar.xz
source_filename = harfbuzz-4.3.0.tar.xz
source_hash = a49628f4c4c8e6d8df95ef44935a93446cf2e46366915b0e3ca30df21fffb530
[provide]
harfbuzz = libharfbuzz_dep
harfbuzz-subset = libharfbuzz_subset_dep
harfbuzz-icu = libharfbuzz_icu_dep
harfbuzz-gobject = libharfbuzz_gobject_dep

View File

@ -1,11 +1,11 @@
[wrap-file]
directory = zlib-1.2.11
source_url = http://zlib.net/fossils/zlib-1.2.11.tar.gz
source_filename = zlib-1.2.11.tar.gz
source_hash = c3e5e9fdd5004dcb542feda5ee4f0ff0744628baf8ed2dd5d66f8ca1197cb1a1
patch_url = https://wrapdb.mesonbuild.com/v2/zlib_1.2.11-5/get_patch
patch_filename = zlib-1.2.11-5-wrap.zip
patch_hash = 728c8e24acbc2e6682fbd950fec39e2fc77528af361adb87259f8a8511434004
directory = zlib-1.2.12
source_url = http://zlib.net/fossils/zlib-1.2.12.tar.gz
source_filename = zlib-1.2.12.tar.gz
source_hash = 91844808532e5ce316b3c010929493c0244f3d37593afd6de04f71821d5136d9
patch_filename = zlib_1.2.12-1_patch.zip
patch_url = https://wrapdb.mesonbuild.com/v2/zlib_1.2.12-1/get_patch
patch_hash = 8ec8344f3fe7b06ad4be768fd416694bc56cb4545ce78b0f1c18b3e72b3ec936
[provide]
zlib = zlib_dep