set_font(&font);
#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)
if (current_step == STEP_WELCOME) {
/* draw the prompt … */
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 */
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 */
xcb_copy_area(conn, pixmap, win, pixmap_gc, 0, 0, 0, 0, /* */ 500, font.height + 8);
/* restore font color */
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);
/* render close button */
values[0] = 1;
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);
y -= w;
values[0] = color_text;
values[1] = 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;
uint32_t colorpixel = (block->color ? get_colorpixel(block->color) : colors.bar_fg);
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),
- true, statusline_pm, statusline_ctx, x, 0, block->width);
+ draw_text(block->full_text, statusline_pm, statusline_ctx, x, 0, block->width);
x += block->width;
if (TAILQ_NEXT(block, blocks) != NULL) {
1,
&rect);
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,
- outputs_walk->buffer, outputs_walk->bargc, i + 5, 2, ws_walk->name_width);
+ draw_text(ws_walk->name, outputs_walk->buffer, outputs_walk->bargc, i + 5, 2, ws_walk->name_width);
i += 10 + ws_walk->name_width + 1;
}
* 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).
+ * Text must be specified as an i3String.
*
*/
-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_change_gc(conn, gc, mask, values);
}
-/*
- * 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,
+static void draw_text_xcb(const xcb_char2b_t *text, size_t text_len, xcb_drawable_t drawable,
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 */
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
* multiple calls */
- int pos_x = x;
int offset = 0;
for (;;) {
/* Calculate the size of this chunk */
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 */
- 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 */
offset += chunk_size;
break;
/* 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)
- free(input);
+/*
+ * 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 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) {
set_font_colors(pixmap_gc, get_colorpixel("#FFFFFF"), get_colorpixel("#000000"));
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);
}
if (win == NULL || win->name == NULL) {
/* this is a non-leaf container, we need to make up a good description */
// 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,
con->deco_rect.x + 2, con->deco_rect.y + text_offset_y,
con->deco_rect.width - 2);
//DLOG("indent_level = %d, indent_mult = %d\n", indent_level, 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,
con->deco_rect.x + 2 + indent_px, con->deco_rect.y + text_offset_y,
con->deco_rect.width - 2 - indent_px);