freetype-commit
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Git][freetype/freetype][download-test-fonts] 8 commits: Small clean-ups


From: David Turner (@david.freetype)
Subject: [Git][freetype/freetype][download-test-fonts] 8 commits: Small clean-ups for the last few commits.
Date: Thu, 15 Jul 2021 11:17:48 +0000

David Turner pushed to branch download-test-fonts at FreeType / FreeType

Commits:

18 changed files:

Changes:

  • ChangeLog
    1
    +2021-07-15  David Turner  <david@freetype.org>
    
    2
    +
    
    3
    +	Replaces download-test-fonts.sh with download-test-fonts.py which
    
    4
    +	does the same work, and also avoids downloading anything if the
    
    5
    +	files are already installed with the right content.
    
    6
    +
    
    7
    +	Now uses the first 8 byte of each file's sha256 hash for the digest.
    
    8
    +
    
    9
    +	* tests/scripts/download-test-fonts.sh: Removed
    
    10
    +	* tests/scripts/download-test-fonts.py: New script
    
    11
    +	* tests/README.md: Updated
    
    12
    +
    
    13
    +2021-07-15  Alex Richardson  <Alexander.Richardson@cl.cam.ac.uk>
    
    14
    +
    
    15
    +	Support architectures where `long` is smaller than pointers.
    
    16
    +
    
    17
    +	I am currently trying to compile FreeType for CHERI-extended ISAs
    
    18
    +	(CHERI-RISC-V and Arm's Morello), but I am getting compiler warnings
    
    19
    +	from the `FT_UINT_TO_POINTER` macro.  When compiling with the CHERI
    
    20
    +	Clang compiler, not using `uinptr_t` for casts between integers an
    
    21
    +	pointers results in the following `-Werror` build failures:
    
    22
    +
    
    23
    +	```
    
    24
    +	In file included from .../src/truetype/truetype.c:22:
    
    25
    +	  .../src/truetype/ttgload.c:1925:22: error:
    
    26
    +	    cast from provenance-free integer type to pointer type will
    
    27
    +	    give pointer that can not be dereferenced
    
    28
    +	    [-Werror,-Wcheri-capability-misuse]
    
    29
    +	  node->data = "" glyph_index );
    
    30
    +	               ^
    
    31
    +	  .../include/freetype/internal/compiler-macros.h:79:34: note:
    
    32
    +	    expanded from macro 'FT_UINT_TO_POINTER'
    
    33
    +	```
    
    34
    +
    
    35
    +	* include/freetype/internal/compiler-macros.h (FT_UINT_TO_POINTER):
    
    36
    +	The ISO C standard compliant fix for this would be to use
    
    37
    +	`uintptr_t` from `stdint.h`, but I am not sure if this is supported
    
    38
    +	by the minimum compiler version.  Therefore, use the
    
    39
    +	compiler-defined `__UINTPTR_TYPE__` macro (supported in GCC 4.6+ and
    
    40
    +	Clang since about 3.0) before checking for `_WIN64` and falling back
    
    41
    +	to `unsigned long`.
    
    42
    +
    
    43
    +2021-07-13  Oleg Oshmyan  <chortos@inbox.lv>
    
    44
    +
    
    45
    +	[base] Fix `FT_Open_Face`'s handling of user-supplied streams.
    
    46
    +
    
    47
    +	This was already true (though undocumented) most of the time, but
    
    48
    +	not if `FT_NEW` inside `FT_Stream_New` failed or if the
    
    49
    +	`FT_OPEN_XXX` flags were bad.
    
    50
    +
    
    51
    +	Normally, `FT_Open_Face` calls `FT_Stream_New`, which returns the
    
    52
    +	user-supplied stream unchanged, and in case of any subsequent error
    
    53
    +	in `FT_Open_Face`, the stream is closed via `FT_Stream_Free`.
    
    54
    +
    
    55
    +	Up to now, however, `FT_Stream_New` allocates a new stream even if
    
    56
    +	it is already given one by the user.  If this allocation fails, the
    
    57
    +	user-supplied stream is not returned to `FT_Open_Face` and never
    
    58
    +	closed.  Moreover, the user cannot detect this situation: all they
    
    59
    +	see is that `FT_Open_Face` returns `FT_Err_Out_Of_Memory`, but that
    
    60
    +	can also happen after a different allocation fails within the main
    
    61
    +	body of `FT_Open_Face`, when the user's stream has already been
    
    62
    +	closed by `FT_Open_Face`.  It is plausible that the user stream's
    
    63
    +	`close` method frees memory allocated for the stream object itself,
    
    64
    +	so the user cannot defensively free it upon `FT_Open_Face` failure
    
    65
    +	lest it ends up doubly freed.  All in all, this ends up leaking the
    
    66
    +	memory/resources used by user's stream.
    
    67
    +
    
    68
    +	Furthermore, `FT_Stream_New` simply returns an error if the
    
    69
    +	`FT_OPEN_XXX` flags are unsupported, which can mean either an
    
    70
    +	invalid combination of flags or a perfectly innocent
    
    71
    +	`FT_OPEN_STREAM` on a FreeType build that lacks stream support.
    
    72
    +	With this patch, the user-supplied stream is closed even in these
    
    73
    +	cases, so the user can be sure that if `FT_Open_Face` failed, the
    
    74
    +	stream is definitely closed.
    
    75
    +
    
    76
    +	* src/base/ftobjs.c (FT_Stream_New): Don't allocate a buffer
    
    77
    +	unnecessarily.
    
    78
    +	Move error-handling code to make the control flow more obvious.
    
    79
    +	Close user-supplied stream if the flags are unsupported.
    
    80
    +	`FT_Stream_Open` always sets `pathname.pointer`, so remove the
    
    81
    +	redundant (re)assignment.  None of the `FT_Stream_Open...` functions
    
    82
    +	uses `stream->memory`, so keep just one assignment at the end,
    
    83
    +	shared among all possible control flow paths.
    
    84
    +	('Unsupported flags' that may need a stream closure can be either an
    
    85
    +	invalid combination of multiple `FT_OPEN_XXX` mode flags or a clean
    
    86
    +	`FT_OPEN_STREAM` flag on a FreeType build that lacks stream
    
    87
    +	support.)
    
    88
    +
    
    89
    +2021-07-13  Oleg Oshmyan  <chortos@inbox.lv>
    
    90
    +
    
    91
    +	[base] Reject combinations of incompatible `FT_OPEN_XXX` flags.
    
    92
    +
    
    93
    +	The three modes are mutually exclusive, and the documentation of the
    
    94
    +	`FT_OPEN_XXX` constants notes this.  However, there was no check to
    
    95
    +	validate this in the code, and the documentation on `FT_Open_Args`
    
    96
    +	claimed that the corresponding bits were checked in a well-defined
    
    97
    +	order, implying it was valid (if useless) to specify more than one.
    
    98
    +	Ironically, this documented order did not agree with the actual
    
    99
    +	code, so it could not be relied upon; hopefully, nobody did this and
    
    100
    +	nobody will be hurt by the new validation.
    
    101
    +
    
    102
    +	Even if multiple mode bits were allowed, they could cause memory
    
    103
    +	leaks: if both `FT_OPEN_STREAM` and `stream` are set along with
    
    104
    +	either `FT_OPEN_MEMORY` or `FT_OPEN_PATHNAME`, then `FT_Stream_New`
    
    105
    +	allocated a new stream but `FT_Open_Face` marked it as an 'external'
    
    106
    +	stream, so the stream object was never released.
    
    107
    +
    
    108
    +	* src/base/ftobjs.c (FT_Stream_New): Reject incompatible
    
    109
    +	`FT_OPEN_XXX` flags.
    
    110
    +
    
    111
    +2021-07-12  Alex Richardson  <Alexander.Richardson@cl.cam.ac.uk>
    
    112
    +
    
    113
    +	* meson.build: Fix build for other UNIX systems (e.g., FreeBSD).
    
    114
    +
    
    115
    +	Without this change the build of `unix/ftsystem.c` fails because the
    
    116
    +	`ftconfig.h` header that defines macros such as `HAVE_UNISTD_H` and
    
    117
    +	`HAVE_FCNTL_H` is only being generated for Linux, macOS, and Cygwin
    
    118
    +	systems:
    
    119
    +
    
    120
    +	```
    
    121
    +	.../builds/unix/ftsystem.c:258:32: error:
    
    122
    +	    use of undeclared identifier 'O_RDONLY'
    
    123
    +	file = open( filepathname, O_RDONLY );
    
    124
    +	```
    
    125
    +
    
    126
    +	Instead of hardcoding a list of operating systems for this check,
    
    127
    +	update the logic that decides whether to build the file and set a
    
    128
    +	boolean flag that can be checked instead.
    
    129
    +
    
    130
    +2021-07-12  Werner Lemberg  <wl@gnu.org>
    
    131
    +
    
    132
    +	[autofit] More clean-ups.
    
    133
    +
    
    134
    +	* src/autofit/afhints.h (AF_GlyphHintsRec): Remove the no longer
    
    135
    +	needed fields `xmin_delta` and `xmax_delta`.
    
    136
    +
    
    137
    +	* src/autofit/afhints.c (af_glyph_hints_reload),
    
    138
    +	src/autofit/afloader.c (af_loader_load_glyph): Updated.
    
    139
    +
    
    140
    +2021-07-12  Werner Lemberg  <wl@gnu.org>
    
    141
    +
    
    142
    +	Small clean-ups for the last few commits.
    
    143
    +
    
    144
    +	* include/freetype/fttrace.h (afwarp): Removed.
    
    145
    +
    
    1 146
     2021-07-12  David Turner  <david@freetype.org>
    
    2 147
     
    
    3 148
     	Remove obsolete AF_Angle type and related sources.
    
    4 149
     
    
    5
    -	Move the af_sort_xxx() functions from afangles.c to afhints.c in
    
    6
    -	order to get rid of the obsolete angle-related types, macros and
    
    7
    -	function definitions.
    
    150
    +	* src/autofit/afangles.c: File removed.  Functions related to
    
    151
    +	sorting moved to...
    
    152
    +	* src/autofit/afhints.c (af_sort_pos, af_sort_and_quantize_widths):
    
    153
    +	This file.
    
    154
    +	* src/autofit/afangles.h: File removed.
    
    155
    +	* src/autofit/aftypes.h: Updated.
    
    156
    +	* src/autofit/autofit.c: Updated.
    
    8 157
     
    
    9
    -	* src/autofit/*: Remove code.
    
    158
    +	* src/autofit/rules.mk (AUTOF_DRV_SRC): Updated.
    
    10 159
     
    
    11 160
     2021-07-12  David Turner  <david@freetype.org>
    
    12 161
     
    
    13 162
     	Remove experimental auto-hinting 'warp' mode.
    
    14 163
     
    
    15
    -	This feature was always experimental, and probably nevery worked
    
    16
    -	properly. This patch completely removes it from the source code,
    
    164
    +	This feature was always experimental, and probably never worked
    
    165
    +	properly.  This patch completely removes it from the source code,
    
    17 166
     	except for a documentation block describing it for historical
    
    18
    -	purpose.
    
    167
    +	purposes.
    
    168
    +
    
    169
    +	* devel/ftoption.h, include/freetype/config/ftoption.h: Remove
    
    170
    +	`AF_CONFIG_OPTION_USE_WARPER`.
    
    171
    +
    
    172
    +	* include/freetype/ftdriver.h: Document 'warping' property as
    
    173
    +	obsolete.
    
    19 174
     
    
    20
    -	* devel/ftoption.h: Remove AF_CONFIG_OPTION_USE_WARPER.
    
    21
    -	* include/freetype/config/ftoption.h: Remove AF_CONFIG_OPTION_USE_WARPER.
    
    22
    -	* include/freetype/ftdriver.h: Document 'warping' property as obsolete.
    
    23
    -	* src/autofit/*: Remove any warp mode related code.
    
    175
    +	* src/autofit/afwarp.c, src/autofit/afwarp.h: Files removed.
    
    176
    +	* src/autofit/*: Remove any code related to warp mode.
    
    24 177
     
    
    25 178
     2021-07-12  David Turner  <david@freetype.org>
    
    26 179
     
    
    27
    -	Remove experimental "Latin2" writing system (FT_OPTION_AUTOFIT2)
    
    180
    +	Remove experimental 'Latin2' writing system (`FT_OPTION_AUTOFIT2`).
    
    28 181
     
    
    29 182
     	This code has always been experimental and was never compiled anyway
    
    30
    -	(FT_OPTION_AUTOFIT2 does not appear in ftoption.h or even any of our
    
    31
    -	build files).
    
    32
    -
    
    33
    -	* include/freetype/internal/fttrace.h: Remove 'FT_TRACE_DEF( aflatin2 )'.
    
    34
    -	* src/autofit/aflatin2.[hc]: Removed.
    
    35
    -	* src/autofit/afloader.c: Remove undocumented hook to activate Latin2 system.
    
    36
    -	* src/autofit/afstyles.h: Remove ltn2_dflt style definition.
    
    37
    -	* src/autofit/afwrtsys.h: Remove LATIN2 writing system definition.
    
    183
    +	(`FT_OPTION_AUTOFIT2` does not appear in `ftoption.h` or even any of
    
    184
    +	our build files).
    
    185
    +
    
    186
    +	* include/freetype/internal/fttrace.h (aflatin2): Removed.
    
    187
    +	* src/autofit/aflatin2.h, src/autofit/aflatin2.c: Files removed.
    
    188
    +	* src/autofit/afloader.c: Remove undocumented hook to activate
    
    189
    +	Latin2 system.
    
    190
    +	* src/autofit/afstyles.h: Remove `ltn2_dflt` style definition.
    
    191
    +	* src/autofit/afwrtsys.h: Remove `LATIN2` writing system definition.
    
    38 192
     	* src/autofit/autofit.c: Updated.
    
    39 193
     
    
    40 194
     2021-07-05  Werner Lemberg  <wl@gnu.org>
    

  • devel/ftoption.h
    ... ... @@ -105,8 +105,7 @@ FT_BEGIN_HEADER
    105 105
        *
    
    106 106
        * ```
    
    107 107
        *   FREETYPE_PROPERTIES=truetype:interpreter-version=35 \
    
    108
    -   *                       cff:no-stem-darkening=1 \
    
    109
    -   *                       autofitter:warping=1
    
    108
    +   *                       cff:no-stem-darkening=1
    
    110 109
        * ```
    
    111 110
        *
    
    112 111
        */
    

  • docs/CHANGES
    ... ... @@ -72,6 +72,9 @@ CHANGES BETWEEN 2.10.4 and 2.11.0
    72 72
     
    
    73 73
         This work was Priyesh Kumar's GSoC 2020 project.
    
    74 74
     
    
    75
    +  - The experimental 'warp' mode (AF_CONFIG_OPTION_USE_WARPER) for the
    
    76
    +    auto-hinter has been removed.
    
    77
    +
    
    75 78
       - The smooth rasterizer performance has been improved by >10%.
    
    76 79
     
    
    77 80
       - PCF bitmap fonts compressed with LZW (these are usually files with
    

  • include/freetype/config/ftoption.h
    ... ... @@ -105,8 +105,7 @@ FT_BEGIN_HEADER
    105 105
        *
    
    106 106
        * ```
    
    107 107
        *   FREETYPE_PROPERTIES=truetype:interpreter-version=35 \
    
    108
    -   *                       cff:no-stem-darkening=1 \
    
    109
    -   *                       autofitter:warping=1
    
    108
    +   *                       cff:no-stem-darkening=1
    
    110 109
        * ```
    
    111 110
        *
    
    112 111
        */
    

  • include/freetype/freetype.h
    ... ... @@ -2113,8 +2113,7 @@ FT_BEGIN_HEADER
    2113 2113
        *     Extra parameters passed to the font driver when opening a new face.
    
    2114 2114
        *
    
    2115 2115
        * @note:
    
    2116
    -   *   The stream type is determined by the contents of `flags` that are
    
    2117
    -   *   tested in the following order by @FT_Open_Face:
    
    2116
    +   *   The stream type is determined by the contents of `flags`:
    
    2118 2117
        *
    
    2119 2118
        *   If the @FT_OPEN_MEMORY bit is set, assume that this is a memory file
    
    2120 2119
        *   of `memory_size` bytes, located at `memory_address`.  The data are not
    
    ... ... @@ -2127,6 +2126,9 @@ FT_BEGIN_HEADER
    2127 2126
        *   Otherwise, if the @FT_OPEN_PATHNAME bit is set, assume that this is a
    
    2128 2127
        *   normal file and use `pathname` to open it.
    
    2129 2128
        *
    
    2129
    +   *   If none of the above bits are set or if multiple are set at the same
    
    2130
    +   *   time, the flags are invalid and @FT_Open_Face fails.
    
    2131
    +   *
    
    2130 2132
        *   If the @FT_OPEN_DRIVER bit is set, @FT_Open_Face only tries to open
    
    2131 2133
        *   the file with the driver whose handler is in `driver`.
    
    2132 2134
        *
    
    ... ... @@ -2299,6 +2301,10 @@ FT_BEGIN_HEADER
    2299 2301
        *   See the discussion of reference counters in the description of
    
    2300 2302
        *   @FT_Reference_Face.
    
    2301 2303
        *
    
    2304
    +   *   If `FT_OPEN_STREAM` is set in `args->flags`, the stream in
    
    2305
    +   *   `args->stream` is automatically closed before this function returns
    
    2306
    +   *   any error (including `FT_Err_Invalid_Argument`).
    
    2307
    +   *
    
    2302 2308
        * @example:
    
    2303 2309
        *   To loop over all faces, use code similar to the following snippet
    
    2304 2310
        *   (omitting the error handling).
    
    ... ... @@ -3307,13 +3313,13 @@ FT_BEGIN_HEADER
    3307 3313
        *     pixels and use the @FT_PIXEL_MODE_LCD_V mode.
    
    3308 3314
        *
    
    3309 3315
        *   FT_RENDER_MODE_SDF ::
    
    3310
    -   *     This mode corresponds to 8-bit signed distance fields (SDF)
    
    3311
    -   *     bitmaps.  Each pixel in a SDF bitmap contains information about the
    
    3312
    -   *     nearest edge of the glyph outline.  The distances are calculated
    
    3313
    -   *     from the center of the pixel and are positive if they are filled by
    
    3314
    -   *     the outline (i.e., inside the outline) and negative otherwise.
    
    3315
    -   *     Check the note below on how to convert the output values to usable
    
    3316
    -   *     data.
    
    3316
    +   *     This mode corresponds to 8-bit, single-channel signed distance field
    
    3317
    +   *     (SDF) bitmaps.  Each pixel in the SDF grid is the value from the
    
    3318
    +   *     pixel's position to the nearest glyph's outline.  The distances are
    
    3319
    +   *     calculated from the center of the pixel and are positive if they are
    
    3320
    +   *     filled by the outline (i.e., inside the outline) and negative
    
    3321
    +   *     otherwise.  Check the note below on how to convert the output values
    
    3322
    +   *     to usable data.
    
    3317 3323
        *
    
    3318 3324
        * @note:
    
    3319 3325
        *   The selected render mode only affects vector glyphs of a font.
    

  • include/freetype/ftdriver.h
    ... ... @@ -53,10 +53,10 @@ FT_BEGIN_HEADER
    53 53
        *   reasons.
    
    54 54
        *
    
    55 55
        *   Available properties are @increase-x-height, @no-stem-darkening
    
    56
    -   *   (experimental), @darkening-parameters (experimental), @warping
    
    57
    -   *   (experimental), @glyph-to-script-map (experimental), @fallback-script
    
    58
    -   *   (experimental), and @default-script (experimental), as documented in
    
    59
    -   *   the @properties section.
    
    56
    +   *   (experimental), @darkening-parameters (experimental),
    
    57
    +   *   @glyph-to-script-map (experimental), @fallback-script (experimental),
    
    58
    +   *   and @default-script (experimental), as documented in the @properties
    
    59
    +   *   section.
    
    60 60
        *
    
    61 61
        */
    
    62 62
     
    
    ... ... @@ -1165,15 +1165,15 @@ FT_BEGIN_HEADER
    1165 1165
        *   **Obsolete**
    
    1166 1166
        *
    
    1167 1167
        *   This property was always experimental and probably never worked
    
    1168
    -   *   correctly. It was entirely removed from the FreeType 2 sources.
    
    1169
    -   *   This entry is only here for historical reference.
    
    1168
    +   *   correctly.  It was entirely removed from the FreeType~2 sources.  This
    
    1169
    +   *   entry is only here for historical reference.
    
    1170 1170
        *
    
    1171
    -   *   Warping only works in 'normal' auto-hinting mode replacing it.  The
    
    1172
    -   *   idea of the code is to slightly scale and shift a glyph along the
    
    1171
    +   *   Warping only worked in 'normal' auto-hinting mode replacing it.  The
    
    1172
    +   *   idea of the code was to slightly scale and shift a glyph along the
    
    1173 1173
        *   non-hinted dimension (which is usually the horizontal axis) so that as
    
    1174
    -   *   much of its segments are aligned (more or less) to the grid.  To find
    
    1174
    +   *   much of its segments were aligned (more or less) to the grid.  To find
    
    1175 1175
        *   out a glyph's optimal scaling and shifting value, various parameter
    
    1176
    -   *   combinations are tried and scored.
    
    1176
    +   *   combinations were tried and scored.
    
    1177 1177
        *
    
    1178 1178
        * @since:
    
    1179 1179
        *   2.6
    

  • include/freetype/ftmodapi.h
    ... ... @@ -508,8 +508,7 @@ FT_BEGIN_HEADER
    508 508
        *
    
    509 509
        *   ```
    
    510 510
        *     FREETYPE_PROPERTIES=truetype:interpreter-version=35 \
    
    511
    -   *                         cff:no-stem-darkening=0 \
    
    512
    -   *                         autofitter:warping=1
    
    511
    +   *                         cff:no-stem-darkening=0
    
    513 512
        *   ```
    
    514 513
        *
    
    515 514
        * @inout:
    

  • include/freetype/internal/compiler-macros.h
    ... ... @@ -71,12 +71,18 @@ FT_BEGIN_HEADER
    71 71
        */
    
    72 72
     #define FT_DUMMY_STMNT  FT_BEGIN_STMNT FT_END_STMNT
    
    73 73
     
    
    74
    -#ifdef _WIN64
    
    74
    +#ifdef __UINTPTR_TYPE__
    
    75
    +  /*
    
    76
    +   * GCC and Clang both provide a `__UINTPTR_TYPE__` that can be used to
    
    77
    +   * avoid a dependency on `stdint.h`.
    
    78
    +   */
    
    79
    +#  define FT_UINT_TO_POINTER( x )  (void *)(__UINTPTR_TYPE__)(x)
    
    80
    +#elif defined( _WIN64 )
    
    75 81
       /* only 64bit Windows uses the LLP64 data model, i.e., */
    
    76 82
       /* 32-bit integers, 64-bit pointers.                   */
    
    77
    -#define FT_UINT_TO_POINTER( x )  (void *)(unsigned __int64)(x)
    
    83
    +#  define FT_UINT_TO_POINTER( x )  (void *)(unsigned __int64)(x)
    
    78 84
     #else
    
    79
    -#define FT_UINT_TO_POINTER( x )  (void *)(unsigned long)(x)
    
    85
    +#  define FT_UINT_TO_POINTER( x )  (void *)(unsigned long)(x)
    
    80 86
     #endif
    
    81 87
     
    
    82 88
       /*
    

  • include/freetype/internal/fttrace.h
    ... ... @@ -160,7 +160,6 @@ FT_TRACE_DEF( afhints )
    160 160
     FT_TRACE_DEF( afmodule )
    
    161 161
     FT_TRACE_DEF( aflatin )
    
    162 162
     FT_TRACE_DEF( afshaper )
    
    163
    -FT_TRACE_DEF( afwarp )
    
    164 163
     
    
    165 164
       /* SDF components */
    
    166 165
     FT_TRACE_DEF( sdf )       /* signed distance raster for outlines (ftsdf.c) */
    

  • meson.build
    ... ... @@ -193,6 +193,7 @@ has_sys_mman_h = cc.has_header('sys/mman.h')
    193 193
     
    
    194 194
     mmap_option = get_option('mmap')
    
    195 195
     
    
    196
    +use_unix_ftsystem_c = false
    
    196 197
     if mmap_option.disabled()
    
    197 198
       ft2_sources += files(['src/base/ftsystem.c',])
    
    198 199
     elif host_machine.system() == 'windows'
    
    ... ... @@ -201,6 +202,7 @@ else
    201 202
       if has_unistd_h and has_fcntl_h and has_sys_mman_h
    
    202 203
         # This version of `ftsystem.c` uses `mmap` to read input font files.
    
    203 204
         ft2_sources += files(['builds/unix/ftsystem.c',])
    
    205
    +    use_unix_ftsystem_c = true
    
    204 206
       elif mmap_option.enabled()
    
    205 207
         error('mmap was enabled via options but is not available,'
    
    206 208
               + ' required headers were not found!')
    
    ... ... @@ -321,7 +323,7 @@ if has_fcntl_h
    321 323
       ftconfig_command += '--enable=HAVE_FCNTL_H'
    
    322 324
     endif
    
    323 325
     
    
    324
    -if host_machine.system() in ['linux', 'darwin', 'cygwin']
    
    326
    +if use_unix_ftsystem_c
    
    325 327
       ftconfig_h_in = files('builds/unix/ftconfig.h.in')
    
    326 328
       ftconfig_h = custom_target('ftconfig.h',
    
    327 329
         input: ftconfig_h_in,
    

  • src/autofit/afhints.c
    ... ... @@ -953,9 +953,6 @@
    953 953
         hints->x_delta = x_delta;
    
    954 954
         hints->y_delta = y_delta;
    
    955 955
     
    
    956
    -    hints->xmin_delta = 0;
    
    957
    -    hints->xmax_delta = 0;
    
    958
    -
    
    959 956
         points = hints->points;
    
    960 957
         if ( hints->num_points == 0 )
    
    961 958
           goto Exit;
    

  • src/autofit/afhints.h
    ... ... @@ -362,9 +362,6 @@ FT_BEGIN_HEADER
    362 362
                                         /* implementations         */
    
    363 363
         AF_StyleMetrics  metrics;
    
    364 364
     
    
    365
    -    FT_Pos           xmin_delta;    /* used for warping */
    
    366
    -    FT_Pos           xmax_delta;
    
    367
    -
    
    368 365
         /* Two arrays to avoid allocation penalty.            */
    
    369 366
         /* The `embedded' structure must be the last element! */
    
    370 367
         struct
    

  • src/autofit/afloader.c
    ... ... @@ -473,8 +473,8 @@
    473 473
               FT_Pos  pp2x = loader->pp2.x;
    
    474 474
     
    
    475 475
     
    
    476
    -          loader->pp1.x = FT_PIX_ROUND( pp1x + hints->xmin_delta );
    
    477
    -          loader->pp2.x = FT_PIX_ROUND( pp2x + hints->xmax_delta );
    
    476
    +          loader->pp1.x = FT_PIX_ROUND( pp1x );
    
    477
    +          loader->pp2.x = FT_PIX_ROUND( pp2x );
    
    478 478
     
    
    479 479
               slot->lsb_delta = loader->pp1.x - pp1x;
    
    480 480
               slot->rsb_delta = loader->pp2.x - pp2x;
    

  • src/base/ftobjs.c
    ... ... @@ -197,6 +197,7 @@
    197 197
         FT_Error   error;
    
    198 198
         FT_Memory  memory;
    
    199 199
         FT_Stream  stream = NULL;
    
    200
    +    FT_UInt    mode;
    
    200 201
     
    
    201 202
     
    
    202 203
         *astream = NULL;
    
    ... ... @@ -208,15 +209,15 @@
    208 209
           return FT_THROW( Invalid_Argument );
    
    209 210
     
    
    210 211
         memory = library->memory;
    
    212
    +    mode   = args->flags &
    
    213
    +               ( FT_OPEN_MEMORY | FT_OPEN_STREAM | FT_OPEN_PATHNAME );
    
    211 214
     
    
    212
    -    if ( FT_NEW( stream ) )
    
    213
    -      goto Exit;
    
    214
    -
    
    215
    -    stream->memory = memory;
    
    216
    -
    
    217
    -    if ( args->flags & FT_OPEN_MEMORY )
    
    215
    +    if ( mode == FT_OPEN_MEMORY )
    
    218 216
         {
    
    219 217
           /* create a memory-based stream */
    
    218
    +      if ( FT_NEW( stream ) )
    
    219
    +        goto Exit;
    
    220
    +
    
    220 221
           FT_Stream_OpenMemory( stream,
    
    221 222
                                 (const FT_Byte*)args->memory_base,
    
    222 223
                                 (FT_ULong)args->memory_size );
    
    ... ... @@ -224,33 +225,40 @@
    224 225
     
    
    225 226
     #ifndef FT_CONFIG_OPTION_DISABLE_STREAM_SUPPORT
    
    226 227
     
    
    227
    -    else if ( args->flags & FT_OPEN_PATHNAME )
    
    228
    +    else if ( mode == FT_OPEN_PATHNAME )
    
    228 229
         {
    
    229 230
           /* create a normal system stream */
    
    231
    +      if ( FT_NEW( stream ) )
    
    232
    +        goto Exit;
    
    233
    +
    
    230 234
           error = FT_Stream_Open( stream, args->pathname );
    
    231
    -      stream->pathname.pointer = args->pathname;
    
    235
    +      if ( error )
    
    236
    +        FT_FREE( stream );
    
    232 237
         }
    
    233
    -    else if ( ( args->flags & FT_OPEN_STREAM ) && args->stream )
    
    238
    +    else if ( ( mode == FT_OPEN_STREAM ) && args->stream )
    
    234 239
         {
    
    235 240
           /* use an existing, user-provided stream */
    
    236 241
     
    
    237 242
           /* in this case, we do not need to allocate a new stream object */
    
    238 243
           /* since the caller is responsible for closing it himself       */
    
    239
    -      FT_FREE( stream );
    
    240 244
           stream = args->stream;
    
    245
    +      error  = FT_Err_Ok;
    
    241 246
         }
    
    242 247
     
    
    243 248
     #endif
    
    244 249
     
    
    245 250
         else
    
    251
    +    {
    
    246 252
           error = FT_THROW( Invalid_Argument );
    
    253
    +      if ( ( args->flags & FT_OPEN_STREAM ) && args->stream )
    
    254
    +        FT_Stream_Close( args->stream );
    
    255
    +    }
    
    247 256
     
    
    248
    -    if ( error )
    
    249
    -      FT_FREE( stream );
    
    250
    -    else
    
    251
    -      stream->memory = memory;  /* just to be certain */
    
    252
    -
    
    253
    -    *astream = stream;
    
    257
    +    if ( !error )
    
    258
    +    {
    
    259
    +      stream->memory = memory;
    
    260
    +      *astream       = stream;
    
    261
    +    }
    
    254 262
     
    
    255 263
       Exit:
    
    256 264
         return error;
    

  • src/sdf/ftsdf.c
    ... ... @@ -41,7 +41,8 @@
    41 41
        *     file `ftbsdf.c` for more.
    
    42 42
        *
    
    43 43
        *   * The basic idea of generating the SDF is taken from Viktor Chlumsky's
    
    44
    -   *     research paper.
    
    44
    +   *     research paper.  The paper explains both single and multi-channel
    
    45
    +   *     SDF, however, this implementation only generates single-channel SDF.
    
    45 46
        *
    
    46 47
        *       Chlumsky, Viktor: Shape Decomposition for Multi-channel Distance
    
    47 48
        *       Fields.  Master's thesis.  Czech Technical University in Prague,
    

  • tests/README.md
    ... ... @@ -4,7 +4,7 @@
    4 4
     
    
    5 5
     ### Download test fonts
    
    6 6
     
    
    7
    -Run the `tests/scripts/download-fonts.sh` script, which will
    
    7
    +Run the `tests/scripts/download-fonts.py` script, which will
    
    8 8
     download test fonts to the `tests/data/` directory first.
    
    9 9
     
    
    10 10
     ### Build the test programs
    

  • tests/scripts/download-test-fonts.py
    1
    +#!/usr/bin/env python3
    
    2
    +
    
    3
    +"""Download test fonts used by the FreeType regression test programs.
    
    4
    +These will be copied to $FREETYPE/tests/data/ by default.
    
    5
    +"""
    
    6
    +
    
    7
    +import argparse
    
    8
    +import collections
    
    9
    +import hashlib
    
    10
    +import io
    
    11
    +import os
    
    12
    +import requests
    
    13
    +import sys
    
    14
    +import zipfile
    
    15
    +
    
    16
    +from typing import Callable, List, Optional, Tuple
    
    17
    +
    
    18
    +# The list of download items describing the font files to install.
    
    19
    +# Each download item is a dictionary with one of the following schemas:
    
    20
    +#
    
    21
    +# - File item:
    
    22
    +#
    
    23
    +#      file_url
    
    24
    +#        Type: URL string.
    
    25
    +#        Required: Yes.
    
    26
    +#        Description: URL to download the file from.
    
    27
    +#
    
    28
    +#      install_name
    
    29
    +#        Type: file name string
    
    30
    +#        Required: No
    
    31
    +#        Description: Installation name for the font file, only provided if it
    
    32
    +#          must be different from the original URL's basename.
    
    33
    +#
    
    34
    +#      hex_digest
    
    35
    +#        Type: hexadecimal string
    
    36
    +#        Required: No
    
    37
    +#        Description: Digest of the input font file.
    
    38
    +#
    
    39
    +# - Zip items:
    
    40
    +#
    
    41
    +#   These items correspond to one or more font files that are embedded in a
    
    42
    +#   remote zip archive. Each entry has the following fields:
    
    43
    +#
    
    44
    +#      zip_url
    
    45
    +#        Type: URL string.
    
    46
    +#        Required: Yes.
    
    47
    +#        Description: URL to download the zip archive from.
    
    48
    +#
    
    49
    +#      zip_files
    
    50
    +#        Type: List of file entries (see below)
    
    51
    +#        Required: Yes
    
    52
    +#        Description: A list of entries describing a single font file to be
    
    53
    +#          extracted from the archive
    
    54
    +#
    
    55
    +# Apart from that, some schemas are used for dictionaries used inside download
    
    56
    +# items:
    
    57
    +#
    
    58
    +# - File entries:
    
    59
    +#
    
    60
    +#   These are dictionaries describing a single font file to extract from an archive.
    
    61
    +#
    
    62
    +#      filename
    
    63
    +#        Type: file path string
    
    64
    +#        Required: Yes
    
    65
    +#        Description: Path of source file, relative to the archive's top-level directory.
    
    66
    +#
    
    67
    +#      install_name
    
    68
    +#        Type: file name string
    
    69
    +#        Required: No
    
    70
    +#        Description: Installation name for the font file, only provided if it must be
    
    71
    +#          different from the original filename value.
    
    72
    +#
    
    73
    +#      hex_digest
    
    74
    +#        Type: hexadecimal string
    
    75
    +#        Required: No
    
    76
    +#        Description: Digest of the input source file
    
    77
    +#
    
    78
    +_DOWNLOAD_ITEMS = [
    
    79
    +    {
    
    80
    +        "zip_url": "https://github.com/python-pillow/Pillow/files/6622147/As.I.Lay.Dying.zip",
    
    81
    +        "zip_files": [
    
    82
    +            {
    
    83
    +                "filename": "As I Lay Dying.ttf",
    
    84
    +                "install_name": "As.I.Lay.Dying.ttf",
    
    85
    +                "hex_digest": "ef146bbc2673b387",
    
    86
    +            },
    
    87
    +        ],
    
    88
    +    },
    
    89
    +]
    
    90
    +
    
    91
    +
    
    92
    +def digest_data(data: bytes):
    
    93
    +    """Compute the digest of a given input byte string, which are the first 8 bytes of its sha256 hash."""
    
    94
    +    m = hashlib.sha256()
    
    95
    +    m.update(data)
    
    96
    +    return m.digest()[:8]
    
    97
    +
    
    98
    +
    
    99
    +def check_existing(path: str, hex_digest: str):
    
    100
    +    """Return True if |path| exists and matches |hex_digest|."""
    
    101
    +    if not os.path.exists(path) or hex_digest is None:
    
    102
    +        return False
    
    103
    +
    
    104
    +    with open(path, "rb") as f:
    
    105
    +        existing_content = f.read()
    
    106
    +
    
    107
    +    return bytes.fromhex(hex_digest) == digest_data(existing_content)
    
    108
    +
    
    109
    +
    
    110
    +def install_file(content: bytes, dest_path: str):
    
    111
    +    """Write a byte string to a given destination file.
    
    112
    +
    
    113
    +    Args:
    
    114
    +      content: Input data, as a byte string
    
    115
    +      dest_path: Installation path
    
    116
    +    """
    
    117
    +    parent_path = os.path.dirname(dest_path)
    
    118
    +    if not os.path.exists(parent_path):
    
    119
    +        os.makedirs(parent_path)
    
    120
    +
    
    121
    +    with open(dest_path, "wb") as f:
    
    122
    +        f.write(content)
    
    123
    +
    
    124
    +
    
    125
    +def download_file(url: str, expected_digest: Optional[bytes] = None):
    
    126
    +    """Download a file from a given URL.
    
    127
    +
    
    128
    +    Args:
    
    129
    +      url: Input URL
    
    130
    +      expected_digest: Optional digest of the file
    
    131
    +        as a byte string
    
    132
    +    Returns:
    
    133
    +      URL content as binary string.
    
    134
    +    """
    
    135
    +    r = requests.get(url, allow_redirects=True)
    
    136
    +    content = r.content
    
    137
    +    if expected_digest is not None:
    
    138
    +        digest = digest_data(r.content)
    
    139
    +        if digest != expected_digest:
    
    140
    +            raise ValueError(
    
    141
    +                "%s has invalid digest %s (expected %s)"
    
    142
    +                % (url, digest.hex(), expected_digest.hex())
    
    143
    +            )
    
    144
    +
    
    145
    +    return content
    
    146
    +
    
    147
    +
    
    148
    +def extract_file_from_zip_archive(
    
    149
    +    archive: zipfile.ZipFile,
    
    150
    +    archive_name: str,
    
    151
    +    filepath: str,
    
    152
    +    expected_digest: Optional[bytes] = None,
    
    153
    +):
    
    154
    +    """Extract a file from a given zipfile.ZipFile archive.
    
    155
    +
    
    156
    +    Args:
    
    157
    +      archive: Input ZipFile objec.
    
    158
    +      archive_name: Archive name or URL, only used to generate a human-readable error
    
    159
    +        message.
    
    160
    +      filepath: Input filepath in archive.
    
    161
    +      expected_digest: Optional digest for the file.
    
    162
    +    Returns:
    
    163
    +      A new File instance corresponding to the extract file.
    
    164
    +    Raises:
    
    165
    +      ValueError if expected_digest is not None and does not match the extracted file.
    
    166
    +    """
    
    167
    +    file = archive.open(filepath)
    
    168
    +    if expected_digest is not None:
    
    169
    +        digest = digest_data(archive.open(filepath).read())
    
    170
    +        if digest != expected_digest:
    
    171
    +            raise ValueError(
    
    172
    +                "%s in zip archive at %s has invalid digest %s (expected %s)"
    
    173
    +                % (filepath, archive_name, digest.hex(), expected_digest.hex())
    
    174
    +            )
    
    175
    +    return file.read()
    
    176
    +
    
    177
    +
    
    178
    +def _get_and_install_file(
    
    179
    +    install_path: str,
    
    180
    +    hex_digest: Optional[str],
    
    181
    +    force_download: bool,
    
    182
    +    get_content: Callable[[], bytes],
    
    183
    +) -> bool:
    
    184
    +    if not force_download and hex_digest is not None and os.path.exists(install_path):
    
    185
    +        with open(install_path, "rb") as f:
    
    186
    +            content: bytes = f.read()
    
    187
    +        if bytes.fromhex(hex_digest) == digest_data(content):
    
    188
    +            return False
    
    189
    +
    
    190
    +    content = get_content()
    
    191
    +    install_file(content, install_path)
    
    192
    +    return True
    
    193
    +
    
    194
    +
    
    195
    +def download_and_install_item(
    
    196
    +    item: dict, install_dir: str, force_download: bool
    
    197
    +) -> List[Tuple[str, bool]]:
    
    198
    +    """Download and install one item.
    
    199
    +
    
    200
    +    Args:
    
    201
    +      item: Download item as a dictionary, see above for schema.
    
    202
    +      install_dir: Installation directory.
    
    203
    +      force_download: Set to True to force download and installation, even if
    
    204
    +        the font file is already installed with the right content.
    
    205
    +
    
    206
    +    Returns:
    
    207
    +      A list of (install_name, status) tuples, where 'install_name' is the file's
    
    208
    +      installation name under 'install_dir', and 'status' is a boolean that is True
    
    209
    +      to indicate that the file was downloaded and installed, or False to indicate that
    
    210
    +      the file is already installed with the right content.
    
    211
    +    """
    
    212
    +    if "file_url" in item:
    
    213
    +        file_url = item["file_url"]
    
    214
    +        install_name = item.get("install_name", os.path.basename(file_url))
    
    215
    +        install_path = os.path.join(install_dir, install_name)
    
    216
    +        hex_digest = item.get("hex_digest")
    
    217
    +
    
    218
    +        def get_content():
    
    219
    +            return download_file(file_url, hex_digest)
    
    220
    +
    
    221
    +        status = _get_and_install_file(
    
    222
    +            install_path, hex_digest, force_download, get_content
    
    223
    +        )
    
    224
    +        return [(install_name, status)]
    
    225
    +
    
    226
    +    if "zip_url" in item:
    
    227
    +        # One or more files from a zip archive.
    
    228
    +        archive_url = item["zip_url"]
    
    229
    +        archive = zipfile.ZipFile(io.BytesIO(download_file(archive_url)))
    
    230
    +
    
    231
    +        result = []
    
    232
    +        for f in item["zip_files"]:
    
    233
    +            filename = f["filename"]
    
    234
    +            install_name = f.get("install_name", filename)
    
    235
    +            hex_digest = f.get("hex_digest")
    
    236
    +
    
    237
    +            def get_content():
    
    238
    +                return extract_file_from_zip_archive(
    
    239
    +                    archive,
    
    240
    +                    archive_url,
    
    241
    +                    filename,
    
    242
    +                    bytes.fromhex(hex_digest) if hex_digest else None,
    
    243
    +                )
    
    244
    +
    
    245
    +            status = _get_and_install_file(
    
    246
    +                os.path.join(install_dir, install_name),
    
    247
    +                hex_digest,
    
    248
    +                force_download,
    
    249
    +                get_content,
    
    250
    +            )
    
    251
    +            result.append((install_name, status))
    
    252
    +
    
    253
    +        return result
    
    254
    +
    
    255
    +    else:
    
    256
    +        raise ValueError("Unknown download item schema: %s" % item)
    
    257
    +
    
    258
    +
    
    259
    +def main():
    
    260
    +    parser = argparse.ArgumentParser(description=__doc__)
    
    261
    +
    
    262
    +    # Assume this script is under tests/scripts/ and tests/data/
    
    263
    +    # is the default installation directory.
    
    264
    +    install_dir = os.path.normpath(
    
    265
    +        os.path.join(os.path.dirname(__file__), "..", "data")
    
    266
    +    )
    
    267
    +
    
    268
    +    parser.add_argument(
    
    269
    +        "--force",
    
    270
    +        action="store_true",
    
    271
    +        default=False,
    
    272
    +        help="Force download and installation of font files",
    
    273
    +    )
    
    274
    +
    
    275
    +    parser.add_argument(
    
    276
    +        "--install-dir",
    
    277
    +        default=install_dir,
    
    278
    +        help="Specify installation directory [%s]" % install_dir,
    
    279
    +    )
    
    280
    +
    
    281
    +    args = parser.parse_args()
    
    282
    +
    
    283
    +    for item in _DOWNLOAD_ITEMS:
    
    284
    +        for install_name, status in download_and_install_item(
    
    285
    +            item, args.install_dir, args.force
    
    286
    +        ):
    
    287
    +            print("%s %s" % (install_name, "INSTALLED" if status else "UP-TO-DATE"))
    
    288
    +
    
    289
    +    return 0
    
    290
    +
    
    291
    +
    
    292
    +if __name__ == "__main__":
    
    293
    +    sys.exit(main())

  • tests/scripts/download-test-fonts.sh deleted
    1
    -#!/usr/bin/bash
    
    2
    -# Download test fonts used by the FreeType regression test programs.
    
    3
    -# These will be copied to $FREETYPE/tests/data/
    
    4
    -# Each font file contains an 8-hexchar prefix corresponding to its md5sum
    
    5
    -
    
    6
    -set -e
    
    7
    -
    
    8
    -export LANG=C
    
    9
    -export LC_ALL=C
    
    10
    -
    
    11
    -PROGDIR=$(dirname "$0")
    
    12
    -PROGNAME=$(basename "$0")
    
    13
    -
    
    14
    -# Download a file from a given URL
    
    15
    -#
    
    16
    -# $1: URL
    
    17
    -# $2: Destination directory
    
    18
    -# $3: If not empty, destination file name. Default is to take
    
    19
    -# the URL's basename.
    
    20
    -#
    
    21
    -download_file () {
    
    22
    -  local URL=$1
    
    23
    -  local DST_DIR=$2
    
    24
    -  local DST_FILE=$3
    
    25
    -  if [[ -z "$DST_FILE" ]]; then
    
    26
    -    DST_FILE=$(basename "$URL")
    
    27
    -  fi
    
    28
    -  echo "URL: $URL"
    
    29
    -  wget -q -O "$DST_DIR/$DST_FILE" "$URL"
    
    30
    -}
    
    31
    -
    
    32
    -# $1: URL
    
    33
    -# $2: Destination directory
    
    34
    -# $3+: Optional file list, otherwise the full archive is extracted to $2
    
    35
    -download_and_extract_zip () {
    
    36
    -  local URL=$1
    
    37
    -  local DST_DIR=$2
    
    38
    -  shift
    
    39
    -  shift
    
    40
    -  TEMP_DST_DIR=$(mktemp -d)
    
    41
    -  TEMP_DST_NAME="a.zip"
    
    42
    -  download_file "$URL" "$TEMP_DST_DIR" "$TEMP_DST_NAME"
    
    43
    -  unzip -qo "$TEMP_DST_DIR/$TEMP_DST_NAME" -d "$DST_DIR" "$@"
    
    44
    -  rm -rf "$TEMP_DST_DIR"
    
    45
    -}
    
    46
    -
    
    47
    -# $1: File path
    
    48
    -# $2: Expected md5sum
    
    49
    -md5sum_check () {
    
    50
    -  local FILE=$1
    
    51
    -  local EXPECTED=$2
    
    52
    -  local HASH=$(md5sum "$FILE" | cut -d" " -f1)
    
    53
    -  if [[ "$EXPECTED" != "$HASH" ]]; then
    
    54
    -    echo "$FILE: Invalid md5sum $HASH expected $EXPECTED"
    
    55
    -    return 1
    
    56
    -  fi
    
    57
    -}
    
    58
    -
    
    59
    -INSTALL_DIR=$(cd $PROGDIR/.. && pwd)/data
    
    60
    -
    
    61
    -mkdir -p "$INSTALL_DIR"
    
    62
    -
    
    63
    -# See https://gitlab.freedesktop.org/freetype/freetype/-/issues/1063
    
    64
    -download_and_extract_zip "https://github.com/python-pillow/Pillow/files/6622147/As.I.Lay.Dying.zip" "$INSTALL_DIR"
    
    65
    -mv "$INSTALL_DIR/As I Lay Dying.ttf" "$INSTALL_DIR/As.I.Lay.Dying.ttf"
    
    66
    -md5sum_check "$INSTALL_DIR/As.I.Lay.Dying.ttf" e153d60e66199660f7cfe99ef4705ad7


  • reply via email to

    [Prev in Thread] Current Thread [Next in Thread]