diff --git a/dat.h b/dat.h index e267ba3..90efd23 100644 --- a/dat.h +++ b/dat.h @@ -44,7 +44,6 @@ extern int popupscale; #define PopupNumw Fontsz #define PopupTextw (12*Fontsz) #define PopupBasew (2*PopupPad + PopupNumw + PopupTextw) -#define Imgh (2*PopupPad + (Maxdisp + 2)*Fontsz + PopupSep) typedef struct Str Str; struct Str diff --git a/fn.h b/fn.h index f49d523..84cd3c3 100644 --- a/fn.h +++ b/fn.h @@ -48,7 +48,7 @@ int keymeaningful(u32int); void* emalloc(ulong); void* erealloc(void*, ulong); -int textinit(void); +void textinit(void); void textclose(void); int textwidth(Str*); void textdraw(u32int*, int, int, int, int, int, u32int, Str*); diff --git a/font.c b/font.c index 00a1b04..c3486f5 100644 --- a/font.c +++ b/font.c @@ -7,13 +7,6 @@ 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); -} - void textclose(void) { @@ -50,28 +43,16 @@ setfont(void) pango_font_description_free(font); } -int +void textinit(void) { - textclose(); FcInit(); fontmap = pango_cairo_font_map_new(); - if(fontmap == nil){ - fprint(2, "strans: popup: can't initialize PangoCairo\n"); - return 0; - } pango_cairo_font_map_set_resolution(PANGO_CAIRO_FONT_MAP(fontmap), 96); context = pango_font_map_create_context(fontmap); - if(context != nil) - layout = pango_layout_new(context); - if(context == nil || layout == nil){ - fprint(2, "strans: popup: can't create text layout\n"); - textclose(); - return 0; - } + layout = pango_layout_new(context); pango_layout_set_single_paragraph_mode(layout, TRUE); setfont(); - return 1; } static int @@ -80,8 +61,6 @@ settext(Str *s) char utf[Maxutf]; int n; - if(layout == nil || s == nil || s->n <= 0) - return 0; n = stoutf(s, utf, sizeof utf); pango_layout_set_text(layout, utf, n); return n > 0; @@ -109,9 +88,8 @@ textwidth(Str *s) { PangoRectangle r; - if(layout == nil) - return 0; - resetlayout(); + pango_layout_set_width(layout, -1); + pango_layout_set_ellipsize(layout, PANGO_ELLIPSIZE_NONE); if(!settext(s)) return 0; textextents(&r); @@ -130,20 +108,16 @@ textdraw(u32int *buf, int w, int h, int x, int y, int fit, u32int color, PangoRectangle r; cairo_surface_t *surface; cairo_t *cr; - int b, g, red, stride; + int b, g, red; - if(layout == nil || fit <= 0) + if(fit <= 0) return; - resetlayout(); 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]) - return; surface = cairo_image_surface_create_for_data((uchar*)buf, - CAIRO_FORMAT_RGB24, w, h, stride); + CAIRO_FORMAT_RGB24, w, h, w * sizeof buf[0]); if(cairo_surface_status(surface) != CAIRO_STATUS_SUCCESS){ cairo_surface_destroy(surface); return; diff --git a/popup_layout.c b/popup_layout.c index c349dfa..ad187a6 100644 --- a/popup_layout.c +++ b/popup_layout.c @@ -119,7 +119,7 @@ void popuplayout(Drawcmd *dc, int areaw, int areah, Popup *p) { char buf[32]; - int first, i, markrow, nall, nmark, npre, pad, total, width, y; + int first, i, markrow, nall, nmark, npre, total, width, y; memset(p, 0, sizeof *p); p->prey = -1; @@ -127,14 +127,12 @@ popuplayout(Drawcmd *dc, int areaw, int areah, Popup *p) p->rowsy = -1; p->marky = -1; p->sely = -1; - pad = PopupPad; nall = min(max(dc->nkouho, 0), Maxdisp); npre = dc->pre.n != 0; if((nall == 0 && !npre) || areaw <= 0 || areah <= 0) return; - /* Rows first; a page marker when they do not all fit; and in a - * sliver of a work area the selected row alone, unpadded. */ + /* As many rows as fit, and a page marker when they do not all. */ total = max(dc->total, dc->first + nall); markrow = dc->first > 0 || nall < total; p->n = fitrows(areah, npre, markrow, nall); @@ -142,15 +140,8 @@ popuplayout(Drawcmd *dc, int areaw, int areah, Popup *p) markrow = 1; p->n = fitrows(areah, npre, markrow, nall); } - if(p->n == 0 && markrow){ - markrow = 0; - p->n = fitrows(areah, npre, markrow, nall); - } - if(p->n == 0 && nall != 0){ - npre = 0; - pad = 0; - p->n = max(min(nall, areah / Fontsz), 1); - } + if(p->n == 0 && !npre) + return; if(p->n != 0 && dc->sel >= p->n) p->row0 = min(dc->sel - p->n + 1, nall - p->n); first = dc->first + p->row0; @@ -171,7 +162,7 @@ popuplayout(Drawcmd *dc, int areaw, int areah, Popup *p) } p->w = min(width, areaw); - y = pad; + y = PopupPad; if(npre){ p->prey = y; y += Fontsz; @@ -188,7 +179,7 @@ popuplayout(Drawcmd *dc, int areaw, int areah, Popup *p) p->marky = y; y += Fontsz; } - p->h = min(y + pad, areah); + p->h = min(y + PopupPad, areah); p->textw = max(p->w - 2*PopupPad - PopupNumw, 0); if(markrow){ p->markw = min(p->markw, max(p->w - 2*PopupPad, 0)); @@ -206,10 +197,6 @@ popupdraw(u32int *img, Drawcmd *dc, Popup *p) u32int color; int i, j, y; - if(img == nil || p->n < 0 || p->n > Maxdisp || - p->row0 < 0 || p->row0 + p->n > dc->nkouho || - p->w <= 0 || p->h <= 0 || p->h > Imgh) - return; fill(img, p->w*p->h, Colbg); if(p->prey >= 0) textdraw(img, p->w, p->h, PopupPad, p->prey, diff --git a/tests/font_test.c b/tests/font_test.c index aaab744..8ca443f 100644 --- a/tests/font_test.c +++ b/tests/font_test.c @@ -189,10 +189,7 @@ font_render(struct ct *t) buf = mem + Guard; fillpixels(buf, Testn, Colbg); a = mkstr("A"); - if(!CT_CHECK(t, textinit())){ - free(mem); - return; - } + textinit(); for(i = 0; i < nelem(plain); i++) checktext(t, buf, plain[i]); @@ -257,6 +254,4 @@ font_render(struct ct *t) checkguards(t, mem); free(mem); textclose(); - textclose(); - CT_EQ_INT(t, 0, textwidth(&a)); } diff --git a/tests/popup_test.c b/tests/popup_test.c index b83b27a..3a7d2fb 100644 --- a/tests/popup_test.c +++ b/tests/popup_test.c @@ -2,6 +2,9 @@ #include "fn.h" #include "test.h" +/* A popup with every section, tall enough for the tests. */ +#define Imgh (2*PopupPad + (Maxdisp + 2)*Fontsz + PopupSep) + enum { Rgbmask = 0xffffff, }; @@ -40,9 +43,6 @@ checkpadding(struct ct *t, u32int *img, Popup *p) void popup_layout(struct ct *t) { - int tinyheight[] = { - 1, PopupPad, 2*PopupPad + Fontsz - 1, - }; static const struct { int first; int shown; @@ -132,8 +132,7 @@ popup_layout(struct ct *t) CT_EQ_INT(t, 100, x); CT_EQ_INT(t, 200, y); - if(!CT_CHECK(t, textinit())) - return; + textinit(); /* Empty sections reserve nothing. */ memset(&dc, 0, sizeof dc); @@ -320,24 +319,5 @@ popup_layout(struct ct *t) CT_CHECK(t, numink > 0); /* full-width 9 */ CT_CHECK(t, markink > 0); /* 9-9/9 */ - /* The selected row wins over preedit and footer in one-row height. */ - dc.pre = mkstr("preedit"); - popuplayout(&dc, PopupBasew, 2*PopupPad + Fontsz, &p); - CT_EQ_INT(t, -1, p.prey); - CT_EQ_INT(t, 1, p.n); - CT_EQ_INT(t, Maxdisp - 1, p.row0); - CT_EQ_INT(t, -1, p.marky); - - /* With less than one padded row, selected content starts at the top. */ - for(i = 0; i < nelem(tinyheight); i++){ - popuplayout(&dc, PopupBasew, tinyheight[i], &p); - CT_EQ_INT(t, min(tinyheight[i], Fontsz), p.h); - CT_EQ_INT(t, 0, p.rowsy); - CT_EQ_INT(t, 0, p.sely); - CT_EQ_INT(t, 1, p.n); - CT_EQ_INT(t, Maxdisp - 1, p.row0); - popupdraw(img, &dc, &p); - CT_EQ_UINT(t, Colsel, pixel(img, &p, p.w - PopupPad - 1, 0)); - } free(img); } diff --git a/win.c b/win.c index 6e16c81..4a52ebb 100644 --- a/win.c +++ b/win.c @@ -250,11 +250,7 @@ wininit(void) win, type, XCB_ATOM_ATOM, 32, 1, &tooltip); gc = xcb_generate_id(conn); xcb_create_gc(conn, gc, win, 0, nil); - if(!textinit()){ - fprint(2, "strans: popup disabled: no usable fonts\n"); - wincleanup(); - return 0; - } + textinit(); return 1; }