diff options
-rw-r--r-- | config.def.h | 2 | ||||
-rw-r--r-- | config.mk | 2 | ||||
-rw-r--r-- | st.c | 96 |
3 files changed, 69 insertions, 31 deletions
diff --git a/config.def.h b/config.def.h index 3e6667a..9c64948 100644 --- a/config.def.h +++ b/config.def.h | |||
@@ -1,5 +1,5 @@ | |||
1 | 1 | ||
2 | #define FONT "Liberation Mono:pixelsize=12:antialias=true:autohint=true" | 2 | #define FONT "Liberation Mono:pixelsize=12:antialias=true:autohint=false" |
3 | 3 | ||
4 | /* Space in pixels around the terminal buffer */ | 4 | /* Space in pixels around the terminal buffer */ |
5 | #define BORDER 2 | 5 | #define BORDER 2 |
@@ -12,7 +12,7 @@ X11LIB = /usr/X11R6/lib | |||
12 | 12 | ||
13 | # includes and libs | 13 | # includes and libs |
14 | INCS = -I. -I/usr/include -I${X11INC} -I/usr/include/freetype2 | 14 | INCS = -I. -I/usr/include -I${X11INC} -I/usr/include/freetype2 |
15 | LIBS = -L/usr/lib -lc -L${X11LIB} -lX11 -lutil -lXext -lXft | 15 | LIBS = -L/usr/lib -lc -L${X11LIB} -lX11 -lutil -lXext -lXft -lfontconfig |
16 | 16 | ||
17 | # flags | 17 | # flags |
18 | CPPFLAGS = -DVERSION=\"${VERSION}\" | 18 | CPPFLAGS = -DVERSION=\"${VERSION}\" |
@@ -26,6 +26,7 @@ | |||
26 | #include <X11/keysym.h> | 26 | #include <X11/keysym.h> |
27 | #include <X11/extensions/Xdbe.h> | 27 | #include <X11/extensions/Xdbe.h> |
28 | #include <X11/Xft/Xft.h> | 28 | #include <X11/Xft/Xft.h> |
29 | #include <fontconfig/fontconfig.h> | ||
29 | #define Glyph Glyph_ | 30 | #define Glyph Glyph_ |
30 | #define Font Font_ | 31 | #define Font Font_ |
31 | 32 | ||
@@ -235,6 +236,8 @@ typedef struct { | |||
235 | 236 | ||
236 | /* Font structure */ | 237 | /* Font structure */ |
237 | typedef struct { | 238 | typedef struct { |
239 | int height; | ||
240 | int width; | ||
238 | int ascent; | 241 | int ascent; |
239 | int descent; | 242 | int descent; |
240 | short lbearing; | 243 | short lbearing; |
@@ -1345,7 +1348,7 @@ tsetmode(bool priv, bool set, int *args, int narg) { | |||
1345 | case 1: /* DECCKM -- Cursor key */ | 1348 | case 1: /* DECCKM -- Cursor key */ |
1346 | MODBIT(term.mode, set, MODE_APPKEYPAD); | 1349 | MODBIT(term.mode, set, MODE_APPKEYPAD); |
1347 | break; | 1350 | break; |
1348 | case 5: /* DECSCNM -- Reverve video */ | 1351 | case 5: /* DECSCNM -- Reverse video */ |
1349 | mode = term.mode; | 1352 | mode = term.mode; |
1350 | MODBIT(term.mode, set, MODE_REVERSE); | 1353 | MODBIT(term.mode, set, MODE_REVERSE); |
1351 | if(mode != term.mode) | 1354 | if(mode != term.mode) |
@@ -1965,8 +1968,8 @@ xloadcols(void) { | |||
1965 | } | 1968 | } |
1966 | 1969 | ||
1967 | /* load colors [16-255] ; same colors as xterm */ | 1970 | /* load colors [16-255] ; same colors as xterm */ |
1968 | for(i = 16, r = 0; r < 6; r++) | 1971 | for(i = 16, r = 0; r < 6; r++) { |
1969 | for(g = 0; g < 6; g++) | 1972 | for(g = 0; g < 6; g++) { |
1970 | for(b = 0; b < 6; b++) { | 1973 | for(b = 0; b < 6; b++) { |
1971 | xft_color.red = r == 0 ? 0 : 0x3737 + 0x2828 * r; | 1974 | xft_color.red = r == 0 ? 0 : 0x3737 + 0x2828 * r; |
1972 | xft_color.green = g == 0 ? 0 : 0x3737 + 0x2828 * g; | 1975 | xft_color.green = g == 0 ? 0 : 0x3737 + 0x2828 * g; |
@@ -1976,12 +1979,13 @@ xloadcols(void) { | |||
1976 | } | 1979 | } |
1977 | i++; | 1980 | i++; |
1978 | } | 1981 | } |
1982 | } | ||
1983 | } | ||
1979 | 1984 | ||
1980 | for(r = 0; r < 24; r++, i++) { | 1985 | for(r = 0; r < 24; r++, i++) { |
1981 | xft_color.red = xft_color.green = xft_color.blue = 0x0808 + 0x0a0a * r; | 1986 | xft_color.red = xft_color.green = xft_color.blue = 0x0808 + 0x0a0a * r; |
1982 | if(!XftColorAllocValue(xw.dpy, xw.vis, xw.cmap, &xft_color, &dc.xft_col[i])) { | 1987 | if(!XftColorAllocValue(xw.dpy, xw.vis, xw.cmap, &xft_color, &dc.xft_col[i])) { |
1983 | dc.xft_col[i] = dc.xft_col[256]; | 1988 | die("Could not allocate color %d\n", i); |
1984 | fprintf(stderr, "Could not allocate color %d\n", i); | ||
1985 | } | 1989 | } |
1986 | } | 1990 | } |
1987 | } | 1991 | } |
@@ -2045,15 +2049,29 @@ xhints(void) { | |||
2045 | 2049 | ||
2046 | void | 2050 | void |
2047 | xinitfont(Font *f, char *fontstr) { | 2051 | xinitfont(Font *f, char *fontstr) { |
2048 | f->xft_set = XftFontOpenName(xw.dpy, xw.scr, fontstr); | 2052 | FcPattern *pattern, *match; |
2049 | 2053 | FcResult result; | |
2050 | if(!f->xft_set) | 2054 | |
2055 | pattern = FcNameParse((FcChar8 *)fontstr); | ||
2056 | if(!pattern) | ||
2057 | die("st: can't open font %s\n", fontstr); | ||
2058 | |||
2059 | match = XftFontMatch(xw.dpy, xw.scr, pattern, &result); | ||
2060 | FcPatternDestroy(pattern); | ||
2061 | if(!match) | ||
2062 | die("st: can't open font %s\n", fontstr); | ||
2063 | if(!(f->xft_set = XftFontOpenPattern(xw.dpy, match))) { | ||
2064 | FcPatternDestroy(match); | ||
2051 | die("st: can't open font %s.\n", fontstr); | 2065 | die("st: can't open font %s.\n", fontstr); |
2066 | } | ||
2052 | 2067 | ||
2053 | f->ascent = f->xft_set->ascent; | 2068 | f->ascent = f->xft_set->ascent; |
2054 | f->descent = f->xft_set->descent; | 2069 | f->descent = f->xft_set->descent; |
2055 | f->lbearing = 0; | 2070 | f->lbearing = 0; |
2056 | f->rbearing = f->xft_set->max_advance_width; | 2071 | f->rbearing = f->xft_set->max_advance_width; |
2072 | |||
2073 | f->height = f->xft_set->height; | ||
2074 | f->width = f->lbearing + f->rbearing; | ||
2057 | } | 2075 | } |
2058 | 2076 | ||
2059 | void | 2077 | void |
@@ -2061,6 +2079,8 @@ initfonts(char *fontstr) { | |||
2061 | char *fstr; | 2079 | char *fstr; |
2062 | 2080 | ||
2063 | xinitfont(&dc.font, fontstr); | 2081 | xinitfont(&dc.font, fontstr); |
2082 | xw.cw = dc.font.width; | ||
2083 | xw.ch = dc.font.height; | ||
2064 | 2084 | ||
2065 | fstr = smstrcat(fontstr, ":weight=bold", NULL); | 2085 | fstr = smstrcat(fontstr, ":weight=bold", NULL); |
2066 | xinitfont(&dc.bfont, fstr); | 2086 | xinitfont(&dc.bfont, fstr); |
@@ -2090,10 +2110,6 @@ xinit(void) { | |||
2090 | /* font */ | 2110 | /* font */ |
2091 | initfonts((opt_font != NULL)? opt_font : FONT); | 2111 | initfonts((opt_font != NULL)? opt_font : FONT); |
2092 | 2112 | ||
2093 | /* XXX: Assuming same size for bold font */ | ||
2094 | xw.cw = dc.font.rbearing - dc.font.lbearing; | ||
2095 | xw.ch = dc.font.ascent + dc.font.descent; | ||
2096 | |||
2097 | /* colors */ | 2113 | /* colors */ |
2098 | xw.cmap = XDefaultColormap(xw.dpy, xw.scr); | 2114 | xw.cmap = XDefaultColormap(xw.dpy, xw.scr); |
2099 | xloadcols(); | 2115 | xloadcols(); |
@@ -2166,37 +2182,59 @@ xinit(void) { | |||
2166 | 2182 | ||
2167 | void | 2183 | void |
2168 | xdraws(char *s, Glyph base, int x, int y, int charlen, int bytelen) { | 2184 | xdraws(char *s, Glyph base, int x, int y, int charlen, int bytelen) { |
2169 | int fg = base.fg, bg = base.bg, temp; | 2185 | int winx = BORDER+x*xw.cw, winy = BORDER+y*xw.ch, |
2170 | int winx = BORDER+x*xw.cw, winy = BORDER+y*xw.ch + dc.font.ascent, width = charlen*xw.cw; | 2186 | width = charlen*xw.cw; |
2171 | Font *font = &dc.font; | 2187 | Font *font = &dc.font; |
2172 | XGlyphInfo extents; | 2188 | XGlyphInfo extents; |
2173 | 2189 | XftColor *fg = &dc.xft_col[base.fg], *bg = &dc.xft_col[base.bg], | |
2174 | /* only switch default fg/bg if term is in RV mode */ | 2190 | *temp, revfg, revbg; |
2175 | if(IS_SET(MODE_REVERSE)) { | 2191 | XRenderColor colfg, colbg; |
2176 | if(fg == DefaultFG) | ||
2177 | fg = DefaultBG; | ||
2178 | if(bg == DefaultBG) | ||
2179 | bg = DefaultFG; | ||
2180 | } | ||
2181 | 2192 | ||
2182 | if(base.mode & ATTR_REVERSE) | 2193 | if(base.mode & ATTR_REVERSE) |
2183 | temp = fg, fg = bg, bg = temp; | 2194 | temp = fg, fg = bg, bg = temp; |
2184 | 2195 | if(base.mode & ATTR_BOLD) { | |
2185 | if(base.mode & ATTR_BOLD) | 2196 | fg = &dc.xft_col[base.fg + 8]; |
2186 | font = &dc.bfont; | 2197 | font = &dc.bfont; |
2187 | 2198 | } | |
2188 | if(base.mode & ATTR_ITALIC) | 2199 | if(base.mode & ATTR_ITALIC) |
2189 | font = &dc.ifont; | 2200 | font = &dc.ifont; |
2190 | if(base.mode & (ATTR_ITALIC|ATTR_ITALIC)) | 2201 | if(base.mode & (ATTR_ITALIC|ATTR_ITALIC)) |
2191 | font = &dc.ibfont; | 2202 | font = &dc.ibfont; |
2192 | 2203 | ||
2193 | XftTextExtentsUtf8(xw.dpy, font->xft_set, (FcChar8 *)s, bytelen, &extents); | 2204 | if(IS_SET(MODE_REVERSE)) { |
2205 | if(fg == &dc.xft_col[DefaultFG]) { | ||
2206 | fg = &dc.xft_col[DefaultBG]; | ||
2207 | } else { | ||
2208 | colfg.red = ~fg->color.red; | ||
2209 | colfg.green = ~fg->color.green; | ||
2210 | colfg.blue = ~fg->color.blue; | ||
2211 | colfg.alpha = fg->color.alpha; | ||
2212 | XftColorAllocValue(xw.dpy, xw.vis, xw.cmap, &colfg, &revfg); | ||
2213 | fg = &revfg; | ||
2214 | } | ||
2215 | |||
2216 | if(bg == &dc.xft_col[DefaultBG]) { | ||
2217 | bg = &dc.xft_col[DefaultFG]; | ||
2218 | } else { | ||
2219 | colbg.red = ~bg->color.red; | ||
2220 | colbg.green = ~bg->color.green; | ||
2221 | colbg.blue = ~bg->color.blue; | ||
2222 | colbg.alpha = bg->color.alpha; | ||
2223 | XftColorAllocValue(xw.dpy, xw.vis, xw.cmap, &colbg, &revbg); | ||
2224 | bg = &revbg; | ||
2225 | } | ||
2226 | } | ||
2227 | |||
2228 | XftTextExtentsUtf8(xw.dpy, font->xft_set, (FcChar8 *)s, bytelen, | ||
2229 | &extents); | ||
2194 | width = extents.xOff; | 2230 | width = extents.xOff; |
2195 | XftDrawRect(xw.xft_draw, &dc.xft_col[bg], winx, winy - font->ascent, width, xw.ch); | 2231 | |
2196 | XftDrawStringUtf8(xw.xft_draw, &dc.xft_col[fg], font->xft_set, winx, winy, (FcChar8 *)s, bytelen); | 2232 | XftDrawRect(xw.xft_draw, bg, winx, winy, width, xw.ch); |
2233 | XftDrawStringUtf8(xw.xft_draw, fg, font->xft_set, winx, | ||
2234 | winy + font->ascent, (FcChar8 *)s, bytelen); | ||
2197 | 2235 | ||
2198 | if(base.mode & ATTR_UNDERLINE) { | 2236 | if(base.mode & ATTR_UNDERLINE) { |
2199 | XftDrawRect(xw.xft_draw, &dc.xft_col[fg], winx, winy+1, | 2237 | XftDrawRect(xw.xft_draw, fg, winx, winy+1, |
2200 | width, 1); | 2238 | width, 1); |
2201 | } | 2239 | } |
2202 | } | 2240 | } |