1 /****************************************************************************
2  *
3  * pshints.h
4  *
5  *   Adobe's code for handling CFF hints (body).
6  *
7  * Copyright 2007-2013 Adobe Systems Incorporated.
8  *
9  * This software, and all works of authorship, whether in source or
10  * object code form as indicated by the copyright notice(s) included
11  * herein (collectively, the "Work") is made available, and may only be
12  * used, modified, and distributed under the FreeType Project License,
13  * LICENSE.TXT.  Additionally, subject to the terms and conditions of the
14  * FreeType Project License, each contributor to the Work hereby grants
15  * to any individual or legal entity exercising permissions granted by
16  * the FreeType Project License and this section (hereafter, "You" or
17  * "Your") a perpetual, worldwide, non-exclusive, no-charge,
18  * royalty-free, irrevocable (except as stated in this section) patent
19  * license to make, have made, use, offer to sell, sell, import, and
20  * otherwise transfer the Work, where such license applies only to those
21  * patent claims licensable by such contributor that are necessarily
22  * infringed by their contribution(s) alone or by combination of their
23  * contribution(s) with the Work to which such contribution(s) was
24  * submitted.  If You institute patent litigation against any entity
25  * (including a cross-claim or counterclaim in a lawsuit) alleging that
26  * the Work or a contribution incorporated within the Work constitutes
27  * direct or contributory patent infringement, then any patent licenses
28  * granted to You under this License for that Work shall terminate as of
29  * the date such litigation is filed.
30  *
31  * By using, modifying, or distributing the Work you indicate that you
32  * have read and understood the terms and conditions of the
33  * FreeType Project License as well as those provided in this section,
34  * and you accept them fully.
35  *
36  */
37 
38 
39 #ifndef PSHINT_H_
40 #define PSHINT_H_
41 
42 FT_BEGIN_HEADER
43 
44 
45   enum
46   {
47     CF2_MAX_HINTS = 96    /* maximum # of hints */
48   };
49 
50 
51   /*
52    * A HintMask object stores a bit mask that specifies which hints in the
53    * charstring are active at a given time.  Hints in CFF must be declared
54    * at the start, before any drawing operators, with horizontal hints
55    * preceding vertical hints.  The HintMask is ordered the same way, with
56    * horizontal hints immediately followed by vertical hints.  Clients are
57    * responsible for knowing how many of each type are present.
58    *
59    * The maximum total number of hints is 96, as specified by the CFF
60    * specification.
61    *
62    * A HintMask is built 0 or more times while interpreting a charstring, by
63    * the HintMask operator.  There is only one HintMask, but it is built or
64    * rebuilt each time there is a hint substitution (HintMask operator) in
65    * the charstring.  A default HintMask with all bits set is built if there
66    * has been no HintMask operator prior to the first drawing operator.
67    *
68    */
69 
70   typedef struct  CF2_HintMaskRec_
71   {
72     FT_Error*  error;
73 
74     FT_Bool  isValid;
75     FT_Bool  isNew;
76 
77     size_t  bitCount;
78     size_t  byteCount;
79 
80     FT_Byte  mask[( CF2_MAX_HINTS + 7 ) / 8];
81 
82   } CF2_HintMaskRec, *CF2_HintMask;
83 
84 
85   typedef struct  CF2_StemHintRec_
86   {
87     FT_Bool  used;     /* DS positions are valid         */
88 
89     CF2_Fixed  min;    /* original character space value */
90     CF2_Fixed  max;
91 
92     CF2_Fixed  minDS;  /* DS position after first use    */
93     CF2_Fixed  maxDS;
94 
95   } CF2_StemHintRec, *CF2_StemHint;
96 
97 
98   /*
99    * A HintMap object stores a piecewise linear function for mapping
100    * y-coordinates from character space to device space, providing
101    * appropriate pixel alignment to stem edges.
102    *
103    * The map is implemented as an array of `CF2_Hint' elements, each
104    * representing an edge.  When edges are paired, as from stem hints, the
105    * bottom edge must immediately precede the top edge in the array.
106    * Element character space AND device space positions must both increase
107    * monotonically in the array.  `CF2_Hint' elements are also used as
108    * parameters to `cf2_blues_capture'.
109    *
110    * The `cf2_hintmap_build' method must be called before any drawing
111    * operation (beginning with a Move operator) and at each hint
112    * substitution (HintMask operator).
113    *
114    * The `cf2_hintmap_map' method is called to transform y-coordinates at
115    * each drawing operation (move, line, curve).
116    *
117    */
118 
119   /* TODO: make this a CF2_ArrStack and add a deep copy method */
120   enum
121   {
122     CF2_MAX_HINT_EDGES = CF2_MAX_HINTS * 2
123   };
124 
125 
126   typedef struct  CF2_HintMapRec_
127   {
128     CF2_Font  font;
129 
130     /* initial map based on blue zones */
131     struct CF2_HintMapRec_*  initialHintMap;
132 
133     /* working storage for 2nd pass adjustHints */
134     CF2_ArrStack  hintMoves;
135 
136     FT_Bool  isValid;
137     FT_Bool  hinted;
138 
139     CF2_Fixed  scale;
140     CF2_UInt   count;
141 
142     /* start search from this index */
143     CF2_UInt  lastIndex;
144 
145     CF2_HintRec  edge[CF2_MAX_HINT_EDGES]; /* 192 */
146 
147   } CF2_HintMapRec, *CF2_HintMap;
148 
149 
150   FT_LOCAL( FT_Bool )
151   cf2_hint_isValid( const CF2_Hint  hint );
152   FT_LOCAL( FT_Bool )
153   cf2_hint_isTop( const CF2_Hint  hint );
154   FT_LOCAL( FT_Bool )
155   cf2_hint_isBottom( const CF2_Hint  hint );
156   FT_LOCAL( void )
157   cf2_hint_lock( CF2_Hint  hint );
158 
159 
160   FT_LOCAL( void )
161   cf2_hintmap_init( CF2_HintMap   hintmap,
162                     CF2_Font      font,
163                     CF2_HintMap   initialMap,
164                     CF2_ArrStack  hintMoves,
165                     CF2_Fixed     scale );
166   FT_LOCAL( void )
167   cf2_hintmap_build( CF2_HintMap   hintmap,
168                      CF2_ArrStack  hStemHintArray,
169                      CF2_ArrStack  vStemHintArray,
170                      CF2_HintMask  hintMask,
171                      CF2_Fixed     hintOrigin,
172                      FT_Bool       initialMap );
173 
174 
175   /*
176    * GlyphPath is a wrapper for drawing operations that scales the
177    * coordinates according to the render matrix and HintMap.  It also tracks
178    * open paths to control ClosePath and to insert MoveTo for broken fonts.
179    *
180    */
181   typedef struct  CF2_GlyphPathRec_
182   {
183     /* TODO: gather some of these into a hinting context */
184 
185     CF2_Font              font;           /* font instance    */
186     CF2_OutlineCallbacks  callbacks;      /* outline consumer */
187 
188 
189     CF2_HintMapRec  hintMap;        /* current hint map            */
190     CF2_HintMapRec  firstHintMap;   /* saved copy                  */
191     CF2_HintMapRec  initialHintMap; /* based on all captured hints */
192 
193     CF2_ArrStackRec  hintMoves;  /* list of hint moves for 2nd pass */
194 
195     CF2_Fixed  scaleX;         /* matrix a */
196     CF2_Fixed  scaleC;         /* matrix c */
197     CF2_Fixed  scaleY;         /* matrix d */
198 
199     FT_Vector  fractionalTranslation;  /* including deviceXScale */
200 #if 0
201     CF2_Fixed  hShift;    /* character space horizontal shift */
202                           /* (for fauxing)                    */
203 #endif
204 
205     FT_Bool  pathIsOpen;     /* true after MoveTo                     */
206     FT_Bool  pathIsClosing;  /* true when synthesizing closepath line */
207     FT_Bool  darken;         /* true if stem darkening                */
208     FT_Bool  moveIsPending;  /* true between MoveTo and offset MoveTo */
209 
210     /* references used to call `cf2_hintmap_build', if necessary */
211     CF2_ArrStack         hStemHintArray;
212     CF2_ArrStack         vStemHintArray;
213     CF2_HintMask         hintMask;     /* ptr to the current mask */
214     CF2_Fixed            hintOriginY;  /* copy of current origin  */
215     const CF2_BluesRec*  blues;
216 
217     CF2_Fixed  xOffset;        /* character space offsets */
218     CF2_Fixed  yOffset;
219 
220     /* character space miter limit threshold */
221     CF2_Fixed  miterLimit;
222     /* vertical/horizontal snap distance in character space */
223     CF2_Fixed  snapThreshold;
224 
225     FT_Vector  offsetStart0;  /* first and second points of first */
226     FT_Vector  offsetStart1;  /* element with offset applied      */
227 
228     /* current point, character space, before offset */
229     FT_Vector  currentCS;
230     /* current point, device space */
231     FT_Vector  currentDS;
232     /* start point of subpath, character space */
233     FT_Vector  start;
234 
235     /* the following members constitute the `queue' of one element */
236     FT_Bool  elemIsQueued;
237     CF2_Int  prevElemOp;
238 
239     FT_Vector  prevElemP0;
240     FT_Vector  prevElemP1;
241     FT_Vector  prevElemP2;
242     FT_Vector  prevElemP3;
243 
244   } CF2_GlyphPathRec, *CF2_GlyphPath;
245 
246 
247   FT_LOCAL( void )
248   cf2_glyphpath_init( CF2_GlyphPath         glyphpath,
249                       CF2_Font              font,
250                       CF2_OutlineCallbacks  callbacks,
251                       CF2_Fixed             scaleY,
252                       /* CF2_Fixed hShift, */
253                       CF2_ArrStack          hStemHintArray,
254                       CF2_ArrStack          vStemHintArray,
255                       CF2_HintMask          hintMask,
256                       CF2_Fixed             hintOrigin,
257                       const CF2_Blues       blues,
258                       const FT_Vector*      fractionalTranslation );
259   FT_LOCAL( void )
260   cf2_glyphpath_finalize( CF2_GlyphPath  glyphpath );
261 
262   FT_LOCAL( void )
263   cf2_glyphpath_moveTo( CF2_GlyphPath  glyphpath,
264                         CF2_Fixed      x,
265                         CF2_Fixed      y );
266   FT_LOCAL( void )
267   cf2_glyphpath_lineTo( CF2_GlyphPath  glyphpath,
268                         CF2_Fixed      x,
269                         CF2_Fixed      y );
270   FT_LOCAL( void )
271   cf2_glyphpath_curveTo( CF2_GlyphPath  glyphpath,
272                          CF2_Fixed      x1,
273                          CF2_Fixed      y1,
274                          CF2_Fixed      x2,
275                          CF2_Fixed      y2,
276                          CF2_Fixed      x3,
277                          CF2_Fixed      y3 );
278   FT_LOCAL( void )
279   cf2_glyphpath_closeOpenPath( CF2_GlyphPath  glyphpath );
280 
281 
282 FT_END_HEADER
283 
284 
285 #endif /* PSHINT_H_ */
286 
287 
288 /* END */
289