Skip to content
Snippets Groups Projects
Commit 187e7906 authored by Cédric Roux's avatar Cédric Roux
Browse files

use Xft to draw strings

parent 120951d7
No related branches found
No related tags found
No related merge requests found
......@@ -3,7 +3,7 @@ CFLAGS=-Wall -g -pthread -DT_TRACER -I.
#CFLAGS += -O3 -ffast-math -fomit-frame-pointer
LIBS=-lX11 -lm -lpng
LIBS=-lX11 -lm -lpng -lXft
tracer_remote: remote_old.o plot.o database.o gui.o utils.o gui/gui.a
$(CC) $(CFLAGS) -o tracer_remote $^ $(LIBS)
......
CC=gcc
CFLAGS=-Wall -g -pthread
CFLAGS=-Wall -g -pthread -I/usr/include/X11/Xft -I/usr/include/freetype2
OBJS=init.o loop.o toplevel_window.o x.o container.o widget.o \
gui.o label.o event.o xy_plot.o textlist.o notify.o positioner.o \
......
......@@ -12,6 +12,8 @@ typedef void widget;
#define BACKGROUND_COLOR 0
#define FOREGROUND_COLOR 1
#define DEFAULT_FONT 0
/* key modifiers */
#define KEY_SHIFT (1<<0)
#define KEY_CONTROL (1<<1)
......
......@@ -10,7 +10,7 @@ static void paint(gui *_gui, widget *_w)
struct gui *g = _gui;
struct label_widget *l = _w;
LOGD("PAINT label '%s'\n", l->t);
x_draw_string(g->x, g->xwin, l->color,
x_draw_string(g->x, g->xwin, DEFAULT_FONT, l->color,
l->common.x, l->common.y + l->baseline, l->t);
}
......@@ -35,7 +35,8 @@ widget *new_label(gui *_gui, const char *label)
if (w->t == NULL) OOM;
w->color = FOREGROUND_COLOR;
x_text_get_dimensions(g->x, label, &w->width, &w->height, &w->baseline);
x_text_get_dimensions(g->x, DEFAULT_FONT, label,
&w->width, &w->height, &w->baseline);
w->common.paint = paint;
w->common.hints = hints;
......
......@@ -16,7 +16,7 @@ static void paint(gui *_gui, widget *_this)
this->common.width, this->common.height);
for (i = 0, j = this->starting_line;
i < this->allocated_nlines && j < this->text_count; i++, j++)
x_draw_clipped_string(g->x, g->xwin, this->color[j],
x_draw_clipped_string(g->x, g->xwin, DEFAULT_FONT, this->color[j],
this->common.x,
this->common.y + i * this->line_height + this->baseline,
this->text[j],
......@@ -79,7 +79,8 @@ widget *new_textlist(gui *_gui, int width, int nlines, int bgcol)
w = new_widget(g, TEXT_LIST, sizeof(struct textlist_widget));
w->wanted_nlines = nlines;
x_text_get_dimensions(g->x, ".", &dummy, &w->line_height, &w->baseline);
x_text_get_dimensions(g->x, DEFAULT_FONT, ".",
&dummy, &w->line_height, &w->baseline);
w->background_color = bgcol;
w->wanted_width = width;
......
......@@ -33,12 +33,34 @@ int x_new_color(x_connection *_x, char *color)
{
struct x_connection *x = _x;
x->ncolors++;
x->colors = realloc(x->colors, x->ncolors * sizeof(GC));
if (x->colors == NULL) OOM;
x->colors[x->ncolors-1] = create_gc(x->d, color);
x->xft_colors = realloc(x->xft_colors, x->ncolors * sizeof(XftColor));
if (x->xft_colors == NULL) OOM;
if (XftColorAllocName(x->d, DefaultVisual(x->d, DefaultScreen(x->d)),
DefaultColormap(x->d, DefaultScreen(x->d)),
color, &x->xft_colors[x->ncolors-1]) == False)
ERR("could not allocate color '%s'\n", color);
return x->ncolors - 1;
}
int x_new_font(x_connection *_x, char *font)
{
struct x_connection *x = _x;
/* TODO: allocate fonts only once */
x->nfonts++;
x->fonts = realloc(x->fonts, x->nfonts * sizeof(XftFont *));
if (x->fonts == NULL) OOM;
x->fonts[x->nfonts-1] = XftFontOpenName(x->d, DefaultScreen(x->d), font);
if (x->fonts[x->nfonts-1] == NULL)
ERR("failed allocating font '%s'\n", font);
return x->nfonts - 1;
}
x_connection *x_open(void)
{
struct x_connection *ret;
......@@ -53,6 +75,8 @@ x_connection *x_open(void)
x_new_color(ret, "white"); /* background color */
x_new_color(ret, "black"); /* foreground color */
x_new_font(ret, "sans-8");
return ret;
}
......@@ -78,6 +102,11 @@ x_window *x_create_window(x_connection *_x, int width, int height,
XFillRectangle(x->d, ret->p, x->colors[BACKGROUND_COLOR],
0, 0, width, height);
ret->xft = XftDrawCreate(x->d, ret->p,
DefaultVisual(x->d, DefaultScreen(x->d)),
DefaultColormap(x->d, DefaultScreen(x->d)));
if (ret->xft == NULL) ERR("XftDrawCreate failed\n");
/* enable backing store */
{
XSetWindowAttributes att;
......@@ -261,11 +290,17 @@ void x_events(gui *_gui)
w->common.allocate(g, w, 0, 0, xw->new_width, xw->new_height);
xw->width = xw->new_width;
xw->height = xw->new_height;
XftDrawDestroy(xw->xft);
XFreePixmap(x->d, xw->p);
xw->p = XCreatePixmap(x->d, xw->w, xw->width, xw->height,
DefaultDepth(x->d, DefaultScreen(x->d)));
XFillRectangle(x->d, xw->p, x->colors[BACKGROUND_COLOR],
0, 0, xw->width, xw->height);
xw->xft = XftDrawCreate(x->d, xw->p,
DefaultVisual(x->d, DefaultScreen(x->d)),
DefaultColormap(x->d, DefaultScreen(x->d)));
if (xw->xft == NULL) ERR("XftDrawCreate failed\n");
//xw->repaint = 1;
}
}
......@@ -290,24 +325,17 @@ void x_flush(x_connection *_x)
XFlush(x->d);
}
void x_text_get_dimensions(x_connection *_c, const char *t,
void x_text_get_dimensions(x_connection *_c, int font, const char *t,
int *width, int *height, int *baseline)
{
struct x_connection *c = _c;
int dir;
int ascent;
int descent;
XCharStruct overall;
XGlyphInfo ext;
/* TODO: don't use XQueryTextExtents (X roundtrip) */
XQueryTextExtents(c->d, XGContextFromGC(c->colors[1]), t, strlen(t),
&dir, &ascent, &descent, &overall);
XftTextExtents8(c->d, c->fonts[font], (FcChar8 *)t, strlen(t), &ext);
//LOGD("dir %d ascent %d descent %d lbearing %d rbearing %d width %d ascent %d descent %d\n", dir, ascent, descent, overall.lbearing, overall.rbearing, overall.width, overall.ascent, overall.descent);
*width = overall.width;
*height = ascent + descent;
*baseline = ascent;
*width = ext.width;
*height = c->fonts[font]->height;
*baseline = c->fonts[font]->ascent;
}
/***********************************************************************/
......@@ -338,25 +366,26 @@ void x_fill_rectangle(x_connection *_c, x_window *_w, int color,
XFillRectangle(c->d, w->p, c->colors[color], x, y, width, height);
}
void x_draw_string(x_connection *_c, x_window *_w, int color,
void x_draw_string(x_connection *_c, x_window *_w, int font, int color,
int x, int y, const char *t)
{
struct x_connection *c = _c;
struct x_window *w = _w;
int tlen = strlen(t);
XDrawString(c->d, w->p, c->colors[color], x, y, t, tlen);
XftDrawString8(w->xft, &c->xft_colors[color], c->fonts[font],
x, y, (const unsigned char *)t, tlen);
}
void x_draw_clipped_string(x_connection *_c, x_window *_w, int color,
int x, int y, const char *t,
void x_draw_clipped_string(x_connection *_c, x_window *_w, int font,
int color, int x, int y, const char *t,
int clipx, int clipy, int clipwidth, int clipheight)
{
struct x_connection *c = _c;
struct x_window *w = _w;
XRectangle clip = { clipx, clipy, clipwidth, clipheight };
XSetClipRectangles(c->d, c->colors[color], 0, 0, &clip, 1, Unsorted);
x_draw_string(_c, _w, color, x, y, t);
XSetClipMask(c->d, c->colors[color], None);
if (XftDrawSetClipRectangles(w->xft, 0, 0, &clip, 1) == False) abort();
x_draw_string(_c, _w, font, color, x, y, t);
if (XftDrawSetClip(w->xft, NULL) == False) abort();
}
void x_draw_image(x_connection *_c, x_window *_w, x_image *_img, int x, int y)
......
......@@ -20,12 +20,13 @@ int x_connection_fd(x_connection *x);
void x_flush(x_connection *x);
int x_new_color(x_connection *x, char *color);
int x_new_font(x_connection *x, char *font);
/* for x_events, we pass the gui */
#include "gui.h"
void x_events(gui *gui);
void x_text_get_dimensions(x_connection *, const char *t,
void x_text_get_dimensions(x_connection *, int font, const char *t,
int *width, int *height, int *baseline);
/* drawing functions */
......@@ -39,11 +40,11 @@ void x_draw_rectangle(x_connection *c, x_window *w, int color,
void x_fill_rectangle(x_connection *c, x_window *w, int color,
int x, int y, int width, int height);
void x_draw_string(x_connection *_c, x_window *_w, int color,
void x_draw_string(x_connection *_c, x_window *_w, int font, int color,
int x, int y, const char *t);
void x_draw_clipped_string(x_connection *_c, x_window *_w, int color,
int x, int y, const char *t,
void x_draw_clipped_string(x_connection *_c, x_window *_w, int font,
int color, int x, int y, const char *t,
int clipx, int clipy, int clipwidth, int clipheight);
void x_draw_image(x_connection *c, x_window *w, x_image *img, int x, int y);
......
......@@ -2,14 +2,18 @@
#define _X_DEFS_H_
#include <X11/Xlib.h>
#include <Xft.h>
struct x_connection {
Display *d;
GC *colors;
XftColor *xft_colors;
int ncolors;
XPoint *pts;
int pts_size;
int pts_maxsize;
XftFont **fonts;
int nfonts;
};
struct x_window {
......@@ -17,6 +21,7 @@ struct x_window {
Pixmap p;
int width;
int height;
XftDraw *xft;
/* below: internal data used for X events handling */
int redraw;
int repaint;
......
......@@ -79,8 +79,8 @@ static void paint(gui *_gui, widget *_this)
this->common.x + this->vrule_width + x,
this->common.y + this->common.height - this->label_height * 2 - 5);
sprintf(v, "%g", k * ticstep);
x_text_get_dimensions(g->x, v, &vwidth, &dummy, &dummy);
x_draw_string(g->x, g->xwin, FOREGROUND_COLOR,
x_text_get_dimensions(g->x, DEFAULT_FONT, v, &vwidth, &dummy, &dummy);
x_draw_string(g->x, g->xwin, DEFAULT_FONT, FOREGROUND_COLOR,
this->common.x + this->vrule_width + x - vwidth/2,
this->common.y + this->common.height - this->label_height * 2 +
this->label_baseline,
......@@ -116,20 +116,20 @@ static void paint(gui *_gui, widget *_this)
(allocated_ymax - allocated_ymin) *
(allocated_plot_height - 1);
sprintf(v, "%g", k * ticstep);
x_text_get_dimensions(g->x, v, &vwidth, &dummy, &dummy);
x_text_get_dimensions(g->x, DEFAULT_FONT, v, &vwidth, &dummy, &dummy);
x_draw_line(g->x, g->xwin, FOREGROUND_COLOR,
this->common.x + this->vrule_width,
this->common.y + FLIP(y),
this->common.x + this->vrule_width + 5,
this->common.y + FLIP(y));
x_draw_string(g->x, g->xwin, FOREGROUND_COLOR,
x_draw_string(g->x, g->xwin, DEFAULT_FONT, FOREGROUND_COLOR,
this->common.x + this->vrule_width - vwidth - 2,
this->common.y + FLIP(y) - this->label_height/2+this->label_baseline,
v);
}
/* label at bottom, in the middle */
x_draw_string(g->x, g->xwin, FOREGROUND_COLOR,
x_draw_string(g->x, g->xwin, DEFAULT_FONT, FOREGROUND_COLOR,
this->common.x + (this->common.width - this->label_width) / 2,
this->common.y + this->common.height - this->label_height
+ this->label_baseline,
......@@ -177,8 +177,8 @@ widget *new_xy_plot(gui *_gui, int width, int height, char *label,
w->label = strdup(label); if (w->label == NULL) OOM;
/* TODO: be sure calling X there is valid wrt "global model" (we are
* not in the "gui thread") */
x_text_get_dimensions(g->x, label, &w->label_width, &w->label_height,
&w->label_baseline);
x_text_get_dimensions(g->x, DEFAULT_FONT, label,
&w->label_width, &w->label_height, &w->label_baseline);
LOGD("XY PLOT label wh %d %d\n", w->label_width, w->label_height);
w->wanted_width = width;
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment