forked from minhngoc25a/freetype2
* include/freetype/internal/tttypes.h, src/autofit/afangles.c,
src/autofit/afcjk.c, src/autofit/afhints.c, src/autofit/aflatin.c, src/autofit/aftypes.h, src/base/ftcalc.c, src/base/ftoutln.c, src/gzip/ftgzip.c, src/psaux/psconv.c, src/truetype/ttgload.c, src/type1/t1gload.c: this is a major patch used to drastically improve the performance of loading glyphs. This both speeds up loading the glypn vector themselves and the auto-fitter. note that we've started using inline assembler with GCC to implement FT_MulFix, given that this function is so damn important for the engine's performance. the resulting speed-up is about 25%.
This commit is contained in:
parent
dc3ff31c3f
commit
281679de85
23
ChangeLog
23
ChangeLog
|
@ -1,5 +1,22 @@
|
|||
2006-05-17 David Turner <david@freetype.org>
|
||||
|
||||
* include/freetype/internal/tttypes.h, src/autofit/afangles.c,
|
||||
src/autofit/afcjk.c, src/autofit/afhints.c, src/autofit/aflatin.c,
|
||||
src/autofit/aftypes.h, src/base/ftcalc.c, src/base/ftoutln.c,
|
||||
src/gzip/ftgzip.c, src/psaux/psconv.c, src/truetype/ttgload.c,
|
||||
src/type1/t1gload.c:
|
||||
|
||||
this is a major patch used to drastically improve the performance
|
||||
of loading glyphs. This both speeds up loading the glypn vector
|
||||
themselves and the auto-fitter.
|
||||
|
||||
note that we've started using inline assembler with GCC to
|
||||
implement FT_MulFix, given that this function is so damn
|
||||
important for the engine's performance.
|
||||
|
||||
the resulting speed-up is about 25%.
|
||||
|
||||
|
||||
* src/ftccmap.c (FTC_CMapCache_Lookup): changed the threshold
|
||||
used to detect rogue clients from 4 to 16. This is to prevent
|
||||
some segmentation faults with fonts like KozMinProVI-Regular.otf
|
||||
|
@ -8,7 +25,7 @@
|
|||
2007-05-17 Werner Lemberg <wl@gnu.org>
|
||||
|
||||
* src/cff/cffload.c (cff_font_done): Deallocate subfont array. This
|
||||
fixes the first part of Savannah bug #16590.
|
||||
fixes the first part of Savannah bug #16590.
|
||||
|
||||
2006-05-16 Werner Lemberg <wl@gnu.org>
|
||||
|
||||
|
@ -52,8 +69,8 @@
|
|||
Update handling of re_italic and re_bold.
|
||||
|
||||
2006-05-11 Masatake YAMATO <jet@gyve.org>
|
||||
|
||||
* builds/unix/ftsystem.c (FT_Stream_Open): Check errno only if
|
||||
|
||||
* builds/unix/ftsystem.c (FT_Stream_Open): Check errno only if
|
||||
read system call returns -1.
|
||||
Remove a redundant parenthesis.
|
||||
|
||||
|
|
|
@ -1521,6 +1521,10 @@ FT_BEGIN_HEADER
|
|||
FT_Vector pp3;
|
||||
FT_Vector pp4;
|
||||
|
||||
/* since version 2.2.1 */
|
||||
FT_Byte* cursor;
|
||||
FT_Byte* limit;
|
||||
|
||||
} TT_LoaderRec;
|
||||
|
||||
|
||||
|
|
|
@ -20,7 +20,94 @@
|
|||
#include "aftypes.h"
|
||||
|
||||
|
||||
#if 1
|
||||
FT_LOCAL_DEF( FT_Int )
|
||||
af_corner_is_flat( FT_Pos x_in,
|
||||
FT_Pos y_in,
|
||||
FT_Pos x_out,
|
||||
FT_Pos y_out )
|
||||
{
|
||||
FT_Pos ax = x_in;
|
||||
FT_Pos ay = y_in;
|
||||
|
||||
FT_Pos d_in, d_out, d_corner;
|
||||
|
||||
if ( ax < 0 ) ax = -ax;
|
||||
if ( ay < 0 ) ay = -ay;
|
||||
d_in = ax + ay;
|
||||
|
||||
ax = x_out; if ( ax < 0 ) ax = -ax;
|
||||
ay = y_out; if ( ay < 0 ) ay = -ay;
|
||||
d_out = ax+ay;
|
||||
|
||||
ax = x_out + x_in; if ( ax < 0 ) ax = -ax;
|
||||
ay = y_out + y_in; if ( ay < 0 ) ay = -ay;
|
||||
d_corner = ax+ay;
|
||||
|
||||
return ( d_in + d_out - d_corner ) < (d_corner >> 4);
|
||||
}
|
||||
|
||||
|
||||
FT_LOCAL_DEF( FT_Int )
|
||||
af_corner_orientation( FT_Pos x_in,
|
||||
FT_Pos y_in,
|
||||
FT_Pos x_out,
|
||||
FT_Pos y_out )
|
||||
{
|
||||
FT_Pos delta;
|
||||
|
||||
delta = x_in*y_out - y_in*x_out;
|
||||
|
||||
if ( delta == 0 )
|
||||
return 0;
|
||||
else
|
||||
return 1 - 2*(delta < 0);
|
||||
}
|
||||
|
||||
|
||||
/* we're not using af_angle_atan anymore, but we keep the source
|
||||
* code below just in case :-)
|
||||
*/
|
||||
#if 0
|
||||
|
||||
/* the trick here is to realize that we don't need an very accurate
|
||||
* angle approximation. We're going to use the result of af_angle_atan
|
||||
* to only compare the sign of angle differences, or see if its magnitude
|
||||
* is very small.
|
||||
*
|
||||
* the approximation (dy*PI/(|dx|+|dy|))) should be enough, and much
|
||||
* faster to compute.
|
||||
*/
|
||||
FT_LOCAL_DEF( AF_Angle )
|
||||
af_angle_atan( FT_Fixed dx,
|
||||
FT_Fixed dy )
|
||||
{
|
||||
AF_Angle angle;
|
||||
FT_Fixed ax = dx;
|
||||
FT_Fixed ay = dy;
|
||||
|
||||
if ( ax < 0 ) ax = -ax;
|
||||
if ( ay < 0 ) ay = -ay;
|
||||
|
||||
ax += ay;
|
||||
|
||||
if ( ax == 0 )
|
||||
angle = 0;
|
||||
else
|
||||
{
|
||||
angle = (AF_ANGLE_PI2*dy)/(ax+ay);
|
||||
if ( dx < 0 )
|
||||
{
|
||||
if ( angle >= 0 )
|
||||
angle = AF_ANGLE_PI - angle;
|
||||
else
|
||||
angle = -AF_ANGLE_PI - angle;
|
||||
}
|
||||
}
|
||||
|
||||
return angle;
|
||||
}
|
||||
|
||||
#elif 0
|
||||
|
||||
/* the following table has been automatically generated with */
|
||||
/* the `mather.py' Python script */
|
||||
|
@ -124,224 +211,8 @@
|
|||
}
|
||||
|
||||
|
||||
#else /* 0 */
|
||||
|
||||
/*
|
||||
* a python script used to generate the following table
|
||||
*
|
||||
|
||||
import sys, math
|
||||
|
||||
units = 256
|
||||
scale = units/math.pi
|
||||
comma = ""
|
||||
|
||||
print ""
|
||||
print "table of arctan( 1/2^n ) for PI = " + repr( units / 65536.0 ) + " units"
|
||||
|
||||
r = [-1] + range( 32 )
|
||||
|
||||
for n in r:
|
||||
if n >= 0:
|
||||
x = 1.0 / ( 2.0 ** n ) # tangent value
|
||||
else:
|
||||
x = 2.0 ** ( -n )
|
||||
|
||||
angle = math.atan( x ) # arctangent
|
||||
angle2 = angle * scale # arctangent in FT_Angle units
|
||||
|
||||
# determine which integer value for angle gives the best tangent
|
||||
lo = int( angle2 )
|
||||
hi = lo + 1
|
||||
tlo = math.tan( lo / scale )
|
||||
thi = math.tan( hi / scale )
|
||||
|
||||
errlo = abs( tlo - x )
|
||||
errhi = abs( thi - x )
|
||||
|
||||
angle2 = hi
|
||||
if errlo < errhi:
|
||||
angle2 = lo
|
||||
|
||||
if angle2 <= 0:
|
||||
break
|
||||
|
||||
sys.stdout.write( comma + repr( int( angle2 ) ) )
|
||||
comma = ", "
|
||||
|
||||
*
|
||||
* end of python script
|
||||
*/
|
||||
|
||||
|
||||
/* this table was generated for AF_ANGLE_PI = 256 */
|
||||
#define AF_ANGLE_MAX_ITERS 8
|
||||
#define AF_TRIG_MAX_ITERS 8
|
||||
|
||||
static const FT_Fixed
|
||||
af_angle_arctan_table[9] =
|
||||
{
|
||||
90, 64, 38, 20, 10, 5, 3, 1, 1
|
||||
};
|
||||
|
||||
|
||||
static FT_Int
|
||||
af_angle_prenorm( FT_Vector* vec )
|
||||
{
|
||||
FT_Fixed x, y, z;
|
||||
FT_Int shift;
|
||||
|
||||
|
||||
x = vec->x;
|
||||
y = vec->y;
|
||||
|
||||
z = ( ( x >= 0 ) ? x : - x ) | ( (y >= 0) ? y : -y );
|
||||
shift = 0;
|
||||
|
||||
if ( z < ( 1L << 27 ) )
|
||||
{
|
||||
do
|
||||
{
|
||||
shift++;
|
||||
z <<= 1;
|
||||
} while ( z < ( 1L << 27 ) );
|
||||
|
||||
vec->x = x << shift;
|
||||
vec->y = y << shift;
|
||||
}
|
||||
else if ( z > ( 1L << 28 ) )
|
||||
{
|
||||
do
|
||||
{
|
||||
shift++;
|
||||
z >>= 1;
|
||||
} while ( z > ( 1L << 28 ) );
|
||||
|
||||
vec->x = x >> shift;
|
||||
vec->y = y >> shift;
|
||||
shift = -shift;
|
||||
}
|
||||
return shift;
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
af_angle_pseudo_polarize( FT_Vector* vec )
|
||||
{
|
||||
FT_Fixed theta;
|
||||
FT_Fixed yi, i;
|
||||
FT_Fixed x, y;
|
||||
const FT_Fixed *arctanptr;
|
||||
|
||||
|
||||
x = vec->x;
|
||||
y = vec->y;
|
||||
|
||||
/* Get the vector into the right half plane */
|
||||
theta = 0;
|
||||
if ( x < 0 )
|
||||
{
|
||||
x = -x;
|
||||
y = -y;
|
||||
theta = AF_ANGLE_PI;
|
||||
}
|
||||
|
||||
if ( y > 0 )
|
||||
theta = -theta;
|
||||
|
||||
arctanptr = af_angle_arctan_table;
|
||||
|
||||
if ( y < 0 )
|
||||
{
|
||||
/* Rotate positive */
|
||||
yi = y + ( x << 1 );
|
||||
x = x - ( y << 1 );
|
||||
y = yi;
|
||||
theta -= *arctanptr++; /* Subtract angle */
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Rotate negative */
|
||||
yi = y - ( x << 1 );
|
||||
x = x + ( y << 1 );
|
||||
y = yi;
|
||||
theta += *arctanptr++; /* Add angle */
|
||||
}
|
||||
|
||||
i = 0;
|
||||
do
|
||||
{
|
||||
if ( y < 0 )
|
||||
{
|
||||
/* Rotate positive */
|
||||
yi = y + ( x >> i );
|
||||
x = x - ( y >> i );
|
||||
y = yi;
|
||||
theta -= *arctanptr++;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Rotate negative */
|
||||
yi = y - ( x >> i );
|
||||
x = x + ( y >> i );
|
||||
y = yi;
|
||||
theta += *arctanptr++;
|
||||
}
|
||||
} while ( ++i < AF_TRIG_MAX_ITERS );
|
||||
|
||||
#if 0
|
||||
/* round theta */
|
||||
if ( theta >= 0 )
|
||||
theta = FT_PAD_ROUND( theta, 2 );
|
||||
else
|
||||
theta = -FT_PAD_ROUND( -theta, 2 );
|
||||
#endif
|
||||
|
||||
vec->x = x;
|
||||
vec->y = theta;
|
||||
}
|
||||
|
||||
|
||||
/* cf. documentation in fttrigon.h */
|
||||
|
||||
FT_LOCAL_DEF( AF_Angle )
|
||||
af_angle_atan( FT_Fixed dx,
|
||||
FT_Fixed dy )
|
||||
{
|
||||
FT_Vector v;
|
||||
|
||||
|
||||
if ( dx == 0 && dy == 0 )
|
||||
return 0;
|
||||
|
||||
v.x = dx;
|
||||
v.y = dy;
|
||||
af_angle_prenorm( &v );
|
||||
af_angle_pseudo_polarize( &v );
|
||||
|
||||
return v.y;
|
||||
}
|
||||
|
||||
|
||||
FT_LOCAL_DEF( AF_Angle )
|
||||
af_angle_diff( AF_Angle angle1,
|
||||
AF_Angle angle2 )
|
||||
{
|
||||
AF_Angle delta = angle2 - angle1;
|
||||
|
||||
|
||||
delta %= AF_ANGLE_2PI;
|
||||
if ( delta < 0 )
|
||||
delta += AF_ANGLE_2PI;
|
||||
|
||||
if ( delta > AF_ANGLE_PI )
|
||||
delta -= AF_ANGLE_2PI;
|
||||
|
||||
return delta;
|
||||
}
|
||||
|
||||
#endif /* 0 */
|
||||
|
||||
|
||||
FT_LOCAL_DEF( void )
|
||||
af_sort_pos( FT_UInt count,
|
||||
|
@ -389,45 +260,4 @@ for n in r:
|
|||
}
|
||||
|
||||
|
||||
#ifdef TEST
|
||||
|
||||
#include <stdio.h>
|
||||
#include <math.h>
|
||||
|
||||
int main( void )
|
||||
{
|
||||
int angle;
|
||||
int dist;
|
||||
|
||||
|
||||
for ( dist = 100; dist < 1000; dist++ )
|
||||
{
|
||||
for ( angle = AF_ANGLE_PI; angle < AF_ANGLE_2PI * 4; angle++ )
|
||||
{
|
||||
double a = ( angle * 3.1415926535 ) / ( 1.0 * AF_ANGLE_PI );
|
||||
int dx, dy, angle1, angle2, delta;
|
||||
|
||||
|
||||
dx = dist * cos( a );
|
||||
dy = dist * sin( a );
|
||||
|
||||
angle1 = ( ( atan2( dy, dx ) * AF_ANGLE_PI ) / 3.1415926535 );
|
||||
angle2 = af_angle_atan( dx, dy );
|
||||
delta = ( angle2 - angle1 ) % AF_ANGLE_2PI;
|
||||
if ( delta < 0 )
|
||||
delta = -delta;
|
||||
|
||||
if ( delta >= 2 )
|
||||
{
|
||||
printf( "dist:%4d angle:%4d => (%4d,%4d) angle1:%4d angle2:%4d\n",
|
||||
dist, angle, dx, dy, angle1, angle2 );
|
||||
}
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
#endif /* TEST */
|
||||
|
||||
|
||||
/* END */
|
||||
|
|
|
@ -1437,7 +1437,9 @@
|
|||
|
||||
static const AF_Script_UniRangeRec af_cjk_uniranges[] =
|
||||
{
|
||||
{ 0x0100, 0xFFFF },
|
||||
#if 0
|
||||
{ 0x0100, 0xFFFF }, /* why ?? */
|
||||
#endif
|
||||
{ 0x2E80, 0x2EFF }, /* CJK Radicals Supplement */
|
||||
{ 0x2F00, 0x2FDF }, /* Kangxi Radicals */
|
||||
{ 0x3000, 0x303F }, /* CJK Symbols and Punctuation */
|
||||
|
|
|
@ -53,7 +53,9 @@
|
|||
}
|
||||
|
||||
segment = axis->segments + axis->num_segments++;
|
||||
#if 0
|
||||
FT_ZERO( segment );
|
||||
#endif
|
||||
|
||||
Exit:
|
||||
*asegment = segment;
|
||||
|
@ -272,54 +274,46 @@
|
|||
FT_Pos dy )
|
||||
{
|
||||
#if 1
|
||||
AF_Direction dir = AF_DIR_NONE;
|
||||
FT_Pos ll, ss; /* long and short arm lengths */
|
||||
AF_Direction dir; /* candidate direction */
|
||||
|
||||
|
||||
/* atan(1/12) == 4.7 degrees */
|
||||
|
||||
if ( dx < 0 )
|
||||
if ( dy >= dx )
|
||||
{
|
||||
if ( dy < 0 )
|
||||
if ( dy >= -dx )
|
||||
{
|
||||
if ( -dx * 12 < -dy )
|
||||
dir = AF_DIR_DOWN;
|
||||
|
||||
else if ( -dy * 12 < -dx )
|
||||
dir = AF_DIR_LEFT;
|
||||
dir = AF_DIR_UP;
|
||||
ll = dy;
|
||||
ss = dx;
|
||||
}
|
||||
else /* dy >= 0 */
|
||||
else
|
||||
{
|
||||
if ( -dx * 12 < dy )
|
||||
dir = AF_DIR_UP;
|
||||
|
||||
else if ( dy * 12 < -dx )
|
||||
dir = AF_DIR_LEFT;
|
||||
dir = AF_DIR_LEFT;
|
||||
ll = -dx;
|
||||
ss = dy;
|
||||
}
|
||||
}
|
||||
else /* dx >= 0 */
|
||||
else /* dy < dx */
|
||||
{
|
||||
if ( dy < 0 )
|
||||
if ( dy >= -dx )
|
||||
{
|
||||
if ( dx * 12 < -dy )
|
||||
dir = AF_DIR_DOWN;
|
||||
|
||||
else if ( -dy * 12 < dx )
|
||||
dir = AF_DIR_RIGHT;
|
||||
dir = AF_DIR_RIGHT;
|
||||
ll = dx;
|
||||
ss = dy;
|
||||
}
|
||||
else /* dy >= 0 */
|
||||
else
|
||||
{
|
||||
if ( dx * 12 < dy )
|
||||
dir = AF_DIR_UP;
|
||||
|
||||
else if ( dy * 12 < dx )
|
||||
dir = AF_DIR_RIGHT;
|
||||
dir = AF_DIR_DOWN;
|
||||
ll = dy;
|
||||
ss = dx;
|
||||
}
|
||||
}
|
||||
|
||||
ss *= 12;
|
||||
if ( ll <= FT_ABS(ss) )
|
||||
dir = AF_DIR_NONE;
|
||||
|
||||
return dir;
|
||||
|
||||
#else /* 0 */
|
||||
|
||||
AF_Direction dir;
|
||||
FT_Pos ax = FT_ABS( dx );
|
||||
FT_Pos ay = FT_ABS( dy );
|
||||
|
@ -341,13 +335,125 @@
|
|||
}
|
||||
|
||||
return dir;
|
||||
|
||||
#endif /* 0 */
|
||||
|
||||
}
|
||||
|
||||
|
||||
/* compute all inflex points in a given glyph */
|
||||
#if 1
|
||||
static void
|
||||
af_glyph_hints_compute_inflections( AF_GlyphHints hints )
|
||||
{
|
||||
AF_Point* contour = hints->contours;
|
||||
AF_Point* contour_limit = contour + hints->num_contours;
|
||||
|
||||
|
||||
/* do each contour separately */
|
||||
for ( ; contour < contour_limit; contour++ )
|
||||
{
|
||||
AF_Point point = contour[0];
|
||||
AF_Point first = point;
|
||||
AF_Point start = point;
|
||||
AF_Point end = point;
|
||||
AF_Point before;
|
||||
AF_Point after;
|
||||
FT_Pos in_x, in_y, out_x, out_y;
|
||||
AF_Angle orient_prev, orient_cur;
|
||||
FT_Int finished = 0;
|
||||
|
||||
|
||||
/* compute first segment in contour */
|
||||
first = point;
|
||||
|
||||
start = end = first;
|
||||
do
|
||||
{
|
||||
end = end->next;
|
||||
if ( end == first )
|
||||
goto Skip;
|
||||
|
||||
in_x = end->fx - start->fx;
|
||||
in_y = end->fy - start->fy;
|
||||
|
||||
} while ( in_x == 0 && in_y == 0 );
|
||||
|
||||
/* extend the segment start whenever possible */
|
||||
before = start;
|
||||
do
|
||||
{
|
||||
do
|
||||
{
|
||||
start = before;
|
||||
before = before->prev;
|
||||
if ( before == first )
|
||||
goto Skip;
|
||||
|
||||
out_x = start->fx - before->fx;
|
||||
out_y = start->fy - before->fy;
|
||||
|
||||
} while ( out_x == 0 && out_y == 0 );
|
||||
|
||||
orient_prev = af_corner_orientation( in_x, in_y, out_x, out_y );
|
||||
|
||||
} while ( orient_prev == 0 );
|
||||
|
||||
first = start;
|
||||
|
||||
in_x = out_x;
|
||||
in_y = out_y;
|
||||
|
||||
/* now, process all segments in the contour */
|
||||
do
|
||||
{
|
||||
/* first, extend current segment's end whenever possible */
|
||||
after = end;
|
||||
do
|
||||
{
|
||||
do
|
||||
{
|
||||
end = after;
|
||||
after = after->next;
|
||||
if ( after == first )
|
||||
finished = 1;
|
||||
|
||||
out_x = after->fx - end->fx;
|
||||
out_y = after->fy - end->fy;
|
||||
|
||||
} while ( out_x == 0 && out_y == 0 );
|
||||
|
||||
orient_cur = af_corner_orientation( in_x, in_y, out_x, out_y );
|
||||
|
||||
} while ( orient_cur == 0 );
|
||||
|
||||
if ( ( orient_prev + orient_cur ) == 0 )
|
||||
{
|
||||
/* we have an inflection point here */
|
||||
do
|
||||
{
|
||||
start->flags |= AF_FLAG_INFLECTION;
|
||||
start = start->next;
|
||||
|
||||
} while ( start != end );
|
||||
|
||||
start->flags |= AF_FLAG_INFLECTION;
|
||||
}
|
||||
|
||||
start = end;
|
||||
end = after;
|
||||
|
||||
orient_prev = orient_cur;
|
||||
in_x = out_x;
|
||||
in_y = out_y;
|
||||
|
||||
} while ( !finished );
|
||||
|
||||
Skip:
|
||||
;
|
||||
}
|
||||
}
|
||||
|
||||
#else /* old code */
|
||||
static void
|
||||
af_glyph_hints_compute_inflections( AF_GlyphHints hints )
|
||||
{
|
||||
|
@ -454,6 +560,7 @@
|
|||
;
|
||||
}
|
||||
}
|
||||
#endif /* old code */
|
||||
|
||||
|
||||
FT_LOCAL_DEF( void )
|
||||
|
@ -702,6 +809,14 @@
|
|||
}
|
||||
else if ( point->out_dir == point->in_dir )
|
||||
{
|
||||
#if 1
|
||||
if ( point->out_dir != AF_DIR_NONE )
|
||||
goto Is_Weak_Point;
|
||||
|
||||
if ( af_corner_is_flat( in_x, in_y, out_x, out_y ) )
|
||||
goto Is_Weak_Point;
|
||||
|
||||
#else /* old code */
|
||||
AF_Angle angle_in, angle_out, delta;
|
||||
|
||||
|
||||
|
@ -715,6 +830,7 @@
|
|||
|
||||
if ( delta < 2 && delta > -2 )
|
||||
goto Is_Weak_Point;
|
||||
#endif /* old code */
|
||||
}
|
||||
else if ( point->in_dir == -point->out_dir )
|
||||
goto Is_Weak_Point;
|
||||
|
@ -1152,7 +1268,7 @@
|
|||
AF_Point points = hints->points;
|
||||
AF_Point points_limit = points + hints->num_points;
|
||||
AF_Point point;
|
||||
|
||||
|
||||
|
||||
if ( dim == AF_DIMENSION_HORZ )
|
||||
{
|
||||
|
|
|
@ -590,6 +590,7 @@
|
|||
FT_Memory memory = hints->memory;
|
||||
FT_Error error = AF_Err_Ok;
|
||||
AF_Segment segment = NULL;
|
||||
AF_SegmentRec seg0;
|
||||
AF_Point* contour = hints->contours;
|
||||
AF_Point* contour_limit = contour + hints->num_contours;
|
||||
AF_Direction major_dir, segment_dir;
|
||||
|
@ -601,6 +602,10 @@
|
|||
FT_Pos max_coord = -32000;
|
||||
#endif
|
||||
|
||||
FT_ZERO( &seg0 );
|
||||
seg0.score = 32000;
|
||||
seg0.flags = AF_EDGE_NORMAL;
|
||||
|
||||
major_dir = (AF_Direction)FT_ABS( axis->major_dir );
|
||||
segment_dir = major_dir;
|
||||
|
||||
|
@ -742,15 +747,12 @@
|
|||
if ( error )
|
||||
goto Exit;
|
||||
|
||||
segment[0] = seg0;
|
||||
segment->dir = (FT_Char)segment_dir;
|
||||
segment->flags = AF_EDGE_NORMAL;
|
||||
min_pos = max_pos = point->u;
|
||||
segment->first = point;
|
||||
segment->last = point;
|
||||
segment->contour = contour;
|
||||
segment->score = 32000;
|
||||
segment->len = 0;
|
||||
segment->link = NULL;
|
||||
on_edge = 1;
|
||||
|
||||
#ifdef AF_HINT_METRICS
|
||||
|
@ -810,14 +812,11 @@
|
|||
if ( error )
|
||||
goto Exit;
|
||||
|
||||
segment[0] = seg0;
|
||||
segment->dir = segment_dir;
|
||||
segment->flags = AF_EDGE_NORMAL;
|
||||
segment->first = min_point;
|
||||
segment->last = min_point;
|
||||
segment->pos = min_pos;
|
||||
segment->score = 32000;
|
||||
segment->len = 0;
|
||||
segment->link = NULL;
|
||||
|
||||
segment = NULL;
|
||||
}
|
||||
|
@ -830,14 +829,11 @@
|
|||
if ( error )
|
||||
goto Exit;
|
||||
|
||||
segment[0] = seg0;
|
||||
segment->dir = segment_dir;
|
||||
segment->flags = AF_EDGE_NORMAL;
|
||||
segment->first = max_point;
|
||||
segment->last = max_point;
|
||||
segment->pos = max_pos;
|
||||
segment->score = 32000;
|
||||
segment->len = 0;
|
||||
segment->link = NULL;
|
||||
|
||||
segment = NULL;
|
||||
}
|
||||
|
@ -926,7 +922,6 @@
|
|||
|
||||
if ( seg2 )
|
||||
{
|
||||
seg2->num_linked++;
|
||||
if ( seg2->link != seg1 )
|
||||
{
|
||||
seg1->link = 0;
|
||||
|
|
|
@ -118,6 +118,7 @@ FT_BEGIN_HEADER
|
|||
#define AF_ANGLE_PI4 ( AF_ANGLE_PI / 4 )
|
||||
|
||||
|
||||
#if 0
|
||||
/*
|
||||
* compute the angle of a given 2-D vector
|
||||
*/
|
||||
|
@ -126,7 +127,6 @@ FT_BEGIN_HEADER
|
|||
FT_Pos dy );
|
||||
|
||||
|
||||
#if 0
|
||||
/*
|
||||
* compute `angle2 - angle1'; the result is always within
|
||||
* the range [-AF_ANGLE_PI .. AF_ANGLE_PI - 1]
|
||||
|
@ -137,6 +137,27 @@ FT_BEGIN_HEADER
|
|||
#endif /* 0 */
|
||||
|
||||
|
||||
/* return TRUE if a corner is flat, or nearly flat, this is equivalent
|
||||
* to say that the angle difference between the 'in' and 'out' vectors is
|
||||
* very small
|
||||
*/
|
||||
FT_LOCAL( FT_Int )
|
||||
af_corner_is_flat( FT_Pos x_in,
|
||||
FT_Pos y_in,
|
||||
FT_Pos x_out,
|
||||
FT_Pos y_out );
|
||||
|
||||
/* return a value that can be -1, 0 or +1 depending on the orientation
|
||||
* of a given corner. We're using the Cartesian coordinate system,
|
||||
* with positive Ys going upwards. The function returns +1 when
|
||||
* the corner turns to the left, -1 to the right, and 0 for undecided
|
||||
*/
|
||||
FT_LOCAL( FT_Int )
|
||||
af_corner_orientation( FT_Pos x_in,
|
||||
FT_Pos y_in,
|
||||
FT_Pos x_out,
|
||||
FT_Pos y_out );
|
||||
|
||||
#define AF_ANGLE_DIFF( result, angle1, angle2 ) \
|
||||
FT_BEGIN_STMNT \
|
||||
AF_Angle _delta = (angle2) - (angle1); \
|
||||
|
|
|
@ -396,7 +396,29 @@
|
|||
FT_MulFix( FT_Long a,
|
||||
FT_Long b )
|
||||
{
|
||||
#if 1
|
||||
/* let's use inline assembly to speed things a bit */
|
||||
#if defined(__GNUC__) && defined(i386)
|
||||
|
||||
FT_Long result;
|
||||
|
||||
__asm__ __volatile__ (
|
||||
"imul %%edx\n"
|
||||
"movl %%edx, %%ecx\n"
|
||||
"sarl $31, %%ecx\n"
|
||||
"addl $0x8000, %%ecx\n"
|
||||
"addl %%ecx, %%eax\n"
|
||||
"adcl $0, %%edx\n"
|
||||
"shrl $16, %%eax\n"
|
||||
"shll $16, %%edx\n"
|
||||
"addl %%edx, %%eax\n"
|
||||
"mov %%eax, %0\n"
|
||||
: "=r"(result)
|
||||
: "a"(a), "d"(b)
|
||||
: "%ecx"
|
||||
);
|
||||
return result;
|
||||
|
||||
#elif 1
|
||||
FT_Long sa, sb;
|
||||
FT_ULong ua, ub;
|
||||
|
||||
|
|
|
@ -732,7 +732,7 @@
|
|||
return ( n % 2 );
|
||||
}
|
||||
|
||||
|
||||
|
||||
static FT_Bool
|
||||
ft_contour_enclosed( FT_Outline* outline,
|
||||
FT_UShort c )
|
||||
|
@ -1012,11 +1012,25 @@
|
|||
++next;
|
||||
}
|
||||
|
||||
#if 1
|
||||
{
|
||||
FT_Pos dx1 = prev->x - xmin_point->x;
|
||||
FT_Pos dy1 = prev->y - xmin_point->y;
|
||||
FT_Pos dx2 = next->x - xmin_point->x;
|
||||
FT_Pos dy2 = next->y - xmin_point->y;
|
||||
|
||||
if ( dy1*dx2 > dy2*dx1 )
|
||||
return FT_ORIENTATION_POSTSCRIPT;
|
||||
else
|
||||
return FT_ORIENTATION_TRUETYPE;
|
||||
}
|
||||
#else
|
||||
if ( FT_Atan2( prev->x - xmin_point->x, prev->y - xmin_point->y ) >
|
||||
FT_Atan2( next->x - xmin_point->x, next->y - xmin_point->y ) )
|
||||
return FT_ORIENTATION_POSTSCRIPT;
|
||||
else
|
||||
return FT_ORIENTATION_TRUETYPE;
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -554,6 +554,27 @@
|
|||
}
|
||||
|
||||
|
||||
static FT_ULong
|
||||
ft_gzip_get_uncompressed_size( FT_Stream stream )
|
||||
{
|
||||
FT_Error error;
|
||||
FT_ULong old_pos;
|
||||
FT_ULong result = 0;
|
||||
|
||||
old_pos = stream->pos;
|
||||
if ( !FT_Stream_Seek( stream, stream->size - 4 ) )
|
||||
{
|
||||
result = (FT_ULong)FT_Stream_ReadLong( stream, &error );
|
||||
if ( error )
|
||||
result = 0;
|
||||
|
||||
FT_Stream_Seek( stream, old_pos );
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
FT_EXPORT_DEF( FT_Error )
|
||||
FT_Stream_OpenGzip( FT_Stream stream,
|
||||
FT_Stream source )
|
||||
|
@ -586,6 +607,47 @@
|
|||
stream->descriptor.pointer = zip;
|
||||
}
|
||||
|
||||
/* ok, here's a trick to try to dramatically improve the performance
|
||||
* of dealing with small files. If the original stream size is less
|
||||
* than a certain threshold, we try to load the whole font file in
|
||||
* memory. this saves us from the 32KB buffer needed to inflate the
|
||||
* file anyway, plus the two 4KB intermediate input/output buffers
|
||||
* used in the FT_GZipFile structure.
|
||||
*/
|
||||
{
|
||||
FT_ULong zip_size = ft_gzip_get_uncompressed_size( source );
|
||||
|
||||
if ( zip_size != 0 && zip_size < 40*1024 )
|
||||
{
|
||||
FT_Byte* zip_buff;
|
||||
|
||||
if ( !FT_ALLOC( zip_buff, zip_size ) )
|
||||
{
|
||||
FT_ULong count;
|
||||
|
||||
count = ft_gzip_file_io( zip, 0, zip_buff, zip_size );
|
||||
if ( count == zip_size )
|
||||
{
|
||||
ft_gzip_file_done( zip );
|
||||
FT_FREE( zip );
|
||||
|
||||
stream->descriptor.pointer = NULL;
|
||||
|
||||
stream->size = zip_size;
|
||||
stream->pos = 0;
|
||||
stream->base = zip_buff;
|
||||
stream->read = NULL;
|
||||
stream->close = ft_gzip_stream_close;
|
||||
|
||||
goto Exit;
|
||||
}
|
||||
ft_gzip_file_io( zip, 0, NULL, 0 );
|
||||
FT_FREE( zip_buff );
|
||||
}
|
||||
error = 0;
|
||||
}
|
||||
}
|
||||
|
||||
stream->size = 0x7FFFFFFFL; /* don't know the real size! */
|
||||
stream->pos = 0;
|
||||
stream->base = 0;
|
||||
|
|
|
@ -331,11 +331,48 @@
|
|||
FT_UInt n )
|
||||
{
|
||||
FT_Byte* p;
|
||||
FT_UInt r = 0;
|
||||
FT_UInt r = 0;
|
||||
FT_UInt w = 0;
|
||||
FT_UInt pad = 0x01;
|
||||
|
||||
|
||||
n *= 2;
|
||||
for ( p = *cursor; r < n && p < limit; p++ )
|
||||
#if 1
|
||||
p = *cursor;
|
||||
if ( n > (FT_UInt)(limit-p) )
|
||||
n = (FT_UInt)(limit - p);
|
||||
|
||||
/* we try to process two nibbles at a time to be as fast as possible
|
||||
*/
|
||||
for ( ; r < n; r++ )
|
||||
{
|
||||
FT_UInt c = p[r];
|
||||
|
||||
if ( IS_PS_SPACE(c) )
|
||||
continue;
|
||||
|
||||
if ( c OP 0x80 )
|
||||
break;
|
||||
|
||||
c = ft_char_table[ c & 0x7F ];
|
||||
if ( (unsigned)c >= 16 )
|
||||
break;
|
||||
|
||||
pad = (pad << 4) | c;
|
||||
if ( pad & 0x100 )
|
||||
{
|
||||
buffer[w++] = (FT_Byte)pad;
|
||||
pad = 0x01;
|
||||
}
|
||||
}
|
||||
|
||||
if ( pad != 0x01 )
|
||||
buffer[w++] = (FT_Byte)(pad << 4);
|
||||
|
||||
*cursor = p+r;
|
||||
return w;
|
||||
#else
|
||||
for ( r = 0; r < n; r++ )
|
||||
{
|
||||
FT_Char c;
|
||||
|
||||
|
@ -348,10 +385,10 @@
|
|||
|
||||
c = ft_char_table[*p & 0x7f];
|
||||
|
||||
if ( c < 0 || c >= 16 )
|
||||
if ( (unsigned)c >= 16 )
|
||||
break;
|
||||
|
||||
if ( r % 2 )
|
||||
if ( r & 1 )
|
||||
{
|
||||
*buffer = (FT_Byte)(*buffer + c);
|
||||
buffer++;
|
||||
|
@ -365,6 +402,7 @@
|
|||
*cursor = p;
|
||||
|
||||
return ( r + 1 ) / 2;
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
|
@ -377,9 +415,25 @@
|
|||
{
|
||||
FT_Byte* p;
|
||||
FT_UInt r;
|
||||
FT_UShort s = *seed;
|
||||
FT_UInt s = *seed;
|
||||
|
||||
#if 1
|
||||
p = *cursor;
|
||||
if ( n > (FT_UInt)(limit - p) )
|
||||
n = (FT_UInt)(limit - p);
|
||||
|
||||
for ( r = 0; r < n; r++ )
|
||||
{
|
||||
FT_UInt val = p[r];
|
||||
FT_UInt b = ( val ^ (s >> 8) );
|
||||
|
||||
s = ( (val + s)*52845U + 22719 ) & 0xFFFFU;
|
||||
buffer[r] = (FT_Byte) b;
|
||||
}
|
||||
|
||||
*cursor = p + n;
|
||||
*seed = (FT_UShort)s;
|
||||
#else
|
||||
for ( r = 0, p = *cursor; r < n && p < limit; r++, p++ )
|
||||
{
|
||||
FT_Byte b = (FT_Byte)( *p ^ ( s >> 8 ) );
|
||||
|
@ -388,9 +442,9 @@
|
|||
s = (FT_UShort)( ( *p + s ) * 52845U + 22719 );
|
||||
*buffer++ = b;
|
||||
}
|
||||
|
||||
*cursor = p;
|
||||
*seed = s;
|
||||
#endif
|
||||
|
||||
return r;
|
||||
}
|
||||
|
|
|
@ -188,6 +188,9 @@
|
|||
if ( FT_STREAM_SEEK( offset ) || FT_FRAME_ENTER( byte_count ) )
|
||||
return error;
|
||||
|
||||
loader->cursor = stream->cursor;
|
||||
loader->limit = stream->limit;
|
||||
|
||||
return TT_Err_Ok;
|
||||
}
|
||||
|
||||
|
@ -205,26 +208,26 @@
|
|||
FT_CALLBACK_DEF( FT_Error )
|
||||
TT_Load_Glyph_Header( TT_Loader loader )
|
||||
{
|
||||
FT_Stream stream = loader->stream;
|
||||
FT_Int byte_len = loader->byte_len - 10;
|
||||
FT_Byte* p = loader->cursor;
|
||||
FT_Byte* limit = loader->limit;
|
||||
|
||||
|
||||
if ( byte_len < 0 )
|
||||
if ( p + 10 > limit )
|
||||
return TT_Err_Invalid_Outline;
|
||||
|
||||
loader->n_contours = FT_GET_SHORT();
|
||||
loader->n_contours = FT_NEXT_SHORT(p);
|
||||
|
||||
loader->bbox.xMin = FT_GET_SHORT();
|
||||
loader->bbox.yMin = FT_GET_SHORT();
|
||||
loader->bbox.xMax = FT_GET_SHORT();
|
||||
loader->bbox.yMax = FT_GET_SHORT();
|
||||
loader->bbox.xMin = FT_NEXT_SHORT(p);
|
||||
loader->bbox.yMin = FT_NEXT_SHORT(p);
|
||||
loader->bbox.xMax = FT_NEXT_SHORT(p);
|
||||
loader->bbox.yMax = FT_NEXT_SHORT(p);
|
||||
|
||||
FT_TRACE5(( " # of contours: %d\n", loader->n_contours ));
|
||||
FT_TRACE5(( " xMin: %4d xMax: %4d\n", loader->bbox.xMin,
|
||||
loader->bbox.xMax ));
|
||||
FT_TRACE5(( " yMin: %4d yMax: %4d\n", loader->bbox.yMin,
|
||||
loader->bbox.yMax ));
|
||||
loader->byte_len = byte_len;
|
||||
loader->cursor = p;
|
||||
|
||||
return TT_Err_Ok;
|
||||
}
|
||||
|
@ -234,14 +237,14 @@
|
|||
TT_Load_Simple_Glyph( TT_Loader load )
|
||||
{
|
||||
FT_Error error;
|
||||
FT_Stream stream = load->stream;
|
||||
FT_Byte* p = load->cursor;
|
||||
FT_Byte* limit = load->limit;
|
||||
FT_GlyphLoader gloader = load->gloader;
|
||||
FT_Int n_contours = load->n_contours;
|
||||
FT_Outline* outline;
|
||||
TT_Face face = (TT_Face)load->face;
|
||||
FT_UShort n_ins;
|
||||
FT_Int n, n_points;
|
||||
FT_Int byte_len = load->byte_len;
|
||||
|
||||
FT_Byte *flag, *flag_limit;
|
||||
FT_Byte c, count;
|
||||
|
@ -260,12 +263,11 @@
|
|||
cont_limit = cont + n_contours;
|
||||
|
||||
/* check space for contours array + instructions count */
|
||||
byte_len -= 2 * ( n_contours + 1 );
|
||||
if ( byte_len < 0 )
|
||||
if ( n_contours >= 0xFFF || p + (n_contours+1)*2 > limit )
|
||||
goto Invalid_Outline;
|
||||
|
||||
for ( ; cont < cont_limit; cont++ )
|
||||
cont[0] = FT_GET_USHORT();
|
||||
cont[0] = FT_NEXT_USHORT(p);
|
||||
|
||||
n_points = 0;
|
||||
if ( n_contours > 0 )
|
||||
|
@ -287,7 +289,10 @@
|
|||
load->glyph->control_len = 0;
|
||||
load->glyph->control_data = 0;
|
||||
|
||||
n_ins = FT_GET_USHORT();
|
||||
if ( p+2 > limit )
|
||||
goto Invalid_Outline;
|
||||
|
||||
n_ins = FT_NEXT_USHORT(p);
|
||||
|
||||
FT_TRACE5(( " Instructions size: %u\n", n_ins ));
|
||||
|
||||
|
@ -298,8 +303,7 @@
|
|||
goto Fail;
|
||||
}
|
||||
|
||||
byte_len -= (FT_Int)n_ins;
|
||||
if ( byte_len < 0 )
|
||||
if ( (limit - p) < n_ins )
|
||||
{
|
||||
FT_TRACE0(( "TT_Load_Simple_Glyph: Instruction count mismatch!\n" ));
|
||||
error = TT_Err_Too_Many_Hints;
|
||||
|
@ -313,12 +317,12 @@
|
|||
load->glyph->control_len = n_ins;
|
||||
load->glyph->control_data = load->exec->glyphIns;
|
||||
|
||||
FT_MEM_COPY( load->exec->glyphIns, stream->cursor, (FT_Long)n_ins );
|
||||
FT_MEM_COPY( load->exec->glyphIns, p, (FT_Long)n_ins );
|
||||
}
|
||||
|
||||
#endif /* TT_CONFIG_OPTION_BYTECODE_INTERPRETER */
|
||||
|
||||
stream->cursor += (FT_Int)n_ins;
|
||||
p += n_ins;
|
||||
|
||||
/* reading the point tags */
|
||||
flag = (FT_Byte*)outline->tags;
|
||||
|
@ -328,16 +332,16 @@
|
|||
|
||||
while ( flag < flag_limit )
|
||||
{
|
||||
if ( --byte_len < 0 )
|
||||
if ( p+1 > limit )
|
||||
goto Invalid_Outline;
|
||||
|
||||
*flag++ = c = FT_GET_BYTE();
|
||||
*flag++ = c = FT_NEXT_BYTE(p);
|
||||
if ( c & 8 )
|
||||
{
|
||||
if ( --byte_len < 0 )
|
||||
if ( p+1 > limit )
|
||||
goto Invalid_Outline;
|
||||
|
||||
count = FT_GET_BYTE();
|
||||
count = FT_NEXT_BYTE(p);
|
||||
if ( flag + (FT_Int)count > flag_limit )
|
||||
goto Invalid_Outline;
|
||||
|
||||
|
@ -346,23 +350,6 @@
|
|||
}
|
||||
}
|
||||
|
||||
/* check that there is enough room to load the coordinates */
|
||||
for ( flag = (FT_Byte*)outline->tags; flag < flag_limit; flag++ )
|
||||
{
|
||||
if ( *flag & 2 )
|
||||
byte_len -= 1;
|
||||
else if ( ( *flag & 16 ) == 0 )
|
||||
byte_len -= 2;
|
||||
|
||||
if ( *flag & 4 )
|
||||
byte_len -= 1;
|
||||
else if ( ( *flag & 32 ) == 0 )
|
||||
byte_len -= 2;
|
||||
}
|
||||
|
||||
if ( byte_len < 0 )
|
||||
goto Invalid_Outline;
|
||||
|
||||
/* reading the X coordinates */
|
||||
|
||||
vec = outline->points;
|
||||
|
@ -377,12 +364,20 @@
|
|||
|
||||
if ( *flag & 2 )
|
||||
{
|
||||
y = (FT_Pos)FT_GET_BYTE();
|
||||
if ( p+1 > limit )
|
||||
goto Invalid_Outline;
|
||||
|
||||
y = (FT_Pos)FT_NEXT_BYTE(p);
|
||||
if ( ( *flag & 16 ) == 0 )
|
||||
y = -y;
|
||||
}
|
||||
else if ( ( *flag & 16 ) == 0 )
|
||||
y = (FT_Pos)FT_GET_SHORT();
|
||||
{
|
||||
if ( p+2 > limit )
|
||||
goto Invalid_Outline;
|
||||
|
||||
y = (FT_Pos)FT_NEXT_SHORT(p);
|
||||
}
|
||||
|
||||
x += y;
|
||||
vec->x = x;
|
||||
|
@ -402,12 +397,20 @@
|
|||
|
||||
if ( *flag & 4 )
|
||||
{
|
||||
y = (FT_Pos)FT_GET_BYTE();
|
||||
if ( p+1 > limit )
|
||||
goto Invalid_Outline;
|
||||
|
||||
y = (FT_Pos)FT_NEXT_BYTE(p);
|
||||
if ( ( *flag & 32 ) == 0 )
|
||||
y = -y;
|
||||
}
|
||||
else if ( ( *flag & 32 ) == 0 )
|
||||
y = (FT_Pos)FT_GET_SHORT();
|
||||
{
|
||||
if ( p+2 > limit )
|
||||
goto Invalid_Outline;
|
||||
|
||||
y = (FT_Pos)FT_NEXT_SHORT(p);
|
||||
}
|
||||
|
||||
x += y;
|
||||
vec->y = x;
|
||||
|
@ -420,7 +423,7 @@
|
|||
outline->n_points = (FT_UShort)n_points;
|
||||
outline->n_contours = (FT_Short) n_contours;
|
||||
|
||||
load->byte_len = byte_len;
|
||||
load->cursor = p;
|
||||
|
||||
Fail:
|
||||
return error;
|
||||
|
@ -435,11 +438,11 @@
|
|||
TT_Load_Composite_Glyph( TT_Loader loader )
|
||||
{
|
||||
FT_Error error;
|
||||
FT_Stream stream = loader->stream;
|
||||
FT_Byte* p = loader->cursor;
|
||||
FT_Byte* limit = loader->limit;
|
||||
FT_GlyphLoader gloader = loader->gloader;
|
||||
FT_SubGlyph subglyph;
|
||||
FT_UInt num_subglyphs;
|
||||
FT_Int byte_len = loader->byte_len;
|
||||
|
||||
|
||||
num_subglyphs = 0;
|
||||
|
@ -447,6 +450,7 @@
|
|||
do
|
||||
{
|
||||
FT_Fixed xx, xy, yy, yx;
|
||||
FT_UInt count;
|
||||
|
||||
|
||||
/* check that we can load a new subglyph */
|
||||
|
@ -455,41 +459,40 @@
|
|||
goto Fail;
|
||||
|
||||
/* check space */
|
||||
byte_len -= 4;
|
||||
if ( byte_len < 0 )
|
||||
if ( p+4 > limit )
|
||||
goto Invalid_Composite;
|
||||
|
||||
subglyph = gloader->current.subglyphs + num_subglyphs;
|
||||
|
||||
subglyph->arg1 = subglyph->arg2 = 0;
|
||||
|
||||
subglyph->flags = FT_GET_USHORT();
|
||||
subglyph->index = FT_GET_USHORT();
|
||||
subglyph->flags = FT_NEXT_USHORT(p);
|
||||
subglyph->index = FT_NEXT_USHORT(p);
|
||||
|
||||
/* check space */
|
||||
byte_len -= 2;
|
||||
count = 2;
|
||||
if ( subglyph->flags & ARGS_ARE_WORDS )
|
||||
byte_len -= 2;
|
||||
count += 2;
|
||||
if ( subglyph->flags & WE_HAVE_A_SCALE )
|
||||
byte_len -= 2;
|
||||
count += 2;
|
||||
else if ( subglyph->flags & WE_HAVE_AN_XY_SCALE )
|
||||
byte_len -= 4;
|
||||
count += 4;
|
||||
else if ( subglyph->flags & WE_HAVE_A_2X2 )
|
||||
byte_len -= 8;
|
||||
count += 8;
|
||||
|
||||
if ( byte_len < 0 )
|
||||
if ( p + count > limit )
|
||||
goto Invalid_Composite;
|
||||
|
||||
/* read arguments */
|
||||
if ( subglyph->flags & ARGS_ARE_WORDS )
|
||||
{
|
||||
subglyph->arg1 = FT_GET_SHORT();
|
||||
subglyph->arg2 = FT_GET_SHORT();
|
||||
subglyph->arg1 = FT_NEXT_SHORT(p);
|
||||
subglyph->arg2 = FT_NEXT_SHORT(p);
|
||||
}
|
||||
else
|
||||
{
|
||||
subglyph->arg1 = FT_GET_CHAR();
|
||||
subglyph->arg2 = FT_GET_CHAR();
|
||||
subglyph->arg1 = FT_NEXT_CHAR(p);
|
||||
subglyph->arg2 = FT_NEXT_CHAR(p);
|
||||
}
|
||||
|
||||
/* read transform */
|
||||
|
@ -498,20 +501,20 @@
|
|||
|
||||
if ( subglyph->flags & WE_HAVE_A_SCALE )
|
||||
{
|
||||
xx = (FT_Fixed)FT_GET_SHORT() << 2;
|
||||
xx = (FT_Fixed)FT_NEXT_SHORT(p) << 2;
|
||||
yy = xx;
|
||||
}
|
||||
else if ( subglyph->flags & WE_HAVE_AN_XY_SCALE )
|
||||
{
|
||||
xx = (FT_Fixed)FT_GET_SHORT() << 2;
|
||||
yy = (FT_Fixed)FT_GET_SHORT() << 2;
|
||||
xx = (FT_Fixed)FT_NEXT_SHORT(p) << 2;
|
||||
yy = (FT_Fixed)FT_NEXT_SHORT(p) << 2;
|
||||
}
|
||||
else if ( subglyph->flags & WE_HAVE_A_2X2 )
|
||||
{
|
||||
xx = (FT_Fixed)FT_GET_SHORT() << 2;
|
||||
yx = (FT_Fixed)FT_GET_SHORT() << 2;
|
||||
xy = (FT_Fixed)FT_GET_SHORT() << 2;
|
||||
yy = (FT_Fixed)FT_GET_SHORT() << 2;
|
||||
xx = (FT_Fixed)FT_NEXT_SHORT(p) << 2;
|
||||
yx = (FT_Fixed)FT_NEXT_SHORT(p) << 2;
|
||||
xy = (FT_Fixed)FT_NEXT_SHORT(p) << 2;
|
||||
yy = (FT_Fixed)FT_NEXT_SHORT(p) << 2;
|
||||
}
|
||||
|
||||
subglyph->transform.xx = xx;
|
||||
|
@ -533,12 +536,12 @@
|
|||
/* we will process them later... */
|
||||
/* */
|
||||
loader->ins_pos = (FT_ULong)( FT_STREAM_POS() +
|
||||
stream->cursor - stream->limit );
|
||||
p - limit );
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
loader->byte_len = byte_len;
|
||||
loader->cursor = p;
|
||||
|
||||
Fail:
|
||||
return error;
|
||||
|
|
|
@ -310,11 +310,14 @@
|
|||
|
||||
#if 1
|
||||
/* apply the font matrix, if any */
|
||||
FT_Outline_Transform( &glyph->root.outline, &font_matrix );
|
||||
if ( font_matrix.xx != 0x10000L || font_matrix.yy != font_matrix.xx ||
|
||||
font_matrix.xy != 0 || font_matrix.yx != 0 )
|
||||
FT_Outline_Transform( &glyph->root.outline, &font_matrix );
|
||||
|
||||
FT_Outline_Translate( &glyph->root.outline,
|
||||
font_offset.x,
|
||||
font_offset.y );
|
||||
if ( font_offset.x || font_offset.y )
|
||||
FT_Outline_Translate( &glyph->root.outline,
|
||||
font_offset.x,
|
||||
font_offset.y );
|
||||
|
||||
advance.x = metrics->horiAdvance;
|
||||
advance.y = 0;
|
||||
|
|
Loading…
Reference in New Issue