* src/truetype/ttpload.c (tt_face_load_hdmx): Handle `record_size'
values which have the upper two bytes set to 0xFF instead of 0xFF (as it happens in at least two CJKV fonts, `HAN NOM A.ttf' and `HAN NOM B.ttf'). * src/smooth/ftgrays.c [GRAYS_USE_GAMMA]: Really remove all code. Formatting.
This commit is contained in:
parent
2066e0acd6
commit
36d2eab054
26
ChangeLog
26
ChangeLog
|
@ -1,10 +1,28 @@
|
|||
2006-09-05 Werner Lemberg <wl@gnu.org>
|
||||
|
||||
* src/truetype/ttpload.c (tt_face_load_hdmx): Handle `record_size'
|
||||
values which have the upper two bytes set to 0xFF instead of 0xFF
|
||||
(as it happens in at least two CJKV fonts, `HAN NOM A.ttf' and
|
||||
`HAN NOM B.ttf').
|
||||
|
||||
* src/smooth/ftgrays.c [GRAYS_USE_GAMMA]: Really remove all code.
|
||||
|
||||
2006-09-05 David Turner <david@freetype.org>
|
||||
|
||||
* src/smooth/ftgrays.c: minor source cleanups and optimization
|
||||
|
||||
* src/smooth/ftgrays.c (gray_sweep): Avoid buffer overwrites
|
||||
when to drawing the end of a bitmap scanline. The fun never ends ;-)
|
||||
Minor source cleanups and optimizations.
|
||||
|
||||
* src/smooth/ftgrays.c (GRAYS_COMPACT): Removed.
|
||||
(TRaster): Remove `count_ex' and `count_ey'.
|
||||
(gray_find_cell): Remove 2nd and 3rd argument.
|
||||
(gray_alloc_cell): Merged with `gray_find_cell'.
|
||||
(gray_record_cell): Simplify.
|
||||
(gray_set_cell): Rewrite.
|
||||
(gray_start_cell): Apply offsets to `ras.ex' and `ras.ey'.
|
||||
(gray_render_span): Don't use FT_MEM_SET for small values.
|
||||
(gray_dump_cells) [DEBUG_GRAYS]: New function.
|
||||
(gray_sweep): Avoid buffer overwrites when to drawing the end of a
|
||||
bitmap scanline.
|
||||
(gray_convert_glyph): Fix speed-up.
|
||||
|
||||
2006-09-04 David Turner <david@freetype.org>
|
||||
|
||||
|
|
|
@ -91,7 +91,7 @@
|
|||
#define FT_COMPONENT trace_smooth
|
||||
|
||||
|
||||
#define ErrRaster_MemoryOverflow -4
|
||||
#define ErrRaster_MemoryOverflow -4
|
||||
|
||||
|
||||
#ifdef _STANDALONE_
|
||||
|
@ -160,6 +160,7 @@
|
|||
/* define this to dump debugging information */
|
||||
#define xxxDEBUG_GRAYS
|
||||
|
||||
|
||||
/* as usual, for the speed hungry :-) */
|
||||
|
||||
#ifndef FT_STATIC_RASTER
|
||||
|
@ -207,6 +208,7 @@
|
|||
#define DOWNSCALE( x ) ( (x) << ( 6 - PIXEL_BITS ) )
|
||||
#endif
|
||||
|
||||
|
||||
/*************************************************************************/
|
||||
/* */
|
||||
/* TYPE DEFINITIONS */
|
||||
|
@ -225,7 +227,7 @@
|
|||
|
||||
#if PIXEL_BITS <= 7
|
||||
|
||||
typedef int TArea;
|
||||
typedef int TArea;
|
||||
|
||||
#else /* PIXEL_BITS >= 8 */
|
||||
|
||||
|
@ -233,7 +235,7 @@
|
|||
#if FT_UINT_MAX == 0xFFFFU
|
||||
typedef long TArea;
|
||||
#else
|
||||
typedef int TArea;
|
||||
typedef int TArea;
|
||||
#endif
|
||||
|
||||
#endif /* PIXEL_BITS >= 8 */
|
||||
|
@ -242,17 +244,17 @@
|
|||
/* maximal number of gray spans in a call to the span callback */
|
||||
#define FT_MAX_GRAY_SPANS 32
|
||||
|
||||
typedef struct TCell_* PCell;
|
||||
|
||||
typedef struct TCell_
|
||||
{
|
||||
int x;
|
||||
int cover;
|
||||
TArea area;
|
||||
PCell next;
|
||||
typedef struct TCell_* PCell;
|
||||
|
||||
} TCell;
|
||||
typedef struct TCell_
|
||||
{
|
||||
int x;
|
||||
int cover;
|
||||
TArea area;
|
||||
PCell next;
|
||||
|
||||
} TCell;
|
||||
|
||||
|
||||
typedef struct TRaster_
|
||||
|
@ -382,7 +384,7 @@ typedef struct TCell_
|
|||
int x = ras.ex;
|
||||
|
||||
|
||||
pcell = &ras.ycells[ ras.ey ];
|
||||
pcell = &ras.ycells[ras.ey];
|
||||
for (;;)
|
||||
{
|
||||
cell = *pcell;
|
||||
|
@ -414,9 +416,10 @@ typedef struct TCell_
|
|||
static void
|
||||
gray_record_cell( RAS_ARG )
|
||||
{
|
||||
if ( !ras.invalid && (ras.area | ras.cover) )
|
||||
if ( !ras.invalid && ( ras.area | ras.cover ) )
|
||||
{
|
||||
PCell cell = gray_find_cell( RAS_VAR );
|
||||
PCell cell = gray_find_cell( RAS_VAR );
|
||||
|
||||
|
||||
cell->area += ras.area;
|
||||
cell->cover += ras.cover;
|
||||
|
@ -463,7 +466,7 @@ typedef struct TCell_
|
|||
ras.ex = ex;
|
||||
ras.ey = ey;
|
||||
ras.invalid = ( (unsigned)ey >= (unsigned)ras.count_ey ||
|
||||
ex >= ras.count_ex );
|
||||
ex >= ras.count_ex );
|
||||
}
|
||||
|
||||
|
||||
|
@ -472,11 +475,11 @@ typedef struct TCell_
|
|||
/* Start a new contour at a given cell. */
|
||||
/* */
|
||||
static void
|
||||
gray_start_cell( RAS_ARG_ TCoord ex,
|
||||
TCoord ey )
|
||||
gray_start_cell( RAS_ARG_ TCoord ex,
|
||||
TCoord ey )
|
||||
{
|
||||
if ( ex < ras.min_ex )
|
||||
ex = (TCoord)(ras.min_ex - 1);
|
||||
ex = (TCoord)( ras.min_ex - 1 );
|
||||
|
||||
ras.area = 0;
|
||||
ras.cover = 0;
|
||||
|
@ -494,11 +497,11 @@ typedef struct TCell_
|
|||
/* Render a scanline as one or more cells. */
|
||||
/* */
|
||||
static void
|
||||
gray_render_scanline( RAS_ARG_ TCoord ey,
|
||||
TPos x1,
|
||||
TCoord y1,
|
||||
TPos x2,
|
||||
TCoord y2 )
|
||||
gray_render_scanline( RAS_ARG_ TCoord ey,
|
||||
TPos x1,
|
||||
TCoord y1,
|
||||
TPos x2,
|
||||
TCoord y2 )
|
||||
{
|
||||
TCoord ex1, ex2, fx1, fx2, delta;
|
||||
long p, first, dx;
|
||||
|
@ -611,7 +614,7 @@ typedef struct TCell_
|
|||
|
||||
|
||||
ey1 = TRUNC( ras.last_ey );
|
||||
ey2 = TRUNC( to_y ); /* if (ey2 >= ras.max_ey) ey2 = ras.max_ey-1; */
|
||||
ey2 = TRUNC( to_y ); /* if (ey2 >= ras.max_ey) ey2 = ras.max_ey-1; */
|
||||
fy1 = (TCoord)( ras.y - ras.last_ey );
|
||||
fy2 = (TCoord)( to_y - SUBPIXELS( ey2 ) );
|
||||
|
||||
|
@ -675,12 +678,14 @@ typedef struct TCell_
|
|||
ras.area += area;
|
||||
ras.cover += delta;
|
||||
ey1 += incr;
|
||||
|
||||
gray_set_cell( raster, ex, ey1 );
|
||||
}
|
||||
|
||||
delta = (int)( fy2 - ONE_PIXEL + first );
|
||||
ras.area += (TArea)two_fx * delta;
|
||||
ras.cover += delta;
|
||||
|
||||
goto End;
|
||||
}
|
||||
|
||||
|
@ -807,7 +812,7 @@ typedef struct TCell_
|
|||
{
|
||||
/* we compute the mid-point directly in order to avoid */
|
||||
/* calling gray_split_conic() */
|
||||
TPos to_x, to_y, mid_x, mid_y;
|
||||
TPos to_x, to_y, mid_x, mid_y;
|
||||
|
||||
|
||||
to_x = UPSCALE( to->x );
|
||||
|
@ -817,6 +822,7 @@ typedef struct TCell_
|
|||
|
||||
gray_render_line( RAS_VAR_ mid_x, mid_y );
|
||||
gray_render_line( RAS_VAR_ to_x, to_y );
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -878,6 +884,7 @@ typedef struct TCell_
|
|||
arc -= 2;
|
||||
}
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -1026,6 +1033,7 @@ typedef struct TCell_
|
|||
arc -= 3;
|
||||
}
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -1106,27 +1114,28 @@ typedef struct TCell_
|
|||
|
||||
if ( coverage )
|
||||
{
|
||||
/* for small-spans, it's faster to do it ourselves than
|
||||
* calling memset. this is mainly due to the cost of the
|
||||
* function call.
|
||||
*/
|
||||
/* For small-spans it is faster to do it by ourselves than
|
||||
* calling `memset'. This is mainly due to the cost of the
|
||||
* function call.
|
||||
*/
|
||||
if ( spans->len >= 8 )
|
||||
FT_MEM_SET( p + spans->x, (unsigned char)coverage, spans->len );
|
||||
else
|
||||
{
|
||||
unsigned char* q = p + spans->x;
|
||||
|
||||
|
||||
switch ( spans->len )
|
||||
{
|
||||
case 7: *q++ = (unsigned char)coverage;
|
||||
case 6: *q++ = (unsigned char)coverage;
|
||||
case 5: *q++ = (unsigned char)coverage;
|
||||
case 4: *q++ = (unsigned char)coverage;
|
||||
case 3: *q++ = (unsigned char)coverage;
|
||||
case 2: *q++ = (unsigned char)coverage;
|
||||
case 1: *q = (unsigned char)coverage;
|
||||
default:
|
||||
;
|
||||
case 7: *q++ = (unsigned char)coverage;
|
||||
case 6: *q++ = (unsigned char)coverage;
|
||||
case 5: *q++ = (unsigned char)coverage;
|
||||
case 4: *q++ = (unsigned char)coverage;
|
||||
case 3: *q++ = (unsigned char)coverage;
|
||||
case 2: *q++ = (unsigned char)coverage;
|
||||
case 1: *q = (unsigned char)coverage;
|
||||
default:
|
||||
;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1140,9 +1149,9 @@ typedef struct TCell_
|
|||
TPos area,
|
||||
int acount )
|
||||
{
|
||||
FT_Span* span;
|
||||
int count;
|
||||
int coverage;
|
||||
FT_Span* span;
|
||||
int count;
|
||||
int coverage;
|
||||
|
||||
|
||||
/* compute the coverage line's coverage, depending on the */
|
||||
|
@ -1176,13 +1185,13 @@ typedef struct TCell_
|
|||
|
||||
if ( coverage )
|
||||
{
|
||||
/* see if we can add this span to the current list */
|
||||
/* see whether we can add this span to the current list */
|
||||
count = ras.num_gray_spans;
|
||||
span = ras.gray_spans + count - 1;
|
||||
if ( count > 0 &&
|
||||
ras.span_y == y &&
|
||||
(int)span->x + span->len == (int)x &&
|
||||
span->coverage == coverage )
|
||||
span->coverage == coverage )
|
||||
{
|
||||
span->len = (unsigned short)( span->len + acount );
|
||||
return;
|
||||
|
@ -1225,6 +1234,7 @@ typedef struct TCell_
|
|||
span->x = (short)x;
|
||||
span->len = (unsigned short)acount;
|
||||
span->coverage = (unsigned char)coverage;
|
||||
|
||||
ras.num_gray_spans++;
|
||||
}
|
||||
}
|
||||
|
@ -1237,10 +1247,12 @@ typedef struct TCell_
|
|||
{
|
||||
int yindex;
|
||||
|
||||
|
||||
for ( yindex = 0; yindex < ras.ycount; yindex++ )
|
||||
{
|
||||
PCell cell;
|
||||
|
||||
|
||||
printf( "%3d:", yindex );
|
||||
|
||||
for ( cell = ras.ycells[yindex]; cell != NULL; cell = cell->next )
|
||||
|
@ -1380,8 +1392,11 @@ typedef struct TCell_
|
|||
v_start = outline->points[first];
|
||||
v_last = outline->points[last];
|
||||
|
||||
v_start.x = SCALED( v_start.x ); v_start.y = SCALED( v_start.y );
|
||||
v_last.x = SCALED( v_last.x ); v_last.y = SCALED( v_last.y );
|
||||
v_start.x = SCALED( v_start.x );
|
||||
v_start.y = SCALED( v_start.y );
|
||||
|
||||
v_last.x = SCALED( v_last.x );
|
||||
v_last.y = SCALED( v_last.y );
|
||||
|
||||
v_control = v_start;
|
||||
|
||||
|
@ -1464,7 +1479,8 @@ typedef struct TCell_
|
|||
|
||||
if ( tag == FT_CURVE_TAG_ON )
|
||||
{
|
||||
error = func_interface->conic_to( &v_control, &vec, user );
|
||||
error = func_interface->conic_to( &v_control, &vec,
|
||||
user );
|
||||
if ( error )
|
||||
goto Exit;
|
||||
continue;
|
||||
|
@ -1476,7 +1492,8 @@ typedef struct TCell_
|
|||
v_middle.x = ( v_control.x + vec.x ) / 2;
|
||||
v_middle.y = ( v_control.y + vec.y ) / 2;
|
||||
|
||||
error = func_interface->conic_to( &v_control, &v_middle, user );
|
||||
error = func_interface->conic_to( &v_control, &v_middle,
|
||||
user );
|
||||
if ( error )
|
||||
goto Exit;
|
||||
|
||||
|
@ -1484,7 +1501,8 @@ typedef struct TCell_
|
|||
goto Do_Conic;
|
||||
}
|
||||
|
||||
error = func_interface->conic_to( &v_control, &v_start, user );
|
||||
error = func_interface->conic_to( &v_control, &v_start,
|
||||
user );
|
||||
goto Close;
|
||||
}
|
||||
|
||||
|
@ -1500,8 +1518,11 @@ typedef struct TCell_
|
|||
point += 2;
|
||||
tags += 2;
|
||||
|
||||
vec1.x = SCALED( point[-2].x ); vec1.y = SCALED( point[-2].y );
|
||||
vec2.x = SCALED( point[-1].x ); vec2.y = SCALED( point[-1].y );
|
||||
vec1.x = SCALED( point[-2].x );
|
||||
vec1.y = SCALED( point[-2].y );
|
||||
|
||||
vec2.x = SCALED( point[-1].x );
|
||||
vec2.y = SCALED( point[-1].y );
|
||||
|
||||
if ( point <= limit )
|
||||
{
|
||||
|
@ -1689,13 +1710,13 @@ typedef struct TCell_
|
|||
ras.invalid = 1;
|
||||
ras.min_ey = band->min;
|
||||
ras.max_ey = band->max;
|
||||
ras.count_ey = band->max - band->min;
|
||||
ras.count_ey = band->max - band->min;
|
||||
|
||||
error = gray_convert_glyph_inner( RAS_VAR );
|
||||
|
||||
if ( !error )
|
||||
{
|
||||
gray_sweep( RAS_VAR_ &ras.target );
|
||||
gray_sweep( RAS_VAR_ &ras.target );
|
||||
band--;
|
||||
continue;
|
||||
}
|
||||
|
@ -1703,13 +1724,13 @@ typedef struct TCell_
|
|||
return 1;
|
||||
|
||||
ReduceBands:
|
||||
/* render pool overflow, we will reduce the render band by half */
|
||||
/* render pool overflow; we will reduce the render band by half */
|
||||
bottom = band->min;
|
||||
top = band->max;
|
||||
middle = bottom + ( ( top - bottom ) >> 1 );
|
||||
|
||||
/* waoow! This is too complex for a single scanline, something */
|
||||
/* must be really rotten here! */
|
||||
/* This is too complex for a single scanline; there must */
|
||||
/* be some problems. */
|
||||
if ( middle == bottom )
|
||||
{
|
||||
#ifdef DEBUG_GRAYS
|
||||
|
@ -1825,10 +1846,6 @@ typedef struct TCell_
|
|||
*araster = (FT_Raster)&the_raster;
|
||||
FT_MEM_ZERO( &the_raster, sizeof ( the_raster ) );
|
||||
|
||||
#ifdef GRAYS_USE_GAMMA
|
||||
grays_init_gamma( (PRaster)*araster );
|
||||
#endif
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -1855,10 +1872,6 @@ typedef struct TCell_
|
|||
{
|
||||
raster->memory = memory;
|
||||
*araster = (FT_Raster)raster;
|
||||
|
||||
#ifdef GRAYS_USE_GAMMA
|
||||
grays_init_gamma( raster );
|
||||
#endif
|
||||
}
|
||||
|
||||
return error;
|
||||
|
@ -1878,9 +1891,9 @@ typedef struct TCell_
|
|||
|
||||
|
||||
static void
|
||||
gray_raster_reset( FT_Raster raster,
|
||||
char* pool_base,
|
||||
long pool_size )
|
||||
gray_raster_reset( FT_Raster raster,
|
||||
char* pool_base,
|
||||
long pool_size )
|
||||
{
|
||||
PRaster rast = (PRaster)raster;
|
||||
|
||||
|
|
|
@ -562,7 +562,23 @@
|
|||
num_records = FT_NEXT_USHORT( p );
|
||||
record_size = FT_NEXT_ULONG( p );
|
||||
|
||||
if ( version != 0 || num_records > 255 || record_size > 0x40000 )
|
||||
/* The maximum number of bytes in an hdmx device record is the */
|
||||
/* maximum number of glyphs + 2; this is 0xFFFF + 2; this is */
|
||||
/* the reason why `record_size' is a long (which we read as */
|
||||
/* unsigned long for convenience). In practice, two bytes */
|
||||
/* sufficient to hold the size value. */
|
||||
/* */
|
||||
/* There are at least two fonts, HANNOM-A and HANNOM-B version */
|
||||
/* 2.0 (2005), which get this wrong: The upper two bytes of */
|
||||
/* the size value are set to 0xFF instead of 0x00. We catch */
|
||||
/* and fix this. */
|
||||
|
||||
if ( record_size >= 0xFFFF0000UL )
|
||||
record_size &= 0xFFFFU;
|
||||
|
||||
/* The limit for `num_records' is a heuristic value. */
|
||||
|
||||
if ( version != 0 || num_records > 255 || record_size > 0x10001L )
|
||||
{
|
||||
error = TT_Err_Invalid_File_Format;
|
||||
goto Fail;
|
||||
|
@ -638,12 +654,25 @@
|
|||
|
||||
FT_FRAME_EXIT();
|
||||
|
||||
/* The maximum number of bytes in an hdmx device record is the */
|
||||
/* maximum number of glyphs + 2; this is 0xFFFF + 2; this is */
|
||||
/* the reason why `record_size' is a long. In practice, two */
|
||||
/* bytes sufficient to hold the size value. */
|
||||
/* */
|
||||
/* There are at least two fonts, HANNOM-A and HANNOM-B version */
|
||||
/* 2.0 (2005), which get this wrong: The upper two bytes of */
|
||||
/* the size value are set to 0xFF instead of 0x00. We catch */
|
||||
/* and fix this. */
|
||||
|
||||
if ( (FT_ULong)record_size >= 0xFFFF0000UL )
|
||||
record_size = (FT_Long)( (FT_ULong)record_size & 0xFFFFU );
|
||||
|
||||
if ( record_size < 0 || num_records < 0 )
|
||||
return TT_Err_Invalid_File_Format;
|
||||
|
||||
/* Only recognize format 0 */
|
||||
if ( hdmx->version != 0 )
|
||||
goto Exit;
|
||||
return TT_Err_Invalid_File_Format;
|
||||
|
||||
/* we can't use FT_QNEW_ARRAY here; otherwise tt_face_free_hdmx */
|
||||
/* could fail during deallocation */
|
||||
|
|
Loading…
Reference in New Issue