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

View File

@ -120,4 +120,4 @@ Legal Terms
Packages, you indicate that you understand and accept all the
terms of this license.
--- end of license.txt ---
--- end of license.txt ---

View File

@ -20,4 +20,4 @@ UseFreeTypeHeaders ;
FT2_Library $(FT2_LIB) : $(_sources).c ;
}
# end of src/autohint Jamfile
# end of src/autohint Jamfile

View File

@ -144,4 +144,4 @@
return delta;
}
/* END */
/* END */

View File

@ -61,4 +61,4 @@ FT_END_HEADER
#endif /* __AHANGLES_H__ */
/* END */
/* END */

View File

@ -37,4 +37,4 @@
#endif /* __AHERRORS_H__ */
/* END */
/* END */

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;
@ -393,4 +395,4 @@
}
/* END */
/* END */

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 */
@ -47,4 +53,4 @@ FT_END_HEADER
#endif /* __AHGLOBAL_H__ */
/* END */
/* END */

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++ )
{
@ -1579,4 +1592,4 @@
}
/* END */
/* END */

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 )
@ -90,4 +92,4 @@ FT_END_HEADER
#endif /* __AHGLYPH_H__ */
/* END */
/* END */

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,123 @@
dist = globals->stds[vertical];
if ( dist < 48 )
dist = 48;
goto Done_Width;
goto Done_Width;
}
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;
}
}
}
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 )
@ -205,9 +325,6 @@
dist = ( dist + 32 ) & -64;
}
}
Done_Width:
}
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 ;
@ -1663,4 +1783,4 @@
}
/* END */
/* END */

View File

@ -72,4 +72,4 @@ FT_END_HEADER
#endif /* __AHHINT_H__ */
/* END */
/* END */

View File

@ -58,4 +58,4 @@ FT_END_HEADER
#endif /* __AHLOADER_H__ */
/* END */
/* END */

View File

@ -134,4 +134,4 @@
};
/* END */
/* END */

View File

@ -39,4 +39,4 @@ FT_END_HEADER
#endif /* __AHMODULE_H__ */
/* END */
/* END */

View File

@ -879,4 +879,4 @@
}
/* END */
/* END */

View File

@ -134,4 +134,4 @@ FT_END_HEADER
#endif /* __AHOPTIM_H__ */
/* END */
/* END */

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;
@ -516,4 +530,4 @@ FT_END_HEADER
#endif /* __AHTYPES_H__ */
/* END */
/* END */

View File

@ -29,4 +29,4 @@
#include "ahmodule.c"
/* END */
/* END */

View File

@ -22,4 +22,4 @@ OBJS=autohint.obj
all : $(OBJS)
library [--.lib]freetype.olb $(OBJS)
# EOF
# EOF

View File

@ -75,4 +75,4 @@ print_arctan( 8 )
print
# END
# END

View File

@ -22,4 +22,4 @@ add_autohint_module:
$(OPEN_DRIVER)autohint_module_class$(CLOSE_DRIVER)
$(ECHO_DRIVER)autohint $(ECHO_DRIVER_DESC)automatic hinting module$(ECHO_DRIVER_DONE)
# EOF
# EOF

View File

@ -75,4 +75,4 @@ DRV_OBJS_S += $(AUTO_DRV_OBJ_S)
DRV_OBJS_M += $(AUTO_DRV_OBJ_M)
# EOF
# EOF

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.
#
@ -33,4 +35,4 @@ if $(MAC)
FT2_Library $(FT2_LIB) : ftmac.c ;
}
# end of src/base Jamfile
# end of src/base Jamfile

View File

@ -15,9 +15,9 @@
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)
# EOF
# EOF

View File

@ -118,4 +118,4 @@
}
/* END */
/* END */

View File

@ -31,4 +31,4 @@
#include "ftnames.c"
/* END */
/* END */

View File

@ -650,4 +650,4 @@
}
/* END */
/* END */

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,
@ -29,35 +45,52 @@
FT_Error error;
const char* encoding = NULL;
const char* registry = NULL;
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 )
*acharset_encoding = encoding;
if ( acharset_registry )
*acharset_registry = registry;
return error;
}
}
/* END */
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 */

View File

@ -558,4 +558,4 @@
}
/* END */
/* END */

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;
}
}
@ -669,4 +715,4 @@
#endif /* !FT_DEBUG_MEMORY */
/* END */
/* END */

View File

@ -194,4 +194,4 @@
#endif /* !FT_DEBUG_LEVEL_TRACE */
/* END */
/* END */

View File

@ -358,4 +358,4 @@
}
/* END */
/* END */

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;
@ -681,4 +681,4 @@
}
/* END */
/* END */

View File

@ -243,4 +243,4 @@
}
Exit:
return error;
}
}

View File

@ -158,4 +158,4 @@
}
/* END */
/* END */

View File

@ -214,4 +214,4 @@
}
/* END */
/* END */

View File

@ -916,4 +916,4 @@
}
/* END */
/* END */

