libgui 2.01
libgui is a GUI library for the GameCube, Wii, and Wii U
 
Loading...
Searching...
No Matches
GuiGeometry.h
1/****************************************************************************
2 * libgui
3 * Daryl Borth 2026
4 * GuiGeometry.h
5 *
6 * Platform-agnostic shape tessellation. Turns rounded rectangles, ellipses,
7 * polygons, strokes, arcs and soft shadows into triangle meshes with
8 * per-vertex colors. Edges are anti-aliased by a thin feathered fringe whose
9 * vertices fade to alpha 0, so no multisampling is needed. Nothing here
10 * touches a platform API; a mesh is drawn by whatever renders MeshVertex
11 * triangle lists.
12 *
13 * Coordinates are design-canvas pixels, +Y down. Every triangle is emitted
14 * with the same (clockwise on screen) winding.
15 ***************************************************************************/
16#pragma once
17#include <cstddef>
18#include <vector>
19#include "../drivers/Mesh.h"
20
23struct GuiPoint {
24 float x;
25 float y;
26};
27
30struct GuiRect {
31 float x;
32 float y;
33 float w;
34 float h;
35};
36
40struct GuiCorners {
41 float tl;
42 float tr;
43 float br;
44 float bl;
46 GuiCorners(float r = 0) : tl(r), tr(r), br(r), bl(r) {}
47 GuiCorners(float tl_, float tr_, float br_, float bl_) : tl(tl_), tr(tr_), br(br_), bl(bl_) {}
48};
49
52enum class STROKE {
54 CENTRE,
56};
57
60struct GuiFill {
63 float angle;
64 bool gradient;
65
67 static GuiFill solid(PixelColor c);
72 static GuiFill linear(PixelColor a, PixelColor b, float angleDeg);
73};
74
81struct GuiPath {
82 enum CMD : uint8_t { MOVE = 'M', LINE = 'L', CUBIC = 'C', CLOSE = 'Z' };
83 std::vector<uint8_t> cmds;
84 std::vector<float> pts;
85
87 bool empty() const { return cmds.empty(); }
88 GuiPath& moveTo(float x, float y) { cmds.push_back(MOVE); pts.push_back(x); pts.push_back(y); return *this; }
89 GuiPath& lineTo(float x, float y) { cmds.push_back(LINE); pts.push_back(x); pts.push_back(y); return *this; }
90 GuiPath& cubicTo(float x1, float y1, float x2, float y2, float x, float y)
91 {
92 cmds.push_back(CUBIC);
93 pts.push_back(x1); pts.push_back(y1); pts.push_back(x2); pts.push_back(y2); pts.push_back(x); pts.push_back(y);
94 return *this;
95 }
96 GuiPath& close() { cmds.push_back(CLOSE); return *this; }
97};
98
106std::vector<std::vector<GuiPoint> > GuiFlattenPath(const GuiPath& path, float scale, float tolerance = 0.15f);
107
111GuiRect GuiPathBounds(const GuiPath& path, float scale = 1.0f);
112
121std::vector<GuiPoint> GuiRoundRectPolygon(const GuiRect& r, float radius, float angleDeg, float tolerance = 0.15f);
122
128{
129 public:
135 GuiMesh(float featherWidth = 1.0f, float curveTolerance = 0.3f);
136
138 void clear();
140 size_t size() const { return verts.size(); }
142 bool empty() const { return verts.empty(); }
144 const std::vector<MeshVertex>& vertices() const { return verts; }
146 float getFeather() const { return feather; }
148 float getTolerance() const { return tolerance; }
149
151 void addRect(const GuiRect& r, const GuiFill& fill, bool edgeFringe = true);
155 void addRoundRect(const GuiRect& r, const GuiCorners& corners, const GuiFill& fill, bool edgeFringe = true);
158 void addEllipse(const GuiRect& r, const GuiFill& fill, bool edgeFringe = true);
162 void addPolygon(const std::vector<GuiPoint>& pts, const GuiFill& fill, bool edgeFringe = true);
164 void addLine(GuiPoint a, GuiPoint b, float width, const GuiFill& fill);
165
167 void strokeRoundRect(const GuiRect& r, const GuiCorners& corners, float width, STROKE align, const GuiFill& fill);
169 void strokeEllipse(const GuiRect& r, float width, STROKE align, const GuiFill& fill);
172 void strokePolygon(const std::vector<GuiPoint>& pts, float width, STROKE align, const GuiFill& fill);
175 void strokeArc(GuiPoint centre, float radius, float startDeg, float sweepDeg, float width, PixelColor color);
176
183 void addShadow(const GuiRect& r, const GuiCorners& corners, float blur, float spread, float dx, float dy, PixelColor color);
184
185 private:
186 std::vector<MeshVertex> verts;
187 float feather;
188 float tolerance;
189};
void addShadow(const GuiRect &r, const GuiCorners &corners, float blur, float spread, float dx, float dy, PixelColor color)
Adds a soft drop shadow or glow for a rounded rectangle.
float getTolerance() const
Gets the curve tolerance the mesh was built with.
bool empty() const
Checks whether the mesh has no geometry.
void clear()
Removes all geometry (keeps the feather and tolerance settings)
GuiMesh(float featherWidth=1.0f, float curveTolerance=0.3f)
Constructor.
void addLine(GuiPoint a, GuiPoint b, float width, const GuiFill &fill)
Adds a straight line with flat ends.
void strokePolygon(const std::vector< GuiPoint > &pts, float width, STROKE align, const GuiFill &fill)
Adds a polygon outline with mitered corners (the miter is capped on very sharp corners).
void strokeEllipse(const GuiRect &r, float width, STROKE align, const GuiFill &fill)
Adds an ellipse outline.
size_t size() const
Gets the number of vertices (a multiple of 3)
void addRoundRect(const GuiRect &r, const GuiCorners &corners, const GuiFill &fill, bool edgeFringe=true)
Adds a filled rounded rectangle.
void strokeArc(GuiPoint centre, float radius, float startDeg, float sweepDeg, float width, PixelColor color)
Adds an arc stroke centered on a radius, with flat ends.
void addPolygon(const std::vector< GuiPoint > &pts, const GuiFill &fill, bool edgeFringe=true)
Adds a filled polygon (triangle, chevron, a controller silhouette, ...).
void addRect(const GuiRect &r, const GuiFill &fill, bool edgeFringe=true)
Adds a filled rectangle.
void strokeRoundRect(const GuiRect &r, const GuiCorners &corners, float width, STROKE align, const GuiFill &fill)
Adds a rounded-rectangle outline.
float getFeather() const
Gets the feather width the mesh was built with.
const std::vector< MeshVertex > & vertices() const
Gets the triangle list.
void addEllipse(const GuiRect &r, const GuiFill &fill, bool edgeFringe=true)
Adds a filled ellipse inscribed in a rectangle (a circle when w == h)
std::vector< GuiPoint > GuiRoundRectPolygon(const GuiRect &r, float radius, float angleDeg, float tolerance=0.15f)
A rounded rectangle as a convex polygon, rotated about its center.
STROKE
Where a stroke sits relative to the shape's geometric edge.
Definition GuiGeometry.h:52
std::vector< std::vector< GuiPoint > > GuiFlattenPath(const GuiPath &path, float scale, float tolerance=0.15f)
Turns a path into one polygon per contour, multiplied by scale.
GuiRect GuiPathBounds(const GuiPath &path, float scale=1.0f)
Gets the bounding box of a path's points (control points included, so it can be a little larger than ...
@ INSIDE
Entirely inside the edge (the shape keeps its size)
Definition GuiGeometry.h:53
@ OUTSIDE
Entirely outside the edge.
Definition GuiGeometry.h:55
Per-corner radii, in the order top-left, top-right, bottom-right, bottom-left.
Definition GuiGeometry.h:40
float tl
Top-left radius.
Definition GuiGeometry.h:41
GuiCorners(float r=0)
Same radius on every corner (0 = square)
Definition GuiGeometry.h:46
float bl
Bottom-left radius.
Definition GuiGeometry.h:44
float tr
Top-right radius.
Definition GuiGeometry.h:42
float br
Bottom-right radius.
Definition GuiGeometry.h:43
A solid color or a two-color linear gradient.
Definition GuiGeometry.h:60
bool gradient
true for a gradient, false for a solid color.
Definition GuiGeometry.h:64
PixelColor from
Solid color, or the gradient's start color.
Definition GuiGeometry.h:61
static GuiFill linear(PixelColor a, PixelColor b, float angleDeg)
A linear gradient across the shape's bounding box.
static GuiFill solid(PixelColor c)
A single flat color.
PixelColor to
The gradient's end color (unused when solid).
Definition GuiGeometry.h:62
float angle
Gradient direction in degrees: 0 = left to right, 90 = top to bottom.
Definition GuiGeometry.h:63
A closed outline made of straight lines and cubic Beziers, in whatever units the caller likes.
Definition GuiGeometry.h:81
std::vector< uint8_t > cmds
One CMD per segment.
Definition GuiGeometry.h:83
std::vector< float > pts
x, y pairs, as many as the commands consume.
Definition GuiGeometry.h:84
bool empty() const
Checks whether the path has no commands.
Definition GuiGeometry.h:87
A 2D point in design-canvas pixels.
Definition GuiGeometry.h:23
float x
X coordinate.
Definition GuiGeometry.h:24
float y
Y coordinate.
Definition GuiGeometry.h:25
An axis-aligned rectangle (top-left origin) in design-canvas pixels.
Definition GuiGeometry.h:30
float x
Left edge.
Definition GuiGeometry.h:31
float w
Width.
Definition GuiGeometry.h:33
float h
Height.
Definition GuiGeometry.h:34
float y
Top edge.
Definition GuiGeometry.h:32
8-bit-per-channel RGBA color used by the video interfaces.
Definition Mesh.h:16