/**************************************************************************** * * pshints.c * * Adobe's code for handling CFF hints (body). * * Copyright 2007-2014 Adobe Systems Incorporated. * * This software, and all works of authorship, whether in source or * object code form as indicated by the copyright notice(s) included * herein (collectively, the "Work") is made available, and may only be * used, modified, and distributed under the FreeType Project License, * LICENSE.TXT. Additionally, subject to the terms and conditions of the * FreeType Project License, each contributor to the Work hereby grants * to any individual or legal entity exercising permissions granted by * the FreeType Project License and this section (hereafter, "You" or * "Your") a perpetual, worldwide, non-exclusive, no-charge, * royalty-free, irrevocable (except as stated in this section) patent * license to make, have made, use, offer to sell, sell, import, and * otherwise transfer the Work, where such license applies only to those * patent claims licensable by such contributor that are necessarily * infringed by their contribution(s) alone or by combination of their * contribution(s) with the Work to which such contribution(s) was * submitted. If You institute patent litigation against any entity * (including a cross-claim or counterclaim in a lawsuit) alleging that * the Work or a contribution incorporated within the Work constitutes * direct or contributory patent infringement, then any patent licenses * granted to You under this License for that Work shall terminate as of * the date such litigation is filed. * * By using, modifying, or distributing the Work you indicate that you * have read and understood the terms and conditions of the * FreeType Project License as well as those provided in this section, * and you accept them fully. * */ #include "psft.h" #include <freetype/internal/ftdebug.h> #include "psglue.h" #include "psfont.h" #include "pshints.h" #include "psintrp.h" /************************************************************************** * * The macro FT_COMPONENT is used in trace mode. It is an implicit * parameter of the FT_TRACE() and FT_ERROR() macros, used to print/log * messages during execution. */ #undef FT_COMPONENT #define FT_COMPONENT … CF2_HintMove; /* Compute angular momentum for winding order detection. It is called */ /* for all lines and curves, but not necessarily in element order. */ static CF2_Int cf2_getWindingMomentum( CF2_Fixed x1, CF2_Fixed y1, CF2_Fixed x2, CF2_Fixed y2 ) { … } /* * Construct from a StemHint; this is used as a parameter to * `cf2_blues_capture'. * `hintOrigin' is the character space displacement of a seac accent. * Adjust stem hint for darkening here. * */ static void cf2_hint_init( CF2_Hint hint, const CF2_ArrStack stemHintArray, size_t indexStemHint, const CF2_Font font, CF2_Fixed hintOrigin, CF2_Fixed scale, FT_Bool bottom ) { … } /* initialize an invalid hint map element */ static void cf2_hint_initZero( CF2_Hint hint ) { … } FT_LOCAL_DEF( FT_Bool ) cf2_hint_isValid( const CF2_Hint hint ) { … } static FT_Bool cf2_hint_isPair( const CF2_Hint hint ) { … } static FT_Bool cf2_hint_isPairTop( const CF2_Hint hint ) { … } FT_LOCAL_DEF( FT_Bool ) cf2_hint_isTop( const CF2_Hint hint ) { … } FT_LOCAL_DEF( FT_Bool ) cf2_hint_isBottom( const CF2_Hint hint ) { … } static FT_Bool cf2_hint_isLocked( const CF2_Hint hint ) { … } static FT_Bool cf2_hint_isSynthetic( const CF2_Hint hint ) { … } FT_LOCAL_DEF( void ) cf2_hint_lock( CF2_Hint hint ) { … } FT_LOCAL_DEF( void ) cf2_hintmap_init( CF2_HintMap hintmap, CF2_Font font, CF2_HintMap initialMap, CF2_ArrStack hintMoves, CF2_Fixed scale ) { … } static FT_Bool cf2_hintmap_isValid( const CF2_HintMap hintmap ) { … } static void cf2_hintmap_dump( CF2_HintMap hintmap ) { … } /* transform character space coordinate to device space using hint map */ static CF2_Fixed cf2_hintmap_map( CF2_HintMap hintmap, CF2_Fixed csCoord ) { … } /* * This hinting policy moves a hint pair in device space so that one of * its two edges is on a device pixel boundary (its fractional part is * zero). `cf2_hintmap_insertHint' guarantees no overlap in CS * space. Ensure here that there is no overlap in DS. * * In the first pass, edges are adjusted relative to adjacent hints. * Those that are below have already been adjusted. Those that are * above have not yet been adjusted. If a hint above blocks an * adjustment to an optimal position, we will try again in a second * pass. The second pass is top-down. * */ static void cf2_hintmap_adjustHints( CF2_HintMap hintmap ) { … } /* insert hint edges into map, sorted by csCoord */ static void cf2_hintmap_insertHint( CF2_HintMap hintmap, CF2_Hint bottomHintEdge, CF2_Hint topHintEdge ) { … } /* * Build a map from hints and mask. * * This function may recur one level if `hintmap->initialHintMap' is not yet * valid. * If `initialMap' is true, simply build initial map. * * Synthetic hints are used in two ways. A hint at zero is inserted, if * needed, in the initial hint map, to prevent translations from * propagating across the origin. If synthetic em box hints are enabled * for ideographic dictionaries, then they are inserted in all hint * maps, including the initial one. * */ FT_LOCAL_DEF( void ) cf2_hintmap_build( CF2_HintMap hintmap, CF2_ArrStack hStemHintArray, CF2_ArrStack vStemHintArray, CF2_HintMask hintMask, CF2_Fixed hintOrigin, FT_Bool initialMap ) { … } FT_LOCAL_DEF( void ) cf2_glyphpath_init( CF2_GlyphPath glyphpath, CF2_Font font, CF2_OutlineCallbacks callbacks, CF2_Fixed scaleY, /* CF2_Fixed hShift, */ CF2_ArrStack hStemHintArray, CF2_ArrStack vStemHintArray, CF2_HintMask hintMask, CF2_Fixed hintOriginY, const CF2_Blues blues, const FT_Vector* fractionalTranslation ) { … } FT_LOCAL_DEF( void ) cf2_glyphpath_finalize( CF2_GlyphPath glyphpath ) { … } /* * Hint point in y-direction and apply outerTransform. * Input `current' hint map (which is actually delayed by one element). * Input x,y point in Character Space. * Output x,y point in Device Space, including translation. */ static void cf2_glyphpath_hintPoint( CF2_GlyphPath glyphpath, CF2_HintMap hintmap, FT_Vector* ppt, CF2_Fixed x, CF2_Fixed y ) { … } /* * From two line segments, (u1,u2) and (v1,v2), compute a point of * intersection on the corresponding lines. * Return false if no intersection is found, or if the intersection is * too far away from the ends of the line segments, u2 and v1. * */ static FT_Bool cf2_glyphpath_computeIntersection( CF2_GlyphPath glyphpath, const FT_Vector* u1, const FT_Vector* u2, const FT_Vector* v1, const FT_Vector* v2, FT_Vector* intersection ) { … } /* * Push the cached element (glyphpath->prevElem*) to the outline * consumer. When a darkening offset is used, the end point of the * cached element may be adjusted to an intersection point or we may * synthesize a connecting line to the current element. If we are * closing a subpath, we may also generate a connecting line to the start * point. * * This is where Character Space (CS) is converted to Device Space (DS) * using a hint map. This calculation must use a HintMap that was valid * at the time the element was saved. For the first point in a subpath, * that is a saved HintMap. For most elements, it just means the caller * has delayed building a HintMap from the current HintMask. * * Transform each point with outerTransform and call the outline * callbacks. This is a general 3x3 transform: * * x' = a*x + c*y + tx, y' = b*x + d*y + ty * * but it uses 4 elements from CF2_Font and the translation part * from CF2_GlyphPath. * */ static void cf2_glyphpath_pushPrevElem( CF2_GlyphPath glyphpath, CF2_HintMap hintmap, FT_Vector* nextP0, FT_Vector nextP1, FT_Bool close ) { … } /* push a MoveTo element based on current point and offset of current */ /* element */ static void cf2_glyphpath_pushMove( CF2_GlyphPath glyphpath, FT_Vector start ) { … } /* * All coordinates are in character space. * On input, (x1, y1) and (x2, y2) give line segment. * On output, (x, y) give offset vector. * We use a piecewise approximation to trig functions. * * TODO: Offset true perpendicular and proper length * supply the y-translation for hinting here, too, * that adds yOffset unconditionally to *y. */ static void cf2_glyphpath_computeOffset( CF2_GlyphPath glyphpath, CF2_Fixed x1, CF2_Fixed y1, CF2_Fixed x2, CF2_Fixed y2, CF2_Fixed* x, CF2_Fixed* y ) { … } /* * The functions cf2_glyphpath_{moveTo,lineTo,curveTo,closeOpenPath} are * called by the interpreter with Character Space (CS) coordinates. Each * path element is placed into a queue of length one to await the * calculation of the following element. At that time, the darkening * offset of the following element is known and joins can be computed, * including possible modification of this element, before mapping to * Device Space (DS) and passing it on to the outline consumer. * */ FT_LOCAL_DEF( void ) cf2_glyphpath_moveTo( CF2_GlyphPath glyphpath, CF2_Fixed x, CF2_Fixed y ) { … } FT_LOCAL_DEF( void ) cf2_glyphpath_lineTo( CF2_GlyphPath glyphpath, CF2_Fixed x, CF2_Fixed y ) { … } FT_LOCAL_DEF( void ) cf2_glyphpath_curveTo( CF2_GlyphPath glyphpath, CF2_Fixed x1, CF2_Fixed y1, CF2_Fixed x2, CF2_Fixed y2, CF2_Fixed x3, CF2_Fixed y3 ) { … } FT_LOCAL_DEF( void ) cf2_glyphpath_closeOpenPath( CF2_GlyphPath glyphpath ) { … } /* END */