popup: place and bound the input panel

This commit is contained in:
2026-08-14 20:00:36 +09:00
parent 7619d2bd9d
commit 193ed009bd
6 changed files with 97 additions and 10 deletions

40
font.c
View File

@@ -6,6 +6,13 @@ static PangoFontMap *fontmap;
static PangoContext *context;
static PangoLayout *layout;
static void
resetlayout(void)
{
pango_layout_set_width(layout, -1);
pango_layout_set_ellipsize(layout, PANGO_ELLIPSIZE_NONE);
}
static void
textclear(void)
{
@@ -100,20 +107,32 @@ textwidth(Str *s)
{
PangoRectangle r;
if(layout == nil)
return 0;
resetlayout();
if(!settext(s))
return 0;
textextents(&r);
return r.width;
}
void
textdraw(u32int *buf, int w, int h, int x, int y, Str *s)
static void
drawtext(u32int *buf, int w, int h, int x, int y, int fit, Str *s)
{
PangoRectangle r;
cairo_surface_t *surface;
cairo_t *cr;
int stride;
if(layout == nil)
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))
return;
stride = cairo_format_stride_for_width(CAIRO_FORMAT_RGB24, w);
@@ -131,7 +150,10 @@ textdraw(u32int *buf, int w, int h, int x, int y, Str *s)
pango_cairo_update_layout(cr, layout);
textextents(&r);
/* A fallback face must not paint into another popup row. */
cairo_rectangle(cr, 0, y, w, Fontsz);
if(fit > 0)
cairo_rectangle(cr, x, y, fit, Fontsz);
else
cairo_rectangle(cr, 0, y, w, Fontsz);
cairo_clip(cr);
cairo_move_to(cr, x - r.x, y + (Fontsz - r.height) / 2 - r.y);
cairo_set_source_rgb(cr, 0, 0, 0);
@@ -141,3 +163,15 @@ textdraw(u32int *buf, int w, int h, int x, int y, Str *s)
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, s);
}
void
textdrawfit(u32int *buf, int w, int h, int x, int y, int fit, Str *s)
{
drawtext(buf, w, h, x, y, fit, s);
}