fix(bevel): Bisel inset +1px para no solapar borde exterior

- drawBeveledRect: bordes ahora en x+1,y+1 (interior del rect)
- drawBeveledRectPressed: mismo fix para estado presionado
- inner_w/inner_h calculados como w-2/h-2 para correcta insetación
- Fix identificado en verificación MASTER_RESCATE punto C

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
R.Eugenio 2025-12-31 13:48:54 +01:00
parent 326470ef92
commit 89c7508426
2 changed files with 43 additions and 32 deletions

View file

@ -46,6 +46,7 @@
| 2025-12-30 | v0.24.0 | ⭐ FilledCircle primitive: Midpoint Circle Algorithm (Bresenham) | | 2025-12-30 | v0.24.0 | ⭐ FilledCircle primitive: Midpoint Circle Algorithm (Bresenham) |
| 2025-12-30 | v0.25.0 | ⭐ IdleCompanion widget: mascota animada que aparece tras inactividad | | 2025-12-30 | v0.25.0 | ⭐ IdleCompanion widget: mascota animada que aparece tras inactividad |
| 2025-12-31 | v0.26.0 | ⭐ Z-Design V5 Pixel Perfect: títulos legibles (contrastTextColor), botones centrados (+2px TTF), semáforo reubicado (texto + cuadrado derecha) | | 2025-12-31 | v0.26.0 | ⭐ Z-Design V5 Pixel Perfect: títulos legibles (contrastTextColor), botones centrados (+2px TTF), semáforo reubicado (texto + cuadrado derecha) |
| 2025-12-31 | v0.26.1 | Fix: drawBeveledRect bisel ahora +1px inset (no solapa borde exterior) |
--- ---

View file

@ -466,6 +466,7 @@ pub const Context = struct {
/// Creates illusion of depth with light from top-left /// Creates illusion of depth with light from top-left
/// - Top/Left edges: lighter (raised) /// - Top/Left edges: lighter (raised)
/// - Bottom/Right edges: darker (shadow) /// - Bottom/Right edges: darker (shadow)
/// Note: Bevel is drawn INSIDE the rect (inset by 1px) to not overlap border
pub fn drawBeveledRect(self: *Self, x: i32, y: i32, w: u32, h: u32, base_color: Style.Color) void { pub fn drawBeveledRect(self: *Self, x: i32, y: i32, w: u32, h: u32, base_color: Style.Color) void {
const light = base_color.lightenHsl(10); const light = base_color.lightenHsl(10);
const dark = base_color.darkenHsl(15); const dark = base_color.darkenHsl(15);
@ -479,45 +480,50 @@ pub const Context = struct {
.color = base_color, .color = base_color,
} }); } });
// Top edge (light) // Bevel inset by 1px to stay inside border
const inner_w = if (w > 2) w - 2 else 1;
const inner_h = if (h > 2) h - 2 else 1;
// Top edge (light) - inset
self.pushCommand(.{ .rect = .{ self.pushCommand(.{ .rect = .{
.x = x, .x = x + 1,
.y = y, .y = y + 1,
.w = w, .w = inner_w,
.h = 1, .h = 1,
.color = light, .color = light,
} }); } });
// Left edge (light) // Left edge (light) - inset
self.pushCommand(.{ .rect = .{ self.pushCommand(.{ .rect = .{
.x = x, .x = x + 1,
.y = y, .y = y + 1,
.w = 1, .w = 1,
.h = h, .h = inner_h,
.color = light, .color = light,
} }); } });
// Bottom edge (dark) // Bottom edge (dark) - inset
self.pushCommand(.{ .rect = .{ self.pushCommand(.{ .rect = .{
.x = x, .x = x + 1,
.y = y + @as(i32, @intCast(h)) - 1, .y = y + @as(i32, @intCast(h)) - 2,
.w = w, .w = inner_w,
.h = 1, .h = 1,
.color = dark, .color = dark,
} }); } });
// Right edge (dark) // Right edge (dark) - inset
self.pushCommand(.{ .rect = .{ self.pushCommand(.{ .rect = .{
.x = x + @as(i32, @intCast(w)) - 1, .x = x + @as(i32, @intCast(w)) - 2,
.y = y, .y = y + 1,
.w = 1, .w = 1,
.h = h, .h = inner_h,
.color = dark, .color = dark,
} }); } });
} }
/// Draw a rectangle with inverted 3D bevel effect (pressed state) /// Draw a rectangle with inverted 3D bevel effect (pressed state)
/// Dark edges on top/left, light on bottom/right /// Dark edges on top/left, light on bottom/right
/// Note: Bevel is drawn INSIDE the rect (inset by 1px) to not overlap border
pub fn drawBeveledRectPressed(self: *Self, x: i32, y: i32, w: u32, h: u32, base_color: Style.Color) void { pub fn drawBeveledRectPressed(self: *Self, x: i32, y: i32, w: u32, h: u32, base_color: Style.Color) void {
const light = base_color.lightenHsl(10); const light = base_color.lightenHsl(10);
const dark = base_color.darkenHsl(15); const dark = base_color.darkenHsl(15);
@ -531,39 +537,43 @@ pub const Context = struct {
.color = base_color, .color = base_color,
} }); } });
// Top edge (dark - inverted) // Bevel inset by 1px to stay inside border
const inner_w = if (w > 2) w - 2 else 1;
const inner_h = if (h > 2) h - 2 else 1;
// Top edge (dark - inverted) - inset
self.pushCommand(.{ .rect = .{ self.pushCommand(.{ .rect = .{
.x = x, .x = x + 1,
.y = y, .y = y + 1,
.w = w, .w = inner_w,
.h = 1, .h = 1,
.color = dark, .color = dark,
} }); } });
// Left edge (dark - inverted) // Left edge (dark - inverted) - inset
self.pushCommand(.{ .rect = .{ self.pushCommand(.{ .rect = .{
.x = x, .x = x + 1,
.y = y, .y = y + 1,
.w = 1, .w = 1,
.h = h, .h = inner_h,
.color = dark, .color = dark,
} }); } });
// Bottom edge (light - inverted) // Bottom edge (light - inverted) - inset
self.pushCommand(.{ .rect = .{ self.pushCommand(.{ .rect = .{
.x = x, .x = x + 1,
.y = y + @as(i32, @intCast(h)) - 1, .y = y + @as(i32, @intCast(h)) - 2,
.w = w, .w = inner_w,
.h = 1, .h = 1,
.color = light, .color = light,
} }); } });
// Right edge (light - inverted) // Right edge (light - inverted) - inset
self.pushCommand(.{ .rect = .{ self.pushCommand(.{ .rect = .{
.x = x + @as(i32, @intCast(w)) - 1, .x = x + @as(i32, @intCast(w)) - 2,
.y = y, .y = y + 1,
.w = 1, .w = 1,
.h = h, .h = inner_h,
.color = light, .color = light,
} }); } });
} }