51 cf2_computeDarkening( CF2_Fixed emRatio,
54 CF2_Fixed* darkenAmount,
55 CF2_Fixed boldenAmount,
57 FT_Int* darkenParams )
109 CF2_Fixed stemWidthPer1000, scaledStem;
115 if ( boldenAmount == 0 && !stemDarkened )
119 if ( emRatio < cf2_doubleToFixed( .01 ) )
124 FT_Int x1 = darkenParams[0];
125 FT_Int y1 = darkenParams[1];
126 FT_Int x2 = darkenParams[2];
127 FT_Int y2 = darkenParams[3];
128 FT_Int x3 = darkenParams[4];
129 FT_Int y3 = darkenParams[5];
130 FT_Int x4 = darkenParams[6];
131 FT_Int y4 = darkenParams[7];
139 stemWidthPer1000 = FT_MulFix( stemWidth + boldenAmount, emRatio );
155 logBase2 = FT_MSB( (FT_UInt32)stemWidthPer1000 ) +
156 FT_MSB( (FT_UInt32)ppem );
158 if ( logBase2 >= 46 )
160 scaledStem = cf2_intToFixed( x4 );
162 scaledStem = FT_MulFix( stemWidthPer1000, ppem );
166 if ( scaledStem < cf2_intToFixed( x1 ) )
167 *darkenAmount = FT_DivFix( cf2_intToFixed( y1 ), ppem );
169 else if ( scaledStem < cf2_intToFixed( x2 ) )
171 FT_Int xdelta = x2 - x1;
172 FT_Int ydelta = y2 - y1;
173 FT_Int x = stemWidthPer1000 -
174 FT_DivFix( cf2_intToFixed( x1 ), ppem );
180 *darkenAmount = FT_MulDiv( x, ydelta, xdelta ) +
181 FT_DivFix( cf2_intToFixed( y1 ), ppem );
184 else if ( scaledStem < cf2_intToFixed( x3 ) )
188 FT_Int xdelta = x3 - x2;
189 FT_Int ydelta = y3 - y2;
190 FT_Int x = stemWidthPer1000 -
191 FT_DivFix( cf2_intToFixed( x2 ), ppem );
197 *darkenAmount = FT_MulDiv( x, ydelta, xdelta ) +
198 FT_DivFix( cf2_intToFixed( y2 ), ppem );
202 else if ( scaledStem < cf2_intToFixed( x4 ) )
206 FT_Int xdelta = x4 - x3;
207 FT_Int ydelta = y4 - y3;
208 FT_Int x = stemWidthPer1000 -
209 FT_DivFix( cf2_intToFixed( x3 ), ppem );
215 *darkenAmount = FT_MulDiv( x, ydelta, xdelta ) +
216 FT_DivFix( cf2_intToFixed( y3 ), ppem );
223 *darkenAmount = FT_DivFix( cf2_intToFixed( y4 ), ppem );
228 *darkenAmount = FT_DivFix( *darkenAmount, 2 * emRatio );
232 *darkenAmount += boldenAmount / 2;
241 cf2_font_setup( CF2_Font font,
242 const CF2_Matrix* transform )
245 PS_Decoder* decoder = font->decoder;
247 FT_Bool needExtraSetup = FALSE;
249 CFF_VStoreRec* vstore;
250 FT_Bool hasVariations = FALSE;
253 CF2_Fixed boldenX = font->syntheticEmboldeningAmountX;
254 CF2_Fixed boldenY = font->syntheticEmboldeningAmountY;
259 CF2_UInt lenNormalizedV = 0;
260 FT_Fixed* normalizedV = NULL;
263 font->error = FT_Err_Ok;
267 subFont = cf2_getSubfont( decoder );
268 if ( font->lastSubfont != subFont )
270 font->lastSubfont = subFont;
271 needExtraSetup = TRUE;
277 vstore = cf2_getVStore( decoder );
278 hasVariations = ( vstore->dataCount != 0 );
282#ifdef TT_CONFIG_OPTION_GX_VAR_SUPPORT
283 FT_Service_CFFLoad cffload = (FT_Service_CFFLoad)font->cffload;
287 font->error = cf2_getNormalizedVector( decoder,
293 if ( cffload->blend_check_vector( &subFont->blend,
294 subFont->private_dict.vsindex,
299 cffload->load_private_dict( decoder->cff,
303 needExtraSetup = TRUE;
308 font->blend.font = subFont->blend.font;
311 font->blend.usedBV = FALSE;
314 font->vsindex = subFont->private_dict.vsindex;
317 font->lenNDV = lenNormalizedV;
318 font->NDV = normalizedV;
325 ppem = cf2_getPpemY( decoder );
326 if ( font->ppem != ppem )
329 needExtraSetup = TRUE;
333 font->hinted = FT_BOOL( font->renderingFlags & CF2_FlagsHinted );
337 if ( ft_memcmp( transform,
338 &font->currentTransform,
339 4 * sizeof ( CF2_Fixed ) ) != 0 )
343 font->currentTransform = *transform;
344 font->currentTransform.tx =
345 font->currentTransform.ty = cf2_intToFixed( 0 );
349 font->innerTransform = *transform;
350 font->outerTransform.a =
351 font->outerTransform.d = cf2_intToFixed( 1 );
352 font->outerTransform.b =
353 font->outerTransform.c = cf2_intToFixed( 0 );
355 needExtraSetup = TRUE;
365 if ( font->stemDarkened != ( font->renderingFlags & CF2_FlagsDarkened ) )
368 FT_BOOL( font->renderingFlags & CF2_FlagsDarkened );
371 needExtraSetup = TRUE;
376 if ( needExtraSetup )
389 CF2_Int unitsPerEm = font->unitsPerEm;
392 if ( unitsPerEm == 0 )
395 ppem = FT_MAX( cf2_intToFixed( 4 ),
401 emRatio = cf2_fixedFracMul( cf2_intToFixed( 1000 ), fontMatrix->a );
407 emRatio = cf2_intToFixed( 1000 ) / unitsPerEm;
408 font->stdVW = cf2_getStdVW( decoder );
410 if ( font->stdVW <= 0 )
411 font->stdVW = FT_DivFix( cf2_intToFixed( 75 ), emRatio );
417 boldenX = FT_MAX( boldenX,
418 FT_DivFix( cf2_intToFixed( unitsPerEm ), ppem ) );
425 cf2_computeDarkening( emRatio,
431 font->darkenParams );
434 cf2_computeDarkening( emRatio,
440 font->darkenParams );
446 emRatio = cf2_fixedFracMul( cf2_intToFixed( 1000 ), fontMatrix->d );
452 stdHW = cf2_getStdHW( decoder );
454 if ( stdHW > 0 && font->stdVW > MUL_INT32( 2, stdHW ) )
455 font->stdHW = FT_DivFix( cf2_intToFixed( 75 ), emRatio );
459 font->stdHW = FT_DivFix( cf2_intToFixed( 110 ), emRatio );
462 cf2_computeDarkening( emRatio,
468 font->darkenParams );
470 if ( font->darkenX != 0 || font->darkenY != 0 )
471 font->darkened = TRUE;
473 font->darkened = FALSE;
475 font->reverseWinding = FALSE;
478 cf2_blues_init( &font->blues, font );
485 FT_LOCAL_DEF( FT_Error )
486 cf2_getGlyphOutline( CF2_Font font,
487 CF2_Buffer charstring,
488 const CF2_Matrix* transform,
489 CF2_F16Dot16* glyphWidth )
491 FT_Error lastError = FT_Err_Ok;
493 FT_Vector translation;
496 FT_Vector advancePoint;
499 CF2_Fixed advWidth = 0;
506 translation.x = transform->tx;
507 translation.y = transform->ty;
510 cf2_font_setup( font, transform );
515 font->reverseWinding = FALSE;
518 needWinding = font->darkened;
523 cf2_outline_reset( &font->outline );
526 cf2_interpT2CharString( font,
528 (CF2_OutlineCallbacks)&font->outline,
542 if ( font->outline.root.windingMomentum >= 0 )
547 font->reverseWinding = TRUE;
553 cf2_outline_close( &font->outline );
557 *glyphWidth = advWidth;
560 cf2_setError( &font->error, lastError );