Added FTSmooth patch by David Chester

git-svn-id: file:///srv/svn/repos/haiku/trunk/current@2562 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
DarkWyrm
2003-01-26 21:36:27 +00:00
parent 28bf3daa5d
commit 16b0d71f0b
9 changed files with 251 additions and 44 deletions
@@ -2151,6 +2151,7 @@ FT_BEGIN_HEADER
#define FT_LOAD_TARGET_MONO FT_LOAD_TARGET_( FT_RENDER_MODE_MONO )
#define FT_LOAD_TARGET_LCD FT_LOAD_TARGET_( FT_RENDER_MODE_LCD )
#define FT_LOAD_TARGET_LCD_V FT_LOAD_TARGET_( FT_RENDER_MODE_LCD_V )
#define FT_LOAD_TARGET_SMOOTH FT_LOAD_TARGET_( FT_RENDER_MODE_SMOOTH )
#define FT_LOAD_DEFAULT 0x0
@@ -2239,6 +2240,7 @@ FT_BEGIN_HEADER
FT_RENDER_MODE_MONO,
FT_RENDER_MODE_LCD,
FT_RENDER_MODE_LCD_V,
FT_RENDER_MODE_SMOOTH,
FT_RENDER_MODE_MAX
@@ -321,6 +321,15 @@ FT_BEGIN_HEADER
FT_UInt32 hint_flags;
const char* postscript_name;
FT_F26Dot6 orig_width;
FT_F26Dot6 orig_height;
FT_UInt orig_horz_res;
FT_UInt orig_vert_res;
FT_Fixed orig_x_scale;
FT_Fixed orig_y_scale;
#ifdef FT_CONFIG_OPTION_INCREMENTAL
FT_Incremental_InterfaceRec* incremental_interface;
+1
View File
@@ -32,6 +32,7 @@
{
"THEZOCQS",
"HEZLOCUS",
"fijkdbh",
"xzroesc",
"xzroesc",
"pqgjy"
+2 -1
View File
@@ -33,7 +33,8 @@ FT_BEGIN_HEADER
#define AH_IS_TOP_BLUE( b ) ( (b) == AH_BLUE_CAPITAL_TOP || \
(b) == AH_BLUE_SMALL_TOP )
(b) == AH_BLUE_SMALL_TOP || \
(b) == AH_BLUE_SMALL_F_TOP )
/* compute global metrics automatically */
+5 -2
View File
@@ -1351,7 +1351,10 @@
edge2 = seg2->edge;
if ( is_serif )
{
edge->serif = edge2;
edge2->flags |= AH_EDGE_SERIF;
}
else
edge->link = edge2;
}
@@ -1477,8 +1480,8 @@
/* compute the initial threshold as a fraction of the EM size */
best_dist = FT_MulFix( face_globals->face->units_per_EM / 40, y_scale );
if ( best_dist > 64 / 4 )
best_dist = 64 / 4;
if ( best_dist > 64 / 2 )
best_dist = 64 / 2;
for ( blue = AH_BLUE_CAPITAL_TOP; blue < AH_BLUE_MAX; blue++ )
{
+208 -35
View File
@@ -28,7 +28,9 @@
#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
@@ -91,7 +93,9 @@
static FT_Pos
ah_compute_stem_width( AH_Hinter hinter,
int vertical,
FT_Pos width )
FT_Pos width,
AH_Edge_Flags base_flags,
AH_Edge_Flags stem_flags )
{
AH_Globals globals = &hinter->globals->scaled;
FT_Pos dist = width;
@@ -107,10 +111,20 @@
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;
/* 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 )
dist = 64;
}
else if ( dist < 56 )
dist = 56;
{
FT_Pos delta = dist - globals->stds[vertical];
@@ -124,6 +138,7 @@
dist = globals->stds[vertical];
if ( dist < 48 )
dist = 48;
goto Done_Width;
}
if ( dist < 3 * 64 )
@@ -190,6 +205,9 @@
dist = ( dist + 32 ) & -64;
}
}
Done_Width:
}
if ( sign )
@@ -208,9 +226,13 @@
{
FT_Pos dist = stem_edge->opos - base_edge->opos;
FT_Pos fitted_width = ah_compute_stem_width( hinter,
vertical,
dist,
base_edge->flags,
stem_edge->flags );
stem_edge->pos = base_edge->pos +
ah_compute_stem_width( hinter, vertical, dist );
stem_edge->pos = base_edge->pos + fitted_width;
}
@@ -364,43 +386,120 @@
if ( !anchor )
{
edge->pos = ( edge->opos + 32 ) & -64;
FT_Pos org_len, org_center, cur_len;
FT_Pos cur_pos1, delta1, u_off, d_off;
org_len = edge2->opos - edge->opos;
cur_len = ah_compute_stem_width( hinter, dimension, org_len,
edge->flags, edge2->flags );
if (cur_len <= 64 )
u_off = d_off = 32;
else
{
u_off = 38;
d_off = 26;
}
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 ) ) );
if ( delta1 < 0 )
cur_pos1 -= u_off;
else
cur_pos1 += d_off;
edge->pos = cur_pos1 - cur_len / 2;
edge2->pos = cur_pos1 + cur_len / 2;
}
else
edge->pos = ( edge->opos + 32 ) & -64;
anchor = edge;
edge->flags |= AH_EDGE_DONE;
ah_align_linked_edge( hinter, edge, edge2, dimension );
}
else
{
FT_Pos org_pos, org_len, org_center, cur_len;
FT_Pos cur_pos1, cur_pos2, delta1, delta2;
FT_Pos cur_pos1, cur_pos2, delta1, delta2, u_off, d_off;
org_pos = anchor->pos + (edge->opos - anchor->opos);
org_len = edge2->opos - edge->opos;
org_center = org_pos + ( org_len >> 1 );
cur_len = ah_compute_stem_width( hinter, dimension, org_len );
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 );
if ( delta1 < 0 )
delta1 = -delta1;
if ( cur_len < 96 )
{
cur_pos1 = ( org_center + 32 ) & -64;
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;
if (cur_len <= 64 )
u_off = d_off = 32;
else
{
u_off = 38;
d_off = 26;
}
edge->flags |= AH_EDGE_DONE;
edge2->flags |= AH_EDGE_DONE;
delta1 = ABSVAL( org_center - ( cur_pos1 - u_off ) ) -
ABSVAL( ( org_center - ( cur_pos1 + d_off ) ) );
if ( edge > edges && edge->pos < edge[-1].pos )
edge->pos = edge[-1].pos;
if ( delta1 < 0 )
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
{
org_pos = anchor->pos + (edge->opos - anchor->opos);
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_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;
edge->flags |= AH_EDGE_DONE;
edge2->flags |= AH_EDGE_DONE;
if ( edge > edges && edge->pos < edge[-1].pos )
edge->pos = edge[-1].pos;
}
}
}
@@ -1057,6 +1156,65 @@
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 );
@@ -1160,18 +1318,26 @@
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;
hinter->pp1.x = ( ( new_lsb - old_lsb ) + 32 ) & -64;
hinter->pp2.x = ( ( edge2->pos + old_rsb ) + 32 ) & -64;
/* try to fix certain bad advance computations */
if ( hinter->pp2.x + hinter->pp1.x == edge2->pos && old_rsb > 4 )
hinter->pp2.x += 64;
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;
}
}
/* good, we simply add the glyph to our loader's base */
@@ -1408,8 +1574,14 @@
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 );
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 );
#ifdef DEBUG_HINTER
@@ -1419,8 +1591,9 @@
/* 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 );
hinter->do_horz_snapping = FT_BOOL( hint_mode == FT_RENDER_MODE_MONO ||
hint_mode == FT_RENDER_MODE_LCD ||
hint_mode == FT_RENDER_MODE_SMOOTH );
/* we snap the width of horizontal stems for the monochrome and */
/* vertical LCD rendering targets only. Corresponds to Y snapping. */
+2 -1
View File
@@ -387,7 +387,8 @@ FT_BEGIN_HEADER
#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_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 )
+19 -2
View File
@@ -1298,8 +1298,8 @@
char_height = 1 * 64;
/* Compute pixel sizes in 26.6 units */
dim_x = ( ( ( char_width * horz_resolution ) / 72 ) + 32 ) & -64;
dim_y = ( ( ( char_height * vert_resolution ) / 72 ) + 32 ) & -64;
dim_x = ( ( char_width * horz_resolution ) / 72 ) ;
dim_y = ( ( char_height * vert_resolution ) / 72 ) ;
metrics->x_ppem = (FT_UShort)( dim_x >> 6 );
metrics->y_ppem = (FT_UShort)( dim_y >> 6 );
@@ -1315,6 +1315,15 @@
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,
@@ -1370,6 +1379,14 @@
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,
+3 -3
View File
@@ -568,11 +568,11 @@
/* Compute root ascender, descender, test height, and max_advance */
metrics->ascender = ( FT_MulFix( face->root.ascender,
metrics->y_scale ) + 32 ) & -64;
metrics->y_scale ) + 63 ) & -64;
metrics->descender = ( FT_MulFix( face->root.descender,
metrics->y_scale ) + 32 ) & -64;
metrics->y_scale ) + 0 ) & -64;
metrics->height = ( FT_MulFix( face->root.height,
metrics->y_scale ) + 32 ) & -64;
metrics->y_scale ) + 63 ) & -64;
metrics->max_advance = ( FT_MulFix( face->root.max_advance_width,
metrics->x_scale ) + 32 ) & -64;