aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--config.def.h9
-rw-r--r--config.mk4
-rw-r--r--st.c130
3 files changed, 65 insertions, 78 deletions
diff --git a/config.def.h b/config.def.h
index 7746eaf..5cb1fd2 100644
--- a/config.def.h
+++ b/config.def.h
@@ -1,9 +1,8 @@
1 1
2#define FONT "-*-*-medium-r-*-*-*-120-75-75-*-70-*-*" 2#define FONT "Bitstream Vera Sans Mono:pixelsize=12:antialias=false:autohint=true"
3#define BOLDFONT "-*-*-bold-r-*-*-*-120-75-75-*-70-*-*" 3#define BOLDFONT FONT ":weight=bold"
4/* If italic is not available, fall back to bold. */ 4#define ITALICFONT FONT ":slant=italic,oblique"
5#define ITALICFONT "-*-*-medium-o-*-*-*-120-75-75-*-70-*-*," BOLDFONT 5#define ITALICBOLDFONT BOLDFONT ":slant=italic,oblique"
6#define ITALICBOLDFONT "-*-*-bold-o-*-*-*-120-75-75-*-70-*-*," BOLDFONT
7 6
8/* Space in pixels around the terminal buffer */ 7/* Space in pixels around the terminal buffer */
9#define BORDER 2 8#define BORDER 2
diff --git a/config.mk b/config.mk
index 4f273cd..f57afa2 100644
--- a/config.mk
+++ b/config.mk
@@ -11,8 +11,8 @@ X11INC = /usr/X11R6/include
11X11LIB = /usr/X11R6/lib 11X11LIB = /usr/X11R6/lib
12 12
13# includes and libs 13# includes and libs
14INCS = -I. -I/usr/include -I${X11INC} 14INCS = -I. -I/usr/include -I${X11INC} -I/usr/include/freetype2
15LIBS = -L/usr/lib -lc -L${X11LIB} -lX11 -lutil -lXext 15LIBS = -L/usr/lib -lc -L${X11LIB} -lX11 -lutil -lXext -lXft
16 16
17# flags 17# flags
18CPPFLAGS = -DVERSION=\"${VERSION}\" 18CPPFLAGS = -DVERSION=\"${VERSION}\"
diff --git a/st.c b/st.c
index 89c59b4..f7fecf8 100644
--- a/st.c
+++ b/st.c
@@ -25,6 +25,9 @@
25#include <X11/cursorfont.h> 25#include <X11/cursorfont.h>
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>
29#define Glyph Glyph_
30#define Font Font_
28 31
29#if defined(__linux) 32#if defined(__linux)
30 #include <pty.h> 33 #include <pty.h>
@@ -195,6 +198,8 @@ typedef struct {
195 Atom xembed; 198 Atom xembed;
196 XIM xim; 199 XIM xim;
197 XIC xic; 200 XIC xic;
201 XftDraw *xft_draw;
202 Visual *vis;
198 int scr; 203 int scr;
199 Bool isfixed; /* is fixed geometry? */ 204 Bool isfixed; /* is fixed geometry? */
200 int fx, fy, fw, fh; /* fixed geometry */ 205 int fx, fy, fw, fh; /* fixed geometry */
@@ -212,7 +217,6 @@ typedef struct {
212 char s[ESC_BUF_SIZ]; 217 char s[ESC_BUF_SIZ];
213} Key; 218} Key;
214 219
215
216/* TODO: use better name for vars... */ 220/* TODO: use better name for vars... */
217typedef struct { 221typedef struct {
218 int mode; 222 int mode;
@@ -228,17 +232,22 @@ typedef struct {
228 232
229#include "config.h" 233#include "config.h"
230 234
235/* Font structure */
236typedef struct {
237 int ascent;
238 int descent;
239 short lbearing;
240 short rbearing;
241 XFontSet set;
242 XftFont* xft_set;
243} Font;
244
231/* Drawing Context */ 245/* Drawing Context */
232typedef struct { 246typedef struct {
233 ulong col[LEN(colorname) < 256 ? 256 : LEN(colorname)]; 247 ulong col[LEN(colorname) < 256 ? 256 : LEN(colorname)];
248 XftColor xft_col[LEN(colorname) < 256 ? 256 : LEN(colorname)];
234 GC gc; 249 GC gc;
235 struct { 250 Font font, bfont, ifont, ibfont;
236 int ascent;
237 int descent;
238 short lbearing;
239 short rbearing;
240 XFontSet set;
241 } font, bfont, ifont, ibfont;
242} DC; 251} DC;
243 252
244static void die(const char*, ...); 253static void die(const char*, ...);
@@ -1840,47 +1849,49 @@ void
1840xresize(int col, int row) { 1849xresize(int col, int row) {
1841 xw.tw = MAX(1, 2*BORDER + col * xw.cw); 1850 xw.tw = MAX(1, 2*BORDER + col * xw.cw);
1842 xw.th = MAX(1, 2*BORDER + row * xw.ch); 1851 xw.th = MAX(1, 2*BORDER + row * xw.ch);
1852
1853 XftDrawChange(xw.xft_draw, xw.buf);
1843} 1854}
1844 1855
1845void 1856void
1846xloadcols(void) { 1857xloadcols(void) {
1847 int i, r, g, b; 1858 int i, r, g, b;
1848 XColor color; 1859 XRenderColor xft_color = { .alpha = 0 };
1849 ulong white = WhitePixel(xw.dpy, xw.scr); 1860 ulong white = WhitePixel(xw.dpy, xw.scr);
1850 1861
1851 /* load colors [0-15] colors and [256-LEN(colorname)[ (config.h) */ 1862 /* load colors [0-15] colors and [256-LEN(colorname)[ (config.h) */
1852 for(i = 0; i < LEN(colorname); i++) { 1863 for(i = 0; i < LEN(colorname); i++) {
1853 if(!colorname[i]) 1864 if(!colorname[i])
1854 continue; 1865 continue;
1855 if(!XAllocNamedColor(xw.dpy, xw.cmap, colorname[i], &color, &color)) { 1866 if(!XftColorAllocName(xw.dpy, xw.vis, xw.cmap, colorname[i], &dc.xft_col[i])) {
1856 dc.col[i] = white; 1867 dc.col[i] = white;
1857 fprintf(stderr, "Could not allocate color '%s'\n", colorname[i]); 1868 fprintf(stderr, "Could not allocate color '%s'\n", colorname[i]);
1858 } else 1869 } else
1859 dc.col[i] = color.pixel; 1870 dc.col[i] = dc.xft_col[i].pixel;
1860 } 1871 }
1861 1872
1862 /* load colors [16-255] ; same colors as xterm */ 1873 /* load colors [16-255] ; same colors as xterm */
1863 for(i = 16, r = 0; r < 6; r++) 1874 for(i = 16, r = 0; r < 6; r++)
1864 for(g = 0; g < 6; g++) 1875 for(g = 0; g < 6; g++)
1865 for(b = 0; b < 6; b++) { 1876 for(b = 0; b < 6; b++) {
1866 color.red = r == 0 ? 0 : 0x3737 + 0x2828 * r; 1877 xft_color.red = r == 0 ? 0 : 0x3737 + 0x2828 * r;
1867 color.green = g == 0 ? 0 : 0x3737 + 0x2828 * g; 1878 xft_color.green = g == 0 ? 0 : 0x3737 + 0x2828 * g;
1868 color.blue = b == 0 ? 0 : 0x3737 + 0x2828 * b; 1879 xft_color.blue = b == 0 ? 0 : 0x3737 + 0x2828 * b;
1869 if(!XAllocColor(xw.dpy, xw.cmap, &color)) { 1880 if(!XftColorAllocValue(xw.dpy, xw.vis, xw.cmap, &xft_color, &dc.xft_col[i])) {
1870 dc.col[i] = white; 1881 dc.col[i] = white;
1871 fprintf(stderr, "Could not allocate color %d\n", i); 1882 fprintf(stderr, "Could not allocate color %d\n", i);
1872 } else 1883 } else
1873 dc.col[i] = color.pixel; 1884 dc.col[i] = dc.xft_col[i].pixel;
1874 i++; 1885 i++;
1875 } 1886 }
1876 1887
1877 for(r = 0; r < 24; r++, i++) { 1888 for(r = 0; r < 24; r++, i++) {
1878 color.red = color.green = color.blue = 0x0808 + 0x0a0a * r; 1889 xft_color.red = xft_color.green = xft_color.blue = 0x0808 + 0x0a0a * r;
1879 if(!XAllocColor(xw.dpy, xw.cmap, &color)) { 1890 if(!XftColorAllocValue(xw.dpy, xw.vis, xw.cmap, &xft_color, &dc.xft_col[i])) {
1880 dc.col[i] = white; 1891 dc.col[i] = white;
1881 fprintf(stderr, "Could not allocate color %d\n", i); 1892 fprintf(stderr, "Could not allocate color %d\n", i);
1882 } else 1893 } else
1883 dc.col[i] = color.pixel; 1894 dc.col[i] = dc.xft_col[i].pixel;
1884 } 1895 }
1885} 1896}
1886 1897
@@ -1917,58 +1928,25 @@ xhints(void) {
1917 XFree(sizeh); 1928 XFree(sizeh);
1918} 1929}
1919 1930
1920XFontSet
1921xinitfont(char *fontstr) {
1922 XFontSet set;
1923 char *def, **missing;
1924 int n;
1925
1926 missing = NULL;
1927 set = XCreateFontSet(xw.dpy, fontstr, &missing, &n, &def);
1928 if(missing) {
1929 while(n--)
1930 fprintf(stderr, "st: missing fontset: %s\n", missing[n]);
1931 XFreeStringList(missing);
1932 }
1933 return set;
1934}
1935
1936void 1931void
1937xgetfontinfo(XFontSet set, int *ascent, int *descent, short *lbearing, short *rbearing) { 1932xinitfont(Font *f, char *fontstr) {
1938 XFontStruct **xfonts; 1933 f->xft_set = XftFontOpenName(xw.dpy, xw.scr, fontstr);
1939 char **font_names;
1940 int i, n;
1941 1934
1942 *ascent = *descent = *lbearing = *rbearing = 0; 1935 if(!f->xft_set)
1943 n = XFontsOfFontSet(set, &xfonts, &font_names); 1936 die("st: can't open font %s.\n", fontstr);
1944 for(i = 0; i < n; i++) { 1937
1945 *ascent = MAX(*ascent, (*xfonts)->ascent); 1938 f->ascent = f->xft_set->ascent;
1946 *descent = MAX(*descent, (*xfonts)->descent); 1939 f->descent = f->xft_set->descent;
1947 *lbearing = MAX(*lbearing, (*xfonts)->min_bounds.lbearing); 1940 f->lbearing = 0;
1948 *rbearing = MAX(*rbearing, (*xfonts)->max_bounds.rbearing); 1941 f->rbearing = f->xft_set->max_advance_width;
1949 xfonts++;
1950 }
1951} 1942}
1952 1943
1953void 1944void
1954initfonts(char *fontstr, char *bfontstr, char *ifontstr, char *ibfontstr) { 1945initfonts(char *fontstr, char *bfontstr, char *ifontstr, char *ibfontstr) {
1955 if((dc.font.set = xinitfont(fontstr)) == NULL) 1946 xinitfont(&dc.font, fontstr);
1956 die("Can't load font %s\n", fontstr); 1947 xinitfont(&dc.bfont, bfontstr);
1957 if((dc.bfont.set = xinitfont(bfontstr)) == NULL) 1948 xinitfont(&dc.ifont, ifontstr);
1958 die("Can't load bfont %s\n", bfontstr); 1949 xinitfont(&dc.ibfont, ibfontstr);
1959 if((dc.ifont.set = xinitfont(ifontstr)) == NULL)
1960 die("Can't load ifont %s\n", ifontstr);
1961 if((dc.ibfont.set = xinitfont(ibfontstr)) == NULL)
1962 die("Can't load ibfont %s\n", ibfontstr);
1963
1964 xgetfontinfo(dc.font.set, &dc.font.ascent, &dc.font.descent,
1965 &dc.font.lbearing, &dc.font.rbearing);
1966 xgetfontinfo(dc.bfont.set, &dc.bfont.ascent, &dc.bfont.descent,
1967 &dc.bfont.lbearing, &dc.bfont.rbearing);
1968 xgetfontinfo(dc.ifont.set, &dc.ifont.ascent, &dc.ifont.descent,
1969 &dc.ifont.lbearing, &dc.ifont.rbearing);
1970 xgetfontinfo(dc.ibfont.set, &dc.ibfont.ascent, &dc.ibfont.descent,
1971 &dc.ibfont.lbearing, &dc.ibfont.rbearing);
1972} 1950}
1973 1951
1974void 1952void
@@ -1981,6 +1959,7 @@ xinit(void) {
1981 if(!(xw.dpy = XOpenDisplay(NULL))) 1959 if(!(xw.dpy = XOpenDisplay(NULL)))
1982 die("Can't open display\n"); 1960 die("Can't open display\n");
1983 xw.scr = XDefaultScreen(xw.dpy); 1961 xw.scr = XDefaultScreen(xw.dpy);
1962 xw.vis = XDefaultVisual(xw.dpy, xw.scr);
1984 1963
1985 /* font */ 1964 /* font */
1986 initfonts(FONT, BOLDFONT, ITALICFONT, ITALICBOLDFONT); 1965 initfonts(FONT, BOLDFONT, ITALICFONT, ITALICBOLDFONT);
@@ -2023,14 +2002,19 @@ xinit(void) {
2023 parent = opt_embed ? strtol(opt_embed, NULL, 0) : XRootWindow(xw.dpy, xw.scr); 2002 parent = opt_embed ? strtol(opt_embed, NULL, 0) : XRootWindow(xw.dpy, xw.scr);
2024 xw.win = XCreateWindow(xw.dpy, parent, xw.fx, xw.fy, 2003 xw.win = XCreateWindow(xw.dpy, parent, xw.fx, xw.fy,
2025 xw.w, xw.h, 0, XDefaultDepth(xw.dpy, xw.scr), InputOutput, 2004 xw.w, xw.h, 0, XDefaultDepth(xw.dpy, xw.scr), InputOutput,
2026 XDefaultVisual(xw.dpy, xw.scr), 2005 xw.vis,
2027 CWBackPixel | CWBorderPixel | CWBitGravity | CWEventMask 2006 CWBackPixel | CWBorderPixel | CWBitGravity | CWEventMask
2028 | CWColormap, 2007 | CWColormap,
2029 &attrs); 2008 &attrs);
2009
2010 /* double buffering */
2030 if(!XdbeQueryExtension(xw.dpy, &major, &minor)) 2011 if(!XdbeQueryExtension(xw.dpy, &major, &minor))
2031 die("Xdbe extension is not present\n"); 2012 die("Xdbe extension is not present\n");
2032 xw.buf = XdbeAllocateBackBufferName(xw.dpy, xw.win, XdbeCopied); 2013 xw.buf = XdbeAllocateBackBufferName(xw.dpy, xw.win, XdbeCopied);
2033 2014
2015 /* Xft rendering context */
2016 xw.xft_draw = XftDrawCreate(xw.dpy, xw.buf, xw.vis, xw.cmap);
2017
2034 /* input methods */ 2018 /* input methods */
2035 xw.xim = XOpenIM(xw.dpy, NULL, NULL, NULL); 2019 xw.xim = XOpenIM(xw.dpy, NULL, NULL, NULL);
2036 xw.xic = XCreateIC(xw.xim, XNInputStyle, XIMPreeditNothing 2020 xw.xic = XCreateIC(xw.xim, XNInputStyle, XIMPreeditNothing
@@ -2058,7 +2042,8 @@ void
2058xdraws(char *s, Glyph base, int x, int y, int charlen, int bytelen) { 2042xdraws(char *s, Glyph base, int x, int y, int charlen, int bytelen) {
2059 int fg = base.fg, bg = base.bg, temp; 2043 int fg = base.fg, bg = base.bg, temp;
2060 int winx = BORDER+x*xw.cw, winy = BORDER+y*xw.ch + dc.font.ascent, width = charlen*xw.cw; 2044 int winx = BORDER+x*xw.cw, winy = BORDER+y*xw.ch + dc.font.ascent, width = charlen*xw.cw;
2061 XFontSet fontset = dc.font.set; 2045 Font *font = &dc.font;
2046 XGlyphInfo extents;
2062 int i; 2047 int i;
2063 2048
2064 /* only switch default fg/bg if term is in RV mode */ 2049 /* only switch default fg/bg if term is in RV mode */
@@ -2074,13 +2059,13 @@ xdraws(char *s, Glyph base, int x, int y, int charlen, int bytelen) {
2074 2059
2075 if(base.mode & ATTR_BOLD) { 2060 if(base.mode & ATTR_BOLD) {
2076 fg += 8; 2061 fg += 8;
2077 fontset = dc.bfont.set; 2062 font = &dc.bfont;
2078 } 2063 }
2079 2064
2080 if(base.mode & ATTR_ITALIC) 2065 if(base.mode & ATTR_ITALIC)
2081 fontset = dc.ifont.set; 2066 font = &dc.ifont;
2082 if(base.mode & (ATTR_ITALIC|ATTR_ITALIC)) 2067 if(base.mode & (ATTR_ITALIC|ATTR_ITALIC))
2083 fontset = dc.ibfont.set; 2068 font = &dc.ibfont;
2084 2069
2085 XSetBackground(xw.dpy, dc.gc, dc.col[bg]); 2070 XSetBackground(xw.dpy, dc.gc, dc.col[bg]);
2086 XSetForeground(xw.dpy, dc.gc, dc.col[fg]); 2071 XSetForeground(xw.dpy, dc.gc, dc.col[fg]);
@@ -2095,7 +2080,10 @@ xdraws(char *s, Glyph base, int x, int y, int charlen, int bytelen) {
2095 } 2080 }
2096 } 2081 }
2097 2082
2098 XmbDrawImageString(xw.dpy, xw.buf, fontset, dc.gc, winx, winy, s, bytelen); 2083 XftTextExtentsUtf8(xw.dpy, font->xft_set, (FcChar8 *)s, bytelen, &extents);
2084 width = extents.xOff;
2085 XftDrawRect(xw.xft_draw, &dc.xft_col[bg], winx, winy - font->ascent, width, xw.ch);
2086 XftDrawStringUtf8(xw.xft_draw, &dc.xft_col[fg], font->xft_set, winx, winy, (FcChar8 *)s, bytelen);
2099 2087
2100 if(base.mode & ATTR_UNDERLINE) 2088 if(base.mode & ATTR_UNDERLINE)
2101 XDrawLine(xw.dpy, xw.buf, dc.gc, winx, winy+1, winx+width-1, winy+1); 2089 XDrawLine(xw.dpy, xw.buf, dc.gc, winx, winy+1, winx+width-1, winy+1);