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.217 by root, Wed Jun 23 12:37:32 2021 UTC

134# endif 134# endif
135#endif 135#endif
136 136
137 //{ CS_UNICODE, "-*-unifont-*-*-*-*-*-*-*-*-c-*-iso10646-1" }, // this gem of a font has actual dotted circles within the combining character glyphs. 137 //{ CS_UNICODE, "-*-unifont-*-*-*-*-*-*-*-*-c-*-iso10646-1" }, // this gem of a font has actual dotted circles within the combining character glyphs.
138#if XFT 138#if XFT
139 { CS_UNICODE, "xft:Bitstream Vera Sans Mono:antialias=false:autohint=true" }, 139 { CS_UNICODE, "xft:DejaVu Sans Mono:antialias=false:autohint=true" },
140 { CS_UNICODE, "xft:Courier New:antialias=false:autohint=true" }, 140 { CS_UNICODE, "xft:Courier New:antialias=false:autohint=true" },
141 { CS_UNICODE, "xft:Andale Mono:antialias=false:autohint=false" }, 141 { CS_UNICODE, "xft:Andale Mono:antialias=false:autohint=false" },
142 { CS_UNICODE, "xft:Arial Unicode MS:antialias=false:autohint=false" }, 142 { CS_UNICODE, "xft:Arial Unicode MS:antialias=false:autohint=false" },
143 143
144 // FreeMono is usually uglier than x fonts, so try after the others 144 // FreeMono is usually uglier than x fonts, so try after the others
145 { CS_UNICODE, "xft:FreeMono:autohint=true" }, 145 { CS_UNICODE, "xft:FreeMono:autohint=true" },
146#endif 146#endif
147 147
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);
1436 int cy = y_ + ascent;
1437
1438 XftGlyphSpec ep;
1439 ep.glyph = glyph; 1442 ep->glyph = glyph;
1440 ep.x = cx + (extents0.xOff ? 0 : extents0.xOff);
1441 ep.y = cy; 1443 ep->x = x_;
1444 ep->y = y_ + ascent;
1442 1445
1443 enc.push_back (ep); 1446 // the xft font cell might differ from the terminal font cell,
1447 // in which case we use the average between the two.
1448 ep->x += extents.xOff ? cwidth - extents.xOff >> 1 : 0;
1444 1449
1445 for (int i = 1; ecb_expect_false (i < nchrs); ++i) 1450 // xft/freetype represent combining characters as characters with zero
1446 { 1451 // width rendered over the previous character with some fonts, while
1447 FT_UInt glyph = XftCharIndex (disp, f, chrs [i]); 1452 // in other fonts, they are considered normal characters, while yet
1448 XGlyphInfo extents; 1453 // in other fonts, they are shifted all over the place.
1449 XftGlyphExtents (disp, f, &glyph, 1, &extents); 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 character here, but we don't have that, so we use cwidth.
1457 ep->x += extents.xOff ? 0 : cwidth;
1450 1458
1451 ep.glyph = glyph; 1459 ++ep;
1452 ep.x = cx + (extents.xOff ? 0 : extents0.xOff);
1453
1454 enc.push_back (ep);
1455 }
1456 } 1460 }
1457 1461
1458 x_ += cwidth; 1462 x_ += cwidth;
1459 } 1463 }
1460 1464
1461 if (buffered) 1465 if (buffered)
1462 { 1466 {
1463 if (!enc.empty ()) 1467 if (ep != enc)
1464 { 1468 {
1465 rxvt_drawable &d2 = d.screen->scratch_drawable (w, h); 1469 rxvt_drawable &d2 = d.screen->scratch_drawable (w, h);
1466 1470
1467#ifdef HAVE_IMG 1471#ifdef HAVE_IMG
1468 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
1514 } 1518 }
1515 else 1519 else
1516#endif 1520#endif
1517 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);
1518 1522
1519 XftDrawGlyphSpec (d2, &term->pix_colors[fg].c, f, &enc[0], enc.size ()); 1523 XftDrawGlyphSpec (d2, &term->pix_colors[fg].c, f, enc, ep - enc);
1520 XCopyArea (disp, d2, d, gc, 0, 0, w, h, x, y); 1524 XCopyArea (disp, d2, d, gc, 0, 0, w, h, x, y);
1521 } 1525 }
1522 else 1526 else
1523 clear_rect (d, x, y, w, h, bg); 1527 clear_rect (d, x, y, w, h, bg);
1524 } 1528 }
1525 else 1529 else
1526 { 1530 {
1527 clear_rect (d, x, y, w, h, bg); 1531 clear_rect (d, x, y, w, h, bg);
1528 XftDrawGlyphSpec (d, &term->pix_colors[fg].c, f, &enc[0], enc.size ()); 1532 XftDrawGlyphSpec (d, &term->pix_colors[fg].c, f, enc, ep - enc);
1529 } 1533 }
1530} 1534}
1531 1535
1532#endif 1536#endif
1533 1537
1729} 1733}
1730 1734
1731int 1735int
1732rxvt_fontset::find_font_idx (unicode_t unicode) 1736rxvt_fontset::find_font_idx (unicode_t unicode)
1733{ 1737{
1734 // this limits fmap size. it has to accomodate COMPOSE_HI when UNICODE_3 1738 // this limits fmap size. it has to accommodate COMPOSE_HI when UNICODE_3
1735 if (unicode > 0x1fffff) 1739 if (unicode > 0x1fffff)
1736 return 0; 1740 return 0;
1737 1741
1738 unicode_t hi = unicode >> 8; 1742 unicode_t hi = unicode >> 8;
1739 1743

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines