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