Scale multicell box char line thickness

This commit is contained in:
Kovid Goyal 2024-12-25 09:28:53 +05:30
parent c67475271f
commit 4a845f840d
No known key found for this signature in database
GPG key ID: 06BC317B515ACE7C
4 changed files with 11 additions and 10 deletions

View file

@ -229,6 +229,7 @@ typedef struct Canvas {
uint8_t *mask;
uint width, height, supersample_factor;
struct { double x, y; } dpi;
double scale; // used to scale line thickness with font size for multicell rendering
Range *holes; uint holes_count, holes_capacity;
Limit *y_limits; uint y_limits_count, y_limits_capacity;
} Canvas;
@ -255,7 +256,7 @@ thickness(Canvas *self, uint level, bool horizontal) {
level = min(level, arraysz(OPT(box_drawing_scale)));
double pts = OPT(box_drawing_scale)[level];
double dpi = horizontal ? self->dpi.x : self->dpi.y;
return self->supersample_factor * (uint)ceil(pts * dpi / 72.0);
return (uint)ceil(self->supersample_factor * self->scale * pts * dpi / 72.0);
}
static uint
@ -1338,8 +1339,8 @@ sextant(Canvas *self, uint which) {
}
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;
render_box_char(char_type ch, uint8_t *buf, unsigned width, unsigned height, double dpi_x, double dpi_y, double scale) {
Canvas canvas = {.mask=buf, .width = width, .height = height, .dpi={.x=dpi_x, .y=dpi_y}, .supersample_factor=1u, .scale=scale}, ss = canvas;
ss.mask = buf + width*height; ss.supersample_factor = SUPERSAMPLE_FACTOR; ss.width *= SUPERSAMPLE_FACTOR; ss.height *= SUPERSAMPLE_FACTOR;
fill_canvas(&canvas, 0);
Canvas *c = &canvas;

View file

@ -23,5 +23,5 @@ DecorationGeometry add_missing_glyph(uint8_t *buf, FontCellMetrics fcm);
DecorationGeometry add_beam_cursor(uint8_t *buf, FontCellMetrics fcm, double dpi_x);
DecorationGeometry add_underline_cursor(uint8_t *buf, FontCellMetrics fcm, double dpi_y);
DecorationGeometry add_hollow_cursor(uint8_t *buf, FontCellMetrics fcm, double dpi_x, double dpi_y);
void render_box_char(char_type ch, uint8_t *buf, unsigned width, unsigned height, double dpi_x, double dpi_y);
void render_box_char(char_type ch, uint8_t *buf, unsigned width, unsigned height, double dpi_x, double dpi_y, double scale);
#define SUPERSAMPLE_FACTOR 4u

View file

@ -1713,7 +1713,7 @@ def glfw_get_system_color_theme(query_if_unintialized: bool = True) -> Literal['
def set_redirect_keys_to_overlay(os_window_id: int, tab_id: int, window_id: int, overlay_window_id: int) -> None: ...
def buffer_keys_in_window(os_window_id: int, tab_id: int, window_id: int, enabled: bool = True) -> bool: ...
def sprite_idx_to_pos(idx: int, xnum: int, ynum: int) -> tuple[int, int, int]: ...
def render_box_char(ch: int, width: int, height: int, dpi_x: float = 96.0, dpi_y: float = 96.0) -> bytes: ...
def render_box_char(ch: int, width: int, height: int, scale: float = 1.0, dpi_x: float = 96.0, dpi_y: float = 96.0) -> bytes: ...
class MousePosition(TypedDict):
cell_x: int

View file

@ -1041,7 +1041,7 @@ render_box_cell(FontGroup *fg, RunFont rf, CPUCell *cpu_cell, GPUCell *gpu_cell,
uint8_t *alpha_mask = NULL;
ensure_canvas_can_fit(fg, num_glyphs + 1, rf.scale);
if (num_glyphs == 1) {
render_box_char(ch, fg->canvas.alpha_mask, width, height, fg->logical_dpi_x, fg->logical_dpi_y);
render_box_char(ch, fg->canvas.alpha_mask, width, height, fg->logical_dpi_x, fg->logical_dpi_y, scale);
alpha_mask = fg->canvas.alpha_mask;
} else {
alpha_mask = ((uint8_t*)fg->canvas.buf) + fg->canvas.size_in_bytes - (num_glyphs * width * height);
@ -1049,7 +1049,7 @@ render_box_cell(FontGroup *fg, RunFont rf, CPUCell *cpu_cell, GPUCell *gpu_cell,
for (unsigned i = 0; i < num_glyphs; i++) {
unsigned int ch = global_glyph_render_scratch.lc->chars[cnum++];
while (!ch) ch = global_glyph_render_scratch.lc->chars[cnum++];
render_box_char(ch, fg->canvas.alpha_mask, width, height, fg->logical_dpi_x, fg->logical_dpi_y);
render_box_char(ch, fg->canvas.alpha_mask, width, height, fg->logical_dpi_x, fg->logical_dpi_y, scale);
uint8_t *src = fg->canvas.alpha_mask;
for (unsigned y = 0; y < height; y++) {
uint8_t *dest_row = alpha_mask + y*num_glyphs*width + i*width;
@ -2303,11 +2303,11 @@ sprite_idx_to_pos(PyObject *self UNUSED, PyObject *args) {
static PyObject*
pyrender_box_char(PyObject *self UNUSED, PyObject *args) {
unsigned int ch;
unsigned long width, height; double dpi_x = 96., dpi_y = 96.;
if (!PyArg_ParseTuple(args, "Ikk|dd", &ch, &width, &height, &dpi_x, &dpi_y)) return NULL;
unsigned long width, height; double dpi_x = 96., dpi_y = 96., scale = 1.;
if (!PyArg_ParseTuple(args, "Ikk|ddd", &ch, &width, &height, &scale, &dpi_x, &dpi_y)) return NULL;
RAII_PyObject(ans, PyBytes_FromStringAndSize(NULL, width*16 * height*16));
if (!ans) return NULL;
render_box_char(ch, (uint8_t*)PyBytes_AS_STRING(ans), width, height, dpi_x, dpi_y);
render_box_char(ch, (uint8_t*)PyBytes_AS_STRING(ans), width, height, dpi_x, dpi_y, scale);
if (_PyBytes_Resize(&ans, width * height) != 0) return NULL;
return Py_NewRef(ans);
}