]> git.sur5r.net Git - i3/i3/commitdiff
libi3: Rework draw_text
authorQuentin Glidic <sardemff7+git@sardemff7.net>
Tue, 7 Aug 2012 18:28:39 +0000 (20:28 +0200)
committerQuentin Glidic <sardemff7+git@sardemff7.net>
Mon, 13 Aug 2012 09:37:21 +0000 (11:37 +0200)
We now have two versions of draw_text
draw_text: Now takes an i3String
draw_text_ascii: Designed for static strings in plain ASCII

i3-config-wizard/main.c
i3-input/main.c
i3-nagbar/main.c
i3bar/src/xcb.c
include/libi3.h
libi3/font.c
src/sighandler.c
src/x.c

index be042673f2c53a02a1bbe8855fa13f38ced2b9c0..4c04a6d2662e8424f3146aec6174be9b74ed03e0 100644 (file)
@@ -128,7 +128,7 @@ static int handle_expose() {
     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) {
index 9ab40aec2220b9f024c179ca68e72510d71e66ee..6f5ad78a77713b6eac9aedcfc26fcdfbd97aebe2 100644 (file)
@@ -98,11 +98,15 @@ static int handle_expose(void *data, xcb_connection_t *conn, xcb_expose_event_t
 
     /* 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);
index 7a09b99d6b76740a598ea68befbc89aa16fa284a..26a282f6521167c3d562723b965e74adc6e9da61 100644 (file)
@@ -132,7 +132,7 @@ static int handle_expose(xcb_connection_t *conn, xcb_expose_event_t *event) {
 
     /* 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 */
@@ -159,7 +159,7 @@ static int handle_expose(xcb_connection_t *conn, xcb_expose_event_t *event) {
 
     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;
 
@@ -190,7 +190,7 @@ static int handle_expose(xcb_connection_t *conn, xcb_expose_event_t *event) {
         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;
index be3ca35aa040a4ca82a466f080f5fa1e09ca5d45..729803e1cd325ac51bcf48188db1a7e7de4af071 100644 (file)
@@ -144,8 +144,7 @@ void refresh_statusline() {
 
         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) {
@@ -1519,8 +1518,7 @@ void draw_bars() {
                                     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;
         }
 
index 97383ba301ab010a5959a8b5d3aaabe5a4318b1c..29b8c107ccc17dc507c21e9da96560889b457323 100644 (file)
@@ -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
  * 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);
 
 /**
index 0b276b0b3f52c48f9afe5b3011c1dfcf8bb8dbc9..853e5f92e9e7a32d45152cdbb6c549782915d4e1 100644 (file)
@@ -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);
 }
 
-/*
- * 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;
@@ -154,12 +130,46 @@ void draw_text(char *text, size_t text_len, bool is_ucs2, xcb_drawable_t drawabl
             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) {
index 2c53333d854e2580f43f8b2c40dc82d687390a19..e9a4e9bfaa970930855049049545cb7d3e445caa 100644 (file)
@@ -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"));
 
     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);
     }
 
diff --git a/src/x.c b/src/x.c
index 864949e5281fa56e78a0a9e15abc6974884e8fe3..24fd0eac81d425b2f7db70d6954374338b5141cb 100644 (file)
--- a/src/x.c
+++ b/src/x.c
@@ -484,7 +484,7 @@ void x_draw_decoration(Con *con) {
     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);
@@ -508,7 +508,7 @@ void x_draw_decoration(Con *con) {
     //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);