CeresEngine 0.2.0
A game development framework
Loading...
Searching...
No Matches
Shape.hpp
Go to the documentation of this file.
1//
2// CeresEngine - A game development framework
3//
4// Created by Rogiel Sulzbach.
5// Copyright (c) 2018-2022 Rogiel Sulzbach. All rights reserved.
6//
7
8#pragma once
9
10#include "BezierPath.hpp"
11
14
19
21
22namespace CeresEngine {
23
24 class BezierPath;
25
27 class Paint {
28 public:
43
47 struct BoxGradient {
50
53
55 Rect2 box;
56
58 double radius;
59
61 double feather;
62 };
63
81
82 private:
85
88
89 public:
91 Paint() : Paint(Color()) {}
92
95
101 Paint(const Color& startingColor, const Color& endingColor, const Point2& startingPosition = {0, 0}, const Point2& endingPosition = {1, 1})
102 : mData(LinearGradient{startingColor, endingColor, startingPosition, endingPosition}) {}
103
110 Paint(const Color& startingColor, const Color& endingColor, const Rect2& box = {0, 0, 1, 1}, double radius = 0.0, double feather = 1.0)
111 : mData(BoxGradient{startingColor, endingColor, box, radius, feather}) {}
112
119 Paint(const Color& startingColor, const Color& endingColor, const Point2& center = {0, 0}, double innerRadius = 0.0, double outerRadius = 1.0)
120 : mData(RadialGradient{startingColor, endingColor, center, innerRadius, outerRadius}) {}
121
123 Paint(const Paint&) = default;
124
126 Paint& operator=(const Paint&) = default;
127
128 public:
130 [[nodiscard]] bool isColor() const noexcept { return mData.is<Color>(); }
131
134 [[nodiscard]] const Color& asColor() const { return mData.as<Color>(); }
135
138
142
145
148 [[nodiscard]] const BoxGradient& asBoxGradient() const { return mData.as<BoxGradient>(); }
149
152
156
157 public:
161 void transform(const AffineTransform& aTransform);
162
166 [[nodiscard]] Paint transformed(const AffineTransform& aTransform) const {
167 Paint copy = *this;
169 return copy;
170 }
171
172 public:
175 Paint& tint(const Color& color, double factor = 0.5);
176
178 [[nodiscard]] Paint tinted(const Color& color, const double factor = 0.5) const {
179 Paint copy = *this;
180 return copy.tint(color, factor);
181 }
182
184 Paint& operator*=(const Color& color) { return tint(color); }
185
187 [[nodiscard]] Paint operator*(const Color& color) const { return tinted(color); }
188 };
189
198 class Shape {
199 public:
202 enum class LineCapStyle {
205 Butt,
206
209 Round,
210
213 Square
214 };
215
218 enum class LineJoinStyle {
221 Miter,
222
225 Round,
226
229 Bevel
230 };
231
248 enum class BlendMode {
251 Normal,
252
256 Multiply,
257
262 Screen,
263
265 Overlay,
266
268 Darken,
269
271 Lighten,
272
277
281 ColorBurn,
282
284 SoftLight,
285
287 HardLight,
288
291
296 Exclusion,
297
300 Hue,
301
307
312 Color,
313
318
320 Clear,
321
323 Copy,
324
326 SourceIn,
327
329 SourceOut,
330
333
336
339
342
345
349 XorOp,
350
353
356 };
357
358 enum class ElementType {
359 Fill,
360 Stroke
361 };
362
410
413
414 private:
417
420
421 public:
423 explicit Shape();
424
427 explicit Shape(AnyAllocatorReference allocator);
428
429 Shape(const Shape& other);
430 Shape& operator=(const Shape& other);
431
432 Shape(const Shape& other, AnyAllocatorReference allocator);
433
434 Shape(Shape&& other) noexcept;
435 Shape& operator=(Shape&& other) noexcept;
436
437 ~Shape() = default;
438
440
442 template<typename Allocator> explicit Shape(std::allocator_arg_t, const Allocator& allocator) : Shape(allocator.get_allocator()) {}
443
445 template<typename Allocator>
446 explicit Shape(std::allocator_arg_t, const Allocator& allocator, const Shape& other) : Shape(other, allocator.get_allocator()) {}
447
448 public:
460 void stroke(const BezierPath& path, const Paint& paint, double lineWidth = 1.0, BlendMode blendMode = BlendMode::Normal,
461 LineCapStyle lineCapStyle = LineCapStyle::Butt, LineJoinStyle lineJoinStyle = LineJoinStyle::Miter, double miterLimit = 10.0);
462
464 void stroke(BezierPath&& path, const Paint& paint, double lineWidth = 1.0, BlendMode blendMode = BlendMode::Normal,
465 LineCapStyle lineCapStyle = LineCapStyle::Butt, LineJoinStyle lineJoinStyle = LineJoinStyle::Miter, double miterLimit = 10.0);
466
481 void fill(const BezierPath& path, const Paint& paint, BlendMode blendMode = BlendMode::Normal);
482
484 void fill(BezierPath&& path, const Paint& paint, BlendMode blendMode = BlendMode::Normal);
485
486 private:
491 [[nodiscard]] const BezierPath& appendPath(const BezierPath& path);
492
495
503
506
507 public:
514 void append(const Shape& aShape);
515
518
521 append(aShape);
522 return *this;
523 }
524
527 append(std::move(aShape));
528 return *this;
529 }
530
533 Shape copy = *this;
534 copy += aShape;
535 return copy;
536 }
537
540 Shape copy = *this;
541 copy += std::move(aShape);
542 return copy;
543 }
544
545 public: // Applying Transformations
553 void transform(const AffineTransform& aTransform);
554
556 [[nodiscard]] Shape transformed(const AffineTransform& aTransform) const&;
557
559 [[nodiscard]] Shape&& transformed(const AffineTransform& aTransform) && {
561 return std::move(*this);
562 }
563
564 public: // Performing Hit-Testing
579 [[nodiscard]] bool contains(const Point2& aPoint) const;
580
582 [[nodiscard]] bool operator&(const Point2& aPoint) const { return contains(aPoint); }
583
584 public: // Transformations
593 void flatten();
594
597
600 flatten();
601 return std::move(*this);
602 }
603
620 void reverse();
621
624
627 reverse();
628 return std::move(*this);
629 }
630
631 public: // Querying a Shape
642 [[nodiscard]] Rect2 getBounds() const;
643
653
664 [[nodiscard]] Rect2 getBoundsAccurate() const;
665
670 [[nodiscard]] bool isEmpty() const;
671
672 public: // Accessing Elements of a Shape
676
685 [[nodiscard]] const Element& getElement(UInt32 index) const;
686
688 [[nodiscard]] const Element& operator[](const UInt32 index) const { return getElement(index); }
689
691 [[nodiscard]] ElementIterator cbegin() const { return mElements.cbegin(); }
692
694 [[nodiscard]] ElementIterator begin() const { return cbegin(); }
695
697 [[nodiscard]] ElementIterator cend() const { return mElements.cend(); }
698
700 [[nodiscard]] ElementIterator end() const { return cend(); }
701
702 public:
703 AnyAllocatorReference getAllocator() const noexcept { return mElements.get_allocator().get_allocator(); }
704 };
705
706} // namespace CeresEngine
707
708template<typename Alloc> struct std::uses_allocator<CeresEngine::Shape, Alloc> : std::true_type {};
#define CE_EXPLICIT(EXPR)
Definition Macros.hpp:413
A path that consists of straight and curved line segments that you can render.
Definition BezierPath.hpp:46
A class that encapsulates a 2D paint object.
Definition Shape.hpp:27
Paint & operator=(const Paint &)=default
Assigns the paint object by copying from another.
Paint()
Creates a new default color paint.
Definition Shape.hpp:91
const RadialGradient & asRadialGradient() const
Gets the paint radial gradient value.
Definition Shape.hpp:155
Paint(const Color &startingColor, const Color &endingColor, const Point2 &center={0, 0}, double innerRadius=0.0, double outerRadius=1.0)
Creates a new linear gradient paint.
Definition Shape.hpp:119
Paint transformed(const AffineTransform &aTransform) const
Transforms all coordinates in the paint object with the specified transform.
Definition Shape.hpp:166
Paint(const Paint &)=default
Creates a new paint by copying another.
Paint & tint(const Color &color, double factor=0.5)
Applies a tint color to the paint.
Variant mData
The storage for the concrete paint implementation structure.
Definition Shape.hpp:87
Paint(const Color &startingColor, const Color &endingColor, const Point2 &startingPosition={0, 0}, const Point2 &endingPosition={1, 1})
Creates a new linear gradient paint.
Definition Shape.hpp:101
bool isBoxGradient() const noexcept
Checks if the paint holds a box gradient.
Definition Shape.hpp:144
const LinearGradient & asLinearGradient() const
Gets the paint linear gradient value.
Definition Shape.hpp:141
const Color & asColor() const
Gets the paint solid color value.
Definition Shape.hpp:134
bool isColor() const noexcept
Checks if the paint holds a solid color.
Definition Shape.hpp:130
Paint & operator*=(const Color &color)
Applies a tint color to the paint.
Definition Shape.hpp:184
Paint tinted(const Color &color, const double factor=0.5) const
Applies a tint color to the paint.
Definition Shape.hpp:178
Variant< Color, LinearGradient, BoxGradient, RadialGradient > Variant
A variant used to store the concrete paint implementation structure.
Definition Shape.hpp:84
Paint operator*(const Color &color) const
Applies a tint color to the paint.
Definition Shape.hpp:187
void transform(const AffineTransform &aTransform)
Transforms all coordinates in the paint object with the specified transform.
bool isLinearGradient() const noexcept
Checks if the paint holds a linear gradient.
Definition Shape.hpp:137
Paint(const Color &startingColor, const Color &endingColor, const Rect2 &box={0, 0, 1, 1}, double radius=0.0, double feather=1.0)
Creates a new linear gradient paint.
Definition Shape.hpp:110
const BoxGradient & asBoxGradient() const
Gets the paint box gradient value.
Definition Shape.hpp:148
bool isRadialGradient() const noexcept
Checks if the paint holds a radial gradient.
Definition Shape.hpp:151
A type that describes a conjunction of shapes that can be filled and stroked.
Definition Shape.hpp:198
Deque< BezierPath, AnyAllocator > mPaths
A vector that stores a unique copy of each path.
Definition Shape.hpp:416
Deque< Element, AnyAllocator > mElements
A vector of all elements in the shape.
Definition Shape.hpp:419
Shape & operator+=(const Shape &aShape)
Appends the contents of the specified shape object to the shape.
Definition Shape.hpp:520
ElementType
Definition Shape.hpp:358
Shape transformed(const AffineTransform &aTransform) const &
Transforms all points in the shape using the specified transform.
AnyAllocatorReference getAllocator() const noexcept
Definition Shape.hpp:703
void fill(const BezierPath &path, const Paint &paint, BlendMode blendMode=BlendMode::Normal)
Paints the region enclosed by the path.
Rect2 getBoundsAccurate() const
The bounding box of the shape.
BlendMode
Compositing operations for images.
Definition Shape.hpp:248
@ Exclusion
Produces an effect similar to that produced by difference, but with lower contrast.
@ Saturation
Uses the luminance and hue values of the background with the saturation of the source image.
@ Screen
Multiplies the inverse of the source image samples with the inverse of the background image samples,...
@ DestinationOut
R = D*(1 - Sa)
@ PlusLighter
R = MIN(1, S + D)
@ Luminosity
Uses the hue and saturation of the background with the luminance of the source image.
@ PlusDarker
R = MAX(0, 1 - ((1 - D) + (1 - S)))
@ DestinationOver
R = S*(1 - Da) + D.
@ SourceAtop
R = S*Da + D*(1 - Sa)
@ DestinationAtop
R = S*(1 - Da) + D*Sa.
@ Normal
Paints the source image samples over the background image samples.
@ ColorBurn
Darkens the background image samples to reflect the source image samples.
@ XorOp
R = S*(1 - Da) + D*(1 - Sa).
@ Color
Uses the luminance values of the background with the hue and saturation values of the source image.
@ Multiply
Multiplies the source image samples with the background image samples.
@ ColorDodge
Brightens the background image samples to reflect the source image samples.
@ Hue
Uses the luminance and saturation values of the background with the hue of the source image.
Shape(Shape &&other) noexcept
LineCapStyle
Constants that specify the shape of endpoints for an open path when it is stroked.
Definition Shape.hpp:202
@ Butt
Specifies a butt line cap style for endpoints for an open path when stroked.
@ Round
Specifies a round line cap style for endpoints for an open path when stroked.
@ Square
Specifies a square line cap style for endpoints for an open path when stroked.
typename Deque< Element >::const_iterator ElementIterator
An iterator type that allows iterating over the shape elements.
Definition Shape.hpp:412
Shape()
Creates a new empty shape using a default allocator.
Shape & operator+=(Shape &&aShape)
Appends the contents of the specified shape object to the shape.
Definition Shape.hpp:526
void append(const Shape &aShape)
Appends the contents of the specified shape object to the shape.
void reverse()
Computes a shape containing the reversed contents of the current shape path objects.
Shape(std::allocator_arg_t, const Allocator &allocator, const Shape &other)
Definition Shape.hpp:446
bool operator&(const Point2 &aPoint) const
Returns a Boolean value that indicates whether the shape contains the specified point.
Definition Shape.hpp:582
const Element & getElement(UInt32 index) const
Returns the type of shape element at the specified index.
ElementIterator cend() const
Returns an iterator that points to past-the-last path element.
Definition Shape.hpp:697
void append(Shape &&aShape)
Appends the contents of the specified shape object to the shape.
ElementIterator begin() const
Returns an iterator that points to the first path element.
Definition Shape.hpp:694
void stroke(const BezierPath &path, const Paint &paint, double lineWidth=1.0, BlendMode blendMode=BlendMode::Normal, LineCapStyle lineCapStyle=LineCapStyle::Butt, LineJoinStyle lineJoinStyle=LineJoinStyle::Miter, double miterLimit=10.0)
Draws a line along the path using the given stroke color and drawing attributes.
Shape(std::allocator_arg_t, const Allocator &allocator)
Creates a new empty shape using a custom allocator.
Definition Shape.hpp:442
Shape flattened() const &
Computes a flattened version of the shape object.
Element & appendElement(ElementType type, BezierPath &&path)
Appends a new element to the shape.
Shape(const Shape &other, AnyAllocatorReference allocator)
Shape && transformed(const AffineTransform &aTransform) &&
Transforms all points in the shape using the specified transform.
Definition Shape.hpp:559
void stroke(BezierPath &&path, const Paint &paint, double lineWidth=1.0, BlendMode blendMode=BlendMode::Normal, LineCapStyle lineCapStyle=LineCapStyle::Butt, LineJoinStyle lineJoinStyle=LineJoinStyle::Miter, double miterLimit=10.0)
Draws a line along the path using the given stroke color and drawing attributes.
ElementIterator cbegin() const
Returns an iterator that points to the first path element.
Definition Shape.hpp:691
bool isEmpty() const
A Boolean value that indicates whether the shape is empty.
void flatten()
Computes a flattened version of the shape object.
LineJoinStyle
Constants that specify the shape of the joins between connected segments of a stroked path.
Definition Shape.hpp:218
@ Bevel
Specifies a bevel line shape of the joints between connected segments of a stroked path.
@ Miter
Specifies a miter line shape of the joints between connected segments of a stroked path.
UInt32 getElementCount() const
The total number of shape elements in the shape.
const Element & operator[](const UInt32 index) const
Returns the type of shape element at the specified index.
Definition Shape.hpp:688
void fill(BezierPath &&path, const Paint &paint, BlendMode blendMode=BlendMode::Normal)
Paints the region enclosed by the path.
Shape operator+(Shape &&aShape) const
Appends the contents of the specified shape object to the shape.
Definition Shape.hpp:539
const BezierPath & appendPath(const BezierPath &path)
Appends a path to the internal list of paths.
Shape(AnyAllocatorReference allocator)
Creates a new empty shape using a custom allocator.
Shape & operator=(const Shape &other)
Shape reversed() const &
Computes a shape containing the reversed contents of the current shape path objects.
Rect2 getBounds() const
The bounding box of the shape.
Shape(const Shape &other)
Shape & operator=(Shape &&other) noexcept
AnyStdAllocator< Shape > allocator_type
Definition Shape.hpp:439
const BezierPath & appendPath(BezierPath &&path)
Appends a path to the internal list of paths.
ElementIterator end() const
Returns an iterator that points to past-the-last path element.
Definition Shape.hpp:700
void transform(const AffineTransform &aTransform)
Transforms all points in the shape using the specified transform.
Rect2 getControlPointBounds() const
The bounding box of the shape, including any control points.
Element & appendElement(ElementType type, const BezierPath &path)
Appends a new element to the shape.
Shape operator+(const Shape &aShape) const
Appends the contents of the specified shape object to the shape.
Definition Shape.hpp:532
bool contains(const Point2 &aPoint) const
Returns a Boolean value that indicates whether the shape contains the specified point.
constexpr T & as() &
Definition Variant.hpp:29
constexpr bool is() const noexcept
Definition Variant.hpp:27
Definition Application.hpp:19
std::deque< T, ScopedAllocatorAdaptor< StdAllocator< T, RawAllocator > > > Deque
Deque (double-ended queue) is an indexed sequence container that allows fast insertion and deletion a...
Definition Deque.hpp:20
Box box(T &value)
Creates a new Box object by wraping the value as a reference type.
Definition Box.hpp:672
foonathan::memory::any_allocator_reference AnyAllocatorReference
Definition Allocator.hpp:98
foonathan::memory::any_std_allocator< T > AnyStdAllocator
Definition Allocator.hpp:228
@ Color
Attachment is used for color output.
DefaultAllocator & gDefaultAllocator()
std::uint32_t UInt32
Definition DataTypes.hpp:23
void copy(const A &a, B &b, T &&t=T())
Copies values from one container to another.
Definition Iterator.hpp:564
constexpr size_t hash(const T &v)
Generates a hash for the provided type.
Definition Hash.hpp:25
A structure that describes a box gradient.
Definition Shape.hpp:47
double feather
Feather defines how blurry the border of the rectangle is.
Definition Shape.hpp:61
Color startingColor
The gradient starting color.
Definition Shape.hpp:49
double radius
Defines the corner radius.
Definition Shape.hpp:58
Rect2 box
Defines the box in which the gradient should be drawn.
Definition Shape.hpp:55
Color endingColor
The gradient ending color.
Definition Shape.hpp:52
A structure that describes a linear gradient.
Definition Shape.hpp:30
Point2 startingPosition
The gradient starting position.
Definition Shape.hpp:38
Color startingColor
The gradient starting color at startingPosition.
Definition Shape.hpp:32
Point2 endingPosition
The gradient ending position.
Definition Shape.hpp:41
Color endingColor
The gradient ending color at endingPosition.
Definition Shape.hpp:35
A structure that describes a radial gradient.
Definition Shape.hpp:65
Color startingColor
The gradient starting color at `center“.
Definition Shape.hpp:67
Point2 center
The center of the radial gradient.
Definition Shape.hpp:73
Color endingColor
The gradient ending color at center + outerRadius.
Definition Shape.hpp:70
double outerRadius
The gradient outer radius.
Definition Shape.hpp:79
double innerRadius
The gradient inner radius.
Definition Shape.hpp:76
An element is composed of a path and one or more commands to be done on that path.
Definition Shape.hpp:366
LineJoinStyle lineJoinStyle
The line join style for the path.
Definition Shape.hpp:383
LineCapStyle lineCapStyle
The line cap style for the path.
Definition Shape.hpp:380
double miterLimit
The limit at which miter joins are converted to bevel joins.
Definition Shape.hpp:403
Element(const ElementType type, const BezierPath &path)
Creates a new element instance.
Definition Shape.hpp:408
double lineWidth
The width of stroked path lines.
Definition Shape.hpp:395
BlendMode blendMode
A constant that describes the blending mode for the operation.
Definition Shape.hpp:377
Paint paint
The paint to be used to fill or stroke the path.
Definition Shape.hpp:374
const ElementType type
A constant that describes the type of the element.
Definition Shape.hpp:368
const BezierPath & path
A reference to an internally cached bezier path object.
Definition Shape.hpp:371