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.209 by root, Fri Jun 18 21:58:03 2021 UTC vs.
Revision 1.214 by root, Sat Jun 19 09:47:41 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 FcChar32 *chrs = exp (unicode); 1344#if ENABLE_COMBINING && !UNICODE_3
1345 int nchrs = exp.length (chrs); 1345 if (ecb_expect_false (IS_COMPOSE (unicode)))
1346 1346 if (compose_char *cc = rxvt_composite [unicode])
1347 // allm chars in sequence must be available 1347 if (cc->c2 == NOCHAR)
1348 for (int i = 0; i < nchrs; ++i) 1348 unicode = cc->c1;
1349 if (!XftCharExists (term->dpy, f, chrs [i])) 1349 else
1350 return false;
1351 else
1350 return false; 1352 return false;
1353#endif
1354
1355 FcChar32 chr = unicode;
1356
1357 if (!XftCharExists (term->dpy, f, chr))
1358 return false;
1351 1359
1352 if (!prop || prop->width == rxvt_fontprop::unset) 1360 if (!prop || prop->width == rxvt_fontprop::unset)
1353 return true; 1361 return true;
1354 1362
1355 int wcw = max (WCWIDTH (chrs [0]), 1); 1363 int wcw = max (WCWIDTH (chr), 1);
1356 1364
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; 1365 XGlyphInfo g;
1362 XftTextExtents32 (term->dpy, f, chrs + i, 1, &g); 1366 XftTextExtents32 (term->dpy, f, &chr, 1, &g);
1363 1367
1364 int w = g.width - g.x; 1368 int w = g.width - g.x;
1365 1369
1366 careful = g.x > 0 || w > prop->width * wcw; 1370 careful = g.x > 0 || w > prop->width * wcw;
1367 1371
1368 if (careful && !OVERLAP_OK (w, wcw, prop)) 1372 if (careful && !OVERLAP_OK (w, wcw, prop))
1369 return false; 1373 return false;
1370 1374
1371 // this weeds out _totally_ broken fonts, or glyphs 1375 // this weeds out _totally_ broken fonts, or glyphs
1372 if (!OVERLAP_OK (g.xOff, wcw, prop)) 1376 if (!OVERLAP_OK (g.xOff, wcw, prop))
1373 return false; 1377 return false;
1374 }
1375 1378
1376 return true; 1379 return true;
1377} 1380}
1378 1381
1379void 1382void
1380rxvt_font_xft::draw (rxvt_drawable &d, int x, int y, 1383rxvt_font_xft::draw (rxvt_drawable &d, int x, int y,
1381 const text_t *text, int len, 1384 const text_t *text, int len,
1382 int fg, int bg) 1385 int fg, int bg)
1383{ 1386{
1384 //XftGlyphSpec *enc = rxvt_temp_buf<XftGlyphSpec> (len);//D 1387 XftGlyphSpec *enc = rxvt_temp_buf<XftGlyphSpec> (len);
1385 //XftGlyphSpec *ep = enc;//D 1388 XftGlyphSpec *ep = enc;
1386 static vector<XftGlyphSpec> enc; enc.resize (0); // static to avoid malloc, still slow
1387 1389
1388 dTermDisplay; 1390 dTermDisplay;
1389 dTermGC; 1391 dTermGC;
1390 1392
1391 int w = term->fwidth * len; 1393 int w = term->fwidth * len;
1402 int y_ = buffered ? 0 : y; 1404 int y_ = buffered ? 0 : y;
1403 1405
1404 while (len) 1406 while (len)
1405 { 1407 {
1406 int cwidth = term->fwidth; 1408 int cwidth = term->fwidth;
1407
1408 rxvt_compose_expand_static<FcChar32> exp;
1409 FcChar32 *chrs = exp (*text++); len--; 1409 FcChar32 chr = *text++; len--;
1410 int nchrs = exp.length (chrs);
1411 1410
1412 while (len && *text == NOCHAR) 1411 while (len && *text == NOCHAR)
1413 text++, len--, cwidth += term->fwidth; 1412 text++, len--, cwidth += term->fwidth;
1414 1413
1415 if (chrs [0] != ' ') // skip spaces 1414 if (chr != ' ') // skip spaces
1416 { 1415 {
1416 // handle non-bmp chars when text_t is 16 bit
1417 #if ENABLE_COMBINING && !UNICODE_3
1418 if (ecb_expect_false (IS_COMPOSE (chr)))
1419 if (compose_char *cc = rxvt_composite [chr])
1420 if (cc->c2 == NOCHAR)
1421 chr = cc->c1;
1422 #endif
1423
1417 #if 1 1424 #if 0
1418 FT_UInt glyphs [decltype (exp)::max_size]; 1425 FT_UInt glyphs [decltype (exp)::max_size];
1419 1426
1420 for (int i = 0; i < nchrs; ++i) 1427 for (int i = 0; i < nchrs; ++i)
1421 glyphs [i] = XftCharIndex (disp, f, chrs [i]); 1428 glyphs [i] = XftCharIndex (disp, f, chrs [i]);
1422 1429
1426 XftGlyphExtents (disp, f, glyphs+i, 1, &ep); 1433 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); 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);
1428 } 1435 }
1429 #endif 1436 #endif
1430 1437
1431 FT_UInt glyph = XftCharIndex (disp, f, chrs [0]); 1438 FT_UInt glyph = XftCharIndex (disp, f, chr);
1432 XGlyphInfo extents0; 1439 XGlyphInfo extents;
1433 XftGlyphExtents (disp, f, &glyph, 1, &extents0); 1440 XftGlyphExtents (disp, f, &glyph, 1, &extents);
1434 1441
1435 int cx = x_ + (cwidth - extents0.xOff >> 1); 1442 int xOff = extents.xOff ? extents.xOff : cwidth;
1436 int cy = y_ + ascent;
1437 1443
1438 XftGlyphSpec ep;
1439 ep.glyph = glyph; 1444 ep->glyph = glyph;
1440 ep.x = cx + (extents0.xOff ? 0 : extents0.xOff);
1441 ep.y = cy; 1445 ep->x = x_;
1446 ep->y = y_ + ascent;
1442 1447
1443 enc.push_back (ep); 1448 // the xft font cell might differ from the terminal font cell,
1449 // in which case we use the average between the two.
1450 if (extents.xOff)
1451 ep->x += extents.xOff ? cwidth - extents.xOff >> 1 : 0;
1444 1452
1445 for (int i = 1; ecb_expect_false (i < nchrs); ++i) 1453 // xft/freetype represent combining characters as characters with zero
1446 { 1454 // width rendered over the previous character with some fonts, while
1447 FT_UInt glyph = XftCharIndex (disp, f, chrs [i]); 1455 // in other fonts, they are considered normal characters, while yet
1448 XGlyphInfo extents; 1456 // in other fonts, they are shifted all over the place.
1449 XftGlyphExtents (disp, f, &glyph, 1, &extents); 1457 // we handle the first two cases by keying off on xOff being 0
1458 // for zero-width chars. normally, we would add extents.xOff
1459 // of the base character here, but we don't have that, so we use cwidth.
1460 ep->x += extents.xOff ? 0 : cwidth;
1450 1461
1451 ep.glyph = glyph; 1462 ++ep;
1452 ep.x = cx + (extents.xOff ? 0 : extents0.xOff);
1453
1454 enc.push_back (ep);
1455 }
1456 } 1463 }
1457 1464
1458 x_ += cwidth; 1465 x_ += cwidth;
1459 } 1466 }
1460 1467
1461 if (buffered) 1468 if (buffered)
1462 { 1469 {
1463 if (!enc.empty ()) 1470 if (ep != enc)
1464 { 1471 {
1465 rxvt_drawable &d2 = d.screen->scratch_drawable (w, h); 1472 rxvt_drawable &d2 = d.screen->scratch_drawable (w, h);
1466 1473
1467#ifdef HAVE_IMG 1474#ifdef HAVE_IMG
1468 Picture dst = 0; // the only assignment is done conditionally in the following if condition 1475 Picture dst = 0; // the only assignment is done conditionally in the following if condition
1514 } 1521 }
1515 else 1522 else
1516#endif 1523#endif
1517 XftDrawRect (d2, &term->pix_colors[bg >= 0 ? bg : Color_bg].c, 0, 0, w, h); 1524 XftDrawRect (d2, &term->pix_colors[bg >= 0 ? bg : Color_bg].c, 0, 0, w, h);
1518 1525
1519 XftDrawGlyphSpec (d2, &term->pix_colors[fg].c, f, &enc[0], enc.size ()); 1526 XftDrawGlyphSpec (d2, &term->pix_colors[fg].c, f, enc, ep - enc);
1520 XCopyArea (disp, d2, d, gc, 0, 0, w, h, x, y); 1527 XCopyArea (disp, d2, d, gc, 0, 0, w, h, x, y);
1521 } 1528 }
1522 else 1529 else
1523 clear_rect (d, x, y, w, h, bg); 1530 clear_rect (d, x, y, w, h, bg);
1524 } 1531 }
1525 else 1532 else
1526 { 1533 {
1527 clear_rect (d, x, y, w, h, bg); 1534 clear_rect (d, x, y, w, h, bg);
1528 XftDrawGlyphSpec (d, &term->pix_colors[fg].c, f, &enc[0], enc.size ()); 1535 XftDrawGlyphSpec (d, &term->pix_colors[fg].c, f, enc, ep - enc);
1529 } 1536 }
1530} 1537}
1531 1538
1532#endif 1539#endif
1533 1540
1729} 1736}
1730 1737
1731int 1738int
1732rxvt_fontset::find_font_idx (unicode_t unicode) 1739rxvt_fontset::find_font_idx (unicode_t unicode)
1733{ 1740{
1734 // this limits fmap size. it has to accomodate COMPOSE_HI when UNICODE_3 1741 // this limits fmap size. it has to accommodate COMPOSE_HI when UNICODE_3
1735 if (unicode > 0x1fffff) 1742 if (unicode > 0x1fffff)
1736 return 0; 1743 return 0;
1737 1744
1738 unicode_t hi = unicode >> 8; 1745 unicode_t hi = unicode >> 8;
1739 1746

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines