aboutsummaryrefslogtreecommitdiff
path: root/st.c
diff options
context:
space:
mode:
authorChristoph Lohmann <20h@r-36.net>2012-12-29 15:03:03 +0100
committerChristoph Lohmann <20h@r-36.net>2012-12-29 15:03:03 +0100
commitaddc84834506e24387c1fb70b5d33b3f2ba55b66 (patch)
tree21b7dcb00e2e11e17ae638c91c7c2ceddf2c9512 /st.c
parent9c44229c626ea7351a7809540435f40cffb624bc (diff)
downloadst-addc84834506e24387c1fb70b5d33b3f2ba55b66.tar.gz
st-addc84834506e24387c1fb70b5d33b3f2ba55b66.zip
Speeding up the drawing, then all characters are known.
Diffstat (limited to 'st.c')
-rw-r--r--st.c176
1 files changed, 99 insertions, 77 deletions
diff --git a/st.c b/st.c
index a440959..cc8a22a 100644
--- a/st.c
+++ b/st.c
@@ -437,7 +437,7 @@ typedef struct {
437 */ 437 */
438 438
439static Fontcache frc[256]; 439static Fontcache frc[256];
440static int frccur = 0, frclen = 0; 440static int frccur = -1, frclen = 0;
441 441
442ssize_t 442ssize_t
443xwrite(int fd, char *s, size_t len) { 443xwrite(int fd, char *s, size_t len) {
@@ -2410,7 +2410,7 @@ xunloadfonts(void)
2410 ip = LEN(frc) - 1; 2410 ip = LEN(frc) - 1;
2411 XftFontClose(xw.dpy, frc[ip].font); 2411 XftFontClose(xw.dpy, frc[ip].font);
2412 } 2412 }
2413 frccur = 0; 2413 frccur = -1;
2414 frclen = 0; 2414 frclen = 0;
2415 2415
2416 XftFontClose(xw.dpy, dc.font.match); 2416 XftFontClose(xw.dpy, dc.font.match);
@@ -2532,11 +2532,12 @@ xinit(void) {
2532void 2532void
2533xdraws(char *s, Glyph base, int x, int y, int charlen, int bytelen) { 2533xdraws(char *s, Glyph base, int x, int y, int charlen, int bytelen) {
2534 int winx = borderpx + x * xw.cw, winy = borderpx + y * xw.ch, 2534 int winx = borderpx + x * xw.cw, winy = borderpx + y * xw.ch,
2535 width = charlen * xw.cw, u8clen, xp, i, frp, frcflags; 2535 width = charlen * xw.cw, xp, i;
2536 int frp, frcflags;
2537 int u8fl, u8fblen, u8cblen, doesexist;
2538 char *u8c, *u8fs;
2536 long u8char; 2539 long u8char;
2537 char *u8c;
2538 Font *font = &dc.font; 2540 Font *font = &dc.font;
2539 XftFont *sfont;
2540 FcResult fcres; 2541 FcResult fcres;
2541 FcPattern *fcpattern, *fontpattern; 2542 FcPattern *fcpattern, *fontpattern;
2542 FcFontSet *fcsets[] = { NULL }; 2543 FcFontSet *fcsets[] = { NULL };
@@ -2608,11 +2609,6 @@ xdraws(char *s, Glyph base, int x, int y, int charlen, int bytelen) {
2608 bg = temp; 2609 bg = temp;
2609 } 2610 }
2610 2611
2611 /* Width of the whole string that should be printed. */
2612 XftTextExtentsUtf8(xw.dpy, font->match, (FcChar8 *)s, bytelen,
2613 &extents);
2614 width = extents.xOff;
2615
2616 /* Intelligent cleaning up of the borders. */ 2612 /* Intelligent cleaning up of the borders. */
2617 if(x == 0) { 2613 if(x == 0) {
2618 xclear(0, (y == 0)? 0 : winy, borderpx, 2614 xclear(0, (y == 0)? 0 : winy, borderpx,
@@ -2630,85 +2626,111 @@ xdraws(char *s, Glyph base, int x, int y, int charlen, int bytelen) {
2630 /* Clean up the region we want to draw to. */ 2626 /* Clean up the region we want to draw to. */
2631 XftDrawRect(xw.draw, bg, winx, winy, width, xw.ch); 2627 XftDrawRect(xw.draw, bg, winx, winy, width, xw.ch);
2632 2628
2633 /*
2634 * Step through all UTF-8 characters one by one and search in the font
2635 * cache ring buffer, whether there was some font found to display the
2636 * unicode value of that UTF-8 character.
2637 */
2638 fcsets[0] = font->set; 2629 fcsets[0] = font->set;
2639 for (xp = winx; bytelen > 0; ) { 2630 for (xp = winx; bytelen > 0;) {
2640 u8c = s;
2641 u8clen = utf8decode(s, &u8char);
2642 s += u8clen;
2643 bytelen -= u8clen;
2644
2645 sfont = font->match;
2646 /* 2631 /*
2647 * Only check the font cache or load new fonts, if the 2632 * Search for the range in the to be printed string of glyphs
2648 * characters is not represented in main font. 2633 * that are in the main font. Then print that range. If
2634 * some glyph is found that is not in the font, do the
2635 * fallback dance.
2649 */ 2636 */
2650 if (!XftCharExists(xw.dpy, font->match, u8char)) { 2637 u8fs = s;
2651 frp = frccur; 2638 u8fblen = 0;
2652 /* Search the font cache. */ 2639 u8fl = 0;
2653 for (i = 0; i < frclen; i++, frp--) { 2640 for (;;) {
2654 if (frp <= 0) 2641 u8c = s;
2655 frp = LEN(frc) - 1; 2642 u8cblen = utf8decode(s, &u8char);
2643 s += u8cblen;
2644 bytelen -= u8cblen;
2645
2646 doesexist = XftCharIndex(xw.dpy, font->match, u8char);
2647 if (!doesexist || bytelen <= 0) {
2648 if (bytelen <= 0) {
2649 if (doesexist) {
2650 u8fl++;
2651 u8fblen += u8cblen;
2652 }
2653 }
2656 2654
2657 if (frc[frp].c == u8char 2655 if (u8fl > 0) {
2658 && frc[frp].flags == frcflags) { 2656 XftDrawStringUtf8(xw.draw, fg,
2659 break; 2657 font->match, xp,
2658 winy + font->ascent,
2659 (FcChar8 *)u8fs,
2660 u8fblen);
2661 xp += font->width * u8fl;
2660 } 2662 }
2663 break;
2661 } 2664 }
2662 if (i >= frclen) {
2663 /*
2664 * Nothing was found in the cache. Now use
2665 * some dozen of Fontconfig calls to get the
2666 * font for one single character.
2667 */
2668 fcpattern = FcPatternDuplicate(font->pattern);
2669 fccharset = FcCharSetCreate();
2670
2671 FcCharSetAddChar(fccharset, u8char);
2672 FcPatternAddCharSet(fcpattern, FC_CHARSET,
2673 fccharset);
2674 FcPatternAddBool(fcpattern, FC_SCALABLE,
2675 FcTrue);
2676
2677 FcConfigSubstitute(0, fcpattern,
2678 FcMatchPattern);
2679 FcDefaultSubstitute(fcpattern);
2680
2681 fontpattern = FcFontSetMatch(0, fcsets,
2682 FcTrue, fcpattern, &fcres);
2683
2684 frccur++;
2685 frclen++;
2686 if (frccur >= LEN(frc))
2687 frccur = 0;
2688 if (frclen >= LEN(frc)) {
2689 frclen = LEN(frc);
2690 XftFontClose(xw.dpy, frc[frccur].font);
2691 }
2692 2665
2693 /* 2666 u8fl++;
2694 * Overwrite or create the new cache entry 2667 u8fblen += u8cblen;
2695 * entry. 2668 }
2696 */ 2669 if (doesexist)
2697 frc[frccur].font = XftFontOpenPattern(xw.dpy, 2670 break;
2698 fontpattern);
2699 frc[frccur].c = u8char;
2700 frc[frccur].flags = frcflags;
2701 2671
2702 FcPatternDestroy(fcpattern); 2672 frp = frccur;
2703 FcCharSetDestroy(fccharset); 2673 /* Search the font cache. */
2674 for (i = 0; i < frclen; i++, frp--) {
2675 if (frp <= 0)
2676 frp = LEN(frc) - 1;
2704 2677
2705 frp = frccur; 2678 if (frc[frp].c == u8char
2679 && frc[frp].flags == frcflags) {
2680 break;
2706 } 2681 }
2707 sfont = frc[frp].font;
2708 } 2682 }
2709 2683
2710 XftDrawStringUtf8(xw.draw, fg, sfont, xp, winy + sfont->ascent, 2684 /* Nothing was found. */
2711 (FcChar8 *)u8c, u8clen); 2685 if (i >= frclen) {
2686 /*
2687 * Nothing was found in the cache. Now use
2688 * some dozen of Fontconfig calls to get the
2689 * font for one single character.
2690 */
2691 fcpattern = FcPatternDuplicate(font->pattern);
2692 fccharset = FcCharSetCreate();
2693
2694 FcCharSetAddChar(fccharset, u8char);
2695 FcPatternAddCharSet(fcpattern, FC_CHARSET,
2696 fccharset);
2697 FcPatternAddBool(fcpattern, FC_SCALABLE,
2698 FcTrue);
2699
2700 FcConfigSubstitute(0, fcpattern,
2701 FcMatchPattern);
2702 FcDefaultSubstitute(fcpattern);
2703
2704 fontpattern = FcFontSetMatch(0, fcsets,
2705 FcTrue, fcpattern, &fcres);
2706
2707 /*
2708 * Overwrite or create the new cache entry
2709 * entry.
2710 */
2711 frccur++;
2712 frclen++;
2713 if (frccur >= LEN(frc))
2714 frccur = 0;
2715 if (frclen > LEN(frc)) {
2716 frclen = LEN(frc);
2717 XftFontClose(xw.dpy, frc[frccur].font);
2718 }
2719
2720 frc[frccur].font = XftFontOpenPattern(xw.dpy,
2721 fontpattern);
2722 frc[frccur].c = u8char;
2723 frc[frccur].flags = frcflags;
2724
2725 FcPatternDestroy(fcpattern);
2726 FcCharSetDestroy(fccharset);
2727
2728 frp = frccur;
2729 }
2730
2731 XftDrawStringUtf8(xw.draw, fg, frc[frp].font,
2732 xp, winy + frc[frp].font->ascent,
2733 (FcChar8 *)u8c, u8cblen);
2712 2734
2713 xp += font->width; 2735 xp += font->width;
2714 } 2736 }