diff options
| author | Christoph Lohmann <20h@r-36.net> | 2012-12-29 15:03:03 +0100 | 
|---|---|---|
| committer | Christoph Lohmann <20h@r-36.net> | 2012-12-29 15:03:03 +0100 | 
| commit | addc84834506e24387c1fb70b5d33b3f2ba55b66 (patch) | |
| tree | 21b7dcb00e2e11e17ae638c91c7c2ceddf2c9512 | |
| parent | 9c44229c626ea7351a7809540435f40cffb624bc (diff) | |
| download | st-addc84834506e24387c1fb70b5d33b3f2ba55b66.tar.xz st-addc84834506e24387c1fb70b5d33b3f2ba55b66.zip  | |
Speeding up the drawing, then all characters are known.
| -rw-r--r-- | st.c | 176 | 
1 files changed, 99 insertions, 77 deletions
@@ -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; + +			doesexist = XftCharIndex(xw.dpy, font->match, u8char); +			if (!doesexist || bytelen <= 0) { +				if (bytelen <= 0) { +					if (doesexist) { +						u8fl++; +						u8fblen += u8cblen; +					} +				} -				if (frc[frp].c == u8char -					&& frc[frp].flags == frcflags) { -					break; +				if (u8fl > 0) { +					XftDrawStringUtf8(xw.draw, fg, +							font->match, xp, +							winy + font->ascent, +							(FcChar8 *)u8fs, +							u8fblen); +					xp += font->width * u8fl;  				} +				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; +			u8fl++; +			u8fblen += u8cblen; +		} +		if (doesexist) +			break; -				FcPatternDestroy(fcpattern); -				FcCharSetDestroy(fccharset); +		frp = frccur; +		/* Search the font cache. */ +		for (i = 0; i < frclen; i++, frp--) { +			if (frp <= 0) +				frp = LEN(frc) - 1; -				frp = frccur; +			if (frc[frp].c == u8char +					&& frc[frp].flags == frcflags) { +				break;  			} -			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;  	}  | 
