* src/pshint/pshglob.c: adding correct BlueScale/BlueShift support,

plus family blues processing

    * src/cff/cffgload.c: started adding support for the Postscript hinter
This commit is contained in:
David Turner 2001-12-12 16:07:29 +00:00
parent 110195a9cf
commit 92827826f9
5 changed files with 169 additions and 18 deletions

View File

@ -1,3 +1,10 @@
2001-12-12 David Turner <david@freetype.org>
* src/pshint/pshglob.c: adding correct BlueScale/BlueShift support,
plus family blues processing
* src/cff/cffgload.c: started adding support for the Postscript hinter
2001-12-12 Werner Lemberg <wl@gnu.org>
* builds/unix/freetype2.m4: Some portability fixes.

View File

@ -23,6 +23,7 @@
#include FT_INTERNAL_SFNT_H
#include FT_OUTLINE_H
#include FT_TRUETYPE_TAGS_H
#include FT_INTERNAL_POSTSCRIPT_HINTS_H
#include "cffload.h"
#include "cffgload.h"
@ -701,6 +702,7 @@
FT_Fixed seed;
FT_Fixed* stack;
T2_Hints_Funcs hinter;
/* set default width */
decoder->num_hints = 0;
@ -720,6 +722,8 @@
zone = decoder->zones;
stack = decoder->top;
hinter = (T2_Hints_Funcs) builder->hints_funcs;
builder->path_begun = 0;
zone->base = charstring_base;
@ -731,6 +735,10 @@
x = builder->pos_x;
y = builder->pos_y;
/* begin hints recording session, if any */
if ( hinter )
hinter->open( hinter->hints );
/* now, execute loop */
while ( ip < limit )
{
@ -1053,24 +1061,41 @@
case cff_op_vstem:
case cff_op_hstemhm:
case cff_op_vstemhm:
/* if the number of arguments is not even, the first one */
/* is simply the glyph width, encoded as the difference */
/* to nominalWidthX */
/* the number of arguments is always even here */
FT_TRACE4(( op == cff_op_hstem ? " hstem" :
op == cff_op_vstem ? " vstem" :
op == cff_op_hstemhm ? " hstemhm" :
" vstemhm" ));
( op == cff_op_vstem ? " vstem" :
( op == cff_op_hstemhm ? " hstemhm" : " vstemhm" )) ));
if ( hinter )
hinter->stems( hinter->hints,
( op == cff_op_vstem || op == cff_op_vstemhm ),
num_args/2,
args );
decoder->num_hints += num_args / 2;
args = stack;
break;
case cff_op_hintmask:
case cff_op_cntrmask:
FT_TRACE4(( op == cff_op_hintmask ? " hintmask"
: " cntrmask" ));
FT_TRACE4(( op == cff_op_hintmask ? " hintmask" : " cntrmask" ));
decoder->num_hints += num_args / 2;
if ( hinter )
{
if ( op == cff_op_hintmask )
hinter->hintmask( hinter->hints,
builder->current->n_points,
(decoder->num_hints+7) >> 3,
ip );
else
hinter->counter( hinter->hints,
(decoder->num_hints+7) >> 3,
ip );
}
#ifdef FT_DEBUG_LEVEL_TRACE
{
FT_UInt maskbyte;
@ -1617,6 +1642,18 @@
close_contour( builder );
/* close hints recording session */
if ( hinter )
{
if (hinter->close( hinter->hints, builder->current->n_points ))
goto Syntax_Error;
/* apply hints to the loaded glyph outline now */
hinter->apply( hinter->hints,
builder->current,
(PSH_Globals)builder->hints_globals );
}
/* add current outline to the glyph slot */
FT_GlyphLoader_Add( builder->loader );

View File

@ -112,6 +112,9 @@ FT_BEGIN_HEADER
FT_Error error; /* only used for memory errors */
FT_Bool metrics_only;
void* hints_funcs; /* hinter-specific */
void* hints_globals; /* hinter-specific */
} CFF_Builder;

View File

