Change internal character representation.
This commit is contained in:
		
							parent
							
								
									753fe862b1
								
							
						
					
					
						commit
						21f765426c
					
				
							
								
								
									
										73
									
								
								st.c
									
									
									
									
									
								
							
							
						
						
									
										73
									
								
								st.c
									
									
									
									
									
								
							| @ -72,6 +72,7 @@ char *argv0; | |||||||
| #define ISCONTROLC0(c) (BETWEEN(c, 0, 0x1f) || (c) == '\177') | #define ISCONTROLC0(c) (BETWEEN(c, 0, 0x1f) || (c) == '\177') | ||||||
| #define ISCONTROLC1(c) (BETWEEN(c, 0x80, 0x9f)) | #define ISCONTROLC1(c) (BETWEEN(c, 0x80, 0x9f)) | ||||||
| #define ISCONTROL(c) (ISCONTROLC0(c) || ISCONTROLC1(c)) | #define ISCONTROL(c) (ISCONTROLC0(c) || ISCONTROLC1(c)) | ||||||
|  | #define ISDELIM(u) (BETWEEN(u, 0, 127) && strchr(worddelimiters, u) != NULL) | ||||||
| #define LIMIT(x, a, b)    (x) = (x) < (a) ? (a) : (x) > (b) ? (b) : (x) | #define LIMIT(x, a, b)    (x) = (x) < (a) ? (a) : (x) > (b) ? (b) : (x) | ||||||
| #define ATTRCMP(a, b) ((a).mode != (b).mode || (a).fg != (b).fg || (a).bg != (b).bg) | #define ATTRCMP(a, b) ((a).mode != (b).mode || (a).fg != (b).fg || (a).bg != (b).bg) | ||||||
| #define IS_SET(flag) ((term.mode & (flag)) != 0) | #define IS_SET(flag) ((term.mode & (flag)) != 0) | ||||||
| @ -180,7 +181,7 @@ typedef XftDraw *Draw; | |||||||
| typedef XftColor Color; | typedef XftColor Color; | ||||||
| 
 | 
 | ||||||
