diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/entry.c | 26 | ||||
-rw-r--r-- | src/entry.h | 7 | ||||
-rw-r--r-- | src/entry_backend/harfbuzz.c | 48 | ||||
-rw-r--r-- | src/entry_backend/harfbuzz.h | 8 | ||||
-rw-r--r-- | src/entry_backend/pango.c | 24 | ||||
-rw-r--r-- | src/entry_backend/pango.h | 8 |
6 files changed, 70 insertions, 51 deletions
diff --git a/src/entry.c b/src/entry.c index b3292ce..9050874 100644 --- a/src/entry.c +++ b/src/entry.c @@ -1,6 +1,7 @@ #include <cairo/cairo.h> #include <math.h> #include <wchar.h> +#include <unistd.h> #include "entry.h" #include "log.h" #include "nelem.h" @@ -114,7 +115,18 @@ void entry_init(struct entry *entry, uint8_t *restrict buffer, uint32_t width, u cairo_clip(cr); /* Setup the backend. */ - entry_backend_init(entry, &width, &height); + if (access(entry->font_name, R_OK) != 0) { + /* + * We've been given a font name rather than path, + * so fallback to Pango + */ + entry->use_pango = true; + } + if (entry->use_pango) { + entry_backend_pango_init(entry, &width, &height); + } else { + entry_backend_harfbuzz_init(entry, &width, &height); + } /* * To avoid performing all this drawing twice, we take a small @@ -139,7 +151,11 @@ void entry_init(struct entry *entry, uint8_t *restrict buffer, uint32_t width, u void entry_destroy(struct entry *entry) { - entry_backend_destroy(entry); + if (entry->use_pango) { + entry_backend_pango_destroy(entry); + } else { + entry_backend_harfbuzz_destroy(entry); + } cairo_destroy(entry->cairo[0].cr); cairo_destroy(entry->cairo[1].cr); cairo_surface_destroy(entry->cairo[0].surface); @@ -164,7 +180,11 @@ void entry_update(struct entry *entry) color = entry->foreground_color; cairo_set_source_rgba(cr, color.r, color.g, color.b, color.a); - entry_backend_update(entry); + if (entry->use_pango) { + entry_backend_pango_update(entry); + } else { + entry_backend_harfbuzz_update(entry); + } cairo_restore(cr); log_debug("Finish rendering entry.\n"); diff --git a/src/entry.h b/src/entry.h index f1187d3..1b8bfe4 100644 --- a/src/entry.h +++ b/src/entry.h @@ -1,11 +1,8 @@ #ifndef ENTRY_H #define ENTRY_H -#ifdef USE_PANGO #include "entry_backend/pango.h" -#else #include "entry_backend/harfbuzz.h" -#endif #include <cairo/cairo.h> #include <wchar.h> @@ -21,7 +18,8 @@ struct entry { struct image image; - struct entry_backend backend; + struct entry_backend_harfbuzz harfbuzz; + struct entry_backend_pango pango; struct { cairo_surface_t *surface; cairo_t *cr; @@ -38,6 +36,7 @@ struct entry { struct string_vec results; struct string_vec commands; struct history history; + bool use_pango; /* Options */ bool horizontal; diff --git a/src/entry_backend/harfbuzz.c b/src/entry_backend/harfbuzz.c index 0a46eed..61a691f 100644 --- a/src/entry_backend/harfbuzz.c +++ b/src/entry_backend/harfbuzz.c @@ -100,7 +100,7 @@ static uint32_t render_hb_buffer(cairo_t *cr, hb_buffer_t *buffer) return ceil(width); } -void entry_backend_init( +void entry_backend_harfbuzz_init( struct entry *entry, uint32_t *width, uint32_t *height) @@ -110,7 +110,7 @@ void entry_backend_init( /* Setup FreeType. */ log_debug("Creating FreeType library.\n"); int err; - err = FT_Init_FreeType(&entry->backend.ft_library); + err = FT_Init_FreeType(&entry->harfbuzz.ft_library); if (err) { log_error("Error initialising FreeType: %s\n", get_ft_error_string(err)); @@ -119,14 +119,14 @@ void entry_backend_init( log_debug("Loading FreeType font.\n"); err = FT_New_Face( - entry->backend.ft_library, "font.ttf", 0, - &entry->backend.ft_face); + entry->harfbuzz.ft_library, entry->font_name, 0, + &entry->harfbuzz.ft_face); if (err) { log_error("Error loading font: %s\n", get_ft_error_string(err)); exit(EXIT_FAILURE); } err = FT_Set_Char_Size( - entry->backend.ft_face, + entry->harfbuzz.ft_face, entry->font_size * 64, entry->font_size * 64, 96, @@ -137,12 +137,12 @@ void entry_backend_init( } log_debug("Creating Cairo font.\n"); - entry->backend.cairo_face = - cairo_ft_font_face_create_for_ft_face(entry->backend.ft_face, 0); + entry->harfbuzz.cairo_face = + cairo_ft_font_face_create_for_ft_face(entry->harfbuzz.ft_face, 0); struct color color = entry->foreground_color; cairo_set_source_rgba(cr, color.r, color.g, color.b, color.a); - cairo_set_font_face(cr, entry->backend.cairo_face); + cairo_set_font_face(cr, entry->harfbuzz.cairo_face); cairo_set_font_size(cr, entry->font_size * PT_TO_DPI); cairo_font_options_t *opts = cairo_font_options_create(); //cairo_font_options_set_hint_style(opts, CAIRO_HINT_STYLE_NONE); @@ -150,25 +150,25 @@ void entry_backend_init( /* We also need to set up the font for our other Cairo context. */ - cairo_set_font_face(entry->cairo[1].cr, entry->backend.cairo_face); + cairo_set_font_face(entry->cairo[1].cr, entry->harfbuzz.cairo_face); cairo_set_font_size(entry->cairo[1].cr, entry->font_size * PT_TO_DPI); cairo_set_font_options(entry->cairo[1].cr, opts); cairo_font_options_destroy(opts); log_debug("Creating Harfbuzz font.\n"); - entry->backend.hb_font = - hb_ft_font_create_referenced(entry->backend.ft_face); + entry->harfbuzz.hb_font = + hb_ft_font_create_referenced(entry->harfbuzz.ft_face); log_debug("Creating Harfbuzz buffer.\n"); hb_buffer_t *buffer = hb_buffer_create(); - entry->backend.hb_buffer = buffer; + entry->harfbuzz.hb_buffer = buffer; setup_hb_buffer(buffer); /* Draw the prompt now, as this only needs to be done once */ log_debug("Drawing prompt.\n"); - hb_buffer_add_utf8(entry->backend.hb_buffer, entry->prompt_text, -1, 0, -1); - hb_shape(entry->backend.hb_font, entry->backend.hb_buffer, NULL, 0); + hb_buffer_add_utf8(entry->harfbuzz.hb_buffer, entry->prompt_text, -1, 0, -1); + hb_shape(entry->harfbuzz.hb_font, entry->harfbuzz.hb_buffer, NULL, 0); uint32_t prompt_width = render_hb_buffer(cr, buffer); /* Move and clip so we don't draw over the prompt later */ @@ -178,26 +178,26 @@ void entry_backend_init( cairo_clip(cr); } -void entry_backend_destroy(struct entry *entry) +void entry_backend_harfbuzz_destroy(struct entry *entry) { - hb_buffer_destroy(entry->backend.hb_buffer); - hb_font_destroy(entry->backend.hb_font); - cairo_font_face_destroy(entry->backend.cairo_face); - FT_Done_Face(entry->backend.ft_face); - FT_Done_FreeType(entry->backend.ft_library); + hb_buffer_destroy(entry->harfbuzz.hb_buffer); + hb_font_destroy(entry->harfbuzz.hb_font); + cairo_font_face_destroy(entry->harfbuzz.cairo_face); + FT_Done_Face(entry->harfbuzz.ft_face); + FT_Done_FreeType(entry->harfbuzz.ft_library); } -void entry_backend_update(struct entry *entry) +void entry_backend_harfbuzz_update(struct entry *entry) { cairo_t *cr = entry->cairo[entry->index].cr; - hb_buffer_t *buffer = entry->backend.hb_buffer; + hb_buffer_t *buffer = entry->harfbuzz.hb_buffer; uint32_t width; /* Render the entry text */ hb_buffer_clear_contents(buffer); setup_hb_buffer(buffer); hb_buffer_add_utf8(buffer, entry->input_mb, -1, 0, -1); - hb_shape(entry->backend.hb_font, buffer, NULL, 0); + hb_shape(entry->harfbuzz.hb_font, buffer, NULL, 0); width = render_hb_buffer(cr, buffer); cairo_font_extents_t font_extents; @@ -214,7 +214,7 @@ void entry_backend_update(struct entry *entry) hb_buffer_clear_contents(buffer); setup_hb_buffer(buffer); hb_buffer_add_utf8(buffer, entry->results.buf[i], -1, 0, -1); - hb_shape(entry->backend.hb_font, buffer, NULL, 0); + hb_shape(entry->harfbuzz.hb_font, buffer, NULL, 0); if (i == entry->selection) { cairo_save(cr); struct color color = entry->selection_color; diff --git a/src/entry_backend/harfbuzz.h b/src/entry_backend/harfbuzz.h index 1917632..8404032 100644 --- a/src/entry_backend/harfbuzz.h +++ b/src/entry_backend/harfbuzz.h @@ -8,7 +8,7 @@ struct entry; -struct entry_backend { +struct entry_backend_harfbuzz { FT_Library ft_library; FT_Face ft_face; @@ -18,8 +18,8 @@ struct entry_backend { hb_buffer_t *hb_buffer; }; -void entry_backend_init(struct entry *entry, uint32_t *width, uint32_t *height); -void entry_backend_destroy(struct entry *entry); -void entry_backend_update(struct entry *entry); +void entry_backend_harfbuzz_init(struct entry *entry, uint32_t *width, uint32_t *height); +void entry_backend_harfbuzz_destroy(struct entry *entry); +void entry_backend_harfbuzz_update(struct entry *entry); #endif /* ENTRY_BACKEND_HARFBUZZ_H */ diff --git a/src/entry_backend/pango.c b/src/entry_backend/pango.c index d645dc9..49365fb 100644 --- a/src/entry_backend/pango.c +++ b/src/entry_backend/pango.c @@ -5,7 +5,7 @@ #include "../log.h" #include "../nelem.h" -void entry_backend_init(struct entry *entry, uint32_t *width, uint32_t *height) +void entry_backend_pango_init(struct entry *entry, uint32_t *width, uint32_t *height) { cairo_t *cr = entry->cairo[0].cr; @@ -23,38 +23,38 @@ void entry_backend_init(struct entry *entry, uint32_t *width, uint32_t *height) pango_context_set_font_description(context, font_description); pango_font_description_free(font_description); - entry->backend.layout = pango_layout_new(context); + entry->pango.layout = pango_layout_new(context); log_debug("Setting Pango text.\n"); - pango_layout_set_text(entry->backend.layout, entry->prompt_text, -1); + pango_layout_set_text(entry->pango.layout, entry->prompt_text, -1); log_debug("First Pango draw.\n"); - pango_cairo_update_layout(cr, entry->backend.layout); + pango_cairo_update_layout(cr, entry->pango.layout); /* Draw the prompt now, as this only needs to be done once */ struct color color = entry->foreground_color; cairo_set_source_rgba(cr, color.r, color.g, color.b, color.a); - pango_cairo_show_layout(cr, entry->backend.layout); + pango_cairo_show_layout(cr, entry->pango.layout); /* Move and clip so we don't draw over the prompt */ int prompt_width; - pango_layout_get_pixel_size(entry->backend.layout, &prompt_width, NULL); + pango_layout_get_pixel_size(entry->pango.layout, &prompt_width, NULL); cairo_translate(cr, prompt_width, 0); *width -= prompt_width; cairo_rectangle(cr, 0, 0, *width, *height); cairo_clip(cr); - entry->backend.context = context; + entry->pango.context = context; } -void entry_backend_destroy(struct entry *entry) +void entry_backend_pango_destroy(struct entry *entry) { - g_object_unref(entry->backend.layout); - g_object_unref(entry->backend.context); + g_object_unref(entry->pango.layout); + g_object_unref(entry->pango.context); } -void entry_backend_update(struct entry *entry) +void entry_backend_pango_update(struct entry *entry) { cairo_t *cr = entry->cairo[entry->index].cr; - PangoLayout *layout = entry->backend.layout; + PangoLayout *layout = entry->pango.layout; pango_layout_set_text(layout, entry->input_mb, -1); pango_cairo_update_layout(cr, layout); diff --git a/src/entry_backend/pango.h b/src/entry_backend/pango.h index 769a992..b2b1ba2 100644 --- a/src/entry_backend/pango.h +++ b/src/entry_backend/pango.h @@ -5,13 +5,13 @@ struct entry; -struct entry_backend { +struct entry_backend_pango { PangoContext *context; PangoLayout *layout; }; -void entry_backend_init(struct entry *entry, uint32_t *width, uint32_t *height); -void entry_backend_destroy(struct entry *entry); -void entry_backend_update(struct entry *entry); +void entry_backend_pango_init(struct entry *entry, uint32_t *width, uint32_t *height); +void entry_backend_pango_destroy(struct entry *entry); +void entry_backend_pango_update(struct entry *entry); #endif /* ENTRY_BACKEND_PANGO_H */ |