1 /* 2 * Copyright 2014 Adobe Systems Incorporated (http://www.adobe.com/). 3 * All Rights Reserved. 4 * 5 * This software is licensed as OpenSource, under the Apache License, Version 6 * 2.0. 7 * This license is available at: http://opensource.org/licenses/Apache-2.0. 8 */ 9 10 /* See the discussion in the function definition for: 11 control.c:Blues() 12 static void Blues() 13 */ 14 15 #ifndef AC_AC_H_ 16 #define AC_AC_H_ 17 18 #include "psautohint.h" 19 20 #include "logging.h" 21 #include "memory.h" 22 23 24 /* widely used definitions */ 25 26 /* values for HintSeg.sType */ 27 #define sLINE (0) 28 #define sBEND (1) 29 #define sCURVE (2) 30 #define sGHOST (3) 31 32 /* values for PathElt.type */ 33 #define MOVETO (0) 34 #define LINETO (1) 35 #define CURVETO (2) 36 #define CLOSEPATH (3) 37 38 /* values for pathelt control points */ 39 #define cpStart (0) 40 #define cpCurve1 (1) 41 #define cpCurve2 (2) 42 #define cpEnd (3) 43 44 /* widths of ghost bands */ 45 #define botGhst (-21) 46 #define topGhst (-20) 47 48 /* structures */ 49 50 /* glyph point coordinates */ 51 typedef struct { 52 Fixed x, y; 53 } Cd; 54 55 typedef struct { 56 int16_t limit; 57 Fixed feps; 58 void (*report)(Cd); 59 Cd ll, ur; 60 Fixed llx, lly; 61 } FltnRec; 62 63 typedef struct _hintseg { 64 struct _hintseg *sNxt; 65 /* points to next HintSeg in list */ 66 /* separate lists for top, bottom, left, and right segments */ 67 Fixed sLoc, sMax, sMin; 68 /* sLoc is X loc for vertical seg, Y loc for horizontal seg */ 69 /* sMax and sMin give Y extent for vertical seg, X extent for horizontal */ 70 /* i.e., sTop=sMax, sBot=sMin, sLft=sMin, sRght=sMax. */ 71 Fixed sBonus; 72 /* nonzero for segments in sol-eol subpaths */ 73 /* (probably a leftover that is no longer needed) */ 74 struct _hintval *sLnk; 75 /* points to the best HintVal that uses this HintSeg */ 76 /* set by FindBestValForSegs in pick.c */ 77 struct _pthelt *sElt; 78 /* points to the path element that generated this HintSeg */ 79 /* set by AddSegment in gen.c */ 80 int16_t sType; 81 /* tells what type of segment this is: sLINE sBEND sCURVE or sGHOST */ 82 } HintSeg; 83 84 typedef struct { 85 HintSeg* seg; 86 } SegLnk; 87 88 typedef struct _seglnklst { 89 struct _seglnklst *next; 90 SegLnk* lnk; 91 } SegLnkLst; 92 93 #if 0 94 typedef struct _hintrep { 95 Fixed vVal, vSpc, vLoc1, vLoc2; 96 struct _hintval *vBst; 97 } HintRep; 98 99 typedef struct _hintval { 100 struct _hintval *vNxt; 101 Fixed vVal, vSpc, initVal; 102 Fixed vLoc1, vLoc2; 103 /* vBot=vLoc1, vTop=vLoc2, vLft=vLoc1, vRght=vLoc2 */ 104 int16_t vGhst:8; 105 int16_t pruned:8; 106 HintSeg* vSeg1, *vSeg2; 107 struct _hintval *vBst; 108 HintRep* vRep; 109 } HintVal; 110 #else 111 typedef struct _hintval { 112 struct _hintval *vNxt; 113 /* points to next HintVal in list */ 114 Fixed vVal, vSpc, initVal; 115 /* vVal is value given in eval.c */ 116 /* vSpc is nonzero for "special" HintVals */ 117 /* such as those with a segment in a blue zone */ 118 /* initVal is the initially assigned value */ 119 /* used by FndBstVal in pick.c */ 120 Fixed vLoc1, vLoc2; 121 /* vLoc1 is location corresponding to vSeg1 */ 122 /* vLoc2 is location corresponding to vSeg2 */ 123 /* for horizontal HintVal, vBot=vLoc1 and vTop=vLoc2 */ 124 /* for vertical HintVal, vLft=vLoc1 and vRght=vLoc2 */ 125 unsigned int vGhst:1; /* true iff one of the HintSegs is a sGHOST seg */ 126 unsigned int pruned:1; 127 /* flag used by FindBestHVals and FindBestVVals */ 128 /* and by PruneVVals and PruneHVals */ 129 unsigned int merge:1; 130 /* flag used by ReplaceVals in merge.c */ 131 unsigned int unused:13; 132 HintSeg *vSeg1, *vSeg2; 133 /* vSeg1 points to the left HintSeg in a vertical, bottom in a horizontal */ 134 /* vSeg2 points to the right HintSeg in a vertical, top in a horizontal */ 135 struct _hintval *vBst; 136 /* points to another HintVal if this one has been merged or replaced */ 137 } HintVal; 138 #endif 139 140 typedef struct _pthelt { 141 struct _pthelt *prev, *next, *conflict; 142 int16_t type; 143 SegLnkLst *Hs, *Vs; 144 bool Hcopy:1, Vcopy:1, isFlex:1, yFlex:1, newCP:1; 145 unsigned int unused:9; 146 int16_t count, newhints; 147 Fixed x, y, x1, y1, x2, y2, x3, y3; 148 } PathElt; 149 150 typedef struct _hintpnt { 151 struct _hintpnt *next; 152 Fixed x0, y0, x1, y1; 153 /* for vstem, only interested in x0 and x1 */ 154 /* for hstem, only interested in y0 and y1 */ 155 PathElt *p0, *p1; 156 /* p0 is source of x0,y0; p1 is source of x1,y1 */ 157 char c; 158 /* tells what kind of hinting: 'b' 'y' 'm' or 'v' */ 159 bool done; 160 } HintPoint; 161 162 typedef struct { 163 char** keys; /* font information keys */ 164 char** values; /* font information values */ 165 size_t length; /* number of the entries */ 166 } ACFontInfo; 167 168 /* global data */ 169 170 extern ACBuffer* gBezOutput; 171 172 extern PathElt* gPathStart, *gPathEnd; 173 extern bool gUseV, gUseH, gAutoLinearCurveFix; 174 extern bool gEditGlyph; /* whether glyph can be modified when adding hints */ 175 extern bool gBandError; 176 extern bool gHasFlex, gFlexOK, gFlexStrict; 177 extern Fixed gHBigDist, gVBigDist, gInitBigDist, gMinDist, gGhostWidth, 178 gGhostLength, gBendLength, gBandMargin, gMaxFlare, 179 gMaxBendMerge, gMaxMerge, gMinHintElementLength, gFlexCand; 180 extern Fixed gPruneA, gPruneB, gPruneC, gPruneD, gPruneValue, gBonus; 181 extern float gTheta, gHBigDistR, gVBigDistR, gMaxVal, gMinVal; 182 extern int32_t gDMin, gDelta, gCPpercent, gBendTan, gSCurveTan; 183 extern HintVal *gVHinting, *gHHinting, *gVPrimary, *gHPrimary, *gValList; 184 extern HintSeg* gSegLists[4]; /* left, right, top, bot */ 185 extern HintPoint* gPointList, **gPtLstArray; 186 extern int32_t gPtLstIndex, gNumPtLsts, gMaxPtLsts; 187 188 /* global callbacks */ 189 190 /* if false, then stems defined by curves are excluded from the reporting */ 191 extern unsigned int gAllStems; 192 193 extern AC_REPORTSTEMPTR gAddHStemCB; 194 extern AC_REPORTSTEMPTR gAddVStemCB; 195 196 extern AC_REPORTZONEPTR gAddGlyphExtremesCB; 197 extern AC_REPORTZONEPTR gAddStemExtremesCB; 198 199 extern AC_RETRYPTR gReportRetryCB; 200 201 extern void* gAddStemUserData; 202 extern void* gAddExtremesUserData; 203 extern void* gReportRetryUserData; 204 205 void AddStemExtremes(Fixed bot, Fixed top); 206 207 #define leftList (gSegLists[0]) 208 #define rightList (gSegLists[1]) 209 #define topList (gSegLists[2]) 210 #define botList (gSegLists[3]) 211 212 #define MAXFLEX (PSDist(20)) 213 #define MAXBLUES (20) 214 #define MAXSERIFS (5) 215 extern Fixed gTopBands[MAXBLUES], gBotBands[MAXBLUES], gSerifs[MAXSERIFS]; 216 extern int32_t gLenTopBands, gLenBotBands, gNumSerifs; 217 #define MAXSTEMS (20) 218 extern Fixed gVStems[MAXSTEMS], gHStems[MAXSTEMS]; 219 extern int32_t gNumVStems, gNumHStems; 220 extern char *gHHintList[], *gVHintList[]; 221 extern int32_t gNumHHints, gNumVHints; 222 extern bool gWriteHintedBez; 223 extern Fixed gBlueFuzz; 224 extern bool gDoAligns, gDoStems; 225 extern bool gRoundToInt; 226 extern bool gAddHints; 227 228 #define MAX_GLYPHNAME_LEN 64 229 /* defined in read.c; set from the glyph name at the start of the bex file. */ 230 extern char gGlyphName[MAX_GLYPHNAME_LEN]; 231 232 /* macros */ 233 234 #define FixOne (0x100) 235 #define FixTwo (0x200) 236 #define FixHalf (0x80) 237 #define FixQuarter (0x40) 238 239 #define FIXED_MAX INT32_MAX 240 #define FIXED_MIN INT32_MIN 241 #define FixInt(i) (((int32_t)(i)) * FixOne) 242 #define FixReal(i) ((int32_t)((i) * (float)FixOne)) 243 int32_t FRnd(int32_t x); 244 #define FHalfRnd(x) ((int32_t)(((x)+(1<<7)) & ~0xFF)) 245 #define FracPart(x) ((int32_t)(x) & 0xFF) 246 #define FTrunc(x) (((int32_t)(x)) / FixOne) 247 #define FIXED2FLOAT(x) (x / (float)FixOne) 248 249 #define FixHalfMul(f) (2*((f) >> 2)) /* DEBUG 8 BIT. Revert this to ((f) >>1) once I am confident that there are not bugs from the update to 8 bits for the Fixed fraction. */ 250 #define FixTwoMul(f) ((f) << 1) 251 #define PSDist(d) ((FixInt(d))) 252 #define IsVertical(x1,y1,x2,y2) (VertQuo(x1,y1,x2,y2) > 0) 253 #define IsHorizontal(x1,y1,x2,y2) (HorzQuo(x1,y1,x2,y2) > 0) 254 #define SFACTOR (20) 255 /* SFACTOR must be < 25 for Gothic-Medium-22 c08 */ 256 #define spcBonus (1000) 257 #define ProdLt0(f0, f1) (((f0) < 0 && (f1) > 0) || ((f0) > 0 && (f1) < 0)) 258 #define ProdGe0(f0, f1) (!ProdLt0(f0, f1)) 259 260 #define DEBUG_ROUND(val) { val = ( val >=0 ) ? (2*(val/2)) : (2*((val - 1)/2));} 261 262 /* DEBUG_ROUND is used to force calculations to come out the same as the previous version, where coordinates used 7 bits for the Fixed fraction, rather than the current 8 bits. Once I am confident that there are no bugs in the update, I will remove all occurences of this macro, and accept the differences due to more exact division */ 263 /* procedures */ 264 265 /* The fix to float and float to fixed procs are different for ac because it 266 uses 24 bit of int32_t and 8 bits of fraction. */ 267 void acfixtopflt(Fixed x, float* pf); 268 Fixed acpflttofix(float* pf); 269 270 void *Alloc(int32_t sz); /* Sub-allocator */ 271 272 int AddCounterHintGlyphs(char* charlist, char* HintList[]); 273 bool FindNameInList(char* nm, char** lst); 274 void PruneElementHintSegs(void); 275 int TestHintLst(SegLnkLst* lst, HintVal* hintList, bool flg, bool doLst); 276 HintVal* CopyHints(HintVal* lst); 277 void AutoExtraHints(bool movetoNewHints); 278 int32_t SpecialGlyphType(void); 279 bool VHintGlyph(void); 280 bool HHintGlyph(void); 281 bool NoBlueGlyph(void); 282 bool MoveToNewHints(void); 283 bool GetInflectionPoint(Fixed, Fixed, Fixed, Fixed, Fixed, Fixed, Fixed, Fixed, Fixed *); 284 void CheckSmooth(void); 285 void CheckBBoxEdge(PathElt* e, bool vrt, Fixed lc, Fixed* pf, Fixed* pl); 286 bool CheckSmoothness(Fixed x0, Fixed cy0, Fixed x1, Fixed cy1, Fixed x2, 287 Fixed y2, Fixed* pd); 288 void CheckForDups(void); 289 void AddHintPoint(Fixed x0, Fixed y0, Fixed x1, Fixed y1, char ch, PathElt* p0, 290 PathElt* p1); 291 void AddHPair(HintVal* v, char ch); 292 void AddVPair(HintVal* v, char ch); 293 void XtraHints(PathElt* e); 294 bool AutoHintGlyph(const char* srcglyph, bool extrahint); 295 void EvalV(void); 296 void EvalH(void); 297 void GenVPts(int32_t specialGlyphType); 298 void CheckTfmVal(HintSeg* hSegList, Fixed* bandList, int32_t length); 299 void CheckVals(HintVal* vlst, bool vert); 300 bool FindLineSeg(Fixed loc, HintSeg* sL); 301 void FltnCurve(Cd c0, Cd c1, Cd c2, Cd c3, FltnRec* pfr); 302 bool InBlueBand(Fixed loc, int32_t n, Fixed* p); 303 void GenHPts(void); 304 void PreGenPts(void); 305 PathElt* GetDest(PathElt* cldest); 306 PathElt* GetClosedBy(PathElt* clsdby); 307 void GetEndPoint(PathElt* e, Fixed* x1p, Fixed* y1p); 308 void GetEndPoints(PathElt* p, Fixed* px0, Fixed* py0, Fixed* px1, Fixed* py1); 309 Fixed VertQuo(Fixed xk, Fixed yk, Fixed xl, Fixed yl); 310 Fixed HorzQuo(Fixed xk, Fixed yk, Fixed xl, Fixed yl); 311 bool IsTiny(PathElt* e); 312 bool IsShort(PathElt* e); 313 PathElt* NxtForBend(PathElt* p, Fixed* px2, Fixed* py2, Fixed* px3, Fixed* py3); 314 PathElt* PrvForBend(PathElt* p, Fixed* px2, Fixed* py2); 315 bool IsLower(PathElt* p); 316 bool IsUpper(PathElt* p); 317 bool CloseSegs(HintSeg* s1, HintSeg* s2, bool vert); 318 319 void DoPrune(void); 320 void PruneVVals(void); 321 void PruneHVals(void); 322 void MergeVals(bool vert); 323 void MergeFromMainHints(char ch); 324 void RoundPathCoords(void); 325 void MoveSubpathToEnd(PathElt* e); 326 void InitData(int32_t reason); 327 void InitFix(int32_t reason); 328 void InitGen(int32_t reason); 329 void InitPick(int32_t reason); 330 void AutoAddFlex(void); 331 bool SameHints(int32_t cn1, int32_t cn2); 332 bool PreCheckForHinting(void); 333 int32_t CountSubPaths(void); 334 void PickVVals(HintVal* gValList); 335 void PickHVals(HintVal* gValList); 336 void FindBestHVals(void); 337 void FindBestVVals(void); 338 void ReportAddFlex(void); 339 void ReportLinearCurve(PathElt* e, Fixed x0, Fixed y0, Fixed x1, Fixed y1); 340 void ReportNonHError(Fixed x0, Fixed y0, Fixed x1, Fixed y1); 341 void ReportNonVError(Fixed x0, Fixed y0, Fixed x1, Fixed y1); 342 void ExpectedMoveTo(PathElt* e); 343 void ReportMissingClosePath(void); 344 void ReportTryFlexNearMiss(Fixed x0, Fixed y0, Fixed x2, Fixed y2); 345 void ReportTryFlexError(bool CPflg, Fixed x, Fixed y); 346 void ReportSplit(PathElt* e); 347 void ReportRemFlare(PathElt* e, PathElt* e2, bool hFlg, int32_t i); 348 void ReportRemConflict(PathElt* e); 349 void ReportRemShortHints(Fixed ex, Fixed ey); 350 bool ResolveConflictBySplit(PathElt* e, bool Hflg, SegLnkLst* lnk1, 351 SegLnkLst* lnk2); 352 void ReportPossibleLoop(PathElt* e); 353 void ShowHVal(HintVal* val); 354 void ShowHVals(HintVal* lst); 355 void ReportAddHVal(HintVal* val); 356 void ShowVVal(HintVal* val); 357 void ShowVVals(HintVal* lst); 358 void ReportAddVVal(HintVal* val); 359 void ReportFndBstVal(HintSeg* seg, HintVal* val, bool hFlg); 360 void ReportCarry(Fixed l0, Fixed l1, Fixed loc, HintVal* hints, bool vert); 361 void LogHintInfo(HintPoint* pl); 362 void ReportStemNearMiss(bool vert, Fixed w, Fixed minW, Fixed b, Fixed t, 363 bool curve); 364 void ReportHintConflict(Fixed x0, Fixed y0, Fixed x1, Fixed y1, char ch); 365 void ReportDuplicates(Fixed x, Fixed y); 366 void ReportBBoxBogus(Fixed llx, Fixed lly, Fixed urx, Fixed ury); 367 void ReportMergeHVal(Fixed b0, Fixed t0, Fixed b1, Fixed t1, Fixed v0, Fixed s0, 368 Fixed v1, Fixed s1); 369 void ReportMergeVVal(Fixed l0, Fixed r0, Fixed l1, Fixed r1, Fixed v0, Fixed s0, 370 Fixed v1, Fixed s1); 371 void ReportPruneHVal(HintVal* val, HintVal* v, int32_t i); 372 void ReportPruneVVal(HintVal* val, HintVal* v, int32_t i); 373 unsigned char* InitShuffleSubpaths(void); 374 void MarkLinks(HintVal* vL, bool hFlg, unsigned char* links); 375 void DoShuffleSubpaths(unsigned char* links); 376 void CopyMainH(void); 377 void CopyMainV(void); 378 void RMovePoint(Fixed dx, Fixed dy, int32_t whichcp, PathElt* e); 379 void AddVSegment(Fixed from, Fixed to, Fixed loc, PathElt* p1, PathElt* p2, 380 int32_t typ, int32_t i); 381 void AddHSegment(Fixed from, Fixed to, Fixed loc, PathElt* p1, PathElt* p2, 382 int32_t typ, int32_t i); 383 void Delete(PathElt* e); 384 bool ReadGlyph(const char* srcglyph, bool forBlendData, bool readHints); 385 double FixToDbl(Fixed f); 386 bool CompareValues(HintVal* val1, HintVal* val2, int32_t factor, 387 int32_t ghstshift); 388 void SaveFile(void); 389 void CheckForMultiMoveTo(void); 390 #define STARTUP (0) 391 #define RESTART (1) 392 393 void ListHintInfo(void); 394 395 void InitAll(int32_t reason); 396 397 void AddVStem(Fixed right, Fixed left, bool curved); 398 void AddHStem(Fixed top, Fixed bottom, bool curved); 399 400 void AddGlyphExtremes(Fixed bot, Fixed top); 401 402 bool AutoHint(const ACFontInfo* fontinfo, const char* srcbezdata, 403 bool extrahint, bool changeGlyph, bool roundCoords); 404 405 bool MergeGlyphPaths(const char** srcglyphs, int nmasters, 406 const char** masters, ACBuffer** outbuffers); 407 408 #endif /* AC_AC_H_ */ 409