| 238 |
238 |
|
int |
| 239 |
239 |
|
drw_text(Drw *drw, int x, int y, unsigned int w, unsigned int h, unsigned int lpad, const char *text, int invert) |
| 240 |
240 |
|
{ |
| 241 |
|
- |
int i, ty, ellipsis_x = 0; |
| 242 |
|
- |
unsigned int tmpw, ew, ellipsis_w = 0, ellipsis_len; |
|
241 |
+ |
int ty, ellipsis_x = 0; |
|
242 |
+ |
unsigned int tmpw, ew, ellipsis_w = 0, ellipsis_len, hash, h0, h1; |
| 243 |
243 |
|
XftDraw *d = NULL; |
| 244 |
244 |
|
Fnt *usedfont, *curfont, *nextfont; |
| 245 |
245 |
|
int utf8strlen, utf8charlen, render = x || y || w || h; |
|
| 251 |
251 |
|
XftResult result; |
| 252 |
252 |
|
int charexists = 0, overflow = 0; |
| 253 |
253 |
|
/* keep track of a couple codepoints for which we have no match. */ |
| 254 |
|
- |
enum { nomatches_len = 64 }; |
| 255 |
|
- |
static struct { long codepoint[nomatches_len]; unsigned int idx; } nomatches; |
| 256 |
|
- |
static unsigned int ellipsis_width = 0; |
|
254 |
+ |
static unsigned int nomatches[128], ellipsis_width; |
| 257 |
255 |
|
|
| 258 |
256 |
|
if (!drw || (render && (!drw->scheme || !w)) || !text || !drw->fonts) |
| 259 |
257 |
|
return 0; |
|
| 338 |
336 |
|
* character must be drawn. */ |
| 339 |
337 |
|
charexists = 1; |
| 340 |
338 |
|
|
| 341 |
|
- |
for (i = 0; i < nomatches_len; ++i) { |
| 342 |
|
- |
/* avoid calling XftFontMatch if we know we won't find a match */ |
| 343 |
|
- |
if (utf8codepoint == nomatches.codepoint[i]) |
| 344 |
|
- |
goto no_match; |
| 345 |
|
- |
} |
|
339 |
+ |
hash = (unsigned int)utf8codepoint; |
|
340 |
+ |
hash = ((hash >> 16) ^ hash) * 0x21F0AAAD; |
|
341 |
+ |
hash = ((hash >> 15) ^ hash) * 0xD35A2D97; |
|
342 |
+ |
h0 = ((hash >> 15) ^ hash) % LENGTH(nomatches); |
|
343 |
+ |
h1 = (hash >> 17) % LENGTH(nomatches); |
|
344 |
+ |
/* avoid expensive XftFontMatch call when we know we won't find a match */ |
|
345 |
+ |
if (nomatches[h0] == utf8codepoint || nomatches[h1] == utf8codepoint) |
|
346 |
+ |
goto no_match; |
| 346 |
347 |
|
|
| 347 |
348 |
|
fccharset = FcCharSetCreate(); |
| 348 |
349 |
|
FcCharSetAddChar(fccharset, utf8codepoint); |
|
| 371 |
372 |
|
curfont->next = usedfont; |
| 372 |
373 |
|
} else { |
| 373 |
374 |
|
xfont_free(usedfont); |
| 374 |
|
- |
nomatches.codepoint[++nomatches.idx % nomatches_len] = utf8codepoint; |
|
375 |
+ |
nomatches[nomatches[h0] ? h1 : h0] = utf8codepoint; |
| 375 |
376 |
|
no_match: |
| 376 |
377 |
|
usedfont = drw->fonts; |
| 377 |
378 |
|
} |