upgrading to 2.1.4

git-svn-id: file:///srv/svn/repos/haiku/trunk/current@4058 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
DarkWyrm
2003-07-24 18:52:56 +00:00
parent f5a286efe2
commit 36310414d9
314 changed files with 6457 additions and 5019 deletions
+3 -1
View File
@@ -32,7 +32,9 @@
{
"THEZOCQS",
"HEZLOCUS",
#ifdef FT_CONFIG_CHESTER_SMALL_F
"fijkdbh",
#endif
"xzroesc",
"xzroesc",
"pqgjy"
@@ -321,7 +323,7 @@
if ( error )
goto Exit;
error = ah_outline_load( hinter->glyph, hinter->face );
error = ah_outline_load( hinter->glyph, 0x10000L, 0x10000L, hinter->face );
if ( error )
goto Exit;
+9 -3
View File
@@ -32,9 +32,15 @@
FT_BEGIN_HEADER
#define AH_IS_TOP_BLUE( b ) ( (b) == AH_BLUE_CAPITAL_TOP || \
(b) == AH_BLUE_SMALL_TOP || \
(b) == AH_BLUE_SMALL_F_TOP )
#ifdef FT_CONFIG_CHESTER_SMALL_F
# define AH_IS_TOP_BLUE( b ) ( (b) == AH_BLUE_CAPITAL_TOP || (b) == AH_BLUE_SMALL_F_TOP || (b) == AH_BLUE_SMALL_TOP )
#else /* !CHESTER_SMALL_F */
# define AH_IS_TOP_BLUE( b ) ( (b) == AH_BLUE_CAPITAL_TOP || (b) == AH_BLUE_SMALL_TOP )
#endif /* !CHESTER_SMALL_F */
/* compute global metrics automatically */
+18 -5
View File
@@ -389,6 +389,8 @@
/* */
FT_LOCAL_DEF( FT_Error )
ah_outline_load( AH_Outline outline,
FT_Fixed x_scale,
FT_Fixed y_scale,
FT_Face face )
{
FT_Memory memory = outline->memory;
@@ -461,8 +463,8 @@
outline->horz_major_dir = AH_DIR_RIGHT;
}
outline->x_scale = face->size->metrics.x_scale;
outline->y_scale = face->size->metrics.y_scale;
outline->x_scale = x_scale;
outline->y_scale = y_scale;
points = outline->points;
if ( outline->num_points == 0 )
@@ -478,8 +480,6 @@
/* compute coordinates */
{
FT_Vector* vec = source->points;
FT_Fixed x_scale = outline->x_scale;
FT_Fixed y_scale = outline->y_scale;
for ( point = points; point < point_limit; vec++, point++ )
@@ -1350,13 +1350,20 @@
else
edge2 = seg2->edge;
#ifdef FT_CONFIG_CHESTER_SERIF
if ( is_serif )
{
edge->serif = edge2;
edge->serif = edge2;
edge2->flags |= AH_EDGE_SERIF;
}
else
edge->link = edge2;
#else /* !CHESTER_SERIF */
if ( is_serif )
edge->serif = edge2;
else
edge->link = edge2;
#endif
}
seg = seg->edge_next;
@@ -1480,8 +1487,14 @@
/* compute the initial threshold as a fraction of the EM size */
best_dist = FT_MulFix( face_globals->face->units_per_EM / 40, y_scale );
#ifdef FT_CONFIG_CHESTER_SMALL_F
if ( best_dist > 64 / 2 )
best_dist = 64 / 2;
#else
if ( best_dist > 64 / 4 )
best_dist = 64 / 4;
#endif
for ( blue = AH_BLUE_CAPITAL_TOP; blue < AH_BLUE_MAX; blue++ )
{
+2
View File
@@ -58,6 +58,8 @@ FT_BEGIN_HEADER
FT_LOCAL( FT_Error )
ah_outline_load( AH_Outline outline,
FT_Fixed x_scale,
FT_Fixed y_scale,
FT_Face face );
FT_LOCAL( void )
+250 -130
View File
@@ -28,9 +28,7 @@
#define FACE_GLOBALS( face ) ((AH_Face_Globals)(face)->autohint.data)
#define ABSVAL( x ) ( ( ( x ) < 0 ) ? -( x ) : ( x ))
#define SMOOTH_DEFAULT
#define AH_USE_IUP
#define OPTIM_STEM_SNAP
@@ -90,12 +88,13 @@
/* compute the snapped width of a given stem */
#ifdef FT_CONFIG_CHESTER_SERIF
static FT_Pos
ah_compute_stem_width( AH_Hinter hinter,
int vertical,
FT_Pos width,
AH_Edge_Flags base_flags,
AH_Edge_Flags stem_flags )
ah_compute_stem_width( AH_Hinter hinter,
int vertical,
FT_Pos width,
AH_Edge_Flags base_flags,
AH_Edge_Flags stem_flags )
{
AH_Globals globals = &hinter->globals->scaled;
FT_Pos dist = width;
@@ -108,21 +107,26 @@
sign = 1;
}
if ( ( vertical && !hinter->do_vert_snapping ) ||
( !vertical && !hinter->do_horz_snapping ) )
if ( !hinter->do_stem_adjust )
{
/* leave stem widths unchanged */
}
else if ( ( vertical && !hinter->do_vert_snapping ) ||
( !vertical && !hinter->do_horz_snapping ) )
{
/* smooth hinting process, very lightly quantize the stem width */
/* */
/* leave the widths of serifs alone */
if ( ( stem_flags & AH_EDGE_SERIF ) && vertical && ( dist < 3 * 64 ) )
goto Done_Width;
else if ( ( base_flags & AH_EDGE_ROUND ) ) {
if ( dist < 96 )
else if ( ( base_flags & AH_EDGE_ROUND ) )
{
if ( dist < 80 )
dist = 64;
}
else if ( dist < 56 )
dist = 56;
@@ -138,7 +142,8 @@
dist = globals->stds[vertical];
if ( dist < 48 )
dist = 48;
goto Done_Width;
goto Done_Width;
}
if ( dist < 3 * 64 )
@@ -205,9 +210,121 @@
dist = ( dist + 32 ) & -64;
}
}
}
Done_Width:
Done_Width:
if ( sign )
dist = -dist;
return dist;
}
#else /* !CHESTER_SERIF */
static FT_Pos
ah_compute_stem_width( AH_Hinter hinter,
int vertical,
FT_Pos width )
{
AH_Globals globals = &hinter->globals->scaled;
FT_Pos dist = width;
FT_Int sign = 0;
if ( dist < 0 )
{
dist = -width;
sign = 1;
}
if ( !hinter->do_stem_adjust )
{
/* leave stem widths unchanged */
}
else if ( ( vertical && !hinter->do_vert_snapping ) ||
( !vertical && !hinter->do_horz_snapping ) )
{
/* smooth hinting process, very lightly quantize the stem width */
/* */
if ( dist < 64 )
dist = 64;
{
FT_Pos delta = dist - globals->stds[vertical];
if ( delta < 0 )
delta = -delta;
if ( delta < 40 )
{
dist = globals->stds[vertical];
if ( dist < 48 )
dist = 48;
}
if ( dist < 3 * 64 )
{
delta = ( dist & 63 );
dist &= -64;
if ( delta < 10 )
dist += delta;
else if ( delta < 32 )
dist += 10;
else if ( delta < 54 )
dist += 54;
else
dist += delta;
}
else
dist = ( dist + 32 ) & -64;
}
}
else
{
/* strong hinting process, snap the stem width to integer pixels */
/* */
if ( vertical )
{
dist = ah_snap_width( globals->heights, globals->num_heights, dist );
/* in the case of vertical hinting, always round */
/* the stem heights to integer pixels */
if ( dist >= 64 )
dist = ( dist + 16 ) & -64;
else
dist = 64;
}
else
{
dist = ah_snap_width( globals->widths, globals->num_widths, dist );
if ( hinter->flags & AH_HINTER_MONOCHROME )
{
/* monochrome horizontal hinting: snap widths to integer pixels */
/* with a different threshold */
if ( dist < 64 )
dist = 64;
else
dist = ( dist + 32 ) & -64;
}
else
{
/* for horizontal anti-aliased hinting, we adopt a more subtle */
/* approach: we strengthen small stems, round stems whose size */
/* is between 1 and 2 pixels to an integer, otherwise nothing */
if ( dist < 48 )
dist = ( dist + 64 ) >> 1;
else if ( dist < 128 )
dist = ( dist + 22 ) & -64;
else
/* XXX: round otherwise, prevent color fringes in LCD mode */
dist = ( dist + 32 ) & -64;
}
}
}
if ( sign )
@@ -215,6 +332,7 @@
return dist;
}
#endif /* !CHESTER_SERIF */
/* align one stem edge relative to the previous stem edge */
@@ -226,6 +344,7 @@
{
FT_Pos dist = stem_edge->opos - base_edge->opos;
#ifdef FT_CONFIG_CHESTER_SERIF
FT_Pos fitted_width = ah_compute_stem_width( hinter,
vertical,
dist,
@@ -233,6 +352,10 @@
stem_edge->flags );
stem_edge->pos = base_edge->pos + fitted_width;
#else
stem_edge->pos = base_edge->pos +
ah_compute_stem_width( hinter, vertical, dist );
#endif
}
@@ -246,7 +369,7 @@
FT_Pos sign = 1;
FT_UNUSED( hinter );
FT_UNUSED( vertical );
dist = serif->opos - base->opos;
if ( dist < 0 )
@@ -386,8 +509,9 @@
if ( !anchor )
{
#ifdef FT_CONFIG_CHESTER_STEM
FT_Pos org_len, org_center, cur_len;
FT_Pos cur_pos1, delta1, u_off, d_off;
FT_Pos cur_pos1, error1, error2, u_off, d_off;
org_len = edge2->opos - edge->opos;
cur_len = ah_compute_stem_width( hinter, dimension, org_len,
@@ -401,16 +525,21 @@
d_off = 26;
}
if ( cur_len < 96 ) {
if ( cur_len < 96 )
{
org_center = edge->opos + ( org_len >> 1 );
cur_pos1 = ( org_center + 32 ) & -64;
delta1 = ABSVAL( org_center - ( cur_pos1 - u_off ) ) -
ABSVAL( ( org_center - ( cur_pos1 + d_off ) ) );
error1 = org_center - ( cur_pos1 - u_off );
if ( error1 < 0 )
error1 = -error1;
if ( delta1 < 0 )
error2 = org_center - ( cur_pos1 + d_off );
if ( error2 < 0 )
error2 = -error2;
if ( error1 < error2 )
cur_pos1 -= u_off;
else
cur_pos1 += d_off;
@@ -427,25 +556,40 @@
edge->flags |= AH_EDGE_DONE;
ah_align_linked_edge( hinter, edge, edge2, dimension );
}
#else /* !CHESTER_STEM */
edge->pos = ( edge->opos + 32 ) & -64;
anchor = edge;
edge->flags |= AH_EDGE_DONE;
ah_align_linked_edge( hinter, edge, edge2, dimension );
#endif /* !CHESTER_STEM */
}
else
{
FT_Pos org_pos, org_len, org_center, cur_len;
FT_Pos cur_pos1, cur_pos2, delta1, delta2, u_off, d_off;
FT_Pos cur_pos1, cur_pos2, delta1, delta2;
org_pos = anchor->pos + (edge->opos - anchor->opos);
org_len = edge2->opos - edge->opos;
org_center = org_pos + ( org_len >> 1 );
#ifdef FT_CONFIG_CHESTER_SERIF
cur_len = ah_compute_stem_width( hinter, dimension, org_len,
edge->flags, edge2->flags );
#else /* !CHESTER_SERIF */
cur_len = ah_compute_stem_width( hinter, dimension, org_len );
#endif /* !CHESTER_SERIF */
#ifdef FT_CONFIG_CHESTER_STEM
if ( cur_len < 96 )
{
cur_pos1 = ( org_center + 32 ) & -64;
FT_Pos u_off, d_off;
cur_pos1 = ( org_center + 32 ) & -64;
if (cur_len <= 64 )
u_off = d_off = 32;
else
@@ -454,24 +598,22 @@
d_off = 26;
}
delta1 = ABSVAL( org_center - ( cur_pos1 - u_off ) ) -
ABSVAL( ( org_center - ( cur_pos1 + d_off ) ) );
delta1 = org_center - (cur_pos1 - u_off);
if ( delta1 < 0 )
delta1 = -delta1;
delta2 = org_center - (cur_pos1 + d_off);
if ( delta2 < 0 )
delta2 = -delta2;
if ( delta1 < delta2 )
cur_pos1 -= u_off;
else
cur_pos1 += d_off;
edge->pos = cur_pos1 - cur_len / 2;
edge2->pos = cur_pos1 + cur_len / 2;
edge->flags |= AH_EDGE_DONE;
edge2->flags |= AH_EDGE_DONE;
if ( edge > edges && edge->pos < edge[-1].pos )
edge->pos = edge[-1].pos;
}
else
{
@@ -479,7 +621,8 @@
org_len = edge2->opos - edge->opos;
org_center = org_pos + ( org_len >> 1 );
cur_len = ah_compute_stem_width( hinter, dimension, org_len, edge->flags, edge2->flags );
cur_len = ah_compute_stem_width( hinter, dimension, org_len,
edge->flags, edge2->flags );
cur_pos1 = ( org_pos + 32 ) & -64;
delta1 = ( cur_pos1 + ( cur_len >> 1 ) - org_center );
@@ -493,13 +636,30 @@
edge->pos = ( delta1 < delta2 ) ? cur_pos1 : cur_pos2;
edge2->pos = edge->pos + cur_len;
edge->flags |= AH_EDGE_DONE;
edge2->flags |= AH_EDGE_DONE;
if ( edge > edges && edge->pos < edge[-1].pos )
edge->pos = edge[-1].pos;
}
#else /* !CHESTER_STEM */
cur_pos1 = ( org_pos + 32 ) & -64;
delta1 = ( cur_pos1 + ( cur_len >> 1 ) - org_center );
if ( delta1 < 0 )
delta1 = -delta1;
cur_pos2 = ( ( org_pos + org_len + 32 ) & -64 ) - cur_len;
delta2 = ( cur_pos2 + ( cur_len >> 1 ) - org_center );
if ( delta2 < 0 )
delta2 = -delta2;
edge->pos = ( delta1 <= delta2 ) ? cur_pos1 : cur_pos2;
edge2->pos = edge->pos + cur_len;
#endif /* !CHESTER_STEM */
edge->flags |= AH_EDGE_DONE;
edge2->flags |= AH_EDGE_DONE;
if ( edge > edges && edge->pos < edge[-1].pos )
edge->pos = edge[-1].pos;
}
}
@@ -1150,71 +1310,12 @@
FT_Face face = hinter->face;
FT_GlyphSlot slot = face->glyph;
FT_Slot_Internal internal = slot->internal;
FT_Fixed x_scale = face->size->metrics.x_scale;
FT_Fixed y_scale = face->size->metrics.y_scale;
FT_Fixed x_scale = hinter->globals->x_scale;
FT_Fixed y_scale = hinter->globals->y_scale;
FT_Error error;
AH_Outline outline = hinter->glyph;
AH_Loader gloader = hinter->loader;
{
/* Scale the glyph so that, even before grid-fitting, if it has an edge */
/* which corresponds to AH_BLUE_SMALL_TOP, then that edge is already */
/* aligned on a pixel boundry. This helps to preserve the original */
/* shape of the glyph. */
AH_Globals globals_scaled = &hinter->globals->scaled;
AH_Globals globals_design = &hinter->globals->design;
FT_Int opt_height, opt_width; /* optimal h/w to send */
FT_Int pointSize;
FT_Int reset_dim_x, reset_dim_y;
FT_Fixed reset_x_scale, reset_y_scale;
FT_Pos fitted_blue, active_blue;
y_scale = face->internal->orig_y_scale;
globals_scaled = &hinter->globals->scaled;
globals_design = &hinter->globals->design;
active_blue = FT_MulFix( globals_design->blue_shoots[AH_BLUE_SMALL_TOP],
face->internal->orig_y_scale );
fitted_blue = ( active_blue + 32 ) & -64;
opt_height = ((float)fitted_blue/(float)active_blue) *
(float)face->internal->orig_height;
reset_dim_x = face->internal->orig_width;
reset_dim_y = face->internal->orig_height;
reset_x_scale = face->internal->orig_x_scale;
reset_y_scale = face->internal->orig_y_scale;
pointSize = (int) face->internal->orig_width;
if(opt_height > face->internal->orig_height)
opt_width = 0.98 * opt_height;
else
opt_width = opt_height;
error = FT_Set_Char_Size( face,
opt_width,
opt_height,
face->internal->orig_horz_res,
face->internal->orig_vert_res );
ah_hinter_scale_globals( hinter,
face->size->metrics.x_scale,
face->size->metrics.y_scale );
face->internal->orig_height = reset_dim_y;
face->internal->orig_width = reset_dim_x;
face->internal->orig_x_scale = reset_x_scale;
face->internal->orig_y_scale = reset_y_scale;
}
/* load the glyph */
error = FT_Load_Glyph( face, glyph_index, load_flags );
@@ -1290,7 +1391,7 @@
/* now, load the slot image into the auto-outline, and run the */
/* automatic hinting process */
error = ah_outline_load( outline, face ); /* XXX: change to slot */
error = ah_outline_load( outline, x_scale, y_scale, face );
if ( error )
goto Exit;
@@ -1318,26 +1419,20 @@
AH_Edge edge2 = edge1 +
outline->num_vedges - 1; /* rightmost edge */
/* fit_shift is used to center the glyph in the fitted advance */
FT_Pos fit_shift = ( ( hinter->pp2.x + 32 ) & -64 )
- hinter->pp2.x;
old_advance = hinter->pp2.x;
old_rsb = old_advance - edge2->opos;
old_lsb = edge1->opos;
new_lsb = edge1->pos;
if ( hinter->do_horz_hints )
{
hinter->pp1.x = ( ( new_lsb - old_lsb - fit_shift/2 ) + 32 ) & -64;
hinter->pp2.x = ( ( edge2->pos + old_rsb - fit_shift/2 ) + 32 ) & -64;
}
else
{
hinter->pp1.x -= fit_shift / 2;
hinter->pp2.x -= fit_shift / 2;
}
hinter->pp1.x = ( ( new_lsb - old_lsb ) + 32 ) & -64;
hinter->pp2.x = ( ( edge2->pos + old_rsb ) + 32 ) & -64;
#if 0
/* try to fix certain bad advance computations */
if ( hinter->pp2.x + hinter->pp1.x == edge2->pos && old_rsb > 4 )
hinter->pp2.x += 64;
#endif
}
/* good, we simply add the glyph to our loader's base */
@@ -1566,6 +1661,36 @@
}
#ifdef FT_CONFIG_CHESTER_BLUE_SCALE
/* try to optimize the y_scale so that the top of non-capital letters
* is aligned on a pixel boundary whenever possible
*/
{
AH_Globals design = &face_globals->design;
FT_Pos shoot = design->blue_shoots[ AH_BLUE_SMALL_TOP ];
/* the value of 'shoot' will be -1000 if the font doesn't have */
/* small latin letters; we simply check the sign here... */
if ( shoot > 0 )
{
FT_Pos scaled = FT_MulFix( shoot, y_scale );
FT_Pos fitted = ( scaled + 32 ) & -64;
if ( scaled != fitted )
{
/* adjust y_scale
*/
y_scale = FT_MulDiv( y_scale, fitted, scaled );
/* adust x_scale
*/
if ( fitted < scaled )
x_scale -= x_scale/50; /* x_scale*0.98 with integers */
}
}
}
#endif /* FT_CONFIG_CHESTER_BLUE_SCALE */
/* now, we must check the current character pixel size to see if we */
/* need to rescale the global metrics */
if ( face_globals->x_scale != x_scale ||
@@ -1574,15 +1699,9 @@
ah_loader_rewind( hinter->loader );
#ifdef SMOOTH_DEFAULT
hint_mode = FT_RENDER_MODE_SMOOTH;
#endif
/* reset hinting flags according to load flags and current render target */
hinter->do_horz_hints = !FT_BOOL( ( load_flags & FT_LOAD_NO_AUTOHINT ) ||
hint_mode == FT_RENDER_MODE_SMOOTH );
hinter->do_vert_hints = !FT_BOOL( load_flags & FT_LOAD_NO_AUTOHINT );
hinter->do_horz_hints = FT_BOOL( !(load_flags & FT_LOAD_NO_AUTOHINT) );
hinter->do_vert_hints = FT_BOOL( !(load_flags & FT_LOAD_NO_AUTOHINT) );
#ifdef DEBUG_HINTER
hinter->do_horz_hints = !ah_debug_disable_vert; /* not a bug, the meaning */
@@ -1591,15 +1710,16 @@
/* we snap the width of vertical stems for the monochrome and */
/* horizontal LCD rendering targets only. Corresponds to X snapping. */
hinter->do_horz_snapping = FT_BOOL( hint_mode == FT_RENDER_MODE_MONO ||
hint_mode == FT_RENDER_MODE_LCD ||
hint_mode == FT_RENDER_MODE_SMOOTH );
hinter->do_horz_snapping = FT_BOOL( hint_mode == FT_RENDER_MODE_MONO ||
hint_mode == FT_RENDER_MODE_LCD );
/* we snap the width of horizontal stems for the monochrome and */
/* vertical LCD rendering targets only. Corresponds to Y snapping. */
hinter->do_vert_snapping = FT_BOOL( hint_mode == FT_RENDER_MODE_MONO ||
hint_mode == FT_RENDER_MODE_LCD_V );
hinter->do_stem_adjust = FT_BOOL( hint_mode != FT_RENDER_MODE_LIGHT );
#if 1
load_flags = FT_LOAD_NO_SCALE
| FT_LOAD_IGNORE_TRANSFORM ;
+25 -11
View File
@@ -385,13 +385,26 @@ FT_BEGIN_HEADER
} AH_OutlineRec, *AH_Outline;
#define AH_BLUE_CAPITAL_TOP 0 /* THEZOCQS */
#define AH_BLUE_CAPITAL_BOTTOM ( AH_BLUE_CAPITAL_TOP + 1 ) /* HEZLOCUS */
#define AH_BLUE_SMALL_F_TOP ( AH_BLUE_CAPITAL_BOTTOM + 1 ) /* fijkdbh */
#define AH_BLUE_SMALL_TOP ( AH_BLUE_SMALL_F_TOP + 1 ) /* xzroesc */
#define AH_BLUE_SMALL_BOTTOM ( AH_BLUE_SMALL_TOP + 1 ) /* xzroesc */
#define AH_BLUE_SMALL_MINOR ( AH_BLUE_SMALL_BOTTOM + 1 ) /* pqgjy */
#define AH_BLUE_MAX ( AH_BLUE_SMALL_MINOR + 1 )
#ifdef FT_CONFIG_CHESTER_SMALL_F
# define AH_BLUE_CAPITAL_TOP 0 /* THEZOCQS */
# define AH_BLUE_CAPITAL_BOTTOM ( AH_BLUE_CAPITAL_TOP + 1 ) /* HEZLOCUS */
# define AH_BLUE_SMALL_F_TOP ( AH_BLUE_CAPITAL_BOTTOM + 1 ) /* fijkdbh */
# define AH_BLUE_SMALL_TOP ( AH_BLUE_SMALL_F_TOP + 1 ) /* xzroesc */
# define AH_BLUE_SMALL_BOTTOM ( AH_BLUE_SMALL_TOP + 1 ) /* xzroesc */
# define AH_BLUE_SMALL_MINOR ( AH_BLUE_SMALL_BOTTOM + 1 ) /* pqgjy */
# define AH_BLUE_MAX ( AH_BLUE_SMALL_MINOR + 1 )
#else /* !CHESTER_SMALL_F */
# define AH_BLUE_CAPITAL_TOP 0 /* THEZOCQS */
# define AH_BLUE_CAPITAL_BOTTOM ( AH_BLUE_CAPITAL_TOP + 1 ) /* HEZLOCUS */
# define AH_BLUE_SMALL_TOP ( AH_BLUE_CAPITAL_BOTTOM + 1) /* xzroesc */
# define AH_BLUE_SMALL_BOTTOM ( AH_BLUE_SMALL_TOP + 1 ) /* xzroesc */
# define AH_BLUE_SMALL_MINOR ( AH_BLUE_SMALL_BOTTOM + 1 ) /* pqgjy */
# define AH_BLUE_MAX ( AH_BLUE_SMALL_MINOR + 1 )
#endif /* !CHESTER_SMALL_F */
typedef FT_Int AH_Blue;
@@ -463,12 +476,12 @@ FT_BEGIN_HEADER
/* */
typedef struct AH_Face_GlobalsRec_
{
FT_Face face;
FT_Face face;
AH_GlobalsRec design;
AH_GlobalsRec scaled;
FT_Fixed x_scale;
FT_Fixed y_scale;
FT_Bool control_overshoot;
FT_Fixed x_scale;
FT_Fixed y_scale;
FT_Bool control_overshoot;
} AH_Face_GlobalsRec, *AH_Face_Globals;
@@ -497,6 +510,7 @@ FT_BEGIN_HEADER
FT_Bool do_vert_hints; /* disable Y hinting */
FT_Bool do_horz_snapping; /* disable X stem size snapping */
FT_Bool do_vert_snapping; /* disable Y stem size snapping */
FT_Bool do_stem_adjust; /* disable light stem snapping */
} AH_HinterRec, *AH_Hinter;
+4 -2
View File
@@ -23,8 +23,10 @@ UseFreeTypeHeaders ;
# Add the optional/replaceable files.
#
FT2_Library $(FT2_LIB) : ftsystem.c ftinit.c ftglyph.c ftmm.c ftbdf.c
ftbbox.c ftdebug.c ftxf86.c fttype1.c ftpfr.c ;
FT2_Library $(FT2_LIB) : ftsystem.c ftinit.c ftglyph.c ftmm.c ftbdf.c
ftbbox.c ftdebug.c ftxf86.c fttype1.c ftpfr.c
ftstroker.c ftwinfnt.c
;
# Add Macintosh-specific file to the library when necessary.
#
+1 -1
View File
@@ -15,7 +15,7 @@
CFLAGS=$(COMP_FLAGS)$(DEBUG)/include=([--.builds.vms],[--.include],[--.src.base])
OBJS=ftbase.obj,ftinit.obj,ftglyph.obj,ftdebug.obj,ftbdf.obj,ftmm.obj,fttype1.obj,ftxf86.obj,ftpfr.obj
OBJS=ftbase.obj,ftinit.obj,ftglyph.obj,ftdebug.obj,ftbdf.obj,ftmm.obj,fttype1.obj,ftxf86.obj,ftpfr.obj,ftstroker.obj,ftwinfnt.obj
all : $(OBJS)
library [--.lib]freetype.olb $(OBJS)
+45 -12
View File
@@ -20,6 +20,22 @@
#include FT_INTERNAL_BDF_TYPES_H
#include FT_INTERNAL_OBJECTS_H
static FT_Bool
test_font_type( FT_Face face, const char* name )
{
if ( face && face->driver )
{
FT_Module driver = (FT_Module)face->driver;
if ( driver->clazz && driver->clazz->module_name )
{
if ( ft_strcmp( driver->clazz->module_name, name ) == 0 )
return 1;
}
}
return 0;
}
FT_EXPORT_DEF( FT_Error )
FT_Get_BDF_Charset_ID( FT_Face face,
@@ -33,21 +49,14 @@
error = FT_Err_Invalid_Argument;
if ( face != NULL && face->driver != NULL )
if ( test_font_type( face, "bdf" ) )
{
FT_Module driver = (FT_Module) face->driver;
BDF_Public_Face bdf_face = (BDF_Public_Face)face;
if ( driver->clazz && driver->clazz->module_name &&
ft_strcmp( driver->clazz->module_name, "bdf" ) == 0 )
{
BDF_Public_Face bdf_face = (BDF_Public_Face)face;
encoding = (const char*) bdf_face->charset_encoding;
registry = (const char*) bdf_face->charset_registry;
error = 0;
}
encoding = (const char*) bdf_face->charset_encoding;
registry = (const char*) bdf_face->charset_registry;
error = 0;
}
if ( acharset_encoding )
@@ -60,4 +69,28 @@
}
FT_EXPORT( FT_Error )
FT_Get_BDF_Property( FT_Face face,
const char* prop_name,
BDF_PropertyRec *aproperty )
{
FT_Error error;
error = FT_Err_Invalid_Argument;
aproperty->type = BDF_PROPERTY_TYPE_NONE;
if ( face != NULL && face->driver != NULL )
{
FT_Driver driver = face->driver;
BDF_GetPropertyFunc func;
func = (BDF_GetPropertyFunc) driver->root.clazz->get_interface(
FT_MODULE( driver ), "get_bdf_property" );
if ( func )
error = func( face, prop_name, aproperty );
}
return error;
}
/* END */
+47 -1
View File
@@ -62,6 +62,13 @@
FT_ULong alloc_total;
FT_ULong alloc_current;
FT_ULong alloc_max;
FT_ULong alloc_count;
FT_Bool bound_total;
FT_ULong alloc_total_max;
FT_Bool bound_count;
FT_ULong alloc_count_max;
const char* file_name;
FT_Long line_no;
@@ -476,10 +483,22 @@
if ( size <= 0 )
ft_mem_debug_panic( "negative block size allocation (%ld)", size );
/* return NULL if the maximum number of allocations was reached */
if ( table->bound_count &&
table->alloc_count >= table->alloc_count_max )
return NULL;
/* return NULL if this allocation would overflow the maximum heap size */
if ( table->bound_total &&
table->alloc_current + (FT_ULong)size > table->alloc_total_max )
return NULL;
block = (FT_Byte *)ft_mem_table_alloc( table, size );
if ( block )
ft_mem_table_set( table, block, (FT_ULong)size );
table->alloc_count++;
table->file_name = NULL;
table->line_no = 0;
@@ -570,15 +589,42 @@
FT_Int result = 0;
if ( getenv( "FT_DEBUG_MEMORY" ) )
if ( getenv( "FT2_DEBUG_MEMORY" ) )
{
table = ft_mem_table_new( memory );
if ( table )
{
const char* p;
memory->user = table;
memory->alloc = ft_mem_debug_alloc;
memory->realloc = ft_mem_debug_realloc;
memory->free = ft_mem_debug_free;
p = getenv( "FT2_ALLOC_TOTAL_MAX" );
if ( p != NULL )
{
FT_Long total_max = atol(p);
if ( total_max > 0 )
{
table->bound_total = 1;
table->alloc_total_max = (FT_ULong) total_max;
}
}
p = getenv( "FT2_ALLOC_COUNT_MAX" );
if ( p != NULL )
{
FT_Long total_count = atol(p);
if ( total_count > 0 )
{
table->bound_count = 1;
table->alloc_count_max = (FT_ULong) total_count;
}
}
result = 1;
}
}
+1 -1
View File
@@ -56,7 +56,7 @@
/* documentation is in ftglyph.h */
FT_EXPORT_DEF( void )
FT_Matrix_Multiply( FT_Matrix* a,
FT_Matrix_Multiply( const FT_Matrix* a,
FT_Matrix* b )
{
FT_Fixed xx, xy, yx, yy;
+192 -47
View File
@@ -22,7 +22,9 @@
#include FT_INTERNAL_OBJECTS_H
#include FT_INTERNAL_DEBUG_H
#include FT_INTERNAL_STREAM_H
#include FT_INTERNAL_SFNT_H /* for SFNT_Load_Table_Func */
#include FT_TRUETYPE_TABLES_H
#include FT_TRUETYPE_IDS_H
#include FT_OUTLINE_H
@@ -196,11 +198,9 @@
return error;
}
static void
ft_glyphslot_clear( FT_GlyphSlot slot )
FT_BASE_DEF( void )
ft_glyphslot_free_bitmap( FT_GlyphSlot slot )
{
/* free bitmap if needed */
if ( slot->flags & FT_GLYPH_OWN_BITMAP )
{
FT_Memory memory = FT_FACE_MEMORY( slot->face );
@@ -209,6 +209,48 @@
FT_FREE( slot->bitmap.buffer );
slot->flags &= ~FT_GLYPH_OWN_BITMAP;
}
else
{
/* assume that the bitmap buffer was stolen or not */
/* allocated from the heap */
slot->bitmap.buffer = NULL;
}
}
FT_BASE_DEF( void )
ft_glyphslot_set_bitmap( FT_GlyphSlot slot,
FT_Pointer buffer )
{
ft_glyphslot_free_bitmap( slot );
slot->bitmap.buffer = buffer;
FT_ASSERT( (slot->flags & FT_GLYPH_OWN_BITMAP) == 0 );
}
FT_BASE_DEF( FT_Error )
ft_glyphslot_alloc_bitmap( FT_GlyphSlot slot,
FT_ULong size )
{
FT_Memory memory = FT_FACE_MEMORY( slot->face );
if ( slot->flags & FT_GLYPH_OWN_BITMAP )
FT_FREE( slot->bitmap.buffer );
else
slot->flags |= FT_GLYPH_OWN_BITMAP;
return FT_MEM_ALLOC( slot->bitmap.buffer, size );
}
static void
ft_glyphslot_clear( FT_GlyphSlot slot )
{
/* free bitmap if needed */
ft_glyphslot_free_bitmap( slot );
/* clear all public fields in the glyph slot */
FT_ZERO( &slot->metrics );
@@ -246,8 +288,7 @@
clazz->done_slot( slot );
/* free bitmap buffer if needed */
if ( slot->flags & FT_GLYPH_OWN_BITMAP )
FT_FREE( slot->bitmap.buffer );
ft_glyphslot_free_bitmap( slot );
/* free glyph loader */
if ( FT_DRIVER_USES_OUTLINES( driver ) )
@@ -699,6 +740,100 @@
}
/*************************************************************************/
/* */
/* <Function> */
/* find_unicode_charmap */
/* */
/* <Description> */
/* This function finds a Unicode charmap, if there is one. */
/* And if there is more than one, it tries to favour the more */
/* extensive one, i.e. one that supports UCS-4 against those which */
/* are limited to the BMP (said UCS-2 encoding.) */
/* */
/* This function is called from open_face() (just below), and also */
/* from FT_Select_Charmap( , FT_ENCODING_UNICODE). */
/* */
static FT_Error
find_unicode_charmap( FT_Face face )
{
FT_CharMap* first;
FT_CharMap* cur;
FT_CharMap* unicmap = NULL; /* some UCS-2 map, if we found it */
/* caller should have already checked that `face' is valid */
FT_ASSERT ( face );
first = face->charmaps;
if ( !first )
return FT_Err_Invalid_CharMap_Handle;
/*
* the original TrueType specification(s) only specified charmap
* formats that are capable of mapping 8 or 16 bit character codes to
* glyph indices.
*
* however, recent updates to the Apple and OpenType specifications
* introduced new formats that are capable of mapping 32-bit character
* codes as well. And these are already used on some fonts, mainly to
* map non-BMP Asian ideographs as defined in Unicode.
*
* for compatibility purposes, these fonts generally come with
* *several* Unicode charmaps:
*
* - one of them in the "old" 16-bit format, that cannot access
* all glyphs in the font
*
* - another one in the "new" 32-bit format, that can access all
* the glyphs.
*
* this function has been written to always favor a 32-bit charmap
* when found. Otherwise, a 16-bit one is returned when found
*/
/* since the `interesting' table, with id's 3,10, is normally the */
/* last one, we loop backwards. This looses with type1 fonts with */
/* non-BMP characters (<.0001%), this wins with .ttf with non-BMP */
/* chars (.01% ?), and this is the same about 99.99% of the time! */
cur = first + face->num_charmaps; /* points after the last one */
for ( ; --cur >= first; )
{
if ( cur[0]->encoding == FT_ENCODING_UNICODE )
{
unicmap = cur; /* record we found a Unicode charmap */
/* XXX If some new encodings to represent UCS-4 are added, */
/* they should be added here. */
if ( ( cur[0]->platform_id == TT_PLATFORM_MICROSOFT &&
cur[0]->encoding_id == TT_MS_ID_UCS_4 ) ||
( cur[0]->platform_id == TT_PLATFORM_APPLE_UNICODE &&
cur[0]->encoding_id == TT_APPLE_ID_UNICODE_32 ) )
/* Hurray! We found a UCS-4 charmap. We can stop the scan! */
{
face->charmap = cur[0];
return 0;
}
}
}
/* We do not have any UCS-4 charmap. Sigh. */
/* Let's see if we have some other kind of Unicode charmap, though. */
if ( unicmap != NULL )
{
face->charmap = unicmap[0];
return 0;
}
/* Chou blanc! */
return FT_Err_Invalid_CharMap_Handle;
}
/*************************************************************************/
/* */
/* <Function> */
@@ -718,7 +853,7 @@
FT_Memory memory;
FT_Driver_Class clazz;
FT_Face face = 0;
FT_Error error;
FT_Error error, error2;
FT_Face_Internal internal;
@@ -748,7 +883,7 @@
i++ )
if ( params[i].tag == FT_PARAM_TAG_INCREMENTAL )
face->internal->incremental_interface = params[i].data;
}
}
#endif
error = clazz->init_face( stream,
@@ -760,24 +895,17 @@
goto Fail;
/* select Unicode charmap by default */
error2 = find_unicode_charmap( face );
/* if no Unicode charmap can be found, FT_Err_Invalid_CharMap_Handle is
* returned.
*/
/* no error should happen, but we want to play safe. */
if ( error2 && error2 != FT_Err_Invalid_CharMap_Handle )
{
FT_Int nn;
FT_CharMap unicmap = NULL, cmap;
for ( nn = 0; nn < face->num_charmaps; nn++ )
{
cmap = face->charmaps[nn];
if ( cmap->encoding == FT_ENCODING_UNICODE )
{
unicmap = cmap;
break;
}
}
if ( unicmap != NULL )
face->charmap = unicmap;
error = error2;
goto Fail;
}
*aface = face;
@@ -1241,10 +1369,10 @@
/* Compute root ascender, descender, test height, and max_advance */
metrics->ascender = ( FT_MulFix( face->ascender,
metrics->y_scale ) + 32 ) & -64;
metrics->y_scale ) + 63 ) & -64;
metrics->descender = ( FT_MulFix( face->descender,
metrics->y_scale ) + 32 ) & -64;
metrics->y_scale ) + 0 ) & -64;
metrics->height = ( FT_MulFix( face->height,
metrics->y_scale ) + 32 ) & -64;
@@ -1297,9 +1425,10 @@
if ( char_height < 1 * 64 )
char_height = 1 * 64;
/* Compute pixel sizes in 26.6 units */
dim_x = ( ( char_width * horz_resolution ) / 72 ) ;
dim_y = ( ( char_height * vert_resolution ) / 72 ) ;
/* Compute pixel sizes in 26.6 units. we use rounding
*/
dim_x = ( ( char_width * horz_resolution + (36+32*72) ) / 72 ) & -64;
dim_y = ( ( char_height * vert_resolution + (36+32*72) ) / 72 ) & -64;
metrics->x_ppem = (FT_UShort)( dim_x >> 6 );
metrics->y_ppem = (FT_UShort)( dim_y >> 6 );
@@ -1315,15 +1444,6 @@
ft_recompute_scaled_metrics( face, metrics );
}
face->internal->orig_width = char_width;
face->internal->orig_height = char_height;
face->internal->orig_horz_res = horz_resolution;
face->internal->orig_vert_res = vert_resolution;
face->internal->orig_x_scale = metrics->x_scale;
face->internal->orig_y_scale = metrics->y_scale;
if ( clazz->set_char_sizes )
error = clazz->set_char_sizes( face->size,
char_width,
@@ -1379,14 +1499,6 @@
ft_recompute_scaled_metrics( face, metrics );
}
face->internal->orig_width = pixel_width << 6;
face->internal->orig_height = pixel_height << 6;
face->internal->orig_horz_res = 0;
face->internal->orig_vert_res = 0;
face->internal->orig_x_scale = metrics->x_scale;
face->internal->orig_y_scale = metrics->y_scale;
if ( clazz->set_pixel_sizes )
error = clazz->set_pixel_sizes( face->size,
pixel_width,
@@ -1458,6 +1570,13 @@
if ( !face )
return FT_Err_Invalid_Face_Handle;
/* FT_ENCODING_UNICODE is special. We try to find the `best' Unicode */
/* charmap available, i.e. one with UCS-4 characters, if possible. */
/* */
/* This is done by find_unicode_charmap() above, to share code. */
if ( encoding == FT_ENCODING_UNICODE )
return find_unicode_charmap( face );
cur = face->charmaps;
if ( !cur )
return FT_Err_Invalid_CharMap_Handle;
@@ -1784,6 +1903,32 @@
}
/* documentation is in tttables.h */
FT_EXPORT_DEF( FT_Error )
FT_Load_Sfnt_Table( FT_Face face,
FT_ULong tag,
FT_Long offset,
FT_Byte* buffer,
FT_ULong* length )
{
SFNT_Load_Table_Func func;
FT_Driver driver;
if ( !face || !FT_IS_SFNT( face ) )
return FT_Err_Invalid_Face_Handle;
driver = face->driver;
func = (SFNT_Load_Table_Func) driver->root.clazz->get_interface(
FT_MODULE( driver ), "load_sfnt" );
if ( !func )
return FT_Err_Unimplemented_Feature;
return func( face, tag, offset, buffer, length );
}
FT_EXPORT_DEF( FT_Error )
FT_Activate_Size( FT_Size size )
{
+218 -5
View File
@@ -233,8 +233,12 @@
{
FT_ASSERT( border->start >= 0 );
border->tags[ border->start ] |= FT_STROKE_TAG_BEGIN;
border->tags[ border->num_points-1 ] |= FT_STROKE_TAG_END;
/* don't record empty paths !! */
if ( border->num_points > (FT_UInt)border->start )
{
border->tags[ border->start ] |= FT_STROKE_TAG_BEGIN;
border->tags[ border->num_points-1 ] |= FT_STROKE_TAG_END;
}
border->start = -1;
border->movable = 0;
@@ -469,7 +473,7 @@
FT_Byte* tags = border->tags;
FT_Int in_contour = 0;
for ( ; count > 0; count--, point++, tags++ )
for ( ; count > 0; count--, num_points++, point++, tags++ )
{
if ( tags[0] & FT_STROKE_TAG_BEGIN )
{
@@ -538,7 +542,7 @@
FT_Short* write = outline->contours + outline->n_contours;
FT_Short index = (FT_Short) outline->n_points;
for ( ; count > 0; count--, tags++, write++, index++ )
for ( ; count > 0; count--, tags++, index++ )
{
if ( *tags & FT_STROKE_TAG_END )
{
@@ -787,9 +791,15 @@
theta = FT_Angle_Diff( stroker->angle_in, stroker->angle_out );
if (theta == FT_ANGLE_PI)
{
theta = rotate;
phi = stroker->angle_in;
}
else
{
theta = theta/2;
phi = stroker->angle_in + theta + rotate;
}
thcos = FT_Cos( theta );
sigma = FT_MulFix( stroker->miter_limit, thcos );
@@ -797,7 +807,6 @@
if ( sigma >= 0x10000L )
miter = 0;
phi = stroker->angle_in + theta + rotate;
if (miter) /* this is a miter (broken angle) */
{
@@ -1362,3 +1371,207 @@
ft_stroke_border_export( stroker->borders+1, outline );
}
}
/*
* the following is very similar to FT_Outline_Decompose, except
* that we do support opened paths, and do not scale the outline
*/
FT_EXPORT_DEF( FT_Error )
FT_Stroker_ParseOutline( FT_Stroker stroker,
FT_Outline* outline,
FT_Bool opened )
{
FT_Vector v_last;
FT_Vector v_control;
FT_Vector v_start;
FT_Vector* point;
FT_Vector* limit;
char* tags;
FT_Error error;
FT_Int n; /* index of contour in outline */
FT_UInt first; /* index of first point in contour */
FT_Int tag; /* current point's state */
FT_Int in_path;
if ( !outline || !stroker )
return FT_Err_Invalid_Argument;
first = 0;
in_path = 0;
for ( n = 0; n < outline->n_contours; n++ )
{
FT_Int last; /* index of last point in contour */
last = outline->contours[n];
limit = outline->points + last;
v_start = outline->points[first];
v_last = outline->points[last];
v_control = v_start;
point = outline->points + first;
tags = outline->tags + first;
tag = FT_CURVE_TAG( tags[0] );
/* A contour cannot start with a cubic control point! */
if ( tag == FT_CURVE_TAG_CUBIC )
goto Invalid_Outline;
/* check first point to determine origin */
if ( tag == FT_CURVE_TAG_CONIC )
{
/* first point is conic control. Yes, this happens. */
if ( FT_CURVE_TAG( outline->tags[last] ) == FT_CURVE_TAG_ON )
{
/* start at last point if it is on the curve */
v_start = v_last;
limit--;
}
else
{
/* if both first and last points are conic, */
/* start at their middle and record its position */
/* for closure */
v_start.x = ( v_start.x + v_last.x ) / 2;
v_start.y = ( v_start.y + v_last.y ) / 2;
v_last = v_start;
}
point--;
tags--;
}
error = FT_Stroker_BeginSubPath( stroker, &v_start, opened );
if ( error )
goto Exit;
in_path = 1;
while ( point < limit )
{
point++;
tags++;
tag = FT_CURVE_TAG( tags[0] );
switch ( tag )
{
case FT_CURVE_TAG_ON: /* emit a single line_to */
{
FT_Vector vec;
vec.x = point->x;
vec.y = point->y;
error = FT_Stroker_LineTo( stroker, &vec );
if ( error )
goto Exit;
continue;
}
case FT_CURVE_TAG_CONIC: /* consume conic arcs */
v_control.x = point->x;
v_control.y = point->y;
Do_Conic:
if ( point < limit )
{
FT_Vector vec;
FT_Vector v_middle;
point++;
tags++;
tag = FT_CURVE_TAG( tags[0] );
vec = point[0];
if ( tag == FT_CURVE_TAG_ON )
{
error = FT_Stroker_ConicTo( stroker, &v_control, &vec );
if ( error )
goto Exit;
continue;
}
if ( tag != FT_CURVE_TAG_CONIC )
goto Invalid_Outline;
v_middle.x = ( v_control.x + vec.x ) / 2;
v_middle.y = ( v_control.y + vec.y ) / 2;
error = FT_Stroker_ConicTo( stroker, &v_control, &v_middle );
if ( error )
goto Exit;
v_control = vec;
goto Do_Conic;
}
error = FT_Stroker_ConicTo( stroker, &v_control, &v_start );
goto Close;
default: /* FT_CURVE_TAG_CUBIC */
{
FT_Vector vec1, vec2;
if ( point + 1 > limit ||
FT_CURVE_TAG( tags[1] ) != FT_CURVE_TAG_CUBIC )
goto Invalid_Outline;
point += 2;
tags += 2;
vec1 = point[-2];
vec2 = point[-1];
if ( point <= limit )
{
FT_Vector vec;
vec = point[0];
error = FT_Stroker_CubicTo( stroker, &vec1, &vec2, &vec );
if ( error )
goto Exit;
continue;
}
error = FT_Stroker_CubicTo( stroker, &vec1, &vec2, &v_start );
goto Close;
}
}
}
Close:
if ( error )
goto Exit;
error = FT_Stroker_EndSubPath( stroker );
if ( error )
goto Exit;
first = last + 1;
}
return 0;
Exit:
return error;
Invalid_Outline:
return FT_Err_Invalid_Outline;
}
+2
View File
@@ -474,6 +474,8 @@
FT_Angle delta = angle2 - angle1;
delta %= FT_ANGLE_2PI;
if ( delta < 0 )
delta += FT_ANGLE_2PI;
if ( delta > FT_ANGLE_PI )
delta -= FT_ANGLE_2PI;
+55
View File
@@ -0,0 +1,55 @@
/***************************************************************************/
/* */
/* ftwinfnt.c */
/* */
/* FreeType API for accessing Windows FNT specific info (body). */
/* */
/* Copyright 2002 by */
/* David Turner, Robert Wilhelm, and Werner Lemberg. */
/* */
/* This file is part of the FreeType project, and may only be used, */
/* modified, and distributed under the terms of the FreeType project */
/* license, LICENSE.TXT. By continuing to use, modify, or distribute */
/* this file you indicate that you have read the license and */
/* understand and accept it fully. */
/* */
/***************************************************************************/
#include <ft2build.h>
#include FT_WINFONTS_H
#include FT_INTERNAL_FNT_TYPES_H
#include FT_INTERNAL_OBJECTS_H
FT_EXPORT_DEF( FT_Error )
FT_Get_WinFNT_Header( FT_Face face,
FT_WinFNT_HeaderRec *header )
{
FT_Error error;
error = FT_Err_Invalid_Argument;
if ( face != NULL && face->driver != NULL )
{
FT_Module driver = (FT_Module) face->driver;
if ( driver->clazz && driver->clazz->module_name &&
ft_strcmp( driver->clazz->module_name, "winfonts" ) == 0 )
{
FNT_Size size = (FNT_Size)face->size;
FNT_Font font = size->font;
if (font)
{
FT_MEM_COPY( header, &font->header, sizeof(*header) );
error = 0;
}
}
}
return error;
}
/* END */
+8 -6
View File
@@ -49,12 +49,14 @@ BASE_SRC := $(BASE_)ftcalc.c \
# object. It will then be linked to the final executable only if one of its
# symbols is used by the application.
#
BASE_EXT_SRC := $(BASE_)ftglyph.c \
$(BASE_)ftmm.c \
$(BASE_)ftbdf.c \
$(BASE_)fttype1.c \
$(BASE_)ftxf86.c \
$(BASE_)ftpfr.c \
BASE_EXT_SRC := $(BASE_)ftglyph.c \
$(BASE_)ftmm.c \
$(BASE_)ftbdf.c \
$(BASE_)fttype1.c \
$(BASE_)ftxf86.c \
$(BASE_)ftpfr.c \
$(BASE_)ftstroker.c \
$(BASE_)ftwinfnt.c \
$(BASE_)ftbbox.c
# Default extensions objects
+59 -8
View File
@@ -29,6 +29,7 @@ THE SOFTWARE.
#include FT_INTERNAL_DEBUG_H
#include FT_INTERNAL_STREAM_H
#include FT_INTERNAL_OBJECTS_H
#include FT_BDF_H
#include "bdf.h"
#include "bdfdrivr.h"
@@ -488,8 +489,6 @@ THE SOFTWARE.
int i, j, count;
unsigned char *p, *pp;
FT_Memory memory = face->bdffont->memory;
FT_UNUSED( load_flags );
@@ -513,9 +512,9 @@ THE SOFTWARE.
bitmap->pixel_mode = FT_PIXEL_MODE_MONO;
bitmap->pitch = glyph.bpr;
if ( FT_NEW_ARRAY( bitmap->buffer, glyph.bytes ) )
goto Exit;
FT_MEM_COPY( bitmap->buffer, glyph.bitmap, glyph.bytes );
/* note: we don't allocate a new array to hold the bitmap, we */
/* can simply point to it */
ft_glyphslot_set_bitmap( slot, glyph.bitmap );
}
else
{
@@ -523,7 +522,8 @@ THE SOFTWARE.
bitmap->pixel_mode = FT_PIXEL_MODE_GRAY;
bitmap->pitch = bitmap->width;
if ( FT_NEW_ARRAY( bitmap->buffer, bitmap->rows * bitmap->pitch ) )
error = ft_glyphslot_alloc_bitmap( slot, bitmap->rows * bitmap->pitch );
if ( error )
goto Exit;
switch ( bpp )
@@ -624,13 +624,64 @@ THE SOFTWARE.
slot->linearHoriAdvance = (FT_Fixed)glyph.dwidth << 16;
slot->format = FT_GLYPH_FORMAT_BITMAP;
slot->flags = FT_GLYPH_OWN_BITMAP;
Exit:
return error;
}
static FT_Error
bdf_get_bdf_property( BDF_Face face,
const char* prop_name,
BDF_PropertyRec *aproperty )
{
bdf_property_t* prop;
FT_ASSERT( face && face->bdffont );
prop = bdf_get_font_property( face->bdffont, (char*)prop_name );
if ( prop != NULL )
{
switch ( prop->format )
{
case BDF_ATOM:
aproperty->type = BDF_PROPERTY_TYPE_ATOM;
aproperty->u.atom = prop->value.atom;
break;
case BDF_INTEGER:
aproperty->type = BDF_PROPERTY_TYPE_INTEGER;
aproperty->u.integer = prop->value.int32;
break;
case BDF_CARDINAL:
aproperty->type = BDF_PROPERTY_TYPE_CARDINAL;
aproperty->u.cardinal = prop->value.card32;
break;
default:
goto Fail;
}
return 0;
}
Fail:
return FT_Err_Invalid_Argument;
}
static FT_Module_Interface
bdf_driver_requester( FT_Module module,
const char* name )
{
FT_UNUSED( module );
if ( name && ft_strcmp( name, "get_bdf_property" ) == 0 )
return (FT_Module_Interface) bdf_get_bdf_property;
return NULL;
}
FT_CALLBACK_TABLE_DEF
const FT_Driver_ClassRec bdf_driver_class =
{
@@ -646,7 +697,7 @@ THE SOFTWARE.
(FT_Module_Constructor)0,
(FT_Module_Destructor) 0,
(FT_Module_Requester) 0
(FT_Module_Requester) bdf_driver_requester
},
sizeof ( BDF_FaceRec ),
+1 -1
View File
@@ -9,7 +9,7 @@ UseFreeTypeHeaders ;
# later used in #include statements related to the cache sub-system. It
# needs to be parsed through a HDRMACRO rule for macro definitions.
#
# HDRMACRO [ FT2_SubDir include ftcache.h ] ;
#HDRMACRO [ FT2_SubDir include ftcache.h ] ;
{
local _sources ;
+220 -127
View File
@@ -196,7 +196,8 @@
FTC_Node* pold;
FT_ASSERT( old_index >= FTC_HASH_INITIAL_SIZE );
if ( old_index+1 <= FTC_HASH_INITIAL_SIZE )
goto Exit;
if ( p == 0 )
{
@@ -356,10 +357,12 @@
FT_FREE( node );
#if 0
/* check, just in case of general corruption :-) */
if ( manager->num_nodes == 0 )
FT_ERROR(( "ftc_node_destroy: invalid cache node count! = %d\n",
manager->num_nodes ));
#endif
}
@@ -404,11 +407,14 @@
FT_EXPORT_DEF( void )
ftc_family_done( FTC_Family family )
{
FTC_Manager manager = family->cache->manager;
if ( family && family->cache )
{
FTC_Manager manager = family->cache->manager;
/* remove from manager's family table */
ftc_family_table_free( &manager->families, family->fam_index );
/* remove from manager's family table */
ftc_family_table_free( &manager->families, family->fam_index );
}
}
@@ -545,8 +551,10 @@
FTC_Query query,
FTC_Node *anode )
{
FT_Error error = FT_Err_Ok;
FT_LruNode lru;
FT_Error error = FT_Err_Ok;
FTC_Manager manager;
FT_LruNode lru;
FT_UInt free_count = 0;
if ( !cache || !query || !anode )
@@ -557,152 +565,237 @@
query->hash = 0;
query->family = NULL;
/* XXX: we break encapsulation for the sake of speed! */
manager = cache->manager;
/* here's a small note explaining what's hapenning in the code below.
*
* we need to deal intelligently with out-of-memory (OOM) conditions
* when trying to create a new family or cache node during the lookup.
*
* when an OOM is detected, we'll try to free one or more "old" nodes
* from the cache, then try again. it may be necessary to do that several
* times, so a loop is needed.
*
* the local variable "free_count" holds the number of "old" nodes to
* discard on each attempt. it starts at 1 and doubles on each iteration.
* the loop stops when:
*
* - a non-OOM error is detected
* - a succesful lookup is performed
* - there are no more unused nodes in the cache
*
* for the record, remember that all used nodes appear _before_
* unused ones in the manager's MRU node list.
*/
for (;;)
{
/* first of all, find the relevant family */
FT_LruList list = cache->families;
FT_LruNode fam, *pfam;
FT_LruNode_CompareFunc compare = list->clazz->node_compare;
pfam = &list->nodes;
for (;;)
{
fam = *pfam;
if ( fam == NULL )
/* first of all, find the relevant family */
FT_LruList list = cache->families;
FT_LruNode fam, *pfam;
FT_LruNode_CompareFunc compare = list->clazz->node_compare;
pfam = &list->nodes;
for (;;)
{
error = FT_LruList_Lookup( list, query, &lru );
if ( error )
goto Exit;
goto Skip;
}
if ( compare( fam, query, list->data ) )
break;
pfam = &fam->next;
}
FT_ASSERT( fam != NULL );
/* move to top of list when needed */
if ( fam != list->nodes )
{
*pfam = fam->next;
fam->next = list->nodes;
list->nodes = fam;
}
lru = fam;
Skip:
;
}
{
FTC_Family family = (FTC_Family) lru;
FT_UFast hash = query->hash;
FTC_Node* bucket;
FT_UInt idx;
idx = hash & cache->mask;
if ( idx < cache->p )
idx = hash & ( cache->mask * 2 + 1 );
bucket = cache->buckets + idx;
if ( query->family != family ||
family->fam_index >= cache->manager->families.size )
{
FT_ERROR((
"ftc_cache_lookup: invalid query (bad 'family' field)\n" ));
return FTC_Err_Invalid_Argument;
}
if ( *bucket )
{
FTC_Node* pnode = bucket;
FTC_Node_CompareFunc compare = cache->clazz->node_compare;
for ( ;; )
{
FTC_Node node;
node = *pnode;
if ( node == NULL )
break;
if ( node->hash == hash &&
(FT_UInt)node->fam_index == family->fam_index &&
compare( node, query, cache ) )
fam = *pfam;
if ( fam == NULL )
{
/* move to head of bucket list */
if ( pnode != bucket )
{
*pnode = node->link;
node->link = *bucket;
*bucket = node;
}
error = FT_LruList_Lookup( list, query, &lru );
if ( error )
goto Fail;
/* move to head of MRU list */
if ( node != cache->manager->nodes_list )
ftc_node_mru_up( node, cache->manager );
*anode = node;
goto Exit;
goto Skip;
}
pnode = &node->link;
if ( compare( fam, query, list->data ) )
break;
pfam = &fam->next;
}
FT_ASSERT( fam != NULL );
/* move to top of list when needed */
if ( fam != list->nodes )
{
*pfam = fam->next;
fam->next = list->nodes;
list->nodes = fam;
}
lru = fam;
Skip:
;
}
/* didn't find a node, create a new one */
{
FTC_Cache_Class clazz = cache->clazz;
FTC_Manager manager = cache->manager;
FT_Memory memory = cache->memory;
FTC_Node node;
FTC_Manager manager = cache->manager;
FTC_Family family = (FTC_Family) lru;
FT_UFast hash = query->hash;
FTC_Node* bucket;
FT_UInt idx;
if ( FT_ALLOC( node, clazz->node_size ) )
goto Exit;
idx = hash & cache->mask;
if ( idx < cache->p )
idx = hash & ( cache->mask * 2 + 1 );
node->fam_index = (FT_UShort) family->fam_index;
node->hash = query->hash;
node->ref_count = 0;
bucket = cache->buckets + idx;
error = clazz->node_init( node, query, cache );
if ( error )
if ( query->family != family ||
family->fam_index >= manager->families.size )
{
FT_FREE( node );
FT_ERROR((
"ftc_cache_lookup: invalid query (bad 'family' field)\n" ));
error = FTC_Err_Invalid_Argument;
goto Exit;
}
error = ftc_node_hash_link( node, cache );
if ( error )
if ( *bucket )
{
clazz->node_done( node, cache );
FT_FREE( node );
FTC_Node* pnode = bucket;
FTC_Node_CompareFunc compare = cache->clazz->node_compare;
for ( ;; )
{
FTC_Node node;
node = *pnode;
if ( node == NULL )
break;
if ( node->hash == hash &&
(FT_UInt)node->fam_index == family->fam_index &&
compare( node, query, cache ) )
{
/* move to head of bucket list */
if ( pnode != bucket )
{
*pnode = node->link;
node->link = *bucket;
*bucket = node;
}
/* move to head of MRU list */
if ( node != manager->nodes_list )
ftc_node_mru_up( node, manager );
*anode = node;
goto Exit;
}
pnode = &node->link;
}
}
/* didn't find a node, create a new one */
{
FTC_Cache_Class clazz = cache->clazz;
FT_Memory memory = cache->memory;
FTC_Node node;
if ( FT_ALLOC( node, clazz->node_size ) )
goto Fail;
node->fam_index = (FT_UShort) family->fam_index;
node->hash = query->hash;
node->ref_count = 0;
error = clazz->node_init( node, query, cache );
if ( error )
{
FT_FREE( node );
goto Fail;
}
error = ftc_node_hash_link( node, cache );
if ( error )
{
clazz->node_done( node, cache );
FT_FREE( node );
goto Fail;
}
ftc_node_mru_link( node, cache->manager );
cache->manager->cur_weight += clazz->node_weight( node, cache );
/* now try to compress the node pool when necessary */
if ( manager->cur_weight >= manager->max_weight )
{
node->ref_count++;
FTC_Manager_Compress( manager );
node->ref_count--;
}
*anode = node;
}
/* all is well, exit now
*/
goto Exit;
}
Fail:
if ( error != FT_Err_Out_Of_Memory )
goto Exit;
/* there is not enough memory, try to release some unused nodes
* from the cache to make room for a new one.
*/
{
FT_UInt new_count;
new_count = 1 + free_count*2;
/* check overflow and bounds */
if ( new_count < free_count || free_count > manager->num_nodes )
goto Exit;
}
ftc_node_mru_link( node, cache->manager );
free_count = new_count;
cache->manager->cur_weight += clazz->node_weight( node, cache );
/* now try to compress the node pool when necessary */
if ( manager->cur_weight >= manager->max_weight )
/* try to remove "new_count" nodes from the list */
{
node->ref_count++;
FTC_Manager_Compress( manager );
node->ref_count--;
}
FTC_Node first = manager->nodes_list;
FTC_Node node;
*anode = node;
if ( first == NULL ) /* empty list ! */
goto Exit;
/* go to last node - it's a circular list */
node = first->mru_prev;
for ( ; node && new_count > 0; new_count-- )
{
FTC_Node prev = node->mru_prev;
/* used nodes always appear before unused one in the MRU
* list. if we find one here, we'd better stop right now
* our iteration
*/
if ( node->ref_count > 0 )
{
/* if there are no unused nodes in the list, we'd better exit */
if ( new_count == free_count )
goto Exit;
break;
}
ftc_node_destroy( node, manager );
if ( node == first )
break;
node = prev;
}
}
}
}
+52 -4
View File
@@ -23,9 +23,13 @@
#include FT_CACHE_MANAGER_H
#include FT_INTERNAL_MEMORY_H
#include FT_INTERNAL_DEBUG_H
#include FT_TRUETYPE_IDS_H
#include "ftcerror.h"
#undef FT_COMPONENT
#define FT_COMPONENT trace_cache
/*************************************************************************/
/* */
/* Each FTC_CMapNode contains a simple array to map a range of character */
@@ -189,10 +193,54 @@
break;
case FTC_CMAP_BY_ENCODING:
for ( idx = 0; idx < count; idx++, cur++ )
if ( cur[0]->encoding == desc->u.encoding )
break;
if (desc->u.encoding == FT_ENCODING_UNICODE)
{
/* since the `interesting' table, with id's 3,10, is normally the
* last one, we loop backwards. This looses with type1 fonts with
* non-BMP characters (<.0001%), this wins with .ttf with non-BMP
* chars (.01% ?), and this is the same about 99.99% of the time!
*/
FT_UInt unicmap_idx = count; /* some UCS-2 map, if we found it */
cur += count - 1;
for ( idx = 0; idx < count; idx++, cur-- )
{
if ( cur[0]->encoding == FT_ENCODING_UNICODE )
{
unicmap_idx = idx; /* record we found a Unicode charmap */
/* XXX If some new encodings to represent UCS-4 are added,
* they should be added here.
*/
if ( ( cur[0]->platform_id == TT_PLATFORM_MICROSOFT &&
cur[0]->encoding_id == TT_MS_ID_UCS_4 ) ||
( cur[0]->platform_id == TT_PLATFORM_APPLE_UNICODE &&
cur[0]->encoding_id == TT_APPLE_ID_UNICODE_32 ) )
/* Hurray! We found a UCS-4 charmap. We can stop the scan! */
{
idx = count - 1 - idx;
goto Found_idx_for_FTC_CMAP_BY_ENCODING;
}
}
}
/* We do not have any UCS-4 charmap. Sigh.
* Let's see if we have some other kind of Unicode charmap, though.
*/
if ( unicmap_idx < count )
idx = count - 1 - unicmap_idx;
}
else
{
for ( idx = 0; idx < count; idx++, cur++ )
if ( cur[0]->encoding == desc->u.encoding )
break;
}
Found_idx_for_FTC_CMAP_BY_ENCODING:
hash = idx * 67;
break;
@@ -227,7 +275,7 @@
return error;
Bad_Descriptor:
FT_ERROR(( "ftp_cmap_family_init: invalid charmap descriptor\n" ));
FT_TRACE1(( "ftp_cmap_family_init: invalid charmap descriptor\n" ));
return FTC_Err_Invalid_Argument;
}
+1 -1
View File
@@ -216,7 +216,7 @@
/* we mark unloaded glyphs with `sbit.buffer == 0' */
/* and 'width == 255', 'height == 0' */
/* */
if ( error )
if ( error && error != FT_Err_Out_Of_Memory )
{
sbit->width = 255;
error = 0;
+105 -49
View File
@@ -21,6 +21,7 @@
#include FT_CACHE_INTERNAL_LRU_H
#include FT_LIST_H
#include FT_INTERNAL_OBJECTS_H
#include FT_INTERNAL_DEBUG_H
#include "ftcerror.h"
@@ -187,80 +188,135 @@
goto Exit;
}
/* we haven't found the relevant element. We will now try */
/* to create a new one. */
/* */
/* since we haven't found the relevant element in our LRU list,
* we're going to "create" a new one.
*
* the following code is a bit special, because it tries to handle
* out-of-memory conditions (OOM) in an intelligent way.
*
* more precisely, if not enough memory is available to create a
* new node or "flush" an old one, we need to remove the oldest
* elements from our list, and try again. since several tries may
* be necessary, a loop is needed
*
* this loop will only exit when:
*
* - a new node was succesfully created, or an old node flushed
* - an error other than FT_Err_Out_Of_Memory is detected
* - the list of nodes is empty, and it isn't possible to create
* new nodes
*
* on each unsucesful attempt, one node will be removed from the list
*
*/
/* first, check if our list if full, when appropriate */
if ( list->max_nodes > 0 && list->num_nodes >= list->max_nodes )
{
/* this list list is full; we will now flush */
/* the oldest node, if there's one! */
FT_LruNode last = *plast;
FT_Int drop_last = ( list->max_nodes > 0 &&
list->num_nodes >= list->max_nodes );
if ( last )
for (;;)
{
if ( clazz->node_flush )
node = NULL;
/* when "drop_last" is true, we should free the last node in
* the list to make room for a new one. note that we re-use
* its memory block to save allocation calls.
*/
if ( drop_last )
{
error = clazz->node_flush( last, key, list->data );
/* find the last node in the list
*/
pnode = &list->nodes;
node = *pnode;
if ( node == NULL )
{
FT_ASSERT( list->nodes == 0 );
error = FT_Err_Out_Of_Memory;
goto Exit;
}
FT_ASSERT( list->num_nodes > 0 );
while ( node->next )
{
pnode = &node->next;
node = *pnode;
}
/* remove it from the list, and try to "flush" it. doing this will
* save a significant number of dynamic allocations compared to
* a classic destroy/create cycle
*/
*pnode = NULL;
list->num_nodes -= 1;
if ( clazz->node_flush )
{
error = clazz->node_flush( node, key, list->data );
if ( !error )
goto Success;
/* note that if an error occured during the flush, we need to
* finalize it since it is potentially in incomplete state.
*/
}
/* we finalize, but do not destroy the last node, we
* simply re-use its memory block !
*/
if ( clazz->node_done )
clazz->node_done( node, list->data );
FT_MEM_ZERO( node, clazz->node_size );
}
else
{
if ( clazz->node_done )
clazz->node_done( last, list->data );
last->key = key;
error = clazz->node_init( last, key, list->data );
/* try to allocate a new node when "drop_last" is not TRUE
* this usually happens on the first pass, when the LRU list
* is not already full.
*/
if ( FT_ALLOC( node, clazz->node_size ) )
goto Fail;
}
if ( !error )
FT_ASSERT( node != NULL );
node->key = key;
error = clazz->node_init( node, key, list->data );
if ( error )
{
/* move it to the top of the list */
*plast = NULL;
last->next = list->nodes;
list->nodes = last;
if ( clazz->node_done )
clazz->node_done( node, list->data );
result = last;
goto Exit;
FT_FREE( node );
goto Fail;
}
/* in case of error during the flush or done/init cycle, */
/* we need to discard the node */
if ( clazz->node_done )
clazz->node_done( last, list->data );
Success:
result = node;
*plast = NULL;
list->num_nodes--;
FT_FREE( last );
node->next = list->nodes;
list->nodes = node;
list->num_nodes++;
goto Exit;
Fail:
if ( error != FT_Err_Out_Of_Memory )
goto Exit;
drop_last = 1;
continue;
}
}
/* otherwise, simply allocate a new node */
if ( FT_ALLOC( node, clazz->node_size ) )
goto Exit;
node->key = key;
error = clazz->node_init( node, key, list->data );
if ( error )
{
FT_FREE( node );
goto Exit;
}
result = node;
node->next = list->nodes;
list->nodes = node;
list->num_nodes++;
Exit:
*anode = result;
return error;
}
FT_EXPORT_DEF( void )
FT_LruList_Remove( FT_LruList list,
FT_LruNode node )
+23
View File
@@ -2363,6 +2363,29 @@
cff_builder_done( &decoder.builder );
}
#ifdef FT_CONFIG_OPTION_INCREMENTAL
/* Incremental fonts can optionally override the metrics. */
if ( !error &&
face->root.internal->incremental_interface &&
face->root.internal->incremental_interface->funcs->get_glyph_metrics )
{
FT_Incremental_MetricsRec metrics;
metrics.bearing_x = decoder.builder.left_bearing.x;
metrics.bearing_y = decoder.builder.left_bearing.y;
metrics.advance = decoder.builder.advance.x;
error = face->root.internal->incremental_interface->funcs->get_glyph_metrics(
face->root.internal->incremental_interface->object,
glyph_index, FALSE, &metrics );
decoder.builder.left_bearing.x = metrics.bearing_x;
decoder.builder.left_bearing.y = metrics.bearing_y;
decoder.builder.advance.x = metrics.advance;
decoder.builder.advance.y = 0;
}
#endif /* FT_CONFIG_OPTION_INCREMENTAL */
font_matrix = cff->top_font.font_dict.font_matrix;
font_offset = cff->top_font.font_dict.font_offset;
+33 -13
View File
@@ -1595,17 +1595,16 @@
/* In order to use a predefined charset, the following must be */
/* true: The charset constructed for the glyphs in the font's */
/* charstrings dictionary must match the predefined charset in */
/* the first num_glyphs, and hence must match the predefined */
/* charset *exactly*. */
/* the first num_glyphs */
charset->offset = offset; /* record charset type */
switch ( (FT_UInt)offset )
{
case 0:
if ( num_glyphs != 229 )
if ( num_glyphs > 229 )
{
FT_ERROR(("cff_charset_load: implicit charset not equal to\n"
FT_ERROR(("cff_charset_load: implicit charset larger than\n"
"predefined charset (Adobe ISO-Latin)!\n" ));
error = CFF_Err_Invalid_File_Format;
goto Exit;
@@ -1622,9 +1621,9 @@
break;
case 1:
if ( num_glyphs != 166 )
if ( num_glyphs > 166 )
{
FT_ERROR(( "cff_charset_load: implicit charset not equal to\n"
FT_ERROR(( "cff_charset_load: implicit charset larger than\n"
"predefined charset (Adobe Expert)!\n" ));
error = CFF_Err_Invalid_File_Format;
goto Exit;
@@ -1641,9 +1640,9 @@
break;
case 2:
if ( num_glyphs != 87 )
if ( num_glyphs > 87 )
{
FT_ERROR(( "cff_charset_load: implicit charset not equal to\n"
FT_ERROR(( "cff_charset_load: implicit charset larger than\n"
"predefined charset (Adobe Expert Subset)!\n" ));
error = CFF_Err_Invalid_File_Format;
goto Exit;
@@ -1744,14 +1743,17 @@
FT_READ_BYTE( count ) )
goto Exit;
encoding->count = count + 1;
switch ( encoding->format & 0x7F )
{
case 0:
{
FT_Byte* p;
/* by convention, GID 0 is always ".notdef" and is never */
/* coded in the font. Hence, the number of codes found */
/* in the table is 'count+1' */
/* */
encoding->count = count + 1;
if ( FT_FRAME_ENTER( count ) )
goto Exit;
@@ -1763,7 +1765,7 @@
glyph_code = *p++;
/* Make sure j is not too big. */
if ( (FT_UInt) glyph_code < num_glyphs )
if ( j < num_glyphs )
{
/* Assign code to GID mapping. */
encoding->codes[glyph_code] = (FT_UShort)j;
@@ -1784,6 +1786,8 @@
FT_UInt k;
encoding->count = 0;
/* Parse the Format1 ranges. */
for ( j = 0; j < count; j++, i += nleft )
{
@@ -1798,6 +1802,10 @@
/* Increment nleft, so we read `nleft + 1' codes/sids. */
nleft++;
/* compute max number of character codes */
if ( (FT_UInt)nleft > encoding->count )
encoding->count = nleft;
/* Fill in the range of codes/sids. */
for ( k = i; k < nleft + i; k++, glyph_code++ )
{
@@ -1812,6 +1820,10 @@
}
}
}
/* simple check, one never knows what can be found in a font */
if ( encoding->count > 256 )
encoding->count = 256;
}
break;
@@ -1867,8 +1879,6 @@
/* encoding (see the note at the end of section 12 in the CFF */
/* specification). */
encoding->count = 256;
switch ( (FT_UInt)offset )
{
case 0:
@@ -1886,6 +1896,10 @@
Populate:
/* Construct code to GID mapping from code to SID mapping */
/* and charset. */
encoding->count = 0;
for ( j = 0; j < 256; j++ )
{
/* If j is encoded, find the GID for it. */
@@ -1905,7 +1919,13 @@
encoding->sids [j] = 0;
}
else
{
encoding->codes[j] = (FT_UShort)i;
/* update encoding count */
if ( encoding->count < j+1 )
encoding->count = j+1;
}
}
}
break;
+10 -12
View File
@@ -89,7 +89,7 @@
else
#endif
#endif /* FT_CONFIG_OPTION_INCREMENTAL */
/* For ordinary fonts read the CID font dictionary index */
/* and charstring offset from the CIDMap. */
@@ -162,23 +162,21 @@
face->root.internal->incremental_interface &&
face->root.internal->incremental_interface->funcs->get_glyph_metrics )
{
FT_Bool found = FALSE;
FT_Incremental_MetricsRec metrics;
metrics.bearing_x = decoder->builder.left_bearing.x;
metrics.bearing_y = decoder->builder.left_bearing.y;
metrics.advance = decoder->builder.advance.x;
error = face->root.internal->incremental_interface->funcs->get_glyph_metrics(
face->root.internal->incremental_interface->object,
glyph_index, FALSE, &metrics, &found );
if ( found )
{
decoder->builder.left_bearing.x = metrics.bearing_x;
decoder->builder.left_bearing.y = metrics.bearing_y;
decoder->builder.advance.x = metrics.advance;
decoder->builder.advance.y = 0;
}
glyph_index, FALSE, &metrics );
decoder->builder.left_bearing.x = metrics.bearing_x;
decoder->builder.left_bearing.y = metrics.bearing_y;
decoder->builder.advance.x = metrics.advance;
decoder->builder.advance.y = 0;
}
#endif
#endif /* FT_CONFIG_OPTION_INCREMENTAL */
Exit:
return error;
+5 -5
View File
@@ -3,7 +3,7 @@
* For conditions of distribution and use, see copyright notice in zlib.h
*/
/* @(#) $Id: adler32.c,v 1.1 2002/11/20 19:19:09 bonefish Exp $ */
/* @(#) $Id: adler32.c,v 1.2 2003/07/24 18:52:52 darkwyrm Exp $ */
#include "zlib.h"
@@ -18,10 +18,10 @@
#define DO16(buf) DO8(buf,0); DO8(buf,8);
/* ========================================================================= */
ZEXTERNDEF uLong ZEXPORT adler32(adler, buf, len)
uLong adler;
const Bytef *buf;
uInt len;
ZEXPORT(uLong) adler32( /* adler, buf, len) */
uLong adler,
const Bytef *buf,
uInt len )
{
unsigned long s1 = adler & 0xffff;
unsigned long s2 = (adler >> 16) & 0xffff;
+10 -7
View File
@@ -29,7 +29,7 @@
#ifdef FT_CONFIG_OPTION_SYSTEM_ZLIB
# include "zlib.h"
# include <zlib.h>
#else /* !SYSTEM_ZLIB */
@@ -96,10 +96,10 @@
#ifndef FT_CONFIG_OPTION_SYSTEM_ZLIB
local voidpf
zcalloc (opaque, items, size)
voidpf opaque;
unsigned items;
unsigned size;
zcalloc ( /* opaque, items, size) */
voidpf opaque,
unsigned items,
unsigned size )
{
return ft_gzip_alloc( opaque, items, size );
}
@@ -177,7 +177,7 @@
(void)FT_STREAM_SKIP( 6 );
/* skip the extra field */
if ( head[3] && FT_GZIP_EXTRA_FIELD )
if ( head[3] & FT_GZIP_EXTRA_FIELD )
{
FT_UInt len;
@@ -187,7 +187,7 @@
}
/* skip original file name */
if ( head[3] && FT_GZIP_ORIG_NAME )
if ( head[3] & FT_GZIP_ORIG_NAME )
for (;;)
{
FT_UInt c;
@@ -276,6 +276,8 @@
{
z_stream* zstream = &zip->zstream;
inflateEnd( zstream );
/* clear the rest */
zstream->zalloc = NULL;
zstream->zfree = NULL;
@@ -376,6 +378,7 @@
if ( err == Z_STREAM_END )
{
zip->limit = zstream->next_out;
error = FT_Err_Invalid_Stream_Operation;
break;
}
else if ( err != Z_OK )
+18 -15
View File
@@ -64,10 +64,10 @@ local const uInt border[] = { /* Order of the bit length code lengths */
*/
local void inflate_blocks_reset(s, z, c)
inflate_blocks_statef *s;
z_streamp z;
uLongf *c;
local void inflate_blocks_reset( /* s, z, c) */
inflate_blocks_statef *s,
z_streamp z,
uLongf *c )
{
if (c != Z_NULL)
*c = s->check;
@@ -85,10 +85,10 @@ uLongf *c;
}
local inflate_blocks_statef *inflate_blocks_new(z, c, w)
z_streamp z;
check_func c;
uInt w;
local inflate_blocks_statef *inflate_blocks_new( /* z, c, w) */
z_streamp z,
check_func c,
uInt w )
{
inflate_blocks_statef *s;
@@ -116,10 +116,10 @@ uInt w;
}
local int inflate_blocks(s, z, r)
inflate_blocks_statef *s;
z_streamp z;
int r;
local int inflate_blocks( /* s, z, r) */
inflate_blocks_statef *s,
z_streamp z,
int r )
{
uInt t; /* temporary storage */
uLong b; /* bit buffer */
@@ -365,12 +365,15 @@ int r;
r = Z_STREAM_ERROR;
LEAVE
}
#ifdef NEED_DUMMY_RETURN
return 0;
#endif
}
local int inflate_blocks_free(s, z)
inflate_blocks_statef *s;
z_streamp z;
local int inflate_blocks_free( /* s, z) */
inflate_blocks_statef *s,
z_streamp z )
{
inflate_blocks_reset(s, z, Z_NULL);
ZFREE(z, s->window);
+12 -12
View File
@@ -55,11 +55,11 @@ struct inflate_codes_state {
};
local inflate_codes_statef *inflate_codes_new(bl, bd, tl, td, z)
uInt bl, bd;
inflate_huft *tl;
inflate_huft *td; /* need separate declaration for Borland C++ */
z_streamp z;
local inflate_codes_statef *inflate_codes_new( /* bl, bd, tl, td, z) */
uInt bl, uInt bd,
inflate_huft *tl,
inflate_huft *td, /* need separate declaration for Borland C++ */
z_streamp z )
{
inflate_codes_statef *c;
@@ -77,10 +77,10 @@ z_streamp z;
}
local int inflate_codes(s, z, r)
inflate_blocks_statef *s;
z_streamp z;
int r;
local int inflate_codes( /* s, z, r) */
inflate_blocks_statef *s,
z_streamp z,
int r )
{
uInt j; /* temporary storage */
inflate_huft *t; /* temporary pointer */
@@ -241,9 +241,9 @@ int r;
}
local void inflate_codes_free(c, z)
inflate_codes_statef *c;
z_streamp z;
local void inflate_codes_free( /* c, z) */
inflate_codes_statef *c,
z_streamp z )
{
ZFREE(z, c);
Tracev((stderr, "inflate: codes free\n"));
+12 -12
View File
@@ -51,8 +51,8 @@ struct internal_state {
};
int ZEXPORT inflateReset(z)
z_streamp z;
ZEXPORT(int) inflateReset( /* z) */
z_streamp z )
{
if (z == Z_NULL || z->state == Z_NULL)
return Z_STREAM_ERROR;
@@ -65,8 +65,8 @@ z_streamp z;
}
int ZEXPORT inflateEnd(z)
z_streamp z;
ZEXPORT(int) inflateEnd( /* z) */
z_streamp z )
{
if (z == Z_NULL || z->state == Z_NULL || z->zfree == Z_NULL)
return Z_STREAM_ERROR;
@@ -79,11 +79,11 @@ z_streamp z;
}
int ZEXPORT inflateInit2_(z, w, version, stream_size)
z_streamp z;
int w;
const char *version;
int stream_size;
ZEXPORT(int) inflateInit2_( /* z, w, version, stream_size) */
z_streamp z,
int w,
const char *version,
int stream_size )
{
if (version == Z_NULL || version[0] != ZLIB_VERSION[0] ||
stream_size != sizeof(z_stream))
@@ -144,9 +144,9 @@ int stream_size;
#define NEXTBYTE (z->avail_in--,z->total_in++,*z->next_in++)
int ZEXPORT inflate(z, f)
z_streamp z;
int f;
ZEXPORT(int) inflate( /* z, f) */
z_streamp z,
int f )
{
int r;
uInt b;
+40 -33
View File
@@ -10,8 +10,11 @@
# define BUILDFIXED /* non ANSI compilers may not accept inffixed.h */
#endif
#if 0
local const char inflate_copyright[] =
" inflate 1.1.4 Copyright 1995-2002 Mark Adler ";
#endif
/*
If you use the zlib library in a product, an acknowledgment is welcome
in the documentation of your product. If for some reason you cannot
@@ -89,21 +92,22 @@ local const uInt cpdext[30] = { /* Extra bits for distance codes */
/* If BMAX needs to be larger than 16, then h and x[] should be uLong. */
#define BMAX 15 /* maximum bit length of any code */
local int huft_build(b, n, s, d, e, t, m, hp, hn, v)
uIntf *b; /* code lengths in bits (all assumed <= BMAX) */
uInt n; /* number of codes (assumed <= 288) */
uInt s; /* number of simple-valued codes (0..s-1) */
const uIntf *d; /* list of base values for non-simple codes */
const uIntf *e; /* list of extra bits for non-simple codes */
inflate_huft * FAR *t; /* result: starting table */
uIntf *m; /* maximum lookup bits, returns actual */
inflate_huft *hp; /* space for trees */
uInt *hn; /* hufts used in space */
uIntf *v; /* working area: values in order of bit length */
local int huft_build( /* b, n, s, d, e, t, m, hp, hn, v) */
uIntf *b, /* code lengths in bits (all assumed <= BMAX) */
uInt n, /* number of codes (assumed <= 288) */
uInt s, /* number of simple-valued codes (0..s-1) */
const uIntf *d, /* list of base values for non-simple codes */
const uIntf *e, /* list of extra bits for non-simple codes */
inflate_huft * FAR *t, /* result: starting table */
uIntf *m, /* maximum lookup bits, returns actual */
inflate_huft *hp, /* space for trees */
uInt *hn, /* hufts used in space */
uIntf *v /* working area: values in order of bit length */
/* Given a list of code lengths and a maximum table size, make a set of
tables to decode that set of codes. Return Z_OK on success, Z_BUF_ERROR
if the given code set is incomplete (the tables are still built in this
case), or Z_DATA_ERROR if the input is invalid. */
)
{
uInt a; /* counter for codes of length k */
@@ -289,12 +293,13 @@ uIntf *v; /* working area: values in order of bit length */
}
local int inflate_trees_bits(c, bb, tb, hp, z)
uIntf *c; /* 19 code lengths */
uIntf *bb; /* bits tree desired/actual depth */
inflate_huft * FAR *tb; /* bits tree result */
inflate_huft *hp; /* space for trees */
z_streamp z; /* for messages */
local int inflate_trees_bits( /* c, bb, tb, hp, z) */
uIntf *c, /* 19 code lengths */
uIntf *bb, /* bits tree desired/actual depth */
inflate_huft * FAR *tb, /* bits tree result */
inflate_huft *hp, /* space for trees */
z_streamp z /* for messages */
)
{
int r;
uInt hn = 0; /* hufts used in space */
@@ -316,16 +321,17 @@ z_streamp z; /* for messages */
}
local int inflate_trees_dynamic(nl, nd, c, bl, bd, tl, td, hp, z)
uInt nl; /* number of literal/length codes */
uInt nd; /* number of distance codes */
uIntf *c; /* that many (total) code lengths */
uIntf *bl; /* literal desired/actual bit depth */
uIntf *bd; /* distance desired/actual bit depth */
inflate_huft * FAR *tl; /* literal/length tree result */
inflate_huft * FAR *td; /* distance tree result */
inflate_huft *hp; /* space for trees */
z_streamp z; /* for messages */
local int inflate_trees_dynamic( /* nl, nd, c, bl, bd, tl, td, hp, z) */
uInt nl, /* number of literal/length codes */
uInt nd, /* number of distance codes */
uIntf *c, /* that many (total) code lengths */
uIntf *bl, /* literal desired/actual bit depth */
uIntf *bd, /* distance desired/actual bit depth */
inflate_huft * FAR *tl, /* literal/length tree result */
inflate_huft * FAR *td, /* distance tree result */
inflate_huft *hp, /* space for trees */
z_streamp z /* for messages */
)
{
int r;
uInt hn = 0; /* hufts used in space */
@@ -394,12 +400,13 @@ local inflate_huft *fixed_td;
#endif
local int inflate_trees_fixed(bl, bd, tl, td, z)
uIntf *bl; /* literal desired/actual bit depth */
uIntf *bd; /* distance desired/actual bit depth */
inflate_huft * FAR *tl; /* literal/length tree result */
inflate_huft * FAR *td; /* distance tree result */
z_streamp z; /* for memory allocation */
local int inflate_trees_fixed( /* bl, bd, tl, td, z) */
uIntf *bl, /* literal desired/actual bit depth */
uIntf *bd, /* distance desired/actual bit depth */
inflate_huft * FAR *tl, /* literal/length tree result */
inflate_huft * FAR *td, /* distance tree result */
z_streamp z /* for memory allocation */
)
{
#ifdef BUILDFIXED
/* build fixed tables if not already */
+4 -4
View File
@@ -19,10 +19,10 @@ local uInt inflate_mask[17] = {
/* copy as much as possible from the sliding window to the output area */
local int inflate_flush(s, z, r)
inflate_blocks_statef *s;
z_streamp z;
int r;
local int inflate_flush( /* s, z, r) */
inflate_blocks_statef *s,
z_streamp z,
int r )
{
uInt n;
Bytef *p;
+11 -3
View File
@@ -21,7 +21,11 @@ GZIP_DIR_ := $(GZIP_DIR)$(SEP)
# compilation flags for the driver
#
GZIP_COMPILE := $(FT_COMPILE) $I$(GZIP_DIR)
ifeq ($(SYSTEM_ZLIB),)
GZIP_COMPILE := $(FT_COMPILE) $I$(GZIP_DIR)
else
GZIP_COMPILE := $(FT_COMPILE)
endif
# gzip support sources (i.e., C files)
@@ -33,12 +37,16 @@ GZIP_DRV_SRC := $(GZIP_DIR_)ftgzip.c
GZIP_DRV_H :=
# Pfr driver object(s)
# gzip driver object(s)
#
# GZIP_DRV_OBJ_M is used during `multi' builds
# GZIP_DRV_OBJ_S is used during `single' builds
#
GZIP_DRV_OBJ_M := $(GZIP_DRV_SRC:$(GZIP_DIR_)%.c=$(OBJ_)%.$O)
ifeq ($(SYSTEM_ZLIB),)
GZIP_DRV_OBJ_M := $(GZIP_DRV_SRC:$(GZIP_DIR_)%.c=$(OBJ_)%.$O)
else
GZIP_DRV_OBJ_M := $(OBJ_)ftgzip.$O
endif
GZIP_DRV_OBJ_S := $(OBJ_)ftgzip.$O
# gzip support source file for single build
+16 -13
View File
@@ -3,7 +3,7 @@
* For conditions of distribution and use, see copyright notice in zlib.h
*/
/* @(#) $Id: zconf.h,v 1.1 2002/11/20 19:19:16 bonefish Exp $ */
/* @(#) $Id: zconf.h,v 1.2 2003/07/24 18:52:52 darkwyrm Exp $ */
#ifndef _ZCONF_H
#define _ZCONF_H
@@ -91,11 +91,14 @@
# define NO_DUMMY_DECL
#endif
/* Old Borland C incorrectly complains about missing returns: */
/* Old Borland C and LCC incorrectly complains about missing returns: */
#if defined(__BORLANDC__) && (__BORLANDC__ < 0x500)
# define NEED_DUMMY_RETURN
#endif
#if defined(__LCC__)
# define NEED_DUMMY_RETURN
#endif
/* Maximum value for memLevel in deflateInit2 */
#ifndef MAX_MEM_LEVEL
@@ -167,22 +170,22 @@
# undef FAR
# endif
# include <windows.h>
# define ZEXPORT WINAPI
# define ZEXPORT(x) x WINAPI
# ifdef WIN32
# define ZEXPORTVA WINAPIV
# define ZEXPORTVA(x) x WINAPIV
# else
# define ZEXPORTVA FAR _cdecl _export
# define ZEXPORTVA(x) x FAR _cdecl _export
# endif
# endif
# if defined (__BORLANDC__)
# if (__BORLANDC__ >= 0x0500) && defined (WIN32)
# include <windows.h>
# define ZEXPORT __declspec(dllexport) WINAPI
# define ZEXPORTRVA __declspec(dllexport) WINAPIV
# define ZEXPORT(x) x __declspec(dllexport) WINAPI
# define ZEXPORTRVA(x) x __declspec(dllexport) WINAPIV
# else
# if defined (_Windows) && defined (__DLL__)
# define ZEXPORT _export
# define ZEXPORTVA _export
# define ZEXPORT(x) x _export
# define ZEXPORTVA(x) x _export
# endif
# endif
# endif
@@ -190,16 +193,16 @@
#ifndef ZEXPORT
# define ZEXPORT
# define ZEXPORT(x) static x
#endif
#ifndef ZEXPORTVA
# define ZEXPORTVA
# define ZEXPORTVA(x) static x
#endif
#ifndef ZEXTERN
# define ZEXTERN static
# define ZEXTERN(x) static x
#endif
#ifndef ZEXTERNDEF
# define ZEXTERNDEF static
# define ZEXTERNDEF(x) static x
#endif
#ifndef FAR
+9 -9
View File
@@ -173,7 +173,7 @@ typedef z_stream FAR *z_streamp;
*/
/*
ZEXTERN int ZEXPORT deflateInit OF((z_streamp strm, int level));
ZEXTERN(int) deflateInit OF((z_streamp strm, int level));
Initializes the internal stream state for compression. The fields
zalloc, zfree and opaque must be initialized before by the caller.
@@ -286,7 +286,7 @@ ZEXTERN int ZEXPORT deflateInit OF((z_streamp strm, int level));
/*
ZEXTERN int ZEXPORT inflateInit OF((z_streamp strm));
ZEXTERN(int) inflateInit OF((z_streamp strm));
Initializes the internal stream state for decompression. The fields
next_in, avail_in, zalloc, zfree and opaque must be initialized before by
@@ -306,7 +306,7 @@ ZEXTERN int ZEXPORT inflateInit OF((z_streamp strm));
*/
ZEXTERN int ZEXPORT inflate OF((z_streamp strm, int flush));
ZEXTERN(int) inflate OF((z_streamp strm, int flush));
/*
inflate decompresses as much data as possible, and stops when the input
buffer becomes empty or the output buffer becomes full. It may some
@@ -375,7 +375,7 @@ ZEXTERN int ZEXPORT inflate OF((z_streamp strm, int flush));
*/
ZEXTERN int ZEXPORT inflateEnd OF((z_streamp strm));
ZEXTERN(int) inflateEnd OF((z_streamp strm));
/*
All dynamically allocated data structures for this stream are freed.
This function discards any unprocessed input and does not flush any
@@ -393,7 +393,7 @@ ZEXTERN int ZEXPORT inflateEnd OF((z_streamp strm));
*/
/*
ZEXTERN int ZEXPORT deflateInit2 OF((z_streamp strm,
ZEXTERN(int) deflateInit2 OF((z_streamp strm,
int level,
int method,
int windowBits,
@@ -514,7 +514,7 @@ ZEXTERN int ZEXPORT deflateInit2 OF((z_streamp strm,
*/
/*
ZEXTERN int ZEXPORT inflateInit2 OF((z_streamp strm,
ZEXTERN(int) inflateInit2 OF((z_streamp strm,
int windowBits));
This is another version of inflateInit with an extra parameter. The
@@ -566,7 +566,7 @@ ZEXTERN int ZEXPORT inflateInit2 OF((z_streamp strm,
until success or end of the input data.
*/
ZEXTERN int ZEXPORT inflateReset OF((z_streamp strm));
ZEXTERN(int) inflateReset OF((z_streamp strm));
/*
This function is equivalent to inflateEnd followed by inflateInit,
but does not free and reallocate all the internal decompression state.
@@ -772,7 +772,7 @@ ZEXTERN int ZEXPORT inflateReset OF((z_streamp strm));
compression library.
*/
ZEXTERN uLong ZEXPORT adler32 OF((uLong adler, const Bytef *buf, uInt len));
ZEXTERN(uLong) adler32 OF((uLong adler, const Bytef *buf, uInt len));
/*
Update a running Adler-32 checksum with the bytes buf[0..len-1] and
@@ -810,7 +810,7 @@ ZEXTERN uLong ZEXPORT adler32 OF((uLong adler, const Bytef *buf, uInt len));
/* deflateInit and inflateInit are macros to allow checking the zlib version
* and the compiler's view of z_stream:
*/
ZEXTERN int ZEXPORT inflateInit2_ OF((z_streamp strm, int windowBits,
ZEXTERN(int) inflateInit2_ OF((z_streamp strm, int windowBits,
const char *version, int stream_size));
#define deflateInit(strm, level) \
deflateInit_((strm), (level), ZLIB_VERSION, sizeof(z_stream))
+1 -1
View File
@@ -3,7 +3,7 @@
* For conditions of distribution and use, see copyright notice in zlib.h
*/
/* @(#) $Id: zutil.c,v 1.1 2002/11/20 19:19:19 bonefish Exp $ */
/* @(#) $Id: zutil.c,v 1.2 2003/07/24 18:52:52 darkwyrm Exp $ */
#include "zutil.h"
+2 -2
View File
@@ -8,7 +8,7 @@
subject to change. Applications should only use zlib.h.
*/
/* @(#) $Id: zutil.h,v 1.1 2002/11/20 19:19:20 bonefish Exp $ */
/* @(#) $Id: zutil.h,v 1.2 2003/07/24 18:52:52 darkwyrm Exp $ */
#ifndef _Z_UTIL_H
#define _Z_UTIL_H
@@ -203,7 +203,7 @@ typedef unsigned long ulg;
#endif
typedef uLong (ZEXPORT *check_func) OF((uLong check, const Bytef *buf,
typedef uLong (*check_func) OF((uLong check, const Bytef *buf,
uInt len));
local voidpf zcalloc OF((voidpf opaque, unsigned items, unsigned size));
local void zcfree OF((voidpf opaque, voidpf ptr));
+4 -2
View File
@@ -19,10 +19,12 @@ OTL_SCRIPT_TAG( 'a','r','m','n', "Armenian", ARMENIAN )
OTL_SCRIPT_TAG( 'b','e','n','g', "Bengali", BENGALI )
OTL_SCRIPT_TAG( 'b','o','p','o', "Bopomofo", BOPOMOFO )
OTL_SCRIPT_TAG( 'b','r','a','i', "Braille", BRAILLE )
OTL_SCRIPT_TAG( 'b','y','z','m', "Byzantine Music", BYZANTINE_MUSIC )
OTL_SCRIPT_TAG( 'c','a','n','s', "Canadian Syllabic", CANADIAN )
OTL_SCRIPT_TAG( 'c','h','e','r', "Cherokee", CHEROKEE )
OTL_SCRIPT_TAG( 'h','a','n','i', "CJK Ideographic", CJK )
OTL_SCRIPT_TAG( 'c','y','r','l', "Cyrillic", CYRILLIC )
OTL_SCRIPT_TAG( 'd','f','l','t', "Default", DEFAULT )
OTL_SCRIPT_TAG( 'd','e','v','a', "Devanagari", DEVANAGARI )
OTL_SCRIPT_TAG( 'e','t','h','i', "Ethiopic", ETHIOPIC )
OTL_SCRIPT_TAG( 'g','e','o','r', "Georgian", GEORGIAN )
@@ -32,9 +34,9 @@ OTL_SCRIPT_TAG( 'g','u','r','u', "Gurmukhi", GURMUKHI )
OTL_SCRIPT_TAG( 'j','a','m','o', "Hangul Jamo", JAMO )
OTL_SCRIPT_TAG( 'h','a','n','g', "Hangul", HANGUL )
OTL_SCRIPT_TAG( 'h','e','b','r', "Hebrew", HEBREW )
OTL_SCRIPT_TAG( 'h','i','r','a', "Hiragana", HIRAGANA )
OTL_SCRIPT_TAG( 'h','i','r','a', "Hiragana", HIRAGANA ) /* not in TAGS.txt */
OTL_SCRIPT_TAG( 'k','n','d','a', "Kannada", KANNADA )
OTL_SCRIPT_TAG( 'k','a','n','a', "Katakana", KATAKANA )
OTL_SCRIPT_TAG( 'k','a','n','a', "Katakana", KATAKANA ) /* in TAGS.txt, means Hiragana _and_ Katakana */
OTL_SCRIPT_TAG( 'k','h','m','r', "Khmer", KHMER )
OTL_SCRIPT_TAG( 'l','a','o',' ', "Lao", LAO )
OTL_SCRIPT_TAG( 'l','a','t','n', "Latin", LATIN )
-1
View File
@@ -229,7 +229,6 @@ FT_BEGIN_HEADER
pcf_load_font( FT_Stream,
PCF_Face );
FT_END_HEADER
#endif /* __PCF_H__ */
+48 -4
View File
@@ -32,10 +32,12 @@ THE SOFTWARE.
#include FT_INTERNAL_OBJECTS_H
#include FT_GZIP_H
#include FT_ERRORS_H
#include FT_BDF_H
#include "pcf.h"
#include "pcfdriver.h"
#include "pcfutil.h"
#include "pcfread.h"
#include "pcferror.h"
@@ -353,7 +355,6 @@ THE SOFTWARE.
PCF_Face face = (PCF_Face)FT_SIZE_FACE( size );
FT_Stream stream = face->root.stream;
FT_Error error = PCF_Err_Ok;
FT_Memory memory = FT_FACE( face )->memory;
FT_Bitmap* bitmap = &slot->bitmap;
PCF_Metric metric;
int bytes;
@@ -409,7 +410,8 @@ THE SOFTWARE.
/* XXX: to do: are there cases that need repadding the bitmap? */
bytes = bitmap->pitch * bitmap->rows;
if ( FT_ALLOC( bitmap->buffer, bytes ) )
error = ft_glyphslot_alloc_bitmap( slot, bytes );
if ( error )
goto Exit;
if ( FT_STREAM_SEEK( metric->bits ) ||
@@ -449,7 +451,6 @@ THE SOFTWARE.
slot->linearHoriAdvance = (FT_Fixed)bitmap->width << 16;
slot->format = FT_GLYPH_FORMAT_BITMAP;
slot->flags = FT_GLYPH_OWN_BITMAP;
FT_TRACE4(( " --- ok\n" ));
@@ -458,6 +459,49 @@ THE SOFTWARE.
}
static FT_Error
pcf_get_bdf_property( PCF_Face face,
const char* prop_name,
BDF_PropertyRec *aproperty )
{
PCF_Property prop;
prop = pcf_find_property( face, prop_name );
if ( prop != NULL )
{
if ( prop->isString )
{
aproperty->type = BDF_PROPERTY_TYPE_ATOM;
aproperty->u.atom = prop->value.atom;
}
else
{
/* apparently, the PCF driver loads all properties as signed integers !
* this really doesn't seem to be a problem, because this is
* sufficient for any meaningful values
*/
aproperty->type = BDF_PROPERTY_TYPE_INTEGER;
aproperty->u.integer = prop->value.integer;
}
return 0;
}
return FT_Err_Invalid_Argument;
}
static FT_Module_Interface
pcf_driver_requester( FT_Module module,
const char* name )
{
FT_UNUSED( module );
if ( name && ft_strcmp( name, "get_bdf_property" ) == 0 )
return (FT_Module_Interface) pcf_get_bdf_property;
return NULL;
}
FT_CALLBACK_TABLE_DEF
const FT_Driver_ClassRec pcf_driver_class =
{
@@ -473,7 +517,7 @@ THE SOFTWARE.
(FT_Module_Constructor)0,
(FT_Module_Destructor) 0,
(FT_Module_Requester) 0
(FT_Module_Requester) pcf_driver_requester
},
sizeof( PCF_FaceRec ),
+2 -1
View File
@@ -33,6 +33,7 @@ THE SOFTWARE.
#include "pcf.h"
#include "pcfdriver.h"
#include "pcfread.h"
#include "pcferror.h"
@@ -316,7 +317,7 @@ THE SOFTWARE.
};
static PCF_Property
FT_LOCAL_DEF( PCF_Property )
pcf_find_property( PCF_Face face,
const FT_String* prop )
{
+126 -6
View File
@@ -432,7 +432,16 @@
}
/* load font ID, i.e. name */
/* load font ID, this is a so-called "unique" name that is rather
* long and descriptive (like "Tiresias ScreenFont v7.51").
*
* note that a PFR font's family name is contained in an *undocumented*
* string of the "auxiliary data" portion of a physical font record. this
* may also contain the "real" style name !
*
* if no family name is present, the font id is used instead for the
* family
*/
FT_CALLBACK_DEF( FT_Error )
pfr_extra_item_load_font_id( FT_Byte* p,
FT_Byte* limit,
@@ -693,12 +702,54 @@
};
/* loads a name from the auxiliary data. Since this extracts undocumented
* strings from the font file, we need to be careful here
*/
static FT_Error
pfr_aux_name_load( FT_Byte* p,
FT_UInt len,
FT_Memory memory,
FT_String* *astring )
{
FT_Error error = 0;
FT_String* result = NULL;
FT_UInt n, ok;
if ( len > 0 && p[len-1] == 0 )
len--;
/* check that each character is ASCII, that's to be sure
* to not load garbage..
*/
ok = (len > 0);
for ( n = 0; n < len; n++ )
if ( p[n] < 32 || p[n] > 127 )
{
ok = 0;
break;
}
if ( ok )
{
if ( FT_ALLOC( result, len+1 ) )
goto Exit;
FT_MEM_COPY( result, p, len );
result[len] = 0;
}
Exit:
*astring = result;
return error;
}
FT_LOCAL_DEF( void )
pfr_phy_font_done( PFR_PhyFont phy_font,
FT_Memory memory )
{
if ( phy_font->font_id )
FT_FREE( phy_font->font_id );
FT_FREE( phy_font->font_id );
FT_FREE( phy_font->family_name );
FT_FREE( phy_font->style_name );
FT_FREE( phy_font->vertical.stem_snaps );
phy_font->vertical.num_stem_snaps = 0;
@@ -736,6 +787,7 @@
}
FT_LOCAL_DEF( FT_Error )
pfr_phy_font_load( PFR_PhyFont phy_font,
FT_Stream stream,
@@ -790,12 +842,80 @@
goto Fail;
}
/* skip the aux bytes */
/* in certain fonts, the auxiliary bytes contain interesting */
/* information. These are not in the specification but can be */
/* guessed by looking at the content of a few PFR0 fonts */
PFR_CHECK( 3 );
num_aux = PFR_NEXT_ULONG( p );
PFR_CHECK( num_aux );
p += num_aux;
if ( num_aux > 0 )
{
FT_Byte* q = p;
FT_Byte* q2;
PFR_CHECK( num_aux );
p += num_aux;
while ( num_aux > 0 )
{
FT_UInt length, type;
if ( q + 4 > p )
break;
length = PFR_NEXT_USHORT(q);
if ( length < 4 || length > num_aux )
break;
q2 = q + length - 2;
type = PFR_NEXT_USHORT(q);
switch ( type )
{
case 1:
{
/* this seems to correspond to the font's family name,
* padded to 16-bits with one zero when necessary
*/
error = pfr_aux_name_load( q, length-4U, memory,
&phy_font->family_name );
if ( error )
goto Exit;
}
break;
case 2:
{
if ( q + 32 > q2 )
break;
q += 10;
phy_font->ascent = PFR_NEXT_SHORT(q);
phy_font->descent = PFR_NEXT_SHORT(q);
phy_font->leading = PFR_NEXT_SHORT(q);
q += 16;
}
break;
case 3:
{
/* this seems to correspond to the font's style name,
* padded to 16-bits with one zero when necessary
*/
error = pfr_aux_name_load( q, length-4U, memory,
&phy_font->style_name );
if ( error )
goto Exit;
}
break;
default:
;
}
q = q2;
num_aux -= length;
}
}
/* read the blue values */
{
+46 -2
View File
@@ -41,10 +41,17 @@
FT_LOCAL_DEF( void )
pfr_face_done( PFR_Face face )
{
FT_Memory memory = face->root.driver->root.memory;
/* we don't want dangling pointers */
face->root.family_name = NULL;
face->root.style_name = NULL;
/* finalize the physical font record */
pfr_phy_font_done( &face->phy_font, FT_FACE_MEMORY( face ) );
/* no need to finalize the logical font or the header */
FT_FREE( face->root.available_sizes );
}
@@ -136,8 +143,18 @@
if ( phy_font->num_kern_pairs > 0 )
root->face_flags |= FT_FACE_FLAG_KERNING;
root->family_name = phy_font->font_id;
root->style_name = NULL; /* no style name in font file */
/* if no family name was found in the "undocumented" auxiliary
* data, use the font ID instead. This sucks but is better than
* nothing
*/
root->family_name = phy_font->family_name;
if ( root->family_name == NULL )
root->family_name = phy_font->font_id;
/* note that the style name can be NULL in certain PFR fonts,
* probably meaning "Regular"
*/
root->style_name = phy_font->style_name;
root->num_fixed_sizes = 0;
root->available_sizes = 0;
@@ -150,6 +167,27 @@
( ( ( root->ascender - root->descender ) * 12 )
/ 10 );
if ( phy_font->num_strikes > 0 )
{
FT_UInt n, count = phy_font->num_strikes;
FT_Bitmap_Size* size;
PFR_Strike strike;
FT_Memory memory = root->stream->memory;
if ( FT_NEW_ARRAY( root->available_sizes, count ) )
goto Exit;
size = root->available_sizes;
strike = phy_font->strikes;
for ( n = 0; n < count; n++, size++, strike++ )
{
size->height = (FT_UShort) strike->y_ppm;
size->width = (FT_UShort) strike->x_ppm;
}
root->num_fixed_sizes = count;
}
/* now compute maximum advance width */
if ( ( phy_font->flags & PFR_PHY_PROPORTIONAL ) == 0 )
root->max_advance_width = (FT_Short)phy_font->standard_advance;
@@ -255,6 +293,12 @@
goto Exit;
}
if ( load_flags & FT_LOAD_SBITS_ONLY )
{
error = FT_Err_Invalid_Argument;
goto Exit;
}
gchar = face->phy_font.chars + gindex;
slot->root.format = FT_GLYPH_FORMAT_OUTLINE;
outline->n_points = 0;
+10 -11
View File
@@ -49,7 +49,7 @@
static void
pfr_bitwriter_init( PFR_BitWriter writer,
FT_Bitmap* target,
FT_Bool decreasing )
FT_UInt decreasing )
{
writer->line = target->buffer;
writer->pitch = target->pitch;
@@ -107,7 +107,7 @@
}
else if ( mask == 0 )
{
cur[0] = c;
cur[0] = (FT_Byte)c;
mask = 0x80;
c = 0;
cur ++;
@@ -115,7 +115,7 @@
}
if ( mask != 0x80 )
cur[0] = c;
cur[0] = (FT_Byte) c;
}
@@ -185,7 +185,7 @@
}
else if ( mask == 0 )
{
cur[0] = c;
cur[0] = (FT_Byte) c;
mask = 0x80;
c = 0;
cur ++;
@@ -249,7 +249,7 @@
}
else if ( mask == 0 )
{
cur[0] = c;
cur[0] = (FT_Byte) c;
c = 0;
mask = 0x80;
cur ++;
@@ -281,7 +281,7 @@
FT_ULong* found_size )
{
FT_UInt left, right, char_len;
FT_Bool two = flags & 1;
FT_Bool two = FT_BOOL( flags & 1 );
FT_Byte* buff;
@@ -583,7 +583,7 @@
pfr_lookup_bitmap_data( stream->cursor,
stream->limit,
strike->num_bitmaps,
strike->flags,
(FT_Byte) strike->flags,
character->char_code,
&gps_offset,
&gps_size );
@@ -645,11 +645,10 @@
/* Allocate and read bitmap data */
{
FT_Memory memory = face->root.memory;
FT_Long len = glyph->root.bitmap.pitch * ysize;
FT_ULong len = glyph->root.bitmap.pitch * ysize;
if ( !FT_ALLOC( glyph->root.bitmap.buffer, len ) )
error = ft_glyphslot_alloc_bitmap( &glyph->root, len );
if ( !error )
{
error = pfr_load_bitmap_bits( p,
stream->limit,
+6
View File
@@ -231,10 +231,16 @@ FT_BEGIN_HEADER
FT_UInt flags;
FT_UInt standard_advance;
FT_Int ascent; /* optional, bbox.yMax if not present */
FT_Int descent; /* optional, bbox.yMin if not present */
FT_Int leading; /* optional, 0 if not present */
PFR_DimensionRec horizontal;
PFR_DimensionRec vertical;
FT_String* font_id;
FT_String* family_name;
FT_String* style_name;
FT_UInt num_strikes;
FT_UInt max_strikes;
+3
View File
@@ -111,7 +111,10 @@
/* allocate new base block */
if ( FT_ALLOC( table->block, new_size ) )
{
table->block = old_base;
return error;
}
/* copy elements and shift offsets */
if (old_base )
+212 -11
View File
@@ -332,6 +332,7 @@
/*************************************************************************/
/*************************************************************************/
#if 1
static FT_Pos
psh3_dimension_quantize_len( PSH_Dimension dim,
FT_Pos len,
@@ -380,6 +381,7 @@
return len;
}
#endif /* 0 */
#ifdef DEBUG_HINTER
@@ -456,7 +458,9 @@
return;
}
/* perform stem snapping when requested */
/* perform stem snapping when requested - this is necessary
* for monochrome and LCD hinting modes only
*/
do_snapping = ( dimension == 0 && glyph->do_horz_snapping ) ||
( dimension == 1 && glyph->do_vert_snapping );
@@ -516,17 +520,29 @@
hint->cur_pos = pos;
hint->cur_len = fit_len;
if ( len <= 64 )
/* stem adjustment tries to snap stem widths to standard
* ones. this is important to prevent unpleasant rounding
* artefacts...
*/
if ( glyph->do_stem_adjust )
{
/* the stem is less than one pixel, we will center it */
/* around the nearest pixel center */
/* */
pos = ( pos + ( (len >> 1) & -64 ) );
len = 64;
}
else
{
len = psh3_dimension_quantize_len( dim, len, 0 );
if ( len <= 64 )
{
/* the stem is less than one pixel, we will center it
* around the nearest pixel center
*/
#if 1
pos = ( pos + (len >> 1) ) & -64;
#else
/* this seems to be a bug !! */
pos = ( pos + ( (len >> 1) & -64 ) );
#endif
len = 64;
}
else
{
len = psh3_dimension_quantize_len( dim, len, 0 );
}
}
/* now that we have a good hinted stem width, try to position */
@@ -584,6 +600,189 @@
}
#if 0 /* not used for now, experimental */
/*
* A variant to perform "light" hinting (i.e. FT_RENDER_MODE_LIGHT)
* of stems
*/
static void
psh3_hint_align_light( PSH3_Hint hint,
PSH_Globals globals,
FT_Int dimension,
PSH3_Glyph glyph )
{
PSH_Dimension dim = &globals->dimension[dimension];
FT_Fixed scale = dim->scale_mult;
FT_Fixed delta = dim->scale_delta;
if ( !psh3_hint_is_fitted(hint) )
{
FT_Pos pos = FT_MulFix( hint->org_pos, scale ) + delta;
FT_Pos len = FT_MulFix( hint->org_len, scale );
FT_Pos fit_len;
PSH_AlignmentRec align;
/* ignore stem alignments when requested through the hint flags */
if ( ( dimension == 0 && !glyph->do_horz_hints ) ||
( dimension == 1 && !glyph->do_vert_hints ) )
{
hint->cur_pos = pos;
hint->cur_len = len;
psh3_hint_set_fitted( hint );
return;
}
fit_len = len;
hint->cur_len = fit_len;
/* check blue zones for horizontal stems */
align.align = PSH_BLUE_ALIGN_NONE;
align.align_bot = align.align_top = 0;
if ( dimension == 1 )
psh_blues_snap_stem( &globals->blues,
hint->org_pos + hint->org_len,
hint->org_pos,
&align );
switch ( align.align )
{
case PSH_BLUE_ALIGN_TOP:
/* the top of the stem is aligned against a blue zone */
hint->cur_pos = align.align_top - fit_len;
break;
case PSH_BLUE_ALIGN_BOT:
/* the bottom of the stem is aligned against a blue zone */
hint->cur_pos = align.align_bot;
break;
case PSH_BLUE_ALIGN_TOP | PSH_BLUE_ALIGN_BOT:
/* both edges of the stem are aligned against blue zones */
hint->cur_pos = align.align_bot;
hint->cur_len = align.align_top - align.align_bot;
break;
default:
{
PSH3_Hint parent = hint->parent;
if ( parent )
{
FT_Pos par_org_center, par_cur_center;
FT_Pos cur_org_center, cur_delta;
/* ensure that parent is already fitted */
if ( !psh3_hint_is_fitted( parent ) )
psh3_hint_align_light( parent, globals, dimension, glyph );
par_org_center = parent->org_pos + ( parent->org_len / 2);
par_cur_center = parent->cur_pos + ( parent->cur_len / 2);
cur_org_center = hint->org_pos + ( hint->org_len / 2);
cur_delta = FT_MulFix( cur_org_center - par_org_center, scale );
pos = par_cur_center + cur_delta - ( len >> 1 );
}
/* Stems less than one pixel wide are easy - we want to
* make them as dark as possible, so they must fall within
* one pixel. If the stem is split between two pixels
* then snap the edge that is nearer to the pixel boundary
* to the pixel boundary
*/
if (len <= 64)
{
if ( ( pos + len + 63 ) / 64 != pos / 64 + 1 )
pos += psh3_hint_snap_stem_side_delta ( pos, len );
}
/* Position stems other to minimize the amount of mid-grays.
* There are, in general, two positions that do this,
* illustrated as A) and B) below.
*
* + + + +
*
* A) |--------------------------------|
* B) |--------------------------------|
* C) |--------------------------------|
*
* Position A) (split the excess stem equally) should be better
* for stems of width N + f where f < 0.5
*
* Position B) (split the deficiency equally) should be better
* for stems of width N + f where f > 0.5
*
* It turns out though that minimizing the total number of lit
* pixels is also important, so position C), with one edge
* aligned with a pixel boundary is actually preferable
* to A). There are also more possibile positions for C) than
* for A) or B), so it involves less distortion of the overall
* character shape.
*/
else /* len > 64 */
{
FT_Fixed frac_len = len & 63;
FT_Fixed center = pos + ( len >> 1 );
FT_Fixed delta_a, delta_b;
if ( ( len / 64 ) & 1 )
{
delta_a = ( center & -64 ) + 32 - center;
delta_b = ( ( center + 32 ) & - 64 ) - center;
}
else
{
delta_a = ( ( center + 32 ) & - 64 ) - center;
delta_b = ( center & -64 ) + 32 - center;
}
/* We choose between B) and C) above based on the amount
* of fractinal stem width; for small amounts, choose
* C) always, for large amounts, B) always, and inbetween,
* pick whichever one involves less stem movement.
*/
if (frac_len < 32)
{
pos += psh3_hint_snap_stem_side_delta ( pos, len );
}
else if (frac_len < 48)
{
FT_Fixed side_delta = psh3_hint_snap_stem_side_delta ( pos, len );
if ( ABS( side_delta ) < ABS( delta_b ) )
pos += side_delta;
else
pos += delta_b;
}
else
{
pos += delta_b;
}
}
hint->cur_pos = pos;
}
} /* switch */
psh3_hint_set_fitted( hint );
#ifdef DEBUG_HINTER
if ( ps3_debug_hint_func )
ps3_debug_hint_func( hint, dimension );
#endif
}
}
#endif /* 0 */
static void
psh3_hint_table_align_hints( PSH3_Hint_Table table,
PSH_Globals globals,
@@ -1720,6 +1919,8 @@
glyph->do_vert_snapping = FT_BOOL( hint_mode == FT_RENDER_MODE_MONO ||
hint_mode == FT_RENDER_MODE_LCD_V );
glyph->do_stem_adjust = FT_BOOL( hint_mode != FT_RENDER_MODE_LIGHT );
for ( dimension = 0; dimension < 2; dimension++ )
{
/* load outline coordinates into glyph */
+1
View File
@@ -221,6 +221,7 @@ FT_BEGIN_HEADER
FT_Bool do_vert_hints;
FT_Bool do_horz_snapping;
FT_Bool do_vert_snapping;
FT_Bool do_stem_adjust;
} PSH3_GlyphRec, *PSH3_Glyph;
+3
View File
@@ -228,6 +228,9 @@
if ( ft_strcmp( module_interface, "get_sfnt" ) == 0 )
return (FT_Module_Interface)get_sfnt_table;
if ( ft_strcmp( module_interface, "load_sfnt" ) == 0 )
return (FT_Module_Interface)tt_face_load_any;
#ifdef TT_CONFIG_OPTION_POSTSCRIPT_NAMES
if ( ft_strcmp( module_interface, "glyph_name" ) == 0 )
return (FT_Module_Interface)get_sfnt_glyph_name;
+23 -2
View File
@@ -213,7 +213,14 @@
has_head = 1;
if ( table.Length != 0x36 ||
/* the table length should be 0x36, but certain font tools
* make it 0x38, so we will just check that it is greater.
*
* note that according to the specification,
* the table must be padded to 32-bit lengths, but this doesn't
* apply to the value of its "Length" field !!
*/
if ( table.Length < 0x36 ||
FT_STREAM_SEEK( table.Offset + 12 ) ||
FT_READ_ULONG( magic ) ||
magic != 0x5F0F3CF5UL )
@@ -831,6 +838,20 @@
error = face->goto_table( face, TTAG_hmtx, stream, &table_len );
if ( error )
{
#ifdef FT_CONFIG_OPTION_INCREMENTAL
/* If this is an incrementally loaded font and there are */
/* overriding metrics tolerate a missing 'hmtx' table. */
if ( face->root.internal->incremental_interface &&
face->root.internal->incremental_interface->funcs->
get_glyph_metrics )
{
face->horizontal.number_Of_HMetrics = 0;
error = SFNT_Err_Ok;
goto Exit;
}
#endif
FT_ERROR(( " no horizontal metrics in file!\n" ));
error = SFNT_Err_Hmtx_Table_Missing;
goto Exit;
@@ -1085,7 +1106,7 @@
if ( FT_STREAM_READ_FIELDS( name_table_fields, table ) )
goto Exit;
/* Some popular asian fonts have an invalid `storageOffset' value */
/* Some popular Asian fonts have an invalid `storageOffset' value */
/* (it should be at least "6 + 12*num_names"). However, the string */
/* offsets, computed as "storageOffset + entry->stringOffset", are */
/* valid pointers within the name table... */
+16 -23
View File
@@ -1212,14 +1212,16 @@
TT_SBit_Range range,
FT_ULong ebdt_pos,
FT_ULong glyph_offset,
FT_Bitmap* map,
FT_GlyphSlot slot,
FT_Int x_offset,
FT_Int y_offset,
FT_Stream stream,
TT_SBit_Metrics metrics )
TT_SBit_Metrics metrics,
FT_Int depth )
{
FT_Memory memory = stream->memory;
FT_Error error;
FT_Memory memory = stream->memory;
FT_Bitmap* map = &slot->bitmap;
FT_Error error;
/* place stream at beginning of glyph data and read metrics */
@@ -1230,11 +1232,10 @@
if ( error )
goto Exit;
/* this function is recursive. At the top-level call, the */
/* field map.buffer is NULL. We thus begin by finding the */
/* dimensions of the higher-level glyph to allocate the */
/* final pixmap buffer */
if ( map->buffer == 0 )
/* this function is recursive. At the top-level call, we */
/* compute the dimensions of the higher-level glyph to */
/* allocate the final pixmap buffer */
if ( depth == 0 )
{
FT_Long size;
@@ -1274,7 +1275,8 @@
if ( size == 0 )
goto Exit; /* exit successfully! */
if ( FT_ALLOC( map->buffer, size ) )
error = ft_glyphslot_alloc_bitmap( slot, size );
if (error)
goto Exit;
}
@@ -1348,11 +1350,12 @@
elem_range,
ebdt_pos,
elem_offset,
map,
slot,
x_offset + comp->x_offset,
y_offset + comp->y_offset,
stream,
&elem_metrics );
&elem_metrics,
depth+1 );
if ( error )
goto Fail_Memory;
}
@@ -1409,7 +1412,6 @@
TT_SBit_MetricsRec *metrics )
{
FT_Error error;
FT_Memory memory = stream->memory;
FT_ULong ebdt_pos, glyph_offset;
TT_SBit_Strike strike;
@@ -1432,20 +1434,11 @@
ebdt_pos = FT_STREAM_POS();
/* clear the bitmap & load the bitmap */
if ( face->root.glyph->flags & FT_GLYPH_OWN_BITMAP )
FT_FREE( map->buffer );
map->rows = map->pitch = map->width = 0;
error = Load_SBit_Image( strike, range, ebdt_pos, glyph_offset,
map, 0, 0, stream, metrics );
face->root.glyph, 0, 0, stream, metrics, 0 );
if ( error )
goto Exit;
/* the glyph slot owns this bitmap buffer */
face->root.glyph->flags |= FT_GLYPH_OWN_BITMAP;
/* setup vertical metrics if needed */
if ( strike->flags & 1 )
{
+4 -4
View File
@@ -857,7 +857,7 @@
if ( y < min ) min = y;
if ( y > max ) max = y;
if ( TRUNC( min ) >= ras.max_ey || TRUNC( max ) < 0 )
if ( TRUNC( min ) >= ras.max_ey || TRUNC( max ) < ras.min_ey )
goto Draw;
gray_split_conic( arc );
@@ -1827,9 +1827,9 @@
gray_convert_glyph( RAS_ARG )
{
TBand bands[40];
volatile TBand* band;
volatile int n, num_bands;
volatile TPos min, max, max_y;
TBand* volatile band;
int volatile n, num_bands;
TPos volatile min, max, max_y;
FT_BBox* clip;
+25 -17
View File
@@ -190,32 +190,39 @@
FT_UInt horz_resolution,
FT_UInt vert_resolution )
{
FT_Size_Metrics* metrics = &size->root.metrics;
TT_Face face = (TT_Face)size->root.face;
FT_Size_Metrics* metrics = &size->root.metrics;
FT_Size_Metrics* metrics2 = &size->metrics;
TT_Face face = (TT_Face)size->root.face;
FT_Long dim_x, dim_y;
*metrics2 = *metrics;
/* This bit flag, when set, indicates that the pixel size must be */
/* truncated to an integer. Nearly all TrueType fonts have this */
/* bit set, as hinting won't work really well otherwise. */
/* */
/* However, for those rare fonts who do not set it, we override */
/* the default computations performed by the base layer. I */
/* really don't know whether this is useful, but hey, that's the */
/* spec :-) */
/* */
if ( ( face->header.Flags & 8 ) == 0 )
if ( ( face->header.Flags & 8 ) != 0 )
{
/* Compute pixel sizes in 26.6 units */
dim_x = ( char_width * horz_resolution + 36 ) / 72;
dim_y = ( char_height * vert_resolution + 36 ) / 72;
metrics->x_scale = FT_DivFix( dim_x, face->root.units_per_EM );
metrics->y_scale = FT_DivFix( dim_y, face->root.units_per_EM );
metrics->x_ppem = (FT_UShort)( dim_x >> 6 );
metrics->y_ppem = (FT_UShort)( dim_y >> 6 );
/* we need to use rounding in the following computations. Otherwise,
* the resulting hinted outlines will be very slightly distorted
*/
dim_x = ( ( char_width * horz_resolution + (36+32*72) ) / 72 ) & -64;
dim_y = ( ( char_height * vert_resolution + (36+32*72) ) / 72 ) & -64;
}
else
{
dim_x = ( ( char_width * horz_resolution + 36 ) / 72 );
dim_y = ( ( char_height * vert_resolution + 36 ) / 72 );
}
/* we only modify "metrics2", not "metrics", so these changes have */
/* no effect on the result of the auto-hinter when it is used */
/* */
metrics2->x_ppem = (FT_UShort)( dim_x >> 6 );
metrics2->y_ppem = (FT_UShort)( dim_y >> 6 );
metrics2->x_scale = FT_DivFix( dim_x, face->root.units_per_EM );
metrics2->y_scale = FT_DivFix( dim_y, face->root.units_per_EM );
size->ttmetrics.valid = FALSE;
#ifdef TT_CONFIG_OPTION_EMBEDDED_BITMAPS
@@ -256,6 +263,7 @@
/* many things have been pre-computed by the base layer */
size->metrics = size->root.metrics;
size->ttmetrics.valid = FALSE;
#ifdef TT_CONFIG_OPTION_EMBEDDED_BITMAPS
size->strike_index = 0xFFFF;
+68 -53
View File
@@ -58,6 +58,15 @@
#define UNSCALED_COMPONENT_OFFSET 0x1000
/* Maximum recursion depth we allow for composite glyphs.
* The TrueType spec doesn't say anything about recursion,
* so it isn't clear that recursion is allowed at all. But
* we'll be generous.
*/
#define TT_MAX_COMPOSITE_RECURSE 5
/*************************************************************************/
/* */
/* <Function> */
@@ -747,7 +756,8 @@
/* */
static FT_Error
load_truetype_glyph( TT_Loader loader,
FT_UInt glyph_index )
FT_UInt glyph_index,
FT_UInt recurse_count )
{
#ifdef TT_CONFIG_OPTION_BYTECODE_INTERPRETER
@@ -769,6 +779,11 @@
FT_Bool glyph_data_loaded = 0;
#endif
if ( recurse_count >= TT_MAX_COMPOSITE_RECURSE )
{
error = TT_Err_Invalid_Composite;
goto Exit;
}
/* check glyph index */
if ( glyph_index >= (FT_UInt)face->root.num_glyphs )
@@ -793,42 +808,33 @@
FT_Short left_bearing = 0;
FT_UShort advance_width = 0;
#ifdef FT_CONFIG_OPTION_INCREMENTAL
FT_Bool metrics_found = FALSE;
Get_HMetrics( face, glyph_index,
(FT_Bool)!( loader->load_flags &
FT_LOAD_IGNORE_GLOBAL_ADVANCE_WIDTH ),
&left_bearing,
&advance_width );
#ifdef FT_CONFIG_OPTION_INCREMENTAL
/* If this is an incrementally loaded font see if there are */
/* overriding metrics for this glyph. */
if ( face->root.internal->incremental_interface &&
face->root.internal->incremental_interface->funcs->get_glyph_metrics )
{
FT_Incremental_MetricsRec m;
FT_Incremental_MetricsRec metrics;
metrics.bearing_x = left_bearing;
metrics.bearing_y = 0;
metrics.advance = advance_width;
error = face->root.internal->incremental_interface->funcs->get_glyph_metrics(
face->root.internal->incremental_interface->object,
glyph_index, FALSE, &m, &metrics_found );
glyph_index, FALSE, &metrics );
if ( error )
goto Exit;
left_bearing = (FT_Short)m.bearing_x;
advance_width = (FT_UShort)m.advance;
left_bearing = (FT_Short)metrics.bearing_x;
advance_width = (FT_UShort)metrics.advance;
}
if ( !metrics_found )
Get_HMetrics( face, glyph_index,
(FT_Bool)!( loader->load_flags &
FT_LOAD_IGNORE_GLOBAL_ADVANCE_WIDTH ),
&left_bearing,
&advance_width );
#else
Get_HMetrics( face, glyph_index,
(FT_Bool)!( loader->load_flags &
FT_LOAD_IGNORE_GLOBAL_ADVANCE_WIDTH ),
&left_bearing,
&advance_width );
#endif /* FT_CONFIG_OPTION_INCREMENTAL */
loader->left_bearing = left_bearing;
@@ -985,7 +991,7 @@
/***********************************************************************/
/* otherwise, load a composite! */
else
else if ( contours_count == -1 )
{
TT_GlyphSlot glyph = (TT_GlyphSlot)loader->glyph;
FT_UInt start_point;
@@ -1059,7 +1065,8 @@
num_base_points = gloader->base.outline.n_points;
error = load_truetype_glyph( loader, subglyph->index );
error = load_truetype_glyph( loader, subglyph->index,
recurse_count+1 );
if ( error )
goto Fail;
@@ -1310,7 +1317,6 @@
exec->is_composite = TRUE;
exec->pedantic_hinting =
(FT_Bool)( loader->load_flags & FT_LOAD_PEDANTIC );
error = TT_Run_Context( exec, ((TT_Size)loader->size)->debug );
if ( error && exec->pedantic_hinting )
goto Fail;
@@ -1326,6 +1332,12 @@
}
/* end of composite loading */
}
else
{
/* invalid composite count ( negative but not -1 ) */
error = TT_Err_Invalid_Outline;
goto Fail;
}
/***********************************************************************/
/***********************************************************************/
@@ -1427,33 +1439,9 @@
FT_Pos left; /* scaled vertical left side bearing */
FT_Pos top; /* scaled vertical top side bearing */
FT_Pos advance; /* scaled vertical advance height */
FT_Bool metrics_found = FALSE;
#ifdef FT_CONFIG_OPTION_INCREMENTAL
/* If this is an incrementally loaded font see if there are */
/* overriding metrics for this glyph. */
if ( face->root.internal->incremental_interface &&
face->root.internal->incremental_interface->funcs->get_glyph_metrics )
{
FT_Incremental_MetricsRec m;
FT_Error error =
face->root.internal->incremental_interface->funcs->get_glyph_metrics(
face->root.internal->incremental_interface->object,
glyph_index, TRUE, &m, &metrics_found );
if ( error )
return error;
top_bearing = (FT_Short)m.bearing_y;
advance_height = (FT_UShort)m.advance;
}
#endif /* FT_CONFIG_OPTION_INCREMENTAL */
/* Get the unscaled top bearing and advance height. */
if ( !metrics_found && face->vertical_info &&
if ( face->vertical_info &&
face->vertical.number_Of_VMetrics > 0 )
{
/* Don't assume that both the vertical header and vertical */
@@ -1494,8 +1482,35 @@
}
}
#ifdef FT_CONFIG_OPTION_INCREMENTAL
/* If this is an incrementally loaded font see if there are */
/* overriding metrics for this glyph. */
if ( face->root.internal->incremental_interface &&
face->root.internal->incremental_interface->funcs->get_glyph_metrics )
{
FT_Incremental_MetricsRec metrics;
FT_Error error = 0;
metrics.bearing_x = 0;
metrics.bearing_y = top_bearing;
metrics.advance = advance_height;
error =
face->root.internal->incremental_interface->funcs->get_glyph_metrics(
face->root.internal->incremental_interface->object,
glyph_index, TRUE, &metrics );
if ( error )
return error;
top_bearing = (FT_Short)metrics.bearing_y;
advance_height = (FT_UShort)metrics.advance;
}
#endif /* FT_CONFIG_OPTION_INCREMENTAL */
/* We must adjust the top_bearing value from the bounding box given */
/* in the glyph header to te bounding box calculated with */
/* in the glyph header to the bounding box calculated with */
/* FT_Get_Outline_CBox(). */
/* scale the metrics */
@@ -1757,7 +1772,7 @@
glyph->format = FT_GLYPH_FORMAT_OUTLINE;
glyph->num_subglyphs = 0;
error = load_truetype_glyph( &loader, glyph_index );
error = load_truetype_glyph( &loader, glyph_index, 0 );
if ( !error )
compute_glyph_metrics( &loader, glyph_index );
+1 -1
View File
@@ -568,7 +568,7 @@
exec->FDefs = size->function_defs;
exec->IDefs = size->instruction_defs;
exec->tt_metrics = size->ttmetrics;
exec->metrics = size->root.metrics;
exec->metrics = size->metrics;
exec->maxFunc = size->max_func;
exec->maxIns = size->max_ins;
+18 -14
View File
@@ -70,14 +70,17 @@
{
FT_Memory memory = zone->memory;
if ( memory )
{
FT_FREE( zone->contours );
FT_FREE( zone->tags );
FT_FREE( zone->cur );
FT_FREE( zone->org );
FT_FREE( zone->contours );
FT_FREE( zone->tags );
FT_FREE( zone->cur );
FT_FREE( zone->org );
zone->max_points = zone->n_points = 0;
zone->max_contours = zone->n_contours = 0;
zone->max_points = zone->n_points = 0;
zone->max_contours = zone->n_contours = 0;
zone->memory = NULL;
}
}
@@ -541,7 +544,7 @@
face = (TT_Face)size->root.face;
metrics = &size->root.metrics;
metrics = &size->metrics;
if ( metrics->x_ppem < 1 || metrics->y_ppem < 1 )
return TT_Err_Invalid_PPem;
@@ -568,14 +571,15 @@
/* Compute root ascender, descender, test height, and max_advance */
metrics->ascender = ( FT_MulFix( face->root.ascender,
metrics->y_scale ) + 63 ) & -64;
metrics->y_scale ) + 32 ) & -64;
metrics->descender = ( FT_MulFix( face->root.descender,
metrics->y_scale ) + 0 ) & -64;
metrics->y_scale ) + 32 ) & -64;
metrics->height = ( FT_MulFix( face->root.height,
metrics->y_scale ) + 63 ) & -64;
metrics->y_scale ) + 32 ) & -64;
metrics->max_advance = ( FT_MulFix( face->root.max_advance_width,
metrics->x_scale ) + 32 ) & -64;
#ifdef TT_CONFIG_OPTION_EMBEDDED_BITMAPS
/* set to `invalid' by default */
size->strike_index = 0xFFFFU;
@@ -690,7 +694,7 @@
SFNT_Service sfnt;
metrics = &size->root.metrics;
metrics = &size->metrics;
if ( size->strike_index != 0xFFFFU )
return TT_Err_Ok;
@@ -728,8 +732,8 @@
sbit_metrics->descender;
/* XXX: Is this correct? */
sbit_metrics->max_advance = ( strike->hori.min_origin_SB +
strike->hori.max_width +
sbit_metrics->max_advance = ( strike->hori.min_origin_SB +
strike->hori.max_width +
strike->hori.min_advance_SB ) << 6;
size->strike_index = strike_index;
+1
View File
@@ -311,6 +311,7 @@ FT_BEGIN_HEADER
{
FT_SizeRec root;
FT_Size_Metrics metrics; /* slightly different from the root metrics */
TT_Size_Metrics ttmetrics;
#ifdef TT_CONFIG_OPTION_EMBEDDED_BITMAPS
+11 -13
View File
@@ -76,7 +76,7 @@
glyph_index, char_string );
else
#endif
#endif /* FT_CONFIG_OPTION_INCREMENTAL */
/* For ordinary fonts get the character data stored in the face record. */
{
@@ -95,23 +95,21 @@
if ( !error && face->root.internal->incremental_interface &&
face->root.internal->incremental_interface->funcs->get_glyph_metrics )
{
FT_Bool found = FALSE;
FT_Incremental_MetricsRec metrics;
metrics.bearing_x = decoder->builder.left_bearing.x;
metrics.bearing_y = decoder->builder.left_bearing.y;
metrics.advance = decoder->builder.advance.x;
error = face->root.internal->incremental_interface->funcs->get_glyph_metrics(
face->root.internal->incremental_interface->object,
glyph_index, FALSE, &metrics, &found );
if ( found )
{
decoder->builder.left_bearing.x = metrics.bearing_x;
decoder->builder.left_bearing.y = metrics.bearing_y;
decoder->builder.advance.x = metrics.advance;
decoder->builder.advance.y = 0;
}
glyph_index, FALSE, &metrics );
decoder->builder.left_bearing.x = metrics.bearing_x;
decoder->builder.left_bearing.y = metrics.bearing_y;
decoder->builder.advance.x = metrics.advance;
decoder->builder.advance.y = 0;
}
#endif
#endif /* FT_CONFIG_OPTION_INCREMENTAL */
return error;
}
@@ -137,7 +135,7 @@
face->root.internal->incremental_interface->object,
&glyph_data );
}
#endif
#endif /* FT_CONFIG_OPTION_INCREMENTAL */
return error;
}
+30 -14
View File
@@ -779,17 +779,25 @@
static int
is_alpha( FT_Byte c )
is_name_char( FT_Byte c )
{
/* Note: we must accept "+" as a valid character, as it is used in */
/* embedded type1 fonts in PDF documents. */
/* */
return ( ft_isalnum( c ) ||
c == '.' ||
c == '_' ||
c == '-' ||
c == '+' );
}
/* Note: PostScript allows any non-delimiting, non-whitespace */
/* in a name (PS Ref Manual, 3rd Ed, p31) */
/* PostScript delimiters include (,),<,>,[,],{,},/ and % */
return ( c != '(' &&
c != ')' &&
c != '<' &&
c != '>' &&
c != '[' &&
c != ']' &&
c != '{' &&
c != '}' &&
c != '/' &&
c != '%' &&
! is_space( c )
);
}
static int
@@ -861,7 +869,7 @@
cur++;
cur2 = cur;
while ( cur2 < limit && is_alpha( *cur2 ) )
while ( cur2 < limit && is_name_char( *cur2 ) )
cur2++;
len = cur2 - cur;
@@ -1070,7 +1078,7 @@
FT_PtrDist len;
while ( cur2 < limit && is_alpha( *cur2 ) )
while ( cur2 < limit && is_name_char( *cur2 ) )
cur2++;
len = cur2 - cur - 1;
@@ -1133,6 +1141,14 @@
/* with synthetic fonts, it's possible we get here twice */
return;
if ( parser->root.cursor + 2 > parser->root.limit &&
parser->root.cursor[0] == '[' &&
parser->root.cursor[1] == ']' )
{
/* empty array */
return;
}
loader->num_subrs = (FT_Int)T1_ToInt( parser );
if ( parser->root.error )
return;
@@ -1304,7 +1320,7 @@
FT_PtrDist len;
while ( cur2 < limit && is_alpha( *cur2 ) )
while ( cur2 < limit && is_name_char( *cur2 ) )
cur2++;
len = cur2 - cur - 1;
@@ -1564,7 +1580,7 @@
cur++;
cur2 = cur;
while ( cur2 < limit && is_alpha( *cur2 ) )
while ( cur2 < limit && is_name_char( *cur2 ) )
cur2++;
len = cur2 - cur;
+3 -10
View File
@@ -560,17 +560,10 @@
static void
ft_glyphslot_clear( FT_GlyphSlot slot )
t42_glyphslot_clear( FT_GlyphSlot slot )
{
/* free bitmap if needed */
if ( slot->flags & FT_GLYPH_OWN_BITMAP )
{
FT_Memory memory = FT_FACE_MEMORY( slot->face );
FT_FREE( slot->bitmap.buffer );
slot->flags &= ~FT_GLYPH_OWN_BITMAP;
}
ft_glyphslot_free_bitmap( slot );
/* clear all public fields in the glyph slot */
FT_ZERO( &slot->metrics );
@@ -603,7 +596,7 @@
FT_Driver_Class ttclazz = ((T42_Driver)glyph->face->driver)->ttclazz;
ft_glyphslot_clear( t42slot->ttslot );
t42_glyphslot_clear( t42slot->ttslot );
error = ttclazz->load_glyph( t42slot->ttslot,
t42size->ttsize,
glyph_index,
+21 -23
View File
@@ -17,6 +17,7 @@
#include <ft2build.h>
#include FT_WINFONTS_H
#include FT_INTERNAL_DEBUG_H
#include FT_INTERNAL_STREAM_H
#include FT_INTERNAL_OBJECTS_H
@@ -68,9 +69,9 @@
const FT_Frame_Field winfnt_header_fields[] =
{
#undef FT_STRUCTURE
#define FT_STRUCTURE WinFNT_HeaderRec
#define FT_STRUCTURE FT_WinFNT_HeaderRec
FT_FRAME_START( 134 ),
FT_FRAME_START( 146 ),
FT_FRAME_USHORT_LE( version ),
FT_FRAME_ULONG_LE ( file_size ),
FT_FRAME_BYTES ( copyright, 60 ),
@@ -106,7 +107,7 @@
FT_FRAME_USHORT_LE( B_space ),
FT_FRAME_USHORT_LE( C_space ),
FT_FRAME_USHORT_LE( color_table_offset ),
FT_FRAME_BYTES ( reserved, 4 ),
FT_FRAME_BYTES ( reserved1, 16 ),
FT_FRAME_END
};
@@ -127,8 +128,8 @@
fnt_font_load( FNT_Font font,
FT_Stream stream )
{
FT_Error error;
WinFNT_Header header = &font->header;
FT_Error error;
FT_WinFNT_Header header = &font->header;
/* first of all, read the FNT header */
@@ -145,6 +146,17 @@
goto Exit;
}
/* Version 2 doesn't have these fields */
if ( header->version == 0x200 )
{
header->flags = 0;
header->A_space = 0;
header->B_space = 0;
header->C_space = 0;
header->color_table_offset = 0;
}
if ( header->file_type & 1 )
{
FT_TRACE2(( "[can't handle vector FNT fonts]\n" ));
@@ -592,7 +604,7 @@
len = new_format ? 6 : 4;
/* jump to glyph entry */
p = font->fnt_frame + 118 + len * glyph_index;
p = font->fnt_frame + ( new_format ? 146 : 118 ) + len * glyph_index;
bitmap->width = FT_NEXT_SHORT_LE( p );
@@ -606,32 +618,18 @@
/* allocate and build bitmap */
{
FT_Memory memory = FT_FACE_MEMORY( slot->face );
FT_Int pitch = ( bitmap->width + 7 ) >> 3;
FT_Byte* column;
FT_Byte* write;
bitmap->pitch = pitch;
bitmap->rows = font->header.pixel_height;
bitmap->pixel_mode = FT_PIXEL_MODE_MONO;
if ( FT_ALLOC( bitmap->buffer, pitch * bitmap->rows ) )
goto Exit;
column = (FT_Byte*)bitmap->buffer;
for ( ; pitch > 0; pitch--, column++ )
{
FT_Byte* limit = p + bitmap->rows;
for ( write = column; p < limit; p++, write += bitmap->pitch )
write[0] = p[0];
}
/* note: we don't allocate a new buffer for the bitmap since we */
/* already store the images in the FT_Face */
ft_glyphslot_set_bitmap( slot, p );
}
slot->flags = FT_GLYPH_OWN_BITMAP;
slot->bitmap_left = 0;
slot->bitmap_top = font->header.ascent;
slot->format = FT_GLYPH_FORMAT_BITMAP;