Path.h
1/* Copyright (C) 2017 Marc Boris Duerner
2 Copyright (C) 2017 Aloysius Indrayanto
3
4 This library is free software; you can redistribute it and/or
5 modify it under the terms of the GNU Lesser General Public
6 License as published by the Free Software Foundation; either
7 version 2.1 of the License, or (at your option) any later version.
8
9 As a special exception, you may use this file as part of a free
10 software library without restriction. Specifically, if other files
11 instantiate templates or use macros or inline functions from this
12 file, or you compile this file and link it with other files to
13 produce an executable, this file does not by itself cause the
14 resulting executable to be covered by the GNU General Public
15 License. This exception does not however invalidate any other
16 reasons why the executable file might be covered by the GNU Library
17 General Public License.
18
19 This library is distributed in the hope that it will be useful,
20 but WITHOUT ANY WARRANTY; without even the implied warranty of
21 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
22 Lesser General Public License for more details.
23
24 You should have received a copy of the GNU Lesser General Public
25 License along with this library; if not, write to the Free Software
26 Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
27 MA 02110-1301 USA
28*/
29
30#ifndef PT_GFX_PATH_H
31#define PT_GFX_PATH_H
32
33#include <Pt/Gfx/Api.h>
34#include <Pt/Gfx/FillRule.h>
35#include <Pt/Gfx/Point.h>
36#include <Pt/Gfx/Rect.h>
37#include <Pt/Gfx/Polygon.h>
38#include <Pt/Gfx/Transform.h>
39#include <Pt/SmartPtr.h>
40
41#include <vector>
42#include <iterator>
43#include <cstddef>
44
45namespace Pt {
46
47namespace Gfx {
48
49class PathData;
50class PathElement;
51class PathIterator;
52
80class PT_GFX_API Path
81{
82 public:
86 {
87 MoveTo,
88 LineTo,
89 QuadTo,
90 CubicTo,
91 Close
92 };
93
94 typedef PathIterator Iterator;
95 typedef PathElement Element;
96
97 public:
101
104 Path(const Path& other);
105
108 Path& operator=(const Path& other);
109
113
116 std::size_t size() const;
117
120 bool isEmpty() const;
121
124 Iterator begin() const;
125
128 Iterator end() const;
129
132 void clear();
133
136 RectF boundingRect() const;
137
144 bool contains(const PointF& point, FillRule rule = FillRule::NonZero) const;
145
152 bool contains(const RectF& rect, FillRule rule = FillRule::NonZero) const;
153
161 bool intersects(const RectF& rect, FillRule rule = FillRule::NonZero) const;
162
165 const PointF& currentPosition() const;
166
169 void moveTo(const PointF& p);
170
173 void lineTo(const PointF& p);
174
177 void quadTo(const PointF &cp, const PointF& to);
178
181 void cubicTo(const PointF &cp1, const PointF &cp2, const PointF& to);
182
191 void arcTo(const PointF& topLeft, const SizeF& size,
192 double degBegin, double degEnd);
193
196 void close();
197
200 void addPath(const Path& p);
201
204 void addRect(const RectF& rect);
205
208 void addRoundedRect(const RectF& rect, double radius);
209
214 void addRoundedRect(const RectF& rect, double rx, double ry);
215
218 void addEllipse(const PointF& topLeft, const SizeF& size);
219
225 void addArc(const PointF& topLeft, const SizeF& size,
226 double degBegin, double degEnd);
227
230 void addPie(const PointF& topLeft, const SizeF& size,
231 double degBegin, double degEnd);
232
235 void addChord(const PointF& topLeft, const SizeF& size,
236 double degBegin, double degEnd);
237
240 void addPolyline(const PointF* points, std::size_t count);
241
244 void addPolygon(const PointF* points, std::size_t count);
245
249
253
263 Iterator getPolygon(Iterator it, Polygon& polygon, float tolerance = 0.25f) const;
264
265 private:
266 void detach();
267
268 private:
269 SmartPtr<PathData> _pathData;
270};
271
272/* @internal @brief Path entry.
273*/
274class PathEntry
275{
276 public:
277 typedef Path::ElementType Type;
278
279 public:
280 PathEntry(Type type, std::size_t n)
281 : _type(type)
282 , _size(n)
283 {
284 }
285
286 Type type() const
287 {
288 return _type;
289 }
290
291 std::size_t size() const
292 {
293 return _size;
294 }
295
296 private:
297 Type _type;
298 std::size_t _size;
299};
300
304class PathElement
305{
306 friend class PathIterator;
307
308 protected:
309 PathElement(const PathEntry* entry, const PointF* points)
310 : _entry(entry)
311 , _pos(0.0, 0.0)
312 , _points(points)
313 {
314 }
315
316 void setPosition(const PointF& pos)
317 {
318 _pos = pos;
319 }
320
321 void setEntry(const PathEntry* entry, const PointF* points)
322 {
323 _entry = entry;
324 _points = points;
325 }
326
327 public:
331 {
332 return _entry->type();
333 }
334
337 std::size_t size() const
338 {
339 return _entry->size();
340 }
341
344 const PointF& position() const
345 {
346 return _pos;
347 }
348
351 const PointF& point(std::size_t n) const
352 {
353 return _points[n];
354 }
355
358 void flatten(Polygon& points, double tolerance = 0.25) const;
359
360 private:
361 const PathEntry* _entry;
362 PointF _pos;
363 const PointF* _points;
364};
365
370{
371 public:
372 using iterator_category = std::forward_iterator_tag;
373 using value_type = Path::Element;
374 using difference_type = std::ptrdiff_t;
375 using pointer = const Path::Element*;
376 using reference = const Path::Element&;
377
381 : _entry(0)
382 , _points(0)
383 , _element(0, 0)
384 {
385 }
386
389 PathIterator(const PathEntry* entry, const PointF* points)
390 : _entry(entry)
391 , _points(points)
392 , _element(_entry, _points)
393 {
394 }
395
398 const Path::Element& operator*() const
399 {
400 return _element;
401 }
402
405 const Path::Element* operator->() const
406 {
407 return &_element;
408 }
409
413 {
414 if( _entry->size() > 0)
415 {
416 const PointF& pos = _points[ _entry->size() - 1 ];
417 _element.setPosition(pos);
418 }
419
420 _points += _entry->size();
421 ++_entry;
422
423 _element.setEntry(_entry, _points);
424 return *this;
425 }
426
430 {
431 PathIterator tmp = *this;
432 ++(*this);
433 return tmp;
434 }
435
438 bool operator == (const PathIterator& other) const
439 {
440 return _entry == other._entry;
441 }
442
445 bool operator != (const PathIterator& other) const
446 {
447 return _entry != other._entry;
448 }
449
452 bool operator < (const PathIterator & other) const
453 {
454 return _entry < other._entry;
455 }
456
457 private:
458 const PathEntry* _entry;
459 const PointF* _points;
460 Path::Element _element;
461};
462
463/* @internal Path data.
464*/
465class PathData
466{
467 public:
468 PathData()
469 { }
470
471 ~PathData()
472 { }
473
474 const PointF& currentPosition() const
475 {
476 return _position;
477 }
478
479 void setCurrentPosition(const PointF& p)
480 {
481 _position = p;
482 }
483
484 Path::Iterator begin() const
485 {
486 return Path::Iterator( _entries.data(), _points.data() );
487 }
488
489 Path::Iterator end() const
490 {
491 return Path::Iterator(_entries.data() + _entries.size(), _points.data() + _points.size());
492 }
493
494 std::size_t size() const
495 {
496 return _entries.size();
497 }
498
499 bool isEmpty() const
500 {
501 return _entries.empty();
502 }
503
504 void clear()
505 {
506 _entries.clear();
507 _points.clear();
508 _start = PointF();
509 _position = PointF();
510 }
511
512 void append(const PathData& path);
513
514 void moveTo(const PointF& pos);
515
516 void lineTo(const PointF& pos);
517
518 void quadTo(const PointF& cp, const PointF& to);
519
520 void cubicTo(const PointF& cp1, const PointF& cp2, const PointF& to);
521
522 void close();
523
524 void transform(const Transform& tform);
525
526 private:
527 std::vector<PathEntry> _entries;
528 std::vector<PointF> _points;
529 PointF _start;
530 PointF _position;
531};
532
533} // namespace
534
535} // namespace
536
537#endif
Read-only view of a path element.
Definition Path.h:305
void flatten(Polygon &points, double tolerance=0.25) const
Flattens the element into polygon points.
Path::ElementType type() const
Returns the element type.
Definition Path.h:330
const PointF & position() const
Returns the current path position before the element.
Definition Path.h:344
const PointF & point(std::size_t n) const
Returns one point of the element.
Definition Path.h:351
std::size_t size() const
Returns the number of points stored in the element.
Definition Path.h:337
Forward iterator over path elements.
Definition Path.h:370
PathIterator operator++(int)
Advances to the next path element and returns the previous iterator.
Definition Path.h:429
PathIterator & operator++()
Advances to the next path element.
Definition Path.h:412
const Path::Element & operator*() const
Returns the current path element.
Definition Path.h:398
PathIterator(const PathEntry *entry, const PointF *points)
Constructs an iterator for the given storage pointers.
Definition Path.h:389
bool operator!=(const PathIterator &other) const
Returns true if both iterators refer to different elements.
Definition Path.h:445
bool operator<(const PathIterator &other) const
Returns true if this iterator precedes the other iterator.
Definition Path.h:452
bool operator==(const PathIterator &other) const
Returns true if both iterators refer to the same element.
Definition Path.h:438
const Path::Element * operator->() const
Returns a pointer to the current path element.
Definition Path.h:405
PathIterator()
Constructs an end iterator.
Definition Path.h:380
void quadTo(const PointF &cp, const PointF &to)
Adds a quadratic Bezier segment.
void addRect(const RectF &rect)
Adds a rectangle as a new subpath.
Iterator begin() const
Returns an iterator to the first element.
ElementType
Identifies the command stored in a path element.
Definition Path.h:86
void cubicTo(const PointF &cp1, const PointF &cp2, const PointF &to)
Adds a cubic Bezier segment.
void addChord(const PointF &topLeft, const SizeF &size, double degBegin, double degEnd)
Adds a chord as a new subpath.
void close()
Closes the current subpath.
void lineTo(const PointF &p)
Adds a straight line to the given point.
Iterator end() const
Returns an iterator past the last element.
const PointF & currentPosition() const
Returns the current drawing position.
void addArc(const PointF &topLeft, const SizeF &size, double degBegin, double degEnd)
Adds an arc as a new subpath.
void addEllipse(const PointF &topLeft, const SizeF &size)
Adds an ellipse as a new subpath.
Path toTransformed(const Transform &transform) const
Returns a copy of the path with the transform applied.
Path(const Path &other)
Copies another path.
bool intersects(const RectF &rect, FillRule rule=FillRule::NonZero) const
Returns true if the filled area of the path overlaps rect.
void addRoundedRect(const RectF &rect, double radius)
Adds a rounded rectangle as a new subpath.
void transform(const Transform &transform)
Applies a transform to all path coordinates.
Path()
Constructs an empty path.
bool contains(const PointF &point, FillRule rule=FillRule::NonZero) const
Returns true if the point lies inside the filled area of the path.
Iterator getPolygon(Iterator it, Polygon &polygon, float tolerance=0.25f) const
Flattens one subpath into polygon starting at it.
void addPie(const PointF &topLeft, const SizeF &size, double degBegin, double degEnd)
Adds a pie segment as a new subpath.
void addPolyline(const PointF *points, std::size_t count)
Adds a polyline as a new subpath.
void clear()
Removes all path elements.
bool isEmpty() const
Returns true if the path has no elements.
~Path()
Destroys the path.
void addPath(const Path &p)
Appends all elements of p to this path.
void addRoundedRect(const RectF &rect, double rx, double ry)
Adds a rounded rectangle with elliptical corners as a new subpath.
void arcTo(const PointF &topLeft, const SizeF &size, double degBegin, double degEnd)
Adds an arc segment to the current subpath.
std::size_t size() const
Returns the number of path elements.
void addPolygon(const PointF *points, std::size_t count)
Adds a polygon as a new closed subpath.
void moveTo(const PointF &p)
Starts a new subpath at the given point.
bool contains(const RectF &rect, FillRule rule=FillRule::NonZero) const
Returns true if the rectangle lies entirely inside the filled area.
Path & operator=(const Path &other)
Replaces the path contents.
RectF boundingRect() const
Returns the bounding rectangle of the path.
2D affine transform.
Definition Transform.h:54
Policy based smart pointer.
Definition SmartPtr.h:462
FillRule
Determines how overlapping subpaths of a filled shape are painted.
Definition FillRule.h:45
@ NonZero
Fills regions enclosed by a non-zero net winding count.
Definition FillRule.h:52
Graphics and imaging services.
Definition Api-Argb32Image.h:12
Core module.
Definition Allocator.h:33