1 /***************************************************************************/
2 /*                                                                         */
3 /*  ftstroke.h                                                             */
4 /*                                                                         */
5 /*    FreeType path stroker (specification).                               */
6 /*                                                                         */
7 /*  Copyright 2002-2006, 2008, 2009, 2011-2012 by                          */
8 /*  David Turner, Robert Wilhelm, and Werner Lemberg.                      */
9 /*                                                                         */
10 /*  This file is part of the FreeType project, and may only be used,       */
11 /*  modified, and distributed under the terms of the FreeType project      */
12 /*  license, LICENSE.TXT.  By continuing to use, modify, or distribute     */
13 /*  this file you indicate that you have read the license and              */
14 /*  understand and accept it fully.                                        */
15 /*                                                                         */
16 /***************************************************************************/
17 
18 
19 #ifndef __FT_STROKE_H__
20 #define __FT_STROKE_H__
21 
22 #include <ft2build.h>
23 #include FT_OUTLINE_H
24 #include FT_GLYPH_H
25 
26 
27 FT_BEGIN_HEADER
28 
29 
30  /************************************************************************
31   *
32   * @section:
33   *    glyph_stroker
34   *
35   * @title:
36   *    Glyph Stroker
37   *
38   * @abstract:
39   *    Generating bordered and stroked glyphs.
40   *
41   * @description:
42   *    This component generates stroked outlines of a given vectorial
43   *    glyph.  It also allows you to retrieve the `outside' and/or the
44   *    `inside' borders of the stroke.
45   *
46   *    This can be useful to generate `bordered' glyph, i.e., glyphs
47   *    displayed with a coloured (and anti-aliased) border around their
48   *    shape.
49   */
50 
51 
52  /**************************************************************
53   *
54   * @type:
55   *   FT_Stroker
56   *
57   * @description:
58   *   Opaque handler to a path stroker object.
59   */
60   typedef struct FT_StrokerRec_*  FT_Stroker;
61 
62 
63   /**************************************************************
64    *
65    * @enum:
66    *   FT_Stroker_LineJoin
67    *
68    * @description:
69    *   These values determine how two joining lines are rendered
70    *   in a stroker.
71    *
72    * @values:
73    *   FT_STROKER_LINEJOIN_ROUND ::
74    *     Used to render rounded line joins.  Circular arcs are used
75    *     to join two lines smoothly.
76    *
77    *   FT_STROKER_LINEJOIN_BEVEL ::
78    *     Used to render beveled line joins.  The outer corner of
79    *     the joined lines is filled by enclosing the triangular
80    *     region of the corner with a straight line between the
81    *     outer corners of each stroke.
82    *
83    *   FT_STROKER_LINEJOIN_MITER_FIXED ::
84    *     Used to render mitered line joins, with fixed bevels if the
85    *     miter limit is exceeded.  The outer edges of the strokes
86    *     for the two segments are extended until they meet at an
87    *     angle.  If the segments meet at too sharp an angle (such
88    *     that the miter would extend from the intersection of the
89    *     segments a distance greater than the product of the miter
90    *     limit value and the border radius), then a bevel join (see
91    *     above) is used instead.  This prevents long spikes being
92    *     created.  FT_STROKER_LINEJOIN_MITER_FIXED generates a miter
93    *     line join as used in PostScript and PDF.
94    *
95    *   FT_STROKER_LINEJOIN_MITER_VARIABLE ::
96    *   FT_STROKER_LINEJOIN_MITER ::
97    *     Used to render mitered line joins, with variable bevels if
98    *     the miter limit is exceeded.  The intersection of the
99    *     strokes is clipped at a line perpendicular to the bisector
100    *     of the angle between the strokes, at the distance from the
101    *     intersection of the segments equal to the product of the
102    *     miter limit value and the border radius.  This prevents
103    *     long spikes being created.
104    *     FT_STROKER_LINEJOIN_MITER_VARIABLE generates a mitered line
105    *     join as used in XPS.  FT_STROKER_LINEJOIN_MITER is an alias
106    *     for FT_STROKER_LINEJOIN_MITER_VARIABLE, retained for
107    *     backwards compatibility.
108    */
109   typedef enum  FT_Stroker_LineJoin_
110   {
111     FT_STROKER_LINEJOIN_ROUND          = 0,
112     FT_STROKER_LINEJOIN_BEVEL          = 1,
113     FT_STROKER_LINEJOIN_MITER_VARIABLE = 2,
114     FT_STROKER_LINEJOIN_MITER          = FT_STROKER_LINEJOIN_MITER_VARIABLE,
115     FT_STROKER_LINEJOIN_MITER_FIXED    = 3
116 
117   } FT_Stroker_LineJoin;
118 
119 
120   /**************************************************************
121    *
122    * @enum:
123    *   FT_Stroker_LineCap
124    *
125    * @description:
126    *   These values determine how the end of opened sub-paths are
127    *   rendered in a stroke.
128    *
129    * @values:
130    *   FT_STROKER_LINECAP_BUTT ::
131    *     The end of lines is rendered as a full stop on the last
132    *     point itself.
133    *
134    *   FT_STROKER_LINECAP_ROUND ::
135    *     The end of lines is rendered as a half-circle around the
136    *     last point.
137    *
138    *   FT_STROKER_LINECAP_SQUARE ::
139    *     The end of lines is rendered as a square around the
140    *     last point.
141    */
142   typedef enum  FT_Stroker_LineCap_
143   {
144     FT_STROKER_LINECAP_BUTT = 0,
145     FT_STROKER_LINECAP_ROUND,
146     FT_STROKER_LINECAP_SQUARE
147 
148   } FT_Stroker_LineCap;
149 
150 
151   /**************************************************************
152    *
153    * @enum:
154    *   FT_StrokerBorder
155    *
156    * @description:
157    *   These values are used to select a given stroke border
158    *   in @FT_Stroker_GetBorderCounts and @FT_Stroker_ExportBorder.
159    *
160    * @values:
161    *   FT_STROKER_BORDER_LEFT ::
162    *     Select the left border, relative to the drawing direction.
163    *
164    *   FT_STROKER_BORDER_RIGHT ::
165    *     Select the right border, relative to the drawing direction.
166    *
167    * @note:
168    *   Applications are generally interested in the `inside' and `outside'
169    *   borders.  However, there is no direct mapping between these and the
170    *   `left' and `right' ones, since this really depends on the glyph's
171    *   drawing orientation, which varies between font formats.
172    *
173    *   You can however use @FT_Outline_GetInsideBorder and
174    *   @FT_Outline_GetOutsideBorder to get these.
175    */
176   typedef enum  FT_StrokerBorder_
177   {
178     FT_STROKER_BORDER_LEFT = 0,
179     FT_STROKER_BORDER_RIGHT
180 
181   } FT_StrokerBorder;
182 
183 
184   /**************************************************************
185    *
186    * @function:
187    *   FT_Outline_GetInsideBorder
188    *
189    * @description:
190    *   Retrieve the @FT_StrokerBorder value corresponding to the
191    *   `inside' borders of a given outline.
192    *
193    * @input:
194    *   outline ::
195    *     The source outline handle.
196    *
197    * @return:
198    *   The border index.  @FT_STROKER_BORDER_RIGHT for empty or invalid
199    *   outlines.
200    */
201   FT_EXPORT( FT_StrokerBorder )
202   FT_Outline_GetInsideBorder( FT_Outline*  outline );
203 
204 
205   /**************************************************************
206    *
207    * @function:
208    *   FT_Outline_GetOutsideBorder
209    *
210    * @description:
211    *   Retrieve the @FT_StrokerBorder value corresponding to the
212    *   `outside' borders of a given outline.
213    *
214    * @input:
215    *   outline ::
216    *     The source outline handle.
217    *
218    * @return:
219    *   The border index.  @FT_STROKER_BORDER_LEFT for empty or invalid
220    *   outlines.
221    */
222   FT_EXPORT( FT_StrokerBorder )
223   FT_Outline_GetOutsideBorder( FT_Outline*  outline );
224 
225 
226   /**************************************************************
227    *
228    * @function:
229    *   FT_Stroker_New
230    *
231    * @description:
232    *   Create a new stroker object.
233    *
234    * @input:
235    *   library ::
236    *     FreeType library handle.
237    *
238    * @output:
239    *   astroker ::
240    *     A new stroker object handle.  NULL in case of error.
241    *
242    * @return:
243    *    FreeType error code.  0~means success.
244    */
245   FT_EXPORT( FT_Error )
246   FT_Stroker_New( FT_Library   library,
247                   FT_Stroker  *astroker );
248 
249 
250   /**************************************************************
251    *
252    * @function:
253    *   FT_Stroker_Set
254    *
255    * @description:
256    *   Reset a stroker object's attributes.
257    *
258    * @input:
259    *   stroker ::
260    *     The target stroker handle.
261    *
262    *   radius ::
263    *     The border radius.
264    *
265    *   line_cap ::
266    *     The line cap style.
267    *
268    *   line_join ::
269    *     The line join style.
270    *
271    *   miter_limit ::
272    *     The miter limit for the FT_STROKER_LINEJOIN_MITER_FIXED and
273    *     FT_STROKER_LINEJOIN_MITER_VARIABLE line join styles,
274    *     expressed as 16.16 fixed-point value.
275    *
276    * @note:
277    *   The radius is expressed in the same units as the outline
278    *   coordinates.
279    */
280   FT_EXPORT( void )
281   FT_Stroker_Set( FT_Stroker           stroker,
282                   FT_Fixed             radius,
283                   FT_Stroker_LineCap   line_cap,
284                   FT_Stroker_LineJoin  line_join,
285                   FT_Fixed             miter_limit );
286 
287 
288   /**************************************************************
289    *
290    * @function:
291    *   FT_Stroker_Rewind
292    *
293    * @description:
294    *   Reset a stroker object without changing its attributes.
295    *   You should call this function before beginning a new
296    *   series of calls to @FT_Stroker_BeginSubPath or
297    *   @FT_Stroker_EndSubPath.
298    *
299    * @input:
300    *   stroker ::
301    *     The target stroker handle.
302    */
303   FT_EXPORT( void )
304   FT_Stroker_Rewind( FT_Stroker  stroker );
305 
306 
307   /**************************************************************
308    *
309    * @function:
310    *   FT_Stroker_ParseOutline
311    *
312    * @description:
313    *   A convenience function used to parse a whole outline with
314    *   the stroker.  The resulting outline(s) can be retrieved
315    *   later by functions like @FT_Stroker_GetCounts and @FT_Stroker_Export.
316    *
317    * @input:
318    *   stroker ::
319    *     The target stroker handle.
320    *
321    *   outline ::
322    *     The source outline.
323    *
324    *   opened ::
325    *     A boolean.  If~1, the outline is treated as an open path instead
326    *     of a closed one.
327    *
328    * @return:
329    *   FreeType error code.  0~means success.
330    *
331    * @note:
332    *   If `opened' is~0 (the default), the outline is treated as a closed
333    *   path, and the stroker generates two distinct `border' outlines.
334    *
335    *   If `opened' is~1, the outline is processed as an open path, and the
336    *   stroker generates a single `stroke' outline.
337    *
338    *   This function calls @FT_Stroker_Rewind automatically.
339    */
340   FT_EXPORT( FT_Error )
341   FT_Stroker_ParseOutline( FT_Stroker   stroker,
342                            FT_Outline*  outline,
343                            FT_Bool      opened );
344 
345 
346   /**************************************************************
347    *
348    * @function:
349    *   FT_Stroker_BeginSubPath
350    *
351    * @description:
352    *   Start a new sub-path in the stroker.
353    *
354    * @input:
355    *   stroker ::
356    *     The target stroker handle.
357    *
358    *   to ::
359    *     A pointer to the start vector.
360    *
361    *   open ::
362    *     A boolean.  If~1, the sub-path is treated as an open one.
363    *
364    * @return:
365    *   FreeType error code.  0~means success.
366    *
367    * @note:
368    *   This function is useful when you need to stroke a path that is
369    *   not stored as an @FT_Outline object.
370    */
371   FT_EXPORT( FT_Error )
372   FT_Stroker_BeginSubPath( FT_Stroker  stroker,
373                            FT_Vector*  to,
374                            FT_Bool     open );
375 
376 
377   /**************************************************************
378    *
379    * @function:
380    *   FT_Stroker_EndSubPath
381    *
382    * @description:
383    *   Close the current sub-path in the stroker.
384    *
385    * @input:
386    *   stroker ::
387    *     The target stroker handle.
388    *
389    * @return:
390    *   FreeType error code.  0~means success.
391    *
392    * @note:
393    *   You should call this function after @FT_Stroker_BeginSubPath.
394    *   If the subpath was not `opened', this function `draws' a
395    *   single line segment to the start position when needed.
396    */
397   FT_EXPORT( FT_Error )
398   FT_Stroker_EndSubPath( FT_Stroker  stroker );
399 
400 
401   /**************************************************************
402    *
403    * @function:
404    *   FT_Stroker_LineTo
405    *
406    * @description:
407    *   `Draw' a single line segment in the stroker's current sub-path,
408    *   from the last position.
409    *
410    * @input:
411    *   stroker ::
412    *     The target stroker handle.
413    *
414    *   to ::
415    *     A pointer to the destination point.
416    *
417    * @return:
418    *   FreeType error code.  0~means success.
419    *
420    * @note:
421    *   You should call this function between @FT_Stroker_BeginSubPath and
422    *   @FT_Stroker_EndSubPath.
423    */
424   FT_EXPORT( FT_Error )
425   FT_Stroker_LineTo( FT_Stroker  stroker,
426                      FT_Vector*  to );
427 
428 
429   /**************************************************************
430    *
431    * @function:
432    *   FT_Stroker_ConicTo
433    *
434    * @description:
435    *   `Draw' a single quadratic Bézier in the stroker's current sub-path,
436    *   from the last position.
437    *
438    * @input:
439    *   stroker ::
440    *     The target stroker handle.
441    *
442    *   control ::
443    *     A pointer to a Bézier control point.
444    *
445    *   to ::
446    *     A pointer to the destination point.
447    *
448    * @return:
449    *   FreeType error code.  0~means success.
450    *
451    * @note:
452    *   You should call this function between @FT_Stroker_BeginSubPath and
453    *   @FT_Stroker_EndSubPath.
454    */
455   FT_EXPORT( FT_Error )
456   FT_Stroker_ConicTo( FT_Stroker  stroker,
457                       FT_Vector*  control,
458                       FT_Vector*  to );
459 
460 
461   /**************************************************************
462    *
463    * @function:
464    *   FT_Stroker_CubicTo
465    *
466    * @description:
467    *   `Draw' a single cubic Bézier in the stroker's current sub-path,
468    *   from the last position.
469    *
470    * @input:
471    *   stroker ::
472    *     The target stroker handle.
473    *
474    *   control1 ::
475    *     A pointer to the first Bézier control point.
476    *
477    *   control2 ::
478    *     A pointer to second Bézier control point.
479    *
480    *   to ::
481    *     A pointer to the destination point.
482    *
483    * @return:
484    *   FreeType error code.  0~means success.
485    *
486    * @note:
487    *   You should call this function between @FT_Stroker_BeginSubPath and
488    *   @FT_Stroker_EndSubPath.
489    */
490   FT_EXPORT( FT_Error )
491   FT_Stroker_CubicTo( FT_Stroker  stroker,
492                       FT_Vector*  control1,
493                       FT_Vector*  control2,
494                       FT_Vector*  to );
495 
496 
497   /**************************************************************
498    *
499    * @function:
500    *   FT_Stroker_GetBorderCounts
501    *
502    * @description:
503    *   Call this function once you have finished parsing your paths
504    *   with the stroker.  It returns the number of points and
505    *   contours necessary to export one of the `border' or `stroke'
506    *   outlines generated by the stroker.
507    *
508    * @input:
509    *   stroker ::
510    *     The target stroker handle.
511    *
512    *   border ::
513    *     The border index.
514    *
515    * @output:
516    *   anum_points ::
517    *     The number of points.
518    *
519    *   anum_contours ::
520    *     The number of contours.
521    *
522    * @return:
523    *   FreeType error code.  0~means success.
524    *
525    * @note:
526    *   When an outline, or a sub-path, is `closed', the stroker generates
527    *   two independent `border' outlines, named `left' and `right'.
528    *
529    *   When the outline, or a sub-path, is `opened', the stroker merges
530    *   the `border' outlines with caps.  The `left' border receives all
531    *   points, while the `right' border becomes empty.
532    *
533    *   Use the function @FT_Stroker_GetCounts instead if you want to
534    *   retrieve the counts associated to both borders.
535    */
536   FT_EXPORT( FT_Error )
537   FT_Stroker_GetBorderCounts( FT_Stroker        stroker,
538                               FT_StrokerBorder  border,
539                               FT_UInt          *anum_points,
540                               FT_UInt          *anum_contours );
541 
542 
543   /**************************************************************
544    *
545    * @function:
546    *   FT_Stroker_ExportBorder
547    *
548    * @description:
549    *   Call this function after @FT_Stroker_GetBorderCounts to
550    *   export the corresponding border to your own @FT_Outline
551    *   structure.
552    *
553    *   Note that this function appends the border points and
554    *   contours to your outline, but does not try to resize its
555    *   arrays.
556    *
557    * @input:
558    *   stroker ::
559    *     The target stroker handle.
560    *
561    *   border ::
562    *     The border index.
563    *
564    *   outline ::
565    *     The target outline handle.
566    *
567    * @note:
568    *   Always call this function after @FT_Stroker_GetBorderCounts to
569    *   get sure that there is enough room in your @FT_Outline object to
570    *   receive all new data.
571    *
572    *   When an outline, or a sub-path, is `closed', the stroker generates
573    *   two independent `border' outlines, named `left' and `right'
574    *
575    *   When the outline, or a sub-path, is `opened', the stroker merges
576    *   the `border' outlines with caps. The `left' border receives all
577    *   points, while the `right' border becomes empty.
578    *
579    *   Use the function @FT_Stroker_Export instead if you want to
580    *   retrieve all borders at once.
581    */
582   FT_EXPORT( void )
583   FT_Stroker_ExportBorder( FT_Stroker        stroker,
584                            FT_StrokerBorder  border,
585                            FT_Outline*       outline );
586 
587 
588   /**************************************************************
589    *
590    * @function:
591    *   FT_Stroker_GetCounts
592    *
593    * @description:
594    *   Call this function once you have finished parsing your paths
595    *   with the stroker.  It returns the number of points and
596    *   contours necessary to export all points/borders from the stroked
597    *   outline/path.
598    *
599    * @input:
600    *   stroker ::
601    *     The target stroker handle.
602    *
603    * @output:
604    *   anum_points ::
605    *     The number of points.
606    *
607    *   anum_contours ::
608    *     The number of contours.
609    *
610    * @return:
611    *   FreeType error code.  0~means success.
612    */
613   FT_EXPORT( FT_Error )
614   FT_Stroker_GetCounts( FT_Stroker  stroker,
615                         FT_UInt    *anum_points,
616                         FT_UInt    *anum_contours );
617 
618 
619   /**************************************************************
620    *
621    * @function:
622    *   FT_Stroker_Export
623    *
624    * @description:
625    *   Call this function after @FT_Stroker_GetBorderCounts to
626    *   export all borders to your own @FT_Outline structure.
627    *
628    *   Note that this function appends the border points and
629    *   contours to your outline, but does not try to resize its
630    *   arrays.
631    *
632    * @input:
633    *   stroker ::
634    *     The target stroker handle.
635    *
636    *   outline ::
637    *     The target outline handle.
638    */
639   FT_EXPORT( void )
640   FT_Stroker_Export( FT_Stroker   stroker,
641                      FT_Outline*  outline );
642 
643 
644   /**************************************************************
645    *
646    * @function:
647    *   FT_Stroker_Done
648    *
649    * @description:
650    *   Destroy a stroker object.
651    *
652    * @input:
653    *   stroker ::
654    *     A stroker handle.  Can be NULL.
655    */
656   FT_EXPORT( void )
657   FT_Stroker_Done( FT_Stroker  stroker );
658 
659 
660   /**************************************************************
661    *
662    * @function:
663    *   FT_Glyph_Stroke
664    *
665    * @description:
666    *   Stroke a given outline glyph object with a given stroker.
667    *
668    * @inout:
669    *   pglyph ::
670    *     Source glyph handle on input, new glyph handle on output.
671    *
672    * @input:
673    *   stroker ::
674    *     A stroker handle.
675    *
676    *   destroy ::
677    *     A Boolean.  If~1, the source glyph object is destroyed
678    *     on success.
679    *
680    * @return:
681    *    FreeType error code.  0~means success.
682    *
683    * @note:
684    *   The source glyph is untouched in case of error.
685    *
686    *   Adding stroke may yield a significantly wider and taller glyph
687    *   depending on how large of a radius was used to stroke the glyph.  You
688    *   may need to manually adjust horizontal and vertical advance amounts
689    *   to account for this added size.
690    */
691   FT_EXPORT( FT_Error )
692   FT_Glyph_Stroke( FT_Glyph    *pglyph,
693                    FT_Stroker   stroker,
694                    FT_Bool      destroy );
695 
696 
697   /**************************************************************
698    *
699    * @function:
700    *   FT_Glyph_StrokeBorder
701    *
702    * @description:
703    *   Stroke a given outline glyph object with a given stroker, but
704    *   only return either its inside or outside border.
705    *
706    * @inout:
707    *   pglyph ::
708    *     Source glyph handle on input, new glyph handle on output.
709    *
710    * @input:
711    *   stroker ::
712    *     A stroker handle.
713    *
714    *   inside ::
715    *     A Boolean.  If~1, return the inside border, otherwise
716    *     the outside border.
717    *
718    *   destroy ::
719    *     A Boolean.  If~1, the source glyph object is destroyed
720    *     on success.
721    *
722    * @return:
723    *    FreeType error code.  0~means success.
724    *
725    * @note:
726    *   The source glyph is untouched in case of error.
727    *
728    *   Adding stroke may yield a significantly wider and taller glyph
729    *   depending on how large of a radius was used to stroke the glyph.  You
730    *   may need to manually adjust horizontal and vertical advance amounts
731    *   to account for this added size.
732    */
733   FT_EXPORT( FT_Error )
734   FT_Glyph_StrokeBorder( FT_Glyph    *pglyph,
735                          FT_Stroker   stroker,
736                          FT_Bool      inside,
737                          FT_Bool      destroy );
738 
739  /* */
740 
741 FT_END_HEADER
742 
743 #endif /* __FT_STROKE_H__ */
744 
745 
746 /* END */
747 
748 
749 /* Local Variables: */
750 /* coding: utf-8    */
751 /* End:             */
752