diff options
Diffstat (limited to 'src/entry.c')
-rw-r--r-- | src/entry.c | 295 |
1 files changed, 120 insertions, 175 deletions
diff --git a/src/entry.c b/src/entry.c index 95ab308..b08623c 100644 --- a/src/entry.c +++ b/src/entry.c @@ -13,14 +13,32 @@ #define TWO_PI 6.283185307179586f #endif -static void calculate_font_extents(struct entry *entry, uint32_t scale); -static void draw_circles(struct entry *entry); +void entry_preload(void) +{ + cairo_surface_t *surface = cairo_image_surface_create( + CAIRO_FORMAT_ARGB32, + 10, + 10 + ); + cairo_t *cr = cairo_create(surface); + + PangoContext *context = pango_cairo_create_context(cr); + PangoLayout *layout = pango_layout_new(context); + pango_layout_set_text(layout, "test", -1); + pango_cairo_update_layout(cr, layout); + pango_cairo_show_layout(cr, layout); + g_object_unref(layout); + g_object_unref(context); + cairo_destroy(cr); + cairo_surface_destroy(surface); +} void entry_init(struct entry *entry, uint32_t scale) { - entry->dot_radius = entry->font_size >> 3; /* Calculate the size of the entry from our font and various widths. */ - calculate_font_extents(entry, scale); + //calculate_font_extents(entry, scale); + entry->text_bounds.width = 500; + entry->text_bounds.height = 800; entry->surface.width = entry->text_bounds.width; entry->surface.height = entry->text_bounds.height; @@ -62,82 +80,87 @@ void entry_init(struct entry *entry, uint32_t scale) int32_t height = entry->surface.height / scale; /* Draw the outer outline */ - struct color color = entry->border.outline_color; - cairo_set_source_rgba(cr, color.r, color.g, color.b, color.a); - cairo_paint(cr); - - /* Move and clip following draws to be within this outline */ - cairo_translate( - cr, - entry->border.outline_width, - entry->border.outline_width); - width -= 2 * entry->border.outline_width; - height -= 2 * entry->border.outline_width; - cairo_rectangle(cr, 0, 0, width, height); - cairo_clip(cr); - - /* Draw the border */ - color = entry->border.color; - cairo_set_source_rgba(cr, color.r, color.g, color.b, color.a); - cairo_paint(cr); - - /* Move and clip following draws to be within the border */ - cairo_translate(cr, entry->border.width, entry->border.width); - width -= 2 * entry->border.width; - height -= 2 * entry->border.width; - cairo_rectangle(cr, 0, 0, width, height); - cairo_clip(cr); - - /* Draw the inner outline */ - color = entry->border.outline_color; - cairo_set_source_rgba(cr, color.r, color.g, color.b, color.a); - cairo_paint(cr); - - /* Move and clip following draws to be within this outline */ - cairo_translate( - cr, - entry->border.outline_width, - entry->border.outline_width); - width -= 2 * entry->border.outline_width; - height -= 2 * entry->border.outline_width; - cairo_rectangle(cr, 0, 0, width, height); - cairo_clip(cr); - - /* Draw the entry background */ - color = entry->background_color; - cairo_set_source_rgba(cr, color.r, color.g, color.b, color.a); - cairo_paint(cr); - - /* Move and clip following draws to be within the specified padding */ - cairo_translate(cr, entry->padding, entry->padding); - width -= 2 * entry->padding; - height -= 2 * entry->padding; - cairo_rectangle(cr, 0, 0, width, height); - cairo_clip(cr); + //struct color color = entry->border.outline_color; + //cairo_set_source_rgba(cr, color.r, color.g, color.b, color.a); + //cairo_paint(cr); + + ///* Move and clip following draws to be within this outline */ + //cairo_translate( + // cr, + // entry->border.outline_width, + // entry->border.outline_width); + //width -= 2 * entry->border.outline_width; + //height -= 2 * entry->border.outline_width; + //cairo_rectangle(cr, 0, 0, width, height); + //cairo_clip(cr); + + ///* Draw the border */ + //color = entry->border.color; + //cairo_set_source_rgba(cr, color.r, color.g, color.b, color.a); + //cairo_paint(cr); + + ///* Move and clip following draws to be within the border */ + //cairo_translate(cr, entry->border.width, entry->border.width); + //width -= 2 * entry->border.width; + //height -= 2 * entry->border.width; + //cairo_rectangle(cr, 0, 0, width, height); + //cairo_clip(cr); + + ///* Draw the inner outline */ + //color = entry->border.outline_color; + //cairo_set_source_rgba(cr, color.r, color.g, color.b, color.a); + //cairo_paint(cr); + + ///* Move and clip following draws to be within this outline */ + //cairo_translate( + // cr, + // entry->border.outline_width, + // entry->border.outline_width); + //width -= 2 * entry->border.outline_width; + //height -= 2 * entry->border.outline_width; + //cairo_rectangle(cr, 0, 0, width, height); + //cairo_clip(cr); + + ///* Draw the entry background */ + //color = entry->background_color; + //cairo_set_source_rgba(cr, color.r, color.g, color.b, color.a); + //cairo_paint(cr); + + ///* Move and clip following draws to be within the specified padding */ + //cairo_translate(cr, entry->padding, entry->padding); + //width -= 2 * entry->padding; + //height -= 2 * entry->padding; + //cairo_rectangle(cr, 0, 0, width, height); + //cairo_clip(cr); /* * Move the cursor back up, so that Pango draws in the correct place if * we're doing a tight layout. */ - cairo_translate(cr, -entry->text_bounds.x, -entry->text_bounds.y); + //cairo_translate(cr, -entry->text_bounds.x, -entry->text_bounds.y); /* Setup Pango. */ - if (entry->use_pango) { - PangoContext *context = pango_cairo_create_context(cr); - PangoLayout *layout = pango_layout_new(context); - pango_layout_set_text(layout, "", -1); + PangoContext *context = pango_cairo_create_context(cr); - PangoFontDescription *font_description = - pango_font_description_from_string(entry->font_name); - pango_font_description_set_size( - font_description, - entry->font_size * PANGO_SCALE); - pango_layout_set_font_description(layout, font_description); - pango_font_description_free(font_description); + PangoFontDescription *font_description = + pango_font_description_from_string(entry->font_name); + pango_font_description_set_size( + font_description, + entry->font_size * PANGO_SCALE); + pango_context_set_font_description(context, font_description); + pango_font_description_free(font_description); + + entry->pango.entry_layout = pango_layout_new(context); + pango_layout_set_text(entry->pango.entry_layout, "", -1); - entry->pango.context = context; - entry->pango.layout = layout; + for (size_t i = 0; i < 5; i++) { + PangoLayout *layout = pango_layout_new(context); + pango_layout_set_text(layout, "", -1); + entry->pango.result_layouts[i] = layout; } + + entry->pango.context = context; + entry->cairo.surface = surface; entry->cairo.cr = cr; @@ -148,10 +171,11 @@ void entry_init(struct entry *entry, uint32_t scale) void entry_destroy(struct entry *entry) { - if (entry->use_pango) { - g_object_unref(entry->pango.layout); - g_object_unref(entry->pango.context); + for (size_t i = 0; i < 5; i++) { + g_object_unref(entry->pango.result_layouts[i]); } + g_object_unref(entry->pango.entry_layout); + g_object_unref(entry->pango.context); cairo_destroy(entry->cairo.cr); cairo_surface_destroy(entry->cairo.surface); } @@ -159,120 +183,41 @@ void entry_destroy(struct entry *entry) void entry_update(struct entry *entry) { cairo_t *cr = entry->cairo.cr; - PangoLayout *layout = entry->pango.layout; + cairo_save(cr); entry->image.redraw = true; - /* Redraw the background. */ - struct color color = entry->background_color; - cairo_set_source_rgba(cr, color.r, color.g, color.b, color.a); + /* Clear the image. */ + cairo_set_operator(cr, CAIRO_OPERATOR_CLEAR); cairo_paint(cr); + cairo_set_operator(cr, CAIRO_OPERATOR_OVER); /* Draw our text. */ - color = entry->foreground_color; + struct color color = entry->foreground_color; cairo_set_source_rgba(cr, color.r, color.g, color.b, color.a); - if (!entry->use_pango) { - draw_circles(entry); - return; - } - size_t len = 0; - for (unsigned int i = 0; i < entry->password_length; i++) { - len += wcrtomb(entry->password_mb_print + len, entry->password_character, NULL); + pango_layout_set_text(entry->pango.entry_layout, entry->input_mb, -1); + pango_cairo_update_layout(cr, entry->pango.entry_layout); + pango_cairo_show_layout(cr, entry->pango.entry_layout); + + log_debug("%zu\n", entry->results.count); + for (size_t i = 0; i < 5; i++) { + cairo_translate(cr, 0, 50); + PangoLayout *layout = entry->pango.result_layouts[i]; + const char *str; + if (i < entry->results.count) { + str = entry->results.buf[i]; + } else { + str = ""; + } + pango_layout_set_text(layout, str, -1); + pango_cairo_update_layout(cr, layout); + pango_cairo_show_layout(cr, layout); } - entry->password_mb_print[len] = '\0'; - pango_layout_set_text(layout, entry->password_mb_print, -1); - pango_cairo_update_layout(cr, layout); - pango_cairo_show_layout(cr, layout); + cairo_restore(cr); } void entry_set_scale(struct entry *entry, uint32_t scale) { cairo_surface_set_device_scale(entry->cairo.surface, scale, scale); } - -void calculate_font_extents(struct entry *entry, uint32_t scale) -{ - if (!entry->use_pango) { - /* If we're not using pango, just do a simple calculation. */ - entry->text_bounds.height = 2 * entry->dot_radius; - entry->text_bounds.width = 3 * entry->num_characters * entry->dot_radius; - return; - } - /* - * To calculate the size of the password box, we do the following: - * 1. Load the font we're going to use. - * 2. Create a string of the desired length using the specified - * password character, e.g. ".......". - * 3. Render the string with Pango in some abstract layout. - * 4. Measure the bounding box of the layout. - * 5. Add on the size of the border / outline. - */ - PangoFontMap *font_map = pango_cairo_font_map_get_default(); - PangoContext *context = pango_font_map_create_context(font_map); - - PangoFontDescription *font_description = - pango_font_description_from_string(entry->font_name); - pango_font_description_set_size( - font_description, - entry->font_size * PANGO_SCALE); - pango_context_set_font_description(context, font_description); - -#ifdef DEBUG - { - PangoFont *font = - pango_context_load_font(context, font_description); - PangoFontDescription *desc = pango_font_describe(font); - char *string = pango_font_description_to_string(desc); - log_debug("Using font: %s\n", string); - - g_free(string); - pango_font_description_free(desc); - g_object_unref(font); - } -#endif - pango_font_description_free(font_description); - - PangoLayout *layout = pango_layout_new(context); - char *buf = calloc(MAX_PASSWORD_LENGTH, 4); - size_t len = 0; - for (unsigned int i = 0; i < entry->num_characters; i++) { - len += wcrtomb(buf + len, entry->password_character, NULL); - } - buf[len] = '\0'; - pango_layout_set_text(layout, buf, -1); - free(buf); - - PangoRectangle rect; - if (entry->tight_layout) { - pango_layout_get_pixel_extents(layout, &rect, NULL); - } else { - pango_layout_get_pixel_extents(layout, NULL, &rect); - } - /* - * TODO: This extra 1px padding is needed for certain fonts, why? - */ - rect.width += 2; - rect.height += 2; - rect.x -= 1; - rect.y -= 1; - - entry->text_bounds = rect; - - g_object_unref(layout); - g_object_unref(context); -} - -void draw_circles(struct entry *entry) -{ - cairo_t *cr = entry->cairo.cr; - uint32_t radius = entry->dot_radius; - cairo_save(cr); - cairo_translate(cr, radius, radius); - for (uint32_t i = 0; i < entry->password_length && i < entry->num_characters; i++) { - /* Draw circles with a one-radius gap between them. */ - cairo_arc(cr, 3 * i * radius, 0, radius, 0, TWO_PI); - } - cairo_fill(cr); - cairo_restore(cr); -} |