diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index faa0cd48a..3592724e1 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -54,17 +54,7 @@ variables: # Make sure meson is up to date so we don't need to rebuild the image # with each release. - pip3 install -U 'meson==0.59.*' - - pip3 install --upgrade certifi - pip3 install -U ninja - - # Generate a UWP cross-file in case it's used - - $PSDefaultParameterValues['Out-File:Encoding'] = 'ASCII' - - echo "[binaries]" > uwp-crossfile.meson - - echo "c = 'cl'" >> uwp-crossfile.meson - - echo "strip = ['true']" >> uwp-crossfile.meson - - echo "[built-in options]" >> uwp-crossfile.meson - - echo "c_args = ['-DWINAPI_FAMILY=WINAPI_FAMILY_APP', '-DUNICODE', '-D_WIN32_WINNT=0x0A00', '-we4013']" >> uwp-crossfile.meson - - echo "c_winlibs = ['windowsapp.lib']" >> uwp-crossfile.meson script: # For some reason, options are separated by newlines instead of spaces, # so we have to replace them first. @@ -75,10 +65,12 @@ variables: # script. Environment variables substitutions is done by PowerShell # before calling `cmd.exe`, that's why we use `$env:FOO` instead of # `%FOO%`. - - cmd.exe /C "C:\BuildTools\Common7\Tools\VsDevCmd.bat -host_arch=amd64 -arch=$env:ARCH $env:VS_UWP && - meson setup build $env:MESON_ARGS_WINDOWS $env:MESON_ARGS_UWP && - meson compile --verbose -C build - $env:MESON_WINDOWS_TESTS" + - cmd.exe /C "C:\BuildTools\Common7\Tools\VsDevCmd.bat -host_arch=amd64 -arch=$env:ARCH && + meson setup build $env:MESON_ARGS_WINDOWS && + meson compile --verbose -C build && + meson test -C build && + meson test -C build --benchmark" + .build windows msbuild: extends: '.build windows common' @@ -106,20 +98,11 @@ windows meson vs2019 amd64: extends: '.build windows meson' variables: ARCH: 'amd64' - MESON_WINDOWS_TESTS: '&& meson test -C build && meson test -C build --benchmark' windows meson vs2019 x86: extends: '.build windows meson' variables: ARCH: 'x86' - MESON_WINDOWS_TESTS: '&& meson test -C build && meson test -C build --benchmark' - -windows meson vs2019 amd64 uwp: - extends: '.build windows meson' - variables: - ARCH: 'amd64' - VS_UWP: '-app_platform=UWP' - MESON_ARGS_UWP: '--cross-file uwp-crossfile.meson -Dc_winlibs="windowsapp.lib"' windows msbuild vs2019 amd64: extends: '.build windows msbuild' diff --git a/.mailmap b/.mailmap index 9c7d08f88..31d2a4766 100644 --- a/.mailmap +++ b/.mailmap @@ -19,7 +19,7 @@ Anurag Thakur (अनुराग ठाकुर) David Turner David Turner Anuj Verma (अनुज वर्मा) -Ben Wagner Bungeman +Ben Wagner Ben Wagner Ben Wagner Nikolaus Waxweiler diff --git a/builds/windows/ftsystem.c b/builds/windows/ftsystem.c index 3a56834f6..477cad71f 100644 --- a/builds/windows/ftsystem.c +++ b/builds/windows/ftsystem.c @@ -196,8 +196,8 @@ } - /* non-desktop Universal Windows Platform */ -#if defined( WINAPI_FAMILY ) && WINAPI_FAMILY != WINAPI_FAMILY_DESKTOP_APP + /* support for Universal Windows Platform UWP, formerly WinRT */ +#ifdef _WINRT_DLL #define PACK_DWORD64( hi, lo ) ( ( (DWORD64)(hi) << 32 ) | (DWORD)(lo) ) @@ -248,10 +248,11 @@ dwCreationDisposition, &createExParams ); } -#endif +#endif /* _WINRT_DLL */ -#if defined( _WIN32_WCE ) + /* support for Windows CE */ +#ifdef _WIN32_WCE /* malloc.h provides implementation of alloca()/_alloca() */ #include @@ -291,9 +292,9 @@ dwFlagsAndAttributes, hTemplateFile ); } -#endif - +#endif /* _WIN32_WCE */ + /* support for really old Windows */ #if defined( _WIN32_WCE ) || defined ( _WIN32_WINDOWS ) || \ !defined( _WIN32_WINNT ) || _WIN32_WINNT <= 0x0400 @@ -311,7 +312,7 @@ return TRUE; } -#endif +#endif /* _WIN32_WCE || _WIN32_WINDOWS || _WIN32_WINNT <= 0x0400 */ /* documentation is in ftobjs.h */ diff --git a/docs/CHANGES b/docs/CHANGES index cbf3cc93a..4c98128f8 100644 --- a/docs/CHANGES +++ b/docs/CHANGES @@ -1,11 +1,21 @@ -CHANGES BETWEEN 2.13.2 and 2.13.3 (202Y-Mmm-DD) +CHANGES BETWEEN 2.13.2 and 2.13.3 (2024-Mmm-DD) - I. IMPORTANT BUG FIXES + I. IMPORTANT CHANGES + + - Some fields in the `FT_Outline` structure have been changed + from signed to unsigned type, which better reflects the actual + usage. It is also an additional means to protect against + malformed input. + + + II. IMPORTANT BUG FIXES + + - Rare double-free crashes in the cache subsystem have been fixed. - Excessive stack allocation in the autohinter has been fixed. - II. MISCELLANEOUS + III. MISCELLANEOUS - The B/W rasterizer has received a major upkeep that resulted in large performance improvement. The rendering speed has increased @@ -21,6 +31,10 @@ CHANGES BETWEEN 2.13.2 and 2.13.3 (202Y-Mmm-DD) Code contributed by David Saltzman . + - The internal structures `PS_DesignMap` and `PS_Blend` related to + parsing of old Multiple Masters fonts have been removed from the + public header file `t1tables.h`. + ====================================================================== diff --git a/include/freetype/freetype.h b/include/freetype/freetype.h index e3a0435ba..b88ccc608 100644 --- a/include/freetype/freetype.h +++ b/include/freetype/freetype.h @@ -3771,87 +3771,18 @@ FT_BEGIN_HEADER * pixels and use the @FT_PIXEL_MODE_LCD_V mode. * * FT_RENDER_MODE_SDF :: - * This mode corresponds to 8-bit, single-channel signed distance field - * (SDF) bitmaps. Each pixel in the SDF grid is the value from the - * pixel's position to the nearest glyph's outline. The distances are - * calculated from the center of the pixel and are positive if they are - * filled by the outline (i.e., inside the outline) and negative - * otherwise. Check the note below on how to convert the output values - * to usable data. + * The positive (unsigned) 8-bit bitmap values can be converted to the + * single-channel signed distance field (SDF) by subtracting 128, with + * the positive and negative results corresponding to the inside and + * the outside of a glyph contour, respectively. The distance units are + * arbitrarily determined by an adjustable @spread property. * * @note: - * The selected render mode only affects vector glyphs of a font. + * The selected render mode only affects scalable vector glyphs of a font. * Embedded bitmaps often have a different pixel mode like * @FT_PIXEL_MODE_MONO. You can use @FT_Bitmap_Convert to transform them * into 8-bit pixmaps. * - * For @FT_RENDER_MODE_SDF the output bitmap buffer contains normalized - * distances that are packed into unsigned 8-bit values. To get pixel - * values in floating point representation use the following pseudo-C - * code for the conversion. - * - * ``` - * // Load glyph and render using FT_RENDER_MODE_SDF, - * // then use the output buffer as follows. - * - * ... - * FT_Byte buffer = glyph->bitmap->buffer; - * - * - * for pixel in buffer - * { - * // `sd` is the signed distance and `spread` is the current spread; - * // the default spread is 2 and can be changed. - * - * float sd = (float)pixel - 128.0f; - * - * - * // Convert to pixel values. - * sd = ( sd / 128.0f ) * spread; - * - * // Store `sd` in a buffer or use as required. - * } - * - * ``` - * - * FreeType has two rasterizers for generating SDF, namely: - * - * 1. `sdf` for generating SDF directly from glyph's outline, and - * - * 2. `bsdf` for generating SDF from rasterized bitmaps. - * - * Depending on the glyph type (i.e., outline or bitmap), one of the two - * rasterizers is chosen at runtime and used for generating SDFs. To - * force the use of `bsdf` you should render the glyph with any of the - * FreeType's other rendering modes (e.g., `FT_RENDER_MODE_NORMAL`) and - * then re-render with `FT_RENDER_MODE_SDF`. - * - * There are some issues with stability and possible failures of the SDF - * renderers (specifically `sdf`). - * - * 1. The `sdf` rasterizer is sensitive to really small features (e.g., - * sharp turns that are less than 1~pixel) and imperfections in the - * glyph's outline, causing artifacts in the final output. - * - * 2. The `sdf` rasterizer has limited support for handling intersecting - * contours and *cannot* handle self-intersecting contours whatsoever. - * Self-intersection happens when a single connected contour - * intersects itself at some point; having these in your font - * definitely poses a problem to the rasterizer and cause artifacts, - * too. - * - * 3. Generating SDF for really small glyphs may result in undesirable - * output; the pixel grid (which stores distance information) becomes - * too coarse. - * - * 4. Since the output buffer is normalized, precision at smaller spreads - * is greater than precision at larger spread values because the - * output range of [0..255] gets mapped to a smaller SDF range. A - * spread of~2 should be sufficient in most cases. - * - * Points (1) and (2) can be avoided by using the `bsdf` rasterizer, - * which is more stable than the `sdf` rasterizer in general. - * */ typedef enum FT_Render_Mode_ { diff --git a/include/freetype/ftdriver.h b/include/freetype/ftdriver.h index baf15a460..dd31626b0 100644 --- a/include/freetype/ftdriver.h +++ b/include/freetype/ftdriver.h @@ -817,6 +817,80 @@ FT_BEGIN_HEADER * 2.5 */ + + /************************************************************************** + * + * @property: + * spread + * + * @description: + * This property of the 'sdf' and 'bsdf' renderers defines how the signed + * distance field (SDF) is represented in the output bitmap. The output + * values are calculated as follows, '128 * ( SDF / spread + 1 )', with + * the result clamped to the 8-bit range [0..255]. Therefore, 'spread' + * is also the maximum euclidean distance from the edge after which the + * values are clamped. The spread is specified in pixels with the + * default value of 8. For accurate SDF texture mapping (interpolation), + * the spread should be large enough to accommodate the target grid unit. + * + * @example: + * The following example code demonstrates how to set the SDF spread + * (omitting the error handling). + * + * ``` + * FT_Library library; + * FT_Int spread = 2; + * + * + * FT_Init_FreeType( &library ); + * + * FT_Property_Set( library, "sdf", "spread", &spread ); + * ``` + * + * @note + * FreeType has two rasterizers for generating SDF, namely: + * + * 1. `sdf` for generating SDF directly from glyph's outline, and + * + * 2. `bsdf` for generating SDF from rasterized bitmaps. + * + * Depending on the glyph type (i.e., outline or bitmap), one of the two + * rasterizers is chosen at runtime and used for generating SDFs. To + * force the use of `bsdf` you should render the glyph with any of the + * FreeType's other rendering modes (e.g., `FT_RENDER_MODE_NORMAL`) and + * then re-render with `FT_RENDER_MODE_SDF`. + * + * There are some issues with stability and possible failures of the SDF + * renderers (specifically `sdf`). + * + * 1. The `sdf` rasterizer is sensitive to really small features (e.g., + * sharp turns that are less than 1~pixel) and imperfections in the + * glyph's outline, causing artifacts in the final output. + * + * 2. The `sdf` rasterizer has limited support for handling intersecting + * contours and *cannot* handle self-intersecting contours whatsoever. + * Self-intersection happens when a single connected contour + * intersects itself at some point; having these in your font + * definitely poses a problem to the rasterizer and cause artifacts, + * too. + * + * 3. Generating SDF for really small glyphs may result in undesirable + * output; the pixel grid (which stores distance information) becomes + * too coarse. + * + * 4. Since the output buffer is normalized, precision at smaller spreads + * is greater than precision at larger spread values because the + * output range of [0..255] gets mapped to a smaller SDF range. A + * spread of~2 should be sufficient in most cases. + * + * Points (1) and (2) can be avoided by using the `bsdf` rasterizer, + * which is more stable than the `sdf` rasterizer in general. + * + * @since: + * 2.11 + */ + + /************************************************************************** * * @property: diff --git a/include/freetype/ftimage.h b/include/freetype/ftimage.h index e90537426..08ef52188 100644 --- a/include/freetype/ftimage.h +++ b/include/freetype/ftimage.h @@ -21,6 +21,10 @@ * Note: A 'raster' is simply a scan-line converter, used to render * `FT_Outline`s into `FT_Bitmap`s. * + * Note: This file can be used for STANDALONE_ compilation of raster (B/W) + * and smooth (anti-aliased) renderers. Therefore, it must rely on + * standard variable types only rather than aliases in fttypes.h. + * */ @@ -342,14 +346,14 @@ FT_BEGIN_HEADER */ typedef struct FT_Outline_ { - short n_contours; /* number of contours in glyph */ - short n_points; /* number of points in the glyph */ + unsigned short n_contours; /* number of contours in glyph */ + unsigned short n_points; /* number of points in the glyph */ - FT_Vector* points; /* the outline's points */ - char* tags; /* the points flags */ - short* contours; /* the contour end points */ + FT_Vector* points; /* the outline's points */ + unsigned char* tags; /* the points flags */ + unsigned short* contours; /* the contour end points */ - int flags; /* outline masks */ + int flags; /* outline masks */ } FT_Outline; @@ -357,8 +361,8 @@ FT_BEGIN_HEADER /* Following limits must be consistent with */ /* FT_Outline.{n_contours,n_points} */ -#define FT_OUTLINE_CONTOURS_MAX SHRT_MAX -#define FT_OUTLINE_POINTS_MAX SHRT_MAX +#define FT_OUTLINE_CONTOURS_MAX USHRT_MAX +#define FT_OUTLINE_POINTS_MAX USHRT_MAX /************************************************************************** diff --git a/include/freetype/ftmm.h b/include/freetype/ftmm.h index a6e3e34fb..35ed039c8 100644 --- a/include/freetype/ftmm.h +++ b/include/freetype/ftmm.h @@ -19,8 +19,13 @@ #ifndef FTMM_H_ #define FTMM_H_ +#include -#include +#ifdef FREETYPE_H +#error "freetype.h of FreeType 1 has been loaded!" +#error "Please fix the directory search order for header files" +#error "so that freetype.h of FreeType 2 is found first." +#endif FT_BEGIN_HEADER @@ -53,6 +58,30 @@ FT_BEGIN_HEADER */ + /************************************************************************** + * + * @enum: + * T1_MAX_MM_XXX + * + * @description: + * Multiple Masters limits as defined in their specifications. + * + * @values: + * T1_MAX_MM_AXIS :: + * The maximum number of Multiple Masters axes. + * + * T1_MAX_MM_DESIGNS :: + * The maximum number of Multiple Masters designs. + * + * T1_MAX_MM_MAP_POINTS :: + * The maximum number of elements in a design map. + * + */ +#define T1_MAX_MM_AXIS 4 +#define T1_MAX_MM_DESIGNS 16 +#define T1_MAX_MM_MAP_POINTS 20 + + /************************************************************************** * * @struct: diff --git a/include/freetype/internal/ftmemory.h b/include/freetype/internal/ftmemory.h index 202cd0a7f..4e05a29f1 100644 --- a/include/freetype/internal/ftmemory.h +++ b/include/freetype/internal/ftmemory.h @@ -371,8 +371,11 @@ extern "C++" #define FT_STRDUP( dst, str ) \ FT_MEM_SET_ERROR( FT_MEM_STRDUP( dst, str ) ) -#define FT_MEM_DUP( dst, address, size ) \ - (dst) = ft_mem_dup( memory, (address), (FT_ULong)(size), &error ) +#define FT_MEM_DUP( dst, address, size ) \ + FT_ASSIGNP_INNER( dst, ft_mem_dup( memory, \ + (address), \ + (FT_ULong)(size), \ + &error ) ) #define FT_DUP( dst, address, size ) \ FT_MEM_SET_ERROR( FT_MEM_DUP( dst, address, size ) ) diff --git a/include/freetype/internal/psaux.h b/include/freetype/internal/psaux.h index 41f481d5a..745d2cb56 100644 --- a/include/freetype/internal/psaux.h +++ b/include/freetype/internal/psaux.h @@ -225,6 +225,7 @@ FT_BEGIN_HEADER typedef enum T1_FieldLocation_ { + T1_FIELD_LOCATION_NONE = 0, T1_FIELD_LOCATION_CID_INFO, T1_FIELD_LOCATION_FONT_DICT, T1_FIELD_LOCATION_FONT_EXTRA, @@ -359,7 +360,12 @@ FT_BEGIN_HEADER #define T1_FIELD_CALLBACK( _ident, _name, _dict ) \ T1_NEW_CALLBACK_FIELD( _ident, _name, _dict ) -#define T1_FIELD_ZERO { 0, NULL, 0, 0, NULL, 0, 0, 0, 0, 0 } +#define T1_FIELD_ZERO \ + { \ + 0, \ + NULL, T1_FIELD_LOCATION_NONE, T1_FIELD_TYPE_NONE, \ + NULL, 0, 0, 0, 0, 0 \ + } /*************************************************************************/ diff --git a/include/freetype/internal/t1types.h b/include/freetype/internal/t1types.h index be63e4dcf..1821ae5cc 100644 --- a/include/freetype/internal/t1types.h +++ b/include/freetype/internal/t1types.h @@ -21,7 +21,7 @@ #define T1TYPES_H_ -#include +#include #include #include #include @@ -137,6 +137,54 @@ FT_BEGIN_HEADER } CID_SubrsRec, *CID_Subrs; + /* this structure is used to store the BlendDesignMap entry for an axis */ + typedef struct PS_DesignMap_ + { + FT_Byte num_points; + FT_Long* design_points; + FT_Fixed* blend_points; + + } PS_DesignMapRec, *PS_DesignMap; + + /* backward compatible definition */ + typedef PS_DesignMapRec T1_DesignMap; + + + typedef struct PS_BlendRec_ + { + FT_UInt num_designs; + FT_UInt num_axis; + + FT_String* axis_names[T1_MAX_MM_AXIS]; + FT_Fixed* design_pos[T1_MAX_MM_DESIGNS]; + PS_DesignMapRec design_map[T1_MAX_MM_AXIS]; + + FT_Fixed* weight_vector; + FT_Fixed* default_weight_vector; + + PS_FontInfo font_infos[T1_MAX_MM_DESIGNS + 1]; + PS_Private privates [T1_MAX_MM_DESIGNS + 1]; + + FT_ULong blend_bitflags; + + FT_BBox* bboxes [T1_MAX_MM_DESIGNS + 1]; + + /* since 2.3.0 */ + + /* undocumented, optional: the default design instance; */ + /* corresponds to default_weight_vector -- */ + /* num_default_design_vector == 0 means it is not present */ + /* in the font and associated metrics files */ + FT_UInt default_design_vector[T1_MAX_MM_DESIGNS]; + FT_UInt num_default_design_vector; + + } PS_BlendRec, *PS_Blend; + + + /* backward compatible definition */ + typedef PS_BlendRec T1_Blend; + + /*************************************************************************/ /*************************************************************************/ /*************************************************************************/ diff --git a/include/freetype/internal/tttypes.h b/include/freetype/internal/tttypes.h index 44a0165cc..7053e656a 100644 --- a/include/freetype/internal/tttypes.h +++ b/include/freetype/internal/tttypes.h @@ -1655,9 +1655,9 @@ FT_BEGIN_HEADER { FT_Memory memory; FT_UShort max_points; - FT_Short max_contours; + FT_UShort max_contours; FT_UShort n_points; /* number of points in zone */ - FT_Short n_contours; /* number of contours */ + FT_UShort n_contours; /* number of contours */ FT_Vector* org; /* original point coordinates */ FT_Vector* cur; /* current point coordinates */ diff --git a/include/freetype/t1tables.h b/include/freetype/t1tables.h index 8a1b10593..fbd558aa3 100644 --- a/include/freetype/t1tables.h +++ b/include/freetype/t1tables.h @@ -269,64 +269,6 @@ FT_BEGIN_HEADER /* */ - /* maximum number of Multiple Masters designs, as defined in the spec */ -#define T1_MAX_MM_DESIGNS 16 - - /* maximum number of Multiple Masters axes, as defined in the spec */ -#define T1_MAX_MM_AXIS 4 - - /* maximum number of elements in a design map */ -#define T1_MAX_MM_MAP_POINTS 20 - - - /* this structure is used to store the BlendDesignMap entry for an axis */ - typedef struct PS_DesignMap_ - { - FT_Byte num_points; - FT_Long* design_points; - FT_Fixed* blend_points; - - } PS_DesignMapRec, *PS_DesignMap; - - /* backward compatible definition */ - typedef PS_DesignMapRec T1_DesignMap; - - - typedef struct PS_BlendRec_ - { - FT_UInt num_designs; - FT_UInt num_axis; - - FT_String* axis_names[T1_MAX_MM_AXIS]; - FT_Fixed* design_pos[T1_MAX_MM_DESIGNS]; - PS_DesignMapRec design_map[T1_MAX_MM_AXIS]; - - FT_Fixed* weight_vector; - FT_Fixed* default_weight_vector; - - PS_FontInfo font_infos[T1_MAX_MM_DESIGNS + 1]; - PS_Private privates [T1_MAX_MM_DESIGNS + 1]; - - FT_ULong blend_bitflags; - - FT_BBox* bboxes [T1_MAX_MM_DESIGNS + 1]; - - /* since 2.3.0 */ - - /* undocumented, optional: the default design instance; */ - /* corresponds to default_weight_vector -- */ - /* num_default_design_vector == 0 means it is not present */ - /* in the font and associated metrics files */ - FT_UInt default_design_vector[T1_MAX_MM_DESIGNS]; - FT_UInt num_default_design_vector; - - } PS_BlendRec, *PS_Blend; - - - /* backward compatible definition */ - typedef PS_BlendRec T1_Blend; - - /************************************************************************** * * @struct: diff --git a/src/autofit/afhints.c b/src/autofit/afhints.c index 27d7bc1a9..96ffe343a 100644 --- a/src/autofit/afhints.c +++ b/src/autofit/afhints.c @@ -979,8 +979,8 @@ /* compute coordinates & Bezier flags, next and prev */ { FT_Vector* vec = outline->points; - char* tag = outline->tags; - FT_Short endpoint = outline->contours[0]; + FT_Byte* tag = outline->tags; + FT_UShort endpoint = outline->contours[0]; AF_Point end = points + endpoint; AF_Point prev = end; FT_Int contour_index = 0; @@ -1046,16 +1046,16 @@ /* set up the contours array */ { - AF_Point* contour = hints->contours; - AF_Point* contour_limit = contour + hints->num_contours; - short* end = outline->contours; - short idx = 0; + AF_Point* contour = hints->contours; + AF_Point* contour_limit = contour + hints->num_contours; + FT_UShort* end = outline->contours; + FT_Int idx = 0; for ( ; contour < contour_limit; contour++, end++ ) { contour[0] = points + idx; - idx = (short)( end[0] + 1 ); + idx = *end + 1; } } @@ -1292,7 +1292,7 @@ AF_Point point = hints->points; AF_Point limit = point + hints->num_points; FT_Vector* vec = outline->points; - char* tag = outline->tags; + FT_Byte* tag = outline->tags; for ( ; point < limit; point++, vec++, tag++ ) diff --git a/src/autofit/aflatin.c b/src/autofit/aflatin.c index 316e7c676..89287f7ea 100644 --- a/src/autofit/aflatin.c +++ b/src/autofit/aflatin.c @@ -1263,10 +1263,9 @@ max_height = FT_MAX( max_height, -Axis->blues[nn].descender ); } - dist = FT_ABS( FT_MulFix( max_height, new_scale - scale ) ); - dist &= ~127; + dist = FT_MulFix( max_height, new_scale - scale ); - if ( dist == 0 ) + if ( -128 < dist && dist < 128 ) { FT_TRACE5(( "af_latin_metrics_scale_dim:" " x height alignment (style `%s'):\n", diff --git a/src/base/ftbbox.c b/src/base/ftbbox.c index e98c29fc7..d6aa5d56d 100644 --- a/src/base/ftbbox.c +++ b/src/base/ftbbox.c @@ -489,7 +489,7 @@ return FT_THROW( Invalid_Outline ); /* if outline is empty, return (0,0,0,0) */ - if ( outline->n_points == 0 || outline->n_contours <= 0 ) + if ( outline->n_points == 0 || outline->n_contours == 0 ) { abbox->xMin = abbox->xMax = 0; abbox->yMin = abbox->yMax = 0; diff --git a/src/base/ftgloadr.c b/src/base/ftgloadr.c index e0c107f47..484d98f17 100644 --- a/src/base/ftgloadr.c +++ b/src/base/ftgloadr.c @@ -355,34 +355,25 @@ FT_BASE_DEF( void ) FT_GlyphLoader_Add( FT_GlyphLoader loader ) { - FT_GlyphLoad base; - FT_GlyphLoad current; - - FT_Int n_curr_contours; - FT_Int n_base_points; - FT_Int n; + FT_Outline* base; + FT_Outline* current; + FT_Int n; if ( !loader ) return; - base = &loader->base; - current = &loader->current; - - n_curr_contours = current->outline.n_contours; - n_base_points = base->outline.n_points; - - base->outline.n_points = - (short)( base->outline.n_points + current->outline.n_points ); - base->outline.n_contours = - (short)( base->outline.n_contours + current->outline.n_contours ); - - base->num_subglyphs += current->num_subglyphs; + base = &loader->base.outline; + current = &loader->current.outline; /* adjust contours count in newest outline */ - for ( n = 0; n < n_curr_contours; n++ ) - current->outline.contours[n] = - (short)( current->outline.contours[n] + n_base_points ); + for ( n = 0; n < current->n_contours; n++ ) + current->contours[n] += base->n_points; + + base->n_points += current->n_points; + base->n_contours += current->n_contours; + + loader->base.num_subglyphs += loader->current.num_subglyphs; /* prepare for another new glyph image */ FT_GlyphLoader_Prepare( loader ); diff --git a/src/base/ftoutln.c b/src/base/ftoutln.c index c7564dbd3..ef699b3c7 100644 --- a/src/base/ftoutln.c +++ b/src/base/ftoutln.c @@ -53,7 +53,7 @@ FT_Vector* point; FT_Vector* limit; - char* tags; + FT_Byte* tags; FT_Error error; @@ -332,8 +332,8 @@ FT_NEW_ARRAY( anoutline->contours, numContours ) ) goto Fail; - anoutline->n_points = (FT_Short)numPoints; - anoutline->n_contours = (FT_Short)numContours; + anoutline->n_points = (FT_UShort)numPoints; + anoutline->n_contours = (FT_UShort)numContours; anoutline->flags |= FT_OUTLINE_OWNER; return FT_Err_Ok; @@ -359,12 +359,14 @@ FT_Int n; + FT_TRACE5(( "FT_Outline_Check: contours = %d, points = %d\n", + n_contours, n_points )); /* empty glyph? */ if ( n_points == 0 && n_contours == 0 ) return FT_Err_Ok; /* check point and contour counts */ - if ( n_points <= 0 || n_contours <= 0 ) + if ( n_points == 0 || n_contours == 0 ) goto Bad; end0 = -1; @@ -576,13 +578,13 @@ /* reverse tags table */ { - char* p = outline->tags + first; - char* q = outline->tags + last; + FT_Byte* p = outline->tags + first; + FT_Byte* q = outline->tags + last; while ( p < q ) { - char swap; + FT_Byte swap; swap = *p; diff --git a/src/base/ftstroke.c b/src/base/ftstroke.c index 443b48aaf..64f46ce43 100644 --- a/src/base/ftstroke.c +++ b/src/base/ftstroke.c @@ -711,7 +711,7 @@ { FT_UInt count = border->num_points; FT_Byte* read = border->tags; - FT_Byte* write = (FT_Byte*)outline->tags + outline->n_points; + FT_Byte* write = outline->tags + outline->n_points; for ( ; count > 0; count--, read++, write++ ) @@ -727,10 +727,10 @@ /* copy contours */ { - FT_UInt count = border->num_points; - FT_Byte* tags = border->tags; - FT_Short* write = outline->contours + outline->n_contours; - FT_Short idx = (FT_Short)outline->n_points; + FT_UInt count = border->num_points; + FT_Byte* tags = border->tags; + FT_UShort* write = outline->contours + outline->n_contours; + FT_UShort idx = outline->n_points; for ( ; count > 0; count--, tags++, idx++ ) @@ -743,7 +743,7 @@ } } - outline->n_points += (short)border->num_points; + outline->n_points += (FT_UShort)border->num_points; FT_ASSERT( FT_Outline_Check( outline ) == 0 ); } @@ -2050,7 +2050,7 @@ FT_Vector* point; FT_Vector* limit; - char* tags; + FT_Byte* tags; FT_Error error; diff --git a/src/bdf/bdflib.c b/src/bdf/bdflib.c index 0fa7e0a8c..813a4d839 100644 --- a/src/bdf/bdflib.c +++ b/src/bdf/bdflib.c @@ -864,15 +864,9 @@ p = font->user_props + font->nuser_props; - n = ft_strlen( name ) + 1; - if ( n > FT_LONG_MAX ) - return FT_THROW( Invalid_Argument ); - - if ( FT_QALLOC( p->name, n ) ) + if ( FT_STRDUP( p->name, name ) ) goto Exit; - FT_MEM_COPY( (char *)p->name, name, n ); - p->format = format; p->builtin = 0; p->value.atom = NULL; /* nothing is ever stored here */ @@ -1442,11 +1436,9 @@ goto Exit; } - if ( FT_QALLOC( p->glyph_name, slen + 1 ) ) + if ( FT_DUP( p->glyph_name, s, slen + 1 ) ) goto Exit; - FT_MEM_COPY( p->glyph_name, s, slen + 1 ); - p->flags |= BDF_GLYPH_; FT_TRACE4(( DBGMSG1, lineno, s )); @@ -2051,9 +2043,8 @@ /* Allowing multiple `FONT' lines (which is invalid) doesn't hurt... */ FT_FREE( p->font->name ); - if ( FT_QALLOC( p->font->name, slen + 1 ) ) + if ( FT_DUP( p->font->name, s, slen + 1 ) ) goto Exit; - FT_MEM_COPY( p->font->name, s, slen + 1 ); /* If the font name is an XLFD name, set the spacing to the one in */ /* the font name. If there is no spacing fall back on the default. */ diff --git a/src/cache/ftcbasic.c b/src/cache/ftcbasic.c index b6e13fd7b..04f664fad 100644 --- a/src/cache/ftcbasic.c +++ b/src/cache/ftcbasic.c @@ -37,7 +37,7 @@ typedef struct FTC_BasicAttrRec_ { FTC_ScalerRec scaler; - FT_UInt load_flags; + FT_Int32 load_flags; } FTC_BasicAttrRec, *FTC_BasicAttrs; @@ -143,10 +143,9 @@ FT_Face face = size->face; - error = FT_Load_Glyph( - face, - gindex, - (FT_Int)family->attrs.load_flags | FT_LOAD_RENDER ); + error = FT_Load_Glyph( face, + gindex, + family->attrs.load_flags | FT_LOAD_RENDER ); if ( !error ) *aface = face; } @@ -176,9 +175,7 @@ { face = size->face; - error = FT_Load_Glyph( face, - gindex, - (FT_Int)family->attrs.load_flags ); + error = FT_Load_Glyph( face, gindex, family->attrs.load_flags ); if ( !error ) { if ( face->glyph->format == FT_GLYPH_FORMAT_BITMAP || @@ -246,7 +243,6 @@ ftc_basic_family_compare, /* FTC_MruNode_CompareFunc node_compare */ ftc_basic_family_init, /* FTC_MruNode_InitFunc node_init */ - NULL, /* FTC_MruNode_ResetFunc node_reset */ NULL /* FTC_MruNode_DoneFunc node_done */ }, @@ -293,40 +289,24 @@ FT_Glyph *aglyph, FTC_Node *anode ) { - FTC_BasicQueryRec query; - FTC_Node node = 0; /* make compiler happy */ FT_Error error; + FTC_BasicQueryRec query; + FTC_Node node = NULL; /* make compiler happy */ FT_Offset hash; - /* some argument checks are delayed to `FTC_Cache_Lookup' */ + /* other argument checks delayed to `FTC_Cache_Lookup' */ if ( !aglyph ) - { - error = FT_THROW( Invalid_Argument ); - goto Exit; - } + return FT_THROW( Invalid_Argument ); *aglyph = NULL; if ( anode ) - *anode = NULL; - - /* - * Internal `FTC_BasicAttr->load_flags' is of type `FT_UInt', - * but public `FT_ImageType->flags' is of type `FT_Int32'. - * - * On 16bit systems, higher bits of type->flags cannot be handled. - */ -#if 0xFFFFFFFFUL > FT_UINT_MAX - if ( (type->flags & (FT_ULong)FT_UINT_MAX) ) - FT_TRACE1(( "FTC_ImageCache_Lookup:" - " higher bits in load_flags 0x%lx are dropped\n", - (FT_ULong)type->flags & ~((FT_ULong)FT_UINT_MAX) )); -#endif + *anode = NULL; query.attrs.scaler.face_id = type->face_id; query.attrs.scaler.width = type->width; query.attrs.scaler.height = type->height; - query.attrs.load_flags = (FT_UInt)type->flags; + query.attrs.load_flags = type->flags; query.attrs.scaler.pixel = 1; query.attrs.scaler.x_res = 0; /* make compilers happy */ @@ -334,7 +314,7 @@ hash = FTC_BASIC_ATTR_HASH( &query.attrs ) + gindex; -#if 1 /* inlining is about 50% faster! */ +#ifdef FTC_INLINE /* inlining is about 50% faster! */ FTC_GCACHE_LOOKUP_CMP( cache, ftc_basic_family_compare, ftc_gnode_compare, @@ -359,7 +339,6 @@ } } - Exit: return error; } @@ -374,38 +353,35 @@ FT_Glyph *aglyph, FTC_Node *anode ) { - FTC_BasicQueryRec query; - FTC_Node node = 0; /* make compiler happy */ FT_Error error; + FTC_BasicQueryRec query; + FTC_Node node = NULL; /* make compiler happy */ FT_Offset hash; - /* some argument checks are delayed to `FTC_Cache_Lookup' */ + /* other argument checks delayed to `FTC_Cache_Lookup' */ if ( !aglyph || !scaler ) - { - error = FT_THROW( Invalid_Argument ); - goto Exit; - } + return FT_THROW( Invalid_Argument ); *aglyph = NULL; if ( anode ) - *anode = NULL; + *anode = NULL; /* - * Internal `FTC_BasicAttr->load_flags' is of type `FT_UInt', + * Internal `FTC_BasicAttr->load_flags' is of type `FT_Int32', * but public `FT_Face->face_flags' is of type `FT_Long'. * * On long > int systems, higher bits of load_flags cannot be handled. */ -#if FT_ULONG_MAX > FT_UINT_MAX - if ( load_flags > FT_UINT_MAX ) +#if FT_ULONG_MAX > 0xFFFFFFFFUL + if ( load_flags > 0xFFFFFFFFUL ) FT_TRACE1(( "FTC_ImageCache_LookupScaler:" " higher bits in load_flags 0x%lx are dropped\n", - load_flags & ~((FT_ULong)FT_UINT_MAX) )); + load_flags & ~0xFFFFFFFFUL )); #endif query.attrs.scaler = scaler[0]; - query.attrs.load_flags = (FT_UInt)load_flags; + query.attrs.load_flags = (FT_Int32)load_flags; hash = FTC_BASIC_ATTR_HASH( &query.attrs ) + gindex; @@ -427,7 +403,6 @@ } } - Exit: return error; } @@ -445,7 +420,6 @@ sizeof ( FTC_BasicFamilyRec ), ftc_basic_family_compare, /* FTC_MruNode_CompareFunc node_compare */ ftc_basic_family_init, /* FTC_MruNode_InitFunc node_init */ - NULL, /* FTC_MruNode_ResetFunc node_reset */ NULL /* FTC_MruNode_DoneFunc node_done */ }, @@ -495,36 +469,22 @@ { FT_Error error; FTC_BasicQueryRec query; - FTC_Node node = 0; /* make compiler happy */ + FTC_Node node = NULL; /* make compiler happy */ FT_Offset hash; - if ( anode ) - *anode = NULL; - /* other argument checks delayed to `FTC_Cache_Lookup' */ if ( !ansbit ) return FT_THROW( Invalid_Argument ); *ansbit = NULL; - - /* - * Internal `FTC_BasicAttr->load_flags' is of type `FT_UInt', - * but public `FT_ImageType->flags' is of type `FT_Int32'. - * - * On 16bit systems, higher bits of type->flags cannot be handled. - */ -#if 0xFFFFFFFFUL > FT_UINT_MAX - if ( (type->flags & (FT_ULong)FT_UINT_MAX) ) - FT_TRACE1(( "FTC_ImageCache_Lookup:" - " higher bits in load_flags 0x%lx are dropped\n", - (FT_ULong)type->flags & ~((FT_ULong)FT_UINT_MAX) )); -#endif + if ( anode ) + *anode = NULL; query.attrs.scaler.face_id = type->face_id; query.attrs.scaler.width = type->width; query.attrs.scaler.height = type->height; - query.attrs.load_flags = (FT_UInt)type->flags; + query.attrs.load_flags = type->flags; query.attrs.scaler.pixel = 1; query.attrs.scaler.x_res = 0; /* make compilers happy */ @@ -534,7 +494,7 @@ hash = FTC_BASIC_ATTR_HASH( &query.attrs ) + gindex / FTC_SBIT_ITEMS_PER_NODE; -#if 1 /* inlining is about 50% faster! */ +#ifdef FTC_INLINE /* inlining is about 50% faster! */ FTC_GCACHE_LOOKUP_CMP( cache, ftc_basic_family_compare, ftc_snode_compare, @@ -578,34 +538,33 @@ { FT_Error error; FTC_BasicQueryRec query; - FTC_Node node = 0; /* make compiler happy */ + FTC_Node node = NULL; /* make compiler happy */ FT_Offset hash; - if ( anode ) - *anode = NULL; - /* other argument checks delayed to `FTC_Cache_Lookup' */ if ( !ansbit || !scaler ) - return FT_THROW( Invalid_Argument ); + return FT_THROW( Invalid_Argument ); *ansbit = NULL; + if ( anode ) + *anode = NULL; /* - * Internal `FTC_BasicAttr->load_flags' is of type `FT_UInt', + * Internal `FTC_BasicAttr->load_flags' is of type `FT_Int32', * but public `FT_Face->face_flags' is of type `FT_Long'. * * On long > int systems, higher bits of load_flags cannot be handled. */ -#if FT_ULONG_MAX > FT_UINT_MAX - if ( load_flags > FT_UINT_MAX ) +#if FT_ULONG_MAX > 0xFFFFFFFFUL + if ( load_flags > 0xFFFFFFFFUL ) FT_TRACE1(( "FTC_ImageCache_LookupScaler:" " higher bits in load_flags 0x%lx are dropped\n", - load_flags & ~((FT_ULong)FT_UINT_MAX) )); + load_flags & ~0xFFFFFFFFUL )); #endif query.attrs.scaler = scaler[0]; - query.attrs.load_flags = (FT_UInt)load_flags; + query.attrs.load_flags = (FT_Int32)load_flags; /* beware, the hash must be the same for all glyph ranges! */ hash = FTC_BASIC_ATTR_HASH( &query.attrs ) + diff --git a/src/cache/ftccache.c b/src/cache/ftccache.c index 33a03486d..8a3d887f9 100644 --- a/src/cache/ftccache.c +++ b/src/cache/ftccache.c @@ -544,7 +544,6 @@ FTC_FaceID face_id ) { FTC_Manager manager = cache->manager; - FTC_Node frees = NULL; FT_UFast count = cache->p; FT_UFast i; @@ -557,41 +556,27 @@ for (;;) { FTC_Node node = *pnode; - FT_Bool list_changed = FALSE; if ( !node ) break; - if ( cache->clazz.node_remove_faceid( node, face_id, - cache, &list_changed ) ) + if ( cache->clazz.node_remove_faceid( node, face_id, cache, NULL ) ) { - *pnode = node->link; - node->link = frees; - frees = node; + *pnode = node->link; + + manager->cur_weight -= cache->clazz.node_weight( node, cache ); + ftc_node_mru_unlink( node, manager ); + + cache->clazz.node_free( node, cache ); + + cache->slack++; } else pnode = &node->link; } } - /* remove all nodes in the free list */ - while ( frees ) - { - FTC_Node node; - - - node = frees; - frees = node->link; - - manager->cur_weight -= cache->clazz.node_weight( node, cache ); - ftc_node_mru_unlink( node, manager ); - - cache->clazz.node_free( node, cache ); - - cache->slack++; - } - ftc_cache_resize( cache ); } diff --git a/src/cache/ftccache.h b/src/cache/ftccache.h index ccbf97980..85d321c12 100644 --- a/src/cache/ftccache.h +++ b/src/cache/ftccache.h @@ -87,6 +87,10 @@ FT_BEGIN_HEADER ftc_get_top_node_for_hash( ( cache ), ( hash ) ) #endif + FT_LOCAL( void ) + ftc_node_destroy( FTC_Node node, + FTC_Manager manager ); + /*************************************************************************/ /*************************************************************************/ diff --git a/src/cache/ftccback.h b/src/cache/ftccback.h index 79ba44ab9..a1d76baa7 100644 --- a/src/cache/ftccback.h +++ b/src/cache/ftccback.h @@ -19,11 +19,7 @@ #define FTCCBACK_H_ #include -#include "ftcmru.h" -#include "ftcimage.h" -#include "ftcmanag.h" -#include "ftcglyph.h" -#include "ftcsbits.h" +#include "ftccache.h" FT_BEGIN_HEADER @@ -81,10 +77,6 @@ FT_BEGIN_HEADER FT_LOCAL( void ) ftc_cache_done( FTC_Cache cache ); - FT_LOCAL( void ) - ftc_node_destroy( FTC_Node node, - FTC_Manager manager ); - FT_END_HEADER #endif /* FTCCBACK_H_ */ diff --git a/src/cache/ftccmap.c b/src/cache/ftccmap.c index 43c507361..b5c61e816 100644 --- a/src/cache/ftccmap.c +++ b/src/cache/ftccmap.c @@ -264,7 +264,7 @@ hash = FTC_CMAP_HASH( face_id, (FT_UInt)cmap_index, char_code ); -#if 1 +#ifdef FTC_INLINE FTC_CACHE_LOOKUP_CMP( cache, ftc_cmap_node_compare, hash, &query, node, error ); #else diff --git a/src/cache/ftcglyph.c b/src/cache/ftcglyph.c index cf7820abd..5e7856378 100644 --- a/src/cache/ftcglyph.c +++ b/src/cache/ftcglyph.c @@ -180,7 +180,7 @@ query->gindex = gindex; - FTC_MRULIST_LOOKUP( &cache->families, query, query->family, error ); + FTC_MRULIST_LOOKUP( &gcache->families, query, query->family, error ); if ( !error ) { FTC_Family family = query->family; @@ -193,7 +193,7 @@ error = FTC_Cache_Lookup( FTC_CACHE( gcache ), hash, query, anode ); if ( --family->num_nodes == 0 ) - FTC_FAMILY_FREE( family, cache ); + FTC_FAMILY_FREE( family, FTC_CACHE( gcache ) ); } return error; } diff --git a/src/cache/ftcglyph.h b/src/cache/ftcglyph.h index 66a1bc77e..b1a96da8e 100644 --- a/src/cache/ftcglyph.h +++ b/src/cache/ftcglyph.h @@ -65,7 +65,6 @@ * - FTC_Family sub-class, e.g. MyFamily, with relevant methods: * my_family_compare * my_family_init - * my_family_reset (optional) * my_family_done * * - FTC_GQuery sub-class, e.g. MyQuery, to hold cache-specific query diff --git a/src/cache/ftcimage.c b/src/cache/ftcimage.c index 56ff80915..146306405 100644 --- a/src/cache/ftcimage.c +++ b/src/cache/ftcimage.c @@ -34,11 +34,7 @@ FT_Memory memory = cache->memory; - if ( inode->glyph ) - { - FT_Done_Glyph( inode->glyph ); - inode->glyph = NULL; - } + FT_Done_Glyph( inode->glyph ); FTC_GNode_Done( FTC_GNODE( inode ), cache ); FT_FREE( inode ); @@ -119,10 +115,9 @@ { case FT_GLYPH_FORMAT_BITMAP: { - FT_BitmapGlyph bitg; + FT_BitmapGlyph bitg = (FT_BitmapGlyph)glyph; - bitg = (FT_BitmapGlyph)glyph; size = bitg->bitmap.rows * (FT_Offset)FT_ABS( bitg->bitmap.pitch ) + sizeof ( *bitg ); } @@ -130,10 +125,9 @@ case FT_GLYPH_FORMAT_OUTLINE: { - FT_OutlineGlyph outg; + FT_OutlineGlyph outg = (FT_OutlineGlyph)glyph; - outg = (FT_OutlineGlyph)glyph; size = (FT_Offset)outg->outline.n_points * ( sizeof ( FT_Vector ) + sizeof ( FT_Byte ) ) + (FT_Offset)outg->outline.n_contours * sizeof ( FT_Short ) + diff --git a/src/cache/ftcmanag.c b/src/cache/ftcmanag.c index dd9bb6190..c0a48a53b 100644 --- a/src/cache/ftcmanag.c +++ b/src/cache/ftcmanag.c @@ -22,7 +22,6 @@ #include #include -#include "ftccback.h" #include "ftcerror.h" @@ -86,12 +85,10 @@ FT_Pointer data ) { FTC_SizeNode node = (FTC_SizeNode)ftcnode; - FT_Size size = node->size; FT_UNUSED( data ); - if ( size ) - FT_Done_Size( size ); + FT_Done_Size( node->size ); } @@ -118,32 +115,21 @@ FT_Pointer ftcscaler, FT_Pointer ftcmanager ) { + FT_Error error; + FT_Size size; FTC_SizeNode node = (FTC_SizeNode)ftcnode; FTC_Scaler scaler = (FTC_Scaler)ftcscaler; FTC_Manager manager = (FTC_Manager)ftcmanager; - node->scaler = scaler[0]; + error = ftc_scaler_lookup_size( manager, scaler, &size ); + if ( !error ) + { + node->size = size; + node->scaler = scaler[0]; + } - return ftc_scaler_lookup_size( manager, scaler, &node->size ); - } - - - FT_CALLBACK_DEF( FT_Error ) - ftc_size_node_reset( FTC_MruNode ftcnode, - FT_Pointer ftcscaler, - FT_Pointer ftcmanager ) - { - FTC_SizeNode node = (FTC_SizeNode)ftcnode; - FTC_Scaler scaler = (FTC_Scaler)ftcscaler; - FTC_Manager manager = (FTC_Manager)ftcmanager; - - - FT_Done_Size( node->size ); - - node->scaler = scaler[0]; - - return ftc_scaler_lookup_size( manager, scaler, &node->size ); + return error; } @@ -154,7 +140,6 @@ ftc_size_node_compare, /* FTC_MruNode_CompareFunc node_compare */ ftc_size_node_init, /* FTC_MruNode_InitFunc node_init */ - ftc_size_node_reset, /* FTC_MruNode_ResetFunc node_reset */ ftc_size_node_done /* FTC_MruNode_DoneFunc node_done */ }; @@ -231,23 +216,25 @@ FT_Pointer ftcface_id, FT_Pointer ftcmanager ) { + FT_Error error; + FT_Face face; FTC_FaceNode node = (FTC_FaceNode)ftcnode; FTC_FaceID face_id = (FTC_FaceID)ftcface_id; FTC_Manager manager = (FTC_Manager)ftcmanager; - FT_Error error; - node->face_id = face_id; - error = manager->request_face( face_id, manager->library, manager->request_data, - &node->face ); + &face ); if ( !error ) { /* destroy initial size object; it will be re-created later */ - if ( node->face->size ) - FT_Done_Size( node->face->size ); + if ( face->size ) + FT_Done_Size( face->size ); + + node->face = face; + node->face_id = face_id; } return error; @@ -294,7 +281,6 @@ ftc_face_node_compare, /* FTC_MruNode_CompareFunc node_compare */ ftc_face_node_init, /* FTC_MruNode_InitFunc node_init */ - NULL, /* FTC_MruNode_ResetFunc node_reset */ ftc_face_node_done /* FTC_MruNode_DoneFunc node_done */ }; @@ -435,18 +421,13 @@ { cache->clazz.cache_done( cache ); FT_FREE( cache ); - manager->caches[idx] = NULL; } } - manager->num_caches = 0; /* discard faces and sizes */ FTC_MruList_Done( &manager->sizes ); FTC_MruList_Done( &manager->faces ); - manager->library = NULL; - manager->memory = NULL; - FT_FREE( manager ); } diff --git a/src/cache/ftcmru.c b/src/cache/ftcmru.c index 7171d4d20..f908eb25a 100644 --- a/src/cache/ftcmru.c +++ b/src/cache/ftcmru.c @@ -238,52 +238,43 @@ { FT_Error error; FTC_MruNode node = NULL; + FTC_MruNode prev = NULL; FT_Memory memory = list->memory; - if ( list->num_nodes >= list->max_nodes && list->max_nodes > 0 ) - { - node = list->nodes->prev; - - FT_ASSERT( node ); - - if ( list->clazz.node_reset ) - { - FTC_MruNode_Up( &list->nodes, node ); - - error = list->clazz.node_reset( node, key, list->data ); - if ( !error ) - goto Exit; - } - - FTC_MruNode_Remove( &list->nodes, node ); - list->num_nodes--; - - if ( list->clazz.node_done ) - list->clazz.node_done( node, list->data ); - } - /* zero new node in case of node_init failure */ - else if ( FT_ALLOC( node, list->clazz.node_size ) ) + if ( FT_ALLOC( node, list->clazz.node_size ) ) goto Exit; error = list->clazz.node_init( node, key, list->data ); if ( error ) - goto Fail; + { + prev = node; + node = NULL; + + goto Clean; + } + else if ( list->max_nodes > 0 && list->num_nodes >= list->max_nodes ) + prev = list->nodes->prev; FTC_MruNode_Prepend( &list->nodes, node ); list->num_nodes++; + if ( !prev ) + goto Exit; + + FTC_MruNode_Remove( &list->nodes, prev ); + list->num_nodes--; + + Clean: + if ( list->clazz.node_done ) + list->clazz.node_done( prev, list->data ); + + FT_FREE( prev ); + Exit: *anode = node; return error; - - Fail: - if ( list->clazz.node_done ) - list->clazz.node_done( node, list->data ); - - FT_FREE( node ); - goto Exit; } @@ -309,18 +300,16 @@ FTC_MruList_Remove( FTC_MruList list, FTC_MruNode node ) { + FT_Memory memory = list->memory; + + FTC_MruNode_Remove( &list->nodes, node ); list->num_nodes--; - { - FT_Memory memory = list->memory; + if ( list->clazz.node_done ) + list->clazz.node_done( node, list->data ); - - if ( list->clazz.node_done ) - list->clazz.node_done( node, list->data ); - - FT_FREE( node ); - } + FT_FREE( node ); } diff --git a/src/cache/ftcmru.h b/src/cache/ftcmru.h index abafea3ae..68faab984 100644 --- a/src/cache/ftcmru.h +++ b/src/cache/ftcmru.h @@ -95,11 +95,6 @@ FT_BEGIN_HEADER FT_Pointer key, FT_Pointer data ); - typedef FT_Error - (*FTC_MruNode_ResetFunc)( FTC_MruNode node, - FT_Pointer key, - FT_Pointer data ); - typedef void (*FTC_MruNode_DoneFunc)( FTC_MruNode node, FT_Pointer data ); @@ -111,7 +106,6 @@ FT_BEGIN_HEADER FTC_MruNode_CompareFunc node_compare; FTC_MruNode_InitFunc node_init; - FTC_MruNode_ResetFunc node_reset; FTC_MruNode_DoneFunc node_done; } FTC_MruListClassRec; diff --git a/src/cache/ftcsbits.c b/src/cache/ftcsbits.c index c8548744b..19f3ef04d 100644 --- a/src/cache/ftcsbits.c +++ b/src/cache/ftcsbits.c @@ -53,8 +53,7 @@ size = (FT_ULong)pitch * bitmap->rows; - if ( !FT_QALLOC( sbit->buffer, size ) ) - FT_MEM_COPY( sbit->buffer, bitmap->buffer, size ); + FT_MEM_DUP( sbit->buffer, bitmap->buffer, size ); return error; } diff --git a/src/cff/cffload.c b/src/cff/cffload.c index a23fa4d12..979fd45f6 100644 --- a/src/cff/cffload.c +++ b/src/cff/cffload.c @@ -1202,17 +1202,21 @@ { CFF_AxisCoords* axis = ®ion->axisList[j]; - FT_Int16 start14, peak14, end14; + FT_Int start, peak, end; - if ( FT_READ_SHORT( start14 ) || - FT_READ_SHORT( peak14 ) || - FT_READ_SHORT( end14 ) ) + if ( FT_READ_SHORT( start ) || + FT_READ_SHORT( peak ) || + FT_READ_SHORT( end ) ) goto Exit; - axis->startCoord = FT_fdot14ToFixed( start14 ); - axis->peakCoord = FT_fdot14ToFixed( peak14 ); - axis->endCoord = FT_fdot14ToFixed( end14 ); + /* immediately tag invalid ranges with special peak = 0 */ + if ( ( start < 0 && end > 0 ) || start > peak || peak > end ) + peak = 0; + + axis->startCoord = FT_fdot14ToFixed( start ); + axis->peakCoord = FT_fdot14ToFixed( peak ); + axis->endCoord = FT_fdot14ToFixed( end ); } } @@ -1495,44 +1499,31 @@ for ( j = 0; j < lenNDV; j++ ) { CFF_AxisCoords* axis = &varRegion->axisList[j]; - FT_Fixed axisScalar; - /* compute the scalar contribution of this axis; */ - /* ignore invalid ranges */ - if ( axis->startCoord > axis->peakCoord || - axis->peakCoord > axis->endCoord ) - axisScalar = FT_FIXED_ONE; - - else if ( axis->startCoord < 0 && - axis->endCoord > 0 && - axis->peakCoord != 0 ) - axisScalar = FT_FIXED_ONE; - - /* peak of 0 means ignore this axis */ - else if ( axis->peakCoord == 0 ) - axisScalar = FT_FIXED_ONE; + /* compute the scalar contribution of this axis */ + /* with peak of 0 used for invalid axes */ + if ( axis->peakCoord == NDV[j] || + axis->peakCoord == 0 ) + continue; /* ignore this region if coords are out of range */ - else if ( NDV[j] < axis->startCoord || - NDV[j] > axis->endCoord ) - axisScalar = 0; - - /* calculate a proportional factor */ - else + else if ( NDV[j] <= axis->startCoord || + NDV[j] >= axis->endCoord ) { - if ( NDV[j] == axis->peakCoord ) - axisScalar = FT_FIXED_ONE; - else if ( NDV[j] < axis->peakCoord ) - axisScalar = FT_DivFix( NDV[j] - axis->startCoord, - axis->peakCoord - axis->startCoord ); - else - axisScalar = FT_DivFix( axis->endCoord - NDV[j], - axis->endCoord - axis->peakCoord ); + blend->BV[master] = 0; + break; } - /* take product of all the axis scalars */ - blend->BV[master] = FT_MulFix( blend->BV[master], axisScalar ); + /* adjust proportionally */ + else if ( NDV[j] < axis->peakCoord ) + blend->BV[master] = FT_MulDiv( blend->BV[master], + NDV[j] - axis->startCoord, + axis->peakCoord - axis->startCoord ); + else /* NDV[j] > axis->peakCoord ) */ + blend->BV[master] = FT_MulDiv( blend->BV[master], + axis->endCoord - NDV[j], + axis->endCoord - axis->peakCoord ); } FT_TRACE4(( ", %f ", diff --git a/src/pfr/pfrgload.c b/src/pfr/pfrgload.c index 6216cf169..e85007552 100644 --- a/src/pfr/pfrgload.c +++ b/src/pfr/pfrgload.c @@ -108,7 +108,7 @@ /* don't add empty contours */ if ( last >= first ) - outline->contours[outline->n_contours++] = (short)last; + outline->contours[outline->n_contours++] = (FT_UShort)last; glyph->path_begun = 0; } @@ -178,8 +178,8 @@ error = FT_GLYPHLOADER_CHECK_POINTS( loader, 3, 0 ); if ( !error ) { - FT_Vector* vec = outline->points + outline->n_points; - FT_Byte* tag = (FT_Byte*)outline->tags + outline->n_points; + FT_Vector* vec = outline->points + outline->n_points; + FT_Byte* tag = outline->tags + outline->n_points; vec[0] = *control1; @@ -189,7 +189,7 @@ tag[1] = FT_CURVE_TAG_CUBIC; tag[2] = FT_CURVE_TAG_ON; - outline->n_points = (FT_Short)( outline->n_points + 3 ); + outline->n_points += 3; } Exit: diff --git a/src/psaux/psobjs.c b/src/psaux/psobjs.c index b251b3596..b361d7077 100644 --- a/src/psaux/psobjs.c +++ b/src/psaux/psobjs.c @@ -1624,7 +1624,7 @@ if ( builder->load_points ) { FT_Vector* point = outline->points + outline->n_points; - FT_Byte* control = (FT_Byte*)outline->tags + outline->n_points; + FT_Byte* control = outline->tags + outline->n_points; point->x = FIXED_TO_INT( x ); @@ -1677,8 +1677,7 @@ if ( !error ) { if ( outline->n_contours > 0 ) - outline->contours[outline->n_contours - 1] = - (short)( outline->n_points - 1 ); + outline->contours[outline->n_contours - 1] = outline->n_points - 1; outline->n_contours++; } @@ -1740,7 +1739,7 @@ { FT_Vector* p1 = outline->points + first; FT_Vector* p2 = outline->points + outline->n_points - 1; - FT_Byte* control = (FT_Byte*)outline->tags + outline->n_points - 1; + FT_Byte* control = outline->tags + outline->n_points - 1; /* `delete' last point only if it coincides with the first */ @@ -1760,8 +1759,7 @@ outline->n_points--; } else - outline->contours[outline->n_contours - 1] = - (short)( outline->n_points - 1 ); + outline->contours[outline->n_contours - 1] = outline->n_points - 1; } } @@ -1899,7 +1897,7 @@ if ( builder->load_points ) { FT_Vector* point = outline->points + outline->n_points; - FT_Byte* control = (FT_Byte*)outline->tags + outline->n_points; + FT_Byte* control = outline->tags + outline->n_points; #ifdef CFF_CONFIG_OPTION_OLD_ENGINE PS_Driver driver = (PS_Driver)FT_FACE_DRIVER( builder->face ); @@ -1959,8 +1957,7 @@ if ( !error ) { if ( outline->n_contours > 0 ) - outline->contours[outline->n_contours - 1] = - (short)( outline->n_points - 1 ); + outline->contours[outline->n_contours - 1] = outline->n_points - 1; outline->n_contours++; } @@ -2019,7 +2016,7 @@ { FT_Vector* p1 = outline->points + first; FT_Vector* p2 = outline->points + outline->n_points - 1; - FT_Byte* control = (FT_Byte*)outline->tags + outline->n_points - 1; + FT_Byte* control = outline->tags + outline->n_points - 1; /* `delete' last point only if it coincides with the first */ @@ -2039,8 +2036,7 @@ outline->n_points--; } else - outline->contours[outline->n_contours - 1] = - (short)( outline->n_points - 1 ); + outline->contours[outline->n_contours - 1] = outline->n_points - 1; } } @@ -2188,7 +2184,7 @@ if ( builder->load_points ) { FT_Vector* point = outline->points + outline->n_points; - FT_Byte* control = (FT_Byte*)outline->tags + outline->n_points; + FT_Byte* control = outline->tags + outline->n_points; #ifdef CFF_CONFIG_OPTION_OLD_ENGINE PS_Driver driver = (PS_Driver)FT_FACE_DRIVER( builder->face ); @@ -2267,8 +2263,7 @@ if ( !error ) { if ( outline->n_contours > 0 ) - outline->contours[outline->n_contours - 1] = - (short)( outline->n_points - 1 ); + outline->contours[outline->n_contours - 1] = outline->n_points - 1; outline->n_contours++; } @@ -2327,7 +2322,7 @@ { FT_Vector* p1 = outline->points + first; FT_Vector* p2 = outline->points + outline->n_points - 1; - FT_Byte* control = (FT_Byte*)outline->tags + outline->n_points - 1; + FT_Byte* control = outline->tags + outline->n_points - 1; /* `delete' last point only if it coincides with the first */ @@ -2347,8 +2342,7 @@ outline->n_points--; } else - outline->contours[outline->n_contours - 1] = - (short)( outline->n_points - 1 ); + outline->contours[outline->n_contours - 1] = outline->n_points - 1; } } diff --git a/src/pshinter/pshalgo.c b/src/pshinter/pshalgo.c index 2d7b9c227..967767b34 100644 --- a/src/pshinter/pshalgo.c +++ b/src/pshinter/pshalgo.c @@ -1118,7 +1118,7 @@ FT_UInt n; PSH_Point point = glyph->points; FT_Vector* vec = glyph->outline->points; - char* tags = glyph->outline->tags; + FT_Byte* tags = glyph->outline->tags; for ( n = 0; n < glyph->num_points; n++ ) @@ -1171,8 +1171,8 @@ FT_QNEW_ARRAY( glyph->contours, outline->n_contours ) ) goto Exit; - glyph->num_points = (FT_UInt)outline->n_points; - glyph->num_contours = (FT_UInt)outline->n_contours; + glyph->num_points = outline->n_points; + glyph->num_contours = outline->n_contours; { FT_UInt first = 0, next, n; @@ -1186,7 +1186,7 @@ PSH_Point point; - next = (FT_UInt)outline->contours[n] + 1; + next = outline->contours[n] + 1; count = next - first; contour->start = points + first; diff --git a/src/pshinter/pshrec.c b/src/pshinter/pshrec.c index b10c70ec9..0b2b549fc 100644 --- a/src/pshinter/pshrec.c +++ b/src/pshinter/pshrec.c @@ -806,7 +806,7 @@ ps_hints_stem( PS_Hints hints, FT_UInt dimension, FT_Int count, - FT_Long* stems ) + FT_Pos* stems ) { PS_Dimension dim; diff --git a/src/raster/ftraster.c b/src/raster/ftraster.c index 51ad66b60..e4b7b937d 100644 --- a/src/raster/ftraster.c +++ b/src/raster/ftraster.c @@ -1598,7 +1598,7 @@ FT_Vector* points; FT_Vector* point; FT_Vector* limit; - char* tags; + FT_Byte* tags; UInt tag; /* current point's state */ @@ -2683,7 +2683,7 @@ return FT_THROW( Invalid_Outline ); /* return immediately if the outline is empty */ - if ( outline->n_points == 0 || outline->n_contours <= 0 ) + if ( outline->n_points == 0 || outline->n_contours == 0 ) return Raster_Err_Ok; if ( !outline->contours || !outline->points ) diff --git a/src/sdf/ftsdf.c b/src/sdf/ftsdf.c index 4394001e2..dc55d4263 100644 --- a/src/sdf/ftsdf.c +++ b/src/sdf/ftsdf.c @@ -3837,7 +3837,7 @@ } /* if the outline is empty, return */ - if ( outline->n_points <= 0 || outline->n_contours <= 0 ) + if ( outline->n_points == 0 || outline->n_contours == 0 ) goto Exit; /* check whether the outline has valid fields */ diff --git a/src/sdf/ftsdfcommon.c b/src/sdf/ftsdfcommon.c index 5841ded21..6b2cf7dfe 100644 --- a/src/sdf/ftsdfcommon.c +++ b/src/sdf/ftsdfcommon.c @@ -22,49 +22,6 @@ #include "ftsdfcommon.h" - /************************************************************************** - * - * common functions - * - */ - - /* - * Original algorithm: - * - * https://github.com/chmike/fpsqrt - * - * Use this to compute the square root of a 16.16 fixed-point number. - */ - FT_LOCAL_DEF( FT_16D16 ) - square_root( FT_16D16 val ) - { - FT_ULong t, q, b, r; - - - r = (FT_ULong)val; - b = 0x40000000L; - q = 0; - - while ( b > 0x40L ) - { - t = q + b; - - if ( r >= t ) - { - r -= t; - q = t + b; - } - - r <<= 1; - b >>= 1; - } - - q >>= 8; - - return (FT_16D16)q; - } - - /************************************************************************** * * format and sign manipulating functions diff --git a/src/sdf/ftsdfcommon.h b/src/sdf/ftsdfcommon.h index 44274e349..d0f623f9f 100644 --- a/src/sdf/ftsdfcommon.h +++ b/src/sdf/ftsdfcommon.h @@ -122,8 +122,7 @@ FT_BEGIN_HEADER typedef FT_BBox FT_CBox; /* control box of a curve */ - FT_LOCAL( FT_16D16 ) - square_root( FT_16D16 val ); +#define square_root( x ) (FT_16D16)FT_SqrtFixed( (FT_UInt32)( x ) ) FT_LOCAL( FT_SDFFormat ) map_fixed_to_sdf( FT_16D16 dist, diff --git a/src/sfnt/sfwoff.c b/src/sfnt/sfwoff.c index 8d33b7133..14514bf95 100644 --- a/src/sfnt/sfwoff.c +++ b/src/sfnt/sfwoff.c @@ -18,6 +18,7 @@ #include "sfwoff.h" #include +#include #include #include #include @@ -149,6 +150,7 @@ /* Miscellaneous checks. */ if ( woff.length != stream->size || woff.num_tables == 0 || + woff.num_tables > 0xFFFU || 44 + woff.num_tables * 20UL >= woff.length || 12 + woff.num_tables * 16UL >= woff.totalSfntSize || ( woff.totalSfntSize & 3 ) != 0 || @@ -169,21 +171,11 @@ /* Write sfnt header. */ { - FT_UInt searchRange, entrySelector, rangeShift, x; + FT_Int entrySelector = FT_MSB( woff.num_tables ); + FT_Int searchRange = ( 1 << entrySelector ) * 16; + FT_Int rangeShift = woff.num_tables * 16 - searchRange; - x = woff.num_tables; - entrySelector = 0; - while ( x ) - { - x >>= 1; - entrySelector += 1; - } - entrySelector--; - - searchRange = ( 1 << entrySelector ) * 16; - rangeShift = woff.num_tables * 16 - searchRange; - WRITE_ULONG ( sfnt_header, woff.flavor ); WRITE_USHORT( sfnt_header, woff.num_tables ); WRITE_USHORT( sfnt_header, searchRange ); diff --git a/src/sfnt/sfwoff2.c b/src/sfnt/sfwoff2.c index f3c9e2854..589b3e0c6 100644 --- a/src/sfnt/sfwoff2.c +++ b/src/sfnt/sfwoff2.c @@ -18,6 +18,7 @@ #include "sfwoff2.h" #include "woff2tags.h" #include +#include #include #include @@ -289,23 +290,15 @@ FT_ULong checksum = 0; FT_ULong aligned_size = size & ~3UL; FT_ULong i; - FT_ULong v; + FT_Int shift; for ( i = 0; i < aligned_size; i += 4 ) - checksum += ( (FT_ULong)buf[i ] << 24 ) | - ( (FT_ULong)buf[i + 1] << 16 ) | - ( (FT_ULong)buf[i + 2] << 8 ) | - ( (FT_ULong)buf[i + 3] << 0 ); + checksum += FT_NEXT_ULONG( buf ); - /* If size is not aligned to 4, treat as if it is padded with 0s. */ - if ( size != aligned_size ) - { - v = 0; - for ( i = aligned_size ; i < size; ++i ) - v |= (FT_ULong)buf[i] << ( 24 - 8 * ( i & 3 ) ); - checksum += v; - } + /* remaining bytes can be shifted and added one at a time */ + for ( shift = 24; i < size; i++, shift -= 8 ) + checksum += (FT_UInt32)FT_NEXT_BYTE( buf ) << shift; return checksum; } @@ -1799,7 +1792,6 @@ FT_Byte* sfnt = NULL; FT_Stream sfnt_stream = NULL; - FT_Byte* sfnt_header; FT_ULong sfnt_size; FT_Byte* uncompressed_buf = NULL; @@ -1853,6 +1845,7 @@ /* Miscellaneous checks. */ if ( woff2.length != stream->size || woff2.num_tables == 0 || + woff2.num_tables > 0xFFFU || 48 + woff2.num_tables * 20UL >= woff2.length || ( woff2.metaOffset == 0 && ( woff2.metaLength != 0 || woff2.metaOrigLength != 0 ) ) || @@ -2143,6 +2136,13 @@ WOFF2_TtcFont ttc_font = woff2.ttc_fonts + face_index; + if ( ttc_font->num_tables == 0 || ttc_font->num_tables > 0xFFFU ) + { + FT_ERROR(( "woff2_open_font: invalid WOFF2 CollectionFontEntry\n" )); + error = FT_THROW( Invalid_Table ); + goto Exit; + } + /* Create a temporary array. */ if ( FT_QNEW_ARRAY( temp_indices, ttc_font->num_tables ) ) @@ -2198,27 +2198,15 @@ FT_NEW( sfnt_stream ) ) goto Exit; - sfnt_header = sfnt; - - WRITE_ULONG( sfnt_header, woff2.flavor ); - - if ( woff2.num_tables ) { - FT_UInt searchRange, entrySelector, rangeShift, x; + FT_Byte* sfnt_header = sfnt; + + FT_Int entrySelector = FT_MSB( woff2.num_tables ); + FT_Int searchRange = ( 1 << entrySelector ) * 16; + FT_Int rangeShift = woff2.num_tables * 16 - searchRange; - x = woff2.num_tables; - entrySelector = 0; - while ( x ) - { - x >>= 1; - entrySelector += 1; - } - entrySelector--; - - searchRange = ( 1 << entrySelector ) * 16; - rangeShift = ( woff2.num_tables * 16 ) - searchRange; - + WRITE_ULONG ( sfnt_header, woff2.flavor ); WRITE_USHORT( sfnt_header, woff2.num_tables ); WRITE_USHORT( sfnt_header, searchRange ); WRITE_USHORT( sfnt_header, entrySelector ); diff --git a/src/sfnt/ttcolr.c b/src/sfnt/ttcolr.c index 1c3fd70d0..b37658dde 100644 --- a/src/sfnt/ttcolr.c +++ b/src/sfnt/ttcolr.c @@ -208,18 +208,19 @@ colr->num_base_glyphs = FT_NEXT_USHORT( p ); base_glyph_offset = FT_NEXT_ULONG( p ); - if ( base_glyph_offset >= table_size ) + if ( table_size <= base_glyph_offset ) goto InvalidTable; - if ( colr->num_base_glyphs * BASE_GLYPH_SIZE > - table_size - base_glyph_offset ) + if ( ( table_size - base_glyph_offset ) / BASE_GLYPH_SIZE + < colr->num_base_glyphs ) goto InvalidTable; layer_offset = FT_NEXT_ULONG( p ); colr->num_layers = FT_NEXT_USHORT( p ); - if ( layer_offset >= table_size ) + if ( table_size <= layer_offset ) goto InvalidTable; - if ( colr->num_layers * LAYER_SIZE > table_size - layer_offset ) + if ( ( table_size - layer_offset ) / LAYER_SIZE + < colr->num_layers ) goto InvalidTable; if ( colr->version == 1 ) @@ -229,14 +230,14 @@ base_glyphs_offset_v1 = FT_NEXT_ULONG( p ); - if ( base_glyphs_offset_v1 >= table_size - 4 ) + if ( table_size - 4 <= base_glyphs_offset_v1 ) goto InvalidTable; p1 = (FT_Byte*)( table + base_glyphs_offset_v1 ); num_base_glyphs_v1 = FT_PEEK_ULONG( p1 ); - if ( num_base_glyphs_v1 * BASE_GLYPH_PAINT_RECORD_SIZE > - table_size - base_glyphs_offset_v1 ) + if ( ( table_size - base_glyphs_offset_v1 ) / BASE_GLYPH_PAINT_RECORD_SIZE + < num_base_glyphs_v1 ) goto InvalidTable; colr->num_base_glyphs_v1 = num_base_glyphs_v1; @@ -244,19 +245,19 @@ layer_offset_v1 = FT_NEXT_ULONG( p ); - if ( layer_offset_v1 >= table_size ) + if ( table_size <= layer_offset_v1 ) goto InvalidTable; if ( layer_offset_v1 ) { - if ( layer_offset_v1 >= table_size - 4 ) + if ( table_size - 4 <= layer_offset_v1 ) goto InvalidTable; p1 = (FT_Byte*)( table + layer_offset_v1 ); num_layers_v1 = FT_PEEK_ULONG( p1 ); - if ( num_layers_v1 * LAYER_V1_LIST_PAINT_OFFSET_SIZE > - table_size - layer_offset_v1 ) + if ( ( table_size - layer_offset_v1 ) / LAYER_V1_LIST_PAINT_OFFSET_SIZE + < num_layers_v1 ) goto InvalidTable; colr->num_layers_v1 = num_layers_v1; @@ -279,7 +280,7 @@ clip_list_offset = FT_NEXT_ULONG( p ); - if ( clip_list_offset >= table_size ) + if ( table_size <= clip_list_offset ) goto InvalidTable; if ( clip_list_offset ) @@ -311,7 +312,7 @@ goto InvalidTable; var_store_offset = FT_NEXT_ULONG( p ); - if ( var_store_offset >= table_size ) + if ( table_size <= var_store_offset ) goto InvalidTable; if ( var_store_offset ) @@ -1270,7 +1271,6 @@ static FT_Bool find_base_glyph_v1_record( FT_Byte * base_glyph_begin, FT_UInt num_base_glyph, - FT_Byte * end_colr, FT_UInt glyph_id, BaseGlyphV1Record *record ) { @@ -1290,14 +1290,6 @@ */ FT_Byte *p = base_glyph_begin + 4 + mid * BASE_GLYPH_PAINT_RECORD_SIZE; - - /* We need to be able to read 2 bytes (FT_NEXT_USHORT) for the glyph */ - /* ID, then 4 bytes (FT_NEXT_ULONG) for the paint offset. If that's */ - /* not available before the end of the table, something's wrong with */ - /* the font and we can't find a COLRv1 glyph. */ - if ( p > end_colr - 2 - 4 ) - return 0; - gid = FT_NEXT_USHORT( p ); if ( gid < glyph_id ) @@ -1338,7 +1330,6 @@ if ( !find_base_glyph_v1_record( colr->base_glyphs_v1, colr->num_base_glyphs_v1, - (FT_Byte*)colr->table + colr->table_size, base_glyph, &base_glyph_v1_record ) ) return 0; diff --git a/src/smooth/ftgrays.c b/src/smooth/ftgrays.c index 576e837dc..b7c0632a6 100644 --- a/src/smooth/ftgrays.c +++ b/src/smooth/ftgrays.c @@ -489,7 +489,7 @@ typedef ptrdiff_t FT_PtrDist; typedef struct gray_TWorker_ { - ft_jmp_buf jump_buffer; + FT_BBox cbox; TCoord min_ex, max_ex; /* min and max integer pixel coordinates */ TCoord min_ey, max_ey; @@ -510,6 +510,8 @@ typedef ptrdiff_t FT_PtrDist; FT_Raster_Span_Func render_span; void* render_span_data; + ft_jmp_buf jump_buffer; + } gray_TWorker, *gray_PWorker; #if defined( _MSC_VER ) @@ -1863,11 +1865,8 @@ typedef ptrdiff_t FT_PtrDist; static int gray_convert_glyph( RAS_ARG ) { - const TCoord yMin = ras.min_ey; - const TCoord yMax = ras.max_ey; - TCell buffer[FT_MAX_GRAY_POOL]; - size_t height = (size_t)( yMax - yMin ); + size_t height = (size_t)( ras.cbox.yMax - ras.cbox.yMin ); size_t n = FT_MAX_GRAY_POOL / 8; TCoord y; TCoord bands[32]; /* enough to accommodate bisections */ @@ -1893,35 +1892,36 @@ typedef ptrdiff_t FT_PtrDist; height = ( height + n - 1 ) / n; } - for ( y = yMin; y < yMax; ) + for ( y = ras.cbox.yMin; y < ras.cbox.yMax; ) { ras.min_ey = y; y += height; - ras.max_ey = FT_MIN( y, yMax ); + ras.max_ey = FT_MIN( y, ras.cbox.yMax ); + + ras.count_ey = ras.max_ey - ras.min_ey; band = bands; - band[1] = ras.min_ey; - band[0] = ras.max_ey; + band[1] = ras.cbox.xMin; + band[0] = ras.cbox.xMax; do { - TCoord width = band[0] - band[1]; - TCoord w; + TCoord i; int error; - for ( w = 0; w < width; ++w ) - ras.ycells[w] = ras.cell_null; + ras.min_ex = band[1]; + ras.max_ex = band[0]; - /* memory management: skip ycells */ - n = ( (size_t)width * sizeof ( PCell ) + sizeof ( TCell ) - 1 ) / - sizeof ( TCell ); + /* memory management: zero out and skip ycells */ + for ( i = 0; i < ras.count_ey; ++i ) + ras.ycells[i] = ras.cell_null; + + n = ( (size_t)ras.count_ey * sizeof ( PCell ) + sizeof ( TCell ) - 1 ) + / sizeof ( TCell ); ras.cell_free = buffer + n; ras.cell = ras.cell_null; - ras.min_ey = band[1]; - ras.max_ey = band[0]; - ras.count_ey = width; error = gray_convert_glyph_inner( RAS_VAR_ continued ); continued = 1; @@ -1939,10 +1939,10 @@ typedef ptrdiff_t FT_PtrDist; return error; /* render pool overflow; we will reduce the render band by half */ - width >>= 1; + i = ( band[0] - band[1] ) >> 1; /* this should never happen even with tiny rendering pool */ - if ( width == 0 ) + if ( i == 0 ) { FT_TRACE7(( "gray_convert_glyph: rotten glyph\n" )); return FT_THROW( Raster_Overflow ); @@ -1950,7 +1950,7 @@ typedef ptrdiff_t FT_PtrDist; band++; band[1] = band[0]; - band[0] += width; + band[0] += i; } while ( band >= bands ); } @@ -1981,7 +1981,7 @@ typedef ptrdiff_t FT_PtrDist; return FT_THROW( Invalid_Outline ); /* return immediately if the outline is empty */ - if ( outline->n_points == 0 || outline->n_contours <= 0 ) + if ( outline->n_points == 0 || outline->n_contours == 0 ) return Smooth_Err_Ok; if ( !outline->contours || !outline->points ) @@ -2001,10 +2001,7 @@ typedef ptrdiff_t FT_PtrDist; ras.render_span = (FT_Raster_Span_Func)params->gray_spans; ras.render_span_data = params->user; - ras.min_ex = params->clip_box.xMin; - ras.min_ey = params->clip_box.yMin; - ras.max_ex = params->clip_box.xMax; - ras.max_ey = params->clip_box.yMax; + ras.cbox = params->clip_box; } else { @@ -2030,14 +2027,14 @@ typedef ptrdiff_t FT_PtrDist; ras.render_span = (FT_Raster_Span_Func)NULL; ras.render_span_data = NULL; - ras.min_ex = 0; - ras.min_ey = 0; - ras.max_ex = (FT_Pos)target_map->width; - ras.max_ey = (FT_Pos)target_map->rows; + ras.cbox.xMin = 0; + ras.cbox.yMin = 0; + ras.cbox.xMax = (FT_Pos)target_map->width; + ras.cbox.yMax = (FT_Pos)target_map->rows; } /* exit if nothing to do */ - if ( ras.max_ex <= ras.min_ex || ras.max_ey <= ras.min_ey ) + if ( ras.cbox.xMin >= ras.cbox.xMax || ras.cbox.yMin >= ras.cbox.yMax ) return Smooth_Err_Ok; return gray_convert_glyph( RAS_VAR ); diff --git a/src/truetype/ttgload.c b/src/truetype/ttgload.c index df803a0f3..8cddc394c 100644 --- a/src/truetype/ttgload.c +++ b/src/truetype/ttgload.c @@ -353,7 +353,8 @@ FT_Byte c, count; FT_Vector *vec, *vec_limit; FT_Pos x, y; - FT_Short *cont, *cont_limit, last; + FT_UShort *cont, *cont_limit; + FT_Int last; /* check that we can add the contours to the glyph */ @@ -372,7 +373,7 @@ last = -1; for ( ; cont < cont_limit; cont++ ) { - *cont = FT_NEXT_SHORT( p ); + *cont = FT_NEXT_USHORT( p ); if ( *cont <= last ) goto Invalid_Outline; @@ -418,11 +419,9 @@ /* and thus allocate the bytecode array size by ourselves */ if ( n_ins ) { - if ( FT_QNEW_ARRAY( exec->glyphIns, n_ins ) ) + if ( FT_DUP( exec->glyphIns, p, n_ins ) ) return error; - FT_MEM_COPY( exec->glyphIns, p, (FT_Long)n_ins ); - exec->glyphSize = n_ins; } } @@ -432,7 +431,7 @@ p += n_ins; /* reading the point tags */ - flag = (FT_Byte*)outline->tags; + flag = outline->tags; flag_limit = flag + n_points; FT_ASSERT( flag ); @@ -465,7 +464,7 @@ vec = outline->points; vec_limit = vec + n_points; - flag = (FT_Byte*)outline->tags; + flag = outline->tags; x = 0; for ( ; vec < vec_limit; vec++, flag++ ) @@ -499,7 +498,7 @@ vec = outline->points; vec_limit = vec + n_points; - flag = (FT_Byte*)outline->tags; + flag = outline->tags; y = 0; for ( ; vec < vec_limit; vec++, flag++ ) @@ -532,8 +531,8 @@ *flag = (FT_Byte)( f & ON_CURVE_POINT ); } - outline->n_points = (FT_Short)n_points; - outline->n_contours = (FT_Short)n_contours; + outline->n_points = (FT_UShort)n_points; + outline->n_contours = (FT_UShort)n_contours; load->cursor = p; @@ -754,15 +753,13 @@ FT_UInt start_point, FT_UInt start_contour ) { - zone->n_points = (FT_UShort)load->outline.n_points + 4 - - (FT_UShort)start_point; - zone->n_contours = load->outline.n_contours - - (FT_Short)start_contour; + zone->n_points = load->outline.n_points + 4 - (FT_UShort)start_point; + zone->n_contours = load->outline.n_contours - (FT_UShort)start_contour; zone->org = load->extra_points + start_point; zone->cur = load->outline.points + start_point; zone->orus = load->extra_points2 + start_point; - zone->tags = (FT_Byte*)load->outline.tags + start_point; - zone->contours = (FT_UShort*)load->outline.contours + start_contour; + zone->tags = load->outline.tags + start_point; + zone->contours = load->outline.contours + start_contour; zone->first_point = (FT_UShort)start_point; } @@ -1046,7 +1043,7 @@ current.points = gloader->base.outline.points + num_base_points; current.n_points = gloader->base.outline.n_points - - (short)num_base_points; + (FT_UShort)num_base_points; have_scale = FT_BOOL( subglyph->flags & ( WE_HAVE_A_SCALE | WE_HAVE_AN_XY_SCALE | @@ -1059,7 +1056,7 @@ /* get offset */ if ( !( subglyph->flags & ARGS_ARE_XY_VALUES ) ) { - FT_UInt num_points = (FT_UInt)gloader->base.outline.n_points; + FT_UInt num_points = gloader->base.outline.n_points; FT_UInt k = (FT_UInt)subglyph->arg1; FT_UInt l = (FT_UInt)subglyph->arg2; FT_Vector* p1; @@ -1721,8 +1718,8 @@ FT_List_Add( &loader->composites, node ); } - start_point = (FT_UInt)gloader->base.outline.n_points; - start_contour = (FT_UInt)gloader->base.outline.n_contours; + start_point = gloader->base.outline.n_points; + start_contour = gloader->base.outline.n_contours; /* for each subglyph, read composite header */ error = face->read_composite_glyph( loader ); @@ -1874,7 +1871,7 @@ linear_hadvance = loader->linear; linear_vadvance = loader->vadvance; - num_base_points = (FT_UInt)gloader->base.outline.n_points; + num_base_points = gloader->base.outline.n_points; error = load_truetype_glyph( loader, (FT_UInt)subglyph->index, @@ -1898,7 +1895,7 @@ loader->vadvance = linear_vadvance; } - num_points = (FT_UInt)gloader->base.outline.n_points; + num_points = gloader->base.outline.n_points; if ( num_points == num_base_points ) continue; @@ -2719,7 +2716,7 @@ size->metrics->y_ppem < 24 ) glyph->outline.flags |= FT_OUTLINE_HIGH_PRECISION; - FT_TRACE1(( " subglyphs = %u, contours = %hd, points = %hd," + FT_TRACE1(( " subglyphs = %u, contours = %hu, points = %hu," " flags = 0x%.3x\n", loader.gloader->base.num_subglyphs, glyph->outline.n_contours, diff --git a/src/truetype/ttgxvar.c b/src/truetype/ttgxvar.c index 7b33b8e52..095a72055 100644 --- a/src/truetype/ttgxvar.c +++ b/src/truetype/ttgxvar.c @@ -596,7 +596,7 @@ for ( j = 0; j < itemStore->axisCount; j++ ) { - FT_Short start, peak, end; + FT_Int start, peak, end; if ( FT_READ_SHORT( start ) || @@ -604,6 +604,10 @@ FT_READ_SHORT( end ) ) goto Exit; + /* immediately tag invalid ranges with special peak = 0 */ + if ( ( start < 0 && end > 0 ) || start > peak || peak > end ) + peak = 0; + axisCoords[j].startCoord = FT_fdot14ToFixed( start ); axisCoords[j].peakCoord = FT_fdot14ToFixed( peak ); axisCoords[j].endCoord = FT_fdot14ToFixed( end ); @@ -1024,6 +1028,9 @@ if ( innerIndex >= varData->itemCount ) return 0; /* Out of range. */ + if ( varData->regionIdxCount == 0 ) + return 0; /* Avoid "applying zero offset to null pointer". */ + if ( varData->regionIdxCount < 16 ) { deltaSet = deltaSetStack; @@ -1074,43 +1081,32 @@ /* inner loop steps through axes in this region */ for ( j = 0; j < itemStore->axisCount; j++, axis++ ) { - /* compute the scalar contribution of this axis; */ - /* ignore invalid ranges */ - if ( axis->startCoord > axis->peakCoord || - axis->peakCoord > axis->endCoord ) - continue; + FT_Fixed ncv = ttface->blend->normalizedcoords[j]; - else if ( axis->startCoord < 0 && - axis->endCoord > 0 && - axis->peakCoord != 0 ) - continue; - /* peak of 0 means ignore this axis */ - else if ( axis->peakCoord == 0 ) - continue; - - else if ( ttface->blend->normalizedcoords[j] == axis->peakCoord ) + /* compute the scalar contribution of this axis */ + /* with peak of 0 used for invalid axes */ + if ( axis->peakCoord == ncv || + axis->peakCoord == 0 ) continue; /* ignore this region if coords are out of range */ - else if ( ttface->blend->normalizedcoords[j] <= axis->startCoord || - ttface->blend->normalizedcoords[j] >= axis->endCoord ) + else if ( ncv <= axis->startCoord || + ncv >= axis->endCoord ) { scalar = 0; break; } /* cumulative product of all the axis scalars */ - else if ( ttface->blend->normalizedcoords[j] < axis->peakCoord ) - scalar = - FT_MulDiv( scalar, - ttface->blend->normalizedcoords[j] - axis->startCoord, - axis->peakCoord - axis->startCoord ); - else - scalar = - FT_MulDiv( scalar, - axis->endCoord - ttface->blend->normalizedcoords[j], - axis->endCoord - axis->peakCoord ); + else if ( ncv < axis->peakCoord ) + scalar = FT_MulDiv( scalar, + ncv - axis->startCoord, + axis->peakCoord - axis->startCoord ); + else /* ncv > axis->peakCoord */ + scalar = FT_MulDiv( scalar, + axis->endCoord - ncv, + axis->endCoord - axis->peakCoord ); } /* per-axis loop */ @@ -1920,28 +1916,17 @@ for ( i = 0; i < blend->num_axis; i++ ) { - FT_TRACE6(( " axis %d coordinate %.5f:\n", - i, (double)blend->normalizedcoords[i] / 65536 )); + FT_Fixed ncv = blend->normalizedcoords[i]; + + + FT_TRACE6(( " axis %d coordinate %.5f:\n", i, (double)ncv / 65536 )); /* It's not clear why (for intermediate tuples) we don't need */ /* to check against start/end -- the documentation says we don't. */ /* Similarly, it's unclear why we don't need to scale along the */ /* axis. */ - if ( tuple_coords[i] == 0 ) - { - FT_TRACE6(( " tuple coordinate is zero, ignore\n" )); - continue; - } - - if ( blend->normalizedcoords[i] == 0 ) - { - FT_TRACE6(( " axis coordinate is zero, stop\n" )); - apply = 0; - break; - } - - if ( blend->normalizedcoords[i] == tuple_coords[i] ) + if ( tuple_coords[i] == ncv ) { FT_TRACE6(( " tuple coordinate %.5f fits perfectly\n", (double)tuple_coords[i] / 65536 )); @@ -1949,31 +1934,37 @@ continue; } + if ( tuple_coords[i] == 0 ) + { + FT_TRACE6(( " tuple coordinate is zero, ignore\n" )); + continue; + } + if ( !( tupleIndex & GX_TI_INTERMEDIATE_TUPLE ) ) { /* not an intermediate tuple */ - if ( blend->normalizedcoords[i] < FT_MIN( 0, tuple_coords[i] ) || - blend->normalizedcoords[i] > FT_MAX( 0, tuple_coords[i] ) ) + if ( ( tuple_coords[i] > ncv && ncv > 0 ) || + ( tuple_coords[i] < ncv && ncv < 0 ) ) + { + FT_TRACE6(( " tuple coordinate %.5f fits\n", + (double)tuple_coords[i] / 65536 )); + apply = FT_MulDiv( apply, ncv, tuple_coords[i] ); + } + else { FT_TRACE6(( " tuple coordinate %.5f is exceeded, stop\n", (double)tuple_coords[i] / 65536 )); apply = 0; break; } - - FT_TRACE6(( " tuple coordinate %.5f fits\n", - (double)tuple_coords[i] / 65536 )); - apply = FT_MulDiv( apply, - blend->normalizedcoords[i], - tuple_coords[i] ); } else { /* intermediate tuple */ - if ( blend->normalizedcoords[i] <= im_start_coords[i] || - blend->normalizedcoords[i] >= im_end_coords[i] ) + if ( ncv <= im_start_coords[i] || + ncv >= im_end_coords[i] ) { FT_TRACE6(( " intermediate tuple range ]%.5f;%.5f[ is exceeded," " stop\n", @@ -1986,13 +1977,13 @@ FT_TRACE6(( " intermediate tuple range ]%.5f;%.5f[ fits\n", (double)im_start_coords[i] / 65536, (double)im_end_coords[i] / 65536 )); - if ( blend->normalizedcoords[i] < tuple_coords[i] ) + if ( ncv < tuple_coords[i] ) apply = FT_MulDiv( apply, - blend->normalizedcoords[i] - im_start_coords[i], + ncv - im_start_coords[i], tuple_coords[i] - im_start_coords[i] ); - else + else /* ncv > tuple_coords[i] */ apply = FT_MulDiv( apply, - im_end_coords[i] - blend->normalizedcoords[i], + im_end_coords[i] - ncv, im_end_coords[i] - tuple_coords[i] ); } } @@ -2141,12 +2132,12 @@ outerIndex, innerIndex ); - /* Convert to 16.16 format before adding. */ - v += MUL_INT( delta, 4 ); + /* Convert delta in F2DOT14 to 16.16 before adding. */ + v += MUL_INT( delta, 4 ); - /* Clamp value range. */ - v = v >= 0x10000L ? 0x10000 : v; - v = v <= -0x10000L ? -0x10000 : v; + /* Clamp value range [-1, 1]. */ + v = v >= 0x10000L ? 0x10000 : v; + v = v <= -0x10000L ? -0x10000 : v; new_normalized[i] = v; } @@ -2722,9 +2713,8 @@ FT_UInt n; - if ( FT_ALLOC( mmvar, ttface->blend->mmvar_len ) ) + if ( FT_DUP( mmvar, ttface->blend->mmvar, ttface->blend->mmvar_len ) ) goto Exit; - FT_MEM_COPY( mmvar, ttface->blend->mmvar, ttface->blend->mmvar_len ); axis_flags = (FT_UShort*)( (char*)mmvar + mmvar_size ); @@ -3534,9 +3524,10 @@ FT_ULong here; FT_UInt i, j; - FT_Fixed* tuple_coords = NULL; - FT_Fixed* im_start_coords = NULL; - FT_Fixed* im_end_coords = NULL; + FT_Fixed* peak_coords = NULL; + FT_Fixed* tuple_coords; + FT_Fixed* im_start_coords; + FT_Fixed* im_end_coords; GX_Blend blend = face->blend; @@ -3557,16 +3548,16 @@ { FT_TRACE2(( "\n" )); FT_TRACE2(( "tt_face_vary_cvt: no blend specified\n" )); - error = FT_Err_Ok; - goto Exit; + + return FT_Err_Ok; } if ( !face->cvt ) { FT_TRACE2(( "\n" )); FT_TRACE2(( "tt_face_vary_cvt: no `cvt ' table\n" )); - error = FT_Err_Ok; - goto Exit; + + return FT_Err_Ok; } error = face->goto_table( face, TTAG_cvar, stream, &table_len ); @@ -3574,15 +3565,11 @@ { FT_TRACE2(( "is missing\n" )); - error = FT_Err_Ok; - goto Exit; + return FT_Err_Ok; } if ( FT_FRAME_ENTER( table_len ) ) - { - error = FT_Err_Ok; - goto Exit; - } + return FT_Err_Ok; table_start = FT_Stream_FTell( stream ); if ( FT_GET_LONG() != 0x00010000L ) @@ -3595,11 +3582,6 @@ FT_TRACE2(( "loaded\n" )); - if ( FT_NEW_ARRAY( tuple_coords, blend->num_axis ) || - FT_NEW_ARRAY( im_start_coords, blend->num_axis ) || - FT_NEW_ARRAY( im_end_coords, blend->num_axis ) ) - goto FExit; - tupleCount = FT_GET_USHORT(); offsetToData = FT_GET_USHORT(); @@ -3635,8 +3617,12 @@ tupleCount & GX_TC_TUPLE_COUNT_MASK, ( tupleCount & GX_TC_TUPLE_COUNT_MASK ) == 1 ? "" : "s" )); - if ( FT_NEW_ARRAY( cvt_deltas, face->cvt_size ) ) - goto FExit; + if ( FT_QNEW_ARRAY( peak_coords, 3 * blend->num_axis ) || + FT_NEW_ARRAY( cvt_deltas, face->cvt_size ) ) + goto Exit; + + im_start_coords = peak_coords + blend->num_axis; + im_end_coords = im_start_coords + blend->num_axis; for ( i = 0; i < ( tupleCount & GX_TC_TUPLE_COUNT_MASK ); i++ ) { @@ -3653,32 +3639,19 @@ if ( tupleIndex & GX_TI_EMBEDDED_TUPLE_COORD ) { for ( j = 0; j < blend->num_axis; j++ ) - tuple_coords[j] = FT_fdot14ToFixed( FT_GET_SHORT() ); + peak_coords[j] = FT_fdot14ToFixed( FT_GET_SHORT() ); + tuple_coords = peak_coords; } - else if ( ( tupleIndex & GX_TI_TUPLE_INDEX_MASK ) >= blend->tuplecount ) + else if ( ( tupleIndex & GX_TI_TUPLE_INDEX_MASK ) < blend->tuplecount ) + tuple_coords = blend->tuplecoords + + ( tupleIndex & GX_TI_TUPLE_INDEX_MASK ) * blend->num_axis; + else { FT_TRACE2(( "tt_face_vary_cvt:" " invalid tuple index\n" )); error = FT_THROW( Invalid_Table ); - goto FExit; - } - else - { - if ( !blend->tuplecoords ) - { - FT_TRACE2(( "tt_face_vary_cvt:" - " no valid tuple coordinates available\n" )); - - error = FT_THROW( Invalid_Table ); - goto FExit; - } - - FT_MEM_COPY( - tuple_coords, - blend->tuplecoords + - ( tupleIndex & GX_TI_TUPLE_INDEX_MASK ) * blend->num_axis, - blend->num_axis * sizeof ( FT_Fixed ) ); + goto Exit; } if ( tupleIndex & GX_TI_INTERMEDIATE_TUPLE ) @@ -3821,23 +3794,21 @@ for ( i = 0; i < face->cvt_size; i++ ) face->cvt[i] += FT_fixedToFdot6( cvt_deltas[i] ); - FExit: - FT_FRAME_EXIT(); - - Exit: - if ( sharedpoints != ALL_POINTS ) - FT_FREE( sharedpoints ); - FT_FREE( tuple_coords ); - FT_FREE( im_start_coords ); - FT_FREE( im_end_coords ); - FT_FREE( cvt_deltas ); - /* iterate over all FT_Size objects and set `cvt_ready' to -1 */ /* to trigger rescaling of all CVT values */ FT_List_Iterate( &root->sizes_list, tt_cvt_ready_iterator, NULL ); + Exit: + if ( sharedpoints != ALL_POINTS ) + FT_FREE( sharedpoints ); + FT_FREE( cvt_deltas ); + FT_FREE( peak_coords ); + + FExit: + FT_FRAME_EXIT(); + return error; #else /* !TT_CONFIG_OPTION_BYTECODE_INTERPRETER */ @@ -4100,9 +4071,10 @@ FT_ULong here; FT_UInt i, j; - FT_Fixed* tuple_coords = NULL; - FT_Fixed* im_start_coords = NULL; - FT_Fixed* im_end_coords = NULL; + FT_Fixed* peak_coords = NULL; + FT_Fixed* tuple_coords; + FT_Fixed* im_start_coords; + FT_Fixed* im_end_coords; GX_Blend blend = face->blend; @@ -4137,27 +4109,17 @@ return FT_Err_Ok; } - if ( FT_NEW_ARRAY( points_org, n_points ) || - FT_NEW_ARRAY( points_out, n_points ) || - FT_NEW_ARRAY( has_delta, n_points ) ) - goto Fail1; - dataSize = blend->glyphoffsets[glyph_index + 1] - blend->glyphoffsets[glyph_index]; if ( FT_STREAM_SEEK( blend->glyphoffsets[glyph_index] ) || FT_FRAME_ENTER( dataSize ) ) - goto Fail1; + return error; glyph_start = FT_Stream_FTell( stream ); /* each set of glyph variation data is formatted similarly to `cvar' */ - if ( FT_NEW_ARRAY( tuple_coords, blend->num_axis ) || - FT_NEW_ARRAY( im_start_coords, blend->num_axis ) || - FT_NEW_ARRAY( im_end_coords, blend->num_axis ) ) - goto Fail2; - tupleCount = FT_GET_USHORT(); offsetToData = FT_GET_USHORT(); @@ -4169,7 +4131,7 @@ " invalid glyph variation array header\n" )); error = FT_THROW( Invalid_Table ); - goto Fail2; + goto FExit; } offsetToData += glyph_start; @@ -4193,9 +4155,16 @@ tupleCount & GX_TC_TUPLE_COUNT_MASK, ( tupleCount & GX_TC_TUPLE_COUNT_MASK ) == 1 ? "" : "s" )); - if ( FT_NEW_ARRAY( point_deltas_x, n_points ) || - FT_NEW_ARRAY( point_deltas_y, n_points ) ) - goto Fail3; + if ( FT_QNEW_ARRAY( peak_coords, 3 * blend->num_axis ) || + FT_NEW_ARRAY( point_deltas_x, 2 * n_points ) || + FT_QNEW_ARRAY( points_org, n_points ) || + FT_QNEW_ARRAY( points_out, n_points ) || + FT_QNEW_ARRAY( has_delta, n_points ) ) + goto Exit; + + im_start_coords = peak_coords + blend->num_axis; + im_end_coords = im_start_coords + blend->num_axis; + point_deltas_y = point_deltas_x + n_points; for ( j = 0; j < n_points; j++ ) { @@ -4218,22 +4187,20 @@ if ( tupleIndex & GX_TI_EMBEDDED_TUPLE_COORD ) { for ( j = 0; j < blend->num_axis; j++ ) - tuple_coords[j] = FT_fdot14ToFixed( FT_GET_SHORT() ); + peak_coords[j] = FT_fdot14ToFixed( FT_GET_SHORT() ); + tuple_coords = peak_coords; } - else if ( ( tupleIndex & GX_TI_TUPLE_INDEX_MASK ) >= blend->tuplecount ) + else if ( ( tupleIndex & GX_TI_TUPLE_INDEX_MASK ) < blend->tuplecount ) + tuple_coords = blend->tuplecoords + + ( tupleIndex & GX_TI_TUPLE_INDEX_MASK ) * blend->num_axis; + else { FT_TRACE2(( "TT_Vary_Apply_Glyph_Deltas:" " invalid tuple index\n" )); error = FT_THROW( Invalid_Table ); - goto Fail3; + goto Exit; } - else - FT_MEM_COPY( - tuple_coords, - blend->tuplecoords + - ( tupleIndex & GX_TI_TUPLE_INDEX_MASK ) * blend->num_axis, - blend->num_axis * sizeof ( FT_Fixed ) ); if ( tupleIndex & GX_TI_INTERMEDIATE_TUPLE ) { @@ -4461,23 +4428,17 @@ unrounded[n_points - 2].y ) / 64; } - Fail3: - FT_FREE( point_deltas_x ); - FT_FREE( point_deltas_y ); - - Fail2: + Exit: if ( sharedpoints != ALL_POINTS ) FT_FREE( sharedpoints ); - FT_FREE( tuple_coords ); - FT_FREE( im_start_coords ); - FT_FREE( im_end_coords ); - - FT_FRAME_EXIT(); - - Fail1: FT_FREE( points_org ); FT_FREE( points_out ); FT_FREE( has_delta ); + FT_FREE( peak_coords ); + FT_FREE( point_deltas_x ); + + FExit: + FT_FRAME_EXIT(); return error; } diff --git a/src/truetype/ttinterp.c b/src/truetype/ttinterp.c index 0889c6151..951891dbf 100644 --- a/src/truetype/ttinterp.c +++ b/src/truetype/ttinterp.c @@ -5270,11 +5270,11 @@ FT_UShort refp; FT_F26Dot6 dx, dy; - FT_Short contour, bounds; + FT_UShort contour, bounds; FT_UShort start, limit, i; - contour = (FT_Short)args[0]; + contour = (FT_UShort)args[0]; bounds = ( exc->GS.gep2 == 0 ) ? 1 : exc->zp2.n_contours; if ( BOUNDS( contour, bounds ) ) @@ -5290,15 +5290,13 @@ if ( contour == 0 ) start = 0; else - start = (FT_UShort)( exc->zp2.contours[contour - 1] + 1 - - exc->zp2.first_point ); + start = exc->zp2.contours[contour - 1] + 1 - exc->zp2.first_point; /* we use the number of points if in the twilight zone */ if ( exc->GS.gep2 == 0 ) limit = exc->zp2.n_points; else - limit = (FT_UShort)( exc->zp2.contours[contour] - - exc->zp2.first_point + 1 ); + limit = exc->zp2.contours[contour] + 1 - exc->zp2.first_point; for ( i = start; i < limit; i++ ) { @@ -5341,9 +5339,9 @@ /* Normal zone's `n_points' includes phantoms, so must */ /* use end of last contour. */ if ( exc->GS.gep2 == 0 ) - limit = (FT_UShort)exc->zp2.n_points; + limit = exc->zp2.n_points; else if ( exc->GS.gep2 == 1 && exc->zp2.n_contours > 0 ) - limit = (FT_UShort)( exc->zp2.contours[exc->zp2.n_contours - 1] + 1 ); + limit = exc->zp2.contours[exc->zp2.n_contours - 1] + 1; else limit = 0; diff --git a/src/truetype/ttobjs.c b/src/truetype/ttobjs.c index 3cdbfff1b..08aee62a8 100644 --- a/src/truetype/ttobjs.c +++ b/src/truetype/ttobjs.c @@ -115,7 +115,7 @@ FT_LOCAL_DEF( FT_Error ) tt_glyphzone_new( FT_Memory memory, FT_UShort maxPoints, - FT_Short maxContours, + FT_UShort maxContours, TT_GlyphZone zone ) { FT_Error error; @@ -256,17 +256,20 @@ { FT_Error error; FT_UInt32 checksum = 0; - FT_UInt i; + FT_Byte* p; + FT_Int shift; if ( FT_FRAME_ENTER( length ) ) return 0; - for ( ; length > 3; length -= 4 ) - checksum += (FT_UInt32)FT_GET_ULONG(); + p = (FT_Byte*)stream->cursor; - for ( i = 3; length > 0; length--, i-- ) - checksum += (FT_UInt32)FT_GET_BYTE() << ( i * 8 ); + for ( ; length > 3; length -= 4 ) + checksum += FT_NEXT_ULONG( p ); + + for ( shift = 24; length > 0; length--, shift -=8 ) + checksum += (FT_UInt32)FT_NEXT_BYTE( p ) << shift; FT_FRAME_EXIT(); diff --git a/src/truetype/ttobjs.h b/src/truetype/ttobjs.h index 0a63e6729..9c36ca783 100644 --- a/src/truetype/ttobjs.h +++ b/src/truetype/ttobjs.h @@ -105,7 +105,7 @@ FT_BEGIN_HEADER FT_LOCAL( FT_Error ) tt_glyphzone_new( FT_Memory memory, FT_UShort maxPoints, - FT_Short maxContours, + FT_UShort maxContours, TT_GlyphZone zone ); #endif /* TT_USE_BYTECODE_INTERPRETER */ diff --git a/src/type1/t1load.c b/src/type1/t1load.c index 7f63898fc..ee7fb42a5 100644 --- a/src/type1/t1load.c +++ b/src/type1/t1load.c @@ -751,6 +751,7 @@ PS_DesignMap dmap = blend->design_map + n; + FT_FREE( dmap->blend_points ); FT_FREE( dmap->design_points ); dmap->num_points = 0; } @@ -1043,9 +1044,9 @@ } /* allocate design map data */ - if ( FT_QNEW_ARRAY( map->design_points, num_points * 2 ) ) + if ( FT_QNEW_ARRAY( map->design_points, num_points ) || + FT_QNEW_ARRAY( map->blend_points, num_points ) ) goto Exit; - map->blend_points = map->design_points + num_points; map->num_points = (FT_Byte)num_points; for ( p = 0; p < num_points; p++ ) @@ -1876,9 +1877,8 @@ } /* t1_decrypt() shouldn't write to base -- make temporary copy */ - if ( FT_QALLOC( temp, size ) ) + if ( FT_DUP( temp, base, size ) ) goto Fail; - FT_MEM_COPY( temp, base, size ); psaux->t1_decrypt( temp, size, 4330 ); size -= (FT_ULong)t1face->type1.private_dict.lenIV; error = T1_Add_Table( table, @@ -2090,9 +2090,8 @@ } /* t1_decrypt() shouldn't write to base -- make temporary copy */ - if ( FT_QALLOC( temp, size ) ) + if ( FT_DUP( temp, base, size ) ) goto Fail; - FT_MEM_COPY( temp, base, size ); psaux->t1_decrypt( temp, size, 4330 ); size -= (FT_ULong)t1face->type1.private_dict.lenIV; error = T1_Add_Table( code_table,