diff --git a/src/main/java/org/saturnclient/ui/RenderScope.java b/src/main/java/org/saturnclient/ui/RenderScope.java
index ed4513f..0bbc677 100644
--- a/src/main/java/org/saturnclient/ui/RenderScope.java
+++ b/src/main/java/org/saturnclient/ui/RenderScope.java
@@ -3,6 +3,7 @@ package org.saturnclient.ui;
import java.io.ByteArrayInputStream;
import java.io.InputStream;
import java.nio.charset.StandardCharsets;
+import java.util.Locale;
import org.saturnclient.common.ref.asset.IdentifierRef;
import org.saturnclient.common.ref.asset.SpriteRef;
@@ -36,19 +37,66 @@ public interface RenderScope {
radius = Math.min(radius, width / 2);
radius = Math.min(radius, height / 2);
- String svg = String.format(
- "",
- width, height,
+ String rect = String.format(
+ "",
width, height,
radius, radius);
+ drawSvgShape(rect, "rounded_" + width + "_" + height + "_" + radius, x, y, width, height, color);
+ }
+
+ /**
+ * Draws a rounded outline that stays inside the given bounds, so it lines up
+ * with a {@link #drawRoundedRectangle} of the same size and radius.
+ */
+ default void drawRoundedBorder(int x, int y, int width, int height, int radius, int thickness, int color) {
+ if (color == 0 || thickness <= 0)
+ return;
+
+ radius = Math.min(radius, width / 2);
+ radius = Math.min(radius, height / 2);
+ thickness = Math.min(thickness, Math.min(width, height) / 2);
+
+ // The stroke is centered on the path, so inset it by half its width.
+ float inset = thickness / 2f;
+ float innerRadius = Math.max(0, radius - inset);
+
+ String rect = String.format(Locale.ROOT,
+ "",
+ inset, inset,
+ width - (float) thickness, height - (float) thickness,
+ innerRadius, innerRadius,
+ thickness);
+
+ drawSvgShape(rect, "rounded_border_" + width + "_" + height + "_" + radius + "_" + thickness,
+ x, y, width, height, color);
+ }
+
+ /**
+ * Draws a rounded rectangle filled with {@code background} and outlined with
+ * {@code border}. Either color can be 0 to skip that part.
+ */
+ default void drawRoundedRectangle(int x, int y, int width, int height, int radius, int thickness,
+ int background, int border) {
+ drawRoundedRectangle(x, y, width, height, radius, background);
+ drawRoundedBorder(x, y, width, height, radius, thickness, border);
+ }
+
+ /**
+ * Renders {@code shape} (SVG elements in a {@code width} x {@code height}
+ * canvas, drawn in white) to a cached texture and draws it tinted with
+ * {@code color}.
+ */
+ private void drawSvgShape(String shape, String cacheKey, int x, int y, int width, int height, int color) {
+ String svg = String.format(
+ "",
+ width, height, shape);
+
InputStream svgStream = new ByteArrayInputStream(svg.getBytes(StandardCharsets.UTF_8));
drawTexture(SvgTexture.getSvg(svgStream,
- IdentifierRef.ofSaturn(
- "textures/gui/tmp_rect/rounded_" + width + "_" + height + "_" + radius),
+ IdentifierRef.ofSaturn("textures/gui/tmp_rect/" + cacheKey),
width * 4, height * 4), x, y, 0, 0, width, height, color);
}