| typedef struct { | typedef struct { | ||||||
| 	char c[UTF_SIZ]; /* character code */ | 	long u;           /* character code */ | ||||||
| 	ushort mode;      /* attribute flags */ | 	ushort mode;      /* attribute flags */ | ||||||
| 	uint32_t fg;      /* foreground  */ | 	uint32_t fg;      /* foreground  */ | ||||||
| 	uint32_t bg;      /* background  */ | 	uint32_t bg;      /* background  */ | ||||||
| @ -410,6 +411,7 @@ static void tstrsequence(uchar); | |||||||
| 
 | 
 | ||||||
| static inline ushort sixd_to_16bit(int); | static inline ushort sixd_to_16bit(int); | ||||||
| static void xdraws(char *, Glyph, int, int, int, int); | static void xdraws(char *, Glyph, int, int, int, int); | ||||||
|  | static void xdrawglyph(Glyph, int, int); | ||||||
| static void xhints(void); | static void xhints(void); | ||||||
| static void xclear(int, int, int, int); | static void xclear(int, int, int, int); | ||||||
| static void xdrawcursor(void); | static void xdrawcursor(void); | ||||||
| @ -461,7 +463,6 @@ static size_t utf8decode(char *, long *, size_t); | |||||||
| static long utf8decodebyte(char, size_t *); | static long utf8decodebyte(char, size_t *); | ||||||
| static size_t utf8encode(long, char *); | static size_t utf8encode(long, char *); | ||||||
| static char utf8encodebyte(long, size_t); | static char utf8encodebyte(long, size_t); | ||||||
| static size_t utf8len(char *); |  | ||||||
| static size_t utf8validate(long *, size_t); | static size_t utf8validate(long *, size_t); | ||||||
| 
 | 
 | ||||||
| static ssize_t xwrite(int, const char *, size_t); | static ssize_t xwrite(int, const char *, size_t); | ||||||
| @ -629,11 +630,6 @@ utf8encodebyte(long u, size_t i) { | |||||||
| 	return utfbyte[i] | (u & ~utfmask[i]); | 	return utfbyte[i] | (u & ~utfmask[i]); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| size_t |  | ||||||
| utf8len(char *c) { |  | ||||||
| 	return utf8decode(c, &(long){0}, UTF_SIZ); |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| size_t | size_t | ||||||
| utf8validate(long *u, size_t i) { | utf8validate(long *u, size_t i) { | ||||||
| 	if(!BETWEEN(*u, utfmin[i], utfmax[i]) || BETWEEN(*u, 0xD800, 0xDFFF)) | 	if(!BETWEEN(*u, utfmin[i], utfmax[i]) || BETWEEN(*u, 0xD800, 0xDFFF)) | ||||||
| @ -679,7 +675,7 @@ tlinelen(int y) { | |||||||
| 	if(term.line[y][i - 1].mode & ATTR_WRAP) | 	if(term.line[y][i - 1].mode & ATTR_WRAP) | ||||||
| 		return i; | 		return i; | ||||||
| 
 | 
 | ||||||
| 	while(i > 0 && term.line[y][i - 1].c[0] == ' ') | 	while(i > 0 && term.line[y][i - 1].u == ' ') | ||||||
| 		--i; | 		--i; | ||||||
| 
 | 
 | ||||||
| 	return i; | 	return i; | ||||||
| @ -736,7 +732,7 @@ selsnap(int mode, int *x, int *y, int direction) { | |||||||
| 		 * beginning of a line. | 		 * beginning of a line. | ||||||
| 		 */ | 		 */ | ||||||
| 		prevgp = &term.line[*y][*x]; | 		prevgp = &term.line[*y][*x]; | ||||||
| 		prevdelim = strchr(worddelimiters, prevgp->c[0]) != NULL; | 		prevdelim = ISDELIM(prevgp->u); | ||||||
| 		for(;;) { | 		for(;;) { | ||||||
| 			newx = *x + direction; | 			newx = *x + direction; | ||||||
| 			newy = *y; | 			newy = *y; | ||||||
| @ -758,9 +754,9 @@ selsnap(int mode, int *x, int *y, int direction) { | |||||||
| 				break; | 				break; | ||||||
| 
 | 
 | ||||||
| 			gp = &term.line[newy][newx]; | 			gp = &term.line[newy][newx]; | ||||||
| 			delim = strchr(worddelimiters, gp->c[0]) != NULL; | 			delim = ISDELIM(gp->u); | ||||||
| 			if(!(gp->mode & ATTR_WDUMMY) && (delim != prevdelim | 			if(!(gp->mode & ATTR_WDUMMY) && (delim != prevdelim | ||||||
| 					|| (delim && gp->c[0] != prevgp->c[0]))) | 					|| (delim && gp->u != prevgp->u))) | ||||||
| 				break; | 				break; | ||||||
| 
 | 
 | ||||||
| 			*x = newx; | 			*x = newx; | ||||||
| @ -936,7 +932,7 @@ bpress(XEvent *e) { | |||||||
| char * | char * | ||||||
| getsel(void) { | getsel(void) { | ||||||
| 	char *str, *ptr; | 	char *str, *ptr; | ||||||
| 	int y, bufsize, size, lastx, linelen; | 	int y, bufsize, lastx, linelen; | ||||||
| 	Glyph *gp, *last; | 	Glyph *gp, *last; | ||||||
| 
 | 
 | ||||||
| 	if(sel.ob.x == -1) | 	if(sel.ob.x == -1) | ||||||
| @ -957,16 +953,14 @@ getsel(void) { | |||||||
| 			lastx = (sel.ne.y == y) ? sel.ne.x : term.col-1; | 			lastx = (sel.ne.y == y) ? sel.ne.x : term.col-1; | ||||||
| 		} | 		} | ||||||
| 		last = &term.line[y][MIN(lastx, linelen-1)]; | 		last = &term.line[y][MIN(lastx, linelen-1)]; | ||||||
| 		while(last >= gp && last->c[0] == ' ') | 		while(last >= gp && last->u == ' ') | ||||||
| 			--last; | 			--last; | ||||||
| 
 | 
 | ||||||
| 		for( ; gp <= last; ++gp) { | 		for( ; gp <= last; ++gp) { | ||||||
| 			if(gp->mode & ATTR_WDUMMY) | 			if(gp->mode & ATTR_WDUMMY) | ||||||
| 				continue; | 				continue; | ||||||
| 
 | 
 | ||||||
| 			size = utf8len(gp->c); | 			ptr += utf8encode(gp->u, ptr); | ||||||
| 			memcpy(ptr, gp->c, size); |  | ||||||
| 			ptr += size; |  | ||||||
| 		} | 		} | ||||||
| 
 | 
 | ||||||
| 		/*
 | 		/*
 | ||||||
| @ -1643,17 +1637,17 @@ tsetchar(char *c, Glyph *attr, int x, int y) { | |||||||
| 
 | 
 | ||||||
| 	if(term.line[y][x].mode & ATTR_WIDE) { | 	if(term.line[y][x].mode & ATTR_WIDE) { | ||||||
| 		if(x+1 < term.col) { | 		if(x+1 < term.col) { | ||||||
| 			term.line[y][x+1].c[0] = ' '; | 			term.line[y][x+1].u = ' '; | ||||||
| 			term.line[y][x+1].mode &= ~ATTR_WDUMMY; | 			term.line[y][x+1].mode &= ~ATTR_WDUMMY; | ||||||
| 		} | 		} | ||||||
| 	} else if(term.line[y][x].mode & ATTR_WDUMMY) { | 	} else if(term.line[y][x].mode & ATTR_WDUMMY) { | ||||||
| 		term.line[y][x-1].c[0] = ' '; | 		term.line[y][x-1].u = ' '; | ||||||
| 		term.line[y][x-1].mode &= ~ATTR_WIDE; | 		term.line[y][x-1].mode &= ~ATTR_WIDE; | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	term.dirty[y] = 1; | 	term.dirty[y] = 1; | ||||||
| 	term.line[y][x] = *attr; | 	term.line[y][x] = *attr; | ||||||
| 	memcpy(term.line[y][x].c, c, UTF_SIZ); | 	utf8decode(c, &term.line[y][x].u, UTF_SIZ); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| void | void | ||||||
| @ -1680,7 +1674,7 @@ tclearregion(int x1, int y1, int x2, int y2) { | |||||||
| 			gp->fg = term.c.attr.fg; | 			gp->fg = term.c.attr.fg; | ||||||
| 			gp->bg = term.c.attr.bg; | 			gp->bg = term.c.attr.bg; | ||||||
| 			gp->mode = 0; | 			gp->mode = 0; | ||||||
| 			memcpy(gp->c, " ", 2); | 			gp->u = ' '; | ||||||
| 		} | 		} | ||||||
| 	} | 	} | ||||||
| } | } | ||||||
| @ -2400,13 +2394,14 @@ tdumpsel(void) { | |||||||
| 
 | 
 | ||||||
| void | void | ||||||
| tdumpline(int n) { | tdumpline(int n) { | ||||||
|  | 	char buf[UTF_SIZ]; | ||||||
| 	Glyph *bp, *end; | 	Glyph *bp, *end; | ||||||
| 
 | 
 | ||||||
| 	bp = &term.line[n][0]; | 	bp = &term.line[n][0]; | ||||||
| 	end = &bp[MIN(tlinelen(n), term.col) - 1]; | 	end = &bp[MIN(tlinelen(n), term.col) - 1]; | ||||||
| 	if(bp != end || bp->c[0] != ' ') { | 	if(bp != end || bp->u != ' ') { | ||||||
| 		for( ;bp <= end; ++bp) | 		for( ;bp <= end; ++bp) | ||||||
| 			tprinter(bp->c, utf8len(bp->c)); | 			tprinter(buf, utf8encode(bp->u, buf)); | ||||||
| 	} | 	} | ||||||
| 	tprinter("\n", 1); | 	tprinter("\n", 1); | ||||||
| } | } | ||||||
| @ -2789,7 +2784,7 @@ tputc(char *c, int len) { | |||||||
| 	if(width == 2) { | 	if(width == 2) { | ||||||
| 		gp->mode |= ATTR_WIDE; | 		gp->mode |= ATTR_WIDE; | ||||||
| 		if(term.c.x+1 < term.col) { | 		if(term.c.x+1 < term.col) { | ||||||
| 			gp[1].c[0] = '\0'; | 			gp[1].u = '\0'; | ||||||
| 			gp[1].mode = ATTR_WDUMMY; | 			gp[1].mode = ATTR_WDUMMY; | ||||||
| 		} | 		} | ||||||
| 	} | 	} | ||||||
| @ -3552,11 +3547,20 @@ xdraws(char *s, Glyph base, int x, int y, int charlen, int bytelen) { | |||||||
| 	XftDrawSetClip(xw.draw, 0); | 	XftDrawSetClip(xw.draw, 0); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | void | ||||||
|  | xdrawglyph(Glyph g, int x, int y) { | ||||||
|  | 	static char buf[UTF_SIZ]; | ||||||
|  | 	size_t len = utf8encode(g.u, buf); | ||||||
|  | 	int width = g.mode & ATTR_WIDE ? 2 : 1; | ||||||
|  | 
 | ||||||
|  | 	xdraws(buf, g, x, y, width, len); | ||||||
|  | } | ||||||
|  | 
 | ||||||
| void | void | ||||||
| xdrawcursor(void) { | xdrawcursor(void) { | ||||||
| 	static int oldx = 0, oldy = 0; | 	static int oldx = 0, oldy = 0; | ||||||
| 	int sl, width, curx; | 	int curx; | ||||||
| 	Glyph g = {{' '}, ATTR_NULL, defaultbg, defaultcs}; | 	Glyph g = {' ', ATTR_NULL, defaultbg, defaultcs}; | ||||||
| 
 | 
 | ||||||
| 	LIMIT(oldx, 0, term.col-1); | 	LIMIT(oldx, 0, term.col-1); | ||||||
| 	LIMIT(oldy, 0, term.row-1); | 	LIMIT(oldy, 0, term.row-1); | ||||||
| @ -3569,13 +3573,10 @@ xdrawcursor(void) { | |||||||
| 	if(term.line[term.c.y][curx].mode & ATTR_WDUMMY) | 	if(term.line[term.c.y][curx].mode & ATTR_WDUMMY) | ||||||
| 		curx--; | 		curx--; | ||||||
| 
 | 
 | ||||||
| 	memcpy(g.c, term.line[term.c.y][term.c.x].c, UTF_SIZ); | 	g.u = term.line[term.c.y][term.c.x].u; | ||||||
| 
 | 
 | ||||||
| 	/* remove the old cursor */ | 	/* remove the old cursor */ | ||||||
| 	sl = utf8len(term.line[oldy][oldx].c); | 	xdrawglyph(term.line[oldy][oldx], oldx, oldy); | ||||||
| 	width = (term.line[oldy][oldx].mode & ATTR_WIDE)? 2 : 1; |  | ||||||
| 	xdraws(term.line[oldy][oldx].c, term.line[oldy][oldx], oldx, |  | ||||||
| 			oldy, width, sl); |  | ||||||
| 
 | 
 | ||||||
| 	if(IS_SET(MODE_HIDE)) | 	if(IS_SET(MODE_HIDE)) | ||||||
| 		return; | 		return; | ||||||
| @ -3592,10 +3593,8 @@ xdrawcursor(void) { | |||||||
| 						g.bg = defaultfg; | 						g.bg = defaultfg; | ||||||
| 					} | 					} | ||||||
| 
 | 
 | ||||||
| 				sl = utf8len(g.c); | 				g.mode |= term.line[term.c.y][curx].mode & ATTR_WIDE; | ||||||
| 				width = (term.line[term.c.y][curx].mode & ATTR_WIDE)\ | 				xdrawglyph(g, term.c.x, term.c.y); | ||||||
| 					? 2 : 1; |  | ||||||
| 				xdraws(g.c, g, term.c.x, term.c.y, width, sl); |  | ||||||
| 				break; | 				break; | ||||||
| 			case 3: /* Blinking Underline */ | 			case 3: /* Blinking Underline */ | ||||||
| 			case 4: /* Steady Underline */ | 			case 4: /* Steady Underline */ | ||||||
| @ -3668,7 +3667,7 @@ draw(void) { | |||||||
| 
 | 
 | ||||||
| void | void | ||||||
| drawregion(int x1, int y1, int x2, int y2) { | drawregion(int x1, int y1, int x2, int y2) { | ||||||
| 	int ic, ib, x, y, ox, sl; | 	int ic, ib, x, y, ox; | ||||||
| 	Glyph base, new; | 	Glyph base, new; | ||||||
| 	char buf[DRAW_BUF_SIZ]; | 	char buf[DRAW_BUF_SIZ]; | ||||||
| 	bool ena_sel = sel.ob.x != -1 && sel.alt == IS_SET(MODE_ALTSCREEN); | 	bool ena_sel = sel.ob.x != -1 && sel.alt == IS_SET(MODE_ALTSCREEN); | ||||||
| @ -3700,9 +3699,7 @@ drawregion(int x1, int y1, int x2, int y2) { | |||||||
| 				base = new; | 				base = new; | ||||||
| 			} | 			} | ||||||
| 
 | 
 | ||||||
| 			sl = utf8len(new.c); | 			ib += utf8encode(new.u, buf+ib); | ||||||
| 			memcpy(buf+ib, new.c, sl); |  | ||||||
| 			ib += sl; |  | ||||||
| 			ic += (new.mode & ATTR_WIDE)? 2 : 1; | 			ic += (new.mode & ATTR_WIDE)? 2 : 1; | ||||||
| 		} | 		} | ||||||
| 		if(ib > 0) | 		if(ib > 0) | ||||||
|  | |||||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user
	 noname@inventati.org
						noname@inventati.org