Merge remote-tracking branch 'upstream/master'

This commit is contained in:
H. Utku Maden 2024-06-21 12:23:04 +03:00
commit 57a643ae75
51 changed files with 641 additions and 860 deletions

@ -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'

@ -19,7 +19,7 @@ Anurag Thakur (अनुराग ठाकुर) <anuthadev@gmail.com>
David Turner <david@freetype.org> <david.turner.dev@gmail.com>
David Turner <david@freetype.org> <digit@google.com>
Anuj Verma (अनुज वर्मा) <anujv@iitbhilai.ac.in>
Ben Wagner <bungeman@gmail.com> Bungeman <bungeman@gmail.com>
Ben Wagner <bungeman@gmail.com>
Ben Wagner <bungeman@gmail.com> <bungeman@google.com>
Ben Wagner <bungeman@gmail.com> <bungeman@chromium.org>
Nikolaus Waxweiler <madigens@gmail.com> <nikolaus.waxweiler@daltonmaag.com>

@ -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 <malloc.h>
@ -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 */

@ -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 <davidbsaltzman@gmail.com>.
- 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`.
======================================================================

@ -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_
{

@ -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:

@ -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
/**************************************************************************

@ -19,8 +19,13 @@
#ifndef FTMM_H_
#define FTMM_H_
#include <freetype/freetype.h>
#include <freetype/t1tables.h>
#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:

@ -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 ) )

@ -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 \
}
/*************************************************************************/

@ -21,7 +21,7 @@
#define T1TYPES_H_
#include <freetype/t1tables.h>
#include <freetype/ftmm.h>
#include <freetype/internal/pshints.h>
#include <freetype/internal/ftserv.h>
#include <freetype/internal/fthash.h>
@ -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;
/*************************************************************************/
/*************************************************************************/
/*************************************************************************/

@ -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 */

@ -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:

@ -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++ )

@ -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",

@ -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;

@ -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 );

@ -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;

@ -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;

@ -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. */

113
src/cache/ftcbasic.c vendored

@ -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 ) +

33
src/cache/ftccache.c vendored

@ -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 );
}

@ -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 );
/*************************************************************************/
/*************************************************************************/

10
src/cache/ftccback.h vendored

@ -19,11 +19,7 @@
#define FTCCBACK_H_
#include <freetype/ftcache.h>
#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_ */

2
src/cache/ftccmap.c vendored

@ -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

@ -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;
}

@ -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

12
src/cache/ftcimage.c vendored

@ -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 ) +

55
src/cache/ftcmanag.c vendored

@ -22,7 +22,6 @@
#include <freetype/internal/ftdebug.h>
#include <freetype/ftsizes.h>
#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 );
}

67
src/cache/ftcmru.c vendored

@ -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 );
}

6
src/cache/ftcmru.h vendored

@ -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;

@ -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;
}

@ -1202,17 +1202,21 @@
{
CFF_AxisCoords* axis = &region->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 ",

@ -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:

@ -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;
}
}

@ -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;

@ -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;

@ -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 )

@ -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 */

@ -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

@ -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,

@ -18,6 +18,7 @@
#include "sfwoff.h"
#include <freetype/tttags.h>
#include <freetype/internal/ftcalc.h>
#include <freetype/internal/ftdebug.h>
#include <freetype/internal/ftstream.h>
#include <freetype/ftgzip.h>
@ -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 );

@ -18,6 +18,7 @@
#include "sfwoff2.h"
#include "woff2tags.h"
#include <freetype/tttags.h>
#include <freetype/internal/ftcalc.h>
#include <freetype/internal/ftdebug.h>
#include <freetype/internal/ftstream.h>
@ -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 );

@ -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;

@ -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 );

@ -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,

@ -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;
}

@ -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;

@ -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();

@ -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 */

@ -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,