… | |
… | |
1342 | |
1342 | |
1343 | rxvt_compose_expand_static<FcChar32> exp; |
1343 | rxvt_compose_expand_static<FcChar32> exp; |
1344 | FcChar32 *chrs = exp (unicode); |
1344 | FcChar32 *chrs = exp (unicode); |
1345 | int nchrs = exp.length (chrs); |
1345 | int nchrs = exp.length (chrs); |
1346 | |
1346 | |
1347 | // we handle the sequence if the first char is available |
1347 | // allm chars in sequence must be available |
|
|
1348 | for (int i = 0; i < nchrs; ++i) |
1348 | if (!XftCharExists (term->dpy, f, chrs [0])) |
1349 | if (!XftCharExists (term->dpy, f, chrs [i])) |
1349 | return false; |
1350 | return false; |
1350 | |
1351 | |
1351 | if (!prop || prop->width == rxvt_fontprop::unset) |
1352 | if (!prop || prop->width == rxvt_fontprop::unset) |
1352 | return true; |
1353 | return true; |
1353 | |
1354 | |
1354 | // but we check against the whoile sequence bounding box |
|
|
1355 | |
|
|
1356 | // check character against base font bounding box |
|
|
1357 | FcChar32 ch = unicode; |
|
|
1358 | XGlyphInfo g; |
|
|
1359 | XftTextExtents32 (term->dpy, f, chrs, nchrs, &g); |
|
|
1360 | |
|
|
1361 | int w = g.width - g.x; |
|
|
1362 | int wcw = max (WCWIDTH (chrs [0]), 1); |
1355 | int wcw = max (WCWIDTH (chrs [0]), 1); |
1363 | |
1356 | |
|
|
1357 | // we check against all glyph sizes. this is probably wrong, |
|
|
1358 | // due to the way ->draw positions these glyphs. |
|
|
1359 | for (int i = 0; i < nchrs; ++i) |
|
|
1360 | { |
|
|
1361 | XGlyphInfo g; |
|
|
1362 | XftTextExtents32 (term->dpy, f, chrs + i, 1, &g); |
|
|
1363 | |
|
|
1364 | int w = g.width - g.x; |
|
|
1365 | |
1364 | careful = g.x > 0 || w > prop->width * wcw; |
1366 | careful = g.x > 0 || w > prop->width * wcw; |
1365 | |
1367 | |
1366 | if (careful && !OVERLAP_OK (w, wcw, prop)) |
1368 | if (careful && !OVERLAP_OK (w, wcw, prop)) |
1367 | return false; |
1369 | return false; |
1368 | |
1370 | |
1369 | // this weeds out _totally_ broken fonts, or glyphs |
1371 | // this weeds out _totally_ broken fonts, or glyphs |
1370 | if (!OVERLAP_OK (g.xOff, wcw, prop)) |
1372 | if (!OVERLAP_OK (g.xOff, wcw, prop)) |
1371 | return false; |
1373 | return false; |
|
|
1374 | } |
1372 | |
1375 | |
1373 | return true; |
1376 | return true; |
1374 | } |
1377 | } |
1375 | |
1378 | |
1376 | void |
1379 | void |
1377 | rxvt_font_xft::draw (rxvt_drawable &d, int x, int y, |
1380 | rxvt_font_xft::draw (rxvt_drawable &d, int x, int y, |
1378 | const text_t *text, int len, |
1381 | const text_t *text, int len, |
1379 | int fg, int bg) |
1382 | int fg, int bg) |
1380 | { |
1383 | { |
1381 | XGlyphInfo extents; |
|
|
1382 | //XftGlyphSpec *enc = rxvt_temp_buf<XftGlyphSpec> (len);//D |
1384 | //XftGlyphSpec *enc = rxvt_temp_buf<XftGlyphSpec> (len);//D |
1383 | //XftGlyphSpec *ep = enc;//D |
1385 | //XftGlyphSpec *ep = enc;//D |
1384 | static vector<XftGlyphSpec> enc; enc.resize (0); // static to avoid malloc, still slow |
1386 | static vector<XftGlyphSpec> enc; enc.resize (0); // static to avoid malloc, still slow |
1385 | |
1387 | |
1386 | dTermDisplay; |
1388 | dTermDisplay; |
… | |
… | |
1410 | while (len && *text == NOCHAR) |
1412 | while (len && *text == NOCHAR) |
1411 | text++, len--, cwidth += term->fwidth; |
1413 | text++, len--, cwidth += term->fwidth; |
1412 | |
1414 | |
1413 | if (chrs [0] != ' ') // skip spaces |
1415 | if (chrs [0] != ' ') // skip spaces |
1414 | { |
1416 | { |
1415 | FT_UInt glyphs [rxvt_compose_expand_static<FcChar32>::max_size]; |
1417 | #if 1 |
|
|
1418 | FT_UInt glyphs [decltype (exp)::max_size]; |
1416 | |
1419 | |
1417 | for (int i = 0; i < nchrs; ++i) |
1420 | for (int i = 0; i < nchrs; ++i) |
1418 | glyphs [i] = XftCharIndex (disp, f, chrs [i]); |
1421 | glyphs [i] = XftCharIndex (disp, f, chrs [i]); |
1419 | |
1422 | |
1420 | XftGlyphExtents (disp, f, glyphs, nchrs, &extents); |
|
|
1421 | |
|
|
1422 | XftGlyphSpec ep; |
|
|
1423 | |
|
|
1424 | ep.x = x_ + (cwidth - extents.xOff >> 1); |
|
|
1425 | ep.y = y_ + ascent; |
|
|
1426 | |
|
|
1427 | if (extents.xOff == 0) |
|
|
1428 | ep.x = x_ + cwidth; |
|
|
1429 | |
|
|
1430 | for (int i = 0; i < nchrs; ++i) |
1423 | for (int i = 0; i < nchrs; ++i) |
1431 | { |
1424 | { |
|
|
1425 | XGlyphInfo ep; |
|
|
1426 | XftGlyphExtents (disp, f, glyphs+i, 1, &ep); |
|
|
1427 | printf ("gs %4x g %4x + %3d,%3d o %3d,%3d wh %3d,%3d\n", chrs[i],glyphs[i],ep.x,ep.y,ep.xOff,ep.yOff,ep.width,ep.height); |
|
|
1428 | } |
|
|
1429 | #endif |
|
|
1430 | |
|
|
1431 | FT_UInt glyph = XftCharIndex (disp, f, chrs [0]); |
|
|
1432 | XGlyphInfo extents0; |
|
|
1433 | XftGlyphExtents (disp, f, &glyph, 1, &extents0); |
|
|
1434 | |
|
|
1435 | int cx = x_ + (cwidth - extents0.xOff >> 1); |
|
|
1436 | int cy = y_ + ascent; |
|
|
1437 | |
|
|
1438 | XftGlyphSpec ep; |
|
|
1439 | ep.glyph = glyph; |
|
|
1440 | ep.x = cx + (extents0.xOff ? 0 : extents0.xOff); |
|
|
1441 | ep.y = cy; |
|
|
1442 | |
|
|
1443 | enc.push_back (ep); |
|
|
1444 | |
|
|
1445 | for (int i = 1; ecb_expect_false (i < nchrs); ++i) |
|
|
1446 | { |
|
|
1447 | FT_UInt glyph = XftCharIndex (disp, f, chrs [i]); |
|
|
1448 | XGlyphInfo extents; |
|
|
1449 | XftGlyphExtents (disp, f, &glyph, 1, &extents); |
|
|
1450 | |
1432 | ep.glyph = glyphs [i]; |
1451 | ep.glyph = glyph; |
|
|
1452 | ep.x = cx + (extents.xOff ? 0 : extents0.xOff); |
|
|
1453 | |
1433 | enc.push_back (ep); |
1454 | enc.push_back (ep); |
1434 | } |
1455 | } |
1435 | } |
1456 | } |
1436 | |
1457 | |
1437 | x_ += cwidth; |
1458 | x_ += cwidth; |