Add rounded borders to RenderScope
drawRoundedBorder draws an outline inset into the given bounds so it lines up with a rounded rectangle of the same size and radius, and a new drawRoundedRectangle overload draws both with separate background and border colors. Both shapes share one SVG-to-texture helper. Co-Authored-By: Claude Opus 5.5 <[email protected]>
This commit is contained in:
@@ -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(
|
||||
"<svg xmlns='http://www.w3.org/2000/svg' width='%d' height='%d'>" +
|
||||
"<rect width='%d' height='%d' rx='%d' ry='%d' fill='white'/>" +
|
||||
"</svg>",
|
||||
width, height,
|
||||
String rect = String.format(
|
||||
"<rect width='%d' height='%d' rx='%d' ry='%d' fill='white'/>",
|
||||
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,
|
||||
"<rect x='%.1f' y='%.1f' width='%.1f' height='%.1f' rx='%.1f' ry='%.1f' " +
|
||||
"fill='none' stroke='white' stroke-width='%d'/>",
|
||||
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(
|
||||
"<svg xmlns='http://www.w3.org/2000/svg' width='%d' height='%d'>%s</svg>",
|
||||
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);
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user