|
|
|
@ -51,15 +51,57 @@ |
|
|
|
|
CF2_Fixed stemWidth, |
|
|
|
|
CF2_Fixed* darkenAmount, |
|
|
|
|
CF2_Fixed boldenAmount, |
|
|
|
|
FT_Bool stemDarkened ) |
|
|
|
|
FT_Bool stemDarkened, |
|
|
|
|
FT_Int* darkenParams ) |
|
|
|
|
{ |
|
|
|
|
/*
|
|
|
|
|
* Total darkening amount is computed in 1000 unit character space |
|
|
|
|
* using the modified 5 part curve as Adobe's Avalon rasterizer. |
|
|
|
|
* The darkening amount is smaller for thicker stems. |
|
|
|
|
* It becomes zero when the stem is thicker than 2.333 pixels. |
|
|
|
|
* |
|
|
|
|
* By default, we use |
|
|
|
|
* |
|
|
|
|
* darkenAmount = 0.4 pixels if scaledStem <= 0.5 pixels, |
|
|
|
|
* darkenAmount = 0.275 pixels if 1 <= scaledStem <= 1.667 pixels, |
|
|
|
|
* darkenAmount = 0 pixel if scaledStem >= 2.333 pixels, |
|
|
|
|
* |
|
|
|
|
* and piecewise linear in-between: |
|
|
|
|
* |
|
|
|
|
* |
|
|
|
|
* darkening |
|
|
|
|
* ^ |
|
|
|
|
* | |
|
|
|
|
* | (x1,y1) |
|
|
|
|
* |--------+ |
|
|
|
|
* | \
|
|
|
|
|
* | \
|
|
|
|
|
* | \ (x3,y3) |
|
|
|
|
* | +----------+ |
|
|
|
|
* | (x2,y2) \
|
|
|
|
|
* | \
|
|
|
|
|
* | \
|
|
|
|
|
* | +----------------- |
|
|
|
|
* | (x4,y4) |
|
|
|
|
* +---------------------------------------------> stem |
|
|
|
|
* thickness |
|
|
|
|
* |
|
|
|
|
* |
|
|
|
|
* This corresponds to the following values for the |
|
|
|
|
* `darkening-parameters' property: |
|
|
|
|
* |
|
|
|
|
* (x1, y1) = (500, 400) |
|
|
|
|
* (x2, y2) = (1000, 275) |
|
|
|
|
* (x3, y3) = (1667, 275) |
|
|
|
|
* (x4, y4) = (2333, 0) |
|
|
|
|
* |
|
|
|
|
*/ |
|
|
|
|
|
|
|
|
|
/* Internal calculations are done in units per thousand for */ |
|
|
|
|
/* convenience. */ |
|
|
|
|
CF2_Fixed stemWidthPer1000, scaledStem; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
*darkenAmount = 0; |
|
|
|
|
|
|
|
|
|
if ( boldenAmount == 0 && !stemDarkened ) |
|
|
|
|
return; |
|
|
|
|
|
|
|
|
@ -69,6 +111,16 @@ |
|
|
|
|
|
|
|
|
|
if ( stemDarkened ) |
|
|
|
|
{ |
|
|
|
|
FT_Int x1 = darkenParams[0]; |
|
|
|
|
FT_Int y1 = darkenParams[1]; |
|
|
|
|
FT_Int x2 = darkenParams[2]; |
|
|
|
|
FT_Int y2 = darkenParams[3]; |
|
|
|
|
FT_Int x3 = darkenParams[4]; |
|
|
|
|
FT_Int y3 = darkenParams[5]; |
|
|
|
|
FT_Int x4 = darkenParams[6]; |
|
|
|
|
FT_Int y4 = darkenParams[7]; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/* convert from true character space to 1000 unit character space; */ |
|
|
|
|
/* add synthetic emboldening effect */ |
|
|
|
|
|
|
|
|
@ -81,7 +133,7 @@ |
|
|
|
|
stemWidthPer1000 <= ( stemWidth + boldenAmount ) ) |
|
|
|
|
{ |
|
|
|
|
stemWidthPer1000 = 0; /* to pacify compiler */ |
|
|
|
|
scaledStem = cf2_intToFixed( 2333 ); |
|
|
|
|
scaledStem = cf2_intToFixed( x4 ); |
|
|
|
|
} |
|
|
|
|
else |
|
|
|
|
{ |
|
|
|
@ -89,39 +141,70 @@ |
|
|
|
|
|
|
|
|
|
if ( ppem > CF2_FIXED_ONE && |
|
|
|
|
scaledStem <= stemWidthPer1000 ) |
|
|
|
|
scaledStem = cf2_intToFixed( 2333 ); |
|
|
|
|
scaledStem = cf2_intToFixed( x4 ); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
|
* Total darkening amount is computed in 1000 unit character space |
|
|
|
|
* using the modified 5 part curve as Avalon rasterizer. |
|
|
|
|
* The darkening amount is smaller for thicker stems. |
|
|
|
|
* It becomes zero when the stem is thicker than 2.333 pixels. |
|
|
|
|
* |
|
|
|
|
* By default, we use |
|
|
|
|
* |
|
|
|
|
* darkenAmount = 0.4 pixels if scaledStem <= 0.5 pixels, |
|
|
|
|
* darkenAmount = 0.275 pixels if 1 <= scaledStem <= 1.667 pixels, |
|
|
|
|
* darkenAmount = 0 pixel if scaledStem >= 2.333 pixels, |
|
|
|
|
* |
|
|
|
|
* and piecewise linear in-between. |
|
|
|
|
* |
|
|
|
|
*/ |
|
|
|
|
if ( scaledStem < cf2_intToFixed( 500 ) ) |
|
|
|
|
*darkenAmount = FT_DivFix( cf2_intToFixed( 400 ), ppem ); |
|
|
|
|
|
|
|
|
|
else if ( scaledStem < cf2_intToFixed( 1000 ) ) |
|
|
|
|
*darkenAmount = FT_DivFix( cf2_intToFixed( 525 ), ppem ) - |
|
|
|
|
FT_MulFix( stemWidthPer1000, |
|
|
|
|
cf2_floatToFixed( .25 ) ); |
|
|
|
|
|
|
|
|
|
else if ( scaledStem < cf2_intToFixed( 1667 ) ) |
|
|
|
|
*darkenAmount = FT_DivFix( cf2_intToFixed( 275 ), ppem ); |
|
|
|
|
|
|
|
|
|
else if ( scaledStem < cf2_intToFixed( 2333 ) ) |
|
|
|
|
*darkenAmount = FT_DivFix( cf2_intToFixed( 963 ), ppem ) - |
|
|
|
|
FT_MulFix( stemWidthPer1000, |
|
|
|
|
cf2_floatToFixed( .413 ) ); |
|
|
|
|
/* now apply the darkening parameters */ |
|
|
|
|
|
|
|
|
|
if ( scaledStem < cf2_intToFixed( x1 ) ) |
|
|
|
|
*darkenAmount = FT_DivFix( cf2_intToFixed( y1 ), ppem ); |
|
|
|
|
|
|
|
|
|
else if ( scaledStem < cf2_intToFixed( x2 ) ) |
|
|
|
|
{ |
|
|
|
|
FT_Int xdelta = x2 - x1; |
|
|
|
|
FT_Int ydelta = y2 - y1; |
|
|
|
|
FT_Int x = stemWidthPer1000 - |
|
|
|
|
FT_DivFix( cf2_intToFixed( x1 ), ppem ); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if ( !ydelta ) |
|
|
|
|
goto Try_x3; |
|
|
|
|
|
|
|
|
|
*darkenAmount = FT_MulFix( x, FT_DivFix( ydelta, xdelta ) ) + |
|
|
|
|
FT_DivFix( cf2_intToFixed( y1 ), ppem ); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
else if ( scaledStem < cf2_intToFixed( x3 ) ) |
|
|
|
|
{ |
|
|
|
|
Try_x3: |
|
|
|
|
{ |
|
|
|
|
FT_Int xdelta = x3 - x2; |
|
|
|
|
FT_Int ydelta = y3 - y2; |
|
|
|
|
FT_Int x = stemWidthPer1000 - |
|
|
|
|
FT_DivFix( cf2_intToFixed( x2 ), ppem ); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if ( !ydelta ) |
|
|
|
|
goto Try_x4; |
|
|
|
|
|
|
|
|
|
*darkenAmount = FT_MulFix( x, FT_DivFix( ydelta, xdelta ) ) + |
|
|
|
|
FT_DivFix( cf2_intToFixed( y2 ), ppem ); |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
else if ( scaledStem < cf2_intToFixed( x4 ) ) |
|
|
|
|
{ |
|
|
|
|
Try_x4: |
|
|
|
|
{ |
|
|
|
|
FT_Int xdelta = x4 - x3; |
|
|
|
|
FT_Int ydelta = y4 - y3; |
|
|
|
|
FT_Int x = stemWidthPer1000 - |
|
|
|
|
FT_DivFix( cf2_intToFixed( x3 ), ppem ); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if ( !ydelta ) |
|
|
|
|
goto Use_y4; |
|
|
|
|
|
|
|
|
|
*darkenAmount = FT_MulFix( x, FT_DivFix( ydelta, xdelta ) ) + |
|
|
|
|
FT_DivFix( cf2_intToFixed( y3 ), ppem ); |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
else |
|
|
|
|
{ |
|
|
|
|
Use_y4: |
|
|
|
|
*darkenAmount = FT_DivFix( cf2_intToFixed( y4 ), ppem ); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
/* use half the amount on each side and convert back to true */ |
|
|
|
|
/* character space */ |
|
|
|
@ -268,7 +351,8 @@ |
|
|
|
|
font->stdVW, |
|
|
|
|
&font->darkenX, |
|
|
|
|
boldenX, |
|
|
|
|
FALSE ); |
|
|
|
|
FALSE, |
|
|
|
|
font->darkenParams ); |
|
|
|
|
} |
|
|
|
|
else |
|
|
|
|
cf2_computeDarkening( emRatio, |
|
|
|
@ -276,7 +360,8 @@ |
|
|
|
|
font->stdVW, |
|
|
|
|
&font->darkenX, |
|
|
|
|
0, |
|
|
|
|
font->stemDarkened ); |
|
|
|
|
font->stemDarkened, |
|
|
|
|
font->darkenParams ); |
|
|
|
|
|
|
|
|
|
#if 0 |
|
|
|
|
/* since hstem is measured in the y-direction, we use the `d' member */ |
|
|
|
@ -303,7 +388,8 @@ |
|
|
|
|
font->stdHW, |
|
|
|
|
&font->darkenY, |
|
|
|
|
boldenY, |
|
|
|
|
font->stemDarkened ); |
|
|
|
|
font->stemDarkened, |
|
|
|
|
font->darkenParams ); |
|
|
|
|
|
|
|
|
|
if ( font->darkenX != 0 || font->darkenY != 0 ) |
|
|
|
|
font->darkened = TRUE; |
|
|
|
|