libi3: Rework draw_text
We now have two versions of draw_text draw_text: Now takes an i3String draw_text_ascii: Designed for static strings in plain ASCII
This commit is contained in:
parent
284294e9c2
commit
53365fa887
|
@ -128,7 +128,7 @@ static int handle_expose() {
|
||||||
set_font(&font);
|
set_font(&font);
|
||||||
|
|
||||||
#define txt(x, row, text) \
|
#define txt(x, row, text) \
|
||||||
draw_text(text, strlen(text), false, pixmap, pixmap_gc,\
|
draw_text_ascii(text, pixmap, pixmap_gc,\
|
||||||
x, (row - 1) * font.height + 4, 300 - x * 2)
|
x, (row - 1) * font.height + 4, 300 - x * 2)
|
||||||
|
|
||||||
if (current_step == STEP_WELCOME) {
|
if (current_step == STEP_WELCOME) {
|
||||||
|
|
|
@ -98,11 +98,15 @@ static int handle_expose(void *data, xcb_connection_t *conn, xcb_expose_event_t
|
||||||
|
|
||||||
/* draw the prompt … */
|
/* draw the prompt … */
|
||||||
if (prompt != NULL) {
|
if (prompt != NULL) {
|
||||||
draw_text((char *)i3string_as_ucs2(prompt), i3string_get_num_glyphs(prompt), true, pixmap, pixmap_gc, 4, 4, 492);
|
draw_text(prompt, pixmap, pixmap_gc, 4, 4, 492);
|
||||||
}
|
}
|
||||||
/* … and the text */
|
/* … and the text */
|
||||||
if (input_position > 0)
|
if (input_position > 0)
|
||||||
draw_text((char *)glyphs_ucs, input_position, true, pixmap, pixmap_gc, 4, 4 + prompt_offset, 492 - prompt_offset);
|
{
|
||||||
|
i3String *input = i3string_from_ucs2(glyphs_ucs, input_position);
|
||||||
|
draw_text(input, pixmap, pixmap_gc, 4, 4, 492);
|
||||||
|
i3string_free(input);
|
||||||
|
}
|
||||||
|
|
||||||
/* Copy the contents of the pixmap to the real window */
|
/* Copy the contents of the pixmap to the real window */
|
||||||
xcb_copy_area(conn, pixmap, win, pixmap_gc, 0, 0, 0, 0, /* */ 500, font.height + 8);
|
xcb_copy_area(conn, pixmap, win, pixmap_gc, 0, 0, 0, 0, /* */ 500, font.height + 8);
|
||||||
|
|
|
@ -132,7 +132,7 @@ static int handle_expose(xcb_connection_t *conn, xcb_expose_event_t *event) {
|
||||||
|
|
||||||
/* restore font color */
|
/* restore font color */
|
||||||
set_font_colors(pixmap_gc, color_text, color_background);
|
set_font_colors(pixmap_gc, color_text, color_background);
|
||||||
draw_text((char *)i3string_as_ucs2(prompt), i3string_get_num_glyphs(prompt), true, pixmap, pixmap_gc,
|
draw_text(prompt, pixmap, pixmap_gc,
|
||||||
4 + 4, 4 + 4, rect.width - 4 - 4);
|
4 + 4, 4 + 4, rect.width - 4 - 4);
|
||||||
|
|
||||||
/* render close button */
|
/* render close button */
|
||||||
|
@ -159,7 +159,7 @@ static int handle_expose(xcb_connection_t *conn, xcb_expose_event_t *event) {
|
||||||
|
|
||||||
values[0] = 1;
|
values[0] = 1;
|
||||||
set_font_colors(pixmap_gc, color_text, color_button_background);
|
set_font_colors(pixmap_gc, color_text, color_button_background);
|
||||||
draw_text("X", 1, false, pixmap, pixmap_gc, y - w - line_width + w / 2 - 4,
|
draw_text_ascii("X", pixmap, pixmap_gc, y - w - line_width + w / 2 - 4,
|
||||||
4 + 4 - 1, rect.width - y + w + line_width - w / 2 + 4);
|
4 + 4 - 1, rect.width - y + w + line_width - w / 2 + 4);
|
||||||
y -= w;
|
y -= w;
|
||||||
|
|
||||||
|
@ -190,7 +190,7 @@ static int handle_expose(xcb_connection_t *conn, xcb_expose_event_t *event) {
|
||||||
values[0] = color_text;
|
values[0] = color_text;
|
||||||
values[1] = color_button_background;
|
values[1] = color_button_background;
|
||||||
set_font_colors(pixmap_gc, color_text, color_button_background);
|
set_font_colors(pixmap_gc, color_text, color_button_background);
|
||||||
draw_text((char *)i3string_as_ucs2(buttons[c].label), i3string_get_num_glyphs(buttons[c].label), true, pixmap, pixmap_gc,
|
draw_text(buttons[c].label, pixmap, pixmap_gc,
|
||||||
y - w - line_width + 6, 4 + 3, rect.width - y + w + line_width - 6);
|
y - w - line_width + 6, 4 + 3, rect.width - y + w + line_width - 6);
|
||||||
|
|
||||||
y -= w;
|
y -= w;
|
||||||
|
|
|
@ -144,8 +144,7 @@ void refresh_statusline() {
|
||||||
|
|
||||||
uint32_t colorpixel = (block->color ? get_colorpixel(block->color) : colors.bar_fg);
|
uint32_t colorpixel = (block->color ? get_colorpixel(block->color) : colors.bar_fg);
|
||||||
set_font_colors(statusline_ctx, colorpixel, colors.bar_bg);
|
set_font_colors(statusline_ctx, colorpixel, colors.bar_bg);
|
||||||
draw_text((char *)i3string_as_ucs2(block->full_text), i3string_get_num_glyphs(block->full_text),
|
draw_text(block->full_text, statusline_pm, statusline_ctx, x, 0, block->width);
|
||||||
true, statusline_pm, statusline_ctx, x, 0, block->width);
|
|
||||||
x += block->width;
|
x += block->width;
|
||||||
|
|
||||||
if (TAILQ_NEXT(block, blocks) != NULL) {
|
if (TAILQ_NEXT(block, blocks) != NULL) {
|
||||||
|
@ -1519,8 +1518,7 @@ void draw_bars() {
|
||||||
1,
|
1,
|
||||||
&rect);
|
&rect);
|
||||||
set_font_colors(outputs_walk->bargc, fg_color, bg_color);
|
set_font_colors(outputs_walk->bargc, fg_color, bg_color);
|
||||||
draw_text((char*)i3string_as_ucs2(ws_walk->name), i3string_get_num_glyphs(ws_walk->name), true,
|
draw_text(ws_walk->name, outputs_walk->buffer, outputs_walk->bargc, i + 5, 2, ws_walk->name_width);
|
||||||
outputs_walk->buffer, outputs_walk->bargc, i + 5, 2, ws_walk->name_width);
|
|
||||||
i += 10 + ws_walk->name_width + 1;
|
i += 10 + ws_walk->name_width + 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -297,13 +297,17 @@ void set_font_colors(xcb_gcontext_t gc, uint32_t foreground, uint32_t background
|
||||||
* specified coordinates (from the top left corner of the leftmost, uppermost
|
* specified coordinates (from the top left corner of the leftmost, uppermost
|
||||||
* glyph) and using the provided gc.
|
* glyph) and using the provided gc.
|
||||||
*
|
*
|
||||||
* Text can be specified as UCS-2 or UTF-8. If it's specified as UCS-2, then
|
* Text must be specified as an i3String.
|
||||||
* text_len must be the number of glyphs in the string. If it's specified as
|
|
||||||
* UTF-8, then text_len must be the number of bytes in the string (not counting
|
|
||||||
* the null terminator).
|
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
void draw_text(char *text, size_t text_len, bool is_ucs2, xcb_drawable_t drawable,
|
void draw_text(i3String *text, xcb_drawable_t drawable,
|
||||||
|
xcb_gcontext_t gc, int x, int y, int max_width);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* ASCII version of draw_text to print static strings.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
void draw_text_ascii(const char *text, xcb_drawable_t drawable,
|
||||||
xcb_gcontext_t gc, int x, int y, int max_width);
|
xcb_gcontext_t gc, int x, int y, int max_width);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
72
libi3/font.c
72
libi3/font.c
|
@ -105,45 +105,21 @@ void set_font_colors(xcb_gcontext_t gc, uint32_t foreground, uint32_t background
|
||||||
xcb_change_gc(conn, gc, mask, values);
|
xcb_change_gc(conn, gc, mask, values);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
static void draw_text_xcb(const xcb_char2b_t *text, size_t text_len, xcb_drawable_t drawable,
|
||||||
* Draws text onto the specified X drawable (normally a pixmap) at the
|
|
||||||
* specified coordinates (from the top left corner of the leftmost, uppermost
|
|
||||||
* glyph) and using the provided gc.
|
|
||||||
*
|
|
||||||
* Text can be specified as UCS-2 or UTF-8. If it's specified as UCS-2, then
|
|
||||||
* text_len must be the number of glyphs in the string. If it's specified as
|
|
||||||
* UTF-8, then text_len must be the number of bytes in the string (not counting
|
|
||||||
* the null terminator).
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
void draw_text(char *text, size_t text_len, bool is_ucs2, xcb_drawable_t drawable,
|
|
||||||
xcb_gcontext_t gc, int x, int y, int max_width) {
|
xcb_gcontext_t gc, int x, int y, int max_width) {
|
||||||
assert(savedFont != NULL);
|
|
||||||
assert(text_len != 0);
|
|
||||||
|
|
||||||
/* X11 coordinates for fonts start at the baseline */
|
/* X11 coordinates for fonts start at the baseline */
|
||||||
int pos_y = y + savedFont->info->font_ascent;
|
int pos_y = y + savedFont->info->font_ascent;
|
||||||
|
|
||||||
/* As an optimization, check if we can bypass conversion */
|
|
||||||
if (!is_ucs2 && text_len <= 255) {
|
|
||||||
xcb_image_text_8(conn, text_len, drawable, gc, x, pos_y, text);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Convert the text into UCS-2 so we can do basic pointer math */
|
|
||||||
char *input = (is_ucs2 ? text : (char*)convert_utf8_to_ucs2(text, &text_len));
|
|
||||||
|
|
||||||
/* The X11 protocol limits text drawing to 255 chars, so we may need
|
/* The X11 protocol limits text drawing to 255 chars, so we may need
|
||||||
* multiple calls */
|
* multiple calls */
|
||||||
int pos_x = x;
|
|
||||||
int offset = 0;
|
int offset = 0;
|
||||||
for (;;) {
|
for (;;) {
|
||||||
/* Calculate the size of this chunk */
|
/* Calculate the size of this chunk */
|
||||||
int chunk_size = (text_len > 255 ? 255 : text_len);
|
int chunk_size = (text_len > 255 ? 255 : text_len);
|
||||||
xcb_char2b_t *chunk = (xcb_char2b_t*)input + offset;
|
const xcb_char2b_t *chunk = text + offset;
|
||||||
|
|
||||||
/* Draw it */
|
/* Draw it */
|
||||||
xcb_image_text_16(conn, chunk_size, drawable, gc, pos_x, pos_y, chunk);
|
xcb_image_text_16(conn, chunk_size, drawable, gc, x, pos_y, chunk);
|
||||||
|
|
||||||
/* Advance the offset and length of the text to draw */
|
/* Advance the offset and length of the text to draw */
|
||||||
offset += chunk_size;
|
offset += chunk_size;
|
||||||
|
@ -154,12 +130,46 @@ void draw_text(char *text, size_t text_len, bool is_ucs2, xcb_drawable_t drawabl
|
||||||
break;
|
break;
|
||||||
|
|
||||||
/* Advance pos_x based on the predicted text width */
|
/* Advance pos_x based on the predicted text width */
|
||||||
pos_x += predict_text_width((char*)chunk, chunk_size, true);
|
x += predict_text_width((char*)chunk, chunk_size, true);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/* If we had to convert, free the converted string */
|
/*
|
||||||
if (!is_ucs2)
|
* Draws text onto the specified X drawable (normally a pixmap) at the
|
||||||
free(input);
|
* specified coordinates (from the top left corner of the leftmost, uppermost
|
||||||
|
* glyph) and using the provided gc.
|
||||||
|
*
|
||||||
|
* Text must be specified as an i3String.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
void draw_text(i3String *text, xcb_drawable_t drawable,
|
||||||
|
xcb_gcontext_t gc, int x, int y, int max_width) {
|
||||||
|
assert(savedFont != NULL);
|
||||||
|
|
||||||
|
draw_text_xcb(i3string_as_ucs2(text), i3string_get_num_glyphs(text),
|
||||||
|
drawable, gc, x, y, max_width);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* ASCII version of draw_text to print static strings.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
void draw_text_ascii(const char *text, xcb_drawable_t drawable,
|
||||||
|
xcb_gcontext_t gc, int x, int y, int max_width) {
|
||||||
|
assert(savedFont != NULL);
|
||||||
|
|
||||||
|
size_t text_len = strlen(text);
|
||||||
|
if (text_len > 255) {
|
||||||
|
/* The text is too long to draw it directly to X */
|
||||||
|
i3String *str = i3string_from_utf8(text);
|
||||||
|
draw_text(str, drawable, gc, x, y, max_width);
|
||||||
|
i3string_free(str);
|
||||||
|
} else {
|
||||||
|
/* X11 coordinates for fonts start at the baseline */
|
||||||
|
int pos_y = y + savedFont->info->font_ascent;
|
||||||
|
|
||||||
|
xcb_image_text_8(conn, text_len, drawable, gc, x, pos_y, text);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static int xcb_query_text_width(xcb_char2b_t *text, size_t text_len) {
|
static int xcb_query_text_width(xcb_char2b_t *text, size_t text_len) {
|
||||||
|
|
|
@ -52,7 +52,7 @@ static int sig_draw_window(xcb_window_t win, int width, int height, int font_hei
|
||||||
set_font_colors(pixmap_gc, get_colorpixel("#FFFFFF"), get_colorpixel("#000000"));
|
set_font_colors(pixmap_gc, get_colorpixel("#FFFFFF"), get_colorpixel("#000000"));
|
||||||
|
|
||||||
for (int i = 0; crash_text_i3strings[i] != NULL; ++i) {
|
for (int i = 0; crash_text_i3strings[i] != NULL; ++i) {
|
||||||
draw_text((char *)i3string_as_ucs2(crash_text_i3strings[i]), i3string_get_num_glyphs(crash_text_i3strings[i]), true, pixmap, pixmap_gc,
|
draw_text(crash_text_i3strings[i], pixmap, pixmap_gc,
|
||||||
8, 5 + i * font_height, width - 16);
|
8, 5 + i * font_height, width - 16);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
4
src/x.c
4
src/x.c
|
@ -484,7 +484,7 @@ void x_draw_decoration(Con *con) {
|
||||||
if (win == NULL || win->name == NULL) {
|
if (win == NULL || win->name == NULL) {
|
||||||
/* this is a non-leaf container, we need to make up a good description */
|
/* this is a non-leaf container, we need to make up a good description */
|
||||||
// TODO: use a good description instead of just "another container"
|
// TODO: use a good description instead of just "another container"
|
||||||
draw_text("another container", strlen("another container"), false,
|
draw_text_ascii("another container",
|
||||||
parent->pixmap, parent->pm_gc,
|
parent->pixmap, parent->pm_gc,
|
||||||
con->deco_rect.x + 2, con->deco_rect.y + text_offset_y,
|
con->deco_rect.x + 2, con->deco_rect.y + text_offset_y,
|
||||||
con->deco_rect.width - 2);
|
con->deco_rect.width - 2);
|
||||||
|
@ -508,7 +508,7 @@ void x_draw_decoration(Con *con) {
|
||||||
//DLOG("indent_level = %d, indent_mult = %d\n", indent_level, indent_mult);
|
//DLOG("indent_level = %d, indent_mult = %d\n", indent_level, indent_mult);
|
||||||
int indent_px = (indent_level * 5) * indent_mult;
|
int indent_px = (indent_level * 5) * indent_mult;
|
||||||
|
|
||||||
draw_text((char *)i3string_as_ucs2(win->name), i3string_get_num_glyphs(win->name), true,
|
draw_text(win->name,
|
||||||
parent->pixmap, parent->pm_gc,
|
parent->pixmap, parent->pm_gc,
|
||||||
con->deco_rect.x + 2 + indent_px, con->deco_rect.y + text_offset_y,
|
con->deco_rect.x + 2 + indent_px, con->deco_rect.y + text_offset_y,
|
||||||
con->deco_rect.width - 2 - indent_px);
|
con->deco_rect.width - 2 - indent_px);
|
||||||
|
|
Loading…
Reference in New Issue