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