1/*!
2 * \file path.hpp
3 * \brief file path.hpp
4 *
5 * Copyright 2016 by Intel.
6 *
7 * Contact: kevin.rogovin@gmail.com
8 *
9 * This Source Code Form is subject to the
10 * terms of the Mozilla Public License, v. 2.0.
11 * If a copy of the MPL was not distributed with
12 * this file, You can obtain one at
13 * http://mozilla.org/MPL/2.0/.
14 *
15 * \author Kevin Rogovin <kevin.rogovin@gmail.com>
16 *
17 */
18
19
20
21#ifndef FASTUIDRAW_PATH_HPP
22#define FASTUIDRAW_PATH_HPP
23
24#include <fastuidraw/util/fastuidraw_memory.hpp>
25#include <fastuidraw/util/vecN.hpp>
26#include <fastuidraw/util/rect.hpp>
27#include <fastuidraw/util/c_array.hpp>
28#include <fastuidraw/util/reference_counted.hpp>
29#include <fastuidraw/path_enums.hpp>
30#include <fastuidraw/tessellated_path.hpp>
31#include <fastuidraw/painter/shader_filled_path.hpp>
32
33namespace fastuidraw {
34
35/*!\addtogroup Paths
36 * @{
37 */
38
39/*!
40 * \brief
41 * An PathContour represents a single contour within
42 * a Path.
43 *
44 * Closeing a contour (see \ref close(), \ref
45 * close_generic() and close_arc()) means to specify
46 * the edge from the last point of the PathContour
47 * to the first point.
48 */
49class PathContour:
50 public reference_counted<PathContour>::non_concurrent
51{
52public:
53 /*!
54 * \brief
55 * Provides an interface to resume from a previous tessellation
56 * of a \ref interpolator_base derived object.
57 */
58 class tessellation_state:
59 public reference_counted<tessellation_state>::non_concurrent
60 {
61 public:
62 /*!
63 * To be implemented by a derived class to return the depth
64 * of recursion at this objects stage of tessellation.
65 */
66 virtual
67 unsigned int
68 recursion_depth(void) const = 0;
69
70 /*!
71 * To be implemented by a derived class to resume tessellation
72 * and to (try to) achieve the required threshhold within the
73 * recursion limits of a \ref TessellatedPath::TessellationParams
74 * value.
75 * \param tess_params tessellation parameters
76 * \param out_data location to which to write the tessellations
77 * \param out_max_distance location to which to write an upperbound for the
78 * distance between the curve and the tesseallation
79 * approximation.
80 */
81 virtual
82 void
83 resume_tessellation(const TessellatedPath::TessellationParams &tess_params,
84 TessellatedPath::SegmentStorage *out_data,
85 float *out_max_distance) = 0;
86 };
87
88 /*!
89 * \brief
90 * Base class to describe how to interpolate from one
91 * point of a PathContour to the next, i.e. describes
92 * the shape of an edge.
93 */
94 class interpolator_base:
95 public reference_counted<interpolator_base>::non_concurrent
96 {
97 public:
98 /*!
99 * Ctor.
100 * \param contour \ref PathContour to which to add the interpolator.
101 * The interpolator is added to the contour at the
102 * interpolator's construction. The start point is
103 * computed from the current state of the \ref
104 * PathContour.
105 * \param end end point of the edge of this interpolator
106 * \param tp nature the edge represented by this interpolator_base
107 */
108 interpolator_base(PathContour &contour,
109 const vec2 &end, enum PathEnums::edge_type_t tp);
110
111 virtual
112 ~interpolator_base();
113
114 /*!
115 * Returns the starting point of this interpolator.
116 */
117 const vec2&
118 start_pt(void) const;
119
120 /*!
121 * Returns the ending point of this interpolator
122 */
123 const vec2&
124 end_pt(void) const;
125
126 /*!
127 * Returns the edge type.
128 */
129 enum PathEnums::edge_type_t
130 edge_type(void) const;
131
132 /*!
133 * To be implemented by a derived class to return true if
134 * the interpolator is flat, i.e. is just a line segment
135 * connecting start_pt() to end_pt().
136 */
137 virtual
138 bool
139 is_flat(void) const = 0;
140
141 /*!
142 * To be implemented by a derived class to produce the arc-tessellation
143 * from start_pt() to end_pt(). In addition, for recursive tessellation,
144 * returns the tessellation state to be queried for recursion depth and
145 * reused to refine the tessellation. If the tessellation routine is not
146 * recursive in nature, return nullptr.
147 *
148 * \param tess_params tessellation parameters
149 * \param out_data location to which to write the tessellations
150 * \param out_max_distance location to which to write an upperbound for the
151 * distance between the curve and the tesseallation
152 * approximation.
153 */
154 virtual
155 reference_counted_ptr<tessellation_state>
156 produce_tessellation(const TessellatedPath::TessellationParams &tess_params,
157 TessellatedPath::SegmentStorage *out_data,
158 float *out_max_distance) const = 0;
159
160 /*!
161 * To be implemented by a derived class to return a fast (and approximate)
162 * bounding box for the interpolator.
163 * \param out_bb (output) location to which to write the bounding box value
164 */
165 virtual
166 void
167 approximate_bounding_box(Rect *out_bb) const = 0;
168
169 /*!
170 * To be implemented by a derived class to create and
171 * return a deep copy of the interpolator object.
172 */
173 virtual
174 reference_counted_ptr<interpolator_base>
175 deep_copy(PathContour &contour) const = 0;
176
177 /*!
178 * To be optionally implemented by a derived class to add this
179 * interpolator to a \ref ShaderFilledPath::Builder. A return
180 * code of \ref routine_fail means that the interpolator cannot
181 * be realized in such a way to be added and a \ref Path that
182 * includes such an interpolator in a closed contour will
183 * be unable to realized a \ref ShaderFilledPath value and
184 * \ref Path::shader_filled_path() will return a null handle.
185 * Default implementation is to return routine_fail.
186 * \param builder object to which to add interpolator.
187 * \param tol error goal between the interpolator and how it
188 * is realized on the ShaderFilledPath::Builder
189 */
190 virtual
191 enum return_code
192 add_to_builder(ShaderFilledPath::Builder *builder, float tol) const;
193
194 private:
195 friend class PathContour;
196 void *m_d;
197 };
198
199 /*!
200 * \brief
201 * A flat interpolator represents a flat edge.
202 */
203 class flat:public interpolator_base
204 {
205 public:
206 /*!
207 * Ctor.
208 * \param contour \ref PathContour to which to add the interpolator.
209 * The interpolator is added to the contour at the
210 * interpolator's construction. The start point is
211 * computed from the current state of the \ref
212 * PathContour
213 * \param end end point of the edge of this interpolator
214 * \param tp nature the edge represented by this interpolator_base
215 */
216 flat(PathContour &contour,
217 const vec2 &end, enum PathEnums::edge_type_t tp):
218 interpolator_base(contour, end, tp)
219 {}
220
221 virtual
222 bool
223 is_flat(void) const;
224
225 virtual
226 reference_counted_ptr<tessellation_state>
227 produce_tessellation(const TessellatedPath::TessellationParams &tess_params,
228 TessellatedPath::SegmentStorage *out_data,
229 float *out_max_distance) const;
230 virtual
231 void
232 approximate_bounding_box(Rect *out_bb) const;
233
234 virtual
235 reference_counted_ptr<interpolator_base>
236 deep_copy(PathContour &contour) const;
237
238 virtual
239 enum return_code
240 add_to_builder(ShaderFilledPath::Builder *builder, float tol) const;
241 };
242
243 /*!
244 * \brief
245 * Interpolator generic implements tessellation by recursion
246 * and relying on analytic derivative provided by derived
247 * class.
248 */
249 class interpolator_generic:public interpolator_base
250 {
251 public:
252 /*!
253 * A tessellated_region is a base class for a cookie
254 * used and generated by tessellate().
255 */
256 class tessellated_region:
257 public reference_counted<tessellated_region>::non_concurrent
258 {
259 public:
260 /*!
261 * To be implemented by a derived class to compute an upper-bound
262 * of the distance from the curve restricted to the region to the
263 * line segment connecting the end points of the region.
264 */
265 virtual
266 float
267 distance_to_line_segment(void) const = 0;
268
269 /*!
270 * To be implemented by a derived class to compute an approximate
271 * upper-bound for the distance from the curve restricted to the
272 * region to a given arc.
273 * \param arc_radius radius of the arc
274 * \param center center of the circle of the arc
275 * \param unit_vector_arc_middle unit vector from center to the midpoint of the arc
276 * \param cos_half_arc_angle the cosine of half of the arc-angle
277 */
278 virtual
279 float
280 distance_to_arc(float arc_radius, vec2 center,
281 vec2 unit_vector_arc_middle,
282 float cos_half_arc_angle) const = 0;
283 };
284
285 /*!
286 * Ctor.
287 * \param contour \ref PathContour to which the interpolator is added,
288 * the start point of the interpolator will be ending
289 * point of \ref PathContour::prev_interpolator().
290 * \param end end point of the edge of this interpolator
291 * \param tp nature the edge represented by this interpolator_base
292 */
293 interpolator_generic(PathContour &contour,
294 const vec2 &end, enum PathEnums::edge_type_t tp):
295 interpolator_base(contour, end, tp)
296 {}
297
298 virtual
299 reference_counted_ptr<tessellation_state>
300 produce_tessellation(const TessellatedPath::TessellationParams &tess_params,
301 TessellatedPath::SegmentStorage *out_data,
302 float *out_max_distance) const;
303
304 /*!
305 * To be implemented by a derived to assist in recursive tessellation.
306 * \param in_region region to divide in half, a nullptr value indicates
307 * that the region is the entire interpolator.
308 * \param out_regionA location to which to write the first half
309 * \param out_regionB location to which to write the second half
310 * \param out_p location to which to write the position of the point
311 * on the curve in the middle (with repsect to time) of
312 * in_region
313 */
314 virtual
315 void
316 tessellate(reference_counted_ptr<tessellated_region> in_region,
317 reference_counted_ptr<tessellated_region> *out_regionA,
318 reference_counted_ptr<tessellated_region> *out_regionB,
319 vec2 *out_p) const = 0;
320
321 /*!
322 * To be implemented by a derived class to return a reasonable
323 * lower bound on the needed number of times the edge should be
324 * cut in half in order to capture its shape.
325 */
326 virtual
327 unsigned int
328 minimum_tessellation_recursion(void) const = 0;
329 };
330
331 /*!
332 * \brief
333 * Derived class of interpolator_base to indicate a Bezier curve.
334 * Supports Bezier curves of _any_ degree.
335 */
336 class bezier:public interpolator_generic
337 {
338 public:
339 /*!
340 * Ctor. One control point, thus interpolation is a quadratic curve.
341 * \param contour \ref PathContour to which to add the interpolator.
342 * The interpolator is added to the contour at the
343 * interpolator's construction. The start point is
344 * computed from the current state of the \ref
345 * PathContour
346 * \param ct control point
347 * \param end end of curve
348 * \param tp nature the edge represented by this interpolator_base
349 */
350 bezier(PathContour &contour,
351 const vec2 &ct, const vec2 &end, enum PathEnums::edge_type_t tp);
352
353 /*!
354 * Ctor. Two control points, thus interpolation is a cubic curve.
355 * \param contour \ref PathContour to which to add the interpolator.
356 * The interpolator is added to the contour at the
357 * interpolator's construction. The start point is
358 * computed from the current state of the \ref
359 * PathContour
360 * \param ct1 1st control point
361 * \param ct2 2nd control point
362 * \param end end point of curve
363 * \param tp nature the edge represented by this interpolator_base
364 */
365 bezier(PathContour &contour,
366 const vec2 &ct1, const vec2 &ct2, const vec2 &end,
367 enum PathEnums::edge_type_t tp);
368
369 /*!
370 * Ctor. Iterator range defines the control points of the bezier curve.
371 * \param contour \ref PathContour to which to add the interpolator.
372 * The interpolator is added to the contour at the
373 * interpolator's construction. The start point is
374 * computed from the current state of the \ref
375 * PathContour
376 * \param control_pts control points of the bezier curve created,
377 * can be any size allowing bezier curves of
378 * arbitrary degree
379 * \param end end point of curve
380 * \param tp nature the edge represented by this interpolator_base
381 */
382 bezier(PathContour &contour,
383 c_array<const vec2> control_pts, const vec2 &end,
384 enum PathEnums::edge_type_t tp);
385
386 virtual
387 ~bezier();
388
389 /*!
390 * Returns the control points of the Bezier curve with
391 * c_array<const vec2>::front() having the same value as
392 * start_pt() and c_array<const vec2>::back() having the
393 * same value as end_pt().
394 */
395 c_array<const vec2>
396 pts(void) const;
397
398 virtual
399 bool
400 is_flat(void) const;
401
402 virtual
403 void
404 tessellate(reference_counted_ptr<tessellated_region> in_region,
405 reference_counted_ptr<tessellated_region> *out_regionA,
406 reference_counted_ptr<tessellated_region> *out_regionB,
407 vec2 *out_p) const;
408 virtual
409 void
410 approximate_bounding_box(Rect *out_bb) const;
411
412 virtual
413 reference_counted_ptr<interpolator_base>
414 deep_copy(PathContour &contour) const;
415
416 virtual
417 unsigned int
418 minimum_tessellation_recursion(void) const;
419
420 virtual
421 enum return_code
422 add_to_builder(ShaderFilledPath::Builder *builder, float tol) const;
423
424 private:
425 void *m_d;
426 };
427
428 /*!
429 * \brief
430 * An arc is for connecting one point to the next via an
431 * arc of a circle.
432 */
433 class arc:public interpolator_base
434 {
435 public:
436 /*!
437 * Ctor.
438 * \param contour \ref PathContour to which to add the interpolator.
439 * The interpolator is added to the contour at the
440 * interpolator's construction. The start point is
441 * computed from the current state of the \ref
442 * PathContour
443 * \param angle The angle of the arc in radians, the value must not
444 * be a multiple of 2*FASTUIDRAW_PI. Assuming a coordinate system
445 * where y-increases vertically and x-increases to the right,
446 * a positive value indicates to have the arc go counter-clockwise,
447 * a negative angle for the arc to go clockwise.
448 * \param end end of curve
449 * \param tp nature the edge represented by this interpolator_base
450 */
451 arc(PathContour &contour,
452 float angle, const vec2 &end, enum PathEnums::edge_type_t tp);
453
454 ~arc();
455
456 /*!
457 * Returns the center of the arc.
458 */
459 vec2
460 center(void) const;
461
462 /*!
463 * Returns the starting and ending angle of the arc
464 * each in radians.
465 */
466 range_type<float>
467 angle(void) const;
468
469 virtual
470 bool
471 is_flat(void) const;
472
473 virtual
474 void
475 approximate_bounding_box(Rect *out_bb) const;
476
477 virtual
478 reference_counted_ptr<interpolator_base>
479 deep_copy(PathContour &contour) const;
480
481 virtual
482 reference_counted_ptr<tessellation_state>
483 produce_tessellation(const TessellatedPath::TessellationParams &tess_params,
484 TessellatedPath::SegmentStorage *out_data,
485 float *out_max_distance) const;
486
487 virtual
488 enum return_code
489 add_to_builder(ShaderFilledPath::Builder *builder, float tol) const;
490
491 private:
492 arc(const arc &q, PathContour &contour);
493
494 void *m_d;
495 };
496
497 /*!
498 * Ctor.
499 */
500 explicit
501 PathContour(void);
502
503 ~PathContour();
504
505 /*!
506 * Start the PathContour, may only be called once in the lifetime
507 * of a PathContour() and must be called before adding points
508 * (to_point()), adding control points (add_control_point()),
509 * adding arcs (to_arc()), creating any \ref interpolator_base
510 * objects using this \ref PathContour or closing the contour.
511 */
512 void
513 start(const vec2 &pt);
514
515 /*!
516 * Close the current edge.
517 * \param pt point location of end of edge (and thus start of new edge)
518 * \param etp the edge type of the new edge made; if this is the first
519 * edge of the contour, the value of etp is ignored and the
520 * value \ref PathEnums::starts_new_edge is used.
521 */
522 void
523 to_point(const vec2 &pt, enum PathEnums::edge_type_t etp);
524
525 /*!
526 * Add a control point. Will fail if close() was called
527 * \param pt location of new control point
528 */
529 void
530 add_control_point(const vec2 &pt);
531
532 /*!
533 * Clear any current control points.
534 */
535 void
536 clear_control_points(void);
537
538 /*!
539 * Will fail if close() was called of if add_control_point() has been
540 * called more recently than to_point().
541 * \param angle angle of arc in radians
542 * \param pt point where arc ends (and next edge starts)
543 * \param etp the edge type of the new edge made; if this is the first
544 * edge of the contour, the value of etp is ignored and the
545 * value \ref PathEnums::starts_new_edge is used.
546 */
547 void
548 to_arc(float angle, const vec2 &pt, enum PathEnums::edge_type_t etp);
549
550 /*!
551 * End the PathContour without adding a closing edge.
552 */
553 void
554 end(void);
555
556 /*!
557 * Closes the \ref PathContour using the last \ref interpolator_base
558 * derived object on the \ref PathContour. That interpolator must
559 * interpolate to the start point of the \ref PathContour
560 */
561 void
562 close_generic(void);
563
564 /*!
565 * Closes with the Bezier curve defined by the current
566 * control points added by add_control_point().
567 * \param etp the edge type of the new edge made.
568 */
569 void
570 close(enum PathEnums::edge_type_t etp);
571
572 /*!
573 * Closes with an arc.
574 * \param angle angle of arc in radians
575 * \param etp the edge type of the new edge made.
576 */
577 void
578 close_arc(float angle, enum PathEnums::edge_type_t etp);
579
580 /*!
581 * Returns the last interpolator added to this \ref PathContour.
582 * If no contours have been added, returns a null reference.
583 */
584 const reference_counted_ptr<const interpolator_base>&
585 prev_interpolator(void);
586
587 /*!
588 * Returns true if the PathContour is closed.
589 */
590 bool
591 closed(void) const;
592
593 /*!
594 * Returns true if the PathContour is ended, and thus
595 * no additional interpolator may be added.
596 */
597 bool
598 ended(void) const;
599
600 /*!
601 * Return the I'th point of this PathContour.
602 * For I = 0, returns the value passed to start().
603 * \param I index of point.
604 */
605 const vec2&
606 point(unsigned int I) const;
607
608 /*!
609 * Returns the number of points of this PathContour.
610 */
611 unsigned int
612 number_points(void) const;
613
614 /*!
615 * Returns the number of interpolators of this
616 * PathContour. This is equal to number_points()
617 * if closed() is true; otherwise it is equal to
618 * number_points() - 1.
619 */
620 unsigned int
621 number_interpolators(void) const;
622
623 /*!
624 * Returns the interpolator of this PathContour
625 * that interpolates from the I'th point to the
626 * (I + 1)'th point. When the closed() is true,
627 * if I is number_points() - 1, then returns the
628 * interpolator from the last point to the first
629 * point. When closed() is false, if I has value
630 * number_points() - 1, then returns a null reference.
631 */
632 const reference_counted_ptr<const interpolator_base>&
633 interpolator(unsigned int I) const;
634
635 /*!
636 * Returns an approximation of the bounding box for
637 * this PathContour WITHOUT relying on tessellating
638 * the \ref interpolator_base objects of this \ref
639 * PathContour. Returns false if the box is empty.
640 * \param out_bb (output) location to which to write
641 * the bounding box value
642 */
643 bool
644 approximate_bounding_box(Rect *out_bb) const;
645
646 /*!
647 * Returns true if each interpolator of the PathContour is
648 * flat.
649 */
650 bool
651 is_flat(void) const;
652
653 /*!
654 * Create a deep copy of this PathContour.
655 */
656 reference_counted_ptr<PathContour>
657 deep_copy(void) const;
658
659private:
660 void *m_d;
661};
662
663/*!
664 * \brief
665 * A Path represents a collection of PathContour
666 * objects.
667 */
668class Path:noncopyable
669{
670public:
671 /*!
672 * \brief
673 * Class that wraps a vec2 to mark a point
674 * as a control point for a Bezier curve
675 */
676 class control_point
677 {
678 public:
679 /*!
680 * Ctor
681 * \param pt value to which to set \ref m_location
682 */
683 explicit
684 control_point(const vec2 &pt):
685 m_location(pt)
686 {}
687
688 /*!
689 * Ctor
690 * \param x value to which to set m_location.x()
691 * \param y value to which to set m_location.y()
692 */
693 control_point(float x, float y):
694 m_location(x,y)
695 {}
696
697 /*!
698 * Position of control point
699 */
700 vec2 m_location;
701 };
702
703 /*!
704 * \brief
705 * Wraps the data to specify an arc
706 */
707 class arc
708 {
709 public:
710 /*!
711 * Ctor
712 * \param angle angle of arc in radians
713 * \param pt point to which to arc
714 */
715 arc(float angle, const vec2 &pt):
716 m_angle(angle), m_pt(pt)
717 {}
718
719 /*!
720 * Angle of arc in radians
721 */
722 float m_angle;
723
724 /*!
725 * End point of arc
726 */
727 vec2 m_pt;
728 };
729
730 /*!
731 * \brief
732 * Tag class to mark the close of a contour
733 */
734 class contour_close
735 {};
736
737 /*!
738 * \brief
739 * Tag class to mark the end of a contour without
740 * adding a closing edge of the contour and start
741 * a new contour
742 */
743 class contour_end
744 {};
745
746 /*!
747 * \brief
748 * Indicates to end the existing contour with adding
749 * a closing edge of the contour and start a new contour
750 */
751 class contour_start
752 {
753 public:
754 /*!
755 * Ctor to indicate to start a new contour
756 * without closing the previous contour.
757 */
758 explicit
759 contour_start(const vec2 &pt):
760 m_pt(pt)
761 {}
762
763 /*!
764 * Ctor to indicate to start a new contour
765 * without closing the previous contour.
766 */
767 explicit
768 contour_start(float x, float y):
769 m_pt(x, y)
770 {}
771
772 /*!
773 * Location of start of new contour.
774 */
775 vec2 m_pt;
776 };
777
778 /*!
779 * \brief
780 * Tag class to mark the close of an contour with an arc
781 */
782 class contour_close_arc
783 {
784 public:
785 /*!
786 * Ctor
787 * \param angle angle of arc in radians
788 */
789 explicit
790 contour_close_arc(float angle):
791 m_angle(angle)
792 {}
793
794 /*!
795 * Angle of arc in radians
796 */
797 float m_angle;
798 };
799
800 /*!
801 * Ctor.
802 */
803 explicit
804 Path(void);
805
806 ~Path();
807
808 /*!
809 * Clear the path, i.e. remove all PathContour's from the
810 * path
811 */
812 void
813 clear(void);
814
815 /*!
816 * Swap contents of Path with another Path
817 * \param obj Path with which to swap
818 */
819 void
820 swap(Path &obj);
821
822 /*!
823 * Create an arc but specify the angle in degrees.
824 * \param angle angle of arc in degrees
825 * \param pt point to which to arc
826 */
827 static
828 arc
829 arc_degrees(float angle, const vec2 &pt)
830 {
831 return arc(angle*float(FASTUIDRAW_PI)/180.0f, pt);
832 }
833
834 /*!
835 * Create an contour_close_arc but specify the angle in degrees.
836 * \param angle angle or arc in degrees
837 */
838 static
839 contour_close_arc
840 contour_close_arc_degrees(float angle)
841 {
842 return contour_close_arc(angle*float(FASTUIDRAW_PI)/180.0f);
843 }
844
845 /*!
846 * Operator overload to add a point of the current
847 * contour in the Path.
848 * \param pt point to add
849 */
850 Path&
851 operator<<(const vec2 &pt);
852
853 /*!
854 * Operator overload to add a control point of the current
855 * contour in the Path.
856 * \param pt control point to add
857 */
858 Path&
859 operator<<(const control_point &pt);
860
861 /*!
862 * Operator overload to add an arc to the current contour
863 * in the Path.
864 * \param a arc to add
865 */
866 Path&
867 operator<<(const arc &a);
868
869 /*!
870 * Operator overload to close the current contour
871 */
872 Path&
873 operator<<(contour_close);
874
875 /*!
876 * Operator overload to end the current contour
877 */
878 Path&
879 operator<<(contour_end);
880
881 /*!
882 * Operator overload to close the current contour
883 * \param a specifies the angle of the arc for closing
884 * the current contour
885 */
886 Path&
887 operator<<(contour_close_arc a);
888
889 /*!
890 * Operator overload to start a new contour without closing
891 * the current contour.
892 * \param st specifies the starting point of the new contour
893 */
894 Path&
895 operator<<(const contour_start &st)
896 {
897 move(st.m_pt);
898 return *this;
899 }
900
901 /*!
902 * Operator overload to control PathEnums::edge_type_t
903 * of the next edge made via operator overloads.
904 * If no edge is yet present on the current contour, then
905 * the value is ignored. The tag is reset back to \ref
906 * PathEnums::starts_new_edge after an edge is added.
907 * \param etp edge type
908 */
909 Path&
910 operator<<(enum PathEnums::edge_type_t etp);
911
912 /*!
913 * Append a line to the current contour.
914 * \param pt point to which the line goes
915 * \param etp the edge type of the new line made; if this is the first
916 * edge of the current contour, the value of etp is ignored
917 * and the value \ref PathEnums::starts_new_edge is used.
918 */
919 Path&
920 line_to(const vec2 &pt,
921 enum PathEnums::edge_type_t etp = PathEnums::starts_new_edge);
922
923 /*!
924 * Append a quadratic Bezier curve to the current contour.
925 * \param ct control point of the quadratic Bezier curve
926 * \param pt point to which the quadratic Bezier curve goes
927 * \param etp the edge type of the new quadratic made; if this is the first
928 * edge of the current contour, the value of etp is ignored
929 * and the value \ref PathEnums::starts_new_edge is used.
930 */
931 Path&
932 quadratic_to(const vec2 &ct, const vec2 &pt,
933 enum PathEnums::edge_type_t etp = PathEnums::starts_new_edge);
934
935 /*!
936 * Append a cubic Bezier curve to the current contour.
937 * \param ct1 first control point of the cubic Bezier curve
938 * \param ct2 second control point of the cubic Bezier curve
939 * \param pt point to which the cubic Bezier curve goes
940 * \param etp the edge type of the new cubic made; if this is the first
941 * edge of the current contour, the value of etp is ignored
942 * and the value \ref PathEnums::starts_new_edge is used.
943 */
944 Path&
945 cubic_to(const vec2 &ct1, const vec2 &ct2, const vec2 &pt,
946 enum PathEnums::edge_type_t etp = PathEnums::starts_new_edge);
947
948 /*!
949 * Append an arc curve to the current contour.
950 * \param angle gives the angle of the arc in radians. For a coordinate system
951 * where y increases upwards and x increases to the right, a positive
952 * value indicates counter-clockwise and a negative value indicates
953 * clockwise
954 * \param pt point to which the arc curve goes
955 * \param etp the edge type of the new arc made; if this is the first
956 * edge of the current contour, the value of etp is ignored
957 * and the value \ref PathEnums::starts_new_edge is used.
958 */
959 Path&
960 arc_to(float angle, const vec2 &pt,
961 enum PathEnums::edge_type_t etp = PathEnums::starts_new_edge);
962
963 /*!
964 * Begin a new contour.
965 * \param pt point at which the contour begins
966 */
967 Path&
968 move(const vec2 &pt);
969
970 /*!
971 * End the current contour without adding a closing edge.
972 */
973 Path&
974 end_contour(void);
975
976 /*!
977 * Close the current contour with a line segment.
978 * \param etp the edge type of the closing edge made.
979 */
980 Path&
981 close_contour(enum PathEnums::edge_type_t etp = PathEnums::starts_new_edge);
982
983 /*!
984 * Close the current contour in an arc
985 * \param angle gives the angle of the arc in radians. For a coordinate system
986 * where y increases upwards and x increases to the right, a positive
987 * value indicates counter-clockwise and a negative value indicates
988 * clockwise
989 * \param etp the edge type of the closing edge made.
990 */
991 Path&
992 close_contour_arc(float angle,
993 enum PathEnums::edge_type_t etp = PathEnums::starts_new_edge);
994
995 /*!
996 * Close the current contour in a quadratic Bezier curve
997 * \param ct control point of the quadratic Bezier curve
998 * \param etp the edge type of the closing edge made.
999 */
1000 Path&
1001 close_contour_quadratic(const vec2 &ct,
1002 enum PathEnums::edge_type_t etp = PathEnums::starts_new_edge);
1003
1004 /*!
1005 * Close the current contour in a cubic Bezier curve
1006 * \param ct1 first control point of the cubic Bezier curve
1007 * \param ct2 second control point of the cubic Bezier curve
1008 * \param etp the edge type of the closing edge made.
1009 */
1010 Path&
1011 close_contour_cubic(const vec2 &ct1, const vec2 &ct2,
1012 enum PathEnums::edge_type_t etp = PathEnums::starts_new_edge);
1013
1014 /*!
1015 * The current contour of this \ref Path. Use thie value when creating
1016 * \ref PathContour::interpolator_base objects.
1017 */
1018 PathContour&
1019 current_contour(void);
1020
1021 /*!
1022 * Adds a PathContour to this Path. The current contour remains
1023 * as the current contour though.
1024 * \param contour PathContour to add to the Path
1025 */
1026 Path&
1027 add_contour(const reference_counted_ptr<const PathContour> &contour);
1028
1029 /*!
1030 * Add all the \ref PathContour objects of a Path into this Path.
1031 * \param path Path to add
1032 */
1033 Path&
1034 add_contours(const Path &path);
1035
1036 /*!
1037 * Returns the number of contours of the Path.
1038 */
1039 unsigned int
1040 number_contours(void) const;
1041
1042 /*!
1043 * Returns the named contour
1044 * \param i index of contour to fetch (0 <= i < number_contours())
1045 */
1046 reference_counted_ptr<const PathContour>
1047 contour(unsigned int i) const;
1048
1049 /*!
1050 * Returns true if each PathContour of the Path is flat.
1051 */
1052 bool
1053 is_flat(void) const;
1054
1055 /*!
1056 * Returns an approximation of the bounding box for
1057 * this Path. Returns false if the Path is empty.
1058 * \param out_bb (output) location to which to write
1059 * the bounding box value
1060 */
1061 bool
1062 approximate_bounding_box(Rect *out_bb) const;
1063
1064 /*!
1065 * Return the tessellation of this Path at a specific
1066 * level of detail. The TessellatedPath is constructed
1067 * lazily. Additionally, if this Path changes its geometry,
1068 * then a new TessellatedPath will be contructed on the
1069 * next call to tessellation().
1070 * \param thresh the returned tessellated path will be so that
1071 * TessellatedPath::max_distance() is no more than
1072 * thresh. A non-positive value will return the
1073 * lowest level of detail tessellation.
1074 */
1075 const TessellatedPath&
1076 tessellation(float thresh) const;
1077
1078 /*!
1079 * Provided as a conveniance, returns the starting point tessellation.
1080 * Equivalent to
1081 * \code
1082 * tessellation(-1.0f)
1083 * \endcode
1084 */
1085 const TessellatedPath&
1086 tessellation(void) const;
1087
1088 /*!
1089 * Returns the \ref ShaderFilledPath coming from this
1090 * Path. The returned reference will be null if the
1091 * Path contains anything besides line segments,
1092 * quadratic Bezier curves or cubic Bezier curves.
1093 */
1094 const ShaderFilledPath&
1095 shader_filled_path(void) const;
1096
1097private:
1098 void *m_d;
1099};
1100
1101/*! @} */
1102
1103}
1104
1105#endif
1106