freetype-commit
[Top][All Lists]
Advanced

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

[Git][freetype/freetype][split-conic-dda] 8 commits: Small clean-ups for


From: David Turner (@david.freetype)
Subject: [Git][freetype/freetype][split-conic-dda] 8 commits: Small clean-ups for the last few commits.
Date: Thu, 15 Jul 2021 11:04:51 +0000

David Turner pushed to branch split-conic-dda at FreeType / FreeType

Commits:

15 changed files:

Changes:

  • ChangeLog
    1
    +2021-07-13  David Turner  <david@freetype.org>
    
    2
    +
    
    3
    +	[smooth] Implement Bezier quadratic arc flattenning with DDA
    
    4
    +
    
    5
    +	Benchmarking shows that this provides a very slighty performance
    
    6
    +	boost when rendering fonts with lots of quadratic bezier arcs,
    
    7
    +	compared to the recursive arc splitting, but only when SSE2 is
    
    8
    +	available, or on 64-bit CPUs.
    
    9
    +
    
    10
    +	* src/smooth/ftgrays.c (gray_render_conic): New implementation
    
    11
    +	based on DDA and optionally SSE2.
    
    12
    +
    
    13
    +2021-07-13  David Turner  <david@freetype.org>
    
    14
    +
    
    15
    +	[smooth] Minor speedup to smooth rasterizer
    
    16
    +
    
    17
    +	This speeds up the smooth rasterizer by avoiding a conditional
    
    18
    +	branches in the hot path.
    
    19
    +
    
    20
    +	* src/smooth/ftgrays.c: Define a null cell used to both as a
    
    21
    +	sentinel for all linked-lists, and to accumulate coverage and
    
    22
    +	area values for "out-of-bounds" cell positions without a
    
    23
    +	conditional check.
    
    24
    +
    
    25
    +2021-07-13  Oleg Oshmyan  <chortos@inbox.lv>
    
    26
    +
    
    27
    +	[base] Fix `FT_Open_Face`'s handling of user-supplied streams.
    
    28
    +
    
    29
    +	This was already true (though undocumented) most of the time, but
    
    30
    +	not if `FT_NEW` inside `FT_Stream_New` failed or if the
    
    31
    +	`FT_OPEN_XXX` flags were bad.
    
    32
    +
    
    33
    +	Normally, `FT_Open_Face` calls `FT_Stream_New`, which returns the
    
    34
    +	user-supplied stream unchanged, and in case of any subsequent error
    
    35
    +	in `FT_Open_Face`, the stream is closed via `FT_Stream_Free`.
    
    36
    +
    
    37
    +	Up to now, however, `FT_Stream_New` allocates a new stream even if
    
    38
    +	it is already given one by the user.  If this allocation fails, the
    
    39
    +	user-supplied stream is not returned to `FT_Open_Face` and never
    
    40
    +	closed.  Moreover, the user cannot detect this situation: all they
    
    41
    +	see is that `FT_Open_Face` returns `FT_Err_Out_Of_Memory`, but that
    
    42
    +	can also happen after a different allocation fails within the main
    
    43
    +	body of `FT_Open_Face`, when the user's stream has already been
    
    44
    +	closed by `FT_Open_Face`.  It is plausible that the user stream's
    
    45
    +	`close` method frees memory allocated for the stream object itself,
    
    46
    +	so the user cannot defensively free it upon `FT_Open_Face` failure
    
    47
    +	lest it ends up doubly freed.  All in all, this ends up leaking the
    
    48
    +	memory/resources used by user's stream.
    
    49
    +
    
    50
    +	Furthermore, `FT_Stream_New` simply returns an error if the
    
    51
    +	`FT_OPEN_XXX` flags are unsupported, which can mean either an
    
    52
    +	invalid combination of flags or a perfectly innocent
    
    53
    +	`FT_OPEN_STREAM` on a FreeType build that lacks stream support.
    
    54
    +	With this patch, the user-supplied stream is closed even in these
    
    55
    +	cases, so the user can be sure that if `FT_Open_Face` failed, the
    
    56
    +	stream is definitely closed.
    
    57
    +
    
    58
    +	* src/base/ftobjs.c (FT_Stream_New): Don't allocate a buffer
    
    59
    +	unnecessarily.
    
    60
    +	Move error-handling code to make the control flow more obvious.
    
    61
    +	Close user-supplied stream if the flags are unsupported.
    
    62
    +	`FT_Stream_Open` always sets `pathname.pointer`, so remove the
    
    63
    +	redundant (re)assignment.  None of the `FT_Stream_Open...` functions
    
    64
    +	uses `stream->memory`, so keep just one assignment at the end,
    
    65
    +	shared among all possible control flow paths.
    
    66
    +	('Unsupported flags' that may need a stream closure can be either an
    
    67
    +	invalid combination of multiple `FT_OPEN_XXX` mode flags or a clean
    
    68
    +	`FT_OPEN_STREAM` flag on a FreeType build that lacks stream
    
    69
    +	support.)
    
    70
    +
    
    71
    +2021-07-13  Oleg Oshmyan  <chortos@inbox.lv>
    
    72
    +
    
    73
    +	[base] Reject combinations of incompatible `FT_OPEN_XXX` flags.
    
    74
    +
    
    75
    +	The three modes are mutually exclusive, and the documentation of the
    
    76
    +	`FT_OPEN_XXX` constants notes this.  However, there was no check to
    
    77
    +	validate this in the code, and the documentation on `FT_Open_Args`
    
    78
    +	claimed that the corresponding bits were checked in a well-defined
    
    79
    +	order, implying it was valid (if useless) to specify more than one.
    
    80
    +	Ironically, this documented order did not agree with the actual
    
    81
    +	code, so it could not be relied upon; hopefully, nobody did this and
    
    82
    +	nobody will be hurt by the new validation.
    
    83
    +
    
    84
    +	Even if multiple mode bits were allowed, they could cause memory
    
    85
    +	leaks: if both `FT_OPEN_STREAM` and `stream` are set along with
    
    86
    +	either `FT_OPEN_MEMORY` or `FT_OPEN_PATHNAME`, then `FT_Stream_New`
    
    87
    +	allocated a new stream but `FT_Open_Face` marked it as an 'external'
    
    88
    +	stream, so the stream object was never released.
    
    89
    +
    
    90
    +	* src/base/ftobjs.c (FT_Stream_New): Reject incompatible
    
    91
    +	`FT_OPEN_XXX` flags.
    
    92
    +
    
    93
    +2021-07-12  Alex Richardson  <Alexander.Richardson@cl.cam.ac.uk>
    
    94
    +
    
    95
    +	* meson.build: Fix build for other UNIX systems (e.g., FreeBSD).
    
    96
    +
    
    97
    +	Without this change the build of `unix/ftsystem.c` fails because the
    
    98
    +	`ftconfig.h` header that defines macros such as `HAVE_UNISTD_H` and
    
    99
    +	`HAVE_FCNTL_H` is only being generated for Linux, macOS, and Cygwin
    
    100
    +	systems:
    
    101
    +
    
    102
    +	```
    
    103
    +	.../builds/unix/ftsystem.c:258:32: error:
    
    104
    +	    use of undeclared identifier 'O_RDONLY'
    
    105
    +	file = open( filepathname, O_RDONLY );
    
    106
    +	```
    
    107
    +
    
    108
    +	Instead of hardcoding a list of operating systems for this check,
    
    109
    +	update the logic that decides whether to build the file and set a
    
    110
    +	boolean flag that can be checked instead.
    
    111
    +
    
    112
    +2021-07-12  Werner Lemberg  <wl@gnu.org>
    
    113
    +
    
    114
    +	[autofit] More clean-ups.
    
    115
    +
    
    116
    +	* src/autofit/afhints.h (AF_GlyphHintsRec): Remove the no longer
    
    117
    +	needed fields `xmin_delta` and `xmax_delta`.
    
    118
    +
    
    119
    +	* src/autofit/afhints.c (af_glyph_hints_reload),
    
    120
    +	src/autofit/afloader.c (af_loader_load_glyph): Updated.
    
    121
    +
    
    122
    +2021-07-12  Werner Lemberg  <wl@gnu.org>
    
    123
    +
    
    124
    +	Small clean-ups for the last few commits.
    
    125
    +
    
    126
    +	* include/freetype/fttrace.h (afwarp): Removed.
    
    127
    +
    
    1 128
     2021-07-12  David Turner  <david@freetype.org>
    
    2 129
     
    
    3
    -	Remove obsolete AF_Angle type and related sources.
    
    130
    +	Remove obsolete `AF_Angle` type and related sources.
    
    4 131
     
    
    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.
    
    132
    +	* src/autofit/afangles.c: File removed.  Functions related to
    
    133
    +	sorting moved to...
    
    134
    +	* src/autofit/afhints.c (af_sort_pos, af_sort_and_quantize_widths):
    
    135
    +	This file.
    
    136
    +	* src/autofit/afangles.h: File removed.
    
    137
    +	* src/autofit/aftypes.h: Updated.
    
    138
    +	* src/autofit/autofit.c: Updated.
    
    8 139
     
    
    9
    -	* src/autofit/*: Remove code.
    
    140
    +	* src/autofit/rules.mk (AUTOF_DRV_SRC): Updated.
    
    10 141
     
    
    11 142
     2021-07-12  David Turner  <david@freetype.org>
    
    12 143
     
    
    13 144
     	Remove experimental auto-hinting 'warp' mode.
    
    14 145
     
    
    15
    -	This feature was always experimental, and probably nevery worked
    
    16
    -	properly. This patch completely removes it from the source code,
    
    146
    +	This feature was always experimental, and probably never worked
    
    147
    +	properly.  This patch completely removes it from the source code,
    
    17 148
     	except for a documentation block describing it for historical
    
    18
    -	purpose.
    
    149
    +	purposes.
    
    150
    +
    
    151
    +	* devel/ftoption.h, include/freetype/config/ftoption.h: Remove
    
    152
    +	`AF_CONFIG_OPTION_USE_WARPER`.
    
    153
    +
    
    154
    +	* include/freetype/ftdriver.h: Document 'warping' property as
    
    155
    +	obsolete.
    
    19 156
     
    
    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.
    
    157
    +	* src/autofit/afwarp.c, src/autofit/afwarp.h: Files removed.
    
    158
    +	* src/autofit/*: Remove any code related to warp mode.
    
    24 159
     
    
    25 160
     2021-07-12  David Turner  <david@freetype.org>
    
    26 161
     
    
    27
    -	Remove experimental "Latin2" writing system (FT_OPTION_AUTOFIT2)
    
    162
    +	Remove experimental 'Latin2' writing system (`FT_OPTION_AUTOFIT2`).
    
    28 163
     
    
    29 164
     	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.
    
    165
    +	(`FT_OPTION_AUTOFIT2` does not appear in `ftoption.h` or even any of
    
    166
    +	our build files).
    
    167
    +
    
    168
    +	* include/freetype/internal/fttrace.h (aflatin2): Removed.
    
    169
    +	* src/autofit/aflatin2.h, src/autofit/aflatin2.c: Files removed.
    
    170
    +	* src/autofit/afloader.c: Remove undocumented hook to activate
    
    171
    +	Latin2 system.
    
    172
    +	* src/autofit/afstyles.h: Remove `ltn2_dflt` style definition.
    
    173
    +	* src/autofit/afwrtsys.h: Remove `LATIN2` writing system definition.
    
    38 174
     	* src/autofit/autofit.c: Updated.
    
    39 175
     
    
    40 176
     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/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,
    

  • src/smooth/ftgrays.c
    ... ... @@ -479,19 +479,24 @@ typedef ptrdiff_t FT_PtrDist;
    479 479
       {
    
    480 480
         ft_jmp_buf  jump_buffer;
    
    481 481
     
    
    482
    -    TCoord  min_ex, max_ex;
    
    482
    +    TCoord  min_ex, max_ex;  /* min and max integer pixel coordinates */
    
    483 483
         TCoord  min_ey, max_ey;
    
    484
    +    TCoord  count_ey;        /* same as (max_ey - min_ey) */
    
    484 485
     
    
    485
    -    PCell       cell;
    
    486
    -    PCell*      ycells;
    
    487
    -    PCell       cells;
    
    488
    -    FT_PtrDist  max_cells;
    
    489
    -    FT_PtrDist  num_cells;
    
    486
    +    PCell       cell;        /* current cell                             */
    
    487
    +    PCell       cell_free;   /* call allocation next free slot           */
    
    488
    +    PCell       cell_limit;  /* cell allocation limit                    */
    
    490 489
     
    
    491
    -    TPos    x,  y;
    
    490
    +    PCell*      ycells;      /* array of cell linked-lists, one per      */
    
    491
    +							 /* vertical coordinate in the current band. */
    
    492 492
     
    
    493
    -    FT_Outline  outline;
    
    494
    -    TPixmap     target;
    
    493
    +    PCell       cells;       /* cell storage area     */
    
    494
    +    FT_PtrDist  max_cells;   /* cell storage capacity */
    
    495
    +
    
    496
    +    TPos        x,  y;       /* last point position */
    
    497
    +
    
    498
    +    FT_Outline  outline;     /* input outline */
    
    499
    +    TPixmap     target;      /* target pixmap */
    
    495 500
     
    
    496 501
         FT_Raster_Span_Func  render_span;
    
    497 502
         void*                render_span_data;
    
    ... ... @@ -502,21 +507,34 @@ typedef ptrdiff_t FT_PtrDist;
    502 507
     #pragma warning( pop )
    
    503 508
     #endif
    
    504 509
     
    
    505
    -
    
    506 510
     #ifndef FT_STATIC_RASTER
    
    507 511
     #define ras  (*worker)
    
    508 512
     #else
    
    509 513
       static gray_TWorker  ras;
    
    510 514
     #endif
    
    511 515
     
    
    512
    -#define FT_INTEGRATE( ras, a, b )                                       \
    
    513
    -           if ( ras.cell )                                              \
    
    514
    -             ras.cell->cover += (a), ras.cell->area += (a) * (TArea)(b)
    
    516
    +/* Return a pointer to the "null cell", used as a sentinel at the end   */
    
    517
    +/* of all ycells[] linked lists. Its x coordinate should be maximal     */
    
    518
    +/* to ensure no NULL checks are necessary when looking for an insertion */
    
    519
    +/* point in gray_set_cell(). Other loops should check the cell pointer  */
    
    520
    +/* with CELL_IS_NULL() to detect the end of the list.                   */
    
    521
    +#define NULL_CELL_PTR(ras)  (ras).cells
    
    522
    +
    
    523
    +/* The |x| value of the null cell. Must be the largest possible */
    
    524
    +/* integer value stored in a TCell.x field.                     */
    
    525
    +#define CELL_MAX_X_VALUE    INT_MAX
    
    526
    +
    
    527
    +/* Return true iff |cell| points to the null cell. */
    
    528
    +#define CELL_IS_NULL(cell)  ((cell)->x == CELL_MAX_X_VALUE)
    
    529
    +
    
    530
    +
    
    531
    +#define FT_INTEGRATE( ras, a, b )                                     \
    
    532
    +           ras.cell->cover += (a), ras.cell->area += (a) * (TArea)(b)
    
    515 533
     
    
    516 534
     
    
    517 535
       typedef struct gray_TRaster_
    
    518 536
       {
    
    519
    -    void*         memory;
    
    537
    +    void*  memory;
    
    520 538
     
    
    521 539
       } gray_TRaster, *gray_PRaster;
    
    522 540
     
    
    ... ... @@ -538,7 +556,7 @@ typedef ptrdiff_t FT_PtrDist;
    538 556
     
    
    539 557
           printf( "%3d:", y );
    
    540 558
     
    
    541
    -      for ( ; cell != NULL; cell = cell->next )
    
    559
    +      for ( ; !CELL_IS_NULL(cell); cell = cell->next )
    
    542 560
             printf( " (%3d, c:%4d, a:%6d)",
    
    543 561
                     cell->x, cell->cover, cell->area );
    
    544 562
           printf( "\n" );
    
    ... ... @@ -566,11 +584,12 @@ typedef ptrdiff_t FT_PtrDist;
    566 584
         /* Note that if a cell is to the left of the clipping region, it is    */
    
    567 585
         /* actually set to the (min_ex-1) horizontal position.                 */
    
    568 586
     
    
    569
    -    if ( ey >= ras.max_ey || ey < ras.min_ey || ex >= ras.max_ex )
    
    570
    -      ras.cell = NULL;
    
    587
    +    TCoord ey_index = ey - ras.min_ey;
    
    588
    +    if ( ey_index < 0 || ey_index >= ras.count_ey || ex >= ras.max_ex )
    
    589
    +      ras.cell = NULL_CELL_PTR(ras);
    
    571 590
         else
    
    572 591
         {
    
    573
    -      PCell*  pcell = ras.ycells + ey - ras.min_ey;
    
    592
    +      PCell*  pcell = ras.ycells + ey_index;
    
    574 593
           PCell   cell;
    
    575 594
     
    
    576 595
     
    
    ... ... @@ -580,7 +599,7 @@ typedef ptrdiff_t FT_PtrDist;
    580 599
           {
    
    581 600
             cell = *pcell;
    
    582 601
     
    
    583
    -        if ( !cell || cell->x > ex )
    
    602
    +        if ( cell->x > ex )
    
    584 603
               break;
    
    585 604
     
    
    586 605
             if ( cell->x == ex )
    
    ... ... @@ -589,11 +608,11 @@ typedef ptrdiff_t FT_PtrDist;
    589 608
             pcell = &cell->next;
    
    590 609
           }
    
    591 610
     
    
    592
    -      if ( ras.num_cells >= ras.max_cells )
    
    611
    +      /* insert new cell */
    
    612
    +      cell = ras.cell_free++;
    
    613
    +      if (cell >= ras.cell_limit)
    
    593 614
             ft_longjmp( ras.jump_buffer, 1 );
    
    594 615
     
    
    595
    -      /* insert new cell */
    
    596
    -      cell        = ras.cells + ras.num_cells++;
    
    597 616
           cell->x     = ex;
    
    598 617
           cell->area  = 0;
    
    599 618
           cell->cover = 0;
    
    ... ... @@ -974,6 +993,188 @@ typedef ptrdiff_t FT_PtrDist;
    974 993
     
    
    975 994
     #endif
    
    976 995
     
    
    996
    +/* Benchmarking shows that using DDA to flatten the quadratic bezier
    
    997
    + * arcs is slightly faster in the following cases:
    
    998
    + *
    
    999
    + *   - When the host CPU is 64-bit.
    
    1000
    + *   - When SSE2 SIMD registers and instructions are available (even on x86).
    
    1001
    + *
    
    1002
    + * For other cases, using binary splits is actually slightly faster.
    
    1003
    + */
    
    1004
    +#if defined(__SSE2__) || defined(__x86_64__) || defined(__aarch64__) || defined(_M_AMD64) || defined(_M_ARM64)
    
    1005
    +#define BEZIER_USE_DDA  1
    
    1006
    +#else
    
    1007
    +#define BEZIER_USE_DDA  0
    
    1008
    +#endif
    
    1009
    +
    
    1010
    +#if BEZIER_USE_DDA
    
    1011
    +
    
    1012
    +#include <emmintrin.h>
    
    1013
    +
    
    1014
    +  static void
    
    1015
    +  gray_render_conic( RAS_ARG_ const FT_Vector*  control,
    
    1016
    +                              const FT_Vector*  to )
    
    1017
    +  {
    
    1018
    +    FT_Vector  p0, p1, p2;
    
    1019
    +
    
    1020
    +    p0.x = ras.x;
    
    1021
    +    p0.y = ras.y;
    
    1022
    +    p1.x = UPSCALE( control->x );
    
    1023
    +    p1.y = UPSCALE( control->y );
    
    1024
    +    p2.x = UPSCALE( to->x );
    
    1025
    +    p2.y = UPSCALE( to->y );
    
    1026
    +
    
    1027
    +    /* short-cut the arc that crosses the current band */
    
    1028
    +    if ( ( TRUNC( p0.y ) >= ras.max_ey &&
    
    1029
    +           TRUNC( p1.y ) >= ras.max_ey &&
    
    1030
    +           TRUNC( p2.y ) >= ras.max_ey ) ||
    
    1031
    +         ( TRUNC( p0.y ) <  ras.min_ey &&
    
    1032
    +           TRUNC( p1.y ) <  ras.min_ey &&
    
    1033
    +           TRUNC( p2.y ) <  ras.min_ey ) )
    
    1034
    +    {
    
    1035
    +      ras.x = p2.x;
    
    1036
    +      ras.y = p2.y;
    
    1037
    +      return;
    
    1038
    +    }
    
    1039
    +
    
    1040
    +    TPos dx = FT_ABS( p0.x + p2.x - 2 * p1.x );
    
    1041
    +    TPos dy = FT_ABS( p0.y + p2.y - 2 * p1.y );
    
    1042
    +    if ( dx < dy )
    
    1043
    +      dx = dy;
    
    1044
    +
    
    1045
    +    if ( dx <= ONE_PIXEL / 4 )
    
    1046
    +    {
    
    1047
    +      gray_render_line( RAS_VAR_ p2.x, p2.y );
    
    1048
    +      return;
    
    1049
    +    }
    
    1050
    +
    
    1051
    +    /* We can calculate the number of necessary bisections because  */
    
    1052
    +    /* each bisection predictably reduces deviation exactly 4-fold. */
    
    1053
    +    /* Even 32-bit deviation would vanish after 16 bisections.      */
    
    1054
    +    int shift = 0;
    
    1055
    +    do
    
    1056
    +    {
    
    1057
    +      dx   >>= 2;
    
    1058
    +      shift += 1;
    
    1059
    +    }
    
    1060
    +    while (dx > ONE_PIXEL / 4);
    
    1061
    +
    
    1062
    +    /*
    
    1063
    +     * The (P0,P1,P2) arc equation, for t in [0,1] range:
    
    1064
    +     *
    
    1065
    +     * P(t) = P0*(1-t)^2 + P1*2*t*(1-t) + P2*t^2
    
    1066
    +     *
    
    1067
    +     * P(t) = P0 + 2*(P1-P0)*t + (P0+P2-2*P1)*t^2
    
    1068
    +     *      = P0 + 2*B*t + A*t^2
    
    1069
    +     *
    
    1070
    +     *    for A = P0 + P2 - 2*P1
    
    1071
    +     *    and B = P1 - P0
    
    1072
    +     *
    
    1073
    +     * Let's consider the difference when advancing by a small
    
    1074
    +     * parameter h:
    
    1075
    +     *
    
    1076
    +     *    Q(h,t) = P(t+h) - P(t) = 2*B*h + A*h^2 + 2*A*h*t
    
    1077
    +     *
    
    1078
    +     * And then its own difference:
    
    1079
    +     *
    
    1080
    +     *    R(h,t) = Q(h,t+h) - Q(h,t) = 2*A*h*h = R (constant)
    
    1081
    +     *
    
    1082
    +     * Since R is always a constant, it is possible to compute
    
    1083
    +     * successive positions with:
    
    1084
    +     *
    
    1085
    +     *     P = P0
    
    1086
    +     *     Q = Q(h,0) = 2*B*h + A*h*h
    
    1087
    +     *     R = 2*A*h*h
    
    1088
    +     *
    
    1089
    +     *   loop:
    
    1090
    +     *     P += Q
    
    1091
    +     *     Q += R
    
    1092
    +     *     EMIT(P)
    
    1093
    +     *
    
    1094
    +     * To ensure accurate results, perform computations on 64-bit
    
    1095
    +     * values, after scaling them by 2^32:
    
    1096
    +     *
    
    1097
    +     *     R << 32   = 2 * A << (32 - N - N)
    
    1098
    +     *               = A << (33 - 2 *N)
    
    1099
    +     *
    
    1100
    +     *     Q << 32   = (2 * B << (32 - N)) + (A << (32 - N - N))
    
    1101
    +     *               = (B << (33 - N)) + (A << (32 - N - N))
    
    1102
    +     */
    
    1103
    +#ifdef __SSE2__
    
    1104
    +    /* Experience shows that for small shift values, SSE2 is actually slower. */
    
    1105
    +    if (shift > 2) {
    
    1106
    +      union {
    
    1107
    +        struct { FT_Int64 ax, ay, bx, by; } i;
    
    1108
    +        struct { __m128i a, b; } vec;
    
    1109
    +      } u;
    
    1110
    +
    
    1111
    +      u.i.ax = p0.x + p2.x - 2 * p1.x;
    
    1112
    +      u.i.ay = p0.y + p2.y - 2 * p1.y;
    
    1113
    +      u.i.bx = p1.x - p0.x;
    
    1114
    +      u.i.by = p1.y - p0.y;
    
    1115
    +
    
    1116
    +      __m128i a = _mm_load_si128(&u.vec.a);
    
    1117
    +      __m128i b = _mm_load_si128(&u.vec.b);
    
    1118
    +
    
    1119
    +      __m128i r = _mm_slli_epi64(a, 33 - 2 * shift);
    
    1120
    +      __m128i q = _mm_slli_epi64(b, 33 - shift);
    
    1121
    +      __m128i q2 = _mm_slli_epi64(a, 32 - 2 * shift);
    
    1122
    +      q = _mm_add_epi64(q2, q);
    
    1123
    +
    
    1124
    +      union {
    
    1125
    +        struct { FT_Int32  px_lo, px_hi, py_lo, py_hi; } i;
    
    1126
    +        __m128i vec;
    
    1127
    +      } v;
    
    1128
    +      v.i.px_lo = 0;
    
    1129
    +      v.i.px_hi = p0.x;
    
    1130
    +      v.i.py_lo = 0;
    
    1131
    +      v.i.py_hi = p0.y;
    
    1132
    +
    
    1133
    +      __m128i p = _mm_load_si128(&v.vec);
    
    1134
    +
    
    1135
    +      for (unsigned count = (1u << shift); count > 0; count--) {
    
    1136
    +        p = _mm_add_epi64(p, q);
    
    1137
    +        q = _mm_add_epi64(q, r);
    
    1138
    +
    
    1139
    +        _mm_store_si128(&v.vec, p);
    
    1140
    +
    
    1141
    +        gray_render_line( RAS_VAR_ v.i.px_hi, v.i.py_hi);
    
    1142
    +      }
    
    1143
    +      return;
    
    1144
    +    }
    
    1145
    +#endif  /* !__SSE2__ */
    
    1146
    +    FT_Int64 ax = p0.x + p2.x - 2 * p1.x;
    
    1147
    +    FT_Int64 ay = p0.y + p2.y - 2 * p1.y;
    
    1148
    +    FT_Int64 bx = p1.x - p0.x;
    
    1149
    +    FT_Int64 by = p1.y - p0.y;
    
    1150
    +
    
    1151
    +    FT_Int64 rx = ax << (33 - 2 * shift);
    
    1152
    +    FT_Int64 ry = ay << (33 - 2 * shift);
    
    1153
    +
    
    1154
    +    FT_Int64 qx = (bx << (33 - shift)) + (ax << (32 - 2 * shift));
    
    1155
    +    FT_Int64 qy = (by << (33 - shift)) + (ay << (32 - 2 * shift));
    
    1156
    +
    
    1157
    +    FT_Int64 px = (FT_Int64)p0.x << 32;
    
    1158
    +    FT_Int64 py = (FT_Int64)p0.y << 32;
    
    1159
    +
    
    1160
    +	FT_UInt count = 1u << shift;
    
    1161
    +
    
    1162
    +    for (; count > 0; count--) {
    
    1163
    +      px += qx;
    
    1164
    +      py += qy;
    
    1165
    +      qx += rx;
    
    1166
    +      qy += ry;
    
    1167
    +
    
    1168
    +      gray_render_line( RAS_VAR_ (FT_Pos)(px >> 32), (FT_Pos)(py >> 32));
    
    1169
    +    }
    
    1170
    +  }
    
    1171
    +
    
    1172
    +#else  /* !BEZIER_USE_DDA */
    
    1173
    +
    
    1174
    +  /* Note that multiple attempts to speed up the function below
    
    1175
    +   * with SSE2 intrinsics, using various data layouts, have turned
    
    1176
    +   * out to be slower than the non-SIMD code below.
    
    1177
    +   */
    
    977 1178
       static void
    
    978 1179
       gray_split_conic( FT_Vector*  base )
    
    979 1180
       {
    
    ... ... @@ -1059,7 +1260,15 @@ typedef ptrdiff_t FT_PtrDist;
    1059 1260
         } while ( --draw );
    
    1060 1261
       }
    
    1061 1262
     
    
    1263
    +#endif  /* !BEZIER_USE_DDA */
    
    1062 1264
     
    
    1265
    +  /* For cubic bezier, binary splits are still faster than DDA
    
    1266
    +   * because the splits are adaptive to how quickly each sub-arc
    
    1267
    +   * approaches their chord trisection points.
    
    1268
    +   *
    
    1269
    +   * It might be useful to experiment with SSE2 to speed up
    
    1270
    +   * gray_split_cubic() though.
    
    1271
    +   */
    
    1063 1272
       static void
    
    1064 1273
       gray_split_cubic( FT_Vector*  base )
    
    1065 1274
       {
    
    ... ... @@ -1150,7 +1359,6 @@ typedef ptrdiff_t FT_PtrDist;
    1150 1359
         }
    
    1151 1360
       }
    
    1152 1361
     
    
    1153
    -
    
    1154 1362
       static int
    
    1155 1363
       gray_move_to( const FT_Vector*  to,
    
    1156 1364
                     gray_PWorker      worker )
    
    ... ... @@ -1218,7 +1426,7 @@ typedef ptrdiff_t FT_PtrDist;
    1218 1426
           unsigned char*  line = ras.target.origin - ras.target.pitch * y;
    
    1219 1427
     
    
    1220 1428
     
    
    1221
    -      for ( ; cell != NULL; cell = cell->next )
    
    1429
    +      for ( ; !CELL_IS_NULL(cell); cell = cell->next )
    
    1222 1430
           {
    
    1223 1431
             if ( cover != 0 && cell->x > x )
    
    1224 1432
             {
    
    ... ... @@ -1266,7 +1474,7 @@ typedef ptrdiff_t FT_PtrDist;
    1266 1474
           TArea   area;
    
    1267 1475
     
    
    1268 1476
     
    
    1269
    -      for ( ; cell != NULL; cell = cell->next )
    
    1477
    +      for ( ; !CELL_IS_NULL(cell); cell = cell->next )
    
    1270 1478
           {
    
    1271 1479
             if ( cover != 0 && cell->x > x )
    
    1272 1480
             {
    
    ... ... @@ -1646,8 +1854,8 @@ typedef ptrdiff_t FT_PtrDist;
    1646 1854
           FT_TRACE7(( "band [%d..%d]: %ld cell%s\n",
    
    1647 1855
                       ras.min_ey,
    
    1648 1856
                       ras.max_ey,
    
    1649
    -                  ras.num_cells,
    
    1650
    -                  ras.num_cells == 1 ? "" : "s" ));
    
    1857
    +                  ras.cell_free - ras.cells.,
    
    1858
    +                  ras.cell_free - ras.cells == 1 ? "" : "s" ));
    
    1651 1859
         }
    
    1652 1860
         else
    
    1653 1861
         {
    
    ... ... @@ -1690,8 +1898,18 @@ typedef ptrdiff_t FT_PtrDist;
    1690 1898
     
    
    1691 1899
         ras.cells     = buffer + n;
    
    1692 1900
         ras.max_cells = (FT_PtrDist)( FT_MAX_GRAY_POOL - n );
    
    1901
    +    ras.cell_limit = ras.cells + ras.max_cells;
    
    1693 1902
         ras.ycells    = (PCell*)buffer;
    
    1694 1903
     
    
    1904
    +	/* Initialize the null cell is at the start of the 'cells' array. */
    
    1905
    +	/* Note that this requires ras.cell_free initialization to skip   */
    
    1906
    +	/* over the first entry in the array.                             */
    
    1907
    +	PCell null_cell  = NULL_CELL_PTR(ras);
    
    1908
    +	null_cell->x     = CELL_MAX_X_VALUE;
    
    1909
    +	null_cell->area  = 0;
    
    1910
    +	null_cell->cover = 0;
    
    1911
    +	null_cell->next  = NULL;;
    
    1912
    +
    
    1695 1913
         for ( y = yMin; y < yMax; )
    
    1696 1914
         {
    
    1697 1915
           ras.min_ey = y;
    
    ... ... @@ -1705,15 +1923,17 @@ typedef ptrdiff_t FT_PtrDist;
    1705 1923
           do
    
    1706 1924
           {
    
    1707 1925
             TCoord  width = band[0] - band[1];
    
    1926
    +        TCoord  w;
    
    1708 1927
             int     error;
    
    1709 1928
     
    
    1929
    +        for (w = 0; w < width; ++w)
    
    1930
    +          ras.ycells[w] = null_cell;
    
    1710 1931
     
    
    1711
    -        FT_MEM_ZERO( ras.ycells, height * sizeof ( PCell ) );
    
    1712
    -
    
    1713
    -        ras.num_cells = 0;
    
    1714
    -        ras.cell      = NULL;
    
    1932
    +        ras.cell_free = ras.cells + 1;  /* NOTE: Skip over the null cell. */
    
    1933
    +        ras.cell      = null_cell;
    
    1715 1934
             ras.min_ey    = band[1];
    
    1716 1935
             ras.max_ey    = band[0];
    
    1936
    +        ras.count_ey  = width;
    
    1717 1937
     
    
    1718 1938
             error     = gray_convert_glyph_inner( RAS_VAR, continued );
    
    1719 1939
             continued = 1;
    


  • reply via email to

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