[hackers] [st] don't set the font all the time

From: Anselm R. Garbe <arg_AT_suckless.org>
Date: Fri Mar 02 15:17:17 2007

changeset: 48:6375affefa2f
tag: tip
user: Anselm R. Garbe <arg_AT_suckless.org>
date: Fri Mar 02 15:17:04 2007 +0100
summary: don't set the font all the time

diff -r 0b1a533fa0f7 -r 6375affefa2f events.c
--- a/events.c Fri Mar 02 14:17:49 2007 +0100
+++ b/events.c Fri Mar 02 15:17:04 2007 +0100
@@ -142,8 +142,8 @@ handle_resize(XEvent *xev) {
 handle_resize(XEvent *xev) {
         int new_cols, new_rows;
 
- new_cols = xev->xconfigure.width / font_width;
- new_rows = xev->xconfigure.height / font_height;
+ new_cols = xev->xconfigure.width / dc.font.width;
+ new_rows = xev->xconfigure.height / dc.font.height;
         if(new_cols != screen_cols || new_rows != screen_rows) {
                 buffer_resize(new_rows, new_cols);
                 screen_cols = new_cols;
@@ -246,8 +246,8 @@ handle_buttonpress(XEvent *xev) {
         int click_col, click_row;
         int button;
 
- click_col = xev->xbutton.x / font_width + 1;
- click_row = xev->xbutton.y / font_height + 1;
+ click_col = xev->xbutton.x / dc.font.width + 1;
+ click_row = xev->xbutton.y / dc.font.height + 1;
         click_col = click_col > screen_cols ? screen_cols : (click_col < 1 ? 1 : click_col);
         click_row = click_row > screen_rows ? screen_rows : (click_row < 1 ? 1 : click_row);
         button = xev->xbutton.button;
@@ -382,10 +382,10 @@ handle_x_events(void) {
                         case REFRESH_PARTIALLY:
                                 {
                                         int a,b,c,d;
- a = xev.xexpose.x / font_width + 1;
- b = xev.xexpose.y / font_height + 1;
- c = (xev.xexpose.x + xev.xexpose.width) / font_width + 1;
- d = (xev.xexpose.y + xev.xexpose.height) / font_height + 1;
+ a = xev.xexpose.x / dc.font.width + 1;
+ b = xev.xexpose.y / dc.font.height + 1;
+ c = (xev.xexpose.x + xev.xexpose.width) / dc.font.width + 1;
+ d = (xev.xexpose.y + xev.xexpose.height) / dc.font.height + 1;
                                         a = a > screen_cols ? screen_cols : a;
                                         b = b > screen_rows ? screen_rows : b;
                                         c = c > screen_cols ? screen_cols : c;
diff -r 0b1a533fa0f7 -r 6375affefa2f main.c
--- a/main.c Fri Mar 02 14:17:49 2007 +0100
+++ b/main.c Fri Mar 02 15:17:04 2007 +0100
@@ -2,16 +2,125 @@
  * See LICENSE file for license details.
  */
 #include "st.h"
+#include <locale.h>
 #include <stdio.h>
+#include <X11/cursorfont.h>
+
+/* static */
+
+static char *fgcolors[] = {
+ "black",
+ "red",
+ "green",
+ "yellow",
+ "blue",
+ "magenta",
+ "#00d0d0",
+ "#d0d0d0",
+ "#404040"
+};
+
+static char *bgcolors[] = {
+ "black",
+ "#d00000",
+ "#00d000",
+ "#d0d000",
+ "#0000d0",
+ "#d000d0",
+ "#00d0d0",
+ "#d0d0d0"
+};
+
+static unsigned long
+initcolor(const char *colstr) {
+ Colormap cmap = DefaultColormap(dpy, screen);
+ XColor color;
+
+ if(!XAllocNamedColor(dpy, cmap, colstr, &color, &color))
+ eprint("error, cannot allocate color '%s'\n", colstr);
+ return color.pixel;
+}
+
+static void
+initcolors(void) {
+ unsigned int i;
+
+ dc.nfg = sizeof fgcolors / sizeof fgcolors[0];
+ dc.fg = emalloc(dc.nfg * sizeof(unsigned long));
+ dc.nbg = sizeof bgcolors / sizeof bgcolors[0];
+ dc.bg = emalloc(dc.nbg * sizeof(unsigned long));
+ for(i = 0; i < dc.nfg; i++)
+ dc.fg[i] = initcolor(fgcolors[i]);
+ for(i = 0; i < dc.nbg; i++)
+ dc.bg[i] = initcolor(bgcolors[i]);
+ dc.cursor = initcolor("lightgreen");
+}
+
+static void
+initfont(const char *fontstr) {
+ char *def, **missing;
+ int i, n;
+
+ missing = NULL;
+ if(dc.font.set)
+ XFreeFontSet(dpy, dc.font.set);
+ dc.font.set = NULL;//XCreateFontSet(dpy, fontstr, &missing, &n, &def);
+ if(missing) {
+ while(n--)
+ fprintf(stderr, "missing fontset: %s\n", missing[n]);
+ XFreeStringList(missing);
+ }
+ if(dc.font.set) {
+ XFontSetExtents *font_extents;
+ XFontStruct **xfonts;
+ char **font_names;
+ dc.font.ascent = dc.font.descent = 0;
+ font_extents = XExtentsOfFontSet(dc.font.set);
+ n = XFontsOfFontSet(dc.font.set, &xfonts, &font_names);
+ dc.font.ascent = dc.font.descent = dc.font.width = 0;
+ for(i = 0; i < n; i++) {
+ if(dc.font.width < (*xfonts)->max_bounds.width)
+ dc.font.width = (*xfonts)->max_bounds.width;
+ if(dc.font.ascent < (*xfonts)->ascent)
+ dc.font.ascent = (*xfonts)->ascent;
+ if(dc.font.descent < (*xfonts)->descent)
+ dc.font.descent = (*xfonts)->descent;
+ xfonts++;
+ }
+ }
+ else {
+ if(dc.font.xfont)
+ XFreeFont(dpy, dc.font.xfont);
+ dc.font.xfont = NULL;
+ if(!(dc.font.xfont = XLoadQueryFont(dpy, fontstr)))
+ eprint("error, cannot load font: '%s'\n", fontstr);
+ dc.font.ascent = dc.font.xfont->ascent;
+ dc.font.descent = dc.font.xfont->descent;
+ dc.font.width = dc.font.xfont->max_bounds.width;
+ }
+ dc.font.height = dc.font.ascent + dc.font.descent;
+ screen_rows = screen_rows == -1 ? DEFAULT_NR_ROWS : screen_rows;
+ screen_cols = screen_cols == -1 ? DEFAULT_NR_COLS : screen_cols;
+ ww = screen_cols * dc.font.width;
+ wh = screen_rows * dc.font.height;
+}
+
+/* extern */
+
+DC dc = { 0 };
 
 int
 main(int argc, char **argv) {
- if(init_display())
- return 1;
- if(init_colors())
- return 1;
- if(init_font())
- return 1;
+
+ setlocale(LC_CTYPE, "");
+ if(!(dpy = XOpenDisplay(0)))
+ eprint("cannot open display\n");
+ screen = DefaultScreen(dpy);
+ cmap = DefaultColormap(dpy, screen);
+ if(!(cursor = XCreateFontCursor(dpy, XC_xterm)))
+ eprint("cannot create cursor\n");
+ initcolors();
+ initfont(DEFAULT_FONT);
         if(init_window())
                 return 1;
         if(init_vt_buffer())
diff -r 0b1a533fa0f7 -r 6375affefa2f screen.c
--- a/screen.c Fri Mar 02 14:17:49 2007 +0100
+++ b/screen.c Fri Mar 02 15:17:04 2007 +0100
@@ -210,8 +210,8 @@ clear_area(int x1, int y1, int x2, int y
 clear_area(int x1, int y1, int x2, int y2) {
         int i, j;
 
- win_clear_region((x1 - 1) * font_width, (y1 - 1) * font_height,
- x2 * font_width, y2 * font_height,
+ win_clear_region((x1 - 1) * dc.font.width, (y1 - 1) * dc.font.height,
+ x2 * dc.font.width, y2 * dc.font.height,
                         GET_BG_COLOR(text_attrs));
         for(i = y1; i <= y2; i++)
                 for(j = x1; j <= x2; j++)
diff -r 0b1a533fa0f7 -r 6375affefa2f st.h
--- a/st.h Fri Mar 02 14:17:49 2007 +0100
+++ b/st.h Fri Mar 02 15:17:04 2007 +0100
@@ -8,7 +8,8 @@
 #define END_KEY "\033[4~"
 #define PREV_KEY "\033[5~"
 #define NEXT_KEY "\033[6~"
-#define DEFAULT_FONT "-*-proggyclean-medium-r-*-*-13-*-*-*-*-*-*-*"
+#define DEFAULT_FONT "fixed"
+//"-*-proggyclean-medium-r-*-*-13-*-*-*-*-*-*-*"
 #define DEFAULT_NR_ROWS 24
 #define DEFAULT_NR_COLS 80
 #define DELETE_KEY "\033[3~"
@@ -16,32 +17,12 @@
 #define END_KEY "\033[4~"
 #define PREV_KEY "\033[5~"
 #define NEXT_KEY "\033[6~"
-#define DEFAULT_BACKGROUND_COLOR colors[0]
-#define DEFAULT_FOREGROUND_COLOR colors[7]
 #define win_set_icon_title win_set_window_title
 #define FIXME fprintf(stderr, "FIXME: %s: %d (%s)\n", __FILE__, __LINE__, __FUNCTION__)
 #define CP fprintf(stderr, "Checkpoint: %s:%d\n", __FILE__, __LINE__)
 #define min(a,b) (((a)<(b))?(a):(b))
 #define max(a,b) (((a)>(b))?(a):(b))
-#define GET_BG_COLOR(p) (((p.rev)^(p.sel))?(bgcolors[(p).fg].pixel):(bgcolors[(p).bg].pixel))
-
-typedef struct Fnt Fnt;
-typedef struct Glyph Glyph;
-
-struct Fnt {
- XFontStruct *xfont;
- XFontSet set;
- int ascent;
- int descent;
- int height;
-};
-
-struct Glyph {
- unsigned char *glyph; /* usually 1 char, for UTF8 maybe more */
- unsigned long fg;
- unsigned long bg;
- Fnt *font; /* bold or normal */
-};
+#define GET_BG_COLOR(p) (((p.rev)^(p.sel))?(dc.bg[(p).fg]):(dc.bg[(p).bg]))
 
 typedef struct text_letter_t {
 #ifndef BIGENDIAN
@@ -80,22 +61,34 @@ extern int scroll_region_start;
 extern int scroll_region_start;
 extern int scroll_region_end ;
 extern int scroll_in_region;
+
+typedef struct {
+ unsigned int nfg;
+ unsigned long *fg;
+ unsigned int nbg;
+ unsigned long *bg;
+ unsigned long cursor;
+ struct {
+ XFontStruct *xfont;
+ XFontSet set;
+ int ascent;
+ int descent;
+ int height;
+ int width;
+ } font;
+} DC;
+
+extern DC dc;
 extern text_row_t *text_screen;
 extern text_letter_t text_attrs;
-extern XColor colors[9];
-extern XColor bgcolors[8];
-extern XColor cursor_color;
 extern Display *dpy;
 extern Window win;
-extern XFontStruct *font;
 extern GC gc;
 extern Colormap cmap;
 extern Cursor cursor;
 extern int screen;
 extern int ww;
 extern int wh;
-extern int font_height;
-extern int font_width;
 
 extern int cmd_write(const char *, int);
 extern unsigned char cmdgetc(void);
diff -r 0b1a533fa0f7 -r 6375affefa2f ui.c
--- a/ui.c Fri Mar 02 14:17:49 2007 +0100
+++ b/ui.c Fri Mar 02 15:17:04 2007 +0100
@@ -5,42 +5,17 @@
 #include <assert.h>
 #include <ctype.h>
 #include <stdio.h>
-#include <X11/Xlib.h>
 #include <X11/Xutil.h>
-#include <X11/cursorfont.h>
 
 Display *dpy;
 Window win;
-XFontStruct *font;
 GC gc;
 Colormap cmap;
 Cursor cursor;
 
-XColor colors[9];
-XColor bgcolors[8];
-XColor cursor_color;
 int screen;
 int ww;
 int wh;
-int font_height = -1;
-int font_width = -1;
-
-int
-init_display(void) {
- dpy = XOpenDisplay(NULL);
-
- if(!dpy) {
- fprintf(stderr, "Couldn't open display\n");
- return -1;
- }
- screen = DefaultScreen(dpy);
- cmap = DefaultColormap(dpy, screen);
- if(!(cursor = XCreateFontCursor(dpy, XC_xterm))) {
- fprintf(stderr, "Couldn't create cursor\n");
- return -1;
- }
- return 0;
-}
 
 int
 init_window(void) {
@@ -49,21 +24,20 @@ init_window(void) {
         XWMHints wmh;
         XClassHint ch;
 
- win = XCreateSimpleWindow(dpy, DefaultRootWindow(dpy), 0, 0, ww, wh,
- 0, DEFAULT_BACKGROUND_COLOR.pixel, DEFAULT_BACKGROUND_COLOR.pixel);
+ win = XCreateSimpleWindow(dpy, DefaultRootWindow(dpy), 0, 0, ww, wh, 0, dc.bg[0], dc.bg[0]);
         XSelectInput(dpy, win, StructureNotifyMask);
         XMapWindow(dpy, win);
         /* Wait for the window to be mapped */
         wait_for_specific_event(MapNotify);
         gc = XCreateGC(dpy, win, 0, NULL);
- XSetForeground(dpy, gc, DEFAULT_FOREGROUND_COLOR.pixel);
- XSetBackground(dpy, gc, DEFAULT_BACKGROUND_COLOR.pixel);
+ XSetForeground(dpy, gc, dc.fg[0]);
+ XSetBackground(dpy, gc, dc.bg[0]);
         XDefineCursor(dpy, win, cursor);
         sh.x = sh.y = 0;
         sh.width = ww;
         sh.height = wh;
- sh.width_inc = font_width;
- sh.height_inc = font_height;
+ sh.width_inc = dc.font.width;
+ sh.height_inc = dc.font.height;
         sh.flags = PPosition | PSize | PResizeInc;
         wmh.input = 1;
         wmh.flags = InputHint;
@@ -73,22 +47,8 @@ init_window(void) {
         XStoreName(dpy, win, "st");
         XSync(dpy, 0);
         set_text_attrs(-1, 0);
- XSetFont(dpy, gc, font->fid);
- return 0;
-}
-
-int
-init_font() {
- if(!(font = XLoadQueryFont(dpy, DEFAULT_FONT)))
- eprint("Couldn't load font `%s'\n", DEFAULT_FONT);
- if(font_height == -1 || font_width == -1) {
- font_height = font->ascent + font->descent;
- font_width = font->max_bounds.width;
- }
- screen_rows = screen_rows == -1 ? DEFAULT_NR_ROWS : screen_rows;
- screen_cols = screen_cols == -1 ? DEFAULT_NR_COLS : screen_cols;
- ww = screen_cols * font_width;
- wh = screen_rows * font_height;
+ if(!dc.font.set)
+ XSetFont(dpy, gc, dc.font.xfont->fid);
         return 0;
 }
 
@@ -102,54 +62,6 @@ wait_for_specific_event(int event_type)
         }
 }
 
-int
-find_color(XColor *Xc, char *def) {
- if((XParseColor(dpy, cmap, def, Xc)))
- if(!(XAllocColor(dpy, cmap, Xc)))
- return -1;
- return 0;
-}
-
-int
-init_colors(void) {
- int color;
- char *color_values[9] = {
- "black",
- "red",
- "green",
- "yellow",
- "blue",
- "magenta",
- "#00d0d0",
- "#d0d0d0",
- "#404040"
- };
-
- char *bgcolor_values[8] = {
- "black",
- "#d00000",
- "#00d000",
- "#d0d000",
- "#0000d0",
- "#d000d0",
- "#00d0d0",
- "#d0d0d0"
- };
-
- for(color = 0; color < 9; color++)
- if(find_color(&(colors[color]), color_values[color]))
- fprintf(stderr, "Couldn't allocate color %d (%s)\n",
- color, color_values[color]);
- for(color = 0; color < 8; color++)
- if(find_color(&(bgcolors[color]), bgcolor_values[color]))
- fprintf(stderr, "Couldn't allocate bgcolor %d (%s)\n",
- color, bgcolor_values[color]);
- if(find_color(&(cursor_color), "lightgreen"))
- fprintf(stderr, "Couldn't allocate cursor color (%s)\n",
- "lightgreen");
- return 0;
-}
-
 void
 win_clear_region(int x1, int y1, int x2, int y2, int color) {
         XSetBackground(dpy, gc, color);
@@ -158,9 +70,10 @@ win_clear_region(int x1, int y1, int x2,
 
 void
 win_draw_string(int row, int col, char *s, int l) {
- XDrawImageString(dpy, win, gc,
- col * font_width, row * font_height + font->ascent,
- s, l);
+ if(dc.font.set)
+ XmbDrawString(dpy, win, gc, dc.font.set, col * dc.font.width, row * dc.font.height + dc.font.ascent, s, l);
+ else
+ XDrawImageString(dpy, win, gc, col * dc.font.width, row * dc.font.height + dc.font.ascent, s, l);
 }
 
 void
@@ -171,22 +84,22 @@ void
 void
 window_scroll_up(int lines) {
         XCopyArea(dpy, win, win, gc,
- 0, lines * font_height,
- ww, (screen_rows - lines + 1) * font_height,
+ 0, lines * dc.font.height,
+ ww, (screen_rows - lines + 1) * dc.font.height,
                         0, 0);
- win_clear_region(0, (screen_rows - lines) * font_height,
- ww, screen_rows * font_height,
+ win_clear_region(0, (screen_rows - lines) * dc.font.height,
+ ww, screen_rows * dc.font.height,
                         GET_BG_COLOR(text_attrs));
 }
 
 void
 region_scroll_up(int start, int end, int lines) {
         XCopyArea(dpy, win, win, gc,
- 0, (start - 1 + lines) * font_height,
- ww, (end - start + 2 - lines) * font_height,
- 0, (start - 1) * font_height);
- win_clear_region(0, (end - lines) * font_height,
- ww, end * font_height,
+ 0, (start - 1 + lines) * dc.font.height,
+ ww, (end - start + 2 - lines) * dc.font.height,
+ 0, (start - 1) * dc.font.height);
+ win_clear_region(0, (end - lines) * dc.font.height,
+ ww, end * dc.font.height,
                         GET_BG_COLOR(text_attrs));
 }
 
@@ -194,21 +107,21 @@ window_scroll_down(int lines) {
 window_scroll_down(int lines) {
         XCopyArea(dpy, win, win, gc,
                         0, 0,
- ww, (screen_rows - lines + 1) * font_height,
- 0, lines * font_height);
+ ww, (screen_rows - lines + 1) * dc.font.height,
+ 0, lines * dc.font.height);
         win_clear_region(0, 0,
- ww, (lines) * font_height,
+ ww, (lines) * dc.font.height,
                         GET_BG_COLOR(text_attrs));
 }
 
 void
 region_scroll_down(int start, int end, int lines) {
         XCopyArea(dpy, win, win, gc,
- 0, (start - 1) * font_height,
- ww, (end - start + 2 - lines) * font_height,
- 0, (start - 1 + lines) * font_height);
- win_clear_region(0, (start - 1) * font_height,
- ww, (start + lines - 1) * font_height,
+ 0, (start - 1) * dc.font.height,
+ ww, (end - start + 2 - lines) * dc.font.height,
+ 0, (start - 1 + lines) * dc.font.height);
+ win_clear_region(0, (start - 1) * dc.font.height,
+ ww, (start + lines - 1) * dc.font.height,
                         GET_BG_COLOR(text_attrs));
 }
 
@@ -221,11 +134,12 @@ set_text_attrs(text_letter_t l) {
         else
                 fg = l.fg, bg = l.bg;
         if(l.bold && fg == 0)
- XSetForeground(dpy, gc, colors[8].pixel);
- else
- XSetForeground(dpy, gc, colors[fg].pixel);
- XSetFont(dpy, gc, font->fid);
- XSetBackground(dpy, gc, bgcolors[bg].pixel);
+ XSetForeground(dpy, gc, dc.fg[8]);
+ else
+ XSetForeground(dpy, gc, dc.fg[fg]);
+ if(!dc.font.set)
+ XSetFont(dpy, gc, dc.font.xfont->fid);
+ XSetBackground(dpy, gc, dc.bg[bg]);
 }
 
 int
@@ -254,7 +168,6 @@ redraw_screen(void) {
         for(i = 0; i < screen_rows; i++) {
                 if(!text_screen[i].needs_update)
                         continue;
- /* win_clear_region(0, i * font_height, ww-1, (i + 1) * font_height - 1); */
                 sl = 0; start = 0;
                 for(j = 0; j <= screen_cols; j++) {
                         if(j == screen_cols) {
@@ -298,7 +211,6 @@ redraw_region(int x1, int y1, int x2, in
         int sl, start;
         unsigned char buf[MAXRUNLENGTH];
 
- /* win_clear_region((x1 - 1) * font_width, (y1 - 1) * font_height, x2 * font_width, y2 * font_height); */
         a = (*(int*)&(text_screen[y1-1].line[x1-1])) & ~0xff;
         set_text_attrs(text_screen[y1-1].line[x1-1]);
         for(i = y1 - 1; i < y2; i++) {
@@ -339,16 +251,12 @@ show_cursor(void) {
         cursor_col = curr_col;
         if(curr_col > screen_cols)
                 cursor_col = screen_cols;
- if(text_screen[cursor_row-1].line[cursor_col-1].bold)
- XSetFont(dpy, gc, font->fid);
- else
- XSetFont(dpy, gc, font->fid);
- win_clear_region((cursor_col - 1) * font_width, (cursor_row - 1) * font_height,
- cursor_col * font_width, cursor_row * font_height,
- cursor_color.pixel);
-
- XSetForeground(dpy, gc, colors[0].pixel);
- XSetBackground(dpy, gc, cursor_color.pixel);
+ if(!dc.font.set)
+ XSetFont(dpy, gc, dc.font.xfont->fid);
+ win_clear_region((cursor_col - 1) * dc.font.width, (cursor_row - 1) * dc.font.height,
+ cursor_col * dc.font.width, cursor_row * dc.font.height, dc.cursor);
+ XSetForeground(dpy, gc, dc.fg[0]);
+ XSetBackground(dpy, gc, dc.cursor);
         win_draw_string(cursor_row - 1, cursor_col - 1, &(text_screen[cursor_row - 1].line[cursor_col - 1]), 1);
         XFlush(dpy);
         cursor_is_visible = 1;
@@ -361,8 +269,8 @@ hide_cursor(void) {
         if(cursor_row <= screen_rows && cursor_col <= screen_cols)
         {
                 set_text_attrs(text_screen[cursor_row-1].line[cursor_col-1]);
- win_clear_region((cursor_col - 1) * font_width, (cursor_row - 1) * font_height,
- cursor_col * font_width, cursor_row * font_height,
+ win_clear_region((cursor_col - 1) * dc.font.width, (cursor_row - 1) * dc.font.height,
+ cursor_col * dc.font.width, cursor_row * dc.font.height,
                                 GET_BG_COLOR(text_screen[cursor_row-1].line[cursor_col-1]));
                 win_draw_string(cursor_row - 1, cursor_col - 1, &(text_screen[cursor_row - 1].line[cursor_col - 1]), 1);
                 XFlush(dpy);
Received on Fri Mar 02 2007 - 15:17:17 UTC

This archive was generated by hypermail 2.2.0 : Sun Jul 13 2008 - 15:56:03 UTC