More box chars

This commit is contained in:
Kovid Goyal 2024-12-22 15:05:47 +05:30
parent 68167b9ddb
commit 7bd0b46a71
No known key found for this signature in database
GPG key ID: 06BC317B515ACE7C
2 changed files with 55 additions and 12 deletions

View file

@ -330,15 +330,26 @@ draw_vline(Canvas *self, uint y1, uint y2, uint x, uint level) {
}
}
static uint
half_width(Canvas *self) { // align with non-supersampled co-ords
return self->supersample_factor * (self->width / 2 / self->supersample_factor);
}
static uint
half_height(Canvas *self) { // align with non-supersampled co-ords
return self->supersample_factor * (self->height / 2 / self->supersample_factor);
}
static void
half_hline(Canvas *self, uint level, bool right_half, uint extend_by) {
uint x1, x2;
if (right_half) {
x1 = minus(self->width / 2u, extend_by); x2 = self->width;
x1 = minus(half_width(self), extend_by); x2 = self->width;
} else {
x1 = 0; x2 = self->width / 2 + extend_by;
x1 = 0; x2 = half_width(self) + extend_by;
}
draw_hline(self, x1, x2, self->height / 2, level);
draw_hline(self, x1, x2, half_height(self), level);
}
typedef union Point {
@ -388,11 +399,11 @@ static void
half_vline(Canvas *self, uint level, bool bottom_half, uint extend_by) {
uint y1, y2;
if (bottom_half) {
y1 = minus(self->height / 2u, extend_by); y2 = self->height;
y1 = minus(half_height(self), extend_by); y2 = self->height;
} else {
y1 = 0; y2 = self->height / 2 + extend_by;
y1 = 0; y2 = half_height(self) + extend_by;
}
draw_vline(self, y1, y2, self->width / 2, level);
draw_vline(self, y1, y2, half_width(self), level);
}
static void
@ -1144,8 +1155,7 @@ rectcircle(Canvas *self, Corner which) {
double radius = self->width / 2.;
uint cell_width_is_odd = (self->width / self->supersample_factor) & 1;
Rectircle ans = {
.a = ((self->width / self->supersample_factor) / 2) * self->supersample_factor,
.b = ((self->height / self->supersample_factor) / 2) * self->supersample_factor,
.a = half_width(self), .b = half_height(self),
.yexp = self->height / radius,
.xexp = radius / self->width,
.cell_width = self->width,
@ -1163,6 +1173,18 @@ rounded_corner(Canvas *self, uint level, Corner which) {
draw_parametrized_curve(self, level, r.x(r, t), r.y(r, t));
}
static void
commit(Canvas *self, Edge lines, bool solid) {
static const uint level = 1; static const double scale = 0.9;
uint hw = half_width(self), hh = half_height(self);
if (lines & RIGHT_EDGE) draw_hline(self, hw, self->width, hh, level);
if (lines & LEFT_EDGE) draw_hline(self, 0, hw, hh, level);
if (lines & TOP_EDGE) draw_vline(self, 0, hh, hw, level);
if (lines & BOTTOM_EDGE) draw_vline(self, hh, self->height, hw, level);
draw_circle(self, scale, 0, false);
if (!solid) draw_circle(self, scale, thickness(self, level, true), true);
}
void
render_box_char(char_type ch, uint8_t *buf, unsigned width, unsigned height, double dpi_x, double dpi_y) {
Canvas canvas = {.mask=buf, .width = width, .height = height, .dpi={.x=dpi_x, .y=dpi_y}, .supersample_factor=1u}, ss = canvas;
@ -1471,6 +1493,25 @@ render_box_char(char_type ch, uint8_t *buf, unsigned width, unsigned height, dou
SS(L'', vline(c, 1); rounded_corner(c, 1, TOP_RIGHT), rounded_corner(c, 1, BOTTOM_LEFT));
SS(L'', hline(c, 1); rounded_corner(c, 1, TOP_LEFT), rounded_corner(c, 1, BOTTOM_RIGHT));
SS(L'', hline(c, 1); rounded_corner(c, 1, TOP_RIGHT), rounded_corner(c, 1, BOTTOM_LEFT));
#define P(ch, lines) S(ch, commit, lines, true); S(ch+1, commit, lines, false);
P(L'', 0);
P(L'', RIGHT_EDGE);
P(L'', LEFT_EDGE);
P(L'', LEFT_EDGE | RIGHT_EDGE);
P(L'', BOTTOM_EDGE);
P(L'', TOP_EDGE);
P(L'', BOTTOM_EDGE | TOP_EDGE);
P(L'', RIGHT_EDGE | BOTTOM_EDGE);
P(L'', LEFT_EDGE | BOTTOM_EDGE);
P(L'', RIGHT_EDGE | TOP_EDGE);
P(L'', LEFT_EDGE | TOP_EDGE);
P(L'', TOP_EDGE | BOTTOM_EDGE | RIGHT_EDGE);
P(L'', TOP_EDGE | BOTTOM_EDGE | LEFT_EDGE);
P(L'', LEFT_EDGE | RIGHT_EDGE | BOTTOM_EDGE);
P(L'', LEFT_EDGE | RIGHT_EDGE | TOP_EDGE);
P(L'', LEFT_EDGE | RIGHT_EDGE | TOP_EDGE | BOTTOM_EDGE);
#undef P
}
free(canvas.holes); free(canvas.y_limits);
free(ss.holes); free(ss.y_limits);

View file

@ -54,13 +54,15 @@ def draw_vline(buf: BufType, width: int, y1: int, y2: int, x: int, level: int, s
def half_hline(buf: BufType, width: int, height: int, level: int = 1, which: str = 'left', extend_by: int = 0, ssf: int = 1) -> None:
x1, x2 = (0, extend_by + width // 2) if which == 'left' else (width // 2 - extend_by, width)
draw_hline(buf, width, height, x1, x2, height // 2, level, supersample_factor=ssf)
hw, hh = ssf * (width // 2 // ssf), ssf * (height // 2 // ssf)
x1, x2 = (0, extend_by + hw) if which == 'left' else (hw - extend_by, width)
draw_hline(buf, width, height, x1, x2, hh, level, supersample_factor=ssf)
def half_vline(buf: BufType, width: int, height: int, level: int = 1, which: str = 'top', extend_by: int = 0, ssf: int = 1) -> None:
y1, y2 = (0, height // 2 + extend_by) if which == 'top' else (height // 2 - extend_by, height)
draw_vline(buf, width, y1, y2, width // 2, level, supersample_factor=ssf)
hw, hh = ssf * (width // 2 // ssf), ssf * (height // 2 // ssf)
y1, y2 = (0, hh + extend_by) if which == 'top' else (hh - extend_by, height)
draw_vline(buf, width, y1, y2, hw, level, supersample_factor=ssf)
def get_holes(sz: int, hole_sz: int, num: int) -> list[tuple[int, ...]]: