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", "THEZOCQS",
"HEZLOCUS", "HEZLOCUS",
#ifdef FT_CONFIG_CHESTER_SMALL_F
"fijkdbh", "fijkdbh",
#endif
"xzroesc", "xzroesc",
"xzroesc", "xzroesc",
"pqgjy" "pqgjy"
@@ -321,7 +323,7 @@
if ( error ) if ( error )
goto Exit; goto Exit;
error = ah_outline_load( hinter->glyph, hinter->face ); error = ah_outline_load( hinter->glyph, 0x10000L, 0x10000L, hinter->face );
if ( error ) if ( error )
goto Exit; goto Exit;
+9 -3
View File
@@ -32,9 +32,15 @@
FT_BEGIN_HEADER FT_BEGIN_HEADER
#define AH_IS_TOP_BLUE( b ) ( (b) == AH_BLUE_CAPITAL_TOP || \ #ifdef FT_CONFIG_CHESTER_SMALL_F
(b) == AH_BLUE_SMALL_TOP || \
(b) == AH_BLUE_SMALL_F_TOP ) # 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 */ /* compute global metrics automatically */
+17 -4
View File
@@ -389,6 +389,8 @@
/* */ /* */
FT_LOCAL_DEF( FT_Error ) FT_LOCAL_DEF( FT_Error )
ah_outline_load( AH_Outline outline, ah_outline_load( AH_Outline outline,
FT_Fixed x_scale,
FT_Fixed y_scale,
FT_Face face ) FT_Face face )
{ {
FT_Memory memory = outline->memory; FT_Memory memory = outline->memory;
@@ -461,8 +463,8 @@
outline->horz_major_dir = AH_DIR_RIGHT; outline->horz_major_dir = AH_DIR_RIGHT;
} }
outline->x_scale = face->size->metrics.x_scale; outline->x_scale = x_scale;
outline->y_scale = face->size->metrics.y_scale; outline->y_scale = y_scale;
points = outline->points; points = outline->points;
if ( outline->num_points == 0 ) if ( outline->num_points == 0 )
@@ -478,8 +480,6 @@
/* compute coordinates */ /* compute coordinates */
{ {
FT_Vector* vec = source->points; 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++ ) for ( point = points; point < point_limit; vec++, point++ )
@@ -1350,6 +1350,7 @@
else else
edge2 = seg2->edge; edge2 = seg2->edge;
#ifdef FT_CONFIG_CHESTER_SERIF
if ( is_serif ) if ( is_serif )
{ {
edge->serif = edge2; edge->serif = edge2;
@@ -1357,6 +1358,12 @@
} }
else else
edge->link = edge2; edge->link = edge2;
#else /* !CHESTER_SERIF */
if ( is_serif )
edge->serif = edge2;
else
edge->link = edge2;
#endif
} }
seg = seg->edge_next; seg = seg->edge_next;
@@ -1480,8 +1487,14 @@
/* compute the initial threshold as a fraction of the EM size */ /* compute the initial threshold as a fraction of the EM size */
best_dist = FT_MulFix( face_globals->face->units_per_EM / 40, y_scale ); best_dist = FT_MulFix( face_globals->face->units_per_EM / 40, y_scale );
#ifdef FT_CONFIG_CHESTER_SMALL_F
if ( best_dist > 64 / 2 ) if ( best_dist > 64 / 2 )
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++ ) 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 ) FT_LOCAL( FT_Error )
ah_outline_load( AH_Outline outline, ah_outline_load( AH_Outline outline,
FT_Fixed x_scale,
FT_Fixed y_scale,
FT_Face face ); FT_Face face );
FT_LOCAL( void ) FT_LOCAL( void )
+236 -116
View File
@@ -28,9 +28,7 @@
#define FACE_GLOBALS( face ) ((AH_Face_Globals)(face)->autohint.data) #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 AH_USE_IUP
#define OPTIM_STEM_SNAP #define OPTIM_STEM_SNAP
@@ -90,6 +88,7 @@
/* compute the snapped width of a given stem */ /* compute the snapped width of a given stem */
#ifdef FT_CONFIG_CHESTER_SERIF
static FT_Pos static FT_Pos
ah_compute_stem_width( AH_Hinter hinter, ah_compute_stem_width( AH_Hinter hinter,
int vertical, int vertical,
@@ -108,21 +107,26 @@
sign = 1; sign = 1;
} }
if ( ( vertical && !hinter->do_vert_snapping ) || if ( !hinter->do_stem_adjust )
{
/* leave stem widths unchanged */
}
else if ( ( vertical && !hinter->do_vert_snapping ) ||
( !vertical && !hinter->do_horz_snapping ) ) ( !vertical && !hinter->do_horz_snapping ) )
{ {
/* smooth hinting process, very lightly quantize the stem width */
/* */
/* leave the widths of serifs alone */ /* leave the widths of serifs alone */
if ( ( stem_flags & AH_EDGE_SERIF ) && vertical && ( dist < 3 * 64 ) ) if ( ( stem_flags & AH_EDGE_SERIF ) && vertical && ( dist < 3 * 64 ) )
goto Done_Width; goto Done_Width;
else if ( ( base_flags & AH_EDGE_ROUND ) )
else if ( ( base_flags & AH_EDGE_ROUND ) ) { {
if ( dist < 80 )
if ( dist < 96 )
dist = 64; dist = 64;
} }
else if ( dist < 56 ) else if ( dist < 56 )
dist = 56; dist = 56;
@@ -138,6 +142,7 @@
dist = globals->stds[vertical]; dist = globals->stds[vertical];
if ( dist < 48 ) if ( dist < 48 )
dist = 48; dist = 48;
goto Done_Width; goto Done_Width;
} }
@@ -205,9 +210,121 @@
dist = ( dist + 32 ) & -64; 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 ) if ( sign )
@@ -215,6 +332,7 @@
return dist; return dist;
} }
#endif /* !CHESTER_SERIF */
/* align one stem edge relative to the previous stem edge */ /* align one stem edge relative to the previous stem edge */
@@ -226,6 +344,7 @@
{ {
FT_Pos dist = stem_edge->opos - base_edge->opos; FT_Pos dist = stem_edge->opos - base_edge->opos;
#ifdef FT_CONFIG_CHESTER_SERIF
FT_Pos fitted_width = ah_compute_stem_width( hinter, FT_Pos fitted_width = ah_compute_stem_width( hinter,
vertical, vertical,
dist, dist,
@@ -233,6 +352,10 @@
stem_edge->flags ); stem_edge->flags );
stem_edge->pos = base_edge->pos + fitted_width; 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_Pos sign = 1;
FT_UNUSED( hinter ); FT_UNUSED( hinter );
FT_UNUSED( vertical );
dist = serif->opos - base->opos; dist = serif->opos - base->opos;
if ( dist < 0 ) if ( dist < 0 )
@@ -386,8 +509,9 @@
if ( !anchor ) if ( !anchor )
{ {
#ifdef FT_CONFIG_CHESTER_STEM
FT_Pos org_len, org_center, cur_len; 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; org_len = edge2->opos - edge->opos;
cur_len = ah_compute_stem_width( hinter, dimension, org_len, cur_len = ah_compute_stem_width( hinter, dimension, org_len,
@@ -401,16 +525,21 @@
d_off = 26; d_off = 26;
} }
if ( cur_len < 96 ) { if ( cur_len < 96 )
{
org_center = edge->opos + ( org_len >> 1 ); org_center = edge->opos + ( org_len >> 1 );
cur_pos1 = ( org_center + 32 ) & -64; cur_pos1 = ( org_center + 32 ) & -64;
delta1 = ABSVAL( org_center - ( cur_pos1 - u_off ) ) - error1 = org_center - ( cur_pos1 - u_off );
ABSVAL( ( org_center - ( cur_pos1 + d_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; cur_pos1 -= u_off;
else else
cur_pos1 += d_off; cur_pos1 += d_off;
@@ -427,25 +556,40 @@
edge->flags |= AH_EDGE_DONE; edge->flags |= AH_EDGE_DONE;
ah_align_linked_edge( hinter, edge, edge2, dimension ); 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 else
{ {
FT_Pos org_pos, org_len, org_center, cur_len; 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_pos = anchor->pos + (edge->opos - anchor->opos);
org_len = edge2->opos - edge->opos; org_len = edge2->opos - edge->opos;
org_center = org_pos + ( org_len >> 1 ); org_center = org_pos + ( org_len >> 1 );
#ifdef FT_CONFIG_CHESTER_SERIF
cur_len = ah_compute_stem_width( hinter, dimension, org_len, cur_len = ah_compute_stem_width( hinter, dimension, org_len,
edge->flags, edge2->flags ); 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 ) 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 ) if (cur_len <= 64 )
u_off = d_off = 32; u_off = d_off = 32;
else else
@@ -454,24 +598,22 @@
d_off = 26; d_off = 26;
} }
delta1 = ABSVAL( org_center - ( cur_pos1 - u_off ) ) - delta1 = org_center - (cur_pos1 - u_off);
ABSVAL( ( org_center - ( cur_pos1 + d_off ) ) );
if ( delta1 < 0 ) if ( delta1 < 0 )
delta1 = -delta1;
delta2 = org_center - (cur_pos1 + d_off);
if ( delta2 < 0 )
delta2 = -delta2;
if ( delta1 < delta2 )
cur_pos1 -= u_off; cur_pos1 -= u_off;
else else
cur_pos1 += d_off; cur_pos1 += d_off;
edge->pos = cur_pos1 - cur_len / 2; edge->pos = cur_pos1 - cur_len / 2;
edge2->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 else
{ {
@@ -479,7 +621,8 @@
org_len = edge2->opos - edge->opos; org_len = edge2->opos - edge->opos;
org_center = org_pos + ( org_len >> 1 ); 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; cur_pos1 = ( org_pos + 32 ) & -64;
delta1 = ( cur_pos1 + ( cur_len >> 1 ) - org_center ); delta1 = ( cur_pos1 + ( cur_len >> 1 ) - org_center );
@@ -493,6 +636,24 @@
edge->pos = ( delta1 < delta2 ) ? cur_pos1 : cur_pos2; edge->pos = ( delta1 < delta2 ) ? cur_pos1 : cur_pos2;
edge2->pos = edge->pos + cur_len; edge2->pos = edge->pos + cur_len;
}
#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; edge->flags |= AH_EDGE_DONE;
edge2->flags |= AH_EDGE_DONE; edge2->flags |= AH_EDGE_DONE;
@@ -501,7 +662,6 @@
edge->pos = edge[-1].pos; edge->pos = edge[-1].pos;
} }
} }
}
if ( !has_serifs ) if ( !has_serifs )
goto Next_Dimension; goto Next_Dimension;
@@ -1150,71 +1310,12 @@
FT_Face face = hinter->face; FT_Face face = hinter->face;
FT_GlyphSlot slot = face->glyph; FT_GlyphSlot slot = face->glyph;
FT_Slot_Internal internal = slot->internal; FT_Slot_Internal internal = slot->internal;
FT_Fixed x_scale = face->size->metrics.x_scale; FT_Fixed x_scale = hinter->globals->x_scale;
FT_Fixed y_scale = face->size->metrics.y_scale; FT_Fixed y_scale = hinter->globals->y_scale;
FT_Error error; FT_Error error;
AH_Outline outline = hinter->glyph; AH_Outline outline = hinter->glyph;
AH_Loader gloader = hinter->loader; 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 */ /* load the glyph */
error = FT_Load_Glyph( face, glyph_index, load_flags ); 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 */ /* now, load the slot image into the auto-outline, and run the */
/* automatic hinting process */ /* 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 ) if ( error )
goto Exit; goto Exit;
@@ -1318,26 +1419,20 @@
AH_Edge edge2 = edge1 + AH_Edge edge2 = edge1 +
outline->num_vedges - 1; /* rightmost edge */ 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_advance = hinter->pp2.x;
old_rsb = old_advance - edge2->opos; old_rsb = old_advance - edge2->opos;
old_lsb = edge1->opos; old_lsb = edge1->opos;
new_lsb = edge1->pos; new_lsb = edge1->pos;
if ( hinter->do_horz_hints ) hinter->pp1.x = ( ( new_lsb - old_lsb ) + 32 ) & -64;
{ hinter->pp2.x = ( ( edge2->pos + old_rsb ) + 32 ) & -64;
hinter->pp1.x = ( ( new_lsb - old_lsb - fit_shift/2 ) + 32 ) & -64;
hinter->pp2.x = ( ( edge2->pos + old_rsb - fit_shift/2 ) + 32 ) & -64; #if 0
} /* try to fix certain bad advance computations */
else if ( hinter->pp2.x + hinter->pp1.x == edge2->pos && old_rsb > 4 )
{ hinter->pp2.x += 64;
hinter->pp1.x -= fit_shift / 2; #endif
hinter->pp2.x -= fit_shift / 2;
}
} }
/* good, we simply add the glyph to our loader's base */ /* 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 */ /* now, we must check the current character pixel size to see if we */
/* need to rescale the global metrics */ /* need to rescale the global metrics */
if ( face_globals->x_scale != x_scale || if ( face_globals->x_scale != x_scale ||
@@ -1574,15 +1699,9 @@
ah_loader_rewind( hinter->loader ); 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 */ /* reset hinting flags according to load flags and current render target */
hinter->do_horz_hints = !FT_BOOL( ( load_flags & FT_LOAD_NO_AUTOHINT ) || 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_vert_hints = !FT_BOOL( load_flags & FT_LOAD_NO_AUTOHINT );
#ifdef DEBUG_HINTER #ifdef DEBUG_HINTER
hinter->do_horz_hints = !ah_debug_disable_vert; /* not a bug, the meaning */ hinter->do_horz_hints = !ah_debug_disable_vert; /* not a bug, the meaning */
@@ -1592,14 +1711,15 @@
/* we snap the width of vertical stems for the monochrome and */ /* we snap the width of vertical stems for the monochrome and */
/* horizontal LCD rendering targets only. Corresponds to X snapping. */ /* horizontal LCD rendering targets only. Corresponds to X snapping. */
hinter->do_horz_snapping = FT_BOOL( hint_mode == FT_RENDER_MODE_MONO || hinter->do_horz_snapping = FT_BOOL( hint_mode == FT_RENDER_MODE_MONO ||
hint_mode == FT_RENDER_MODE_LCD || hint_mode == FT_RENDER_MODE_LCD );
hint_mode == FT_RENDER_MODE_SMOOTH );
/* we snap the width of horizontal stems for the monochrome and */ /* we snap the width of horizontal stems for the monochrome and */
/* vertical LCD rendering targets only. Corresponds to Y snapping. */ /* vertical LCD rendering targets only. Corresponds to Y snapping. */
hinter->do_vert_snapping = FT_BOOL( hint_mode == FT_RENDER_MODE_MONO || hinter->do_vert_snapping = FT_BOOL( hint_mode == FT_RENDER_MODE_MONO ||
hint_mode == FT_RENDER_MODE_LCD_V ); hint_mode == FT_RENDER_MODE_LCD_V );
hinter->do_stem_adjust = FT_BOOL( hint_mode != FT_RENDER_MODE_LIGHT );
#if 1 #if 1
load_flags = FT_LOAD_NO_SCALE load_flags = FT_LOAD_NO_SCALE
| FT_LOAD_IGNORE_TRANSFORM ; | FT_LOAD_IGNORE_TRANSFORM ;
+14
View File
@@ -385,6 +385,8 @@ FT_BEGIN_HEADER
} AH_OutlineRec, *AH_Outline; } AH_OutlineRec, *AH_Outline;
#ifdef FT_CONFIG_CHESTER_SMALL_F
# define AH_BLUE_CAPITAL_TOP 0 /* THEZOCQS */ # define AH_BLUE_CAPITAL_TOP 0 /* THEZOCQS */
# define AH_BLUE_CAPITAL_BOTTOM ( AH_BLUE_CAPITAL_TOP + 1 ) /* HEZLOCUS */ # 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_F_TOP ( AH_BLUE_CAPITAL_BOTTOM + 1 ) /* fijkdbh */
@@ -393,6 +395,17 @@ FT_BEGIN_HEADER
# define AH_BLUE_SMALL_MINOR ( AH_BLUE_SMALL_BOTTOM + 1 ) /* pqgjy */ # define AH_BLUE_SMALL_MINOR ( AH_BLUE_SMALL_BOTTOM + 1 ) /* pqgjy */
# define AH_BLUE_MAX ( AH_BLUE_SMALL_MINOR + 1 ) # 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; typedef FT_Int AH_Blue;
@@ -497,6 +510,7 @@ FT_BEGIN_HEADER
FT_Bool do_vert_hints; /* disable Y hinting */ FT_Bool do_vert_hints; /* disable Y hinting */
FT_Bool do_horz_snapping; /* disable X stem size snapping */ FT_Bool do_horz_snapping; /* disable X stem size snapping */
FT_Bool do_vert_snapping; /* disable Y 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; } AH_HinterRec, *AH_Hinter;
+3 -1
View File
@@ -24,7 +24,9 @@ UseFreeTypeHeaders ;
# Add the optional/replaceable files. # Add the optional/replaceable files.
# #
FT2_Library $(FT2_LIB) : ftsystem.c ftinit.c ftglyph.c ftmm.c ftbdf.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 ; ftbbox.c ftdebug.c ftxf86.c fttype1.c ftpfr.c
ftstroker.c ftwinfnt.c
;
# Add Macintosh-specific file to the library when necessary. # 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]) 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) all : $(OBJS)
library [--.lib]freetype.olb $(OBJS) library [--.lib]freetype.olb $(OBJS)
+41 -8
View File
@@ -20,6 +20,22 @@
#include FT_INTERNAL_BDF_TYPES_H #include FT_INTERNAL_BDF_TYPES_H
#include FT_INTERNAL_OBJECTS_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_EXPORT_DEF( FT_Error )
FT_Get_BDF_Charset_ID( FT_Face face, FT_Get_BDF_Charset_ID( FT_Face face,
@@ -33,13 +49,7 @@
error = FT_Err_Invalid_Argument; error = FT_Err_Invalid_Argument;
if ( face != NULL && face->driver != NULL ) if ( test_font_type( face, "bdf" ) )
{
FT_Module driver = (FT_Module) face->driver;
if ( driver->clazz && driver->clazz->module_name &&
ft_strcmp( driver->clazz->module_name, "bdf" ) == 0 )
{ {
BDF_Public_Face bdf_face = (BDF_Public_Face)face; BDF_Public_Face bdf_face = (BDF_Public_Face)face;
@@ -48,7 +58,6 @@
registry = (const char*) bdf_face->charset_registry; registry = (const char*) bdf_face->charset_registry;
error = 0; error = 0;
} }
}
if ( acharset_encoding ) if ( acharset_encoding )
*acharset_encoding = encoding; *acharset_encoding = 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 */ /* END */
+47 -1
View File
@@ -62,6 +62,13 @@
FT_ULong alloc_total; FT_ULong alloc_total;
FT_ULong alloc_current; FT_ULong alloc_current;
FT_ULong alloc_max; 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; const char* file_name;
FT_Long line_no; FT_Long line_no;
@@ -476,10 +483,22 @@
if ( size <= 0 ) if ( size <= 0 )
ft_mem_debug_panic( "negative block size allocation (%ld)", size ); 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 ); block = (FT_Byte *)ft_mem_table_alloc( table, size );
if ( block ) if ( block )
ft_mem_table_set( table, block, (FT_ULong)size ); ft_mem_table_set( table, block, (FT_ULong)size );
table->alloc_count++;
table->file_name = NULL; table->file_name = NULL;
table->line_no = 0; table->line_no = 0;
@@ -570,15 +589,42 @@
FT_Int result = 0; FT_Int result = 0;
if ( getenv( "FT_DEBUG_MEMORY" ) ) if ( getenv( "FT2_DEBUG_MEMORY" ) )
{ {
table = ft_mem_table_new( memory ); table = ft_mem_table_new( memory );
if ( table ) if ( table )
{ {
const char* p;
memory->user = table; memory->user = table;
memory->alloc = ft_mem_debug_alloc; memory->alloc = ft_mem_debug_alloc;
memory->realloc = ft_mem_debug_realloc; memory->realloc = ft_mem_debug_realloc;
memory->free = ft_mem_debug_free; 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; result = 1;
} }
} }
+1 -1
View File
@@ -56,7 +56,7 @@
/* documentation is in ftglyph.h */ /* documentation is in ftglyph.h */
FT_EXPORT_DEF( void ) FT_EXPORT_DEF( void )
FT_Matrix_Multiply( FT_Matrix* a, FT_Matrix_Multiply( const FT_Matrix* a,
FT_Matrix* b ) FT_Matrix* b )
{ {
FT_Fixed xx, xy, yx, yy; FT_Fixed xx, xy, yx, yy;
+191 -46
View File
@@ -22,7 +22,9 @@
#include FT_INTERNAL_OBJECTS_H #include FT_INTERNAL_OBJECTS_H
#include FT_INTERNAL_DEBUG_H #include FT_INTERNAL_DEBUG_H
#include FT_INTERNAL_STREAM_H #include FT_INTERNAL_STREAM_H
#include FT_INTERNAL_SFNT_H /* for SFNT_Load_Table_Func */
#include FT_TRUETYPE_TABLES_H #include FT_TRUETYPE_TABLES_H
#include FT_TRUETYPE_IDS_H
#include FT_OUTLINE_H #include FT_OUTLINE_H
@@ -196,11 +198,9 @@
return error; return error;
} }
FT_BASE_DEF( void )
static void ft_glyphslot_free_bitmap( FT_GlyphSlot slot )
ft_glyphslot_clear( FT_GlyphSlot slot )
{ {
/* free bitmap if needed */
if ( slot->flags & FT_GLYPH_OWN_BITMAP ) if ( slot->flags & FT_GLYPH_OWN_BITMAP )
{ {
FT_Memory memory = FT_FACE_MEMORY( slot->face ); FT_Memory memory = FT_FACE_MEMORY( slot->face );
@@ -209,6 +209,48 @@
FT_FREE( slot->bitmap.buffer ); FT_FREE( slot->bitmap.buffer );
slot->flags &= ~FT_GLYPH_OWN_BITMAP; 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 */ /* clear all public fields in the glyph slot */
FT_ZERO( &slot->metrics ); FT_ZERO( &slot->metrics );
@@ -246,8 +288,7 @@
clazz->done_slot( slot ); clazz->done_slot( slot );
/* free bitmap buffer if needed */ /* free bitmap buffer if needed */
if ( slot->flags & FT_GLYPH_OWN_BITMAP ) ft_glyphslot_free_bitmap( slot );
FT_FREE( slot->bitmap.buffer );
/* free glyph loader */ /* free glyph loader */
if ( FT_DRIVER_USES_OUTLINES( driver ) ) 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> */ /* <Function> */
@@ -718,7 +853,7 @@
FT_Memory memory; FT_Memory memory;
FT_Driver_Class clazz; FT_Driver_Class clazz;
FT_Face face = 0; FT_Face face = 0;
FT_Error error; FT_Error error, error2;
FT_Face_Internal internal; FT_Face_Internal internal;
@@ -760,24 +895,17 @@
goto Fail; goto Fail;
/* select Unicode charmap by default */ /* 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; error = error2;
FT_CharMap unicmap = NULL, cmap; goto Fail;
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;
} }
*aface = face; *aface = face;
@@ -1241,10 +1369,10 @@
/* Compute root ascender, descender, test height, and max_advance */ /* Compute root ascender, descender, test height, and max_advance */
metrics->ascender = ( FT_MulFix( face->ascender, metrics->ascender = ( FT_MulFix( face->ascender,
metrics->y_scale ) + 32 ) & -64; metrics->y_scale ) + 63 ) & -64;
metrics->descender = ( FT_MulFix( face->descender, metrics->descender = ( FT_MulFix( face->descender,
metrics->y_scale ) + 32 ) & -64; metrics->y_scale ) + 0 ) & -64;
metrics->height = ( FT_MulFix( face->height, metrics->height = ( FT_MulFix( face->height,
metrics->y_scale ) + 32 ) & -64; metrics->y_scale ) + 32 ) & -64;
@@ -1297,9 +1425,10 @@
if ( char_height < 1 * 64 ) if ( char_height < 1 * 64 )
char_height = 1 * 64; char_height = 1 * 64;
/* Compute pixel sizes in 26.6 units */ /* Compute pixel sizes in 26.6 units. we use rounding
dim_x = ( ( char_width * horz_resolution ) / 72 ) ; */
dim_y = ( ( char_height * vert_resolution ) / 72 ) ; 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->x_ppem = (FT_UShort)( dim_x >> 6 );
metrics->y_ppem = (FT_UShort)( dim_y >> 6 ); metrics->y_ppem = (FT_UShort)( dim_y >> 6 );
@@ -1315,15 +1444,6 @@
ft_recompute_scaled_metrics( face, metrics ); 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 ) if ( clazz->set_char_sizes )
error = clazz->set_char_sizes( face->size, error = clazz->set_char_sizes( face->size,
char_width, char_width,
@@ -1379,14 +1499,6 @@
ft_recompute_scaled_metrics( face, metrics ); 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 ) if ( clazz->set_pixel_sizes )
error = clazz->set_pixel_sizes( face->size, error = clazz->set_pixel_sizes( face->size,
pixel_width, pixel_width,
@@ -1458,6 +1570,13 @@
if ( !face ) if ( !face )
return FT_Err_Invalid_Face_Handle; 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; cur = face->charmaps;
if ( !cur ) if ( !cur )
return FT_Err_Invalid_CharMap_Handle; 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_EXPORT_DEF( FT_Error )
FT_Activate_Size( FT_Size size ) FT_Activate_Size( FT_Size size )
{ {
+216 -3
View File
@@ -233,8 +233,12 @@
{ {
FT_ASSERT( border->start >= 0 ); FT_ASSERT( border->start >= 0 );
/* don't record empty paths !! */
if ( border->num_points > (FT_UInt)border->start )
{
border->tags[ border->start ] |= FT_STROKE_TAG_BEGIN; border->tags[ border->start ] |= FT_STROKE_TAG_BEGIN;
border->tags[ border->num_points-1 ] |= FT_STROKE_TAG_END; border->tags[ border->num_points-1 ] |= FT_STROKE_TAG_END;
}
border->start = -1; border->start = -1;
border->movable = 0; border->movable = 0;
@@ -469,7 +473,7 @@
FT_Byte* tags = border->tags; FT_Byte* tags = border->tags;
FT_Int in_contour = 0; 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 ) if ( tags[0] & FT_STROKE_TAG_BEGIN )
{ {
@@ -538,7 +542,7 @@
FT_Short* write = outline->contours + outline->n_contours; FT_Short* write = outline->contours + outline->n_contours;
FT_Short index = (FT_Short) outline->n_points; 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 ) if ( *tags & FT_STROKE_TAG_END )
{ {
@@ -787,9 +791,15 @@
theta = FT_Angle_Diff( stroker->angle_in, stroker->angle_out ); theta = FT_Angle_Diff( stroker->angle_in, stroker->angle_out );
if (theta == FT_ANGLE_PI) if (theta == FT_ANGLE_PI)
{
theta = rotate; theta = rotate;
phi = stroker->angle_in;
}
else else
{
theta = theta/2; theta = theta/2;
phi = stroker->angle_in + theta + rotate;
}
thcos = FT_Cos( theta ); thcos = FT_Cos( theta );
sigma = FT_MulFix( stroker->miter_limit, thcos ); sigma = FT_MulFix( stroker->miter_limit, thcos );
@@ -797,7 +807,6 @@
if ( sigma >= 0x10000L ) if ( sigma >= 0x10000L )
miter = 0; miter = 0;
phi = stroker->angle_in + theta + rotate;
if (miter) /* this is a miter (broken angle) */ if (miter) /* this is a miter (broken angle) */
{ {
@@ -1362,3 +1371,207 @@
ft_stroke_border_export( stroker->borders+1, outline ); 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; FT_Angle delta = angle2 - angle1;
delta %= FT_ANGLE_2PI; delta %= FT_ANGLE_2PI;
if ( delta < 0 )
delta += FT_ANGLE_2PI;
if ( delta > FT_ANGLE_PI ) if ( delta > FT_ANGLE_PI )
delta -= FT_ANGLE_2PI; 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 */
+2
View File
@@ -55,6 +55,8 @@ BASE_EXT_SRC := $(BASE_)ftglyph.c \
$(BASE_)fttype1.c \ $(BASE_)fttype1.c \
$(BASE_)ftxf86.c \ $(BASE_)ftxf86.c \
$(BASE_)ftpfr.c \ $(BASE_)ftpfr.c \
$(BASE_)ftstroker.c \
$(BASE_)ftwinfnt.c \
$(BASE_)ftbbox.c $(BASE_)ftbbox.c
# Default extensions objects # Default extensions objects
+59 -8
View File
@@ -29,6 +29,7 @@ THE SOFTWARE.
#include FT_INTERNAL_DEBUG_H #include FT_INTERNAL_DEBUG_H
#include FT_INTERNAL_STREAM_H #include FT_INTERNAL_STREAM_H
#include FT_INTERNAL_OBJECTS_H #include FT_INTERNAL_OBJECTS_H
#include FT_BDF_H
#include "bdf.h" #include "bdf.h"
#include "bdfdrivr.h" #include "bdfdrivr.h"
@@ -488,8 +489,6 @@ THE SOFTWARE.
int i, j, count; int i, j, count;
unsigned char *p, *pp; unsigned char *p, *pp;
FT_Memory memory = face->bdffont->memory;
FT_UNUSED( load_flags ); FT_UNUSED( load_flags );
@@ -513,9 +512,9 @@ THE SOFTWARE.
bitmap->pixel_mode = FT_PIXEL_MODE_MONO; bitmap->pixel_mode = FT_PIXEL_MODE_MONO;
bitmap->pitch = glyph.bpr; bitmap->pitch = glyph.bpr;
if ( FT_NEW_ARRAY( bitmap->buffer, glyph.bytes ) ) /* note: we don't allocate a new array to hold the bitmap, we */
goto Exit; /* can simply point to it */
FT_MEM_COPY( bitmap->buffer, glyph.bitmap, glyph.bytes ); ft_glyphslot_set_bitmap( slot, glyph.bitmap );
} }
else else
{ {
@@ -523,7 +522,8 @@ THE SOFTWARE.
bitmap->pixel_mode = FT_PIXEL_MODE_GRAY; bitmap->pixel_mode = FT_PIXEL_MODE_GRAY;
bitmap->pitch = bitmap->width; 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; goto Exit;
switch ( bpp ) switch ( bpp )
@@ -624,13 +624,64 @@ THE SOFTWARE.
slot->linearHoriAdvance = (FT_Fixed)glyph.dwidth << 16; slot->linearHoriAdvance = (FT_Fixed)glyph.dwidth << 16;
slot->format = FT_GLYPH_FORMAT_BITMAP; slot->format = FT_GLYPH_FORMAT_BITMAP;
slot->flags = FT_GLYPH_OWN_BITMAP;
Exit: Exit:
return error; 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 FT_CALLBACK_TABLE_DEF
const FT_Driver_ClassRec bdf_driver_class = const FT_Driver_ClassRec bdf_driver_class =
{ {
@@ -646,7 +697,7 @@ THE SOFTWARE.
(FT_Module_Constructor)0, (FT_Module_Constructor)0,
(FT_Module_Destructor) 0, (FT_Module_Destructor) 0,
(FT_Module_Requester) 0 (FT_Module_Requester) bdf_driver_requester
}, },
sizeof ( BDF_FaceRec ), sizeof ( BDF_FaceRec ),
+104 -11
View File
@@ -196,7 +196,8 @@
FTC_Node* pold; FTC_Node* pold;
FT_ASSERT( old_index >= FTC_HASH_INITIAL_SIZE ); if ( old_index+1 <= FTC_HASH_INITIAL_SIZE )
goto Exit;
if ( p == 0 ) if ( p == 0 )
{ {
@@ -356,10 +357,12 @@
FT_FREE( node ); FT_FREE( node );
#if 0
/* check, just in case of general corruption :-) */ /* check, just in case of general corruption :-) */
if ( manager->num_nodes == 0 ) if ( manager->num_nodes == 0 )
FT_ERROR(( "ftc_node_destroy: invalid cache node count! = %d\n", FT_ERROR(( "ftc_node_destroy: invalid cache node count! = %d\n",
manager->num_nodes )); manager->num_nodes ));
#endif
} }
@@ -403,6 +406,8 @@
FT_EXPORT_DEF( void ) FT_EXPORT_DEF( void )
ftc_family_done( FTC_Family family ) ftc_family_done( FTC_Family family )
{
if ( family && family->cache )
{ {
FTC_Manager manager = family->cache->manager; FTC_Manager manager = family->cache->manager;
@@ -410,6 +415,7 @@
/* remove from manager's family table */ /* remove from manager's family table */
ftc_family_table_free( &manager->families, family->fam_index ); ftc_family_table_free( &manager->families, family->fam_index );
} }
}
/*************************************************************************/ /*************************************************************************/
@@ -546,7 +552,9 @@
FTC_Node *anode ) FTC_Node *anode )
{ {
FT_Error error = FT_Err_Ok; FT_Error error = FT_Err_Ok;
FTC_Manager manager;
FT_LruNode lru; FT_LruNode lru;
FT_UInt free_count = 0;
if ( !cache || !query || !anode ) if ( !cache || !query || !anode )
@@ -557,7 +565,31 @@
query->hash = 0; query->hash = 0;
query->family = NULL; 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 */ /* first of all, find the relevant family */
FT_LruList list = cache->families; FT_LruList list = cache->families;
@@ -572,7 +604,7 @@
{ {
error = FT_LruList_Lookup( list, query, &lru ); error = FT_LruList_Lookup( list, query, &lru );
if ( error ) if ( error )
goto Exit; goto Fail;
goto Skip; goto Skip;
} }
@@ -600,6 +632,7 @@
} }
{ {
FTC_Manager manager = cache->manager;
FTC_Family family = (FTC_Family) lru; FTC_Family family = (FTC_Family) lru;
FT_UFast hash = query->hash; FT_UFast hash = query->hash;
FTC_Node* bucket; FTC_Node* bucket;
@@ -614,11 +647,12 @@
if ( query->family != family || if ( query->family != family ||
family->fam_index >= cache->manager->families.size ) family->fam_index >= manager->families.size )
{ {
FT_ERROR(( FT_ERROR((
"ftc_cache_lookup: invalid query (bad 'family' field)\n" )); "ftc_cache_lookup: invalid query (bad 'family' field)\n" ));
return FTC_Err_Invalid_Argument; error = FTC_Err_Invalid_Argument;
goto Exit;
} }
if ( *bucket ) if ( *bucket )
@@ -649,8 +683,8 @@
} }
/* move to head of MRU list */ /* move to head of MRU list */
if ( node != cache->manager->nodes_list ) if ( node != manager->nodes_list )
ftc_node_mru_up( node, cache->manager ); ftc_node_mru_up( node, manager );
*anode = node; *anode = node;
goto Exit; goto Exit;
@@ -663,13 +697,12 @@
/* didn't find a node, create a new one */ /* didn't find a node, create a new one */
{ {
FTC_Cache_Class clazz = cache->clazz; FTC_Cache_Class clazz = cache->clazz;
FTC_Manager manager = cache->manager;
FT_Memory memory = cache->memory; FT_Memory memory = cache->memory;
FTC_Node node; FTC_Node node;
if ( FT_ALLOC( node, clazz->node_size ) ) if ( FT_ALLOC( node, clazz->node_size ) )
goto Exit; goto Fail;
node->fam_index = (FT_UShort) family->fam_index; node->fam_index = (FT_UShort) family->fam_index;
node->hash = query->hash; node->hash = query->hash;
@@ -679,7 +712,7 @@
if ( error ) if ( error )
{ {
FT_FREE( node ); FT_FREE( node );
goto Exit; goto Fail;
} }
error = ftc_node_hash_link( node, cache ); error = ftc_node_hash_link( node, cache );
@@ -687,7 +720,7 @@
{ {
clazz->node_done( node, cache ); clazz->node_done( node, cache );
FT_FREE( node ); FT_FREE( node );
goto Exit; goto Fail;
} }
ftc_node_mru_link( node, cache->manager ); ftc_node_mru_link( node, cache->manager );
@@ -704,6 +737,66 @@
*anode = node; *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;
free_count = new_count;
/* try to remove "new_count" nodes from the list */
{
FTC_Node first = manager->nodes_list;
FTC_Node 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;
}
}
}
} }
Exit: Exit:
+49 -1
View File
@@ -23,9 +23,13 @@
#include FT_CACHE_MANAGER_H #include FT_CACHE_MANAGER_H
#include FT_INTERNAL_MEMORY_H #include FT_INTERNAL_MEMORY_H
#include FT_INTERNAL_DEBUG_H #include FT_INTERNAL_DEBUG_H
#include FT_TRUETYPE_IDS_H
#include "ftcerror.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 */ /* Each FTC_CMapNode contains a simple array to map a range of character */
@@ -189,10 +193,54 @@
break; break;
case FTC_CMAP_BY_ENCODING: case FTC_CMAP_BY_ENCODING:
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++ ) for ( idx = 0; idx < count; idx++, cur++ )
if ( cur[0]->encoding == desc->u.encoding ) if ( cur[0]->encoding == desc->u.encoding )
break; break;
}
Found_idx_for_FTC_CMAP_BY_ENCODING:
hash = idx * 67; hash = idx * 67;
break; break;
@@ -227,7 +275,7 @@
return error; return error;
Bad_Descriptor: 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; return FTC_Err_Invalid_Argument;
} }
+1 -1
View File
@@ -216,7 +216,7 @@
/* we mark unloaded glyphs with `sbit.buffer == 0' */ /* we mark unloaded glyphs with `sbit.buffer == 0' */
/* and 'width == 255', 'height == 0' */ /* and 'width == 255', 'height == 0' */
/* */ /* */
if ( error ) if ( error && error != FT_Err_Out_Of_Memory )
{ {
sbit->width = 255; sbit->width = 255;
error = 0; error = 0;
+101 -45
View File
@@ -21,6 +21,7 @@
#include FT_CACHE_INTERNAL_LRU_H #include FT_CACHE_INTERNAL_LRU_H
#include FT_LIST_H #include FT_LIST_H
#include FT_INTERNAL_OBJECTS_H #include FT_INTERNAL_OBJECTS_H
#include FT_INTERNAL_DEBUG_H
#include "ftcerror.h" #include "ftcerror.h"
@@ -187,73 +188,127 @@
goto Exit; goto Exit;
} }
/* we haven't found the relevant element. We will now try */ /* since we haven't found the relevant element in our LRU list,
/* to create a new one. */ * 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 */ FT_Int drop_last = ( list->max_nodes > 0 &&
/* the oldest node, if there's one! */ list->num_nodes >= list->max_nodes );
FT_LruNode last = *plast;
for (;;)
if ( last )
{ {
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 )
{
/* 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 ) if ( clazz->node_flush )
{ {
error = clazz->node_flush( last, key, list->data ); 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 else
{ {
if ( clazz->node_done ) /* try to allocate a new node when "drop_last" is not TRUE
clazz->node_done( last, list->data ); * this usually happens on the first pass, when the LRU list
* is not already full.
last->key = key; */
error = clazz->node_init( last, key, list->data );
}
if ( !error )
{
/* move it to the top of the list */
*plast = NULL;
last->next = list->nodes;
list->nodes = last;
result = last;
goto Exit;
}
/* 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 );
*plast = NULL;
list->num_nodes--;
FT_FREE( last );
goto Exit;
}
}
/* otherwise, simply allocate a new node */
if ( FT_ALLOC( node, clazz->node_size ) ) if ( FT_ALLOC( node, clazz->node_size ) )
goto Exit; goto Fail;
}
FT_ASSERT( node != NULL );
node->key = key; node->key = key;
error = clazz->node_init( node, key, list->data ); error = clazz->node_init( node, key, list->data );
if ( error ) if ( error )
{ {
if ( clazz->node_done )
clazz->node_done( node, list->data );
FT_FREE( node ); FT_FREE( node );
goto Exit; goto Fail;
} }
Success:
result = node; result = node;
node->next = list->nodes; node->next = list->nodes;
list->nodes = node; list->nodes = node;
list->num_nodes++; list->num_nodes++;
goto Exit;
Fail:
if ( error != FT_Err_Out_Of_Memory )
goto Exit;
drop_last = 1;
continue;
}
}
Exit: Exit:
*anode = result; *anode = result;
@@ -261,6 +316,7 @@
} }
FT_EXPORT_DEF( void ) FT_EXPORT_DEF( void )
FT_LruList_Remove( FT_LruList list, FT_LruList_Remove( FT_LruList list,
FT_LruNode node ) FT_LruNode node )
+23
View File
@@ -2363,6 +2363,29 @@
cff_builder_done( &decoder.builder ); 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_matrix = cff->top_font.font_dict.font_matrix;
font_offset = cff->top_font.font_dict.font_offset; 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 */ /* In order to use a predefined charset, the following must be */
/* true: The charset constructed for the glyphs in the font's */ /* true: The charset constructed for the glyphs in the font's */
/* charstrings dictionary must match the predefined charset in */ /* charstrings dictionary must match the predefined charset in */
/* the first num_glyphs, and hence must match the predefined */ /* the first num_glyphs */
/* charset *exactly*. */
charset->offset = offset; /* record charset type */ charset->offset = offset; /* record charset type */
switch ( (FT_UInt)offset ) switch ( (FT_UInt)offset )
{ {
case 0: 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" )); "predefined charset (Adobe ISO-Latin)!\n" ));
error = CFF_Err_Invalid_File_Format; error = CFF_Err_Invalid_File_Format;
goto Exit; goto Exit;
@@ -1622,9 +1621,9 @@
break; break;
case 1: 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" )); "predefined charset (Adobe Expert)!\n" ));
error = CFF_Err_Invalid_File_Format; error = CFF_Err_Invalid_File_Format;
goto Exit; goto Exit;
@@ -1641,9 +1640,9 @@
break; break;
case 2: 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" )); "predefined charset (Adobe Expert Subset)!\n" ));
error = CFF_Err_Invalid_File_Format; error = CFF_Err_Invalid_File_Format;
goto Exit; goto Exit;
@@ -1744,14 +1743,17 @@
FT_READ_BYTE( count ) ) FT_READ_BYTE( count ) )
goto Exit; goto Exit;
encoding->count = count + 1;
switch ( encoding->format & 0x7F ) switch ( encoding->format & 0x7F )
{ {
case 0: case 0:
{ {
FT_Byte* p; 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 ) ) if ( FT_FRAME_ENTER( count ) )
goto Exit; goto Exit;
@@ -1763,7 +1765,7 @@
glyph_code = *p++; glyph_code = *p++;
/* Make sure j is not too big. */ /* Make sure j is not too big. */
if ( (FT_UInt) glyph_code < num_glyphs ) if ( j < num_glyphs )
{ {
/* Assign code to GID mapping. */ /* Assign code to GID mapping. */
encoding->codes[glyph_code] = (FT_UShort)j; encoding->codes[glyph_code] = (FT_UShort)j;
@@ -1784,6 +1786,8 @@
FT_UInt k; FT_UInt k;
encoding->count = 0;
/* Parse the Format1 ranges. */ /* Parse the Format1 ranges. */
for ( j = 0; j < count; j++, i += nleft ) for ( j = 0; j < count; j++, i += nleft )
{ {
@@ -1798,6 +1802,10 @@
/* Increment nleft, so we read `nleft + 1' codes/sids. */ /* Increment nleft, so we read `nleft + 1' codes/sids. */
nleft++; nleft++;
/* compute max number of character codes */
if ( (FT_UInt)nleft > encoding->count )
encoding->count = nleft;
/* Fill in the range of codes/sids. */ /* Fill in the range of codes/sids. */
for ( k = i; k < nleft + i; k++, glyph_code++ ) 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; break;
@@ -1867,8 +1879,6 @@
/* encoding (see the note at the end of section 12 in the CFF */ /* encoding (see the note at the end of section 12 in the CFF */
/* specification). */ /* specification). */
encoding->count = 256;
switch ( (FT_UInt)offset ) switch ( (FT_UInt)offset )
{ {
case 0: case 0:
@@ -1886,6 +1896,10 @@
Populate: Populate:
/* Construct code to GID mapping from code to SID mapping */ /* Construct code to GID mapping from code to SID mapping */
/* and charset. */ /* and charset. */
encoding->count = 0;
for ( j = 0; j < 256; j++ ) for ( j = 0; j < 256; j++ )
{ {
/* If j is encoded, find the GID for it. */ /* If j is encoded, find the GID for it. */
@@ -1905,7 +1919,13 @@
encoding->sids [j] = 0; encoding->sids [j] = 0;
} }
else else
{
encoding->codes[j] = (FT_UShort)i; encoding->codes[j] = (FT_UShort)i;
/* update encoding count */
if ( encoding->count < j+1 )
encoding->count = j+1;
}
} }
} }
break; break;
+6 -8
View File
@@ -89,7 +89,7 @@
else else
#endif #endif /* FT_CONFIG_OPTION_INCREMENTAL */
/* For ordinary fonts read the CID font dictionary index */ /* For ordinary fonts read the CID font dictionary index */
/* and charstring offset from the CIDMap. */ /* and charstring offset from the CIDMap. */
@@ -162,23 +162,21 @@
face->root.internal->incremental_interface && face->root.internal->incremental_interface &&
face->root.internal->incremental_interface->funcs->get_glyph_metrics ) face->root.internal->incremental_interface->funcs->get_glyph_metrics )
{ {
FT_Bool found = FALSE;
FT_Incremental_MetricsRec 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( error = face->root.internal->incremental_interface->funcs->get_glyph_metrics(
face->root.internal->incremental_interface->object, face->root.internal->incremental_interface->object,
glyph_index, FALSE, &metrics, &found ); glyph_index, FALSE, &metrics );
if ( found )
{
decoder->builder.left_bearing.x = metrics.bearing_x; decoder->builder.left_bearing.x = metrics.bearing_x;
decoder->builder.left_bearing.y = metrics.bearing_y; decoder->builder.left_bearing.y = metrics.bearing_y;
decoder->builder.advance.x = metrics.advance; decoder->builder.advance.x = metrics.advance;
decoder->builder.advance.y = 0; decoder->builder.advance.y = 0;
} }
}
#endif #endif /* FT_CONFIG_OPTION_INCREMENTAL */
Exit: Exit:
return error; return error;
+5 -5
View File
@@ -3,7 +3,7 @@
* For conditions of distribution and use, see copyright notice in zlib.h * 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" #include "zlib.h"
@@ -18,10 +18,10 @@
#define DO16(buf) DO8(buf,0); DO8(buf,8); #define DO16(buf) DO8(buf,0); DO8(buf,8);
/* ========================================================================= */ /* ========================================================================= */
ZEXTERNDEF uLong ZEXPORT adler32(adler, buf, len) ZEXPORT(uLong) adler32( /* adler, buf, len) */
uLong adler; uLong adler,
const Bytef *buf; const Bytef *buf,
uInt len; uInt len )
{ {
unsigned long s1 = adler & 0xffff; unsigned long s1 = adler & 0xffff;
unsigned long s2 = (adler >> 16) & 0xffff; unsigned long s2 = (adler >> 16) & 0xffff;
+10 -7
View File
@@ -29,7 +29,7 @@
#ifdef FT_CONFIG_OPTION_SYSTEM_ZLIB #ifdef FT_CONFIG_OPTION_SYSTEM_ZLIB
# include "zlib.h" # include <zlib.h>
#else /* !SYSTEM_ZLIB */ #else /* !SYSTEM_ZLIB */
@@ -96,10 +96,10 @@
#ifndef FT_CONFIG_OPTION_SYSTEM_ZLIB #ifndef FT_CONFIG_OPTION_SYSTEM_ZLIB
local voidpf local voidpf
zcalloc (opaque, items, size) zcalloc ( /* opaque, items, size) */
voidpf opaque; voidpf opaque,
unsigned items; unsigned items,
unsigned size; unsigned size )
{ {
return ft_gzip_alloc( opaque, items, size ); return ft_gzip_alloc( opaque, items, size );
} }
@@ -177,7 +177,7 @@
(void)FT_STREAM_SKIP( 6 ); (void)FT_STREAM_SKIP( 6 );
/* skip the extra field */ /* skip the extra field */
if ( head[3] && FT_GZIP_EXTRA_FIELD ) if ( head[3] & FT_GZIP_EXTRA_FIELD )
{ {
FT_UInt len; FT_UInt len;
@@ -187,7 +187,7 @@
} }
/* skip original file name */ /* skip original file name */
if ( head[3] && FT_GZIP_ORIG_NAME ) if ( head[3] & FT_GZIP_ORIG_NAME )
for (;;) for (;;)
{ {
FT_UInt c; FT_UInt c;
@@ -276,6 +276,8 @@
{ {
z_stream* zstream = &zip->zstream; z_stream* zstream = &zip->zstream;
inflateEnd( zstream );
/* clear the rest */ /* clear the rest */
zstream->zalloc = NULL; zstream->zalloc = NULL;
zstream->zfree = NULL; zstream->zfree = NULL;
@@ -376,6 +378,7 @@
if ( err == Z_STREAM_END ) if ( err == Z_STREAM_END )
{ {
zip->limit = zstream->next_out; zip->limit = zstream->next_out;
error = FT_Err_Invalid_Stream_Operation;
break; break;
} }
else if ( err != Z_OK ) 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) local void inflate_blocks_reset( /* s, z, c) */
inflate_blocks_statef *s; inflate_blocks_statef *s,
z_streamp z; z_streamp z,
uLongf *c; uLongf *c )
{ {
if (c != Z_NULL) if (c != Z_NULL)
*c = s->check; *c = s->check;
@@ -85,10 +85,10 @@ uLongf *c;
} }
local inflate_blocks_statef *inflate_blocks_new(z, c, w) local inflate_blocks_statef *inflate_blocks_new( /* z, c, w) */
z_streamp z; z_streamp z,
check_func c; check_func c,
uInt w; uInt w )
{ {
inflate_blocks_statef *s; inflate_blocks_statef *s;
@@ -116,10 +116,10 @@ uInt w;
} }
local int inflate_blocks(s, z, r) local int inflate_blocks( /* s, z, r) */
inflate_blocks_statef *s; inflate_blocks_statef *s,
z_streamp z; z_streamp z,
int r; int r )
{ {
uInt t; /* temporary storage */ uInt t; /* temporary storage */
uLong b; /* bit buffer */ uLong b; /* bit buffer */
@@ -365,12 +365,15 @@ int r;
r = Z_STREAM_ERROR; r = Z_STREAM_ERROR;
LEAVE LEAVE
} }
#ifdef NEED_DUMMY_RETURN
return 0;
#endif
} }
local int inflate_blocks_free(s, z) local int inflate_blocks_free( /* s, z) */
inflate_blocks_statef *s; inflate_blocks_statef *s,
z_streamp z; z_streamp z )
{ {
inflate_blocks_reset(s, z, Z_NULL); inflate_blocks_reset(s, z, Z_NULL);
ZFREE(z, s->window); 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) local inflate_codes_statef *inflate_codes_new( /* bl, bd, tl, td, z) */
uInt bl, bd; uInt bl, uInt bd,
inflate_huft *tl; inflate_huft *tl,
inflate_huft *td; /* need separate declaration for Borland C++ */ inflate_huft *td, /* need separate declaration for Borland C++ */
z_streamp z; z_streamp z )
{ {
inflate_codes_statef *c; inflate_codes_statef *c;
@@ -77,10 +77,10 @@ z_streamp z;
} }
local int inflate_codes(s, z, r) local int inflate_codes( /* s, z, r) */
inflate_blocks_statef *s; inflate_blocks_statef *s,
z_streamp z; z_streamp z,
int r; int r )
{ {
uInt j; /* temporary storage */ uInt j; /* temporary storage */
inflate_huft *t; /* temporary pointer */ inflate_huft *t; /* temporary pointer */
@@ -241,9 +241,9 @@ int r;
} }
local void inflate_codes_free(c, z) local void inflate_codes_free( /* c, z) */
inflate_codes_statef *c; inflate_codes_statef *c,
z_streamp z; z_streamp z )
{ {
ZFREE(z, c); ZFREE(z, c);
Tracev((stderr, "inflate: codes free\n")); Tracev((stderr, "inflate: codes free\n"));
+12 -12
View File
@@ -51,8 +51,8 @@ struct internal_state {
}; };
int ZEXPORT inflateReset(z) ZEXPORT(int) inflateReset( /* z) */
z_streamp z; z_streamp z )
{ {
if (z == Z_NULL || z->state == Z_NULL) if (z == Z_NULL || z->state == Z_NULL)
return Z_STREAM_ERROR; return Z_STREAM_ERROR;
@@ -65,8 +65,8 @@ z_streamp z;
} }
int ZEXPORT inflateEnd(z) ZEXPORT(int) inflateEnd( /* z) */
z_streamp z; z_streamp z )
{ {
if (z == Z_NULL || z->state == Z_NULL || z->zfree == Z_NULL) if (z == Z_NULL || z->state == Z_NULL || z->zfree == Z_NULL)
return Z_STREAM_ERROR; return Z_STREAM_ERROR;
@@ -79,11 +79,11 @@ z_streamp z;
} }
int ZEXPORT inflateInit2_(z, w, version, stream_size) ZEXPORT(int) inflateInit2_( /* z, w, version, stream_size) */
z_streamp z; z_streamp z,
int w; int w,
const char *version; const char *version,
int stream_size; int stream_size )
{ {
if (version == Z_NULL || version[0] != ZLIB_VERSION[0] || if (version == Z_NULL || version[0] != ZLIB_VERSION[0] ||
stream_size != sizeof(z_stream)) stream_size != sizeof(z_stream))
@@ -144,9 +144,9 @@ int stream_size;
#define NEXTBYTE (z->avail_in--,z->total_in++,*z->next_in++) #define NEXTBYTE (z->avail_in--,z->total_in++,*z->next_in++)
int ZEXPORT inflate(z, f) ZEXPORT(int) inflate( /* z, f) */
z_streamp z; z_streamp z,
int f; int f )
{ {
int r; int r;
uInt b; uInt b;
+40 -33
View File
@@ -10,8 +10,11 @@
# define BUILDFIXED /* non ANSI compilers may not accept inffixed.h */ # define BUILDFIXED /* non ANSI compilers may not accept inffixed.h */
#endif #endif
#if 0
local const char inflate_copyright[] = local const char inflate_copyright[] =
" inflate 1.1.4 Copyright 1995-2002 Mark Adler "; " inflate 1.1.4 Copyright 1995-2002 Mark Adler ";
#endif
/* /*
If you use the zlib library in a product, an acknowledgment is welcome 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 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. */ /* If BMAX needs to be larger than 16, then h and x[] should be uLong. */
#define BMAX 15 /* maximum bit length of any code */ #define BMAX 15 /* maximum bit length of any code */
local int huft_build(b, n, s, d, e, t, m, hp, hn, v) local int huft_build( /* b, n, s, d, e, t, m, hp, hn, v) */
uIntf *b; /* code lengths in bits (all assumed <= BMAX) */ uIntf *b, /* code lengths in bits (all assumed <= BMAX) */
uInt n; /* number of codes (assumed <= 288) */ uInt n, /* number of codes (assumed <= 288) */
uInt s; /* number of simple-valued codes (0..s-1) */ uInt s, /* number of simple-valued codes (0..s-1) */
const uIntf *d; /* list of base values for non-simple codes */ const uIntf *d, /* list of base values for non-simple codes */
const uIntf *e; /* list of extra bits for non-simple codes */ const uIntf *e, /* list of extra bits for non-simple codes */
inflate_huft * FAR *t; /* result: starting table */ inflate_huft * FAR *t, /* result: starting table */
uIntf *m; /* maximum lookup bits, returns actual */ uIntf *m, /* maximum lookup bits, returns actual */
inflate_huft *hp; /* space for trees */ inflate_huft *hp, /* space for trees */
uInt *hn; /* hufts used in space */ uInt *hn, /* hufts used in space */
uIntf *v; /* working area: values in order of bit length */ 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 /* 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 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 if the given code set is incomplete (the tables are still built in this
case), or Z_DATA_ERROR if the input is invalid. */ case), or Z_DATA_ERROR if the input is invalid. */
)
{ {
uInt a; /* counter for codes of length k */ 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) local int inflate_trees_bits( /* c, bb, tb, hp, z) */
uIntf *c; /* 19 code lengths */ uIntf *c, /* 19 code lengths */
uIntf *bb; /* bits tree desired/actual depth */ uIntf *bb, /* bits tree desired/actual depth */
inflate_huft * FAR *tb; /* bits tree result */ inflate_huft * FAR *tb, /* bits tree result */
inflate_huft *hp; /* space for trees */ inflate_huft *hp, /* space for trees */
z_streamp z; /* for messages */ z_streamp z /* for messages */
)
{ {
int r; int r;
uInt hn = 0; /* hufts used in space */ 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) local int inflate_trees_dynamic( /* nl, nd, c, bl, bd, tl, td, hp, z) */
uInt nl; /* number of literal/length codes */ uInt nl, /* number of literal/length codes */
uInt nd; /* number of distance codes */ uInt nd, /* number of distance codes */
uIntf *c; /* that many (total) code lengths */ uIntf *c, /* that many (total) code lengths */
uIntf *bl; /* literal desired/actual bit depth */ uIntf *bl, /* literal desired/actual bit depth */
uIntf *bd; /* distance desired/actual bit depth */ uIntf *bd, /* distance desired/actual bit depth */
inflate_huft * FAR *tl; /* literal/length tree result */ inflate_huft * FAR *tl, /* literal/length tree result */
inflate_huft * FAR *td; /* distance tree result */ inflate_huft * FAR *td, /* distance tree result */
inflate_huft *hp; /* space for trees */ inflate_huft *hp, /* space for trees */
z_streamp z; /* for messages */ z_streamp z /* for messages */
)
{ {
int r; int r;
uInt hn = 0; /* hufts used in space */ uInt hn = 0; /* hufts used in space */
@@ -394,12 +400,13 @@ local inflate_huft *fixed_td;
#endif #endif
local int inflate_trees_fixed(bl, bd, tl, td, z) local int inflate_trees_fixed( /* bl, bd, tl, td, z) */
uIntf *bl; /* literal desired/actual bit depth */ uIntf *bl, /* literal desired/actual bit depth */
uIntf *bd; /* distance desired/actual bit depth */ uIntf *bd, /* distance desired/actual bit depth */
inflate_huft * FAR *tl; /* literal/length tree result */ inflate_huft * FAR *tl, /* literal/length tree result */
inflate_huft * FAR *td; /* distance tree result */ inflate_huft * FAR *td, /* distance tree result */
z_streamp z; /* for memory allocation */ z_streamp z /* for memory allocation */
)
{ {
#ifdef BUILDFIXED #ifdef BUILDFIXED
/* build fixed tables if not already */ /* 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 */ /* copy as much as possible from the sliding window to the output area */
local int inflate_flush(s, z, r) local int inflate_flush( /* s, z, r) */
inflate_blocks_statef *s; inflate_blocks_statef *s,
z_streamp z; z_streamp z,
int r; int r )
{ {
uInt n; uInt n;
Bytef *p; Bytef *p;
+9 -1
View File
@@ -21,7 +21,11 @@ GZIP_DIR_ := $(GZIP_DIR)$(SEP)
# compilation flags for the driver # compilation flags for the driver
# #
ifeq ($(SYSTEM_ZLIB),)
GZIP_COMPILE := $(FT_COMPILE) $I$(GZIP_DIR) GZIP_COMPILE := $(FT_COMPILE) $I$(GZIP_DIR)
else
GZIP_COMPILE := $(FT_COMPILE)
endif
# gzip support sources (i.e., C files) # gzip support sources (i.e., C files)
@@ -33,12 +37,16 @@ GZIP_DRV_SRC := $(GZIP_DIR_)ftgzip.c
GZIP_DRV_H := GZIP_DRV_H :=
# Pfr driver object(s) # gzip driver object(s)
# #
# GZIP_DRV_OBJ_M is used during `multi' builds # GZIP_DRV_OBJ_M is used during `multi' builds
# GZIP_DRV_OBJ_S is used during `single' builds # GZIP_DRV_OBJ_S is used during `single' builds
# #
ifeq ($(SYSTEM_ZLIB),)
GZIP_DRV_OBJ_M := $(GZIP_DRV_SRC:$(GZIP_DIR_)%.c=$(OBJ_)%.$O) 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_DRV_OBJ_S := $(OBJ_)ftgzip.$O
# gzip support source file for single build # 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 * 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 #ifndef _ZCONF_H
#define _ZCONF_H #define _ZCONF_H
@@ -91,11 +91,14 @@
# define NO_DUMMY_DECL # define NO_DUMMY_DECL
#endif #endif
/* Old Borland C incorrectly complains about missing returns: */ /* Old Borland C and LCC incorrectly complains about missing returns: */
#if defined(__BORLANDC__) && (__BORLANDC__ < 0x500) #if defined(__BORLANDC__) && (__BORLANDC__ < 0x500)
# define NEED_DUMMY_RETURN # define NEED_DUMMY_RETURN
#endif #endif
#if defined(__LCC__)
# define NEED_DUMMY_RETURN
#endif
/* Maximum value for memLevel in deflateInit2 */ /* Maximum value for memLevel in deflateInit2 */
#ifndef MAX_MEM_LEVEL #ifndef MAX_MEM_LEVEL
@@ -167,22 +170,22 @@
# undef FAR # undef FAR
# endif # endif
# include <windows.h> # include <windows.h>
# define ZEXPORT WINAPI # define ZEXPORT(x) x WINAPI
# ifdef WIN32 # ifdef WIN32
# define ZEXPORTVA WINAPIV # define ZEXPORTVA(x) x WINAPIV
# else # else
# define ZEXPORTVA FAR _cdecl _export # define ZEXPORTVA(x) x FAR _cdecl _export
# endif # endif
# endif # endif
# if defined (__BORLANDC__) # if defined (__BORLANDC__)
# if (__BORLANDC__ >= 0x0500) && defined (WIN32) # if (__BORLANDC__ >= 0x0500) && defined (WIN32)
# include <windows.h> # include <windows.h>
# define ZEXPORT __declspec(dllexport) WINAPI # define ZEXPORT(x) x __declspec(dllexport) WINAPI
# define ZEXPORTRVA __declspec(dllexport) WINAPIV # define ZEXPORTRVA(x) x __declspec(dllexport) WINAPIV
# else # else
# if defined (_Windows) && defined (__DLL__) # if defined (_Windows) && defined (__DLL__)
# define ZEXPORT _export # define ZEXPORT(x) x _export
# define ZEXPORTVA _export # define ZEXPORTVA(x) x _export
# endif # endif
# endif # endif
# endif # endif
@@ -190,16 +193,16 @@
#ifndef ZEXPORT #ifndef ZEXPORT
# define ZEXPORT # define ZEXPORT(x) static x
#endif #endif
#ifndef ZEXPORTVA #ifndef ZEXPORTVA
# define ZEXPORTVA # define ZEXPORTVA(x) static x
#endif #endif
#ifndef ZEXTERN #ifndef ZEXTERN
# define ZEXTERN static # define ZEXTERN(x) static x
#endif #endif
#ifndef ZEXTERNDEF #ifndef ZEXTERNDEF
# define ZEXTERNDEF static # define ZEXTERNDEF(x) static x
#endif #endif
#ifndef FAR #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 Initializes the internal stream state for compression. The fields
zalloc, zfree and opaque must be initialized before by the caller. 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 Initializes the internal stream state for decompression. The fields
next_in, avail_in, zalloc, zfree and opaque must be initialized before by 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 inflate decompresses as much data as possible, and stops when the input
buffer becomes empty or the output buffer becomes full. It may some 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. All dynamically allocated data structures for this stream are freed.
This function discards any unprocessed input and does not flush any 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 level,
int method, int method,
int windowBits, 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)); int windowBits));
This is another version of inflateInit with an extra parameter. The 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. 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, This function is equivalent to inflateEnd followed by inflateInit,
but does not free and reallocate all the internal decompression state. 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. 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 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 /* deflateInit and inflateInit are macros to allow checking the zlib version
* and the compiler's view of z_stream: * 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)); const char *version, int stream_size));
#define deflateInit(strm, level) \ #define deflateInit(strm, level) \
deflateInit_((strm), (level), ZLIB_VERSION, sizeof(z_stream)) 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 * 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" #include "zutil.h"
+2 -2
View File
@@ -8,7 +8,7 @@
subject to change. Applications should only use zlib.h. 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 #ifndef _Z_UTIL_H
#define _Z_UTIL_H #define _Z_UTIL_H
@@ -203,7 +203,7 @@ typedef unsigned long ulg;
#endif #endif
typedef uLong (ZEXPORT *check_func) OF((uLong check, const Bytef *buf, typedef uLong (*check_func) OF((uLong check, const Bytef *buf,
uInt len)); uInt len));
local voidpf zcalloc OF((voidpf opaque, unsigned items, unsigned size)); local voidpf zcalloc OF((voidpf opaque, unsigned items, unsigned size));
local void zcfree OF((voidpf opaque, voidpf ptr)); 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','e','n','g', "Bengali", BENGALI )
OTL_SCRIPT_TAG( 'b','o','p','o', "Bopomofo", BOPOMOFO ) OTL_SCRIPT_TAG( 'b','o','p','o', "Bopomofo", BOPOMOFO )
OTL_SCRIPT_TAG( 'b','r','a','i', "Braille", BRAILLE ) 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','a','n','s', "Canadian Syllabic", CANADIAN )
OTL_SCRIPT_TAG( 'c','h','e','r', "Cherokee", CHEROKEE ) OTL_SCRIPT_TAG( 'c','h','e','r', "Cherokee", CHEROKEE )
OTL_SCRIPT_TAG( 'h','a','n','i', "CJK Ideographic", CJK ) OTL_SCRIPT_TAG( 'h','a','n','i', "CJK Ideographic", CJK )
OTL_SCRIPT_TAG( 'c','y','r','l', "Cyrillic", CYRILLIC ) 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( 'd','e','v','a', "Devanagari", DEVANAGARI )
OTL_SCRIPT_TAG( 'e','t','h','i', "Ethiopic", ETHIOPIC ) OTL_SCRIPT_TAG( 'e','t','h','i', "Ethiopic", ETHIOPIC )
OTL_SCRIPT_TAG( 'g','e','o','r', "Georgian", GEORGIAN ) 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( 'j','a','m','o', "Hangul Jamo", JAMO )
OTL_SCRIPT_TAG( 'h','a','n','g', "Hangul", HANGUL ) OTL_SCRIPT_TAG( 'h','a','n','g', "Hangul", HANGUL )
OTL_SCRIPT_TAG( 'h','e','b','r', "Hebrew", HEBREW ) 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','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( 'k','h','m','r', "Khmer", KHMER )
OTL_SCRIPT_TAG( 'l','a','o',' ', "Lao", LAO ) OTL_SCRIPT_TAG( 'l','a','o',' ', "Lao", LAO )
OTL_SCRIPT_TAG( 'l','a','t','n', "Latin", LATIN ) 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_load_font( FT_Stream,
PCF_Face ); PCF_Face );
FT_END_HEADER FT_END_HEADER
#endif /* __PCF_H__ */ #endif /* __PCF_H__ */
+48 -4
View File
@@ -32,10 +32,12 @@ THE SOFTWARE.
#include FT_INTERNAL_OBJECTS_H #include FT_INTERNAL_OBJECTS_H
#include FT_GZIP_H #include FT_GZIP_H
#include FT_ERRORS_H #include FT_ERRORS_H
#include FT_BDF_H
#include "pcf.h" #include "pcf.h"
#include "pcfdriver.h" #include "pcfdriver.h"
#include "pcfutil.h" #include "pcfutil.h"
#include "pcfread.h"
#include "pcferror.h" #include "pcferror.h"
@@ -353,7 +355,6 @@ THE SOFTWARE.
PCF_Face face = (PCF_Face)FT_SIZE_FACE( size ); PCF_Face face = (PCF_Face)FT_SIZE_FACE( size );
FT_Stream stream = face->root.stream; FT_Stream stream = face->root.stream;
FT_Error error = PCF_Err_Ok; FT_Error error = PCF_Err_Ok;
FT_Memory memory = FT_FACE( face )->memory;
FT_Bitmap* bitmap = &slot->bitmap; FT_Bitmap* bitmap = &slot->bitmap;
PCF_Metric metric; PCF_Metric metric;
int bytes; int bytes;
@@ -409,7 +410,8 @@ THE SOFTWARE.
/* XXX: to do: are there cases that need repadding the bitmap? */ /* XXX: to do: are there cases that need repadding the bitmap? */
bytes = bitmap->pitch * bitmap->rows; bytes = bitmap->pitch * bitmap->rows;
if ( FT_ALLOC( bitmap->buffer, bytes ) ) error = ft_glyphslot_alloc_bitmap( slot, bytes );
if ( error )
goto Exit; goto Exit;
if ( FT_STREAM_SEEK( metric->bits ) || if ( FT_STREAM_SEEK( metric->bits ) ||
@@ -449,7 +451,6 @@ THE SOFTWARE.
slot->linearHoriAdvance = (FT_Fixed)bitmap->width << 16; slot->linearHoriAdvance = (FT_Fixed)bitmap->width << 16;
slot->format = FT_GLYPH_FORMAT_BITMAP; slot->format = FT_GLYPH_FORMAT_BITMAP;
slot->flags = FT_GLYPH_OWN_BITMAP;
FT_TRACE4(( " --- ok\n" )); 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 FT_CALLBACK_TABLE_DEF
const FT_Driver_ClassRec pcf_driver_class = const FT_Driver_ClassRec pcf_driver_class =
{ {
@@ -473,7 +517,7 @@ THE SOFTWARE.
(FT_Module_Constructor)0, (FT_Module_Constructor)0,
(FT_Module_Destructor) 0, (FT_Module_Destructor) 0,
(FT_Module_Requester) 0 (FT_Module_Requester) pcf_driver_requester
}, },
sizeof( PCF_FaceRec ), sizeof( PCF_FaceRec ),
+2 -1
View File
@@ -33,6 +33,7 @@ THE SOFTWARE.
#include "pcf.h" #include "pcf.h"
#include "pcfdriver.h" #include "pcfdriver.h"
#include "pcfread.h"
#include "pcferror.h" #include "pcferror.h"
@@ -316,7 +317,7 @@ THE SOFTWARE.
}; };
static PCF_Property FT_LOCAL_DEF( PCF_Property )
pcf_find_property( PCF_Face face, pcf_find_property( PCF_Face face,
const FT_String* prop ) const FT_String* prop )
{ {
+123 -3
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 ) FT_CALLBACK_DEF( FT_Error )
pfr_extra_item_load_font_id( FT_Byte* p, pfr_extra_item_load_font_id( FT_Byte* p,
FT_Byte* limit, 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 ) FT_LOCAL_DEF( void )
pfr_phy_font_done( PFR_PhyFont phy_font, pfr_phy_font_done( PFR_PhyFont phy_font,
FT_Memory memory ) 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 ); FT_FREE( phy_font->vertical.stem_snaps );
phy_font->vertical.num_stem_snaps = 0; phy_font->vertical.num_stem_snaps = 0;
@@ -736,6 +787,7 @@
} }
FT_LOCAL_DEF( FT_Error ) FT_LOCAL_DEF( FT_Error )
pfr_phy_font_load( PFR_PhyFont phy_font, pfr_phy_font_load( PFR_PhyFont phy_font,
FT_Stream stream, FT_Stream stream,
@@ -790,13 +842,81 @@
goto Fail; 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 ); PFR_CHECK( 3 );
num_aux = PFR_NEXT_ULONG( p ); num_aux = PFR_NEXT_ULONG( p );
if ( num_aux > 0 )
{
FT_Byte* q = p;
FT_Byte* q2;
PFR_CHECK( num_aux ); PFR_CHECK( num_aux );
p += 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 */ /* read the blue values */
{ {
FT_UInt n, count; FT_UInt n, count;
+45 -1
View File
@@ -41,10 +41,17 @@
FT_LOCAL_DEF( void ) FT_LOCAL_DEF( void )
pfr_face_done( PFR_Face face ) 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 */ /* finalize the physical font record */
pfr_phy_font_done( &face->phy_font, FT_FACE_MEMORY( face ) ); pfr_phy_font_done( &face->phy_font, FT_FACE_MEMORY( face ) );
/* no need to finalize the logical font or the header */ /* 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 ) if ( phy_font->num_kern_pairs > 0 )
root->face_flags |= FT_FACE_FLAG_KERNING; root->face_flags |= FT_FACE_FLAG_KERNING;
/* 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; root->family_name = phy_font->font_id;
root->style_name = NULL; /* no style name in font file */
/* 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->num_fixed_sizes = 0;
root->available_sizes = 0; root->available_sizes = 0;
@@ -150,6 +167,27 @@
( ( ( root->ascender - root->descender ) * 12 ) ( ( ( root->ascender - root->descender ) * 12 )
/ 10 ); / 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 */ /* now compute maximum advance width */
if ( ( phy_font->flags & PFR_PHY_PROPORTIONAL ) == 0 ) if ( ( phy_font->flags & PFR_PHY_PROPORTIONAL ) == 0 )
root->max_advance_width = (FT_Short)phy_font->standard_advance; root->max_advance_width = (FT_Short)phy_font->standard_advance;
@@ -255,6 +293,12 @@
goto Exit; goto Exit;
} }
if ( load_flags & FT_LOAD_SBITS_ONLY )
{
error = FT_Err_Invalid_Argument;
goto Exit;
}
gchar = face->phy_font.chars + gindex; gchar = face->phy_font.chars + gindex;
slot->root.format = FT_GLYPH_FORMAT_OUTLINE; slot->root.format = FT_GLYPH_FORMAT_OUTLINE;
outline->n_points = 0; outline->n_points = 0;
+10 -11
View File
@@ -49,7 +49,7 @@
static void static void
pfr_bitwriter_init( PFR_BitWriter writer, pfr_bitwriter_init( PFR_BitWriter writer,
FT_Bitmap* target, FT_Bitmap* target,
FT_Bool decreasing ) FT_UInt decreasing )
{ {
writer->line = target->buffer; writer->line = target->buffer;
writer->pitch = target->pitch; writer->pitch = target->pitch;
@@ -107,7 +107,7 @@
} }
else if ( mask == 0 ) else if ( mask == 0 )
{ {
cur[0] = c; cur[0] = (FT_Byte)c;
mask = 0x80; mask = 0x80;
c = 0; c = 0;
cur ++; cur ++;
@@ -115,7 +115,7 @@
} }
if ( mask != 0x80 ) if ( mask != 0x80 )
cur[0] = c; cur[0] = (FT_Byte) c;
} }
@@ -185,7 +185,7 @@
} }
else if ( mask == 0 ) else if ( mask == 0 )
{ {
cur[0] = c; cur[0] = (FT_Byte) c;
mask = 0x80; mask = 0x80;
c = 0; c = 0;
cur ++; cur ++;
@@ -249,7 +249,7 @@
} }
else if ( mask == 0 ) else if ( mask == 0 )
{ {
cur[0] = c; cur[0] = (FT_Byte) c;
c = 0; c = 0;
mask = 0x80; mask = 0x80;
cur ++; cur ++;
@@ -281,7 +281,7 @@
FT_ULong* found_size ) FT_ULong* found_size )
{ {
FT_UInt left, right, char_len; FT_UInt left, right, char_len;
FT_Bool two = flags & 1; FT_Bool two = FT_BOOL( flags & 1 );
FT_Byte* buff; FT_Byte* buff;
@@ -583,7 +583,7 @@
pfr_lookup_bitmap_data( stream->cursor, pfr_lookup_bitmap_data( stream->cursor,
stream->limit, stream->limit,
strike->num_bitmaps, strike->num_bitmaps,
strike->flags, (FT_Byte) strike->flags,
character->char_code, character->char_code,
&gps_offset, &gps_offset,
&gps_size ); &gps_size );
@@ -645,11 +645,10 @@
/* Allocate and read bitmap data */ /* Allocate and read bitmap data */
{ {
FT_Memory memory = face->root.memory; FT_ULong len = glyph->root.bitmap.pitch * ysize;
FT_Long len = glyph->root.bitmap.pitch * ysize;
error = ft_glyphslot_alloc_bitmap( &glyph->root, len );
if ( !FT_ALLOC( glyph->root.bitmap.buffer, len ) ) if ( !error )
{ {
error = pfr_load_bitmap_bits( p, error = pfr_load_bitmap_bits( p,
stream->limit, stream->limit,
+6
View File
@@ -231,10 +231,16 @@ FT_BEGIN_HEADER
FT_UInt flags; FT_UInt flags;
FT_UInt standard_advance; 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 horizontal;
PFR_DimensionRec vertical; PFR_DimensionRec vertical;
FT_String* font_id; FT_String* font_id;
FT_String* family_name;
FT_String* style_name;
FT_UInt num_strikes; FT_UInt num_strikes;
FT_UInt max_strikes; FT_UInt max_strikes;
+3
View File
@@ -111,7 +111,10 @@
/* allocate new base block */ /* allocate new base block */
if ( FT_ALLOC( table->block, new_size ) ) if ( FT_ALLOC( table->block, new_size ) )
{
table->block = old_base;
return error; return error;
}
/* copy elements and shift offsets */ /* copy elements and shift offsets */
if (old_base ) if (old_base )
+205 -4
View File
@@ -332,6 +332,7 @@
/*************************************************************************/ /*************************************************************************/
/*************************************************************************/ /*************************************************************************/
#if 1
static FT_Pos static FT_Pos
psh3_dimension_quantize_len( PSH_Dimension dim, psh3_dimension_quantize_len( PSH_Dimension dim,
FT_Pos len, FT_Pos len,
@@ -380,6 +381,7 @@
return len; return len;
} }
#endif /* 0 */
#ifdef DEBUG_HINTER #ifdef DEBUG_HINTER
@@ -456,7 +458,9 @@
return; 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 ) || do_snapping = ( dimension == 0 && glyph->do_horz_snapping ) ||
( dimension == 1 && glyph->do_vert_snapping ); ( dimension == 1 && glyph->do_vert_snapping );
@@ -516,18 +520,30 @@
hint->cur_pos = pos; hint->cur_pos = pos;
hint->cur_len = fit_len; hint->cur_len = fit_len;
/* stem adjustment tries to snap stem widths to standard
* ones. this is important to prevent unpleasant rounding
* artefacts...
*/
if ( glyph->do_stem_adjust )
{
if ( len <= 64 ) if ( len <= 64 )
{ {
/* the stem is less than one pixel, we will center it */ /* the stem is less than one pixel, we will center it
/* around the nearest pixel center */ * around the nearest pixel center
/* */ */
#if 1
pos = ( pos + (len >> 1) ) & -64;
#else
/* this seems to be a bug !! */
pos = ( pos + ( (len >> 1) & -64 ) ); pos = ( pos + ( (len >> 1) & -64 ) );
#endif
len = 64; len = 64;
} }
else else
{ {
len = psh3_dimension_quantize_len( dim, len, 0 ); len = psh3_dimension_quantize_len( dim, len, 0 );
} }
}
/* now that we have a good hinted stem width, try to position */ /* now that we have a good hinted stem width, try to position */
/* the stem along a pixel grid integer coordinate */ /* the stem along a pixel grid integer coordinate */
@@ -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 static void
psh3_hint_table_align_hints( PSH3_Hint_Table table, psh3_hint_table_align_hints( PSH3_Hint_Table table,
PSH_Globals globals, PSH_Globals globals,
@@ -1720,6 +1919,8 @@
glyph->do_vert_snapping = FT_BOOL( hint_mode == FT_RENDER_MODE_MONO || glyph->do_vert_snapping = FT_BOOL( hint_mode == FT_RENDER_MODE_MONO ||
hint_mode == FT_RENDER_MODE_LCD_V ); 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++ ) for ( dimension = 0; dimension < 2; dimension++ )
{ {
/* load outline coordinates into glyph */ /* load outline coordinates into glyph */
+1
View File
@@ -221,6 +221,7 @@ FT_BEGIN_HEADER
FT_Bool do_vert_hints; FT_Bool do_vert_hints;
FT_Bool do_horz_snapping; FT_Bool do_horz_snapping;
FT_Bool do_vert_snapping; FT_Bool do_vert_snapping;
FT_Bool do_stem_adjust;
} PSH3_GlyphRec, *PSH3_Glyph; } PSH3_GlyphRec, *PSH3_Glyph;
+3
View File
@@ -228,6 +228,9 @@
if ( ft_strcmp( module_interface, "get_sfnt" ) == 0 ) if ( ft_strcmp( module_interface, "get_sfnt" ) == 0 )
return (FT_Module_Interface)get_sfnt_table; 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 #ifdef TT_CONFIG_OPTION_POSTSCRIPT_NAMES
if ( ft_strcmp( module_interface, "glyph_name" ) == 0 ) if ( ft_strcmp( module_interface, "glyph_name" ) == 0 )
return (FT_Module_Interface)get_sfnt_glyph_name; return (FT_Module_Interface)get_sfnt_glyph_name;
+23 -2
View File
@@ -213,7 +213,14 @@
has_head = 1; 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_STREAM_SEEK( table.Offset + 12 ) ||
FT_READ_ULONG( magic ) || FT_READ_ULONG( magic ) ||
magic != 0x5F0F3CF5UL ) magic != 0x5F0F3CF5UL )
@@ -831,6 +838,20 @@
error = face->goto_table( face, TTAG_hmtx, stream, &table_len ); error = face->goto_table( face, TTAG_hmtx, stream, &table_len );
if ( error ) 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" )); FT_ERROR(( " no horizontal metrics in file!\n" ));
error = SFNT_Err_Hmtx_Table_Missing; error = SFNT_Err_Hmtx_Table_Missing;
goto Exit; goto Exit;
@@ -1085,7 +1106,7 @@
if ( FT_STREAM_READ_FIELDS( name_table_fields, table ) ) if ( FT_STREAM_READ_FIELDS( name_table_fields, table ) )
goto Exit; 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 */ /* (it should be at least "6 + 12*num_names"). However, the string */
/* offsets, computed as "storageOffset + entry->stringOffset", are */ /* offsets, computed as "storageOffset + entry->stringOffset", are */
/* valid pointers within the name table... */ /* valid pointers within the name table... */
+14 -21
View File
@@ -1212,13 +1212,15 @@
TT_SBit_Range range, TT_SBit_Range range,
FT_ULong ebdt_pos, FT_ULong ebdt_pos,
FT_ULong glyph_offset, FT_ULong glyph_offset,
FT_Bitmap* map, FT_GlyphSlot slot,
FT_Int x_offset, FT_Int x_offset,
FT_Int y_offset, FT_Int y_offset,
FT_Stream stream, FT_Stream stream,
TT_SBit_Metrics metrics ) TT_SBit_Metrics metrics,
FT_Int depth )
{ {
FT_Memory memory = stream->memory; FT_Memory memory = stream->memory;
FT_Bitmap* map = &slot->bitmap;
FT_Error error; FT_Error error;
@@ -1230,11 +1232,10 @@
if ( error ) if ( error )
goto Exit; goto Exit;
/* this function is recursive. At the top-level call, the */ /* this function is recursive. At the top-level call, we */
/* field map.buffer is NULL. We thus begin by finding the */ /* compute the dimensions of the higher-level glyph to */
/* dimensions of the higher-level glyph to allocate the */ /* allocate the final pixmap buffer */
/* final pixmap buffer */ if ( depth == 0 )
if ( map->buffer == 0 )
{ {
FT_Long size; FT_Long size;
@@ -1274,7 +1275,8 @@
if ( size == 0 ) if ( size == 0 )
goto Exit; /* exit successfully! */ goto Exit; /* exit successfully! */
if ( FT_ALLOC( map->buffer, size ) ) error = ft_glyphslot_alloc_bitmap( slot, size );
if (error)
goto Exit; goto Exit;
} }
@@ -1348,11 +1350,12 @@
elem_range, elem_range,
ebdt_pos, ebdt_pos,
elem_offset, elem_offset,
map, slot,
x_offset + comp->x_offset, x_offset + comp->x_offset,
y_offset + comp->y_offset, y_offset + comp->y_offset,
stream, stream,
&elem_metrics ); &elem_metrics,
depth+1 );
if ( error ) if ( error )
goto Fail_Memory; goto Fail_Memory;
} }
@@ -1409,7 +1412,6 @@
TT_SBit_MetricsRec *metrics ) TT_SBit_MetricsRec *metrics )
{ {
FT_Error error; FT_Error error;
FT_Memory memory = stream->memory;
FT_ULong ebdt_pos, glyph_offset; FT_ULong ebdt_pos, glyph_offset;
TT_SBit_Strike strike; TT_SBit_Strike strike;
@@ -1432,20 +1434,11 @@
ebdt_pos = FT_STREAM_POS(); 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, 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 ) if ( error )
goto Exit; goto Exit;
/* the glyph slot owns this bitmap buffer */
face->root.glyph->flags |= FT_GLYPH_OWN_BITMAP;
/* setup vertical metrics if needed */ /* setup vertical metrics if needed */
if ( strike->flags & 1 ) if ( strike->flags & 1 )
{ {
+4 -4
View File
@@ -857,7 +857,7 @@
if ( y < min ) min = y; if ( y < min ) min = y;
if ( y > max ) max = 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; goto Draw;
gray_split_conic( arc ); gray_split_conic( arc );
@@ -1827,9 +1827,9 @@
gray_convert_glyph( RAS_ARG ) gray_convert_glyph( RAS_ARG )
{ {
TBand bands[40]; TBand bands[40];
volatile TBand* band; TBand* volatile band;
volatile int n, num_bands; int volatile n, num_bands;
volatile TPos min, max, max_y; TPos volatile min, max, max_y;
FT_BBox* clip; FT_BBox* clip;
+23 -15
View File
@@ -191,31 +191,38 @@
FT_UInt vert_resolution ) FT_UInt vert_resolution )
{ {
FT_Size_Metrics* metrics = &size->root.metrics; FT_Size_Metrics* metrics = &size->root.metrics;
FT_Size_Metrics* metrics2 = &size->metrics;
TT_Face face = (TT_Face)size->root.face; TT_Face face = (TT_Face)size->root.face;
FT_Long dim_x, dim_y; FT_Long dim_x, dim_y;
*metrics2 = *metrics;
/* This bit flag, when set, indicates that the pixel size must be */ /* This bit flag, when set, indicates that the pixel size must be */
/* truncated to an integer. Nearly all TrueType fonts have this */ /* truncated to an integer. Nearly all TrueType fonts have this */
/* bit set, as hinting won't work really well otherwise. */ /* bit set, as hinting won't work really well otherwise. */
/* */ /* */
/* However, for those rare fonts who do not set it, we override */ if ( ( face->header.Flags & 8 ) != 0 )
/* 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 )
{ {
/* Compute pixel sizes in 26.6 units */ /* we need to use rounding in the following computations. Otherwise,
dim_x = ( char_width * horz_resolution + 36 ) / 72; * the resulting hinted outlines will be very slightly distorted
dim_y = ( char_height * vert_resolution + 36 ) / 72; */
dim_x = ( ( char_width * horz_resolution + (36+32*72) ) / 72 ) & -64;
metrics->x_scale = FT_DivFix( dim_x, face->root.units_per_EM ); dim_y = ( ( char_height * vert_resolution + (36+32*72) ) / 72 ) & -64;
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 );
} }
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; size->ttmetrics.valid = FALSE;
#ifdef TT_CONFIG_OPTION_EMBEDDED_BITMAPS #ifdef TT_CONFIG_OPTION_EMBEDDED_BITMAPS
@@ -256,6 +263,7 @@
/* many things have been pre-computed by the base layer */ /* many things have been pre-computed by the base layer */
size->metrics = size->root.metrics;
size->ttmetrics.valid = FALSE; size->ttmetrics.valid = FALSE;
#ifdef TT_CONFIG_OPTION_EMBEDDED_BITMAPS #ifdef TT_CONFIG_OPTION_EMBEDDED_BITMAPS
size->strike_index = 0xFFFF; size->strike_index = 0xFFFF;
+68 -53
View File
@@ -58,6 +58,15 @@
#define UNSCALED_COMPONENT_OFFSET 0x1000 #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> */ /* <Function> */
@@ -747,7 +756,8 @@
/* */ /* */
static FT_Error static FT_Error
load_truetype_glyph( TT_Loader loader, load_truetype_glyph( TT_Loader loader,
FT_UInt glyph_index ) FT_UInt glyph_index,
FT_UInt recurse_count )
{ {
#ifdef TT_CONFIG_OPTION_BYTECODE_INTERPRETER #ifdef TT_CONFIG_OPTION_BYTECODE_INTERPRETER
@@ -769,6 +779,11 @@
FT_Bool glyph_data_loaded = 0; FT_Bool glyph_data_loaded = 0;
#endif #endif
if ( recurse_count >= TT_MAX_COMPOSITE_RECURSE )
{
error = TT_Err_Invalid_Composite;
goto Exit;
}
/* check glyph index */ /* check glyph index */
if ( glyph_index >= (FT_UInt)face->root.num_glyphs ) if ( glyph_index >= (FT_UInt)face->root.num_glyphs )
@@ -793,42 +808,33 @@
FT_Short left_bearing = 0; FT_Short left_bearing = 0;
FT_UShort advance_width = 0; FT_UShort advance_width = 0;
#ifdef FT_CONFIG_OPTION_INCREMENTAL Get_HMetrics( face, glyph_index,
FT_Bool metrics_found = FALSE; (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 */ /* If this is an incrementally loaded font see if there are */
/* overriding metrics for this glyph. */ /* overriding metrics for this glyph. */
if ( face->root.internal->incremental_interface && if ( face->root.internal->incremental_interface &&
face->root.internal->incremental_interface->funcs->get_glyph_metrics ) 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( error = face->root.internal->incremental_interface->funcs->get_glyph_metrics(
face->root.internal->incremental_interface->object, face->root.internal->incremental_interface->object,
glyph_index, FALSE, &m, &metrics_found ); glyph_index, FALSE, &metrics );
if ( error ) if ( error )
goto Exit; goto Exit;
left_bearing = (FT_Short)m.bearing_x; left_bearing = (FT_Short)metrics.bearing_x;
advance_width = (FT_UShort)m.advance; 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 */ #endif /* FT_CONFIG_OPTION_INCREMENTAL */
loader->left_bearing = left_bearing; loader->left_bearing = left_bearing;
@@ -985,7 +991,7 @@
/***********************************************************************/ /***********************************************************************/
/* otherwise, load a composite! */ /* otherwise, load a composite! */
else else if ( contours_count == -1 )
{ {
TT_GlyphSlot glyph = (TT_GlyphSlot)loader->glyph; TT_GlyphSlot glyph = (TT_GlyphSlot)loader->glyph;
FT_UInt start_point; FT_UInt start_point;
@@ -1059,7 +1065,8 @@
num_base_points = gloader->base.outline.n_points; 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 ) if ( error )
goto Fail; goto Fail;
@@ -1310,7 +1317,6 @@
exec->is_composite = TRUE; exec->is_composite = TRUE;
exec->pedantic_hinting = exec->pedantic_hinting =
(FT_Bool)( loader->load_flags & FT_LOAD_PEDANTIC ); (FT_Bool)( loader->load_flags & FT_LOAD_PEDANTIC );
error = TT_Run_Context( exec, ((TT_Size)loader->size)->debug ); error = TT_Run_Context( exec, ((TT_Size)loader->size)->debug );
if ( error && exec->pedantic_hinting ) if ( error && exec->pedantic_hinting )
goto Fail; goto Fail;
@@ -1326,6 +1332,12 @@
} }
/* end of composite loading */ /* 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 left; /* scaled vertical left side bearing */
FT_Pos top; /* scaled vertical top side bearing */ FT_Pos top; /* scaled vertical top side bearing */
FT_Pos advance; /* scaled vertical advance height */ 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. */ /* Get the unscaled top bearing and advance height. */
if ( !metrics_found && face->vertical_info && if ( face->vertical_info &&
face->vertical.number_Of_VMetrics > 0 ) face->vertical.number_Of_VMetrics > 0 )
{ {
/* Don't assume that both the vertical header and vertical */ /* 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 */ /* 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(). */ /* FT_Get_Outline_CBox(). */
/* scale the metrics */ /* scale the metrics */
@@ -1757,7 +1772,7 @@
glyph->format = FT_GLYPH_FORMAT_OUTLINE; glyph->format = FT_GLYPH_FORMAT_OUTLINE;
glyph->num_subglyphs = 0; glyph->num_subglyphs = 0;
error = load_truetype_glyph( &loader, glyph_index ); error = load_truetype_glyph( &loader, glyph_index, 0 );
if ( !error ) if ( !error )
compute_glyph_metrics( &loader, glyph_index ); compute_glyph_metrics( &loader, glyph_index );
+1 -1
View File
@@ -568,7 +568,7 @@
exec->FDefs = size->function_defs; exec->FDefs = size->function_defs;
exec->IDefs = size->instruction_defs; exec->IDefs = size->instruction_defs;
exec->tt_metrics = size->ttmetrics; exec->tt_metrics = size->ttmetrics;
exec->metrics = size->root.metrics; exec->metrics = size->metrics;
exec->maxFunc = size->max_func; exec->maxFunc = size->max_func;
exec->maxIns = size->max_ins; exec->maxIns = size->max_ins;
+10 -6
View File
@@ -70,7 +70,8 @@
{ {
FT_Memory memory = zone->memory; FT_Memory memory = zone->memory;
if ( memory )
{
FT_FREE( zone->contours ); FT_FREE( zone->contours );
FT_FREE( zone->tags ); FT_FREE( zone->tags );
FT_FREE( zone->cur ); FT_FREE( zone->cur );
@@ -78,6 +79,8 @@
zone->max_points = zone->n_points = 0; zone->max_points = zone->n_points = 0;
zone->max_contours = zone->n_contours = 0; zone->max_contours = zone->n_contours = 0;
zone->memory = NULL;
}
} }
@@ -541,7 +544,7 @@
face = (TT_Face)size->root.face; face = (TT_Face)size->root.face;
metrics = &size->root.metrics; metrics = &size->metrics;
if ( metrics->x_ppem < 1 || metrics->y_ppem < 1 ) if ( metrics->x_ppem < 1 || metrics->y_ppem < 1 )
return TT_Err_Invalid_PPem; return TT_Err_Invalid_PPem;
@@ -568,14 +571,15 @@
/* Compute root ascender, descender, test height, and max_advance */ /* Compute root ascender, descender, test height, and max_advance */
metrics->ascender = ( FT_MulFix( face->root.ascender, 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->descender = ( FT_MulFix( face->root.descender,
metrics->y_scale ) + 0 ) & -64; metrics->y_scale ) + 32 ) & -64;
metrics->height = ( FT_MulFix( face->root.height, 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->max_advance = ( FT_MulFix( face->root.max_advance_width,
metrics->x_scale ) + 32 ) & -64; metrics->x_scale ) + 32 ) & -64;
#ifdef TT_CONFIG_OPTION_EMBEDDED_BITMAPS #ifdef TT_CONFIG_OPTION_EMBEDDED_BITMAPS
/* set to `invalid' by default */ /* set to `invalid' by default */
size->strike_index = 0xFFFFU; size->strike_index = 0xFFFFU;
@@ -690,7 +694,7 @@
SFNT_Service sfnt; SFNT_Service sfnt;
metrics = &size->root.metrics; metrics = &size->metrics;
if ( size->strike_index != 0xFFFFU ) if ( size->strike_index != 0xFFFFU )
return TT_Err_Ok; return TT_Err_Ok;
+1
View File
@@ -311,6 +311,7 @@ FT_BEGIN_HEADER
{ {
FT_SizeRec root; FT_SizeRec root;
FT_Size_Metrics metrics; /* slightly different from the root metrics */
TT_Size_Metrics ttmetrics; TT_Size_Metrics ttmetrics;
#ifdef TT_CONFIG_OPTION_EMBEDDED_BITMAPS #ifdef TT_CONFIG_OPTION_EMBEDDED_BITMAPS
+7 -9
View File
@@ -76,7 +76,7 @@
glyph_index, char_string ); glyph_index, char_string );
else else
#endif #endif /* FT_CONFIG_OPTION_INCREMENTAL */
/* For ordinary fonts get the character data stored in the face record. */ /* For ordinary fonts get the character data stored in the face record. */
{ {
@@ -95,23 +95,21 @@
if ( !error && face->root.internal->incremental_interface && if ( !error && face->root.internal->incremental_interface &&
face->root.internal->incremental_interface->funcs->get_glyph_metrics ) face->root.internal->incremental_interface->funcs->get_glyph_metrics )
{ {
FT_Bool found = FALSE;
FT_Incremental_MetricsRec 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( error = face->root.internal->incremental_interface->funcs->get_glyph_metrics(
face->root.internal->incremental_interface->object, face->root.internal->incremental_interface->object,
glyph_index, FALSE, &metrics, &found ); glyph_index, FALSE, &metrics );
if ( found )
{
decoder->builder.left_bearing.x = metrics.bearing_x; decoder->builder.left_bearing.x = metrics.bearing_x;
decoder->builder.left_bearing.y = metrics.bearing_y; decoder->builder.left_bearing.y = metrics.bearing_y;
decoder->builder.advance.x = metrics.advance; decoder->builder.advance.x = metrics.advance;
decoder->builder.advance.y = 0; decoder->builder.advance.y = 0;
} }
}
#endif #endif /* FT_CONFIG_OPTION_INCREMENTAL */
return error; return error;
} }
@@ -137,7 +135,7 @@
face->root.internal->incremental_interface->object, face->root.internal->incremental_interface->object,
&glyph_data ); &glyph_data );
} }
#endif #endif /* FT_CONFIG_OPTION_INCREMENTAL */
return error; return error;
} }
+29 -13
View File
@@ -779,16 +779,24 @@
static int 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 */ /* Note: PostScript allows any non-delimiting, non-whitespace */
/* embedded type1 fonts in PDF documents. */ /* in a name (PS Ref Manual, 3rd Ed, p31) */
/* */ /* PostScript delimiters include (,),<,>,[,],{,},/ and % */
return ( ft_isalnum( c ) ||
c == '.' || return ( c != '(' &&
c == '_' || c != ')' &&
c == '-' || c != '<' &&
c == '+' ); c != '>' &&
c != '[' &&
c != ']' &&
c != '{' &&
c != '}' &&
c != '/' &&
c != '%' &&
! is_space( c )
);
} }
@@ -861,7 +869,7 @@
cur++; cur++;
cur2 = cur; cur2 = cur;
while ( cur2 < limit && is_alpha( *cur2 ) ) while ( cur2 < limit && is_name_char( *cur2 ) )
cur2++; cur2++;
len = cur2 - cur; len = cur2 - cur;
@@ -1070,7 +1078,7 @@
FT_PtrDist len; FT_PtrDist len;
while ( cur2 < limit && is_alpha( *cur2 ) ) while ( cur2 < limit && is_name_char( *cur2 ) )
cur2++; cur2++;
len = cur2 - cur - 1; len = cur2 - cur - 1;
@@ -1133,6 +1141,14 @@
/* with synthetic fonts, it's possible we get here twice */ /* with synthetic fonts, it's possible we get here twice */
return; 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 ); loader->num_subrs = (FT_Int)T1_ToInt( parser );
if ( parser->root.error ) if ( parser->root.error )
return; return;
@@ -1304,7 +1320,7 @@
FT_PtrDist len; FT_PtrDist len;
while ( cur2 < limit && is_alpha( *cur2 ) ) while ( cur2 < limit && is_name_char( *cur2 ) )
cur2++; cur2++;
len = cur2 - cur - 1; len = cur2 - cur - 1;
@@ -1564,7 +1580,7 @@
cur++; cur++;
cur2 = cur; cur2 = cur;
while ( cur2 < limit && is_alpha( *cur2 ) ) while ( cur2 < limit && is_name_char( *cur2 ) )
cur2++; cur2++;
len = cur2 - cur; len = cur2 - cur;
+3 -10
View File
@@ -560,17 +560,10 @@
static void static void
ft_glyphslot_clear( FT_GlyphSlot slot ) t42_glyphslot_clear( FT_GlyphSlot slot )
{ {
/* free bitmap if needed */ /* free bitmap if needed */
if ( slot->flags & FT_GLYPH_OWN_BITMAP ) ft_glyphslot_free_bitmap( slot );
{
FT_Memory memory = FT_FACE_MEMORY( slot->face );
FT_FREE( slot->bitmap.buffer );
slot->flags &= ~FT_GLYPH_OWN_BITMAP;
}
/* clear all public fields in the glyph slot */ /* clear all public fields in the glyph slot */
FT_ZERO( &slot->metrics ); FT_ZERO( &slot->metrics );
@@ -603,7 +596,7 @@
FT_Driver_Class ttclazz = ((T42_Driver)glyph->face->driver)->ttclazz; 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, error = ttclazz->load_glyph( t42slot->ttslot,
t42size->ttsize, t42size->ttsize,
glyph_index, glyph_index,
+20 -22
View File
@@ -17,6 +17,7 @@
#include <ft2build.h> #include <ft2build.h>
#include FT_WINFONTS_H
#include FT_INTERNAL_DEBUG_H #include FT_INTERNAL_DEBUG_H
#include FT_INTERNAL_STREAM_H #include FT_INTERNAL_STREAM_H
#include FT_INTERNAL_OBJECTS_H #include FT_INTERNAL_OBJECTS_H
@@ -68,9 +69,9 @@
const FT_Frame_Field winfnt_header_fields[] = const FT_Frame_Field winfnt_header_fields[] =
{ {
#undef FT_STRUCTURE #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_USHORT_LE( version ),
FT_FRAME_ULONG_LE ( file_size ), FT_FRAME_ULONG_LE ( file_size ),
FT_FRAME_BYTES ( copyright, 60 ), FT_FRAME_BYTES ( copyright, 60 ),
@@ -106,7 +107,7 @@
FT_FRAME_USHORT_LE( B_space ), FT_FRAME_USHORT_LE( B_space ),
FT_FRAME_USHORT_LE( C_space ), FT_FRAME_USHORT_LE( C_space ),
FT_FRAME_USHORT_LE( color_table_offset ), FT_FRAME_USHORT_LE( color_table_offset ),
FT_FRAME_BYTES ( reserved, 4 ), FT_FRAME_BYTES ( reserved1, 16 ),
FT_FRAME_END FT_FRAME_END
}; };
@@ -128,7 +129,7 @@
FT_Stream stream ) FT_Stream stream )
{ {
FT_Error error; FT_Error error;
WinFNT_Header header = &font->header; FT_WinFNT_Header header = &font->header;
/* first of all, read the FNT header */ /* first of all, read the FNT header */
@@ -145,6 +146,17 @@
goto Exit; 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 ) if ( header->file_type & 1 )
{ {
FT_TRACE2(( "[can't handle vector FNT fonts]\n" )); FT_TRACE2(( "[can't handle vector FNT fonts]\n" ));
@@ -592,7 +604,7 @@
len = new_format ? 6 : 4; len = new_format ? 6 : 4;
/* jump to glyph entry */ /* 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 ); bitmap->width = FT_NEXT_SHORT_LE( p );
@@ -606,32 +618,18 @@
/* allocate and build bitmap */ /* allocate and build bitmap */
{ {
FT_Memory memory = FT_FACE_MEMORY( slot->face );
FT_Int pitch = ( bitmap->width + 7 ) >> 3; FT_Int pitch = ( bitmap->width + 7 ) >> 3;
FT_Byte* column;
FT_Byte* write;
bitmap->pitch = pitch; bitmap->pitch = pitch;
bitmap->rows = font->header.pixel_height; bitmap->rows = font->header.pixel_height;
bitmap->pixel_mode = FT_PIXEL_MODE_MONO; bitmap->pixel_mode = FT_PIXEL_MODE_MONO;
if ( FT_ALLOC( bitmap->buffer, pitch * bitmap->rows ) ) /* note: we don't allocate a new buffer for the bitmap since we */
goto Exit; /* already store the images in the FT_Face */
ft_glyphslot_set_bitmap( slot, p );
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];
}
} }
slot->flags = FT_GLYPH_OWN_BITMAP;
slot->bitmap_left = 0; slot->bitmap_left = 0;
slot->bitmap_top = font->header.ascent; slot->bitmap_top = font->header.ascent;
slot->format = FT_GLYPH_FORMAT_BITMAP; slot->format = FT_GLYPH_FORMAT_BITMAP;