Speeding up the drawing, then all characters are known.
This commit is contained in:
		
							
								
								
									
										184
									
								
								st.c
									
									
									
									
									
								
							
							
						
						
									
										184
									
								
								st.c
									
									
									
									
									
								
							@@ -437,7 +437,7 @@ typedef struct {
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
static Fontcache frc[256];
 | 
			
		||||
static int frccur = 0, frclen = 0;
 | 
			
		||||
static int frccur = -1, frclen = 0;
 | 
			
		||||
 | 
			
		||||
ssize_t
 | 
			
		||||
xwrite(int fd, char *s, size_t len) {
 | 
			
		||||
@@ -2410,7 +2410,7 @@ xunloadfonts(void)
 | 
			
		||||
			ip = LEN(frc) - 1;
 | 
			
		||||
		XftFontClose(xw.dpy, frc[ip].font);
 | 
			
		||||
	}
 | 
			
		||||
	frccur = 0;
 | 
			
		||||
	frccur = -1;
 | 
			
		||||
	frclen = 0;
 | 
			
		||||
 | 
			
		||||
	XftFontClose(xw.dpy, dc.font.match);
 | 
			
		||||
@@ -2532,11 +2532,12 @@ xinit(void) {
 | 
			
		||||
void
 | 
			
		||||
xdraws(char *s, Glyph base, int x, int y, int charlen, int bytelen) {
 | 
			
		||||
	int winx = borderpx + x * xw.cw, winy = borderpx + y * xw.ch,
 | 
			
		||||
	    width = charlen * xw.cw, u8clen, xp, i, frp, frcflags;
 | 
			
		||||
	    width = charlen * xw.cw, xp, i;
 | 
			
		||||
	int frp, frcflags;
 | 
			
		||||
	int u8fl, u8fblen, u8cblen, doesexist;
 | 
			
		||||
	char *u8c, *u8fs;
 | 
			
		||||
	long u8char;
 | 
			
		||||
	char *u8c;
 | 
			
		||||
	Font *font = &dc.font;
 | 
			
		||||
	XftFont *sfont;
 | 
			
		||||
	FcResult fcres;
 | 
			
		||||
	FcPattern *fcpattern, *fontpattern;
 | 
			
		||||
	FcFontSet *fcsets[] = { NULL };
 | 
			
		||||
@@ -2608,11 +2609,6 @@ xdraws(char *s, Glyph base, int x, int y, int charlen, int bytelen) {
 | 
			
		||||
		bg = temp;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	/* Width of the whole string that should be printed. */
 | 
			
		||||
	XftTextExtentsUtf8(xw.dpy, font->match, (FcChar8 *)s, bytelen,
 | 
			
		||||
			&extents);
 | 
			
		||||
	width = extents.xOff;
 | 
			
		||||
 | 
			
		||||
	/* Intelligent cleaning up of the borders. */
 | 
			
		||||
	if(x == 0) {
 | 
			
		||||
		xclear(0, (y == 0)? 0 : winy, borderpx,
 | 
			
		||||
@@ -2630,85 +2626,111 @@ xdraws(char *s, Glyph base, int x, int y, int charlen, int bytelen) {
 | 
			
		||||
	/* Clean up the region we want to draw to. */
 | 
			
		||||
	XftDrawRect(xw.draw, bg, winx, winy, width, xw.ch);
 | 
			
		||||
 | 
			
		||||
	/*
 | 
			
		||||
	 * Step through all UTF-8 characters one by one and search in the font
 | 
			
		||||
	 * cache ring buffer, whether there was some font found to display the
 | 
			
		||||
	 * unicode value of that UTF-8 character.
 | 
			
		||||
	 */
 | 
			
		||||
	fcsets[0] = font->set;
 | 
			
		||||
	for (xp = winx; bytelen > 0; ) {
 | 
			
		||||
		u8c = s;
 | 
			
		||||
		u8clen = utf8decode(s, &u8char);
 | 
			
		||||
		s += u8clen;
 | 
			
		||||
		bytelen -= u8clen;
 | 
			
		||||
 | 
			
		||||
		sfont = font->match;
 | 
			
		||||
	for (xp = winx; bytelen > 0;) {
 | 
			
		||||
		/*
 | 
			
		||||
		 * Only check the font cache or load new fonts, if the
 | 
			
		||||
		 * characters is not represented in main font.
 | 
			
		||||
		 * Search for the range in the to be printed string of glyphs
 | 
			
		||||
		 * that are in the main font. Then print that range. If
 | 
			
		||||
		 * some glyph is found that is not in the font, do the
 | 
			
		||||
		 * fallback dance.
 | 
			
		||||
		 */
 | 
			
		||||
		if (!XftCharExists(xw.dpy, font->match, u8char)) {
 | 
			
		||||
			frp = frccur;
 | 
			
		||||
			/* Search the font cache. */
 | 
			
		||||
			for (i = 0; i < frclen; i++, frp--) {
 | 
			
		||||
				if (frp <= 0)
 | 
			
		||||
					frp = LEN(frc) - 1;
 | 
			
		||||
		u8fs = s;
 | 
			
		||||
		u8fblen = 0;
 | 
			
		||||
		u8fl = 0;
 | 
			
		||||
		for (;;) {
 | 
			
		||||
			u8c = s;
 | 
			
		||||
			u8cblen = utf8decode(s, &u8char);
 | 
			
		||||
			s += u8cblen;
 | 
			
		||||
			bytelen -= u8cblen;
 | 
			
		||||
 | 
			
		||||
				if (frc[frp].c == u8char
 | 
			
		||||
			doesexist = XftCharIndex(xw.dpy, font->match, u8char);
 | 
			
		||||
			if (!doesexist || bytelen <= 0) {
 | 
			
		||||
				if (bytelen <= 0) {
 | 
			
		||||
					if (doesexist) {
 | 
			
		||||
						u8fl++;
 | 
			
		||||
						u8fblen += u8cblen;
 | 
			
		||||
					}
 | 
			
		||||
				}
 | 
			
		||||
 | 
			
		||||
				if (u8fl > 0) {
 | 
			
		||||
					XftDrawStringUtf8(xw.draw, fg,
 | 
			
		||||
							font->match, xp,
 | 
			
		||||
							winy + font->ascent,
 | 
			
		||||
							(FcChar8 *)u8fs,
 | 
			
		||||
							u8fblen);
 | 
			
		||||
					xp += font->width * u8fl;
 | 
			
		||||
				}
 | 
			
		||||
				break;
 | 
			
		||||
			}
 | 
			
		||||
 | 
			
		||||
			u8fl++;
 | 
			
		||||
			u8fblen += u8cblen;
 | 
			
		||||
		}
 | 
			
		||||
		if (doesexist)
 | 
			
		||||
			break;
 | 
			
		||||
 | 
			
		||||
		frp = frccur;
 | 
			
		||||
		/* Search the font cache. */
 | 
			
		||||
		for (i = 0; i < frclen; i++, frp--) {
 | 
			
		||||
			if (frp <= 0)
 | 
			
		||||
				frp = LEN(frc) - 1;
 | 
			
		||||
 | 
			
		||||
			if (frc[frp].c == u8char
 | 
			
		||||
					&& frc[frp].flags == frcflags) {
 | 
			
		||||
					break;
 | 
			
		||||
				}
 | 
			
		||||
				break;
 | 
			
		||||
			}
 | 
			
		||||
			if (i >= frclen) {
 | 
			
		||||
				/*
 | 
			
		||||
				 * Nothing was found in the cache. Now use
 | 
			
		||||
				 * some dozen of Fontconfig calls to get the
 | 
			
		||||
				 * font for one single character.
 | 
			
		||||
				 */
 | 
			
		||||
				fcpattern = FcPatternDuplicate(font->pattern);
 | 
			
		||||
				fccharset = FcCharSetCreate();
 | 
			
		||||
 | 
			
		||||
				FcCharSetAddChar(fccharset, u8char);
 | 
			
		||||
				FcPatternAddCharSet(fcpattern, FC_CHARSET,
 | 
			
		||||
						fccharset);
 | 
			
		||||
				FcPatternAddBool(fcpattern, FC_SCALABLE,
 | 
			
		||||
						FcTrue);
 | 
			
		||||
 | 
			
		||||
				FcConfigSubstitute(0, fcpattern,
 | 
			
		||||
						FcMatchPattern);
 | 
			
		||||
				FcDefaultSubstitute(fcpattern);
 | 
			
		||||
 | 
			
		||||
				fontpattern = FcFontSetMatch(0, fcsets,
 | 
			
		||||
						FcTrue, fcpattern, &fcres);
 | 
			
		||||
 | 
			
		||||
				frccur++;
 | 
			
		||||
				frclen++;
 | 
			
		||||
				if (frccur >= LEN(frc))
 | 
			
		||||
					frccur = 0;
 | 
			
		||||
				if (frclen >= LEN(frc)) {
 | 
			
		||||
					frclen = LEN(frc);
 | 
			
		||||
					XftFontClose(xw.dpy, frc[frccur].font);
 | 
			
		||||
				}
 | 
			
		||||
 | 
			
		||||
				/*
 | 
			
		||||
				 * Overwrite or create the new cache entry
 | 
			
		||||
				 * entry.
 | 
			
		||||
				 */
 | 
			
		||||
				frc[frccur].font = XftFontOpenPattern(xw.dpy,
 | 
			
		||||
						fontpattern);
 | 
			
		||||
				frc[frccur].c = u8char;
 | 
			
		||||
				frc[frccur].flags = frcflags;
 | 
			
		||||
 | 
			
		||||
				FcPatternDestroy(fcpattern);
 | 
			
		||||
				FcCharSetDestroy(fccharset);
 | 
			
		||||
 | 
			
		||||
				frp = frccur;
 | 
			
		||||
			}
 | 
			
		||||
			sfont = frc[frp].font;
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		XftDrawStringUtf8(xw.draw, fg, sfont, xp, winy + sfont->ascent,
 | 
			
		||||
				(FcChar8 *)u8c, u8clen);
 | 
			
		||||
		/* Nothing was found. */
 | 
			
		||||
		if (i >= frclen) {
 | 
			
		||||
			/*
 | 
			
		||||
			 * Nothing was found in the cache. Now use
 | 
			
		||||
			 * some dozen of Fontconfig calls to get the
 | 
			
		||||
			 * font for one single character.
 | 
			
		||||
			 */
 | 
			
		||||
			fcpattern = FcPatternDuplicate(font->pattern);
 | 
			
		||||
			fccharset = FcCharSetCreate();
 | 
			
		||||
 | 
			
		||||
			FcCharSetAddChar(fccharset, u8char);
 | 
			
		||||
			FcPatternAddCharSet(fcpattern, FC_CHARSET,
 | 
			
		||||
					fccharset);
 | 
			
		||||
			FcPatternAddBool(fcpattern, FC_SCALABLE,
 | 
			
		||||
					FcTrue);
 | 
			
		||||
 | 
			
		||||
			FcConfigSubstitute(0, fcpattern,
 | 
			
		||||
					FcMatchPattern);
 | 
			
		||||
			FcDefaultSubstitute(fcpattern);
 | 
			
		||||
 | 
			
		||||
			fontpattern = FcFontSetMatch(0, fcsets,
 | 
			
		||||
					FcTrue, fcpattern, &fcres);
 | 
			
		||||
 | 
			
		||||
			/*
 | 
			
		||||
			 * Overwrite or create the new cache entry
 | 
			
		||||
			 * entry.
 | 
			
		||||
			 */
 | 
			
		||||
			frccur++;
 | 
			
		||||
			frclen++;
 | 
			
		||||
			if (frccur >= LEN(frc))
 | 
			
		||||
				frccur = 0;
 | 
			
		||||
			if (frclen > LEN(frc)) {
 | 
			
		||||
				frclen = LEN(frc);
 | 
			
		||||
				XftFontClose(xw.dpy, frc[frccur].font);
 | 
			
		||||
			}
 | 
			
		||||
 | 
			
		||||
			frc[frccur].font = XftFontOpenPattern(xw.dpy,
 | 
			
		||||
					fontpattern);
 | 
			
		||||
			frc[frccur].c = u8char;
 | 
			
		||||
			frc[frccur].flags = frcflags;
 | 
			
		||||
 | 
			
		||||
			FcPatternDestroy(fcpattern);
 | 
			
		||||
			FcCharSetDestroy(fccharset);
 | 
			
		||||
 | 
			
		||||
			frp = frccur;
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		XftDrawStringUtf8(xw.draw, fg, frc[frp].font,
 | 
			
		||||
				xp, winy + frc[frp].font->ascent,
 | 
			
		||||
				(FcChar8 *)u8c, u8cblen);
 | 
			
		||||
 | 
			
		||||
		xp += font->width;
 | 
			
		||||
	}
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user