[autofit] Implement darkening computation function.

This is a crude adaption of the original `cf2_computeDarkening'
function.

* src/autofit/afloader.c (af_intToFixed, af_fixedToInt,
af_floatToFixed): New macros, taken from `cf2fixed.h'.
(af_loader_compute_darkening): New function.
* src/autofit/afloader.h: Updated.
This commit is contained in:
Nikolaus Waxweiler 2015-11-02 13:12:34 +01:00 committed by Werner Lemberg
parent 37c401ac0a
commit bf2ba9e3d4
3 changed files with 154 additions and 0 deletions

View File

@ -1,3 +1,15 @@
2015-11-02 Nikolaus Waxweiler <madigens@gmail.com>
[autofit] Implement darkening computation function.
This is a crude adaption of the original `cf2_computeDarkening'
function.
* src/autofit/afloader.c (af_intToFixed, af_fixedToInt,
af_floatToFixed): New macros, taken from `cf2fixed.h'.
(af_loader_compute_darkening): New function.
* src/autofit/afloader.h: Updated.
2015-11-02 Nikolaus Waxweiler <madigens@gmail.com>
[autofit] Add functions to get standard widths for writing systems.

View File

@ -405,4 +405,141 @@
}
/*
* Compute amount of font units the face should be emboldened by, in
* analogy to the CFF driver's `cf2_computeDarkening' function. See there
* for details of the algorithm.
*
* XXX: Currently a crude adaption of the original algorithm. Do better?
*/
#define af_intToFixed( i ) \
( (FT_Fixed)( (FT_UInt32)(i) << 16 ) )
#define af_fixedToInt( x ) \
( (FT_Short)( ( (FT_UInt32)(x) + 0x8000U ) >> 16 ) )
#define af_floatToFixed( f ) \
( (FT_Fixed)( (f) * 65536.0 + 0.5 ) )
FT_LOCAL_DEF( FT_Int32 )
af_loader_compute_darkening( AF_Loader loader,
FT_Face face,
FT_Pos standard_width )
{
AF_Module module = loader->globals->module;
FT_UShort units_per_EM;
FT_Fixed ppem, em_ratio;
FT_Fixed stem_width, stem_width_per_1000, scaled_stem, darken_amount;
FT_Int log_base_2;
FT_Int x1, y1, x2, y2, x3, y3, x4, y4;
ppem = FT_MAX( af_intToFixed( 4 ),
af_intToFixed( face->size->metrics.x_ppem ) );
units_per_EM = face->units_per_EM;
em_ratio = FT_DivFix( af_intToFixed( 1000 ),
af_intToFixed ( units_per_EM ) );
if ( em_ratio < af_floatToFixed( .01 ) )
{
/* If something goes wrong, don't embolden. */
return 0;
}
x1 = module->darken_params[0];
y1 = module->darken_params[1];
x2 = module->darken_params[2];
y2 = module->darken_params[3];
x3 = module->darken_params[4];
y3 = module->darken_params[5];
x4 = module->darken_params[6];
y4 = module->darken_params[7];
if ( standard_width <= 0 )
{
stem_width = af_intToFixed( 75 ); /* taken from cf2font.c */
stem_width_per_1000 = stem_width;
}
else
{
stem_width = af_intToFixed( standard_width );
stem_width_per_1000 = FT_MulFix( stem_width, em_ratio );
}
log_base_2 = FT_MSB( (FT_UInt32)stem_width_per_1000 ) +
FT_MSB( (FT_UInt32)ppem );
if ( log_base_2 >= 46 )
{
/* possible overflow */
scaled_stem = af_intToFixed( x4 );
}
else
scaled_stem = FT_MulFix( stem_width_per_1000, ppem );
/* now apply the darkening parameters */
if ( scaled_stem < af_intToFixed( x1 ) )
darken_amount = FT_DivFix( af_intToFixed( y1 ), ppem );
else if ( scaled_stem < af_intToFixed( x2 ) )
{
FT_Int xdelta = x2 - x1;
FT_Int ydelta = y2 - y1;
FT_Int x = stem_width_per_1000 -
FT_DivFix( af_intToFixed( x1 ), ppem );
if ( !xdelta )
goto Try_x3;
darken_amount = FT_MulDiv( x, ydelta, xdelta ) +
FT_DivFix( af_intToFixed( y1 ), ppem );
}
else if ( scaled_stem < af_intToFixed( x3 ) )
{
Try_x3:
{
FT_Int xdelta = x3 - x2;
FT_Int ydelta = y3 - y2;
FT_Int x = stem_width_per_1000 -
FT_DivFix( af_intToFixed( x2 ), ppem );
if ( !xdelta )
goto Try_x4;
darken_amount = FT_MulDiv( x, ydelta, xdelta ) +
FT_DivFix( af_intToFixed( y2 ), ppem );
}
}
else if ( scaled_stem < af_intToFixed( x4 ) )
{
Try_x4:
{
FT_Int xdelta = x4 - x3;
FT_Int ydelta = y4 - y3;
FT_Int x = stem_width_per_1000 -
FT_DivFix( af_intToFixed( x3 ), ppem );
if ( !xdelta )
goto Use_y4;
darken_amount = FT_MulDiv( x, ydelta, xdelta ) +
FT_DivFix( af_intToFixed( y3 ), ppem );
}
}
else
{
Use_y4:
darken_amount = FT_DivFix( af_intToFixed( y4 ), ppem );
}
/* Convert darken_amount from per 1000 em to true character space. */
return af_fixedToInt( FT_DivFix( darken_amount, em_ratio ) );
}
/* END */

View File

@ -75,6 +75,11 @@ FT_BEGIN_HEADER
FT_UInt gindex,
FT_Int32 load_flags );
FT_LOCAL_DEF( FT_Int32 )
af_loader_compute_darkening( AF_Loader loader,
FT_Face face,
FT_Pos standard_width );
/* */