@ -345,6 +345,50 @@
FT_UInt num;
PSH_Blue_Table table = 0;
/* */
/* determine wether we need to suppress overshoots or not */
/* we simply need to compare the vertical scale parameter */
/* to the raw bluescale value. Here's why */
/* */
/* we need to suppress overshoots for all pointsizes */
/* at 300dpi that satisfy: */
/* */
/* pointsize < 240*bluescale + 0.49 */
/* */
/* this corresponds to: */
/* */
/* pixelsize < 1000*bluescale + 49/24 */
/* */
/* scale*EM_Size < 1000*bluescale + 49/24 */
/* */
/* however, for normal Type 1 fonts, EM_Size is 1000 !! */
/* we thus only check: */
/* */
/* scale < bluescale + 49/24000 */
/* */
/* which we shorten to */
/* */
/* "scale < bluescale" */
/* */
blues->no_overshoots = FT_BOOL( scale < blues->blue_scale );
/* */
/* the blue threshold is the font units distance under */
/* which overshoots are suppressed due to the BlueShift */
/* even if the scale is greater than BlueScale */
/* */
/* it's the smallest distance such that */
/* */
/* dist <= BlueShift && dist*scale <= 0.5 pixels */
/* */
{
FT_Int threshold = blues->blue_shift;
while ( threshold > 0 && FT_MulFix( threshold, scale ) > 32 )
threshold --;
blues->blue_threshold = threshold;
}
for ( num = 0; num < 4; num++ )
{
@ -388,7 +432,46 @@
}
}
/* XXX: we should process the family / normal tables here! */
/* process the families now */
for ( num = 0; num < 2; num++ )
{
PSH_Blue_Zone zone1, zone2;
FT_UInt count1, count2;
PSH_Blue_Table normal, family;
switch (num)
{
case 0:
normal = &blues->normal_top;
family = &blues->family_top;
break;
default:
normal = &blues->normal_bottom;
family = &blues->family_bottom;
}
zone1 = normal->zones;
count1 = normal->count;
for ( ; count1 > 0; count1--, zone1++ )
{
/* try to find a family zone whose reference position is less */
/* than 1 pixel far from the current zone.. */
zone2 = family->zones;
count2 = family->count;
for ( ; count2 > 0; count2--, zone2++ )
{
if ( FT_MulFix( zone1->org_ref - zone2->org_ref, scale ) < 64 )
{
zone1->cur_top = zone2->cur_top;
zone1->cur_bottom = zone2->cur_bottom;
zone1->cur_ref = zone2->cur_ref;
zone1->cur_delta = zone2->cur_delta;
break;
}
}
}
}
}
@ -400,11 +483,15 @@
{
PSH_Blue_Table table;
FT_UInt count;
FT_Pos delta;
PSH_Blue_Zone zone;
FT_Int no_shoots;
alignment->align = 0;
no_shoots = blues->no_overshoots;
/* lookup stem top in top zones table */
table = &blues->normal_top;
count = table->count;
@ -412,13 +499,17 @@
for ( ; count > 0; count--, zone++ )
{
if ( stem_top < zone->org_bottom )
delta = stem_top - zone->org_bottom;
if ( delta < 0 )
break;
if ( stem_top <= zone->org_top )
{
alignment->align |= PSH_BLUE_ALIGN_TOP;
alignment->align_top = zone->cur_ref;
if ( no_shoots || delta <= blues->blue_threshold )
{
alignment->align |= PSH_BLUE_ALIGN_TOP;
alignment->align_top = zone->cur_ref;
}
break;
}
}
@ -426,17 +517,21 @@
/* look up stem bottom in bottom zones table */
table = &blues->normal_bottom;
count = table->count;
zone = table->zones;
zone = table->zones + count-1;
for ( ; count > 0; count--, zone++ )
for ( ; count > 0; count--, zone-- )
{
if ( stem_bot < zone->org_bottom )
delta = zone->org_top - stem_bot;
if ( delta < 0 )
break;
if ( stem_bot <= zone->org_top )
if ( stem_bot >= zone->org_bottom )
{
alignment->align |= PSH_BLUE_ALIGN_BOT;
alignment->align_bot = zone->cur_ref;
if ( no_shoots || delta < blues->blue_shift )
{
alignment->align |= PSH_BLUE_ALIGN_BOT;
alignment->align_bot = zone->cur_ref;
}
break;
}
}
@ -543,6 +638,11 @@
priv->family_blues, priv->num_family_other_blues,
priv->family_other_blues, priv->blue_fuzz, 1 );
globals->blues.blue_scale = priv->blue_scale ? priv->blue_scale
: (0.039625*0x400000L);
globals->blues.blue_shift = priv->blue_shift;
globals->dimension[0].scale_mult = 0;
globals->dimension[0].scale_delta = 0;
globals->dimension[1].scale_mult = 0;

View File

@ -120,7 +120,11 @@ FT_BEGIN_HEADER
PSH_Blue_TableRec normal_bottom;
PSH_Blue_TableRec family_top;
PSH_Blue_TableRec family_bottom;
FT_Fixed blue_scale;
FT_Int blue_shift;
FT_Int blue_threshold;
FT_Bool no_overshoots;
} PSH_BluesRec, *PSH_Blues;