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