popup: one text drawing call; drop what the draw thread never reaches

font.c exported three wrappers for one function, and the fit == -1 mode
existed only for the tests; textdraw() takes fit and colour. win.c
tested the empty picture in the thread and again in winshow, interned
two atoms by hand next to getatom(), kept a consumer-side drain that the
producer's already guarantees never finds anything, zeroed ten globals
before returning from the only thread that read them, and re-checked
sizes that resizebacking had just established. The page marker is laid
out once and drawn from the layout instead of being recomputed.
This commit is contained in:
2026-08-16 16:22:37 +09:00
parent eaf31da0d1
commit 849bf1278b
7 changed files with 91 additions and 169 deletions

46
font.c
View File

@@ -116,8 +116,13 @@ textwidth(Str *s)
return r.width;
}
static void
drawtext(u32int *buf, int w, int h, int x, int y, int fit, u32int color,
/*
* Draws s at (x, y) into the w-by-h buffer, ellipsized to fit pixels and
* clipped to its own row so a tall fallback face cannot paint a
* neighbour.
*/
void
textdraw(u32int *buf, int w, int h, int x, int y, int fit, u32int color,
Str *s)
{
PangoRectangle r;
@@ -125,16 +130,12 @@ drawtext(u32int *buf, int w, int h, int x, int y, int fit, u32int color,
cairo_t *cr;
int b, g, red, stride;
if(layout == nil)
if(layout == nil || fit <= 0)
return;
resetlayout();
if(fit != -1 && fit <= 0)
return;
if(fit > 0){
pango_layout_set_width(layout, fit * PANGO_SCALE);
pango_layout_set_ellipsize(layout, PANGO_ELLIPSIZE_END);
}
if(buf == nil || w <= 0 || h <= 0 || !settext(s))
pango_layout_set_width(layout, fit * PANGO_SCALE);
pango_layout_set_ellipsize(layout, PANGO_ELLIPSIZE_END);
if(w <= 0 || h <= 0 || !settext(s))
return;
stride = cairo_format_stride_for_width(CAIRO_FORMAT_RGB24, w);
if(stride < 0 || (vlong)stride != (vlong)w * sizeof buf[0])
@@ -150,11 +151,7 @@ drawtext(u32int *buf, int w, int h, int x, int y, int fit, u32int color,
if(cairo_status(cr) == CAIRO_STATUS_SUCCESS){
pango_cairo_update_layout(cr, layout);
textextents(&r);
/* A fallback face must not paint into another popup row. */
if(fit > 0)
cairo_rectangle(cr, x, y, fit, Fontsz);
else
cairo_rectangle(cr, 0, y, w, Fontsz);
cairo_rectangle(cr, x, y, fit, Fontsz);
cairo_clip(cr);
cairo_move_to(cr, x - r.x, y + (Fontsz - r.height) / 2 - r.y);
red = color >> 16 & 0xff;
@@ -167,22 +164,3 @@ drawtext(u32int *buf, int w, int h, int x, int y, int fit, u32int color,
cairo_surface_flush(surface);
cairo_surface_destroy(surface);
}
void
textdraw(u32int *buf, int w, int h, int x, int y, Str *s)
{
drawtext(buf, w, h, x, y, -1, Colfg, s);
}
void
textdrawfit(u32int *buf, int w, int h, int x, int y, int fit, Str *s)
{
drawtext(buf, w, h, x, y, fit, Colfg, s);
}
void
textdrawfitcolor(u32int *buf, int w, int h, int x, int y, int fit,
u32int color, Str *s)
{
drawtext(buf, w, h, x, y, fit, color, s);
}