15 return t < 0.0f ? 0.0f : (t > 1.0f ? 1.0f : t);
18float lerp(
float a,
float b,
float t)
20 return a + (b - a) * t;
23uint8_t lerp8(uint8_t a, uint8_t b,
float t)
25 return (uint8_t)(lerp((
float)a, (
float)b, t) + 0.5f);
30 return a.
r == b.
r && a.
g == b.
g && a.
b == b.
b && a.
a == b.
a;
43 c.
r = lerp8(a.
r, b.
r, t);
44 c.
g = lerp8(a.
g, b.
g, t);
45 c.
b = lerp8(a.
b, b.
b, t);
46 c.
a = lerp8(a.
a, b.
a, t);
77 shadowColor{ 0, 0, 0, 0 }, shadowBlur(0.0f), shadowSpread(0.0f), shadowDx(0.0f), shadowDy(0.0f)
102GuiPaint& GuiPaint::shadow(
float blur,
PixelColor c,
float dx,
float dy,
float spread)
108 shadowSpread = spread;
112GuiPaint& GuiPaint::glow(
float blur,
PixelColor c,
float spread)
114 return shadow(blur, c, 0.0f, 0.0f, spread);
117bool GuiPaint::operator==(
const GuiPaint& o)
const
121 if(strokeWidth != o.strokeWidth)
123 if(strokeWidth > 0.0f && (strokeAlign != o.strokeAlign || !sameFill(strokeFill, o.strokeFill)))
125 if(shadowColor.a != o.shadowColor.a)
127 if(shadowColor.a != 0 && (!sameColor(shadowColor, o.shadowColor) || shadowBlur != o.shadowBlur ||
128 shadowSpread != o.shadowSpread || shadowDx != o.shadowDx || shadowDy != o.shadowDy))
133GuiPaint GuiPaint::mix(
const GuiPaint& a,
const GuiPaint& b,
float t)
144 if(a.hasFill || b.hasFill)
148 if(!a.hasFill && b.fill.gradient)
149 fa =
GuiFill::linear(transparent(b.fill.from), transparent(b.fill.to), b.fill.angle);
150 if(!b.hasFill && a.fill.gradient)
151 fb =
GuiFill::linear(transparent(a.fill.from), transparent(a.fill.to), a.fill.angle);
152 p.fill = mixFill(fa, fb, t);
157 if(a.strokeWidth > 0.0f || b.strokeWidth > 0.0f)
159 GuiFill sa = a.strokeWidth > 0.0f ? a.strokeFill : b.strokeFill;
160 GuiFill sb = b.strokeWidth > 0.0f ? b.strokeFill : a.strokeFill;
161 p.strokeFill = mixFill(sa, sb, t);
162 p.strokeWidth = lerp(a.strokeWidth, b.strokeWidth, t);
163 p.strokeAlign = t < 0.5f ? (a.strokeWidth > 0.0f ? a.strokeAlign : b.strokeAlign) : (b.strokeWidth > 0.0f ? b.strokeAlign : a.strokeAlign);
167 if(a.shadowColor.a != 0 || b.shadowColor.a != 0)
169 const GuiPaint& sa = a.shadowColor.a != 0 ? a : b;
170 const GuiPaint& sb = b.shadowColor.a != 0 ? b : a;
171 PixelColor ca = a.shadowColor.
a != 0 ? a.shadowColor : transparent(b.shadowColor);
172 PixelColor cb = b.shadowColor.
a != 0 ? b.shadowColor : transparent(a.shadowColor);
173 p.shadowColor = mixColor(ca, cb, t);
174 p.shadowBlur = lerp(sa.shadowBlur, sb.shadowBlur, t);
175 p.shadowSpread = lerp(sa.shadowSpread, sb.shadowSpread, t);
176 p.shadowDx = lerp(sa.shadowDx, sb.shadowDx, t);
177 p.shadowDy = lerp(sa.shadowDy, sb.shadowDy, t);
182GuiShapeStyle::GuiShapeStyle(
const GuiPaint& normalPaint) :
183 normal(normalPaint), hasFocused(false), hasPressed(false), hasDisabled(false)
212 case SHAPE_STATE::PRESSED:
return hasPressed ? pressed : (hasFocused ? focused : normal);
213 case SHAPE_STATE::DISABLED:
return hasDisabled ? disabled : normal;
214 default:
return normal;
220 const float half = 0.5f * std::min(r.
w, r.
h);
223 if(paint.shadowColor.a != 0)
224 mesh.
addShadow(r, outline, paint.shadowBlur, paint.shadowSpread, paint.shadowDx, paint.shadowDy, paint.shadowColor);
231 const bool strokeOpaque = paint.strokeFill.from.a == 255 && (!paint.strokeFill.gradient || paint.strokeFill.to.a == 255);
232 const bool edgeFringe = !(paint.strokeWidth > 0.0f && paint.strokeAlign ==
STROKE::INSIDE && strokeOpaque &&
233 std::min(paint.strokeWidth, half) >= mesh.
getFeather());
241 if(paint.strokeWidth > 0.0f)
244 mesh.
strokeEllipse(r, paint.strokeWidth, paint.strokeAlign, paint.strokeFill);
246 mesh.
strokeRoundRect(r, corners, paint.strokeWidth, paint.strokeAlign, paint.strokeFill);
252 return mixColor(a, b, clamp01(t));
Accumulates shapes as a triangle list of MeshVertex.
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.
void strokeEllipse(const GuiRect &r, float width, STROKE align, const GuiFill &fill)
Adds an ellipse outline.
void addRoundRect(const GuiRect &r, const GuiCorners &corners, const GuiFill &fill, bool edgeFringe=true)
Adds a filled rounded 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.
void addEllipse(const GuiRect &r, const GuiFill &fill, bool edgeFringe=true)
Adds a filled ellipse inscribed in a rectangle (a circle when w == h)
bool hasFill
The look of a shape: an optional fill, an optional outline and an optional shadow or glow.
STROKE
Where a stroke sits relative to the shape's geometric edge.
SHAPE_STATE
The states a styled shape distinguishes.
void GuiAddPaintedShape(GuiMesh &mesh, SHAPE shape, const GuiRect &r, const GuiCorners &corners, const GuiPaint &paint)
Adds a painted shape to a mesh: shadow first, then fill, then outline.
SHAPE
Basic shape kinds a paint can be applied to.
PixelColor GuiMixColor(PixelColor a, PixelColor b, float t)
Blends two colors per channel (alpha included): t = 0 gives a, t = 1 gives b.
@ INSIDE
Entirely inside the edge (the shape keeps its size)
@ FOCUSED
Highlighted: under the cursor, or selected with the D-pad.
@ ELLIPSE
Ellipse inscribed in the rectangle (a circle when it is square)
Per-corner radii, in the order top-left, top-right, bottom-right, bottom-left.
A solid color or a two-color linear gradient.
bool gradient
true for a gradient, false for a solid color.
PixelColor from
Solid color, or the gradient's start color.
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).
float angle
Gradient direction in degrees: 0 = left to right, 90 = top to bottom.
An axis-aligned rectangle (top-left origin) in design-canvas pixels.
A set of paints, one per state. States left unset fall back to the normal paint. GuiShapeStyle(rest)....
const GuiPaint & forState(SHAPE_STATE s) const
Gets the paint for a state, falling back to normal when none was set.
8-bit-per-channel RGBA color used by the video interfaces.
uint8_t g
Green color component.
uint8_t r
Red color component.
uint8_t b
Blue color component.
uint8_t a
Alpha component.