Simplify bigclock digit outline drawing

Use a neighbor direction table and for-loops like the rest of the
UI code, and drop the extra comments.
This commit is contained in:
jR4dh3y 2026-07-11 08:33:57 +05:30
commit 0dccd3e1cc
3 changed files with 40 additions and 63 deletions

View file

@ -19,6 +19,12 @@ pub const CHAR_SIZE = CHAR_WIDTH * CHAR_HEIGHT;
pub const X: u32 = if (ly_core.interop.supportsUnicode()) 0x2593 else '#';
pub const O: u32 = 0;
const OUTLINE_DIRS = [_][2]i8{
.{ -1, -1 }, .{ -1, 0 }, .{ -1, 1 },
.{ 0, -1 }, .{ 0, 1 }, .{ 1, -1 },
.{ 1, 0 }, .{ 1, 1 },
};
// zig fmt: off
pub const LocaleChars = struct {
ZERO: [CHAR_SIZE]u21,
@ -51,7 +57,6 @@ text: []const u8,
max_width: ?usize,
fg: u32,
bg: u32,
/// When set, draw a 1-cell outline around each digit glyph.
outline_fg: ?u32 = null,
locale: BigLabelLocale,
update_fn: ?*const fn (*BigLabel, *anyopaque) anyerror!void,
@ -155,40 +160,23 @@ pub fn childrenPosition(self: BigLabel) Position {
}
fn draw(self: *BigLabel) void {
if (self.text.len == 0) return;
// Optional outline under the glyphs (bigclock_outline_fg).
if (self.outline_fg) |outline_fg| {
for (self.text, 0..) |c, i| {
drawDigitOutline(
self,
c,
self.component_pos.x + i * (CHAR_WIDTH + 1),
self.component_pos.y,
outline_fg,
);
}
}
for (self.text, 0..) |c, i| {
const clock_cell = clockCell(
c,
self.fg,
self.bg,
self.locale,
);
const x = self.component_pos.x + i * (CHAR_WIDTH + 1);
const y = self.component_pos.y;
if (self.outline_fg) |outline_fg|
drawDigitOutline(self, c, x, y, outline_fg);
alphaBlit(
self.component_pos.x + i * (CHAR_WIDTH + 1),
self.component_pos.y,
x,
y,
self.buffer.width,
self.buffer.height,
clock_cell,
clockCell(c, self.fg, self.bg, self.locale),
);
}
}
/// 1-cell outline around each solid cell of a big-clock digit.
fn drawDigitOutline(
self: *BigLabel,
char: u8,
@ -199,42 +187,34 @@ fn drawDigitOutline(
const pattern = toBigNumber(char, self.locale);
const stroke = Cell.init(X, outline_fg, 0x00000000);
var yy: usize = 0;
while (yy < CHAR_HEIGHT) : (yy += 1) {
var xx: usize = 0;
while (xx < CHAR_WIDTH) : (xx += 1) {
for (0..CHAR_HEIGHT) |yy| {
for (0..CHAR_WIDTH) |xx| {
if (pattern[yy * CHAR_WIDTH + xx] == O) continue;
// 8-neighbor outline. Use i8 (not i2) — i2 overflows past 1.
var dy: i8 = -1;
while (dy <= 1) : (dy += 1) {
var dx: i8 = -1;
while (dx <= 1) : (dx += 1) {
if (dx == 0 and dy == 0) continue;
const nx: i32 = @as(i32, @intCast(xx)) + dx;
const ny: i32 = @as(i32, @intCast(yy)) + dy;
if (nx < -1 or ny < -1) continue;
if (nx > CHAR_WIDTH or ny > CHAR_HEIGHT) continue;
for (OUTLINE_DIRS) |dir| {
const nx = @as(i32, @intCast(xx)) + dir[0];
const ny = @as(i32, @intCast(yy)) + dir[1];
if (nx >= 0 and ny >= 0 and
nx < CHAR_WIDTH and ny < CHAR_HEIGHT and
pattern[
@as(usize, @intCast(ny)) * CHAR_WIDTH +
@as(usize, @intCast(nx))
] != O)
{
continue;
}
const sx: i32 = @as(i32, @intCast(base_x)) + nx;
const sy: i32 = @as(i32, @intCast(base_y)) + ny;
if (sx < 0 or sy < 0) continue;
const ux: usize = @intCast(sx);
const uy: usize = @intCast(sy);
if (ux >= self.buffer.width or uy >= self.buffer.height)
continue;
stroke.put(ux, uy) catch {};
if (nx >= 0 and ny >= 0 and
nx < CHAR_WIDTH and ny < CHAR_HEIGHT and
pattern[
@as(usize, @intCast(ny)) * CHAR_WIDTH +
@as(usize, @intCast(nx))
] != O)
{
continue;
}
const sx = @as(i32, @intCast(base_x)) + nx;
const sy = @as(i32, @intCast(base_y)) + ny;
if (sx < 0 or sy < 0) continue;
const ux: usize = @intCast(sx);
const uy: usize = @intCast(sy);
if (ux >= self.buffer.width or uy >= self.buffer.height)
continue;
stroke.put(ux, uy) catch {};
}
}
}

View file

@ -92,9 +92,7 @@ bigclock_12hr = false
# Set bigclock to show the seconds.
bigclock_seconds = false
# Optional 1-cell outline around each big-clock digit (null = none).
# Useful over busy animations so the glyphs stay readable.
# Example black: 0x20000000 (TB_HI_BLACK)
# Bigclock digit outline color (null = none)
bigclock_outline_fg = null
# Blank main box background

View file

@ -2256,7 +2256,6 @@ fn positionWidgets(ptr: *anyopaque) !void {
const clock_text_len = TerminalBuffer.strWidth(state.bigclock_label.text) * (BigLabel.CHAR_WIDTH + 1);
if (state.config.bigclock != .none) {
// Extra row when outline is on: stroke can extend 1 cell below glyphs.
const gap: usize = if (state.config.bigclock_outline_fg != null) 3 else 2;
bb_height += BigLabel.CHAR_HEIGHT + gap;
bb_width = @max(bb_width, clock_text_len);