ViewVC Help
View File | Revision Log | Show Annotations | Download File
/cvs/rxvt-unicode/src/rxvtfont.C
(Generate patch)

Comparing rxvt-unicode/src/rxvtfont.C (file contents):
Revision 1.207 by root, Thu Jun 17 19:42:55 2021 UTC vs.
Revision 1.211 by root, Fri Jun 18 22:12:30 2021 UTC

1338bool 1338bool
1339rxvt_font_xft::has_char (unicode_t unicode, const rxvt_fontprop *prop, bool &careful) const 1339rxvt_font_xft::has_char (unicode_t unicode, const rxvt_fontprop *prop, bool &careful) const
1340{ 1340{
1341 careful = false; 1341 careful = false;
1342 1342
1343 rxvt_compose_expand_static<FcChar32> exp; 1343 // handle non-bmp chars when text_t is 16 bit
1344#if ENABLE_COMBINING && !UNICODE_3
1345 if (ecb_expect_false (IS_COMPOSE (unicode)))
1346 if (compose_char *cc = rxvt_composite [unicode])
1347 if (cc->c2 == NOCHAR)
1348 unicode = cc->c1;
1349 else
1350 return false;
1351 else
1352 return false;
1353#endif
1354
1344 FcChar32 *chrs = exp (unicode); 1355 FcChar32 chr = unicode;
1345 int nchrs = exp.length (chrs);
1346 1356
1347 // we handle the sequence if the first char is available
1348 if (!XftCharExists (term->dpy, f, chrs [0])) 1357 if (!XftCharExists (term->dpy, f, chr))
1349 return false; 1358 return false;
1350 1359
1351 if (!prop || prop->width == rxvt_fontprop::unset) 1360 if (!prop || prop->width == rxvt_fontprop::unset)
1352 return true; 1361 return true;
1353 1362
1354 // but we check against the whole sequence bounding box 1363 int wcw = max (WCWIDTH (chr), 1);
1355 1364
1356 // check character against base font bounding box
1357 FcChar32 ch = unicode;
1358 XGlyphInfo g; 1365 XGlyphInfo g;
1359 XftTextExtents32 (term->dpy, f, chrs, nchrs, &g); 1366 XftTextExtents32 (term->dpy, f, &chr, 1, &g);
1360 1367
1361 int w = g.width - g.x; 1368 int w = g.width - g.x;
1362 int wcw = max (WCWIDTH (chrs [0]), 1);
1363 1369
1364 careful = g.x > 0 || w > prop->width * wcw; 1370 careful = g.x > 0 || w > prop->width * wcw;
1365 1371
1366 if (careful && !OVERLAP_OK (w, wcw, prop)) 1372 if (careful && !OVERLAP_OK (w, wcw, prop))
1367 return false; 1373 return false;
1376void 1382void
1377rxvt_font_xft::draw (rxvt_drawable &d, int x, int y, 1383rxvt_font_xft::draw (rxvt_drawable &d, int x, int y,
1378 const text_t *text, int len, 1384 const text_t *text, int len,
1379 int fg, int bg) 1385 int fg, int bg)
1380{ 1386{
1381 XGlyphInfo extents;
1382 //XftGlyphSpec *enc = rxvt_temp_buf<XftGlyphSpec> (len);//D 1387 XftGlyphSpec *enc = rxvt_temp_buf<XftGlyphSpec> (len);
1383 //XftGlyphSpec *ep = enc;//D 1388 XftGlyphSpec *ep = enc;
1384 static vector<XftGlyphSpec> enc; enc.resize (0); // static to avoid malloc, still slow
1385 1389
1386 dTermDisplay; 1390 dTermDisplay;
1387 dTermGC; 1391 dTermGC;
1388 1392
1389 int w = term->fwidth * len; 1393 int w = term->fwidth * len;
1400 int y_ = buffered ? 0 : y; 1404 int y_ = buffered ? 0 : y;
1401 1405
1402 while (len) 1406 while (len)
1403 { 1407 {
1404 int cwidth = term->fwidth; 1408 int cwidth = term->fwidth;
1405
1406 rxvt_compose_expand_static<FcChar32> exp;
1407 FcChar32 *chrs = exp (*text++); len--; 1409 FcChar32 chr = *text++; len--;
1408 int nchrs = exp.length (chrs); 1410
1411 // handle non-bmp chars when text_t is 16 bit
1412 #if ENABLE_COMBINING && !UNICODE_3
1413 if (ecb_expect_false (IS_COMPOSE (chr)))
1414 if (compose_char *cc = rxvt_composite [chr])
1415 if (cc->c2 == NOCHAR)
1416 chr = cc->c1;
1417 #endif
1409 1418
1410 while (len && *text == NOCHAR) 1419 while (len && *text == NOCHAR)
1411 text++, len--, cwidth += term->fwidth; 1420 text++, len--, cwidth += term->fwidth;
1412 1421
1413 if (chrs [0] != ' ') // skip spaces 1422 if (chr != ' ') // skip spaces
1414 { 1423 {
1415 FT_UInt glyphs [rxvt_compose_expand_static<FcChar32>::max_size]; 1424 #if 0
1425 FT_UInt glyphs [decltype (exp)::max_size];
1416 1426
1417 for (int i = 0; i < nchrs; ++i) 1427 for (int i = 0; i < nchrs; ++i)
1418 glyphs [i] = XftCharIndex (disp, f, chrs [i]); 1428 glyphs [i] = XftCharIndex (disp, f, chrs [i]);
1419 1429
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) 1430 for (int i = 0; i < nchrs; ++i)
1431 { 1431 {
1432 ep.glyph = glyphs [i]; 1432 XGlyphInfo ep;
1433 enc.push_back (ep); 1433 XftGlyphExtents (disp, f, glyphs+i, 1, &ep);
1434 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);
1434 } 1435 }
1436 #endif
1437
1438 FT_UInt glyph = XftCharIndex (disp, f, chr);
1439 XGlyphInfo extents;
1440 XftGlyphExtents (disp, f, &glyph, 1, &extents);
1441
1442 ep->glyph = glyph;
1443 ep->x = x_;
1444 ep->y = y_ + ascent;
1445
1446 // the xft font cell might differ from the terminal font cell,
1447 // in which we use the average between the two
1448 ep->x += cwidth - extents.xOff >> 1;
1449
1450 // xft/freetype represent combining characters as characters with zero
1451 // width rendered over the previous character with some fonts, while
1452 // in other fonts, they are considered normal characters, while yet
1453 // in other fonts, they are shifted all over the place.
1454 // we handle the first two cases by keying off on xOff being 0
1455 // for zero-width chars. normally, we would add extents.xOff
1456 // of the base chaarcter here, but we don't have that, so we use cwidth.
1457 ep->x += extents.xOff ? 0 : cwidth;
1458
1459 ++ep;
1435 } 1460 }
1436 1461
1437 x_ += cwidth; 1462 x_ += cwidth;
1438 } 1463 }
1439 1464
1440 if (buffered) 1465 if (buffered)
1441 { 1466 {
1442 if (!enc.empty ()) 1467 if (ep != enc)
1443 { 1468 {
1444 rxvt_drawable &d2 = d.screen->scratch_drawable (w, h); 1469 rxvt_drawable &d2 = d.screen->scratch_drawable (w, h);
1445 1470
1446#ifdef HAVE_IMG 1471#ifdef HAVE_IMG
1447 Picture dst = 0; // the only assignment is done conditionally in the following if condition 1472 Picture dst = 0; // the only assignment is done conditionally in the following if condition
1493 } 1518 }
1494 else 1519 else
1495#endif 1520#endif
1496 XftDrawRect (d2, &term->pix_colors[bg >= 0 ? bg : Color_bg].c, 0, 0, w, h); 1521 XftDrawRect (d2, &term->pix_colors[bg >= 0 ? bg : Color_bg].c, 0, 0, w, h);
1497 1522
1498 XftDrawGlyphSpec (d2, &term->pix_colors[fg].c, f, &enc[0], enc.size ()); 1523 XftDrawGlyphSpec (d2, &term->pix_colors[fg].c, f, enc, ep - enc);
1499 XCopyArea (disp, d2, d, gc, 0, 0, w, h, x, y); 1524 XCopyArea (disp, d2, d, gc, 0, 0, w, h, x, y);
1500 } 1525 }
1501 else 1526 else
1502 clear_rect (d, x, y, w, h, bg); 1527 clear_rect (d, x, y, w, h, bg);
1503 } 1528 }
1504 else 1529 else
1505 { 1530 {
1506 clear_rect (d, x, y, w, h, bg); 1531 clear_rect (d, x, y, w, h, bg);
1507 XftDrawGlyphSpec (d, &term->pix_colors[fg].c, f, &enc[0], enc.size ()); 1532 XftDrawGlyphSpec (d, &term->pix_colors[fg].c, f, enc, ep - enc);
1508 } 1533 }
1509} 1534}
1510 1535
1511#endif 1536#endif
1512 1537

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines