1/*!
2 * \file tessellated_path.hpp
3 * \brief file tessellated_path.hpp
4 *
5 * Copyright 2018 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#ifndef FASTUIDRAW_TESSELLATED_PATH_HPP
21#define FASTUIDRAW_TESSELLATED_PATH_HPP
22
23
24#include <fastuidraw/util/fastuidraw_memory.hpp>
25#include <fastuidraw/util/rect.hpp>
26#include <fastuidraw/util/vecN.hpp>
27#include <fastuidraw/util/c_array.hpp>
28#include <fastuidraw/util/reference_counted.hpp>
29#include <fastuidraw/path_enums.hpp>
30
31namespace fastuidraw {
32
33///@cond
34class Path;
35class StrokedPath;
36class FilledPath;
37class PartitionedTessellatedPath;
38///@endcond
39
40/*!\addtogroup Paths
41 * @{
42 */
43
44/*!
45 * \brief
46 * An TessellatedPath represents the tessellation of a Path
47 * into line segments and arcs.
48 *
49 * A single contour of a TessellatedPath is constructed from
50 * a single \ref PathContour of the source \ref Path. Each
51 * edge of a contour of a TessellatedPath is contructed from
52 * a single \ref PathContour::interpolator_base of the source \ref
53 * PathContour. The ordering of the contours of a
54 * TessellatedPath is the same ordering as the source
55 * \ref PathContour objects of the source \ref Path. Also,
56 * the ordering of edges within a contour is the same ordering
57 * as the \ref PathContour::interpolator_base objects of
58 * the source \ref PathContour. In particular, for each contour
59 * of a TessellatedPath, if an edge is closed, the closing edge
60 * is the last edge.
61 */
62class TessellatedPath:
63 public reference_counted<TessellatedPath>::non_concurrent
64{
65public:
66 /*!
67 * \brief
68 * Enumeration to identify the type of a \ref segment
69 */
70 enum segment_type_t
71 {
72 /*!
73 * Indicates that the segment is an arc segment,
74 * i.e. it connects two point via an arc of a
75 * circle
76 */
77 arc_segment,
78
79 /*!
80 * Indicates that the segment is a line segment
81 * i.e. it connects two point via a line.
82 */
83 line_segment,
84 };
85
86 /*!
87 * Enumeration to describe if a segment is split
88 */
89 enum split_t
90 {
91 /*!
92 * Indicates that entire segment is before
93 * the split value
94 */
95 segment_completey_before_split,
96
97 /*!
98 * Indicates that entire segment is after
99 * the split value
100 */
101 segment_completey_after_split,
102
103 /*!
104 * indicates that the \ref segment was split
105 * with the segment starting before the split
106 * point.
107 */
108 segment_split_start_before,
109
110 /*!
111 * indicates that the \ref segment was split
112 * with the segment starting after the split
113 * point.
114 */
115 segment_split_start_after,
116 };
117
118 /*!
119 * \brief
120 * A TessellationParams stores how finely to tessellate
121 * the curves of a path.
122 */
123 class TessellationParams
124 {
125 public:
126 /*!
127 * Ctor, initializes values.
128 */
129 TessellationParams(void):
130 m_max_distance(-1.0f),
131 m_max_recursion(5)
132 {}
133
134 /*!
135 * Provided as a conveniance. Equivalent to
136 * \code
137 * m_max_distance = tp;
138 * \endcode
139 * \param p value to which to assign to \ref m_max_distance
140 */
141 TessellationParams&
142 max_distance(float p)
143 {
144 m_max_distance = p;
145 return *this;
146 }
147
148 /*!
149 * Set the value of \ref m_max_recursion.
150 * \param v value to which to assign to \ref m_max_recursion
151 */
152 TessellationParams&
153 max_recursion(unsigned int v)
154 {
155 m_max_recursion = v;
156 return *this;
157 }
158
159 /*!
160 * Maximum distance to attempt between the actual curve and the
161 * tessellation. A value less than or equal to zero indicates to
162 * accept any distance value between the tessellation and the
163 * curve. Default value is -1.0 (i.e. accept any distance value).
164 */
165 float m_max_distance;
166
167 /*!
168 * Maximum number of times to perform recursion to tessellate an edge.
169 * Default value is 5.
170 */
171 unsigned int m_max_recursion;
172 };
173
174 /*!
175 * \brief
176 * Represents segment of a tessellated or arc-tessellated path.
177 */
178 class segment
179 {
180 public:
181 /*!
182 * Specifies the segment type.
183 */
184 enum segment_type_t m_type;
185
186 /*!
187 * Gives the start point on the path of the segment.
188 */
189 vec2 m_start_pt;
190
191 /*!
192 * Gives the end point on the path of the segment.
193 */
194 vec2 m_end_pt;
195
196 /*!
197 * Only valid if \ref m_type is \ref arc_segment; gives
198 * the center of the arc.
199 */
200 vec2 m_center;
201
202 /*!
203 * Only valid if \ref m_type is \ref arc_segment; gives
204 * the angle range of the arc.
205 */
206 range_type<float> m_arc_angle;
207
208 /*!
209 * Only valid if \ref m_type is \ref arc_segment; gives
210 * the radius of the arc.
211 */
212 float m_radius;
213
214 /*!
215 * Gives the length of the segment.
216 */
217 float m_length;
218
219 /*!
220 * Gives the distance of the start of the segment from
221 * the start of the edge (i.e PathContour::interpolator_base).
222 */
223 float m_distance_from_edge_start;
224
225 /*!
226 * Gives the distance of the start of segment to the
227 * start of the -contour-.
228 */
229 float m_distance_from_contour_start;
230
231 /*!
232 * Gives the length of the edge (i.e.
233 * PathContour::interpolator_base) on which the
234 * segment lies. This value is the same for all
235 * segments along a fixed edge.
236 */
237 float m_edge_length;
238
239 /*!
240 * Gives the length of the contour on which this
241 * segment lies. This value is the same for all
242 * segments along a fixed contour.
243 */
244 float m_contour_length;
245
246 /*!
247 * Gives the unit-vector of the path entering the segment.
248 */
249 vec2 m_enter_segment_unit_vector;
250
251 /*!
252 * Gives the unit-vector of the path leaving the segment.
253 */
254 vec2 m_leaving_segment_unit_vector;
255
256 /*!
257 * If true, indicates that the arc is a continuation of
258 * its predecessor. This happens when TessellatedPath
259 * breaks a \ref segment into smaller pieces to make its
260 * angle smaller, to make it monotonic or if it is the
261 * second portion of a split segment as calculated from
262 * \ref compute_split_x() or \ref compute_split_y().
263 */
264 bool m_continuation_with_predecessor;
265
266 /*!
267 * The contour from which the \ref segment originates,
268 * i.e. the \ref segment originates from the \ref
269 * PathContour::interpolator_base \ref
270 * PathContour::interpolator(\ref m_edge_id) of the
271 * \ref PathContour of \ref Path::contour(\ref m_contour_id).
272 */
273 unsigned int m_contour_id;
274
275 /*!
276 * The edge from which the \ref segment originates,
277 * i.e. the \ref segment originates from the \ref
278 * PathContour::interpolator_base \ref
279 * PathContour::interpolator(\ref m_edge_id) of the
280 * \ref PathContour of \ref Path::contour(\ref m_contour_id).
281 */
282 unsigned int m_edge_id;
283
284 /*!
285 * Indicates the this segment is the first segment of
286 * an edge
287 */
288 bool m_first_segment_of_edge;
289
290 /*!
291 * Indicates the this segment is the last segment of
292 * an edge
293 */
294 bool m_last_segment_of_edge;
295
296 /*!
297 * Returns the normal vector to the path at the start of the segment.
298 */
299 vec2
300 enter_segment_normal(void) const
301 {
302 return vec2(-m_enter_segment_unit_vector.y(),
303 +m_enter_segment_unit_vector.x());
304 }
305
306 /*!
307 * Returns the normal vector to the path at the end of the segment.
308 */
309 vec2
310 leaving_segment_normal(void) const
311 {
312 return vec2(-m_leaving_segment_unit_vector.y(),
313 +m_leaving_segment_unit_vector.x());
314 }
315
316 /*!
317 * Split this \ref segment at a time t where the start
318 * of the segment is at t = 0 and the end of the segment
319 * is t = 1.
320 * \param t time to split the segment, must have that 0 <= t <= 1
321 * \param dst_0_t location to which to write the portion of
322 * this \ref segment on the interval [0, t].
323 * \param dst_t_1 location to which to write the portion of
324 * this \ref segment on the interval [t, 1].
325 */
326 void
327 split_segment(float t,
328 segment *dst_0_t,
329 segment *dst_t_1) const;
330
331 /*!
332 * Compute the splitting splitting of this \ref segment
333 * against a vertical line with the given x-coordinate
334 * \param x_split x-coordinate of vertical splitting line
335 * \param dst_before_split location to which to write
336 * the portion of the segment that
337 * comes before the splitting line
338 * \param dst_after_split location to which to write
339 * the portion of the segment that
340 * comes after the splitting line
341 * \returns how the segment was split. Note that if the return
342 * value is \ref segment_completey_before_split or
343 * \ref segment_completey_after_split then neither
344 * of dst_before_split and dst_after_split are
345 * written to.
346 */
347 enum split_t
348 compute_split_x(float x_split,
349 segment *dst_before_split,
350 segment *dst_after_split) const;
351
352 /*!
353 * Compute the splitting splitting of this \ref segment
354 * against a horizontal line with the given y-coordinate
355 * \param y_split y-coordinate of horizontal splitting line
356 * \param dst_before_split location to which to write
357 * the portion of the segment that
358 * comes before the splitting line
359 * \param dst_after_split location to which to write
360 * the portion of the segment that
361 * comes after the splitting line
362 * \returns how the segment was split. Note that if the return
363 * value is \ref segment_completey_before_split or
364 * \ref segment_completey_after_split then neither
365 * of dst_before_split and dst_after_split are
366 * written to.
367 */
368 enum split_t
369 compute_split_y(float y_split,
370 segment *dst_before_split,
371 segment *dst_after_split) const;
372
373 /*!
374 * Compute the splitting splitting of this \ref segment
375 * against a horizontal or vertical line with the given
376 * coordinate. Provided as a conveniance, equivalent to
377 * \code
378 * if (splitting_coordinate == 0)
379 * {
380 * compute_split_x(split, dst_before_split, dst_after_split);
381 * }
382 * else
383 * {
384 * compute_split_y(split, dst_before_split, dst_after_split);
385 * }
386 * \endcode
387 * \param split x-coordinate or y-coordinate of splitting line
388 * \param dst_before_split location to which to write
389 * the portion of the segment that
390 * comes before the splitting line
391 * \param dst_after_split location to which to write
392 * the portion of the segment that
393 * comes after the splitting line
394 * \param splitting_coordinate determines if to split by a vertical
395 * line or a horizontal line.
396 * \returns how the segment was split. Note that if the return
397 * value is \ref segment_completey_before_split or
398 * \ref segment_completey_after_split then neither
399 * of dst_before_split and dst_after_split are
400 * written to.
401 */
402 enum split_t
403 compute_split(float split,
404 segment *dst_before_split,
405 segment *dst_after_split,
406 int splitting_coordinate) const;
407 };
408
409 /*!
410 * A \ref segment_chain is a sequence of \ref
411 * segment values where successive elements are
412 * neighbors of the same edge in the source \ref
413 * Path. It is possible to split edges and keep
414 * neighbor information via the field \ref
415 * m_prev_to_start
416 */
417 class segment_chain
418 {
419 public:
420 /*!
421 * The chain of \ref segment values
422 */
423 c_array<const segment> m_segments;
424
425 /*!
426 * if non-null, gives the segment just
427 * before the first element of \ref
428 * m_segments. If null, then there is
429 * no segment just before \ref m_segments.
430 */
431 const segment *m_prev_to_start;
432 };
433
434 /*!
435 * \brief
436 * Represents the geometric data for a join
437 */
438 class join
439 {
440 public:
441 /*!
442 * Default ctor that does NOT initialize any of the fields
443 * of \ref join
444 */
445 join(void)
446 {}
447
448 /*!
449 * Ctor that initializes the values of a join to be the
450 * values of where two \ref segment values meet.
451 * \param into_join the \ref segment value into the join,
452 * it is required that into_join.m_end_pt
453 * has the same value as from_join.m_start_pt
454 * \param from_join the \ref segment value leaving from the join,
455 * it is required that into_join.m_end_pt
456 * has the same value as from_join.m_start_pt
457 */
458 join(const segment &into_join,
459 const segment &from_join);
460
461 /*!
462 * Gives the position of the join
463 */
464 vec2 m_position;
465
466 /*!
467 * Gives the unit-vector of the path entering the join.
468 */
469 vec2 m_enter_join_unit_vector;
470
471 /*!
472 * Gives the unit-vector of the path leaving the join.
473 */
474 vec2 m_leaving_join_unit_vector;
475
476 /*!
477 * Gives the distance of the join from the previous join.
478 */
479 float m_distance_from_previous_join;
480
481 /*!
482 * Gives the distance of the join from the start
483 * of the -contour- on which the point resides.
484 */
485 float m_distance_from_contour_start;
486
487 /*!
488 * Length of the contour on which the join resides.
489 */
490 float m_contour_length;
491
492 /*!
493 * Gives the contour from which the join originates,
494 * following the same convention as \ref
495 * segment::m_contour_id.
496 */
497 unsigned int m_contour_id;
498
499 /*!
500 * Gives the interpolator that goes into the join,
501 * following the same convention as \ref
502 * segment::m_edge_id.
503 */
504 unsigned int m_edge_into_join_id;
505
506 /*!
507 * Gives the interpolator that leaves the join,
508 * following the same convention as \ref
509 * segment::m_edge_id.
510 */
511 unsigned int m_edge_leaving_join_id;
512
513 /*!
514 * When stroking a join, one needs to know what side of the
515 * edge gets the join. For example a bevel join is formed by
516 * the triangle formed from the three points: the outer edge
517 * at the join of the segment going into the join, the outer
518 * edge of the segment leaving the join and the point where
519 * the segments meet. The value of lambda() gives the sign to
520 * apply to \ref enter_join_normal() and \ref leaving_join_normal()
521 * to get the unit vector from where the segments meet to the
522 * outer edge.
523 */
524 float m_lambda;
525
526 /*!
527 * If this join is realized as a miter-join, returns the distance
528 * from the point of the join (i.e. where the segments intersect)
529 * to the tip of the miter join. If the path enter and leaving
530 * the join are parallel or anti-parallel, then return -1.0.
531 */
532 float m_miter_distance;
533
534 /*!
535 * This gives the angle (in degrees) between the start and
536 * end points of the join.
537 */
538 float m_join_angle;
539
540 /*!
541 * Gives the normal vector to going into the join
542 */
543 vec2
544 enter_join_normal(void) const
545 {
546 return vec2(-m_enter_join_unit_vector.y(), m_enter_join_unit_vector.x());
547 }
548
549 /*!
550 * Gives the normal vector to leaving from the join
551 */
552 vec2
553 leaving_join_normal(void) const
554 {
555 return vec2(-m_leaving_join_unit_vector.y(), m_leaving_join_unit_vector.x());
556 }
557 };
558
559 /*!
560 * \brief
561 * Represents the geometric data for a cap
562 */
563 class cap
564 {
565 public:
566 /*!
567 * Default ctor that does NOT initialize any of the fields
568 * of \ref cap
569 */
570 cap(void)
571 {}
572
573 /*!
574 * Ctor that initializes the values of a cap to be values
575 * of where a segment starts or ends.
576 * \param seg the \ref segment value
577 * \param is_start_cap if true indicates to give the cap
578 * the value as a cap at the start of
579 * the \ref segment, if false, then at
580 * the end of the \ref segment.
581 */
582 cap(const segment &seg, bool is_start_cap);
583
584 /*!
585 * Gives the position of the cap
586 */
587 vec2 m_position;
588
589 /*!
590 * Gives the unit-vector into the cap
591 */
592 vec2 m_unit_vector;
593
594 /*!
595 * Length of the contour on which the cap resides.
596 */
597 float m_contour_length;
598
599 /*!
600 * Length of the edge on which the cap resides.
601 */
602 float m_edge_length;
603
604 /*!
605 * Gives the distance of the cap from the start of the edge
606 * on which the cap resides.
607 */
608 float m_distance_from_edge_start;
609
610 /*!
611 * Gives the distance of the cap start of the -contour-.
612 * For \ref cap values of a \ref TessellatedPath, this is
613 * 0 for a starting cap and \ref m_contour_length for
614 * an ending cap.
615 */
616 float m_distance_from_contour_start;
617
618 /*!
619 * True if the cap is from the start of a contour
620 */
621 bool m_is_starting_cap;
622
623 /*!
624 * Gives the contour from which the join originates,
625 * following the same convention as \ref
626 * segment::m_contour_id.
627 */
628 unsigned int m_contour_id;
629 };
630
631 /*!
632 * \brief
633 * A wrapper over a dynamic array of \ref segment objects;
634 * segment values added to SegmentStorage must be added
635 * in order of time along the domain of a \ref
636 * PathContour::interpolator_base
637 */
638 class SegmentStorage:fastuidraw::noncopyable
639 {
640 public:
641 /*!
642 * Add a \ref segment to the SegmentStorage that is a
643 * line segment between two points.
644 * \param start the starting point of the segment
645 * \param end the ending point of the segment
646 */
647 void
648 add_line_segment(vec2 start, vec2 end);
649
650 /*!
651 * Add a \ref segment to the SegmentStorage that is an
652 * arc segment. If necessary, An arc-segment will be broken
653 * into multiple segments to that each segment is monotonic
654 * in the x and y coordiantes and each segment's arc-angle
655 * is no more than FASTUIDRAW_PI / 4.0 radians (45 degrees).
656 * \param start gives the start point of the arc on the path
657 * \param end gives the end point of the arc on the path
658 * \param center is the center of the circle that defines the arc
659 * \param radius is the radius of the circle that defines the arc
660 * \param arc_angle is the arc-angle range that defines the arc
661 */
662 void
663 add_arc_segment(vec2 start, vec2 end,
664 vec2 center, float radius,
665 range_type<float> arc_angle);
666
667 private:
668 SegmentStorage(void) {}
669 ~SegmentStorage() {}
670
671 friend class TessellatedPath;
672 void *m_d;
673 };
674
675 /*!
676 * A Refiner is stateful object that creates new TessellatedPath
677 * objects from a starting TessellatedPath where the tessellation
678 * is made finer.
679 */
680 class Refiner:
681 public reference_counted<Refiner>::non_concurrent
682 {
683 public:
684 virtual
685 ~Refiner();
686
687 /*!
688 * Update the TessellatedPath returned by tessellated_path() by
689 * refining the current value returned by tessellated_path().
690 * \param max_distance new maximum distance to aim for
691 * \param additional_recursion amount by which to additionally recurse
692 * when tessellating.
693 */
694 void
695 refine_tessellation(float max_distance,
696 unsigned int additional_recursion);
697
698 /*!
699 * Returns the current TessellatedPath of this Refiner.
700 */
701 reference_counted_ptr<TessellatedPath>
702 tessellated_path(void) const;
703
704 private:
705 friend class TessellatedPath;
706 Refiner(TessellatedPath *p, const Path &path);
707
708 void *m_d;
709 };
710
711 /*!
712 * Ctor. Construct a TessellatedPath from a Path
713 * \param input source path to tessellate
714 * \param P parameters on how to tessellate the source Path
715 * \param ref if non-NULL, construct a Refiner object and return
716 * the value via upading the value of ref.
717 */
718 TessellatedPath(const Path &input, TessellationParams P,
719 reference_counted_ptr<Refiner> *ref = nullptr);
720
721 ~TessellatedPath();
722
723 /*!
724 * Returns the tessellation parameters used to construct
725 * this TessellatedPath.
726 */
727 const TessellationParams&
728 tessellation_parameters(void) const;
729
730 /*!
731 * Returns true if and only if there is a \ref segment
732 * in segment_data() for which segment::m_type is
733 * \ref arc_segment.
734 */
735 bool
736 has_arcs(void) const;
737
738 /*!
739 * Returns the maximum across all edges of all contours
740 * of the distance between the tessellation and the actual
741 * path.
742 */
743 float
744 max_distance(void) const;
745
746 /*!
747 * Returns the maximum recursion employed by any edge
748 */
749 unsigned int
750 max_recursion(void) const;
751
752 /*!
753 * Returns all the segment data of the entire path.
754 */
755 c_array<const segment>
756 segment_data(void) const;
757
758 /*!
759 * Returns the array of \ref segment_chain objects
760 * of the entire path.
761 */
762 c_array<const segment_chain>
763 segment_chain_data(void) const;
764
765 /*!
766 * Returns all the join data
767 */
768 c_array<const join>
769 join_data(void) const;
770
771 /*!
772 * Returns all the cap data
773 */
774 c_array<const cap>
775 cap_data(void) const;
776
777 /*!
778 * Returns the number of contours
779 */
780 unsigned int
781 number_contours(void) const;
782
783 /*!
784 * Returns true if the named contour was closed
785 * \param contour which path contour to query, must have
786 * that 0 <= contour < number_contours()
787 */
788 bool
789 contour_closed(unsigned int contour) const;
790
791 /*!
792 * Returns the range into segment_data() for the named
793 * contour.
794 * \param contour which path contour to query, must have
795 * that 0 <= contour < number_contours()
796 */
797 range_type<unsigned int>
798 contour_range(unsigned int contour) const;
799
800 /*!
801 * Returns the segment data of the named contour.
802 * Provided as a conveniance equivalent to
803 * \code
804 * segment_data().sub_array(contour_range(contour))
805 * \endcode
806 * \param contour which path contour to query, must have
807 * that 0 <= contour < number_contours()
808 */
809 c_array<const segment>
810 contour_segment_data(unsigned int contour) const;
811
812 /*!
813 * Returns the array of \ref segment_chain objects
814 * of a contour.
815 * \param contour which path contour to query, must have
816 * that 0 <= contour < number_contours()
817 */
818 c_array<const segment_chain>
819 contour_chains(unsigned int contour) const;
820
821 /*!
822 * Returns the number of edges for the named contour
823 * \param contour which path contour to query, must have
824 * that 0 <= contour < number_contours()
825 */
826 unsigned int
827 number_edges(unsigned int contour) const;
828
829 /*!
830 * Returns the range into segment_data(void)
831 * for the named edge of the named contour.
832 * \param contour which path contour to query, must have
833 * that 0 <= contour < number_contours()
834 * \param edge which edge of the contour to query, must
835 * have that 0 <= edge < number_edges(contour)
836 */
837 range_type<unsigned int>
838 edge_range(unsigned int contour, unsigned int edge) const;
839
840 /*!
841 * Returns the segment data of the named edge of the
842 * named contour, provided as a conveniance, equivalent
843 * to
844 * \code
845 * segment_data().sub_array(edge_range(contour, edge))
846 * \endcode
847 * \param contour which path contour to query, must have
848 * that 0 <= contour < number_contours()
849 * \param edge which edge of the contour to query, must
850 * have that 0 <= edge < number_edges(contour)
851 */
852 c_array<const segment>
853 edge_segment_data(unsigned int contour, unsigned int edge) const;
854
855 /*!
856 * Returns the edge type of the named edge of the named contour
857 * of the source Path.
858 * \param contour which path contour to query, must have
859 * that 0 <= contour < number_contours()
860 * \param edge which edge of the contour to query, must
861 * have that 0 <= edge < number_edges(contour)
862 */
863 enum PathEnums::edge_type_t
864 edge_type(unsigned int contour, unsigned int edge) const;
865
866 /*!
867 * Returns the named edge as a \ref segment_chain taking
868 * correctly into account the value of \ref edge_type()
869 * in setting \ref segment_chain::m_prev_to_start.
870 * \param contour which path contour to query, must have
871 * that 0 <= contour < number_contours()
872 * \param edge which edge of the contour to query, must
873 * have that 0 <= edge < number_edges(contour)
874 */
875 segment_chain
876 edge_segment_chain(unsigned int contour, unsigned int edge) const;
877
878 /*!
879 * Returns the bounding box of the tessellation.
880 */
881 const Rect&
882 bounding_box(void) const;
883
884 /*!
885 * Returns this \ref TessellatedPath where any arcs are
886 * realized as segments. If this \ref TessellatedPath has
887 * no arcs, returns this object. If a non-positive value
888 * is passed, returns a linearization where arc-segments
889 * are tessellated into very few line segments.
890 * \param thresh threshhold at which to linearize
891 * arc-segments.
892 */
893 const TessellatedPath&
894 linearization(float thresh) const;
895
896 /*!
897 * Provided as a conveniance, returns the starting point tessellation.
898 * Equivalent to
899 * \code
900 * linearization(-1.0f)
901 * \endcode
902 */
903 const TessellatedPath&
904 linearization(void) const;
905
906 /*!
907 * Returns this \ref TessellatedPath stroked. The \ref
908 * StrokedPath object is constructed lazily.
909 */
910 const StrokedPath&
911 stroked(void) const;
912
913 /*!
914 * Returns this \ref TessellatedPath filled. If this
915 * \ref TessellatedPath has arcs will return
916 * the fill associated to the linearization() of
917 * this \ref TessellatedPath. If a non-positive value
918 * is passed, returns the fill of the linearization
919 * where arc-segments are tessellated into very few
920 * line segments.
921 * \param thresh threshhold at which to linearize
922 * arc-segments.
923 */
924 const FilledPath&
925 filled(float thresh) const;
926
927 /*!
928 * Provided as a conveniance, returns the starting point tessellation.
929 * Equivalent to
930 * \code
931 * filled(-1.0f)
932 * \endcode
933 */
934 const FilledPath&
935 filled(void) const;
936
937 /*!
938 * Returns the partitioning of this \ref TessellatedPath.
939 */
940 const PartitionedTessellatedPath&
941 partitioned(void) const;
942
943private:
944 TessellatedPath(Refiner *p, float threshhold,
945 unsigned int additional_recursion_count);
946
947 TessellatedPath(const TessellatedPath &with_arcs,
948 float thresh);
949
950 void *m_d;
951};
952
953/*! @} */
954
955}
956
957#endif
958