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 #include "ac.h"
11 #include "fontinfo.h"
12
13 #define MAXSTEMDIST 150 /* initial maximum stem width allowed for hints */
14
15 PathElt *gPathStart, *gPathEnd;
16 bool gUseV, gUseH, gAutoLinearCurveFix, gEditGlyph;
17 bool gHasFlex, gFlexOK, gFlexStrict, gBandError;
18 Fixed gHBigDist, gVBigDist, gInitBigDist, gMinDist, gGhostWidth, gGhostLength,
19 gBendLength, gBandMargin, gMaxFlare, gMaxBendMerge, gMaxMerge,
20 gMinHintElementLength, gFlexCand;
21 Fixed gPruneA, gPruneB, gPruneC, gPruneD, gPruneValue, gBonus;
22 float gTheta, gHBigDistR, gVBigDistR, gMaxVal, gMinVal;
23 int32_t gLenTopBands, gLenBotBands, gNumSerifs, gDMin, gDelta, gCPpercent;
24 int32_t gBendTan, gSCurveTan;
25 HintVal *gVHinting, *gHHinting, *gVPrimary, *gHPrimary, *gValList;
26 HintSeg* gSegLists[4];
27 Fixed gVStems[MAXSTEMS], gHStems[MAXSTEMS];
28 int32_t gNumVStems, gNumHStems;
29 Fixed gTopBands[MAXBLUES], gBotBands[MAXBLUES], gSerifs[MAXSERIFS];
30 HintPoint *gPointList, **gPtLstArray;
31 int32_t gPtLstIndex, gNumPtLsts, gMaxPtLsts;
32 bool gWriteHintedBez = true;
33 Fixed gBlueFuzz;
34 bool gDoAligns = false, gDoStems = false;
35 bool gRoundToInt;
36 static int maxStemDist = MAXSTEMDIST;
37
38 /* if false, then stems defined by curves are excluded from the reporting */
39 unsigned int gAllStems = false;
40 AC_REPORTSTEMPTR gAddHStemCB = NULL;
41 AC_REPORTSTEMPTR gAddVStemCB = NULL;
42 AC_REPORTZONEPTR gAddGlyphExtremesCB = NULL;
43 AC_REPORTZONEPTR gAddStemExtremesCB = NULL;
44 AC_RETRYPTR gReportRetryCB = NULL;
45 void* gAddStemUserData = NULL;
46 void* gAddExtremesUserData = NULL;
47 void* gReportRetryUserData = NULL;
48
49 #define VMSIZE (1000000)
50 static unsigned char *vmfree, *vmlast, vm[VMSIZE];
51
52 /* sub allocator */
53 void*
Alloc(int32_t sz)54 Alloc(int32_t sz)
55 {
56 unsigned char* s;
57 sz = (sz + 3) & ~3; /* make size a multiple of 4 */
58 s = vmfree;
59 vmfree += sz;
60 if (vmfree > vmlast) /* Error! need to make VMSIZE bigger */
61 {
62 LogMsg(LOGERROR, FATALERROR, "Exceeded VM size for hints.");
63 }
64 return s;
65 }
66
67 void
InitData(int32_t reason)68 InitData(int32_t reason)
69 {
70 float tmp;
71
72 gGlyphName[0] = '\0';
73
74 switch (reason) {
75 case STARTUP:
76 gDMin = 50;
77 gDelta = 0;
78 gInitBigDist = PSDist(maxStemDist);
79 /* must be <= 168 for ITC Garamond Book Italic p, q, thorn */
80 gMinDist = PSDist(7);
81 gGhostWidth = PSDist(20);
82 gGhostLength = PSDist(4);
83 gBendLength = PSDist(2);
84 gBendTan = 577; /* 30 sin 30 cos div abs == .57735 */
85 gTheta = (float).38; /* must be <= .38 for Ryumin-Light-32 c49*/
86 gPruneA = FixInt(50);
87 gPruneC = 100;
88 gPruneD = FixOne;
89 tmp = (float)10.24; /* set to 1024 times the threshold value */
90 gPruneValue = gPruneB = acpflttofix(&tmp);
91 /* pruneB must be <= .01 for Yakout/Light/heM */
92 /* pruneValue must be <= .01 for Yakout/Light/heM */
93 gCPpercent = 40;
94 /* must be < 46 for Americana-Bold d bowl vs stem hinting */
95 gBandMargin = PSDist(30);
96 gMaxFlare = PSDist(10);
97 gMaxBendMerge = PSDist(6);
98 gMaxMerge = PSDist(2); /* must be < 3 for Cushing-BookItalic z */
99 gMinHintElementLength = PSDist(12);
100 gFlexCand = PSDist(4);
101 gSCurveTan = 25;
102 gMaxVal = 8000000.0;
103 gMinVal = 1.0f / (float)(FixOne);
104 gEditGlyph = true;
105 gRoundToInt = true;
106 /* Default is to change a curve with collinear points into a line.
107 */
108 gAutoLinearCurveFix = true;
109 gFlexOK = false;
110 gFlexStrict = true;
111 gBlueFuzz = DEFAULTBLUEFUZZ;
112 /* fall through */
113 case RESTART:
114 memset((void*)vm, 0x0, VMSIZE);
115 vmfree = vm;
116 vmlast = vm + VMSIZE;
117
118 /* ?? Does this cause a leak ?? */
119 gPointList = NULL;
120 gMaxPtLsts = 128;
121 gPtLstArray = (HintPoint**)Alloc(gMaxPtLsts * sizeof(HintPoint*));
122 gPtLstIndex = 0;
123 gPtLstArray[0] = NULL;
124 gNumPtLsts = 1;
125 gAddHints = true;
126 gVHinting = NULL;
127 gHHinting = NULL;
128
129 /* if (glyphName != NULL && glyphName[0] == 'g')
130 showHintInfo = showHs = showVs = listHintInfo = true; */
131 }
132 }
133
134 /* Returns whether hinting was successful. */
135 bool
AutoHint(const ACFontInfo * fontinfo,const char * srcbezdata,bool extrahint,bool changeGlyph,bool roundCoords)136 AutoHint(const ACFontInfo* fontinfo, const char* srcbezdata, bool extrahint,
137 bool changeGlyph, bool roundCoords)
138 {
139 InitAll(STARTUP);
140
141 if (!ReadFontInfo(fontinfo))
142 return false;
143
144 gEditGlyph = changeGlyph;
145 gRoundToInt = roundCoords;
146 gAutoLinearCurveFix = gEditGlyph;
147
148 return AutoHintGlyph(srcbezdata, extrahint);
149 }
150