View File

@ -123,4 +123,4 @@
}
/* END */
/* END */

View File

@ -91,4 +91,4 @@
#endif /* TT_CONFIG_OPTION_SFNT_NAMES */
/* END */
/* END */

View File

@ -393,4 +393,4 @@
}
return error;
}
}

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,19 +198,59 @@
return error;
}
FT_BASE_DEF( void )
ft_glyphslot_free_bitmap( FT_GlyphSlot slot )
{
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;
}
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 */
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 );
@ -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 )
{
@ -2519,4 +2664,4 @@
}
/* END */
/* END */

View File

@ -655,4 +655,4 @@
}
/* END */
/* END */

View File

@ -102,4 +102,4 @@
return error;
}
/* END */
/* END */

View File

@ -800,4 +800,4 @@
}
/* END */
/* END */

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

View File

@ -283,4 +283,4 @@
}
/* END */
/* END */

View File

@ -128,4 +128,4 @@
ft_object_create( clazz, pathname, FT_OBJECT_P(astream) );
}

View File

@ -27,4 +27,4 @@
};
FT_APIVAR_DEF( const FT_Memory_Funcs )
ft_memory_funcs_default = &ft_memory_funcs_defaults_rec;
ft_memory_funcs_default = &ft_memory_funcs_defaults_rec;

View File

@ -300,4 +300,4 @@
}
/* END */
/* END */

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;
@ -482,4 +484,4 @@
}
/* END */
/* END */

View File

@ -84,4 +84,4 @@
}
/* END */
/* END */

View File

@ -327,4 +327,4 @@
}
/* END */
/* END */

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

View File

@ -77,4 +77,4 @@
}
/* END */
/* END */

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
@ -89,4 +91,4 @@ $(BASE_OBJ_S): $(BASE_SRC_S) $(BASE_SRC) $(FREETYPE_H)
$(OBJ_)%.$O: $(BASE_)%.c $(FREETYPE_H)
$(BASE_COMPILE) $T$@ $<
# EOF
# EOF

View File

@ -20,4 +20,4 @@ UseFreeTypeHeaders ;
FT2_Library $(FT2_LIB) : $(_sources).c ;
}
# end of src/bdf Jamfile
# end of src/bdf Jamfile

View File

@ -145,4 +145,4 @@ Credits
This driver is based on excellent Mark Leisher's bdf library. If you
find something good in this driver you should probably thank him, not
me.
me.

View File

@ -31,4 +31,4 @@ THE SOFTWARE.
#include "bdfdrivr.c"
/* END */
/* END */

View File

@ -292,4 +292,4 @@ FT_END_HEADER
#endif /* __BDF_H__ */
/* END */
/* END */

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 ),
@ -671,4 +722,4 @@ THE SOFTWARE.
};
/* END */
/* END */

View File

@ -71,4 +71,4 @@ FT_END_HEADER
#endif /* __BDFDRIVR_H__ */
/* END */
/* END */

View File

@ -41,4 +41,4 @@
#endif /* __BDFERROR_H__ */
/* END */
/* END */

View File

@ -2433,4 +2433,4 @@
}
/* END */
/* END */

View File

@ -20,4 +20,4 @@ OBJS=bdf.obj
all : $(OBJS)
library [--.lib]freetype.olb $(OBJS)
# EOF
# EOF

View File

@ -28,4 +28,4 @@ make_module_list: add_bdf_driver
add_bdf_driver:
$(OPEN_DRIVER)bdf_driver_class$(CLOSE_DRIVER)
$(ECHO_DRIVER)bdf $(ECHO_DRIVER_DESC)bdf bitmap fonts$(ECHO_DRIVER_DONE)

View File

@ -76,4 +76,4 @@ $(OBJ_)%.$O: $(BDF_DIR_)%.c $(FREETYPE_H) $(BDF_DRV_H)
DRV_OBJS_S += $(BDF_DRV_OBJ_S)
DRV_OBJS_M += $(BDF_DRV_OBJ_M)
# EOF
# EOF

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 ;
@ -26,4 +26,4 @@ UseFreeTypeHeaders ;
FT2_Library $(FT2_LIB) : $(_sources).c ;
}
# end of src/cache Jamfile
# end of src/cache Jamfile

View File

@ -23,4 +23,4 @@ all : $(OBJS)
ftcache.obj : ftcache.c ftlru.c ftcmanag.c ftccache.c ftcglyph.c ftcimage.c \
ftcsbits.c ftccmap.c
# EOF
# EOF

View File

@ -28,4 +28,4 @@
#include "ftccmap.c"
/* END */
/* END */

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;
}
}
}
}
@ -711,4 +804,4 @@
}
/* END */
/* END */

View File

@ -154,4 +154,4 @@
#undef GEN_CACHE_LOOKUP
/* END */
/* END */

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 */
@ -131,7 +135,7 @@
ftc_cmap_node_weight( FTC_CMapNode cnode )
{
FT_UNUSED( cnode );
return sizeof ( *cnode );
}
@ -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;
}
@ -408,4 +456,4 @@
}
/* END */
/* END */

View File

@ -37,4 +37,4 @@
#endif /* __FTCERROR_H__ */
/* END */
/* END */

View File

@ -112,4 +112,4 @@
}
/* END */
/* END */

View File

@ -396,4 +396,4 @@
}
/* END */
/* END */

View File

@ -762,4 +762,4 @@
}
/* END */
/* END */

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;
@ -554,4 +554,4 @@
}
/* END */
/* END */

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. */
/* */
/* first, check if our list if full, when appropriate */
if ( list->max_nodes > 0 && list->num_nodes >= list->max_nodes )
/* 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
*
*/
{
/* 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;
}
FT_ASSERT( node != NULL );
if ( !error )
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 )
@ -335,4 +391,4 @@
}
/* END */
/* END */

View File

@ -77,4 +77,4 @@ DRV_OBJS_S += $(Cache_DRV_OBJ_S)
DRV_OBJS_M += $(Cache_DRV_OBJ_M)
# EOF
# EOF

View File

@ -20,4 +20,4 @@ UseFreeTypeHeaders ;
FT2_Library $(FT2_LIB) : $(_sources).c ;
}
# end of src/cff Jamfile
# end of src/cff Jamfile

View File

@ -26,4 +26,4 @@
#include "cffgload.c"
#include "cffcmap.c"
/* END */
/* END */

View File

@ -323,4 +323,4 @@
};
/* END */
/* END */

View File

@ -85,4 +85,4 @@ FT_END_HEADER
#endif /* __CFFCMAP_H__ */
/* END */
/* END */

View File

@ -417,4 +417,4 @@
};
/* END */
/* END */

View File

@ -36,4 +36,4 @@ FT_END_HEADER
#endif /* __CFFDRIVER_H__ */
/* END */
/* END */

View File

@ -38,4 +38,4 @@
#endif /* __CFFERRS_H__ */
/* END */
/* END */

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;
@ -2478,4 +2501,4 @@
}
/* END */
/* END */

View File

@ -211,4 +211,4 @@ FT_END_HEADER
#endif /* __CFFGLOAD_H__ */
/* END */
/* END */

View File

@ -1538,10 +1538,10 @@
{
if ( FT_FRAME_ENTER( ( num_glyphs - 1 ) * 2 ) )
goto Exit;
for ( j = 1; j < num_glyphs; j++ )
charset->sids[j] = FT_GET_USHORT();
FT_FRAME_EXIT();
}
break;
@ -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,26 +1743,29 @@
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;
p = (FT_Byte*)stream->cursor;
for ( j = 1; j <= count; j++ )
{
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;
@ -1772,7 +1774,7 @@
encoding->sids[glyph_code] = charset->sids[j];
}
}
FT_FRAME_EXIT();
}
break;
@ -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;
@ -2244,4 +2264,4 @@
}
/* END */
/* END */

View File

@ -71,4 +71,4 @@ FT_END_HEADER
#endif /* __CFFLOAD_H__ */
/* END */
/* END */

View File

@ -572,4 +572,4 @@
}
/* END */
/* END */

View File

@ -157,4 +157,4 @@ FT_END_HEADER
#endif /* __CFFOBJS_H__ */
/* END */
/* END */

View File

@ -678,4 +678,4 @@
}
/* END */
/* END */

View File

@ -66,4 +66,4 @@ FT_END_HEADER
#endif /* __CFF_PARSE_H__ */
/* END */
/* END */

View File

@ -94,4 +94,4 @@
CFF_FIELD_NUM ( 21, nominal_width )
/* END */
/* END */

View File

@ -20,4 +20,4 @@ OBJS=cff.obj
all : $(OBJS)
library [--.lib]freetype.olb $(OBJS)
# EOF
# EOF

View File

@ -19,4 +19,4 @@ add_cff_driver:
$(OPEN_DRIVER)cff_driver_class$(CLOSE_DRIVER)
$(ECHO_DRIVER)cff $(ECHO_DRIVER_DESC)OpenType fonts with extension *.otf$(ECHO_DRIVER_DONE)
# EOF
# EOF

View File

@ -68,4 +68,4 @@ $(OBJ_)%.$O: $(CFF_DIR_)%.c $(FREETYPE_H) $(CFF_DRV_H)
DRV_OBJS_S += $(CFF_DRV_OBJ_S)
DRV_OBJS_M += $(CFF_DRV_OBJ_M)
# EOF
# EOF

View File

@ -20,4 +20,4 @@ UseFreeTypeHeaders ;
FT2_Library $(FT2_LIB) : $(_sources).c ;
}
# end of src/cid Jamfile
# end of src/cid Jamfile

View File

@ -37,4 +37,4 @@
#endif /* __CIDERRS_H__ */
/* END */
/* END */

Some files were not shown because too many files have changed in this diff Show More