]> git.mdlowis.com Git - proto/labwc.git/commitdiff
Make font_texture_create() more generic
authorJohan Malm <jgm323@gmail.com>
Sat, 7 Aug 2021 07:35:46 +0000 (08:35 +0100)
committerJohan Malm <jgm323@gmail.com>
Sat, 7 Aug 2021 07:35:46 +0000 (08:35 +0100)
Move font_texture_create() to font.c so it can be used for purposes other
than rendering the menu, for example server side decoration.

Refactor menu.c and menu.h to use this more generic font_texture_create()

include/common/font.h
include/menu/menu.h
src/common/font.c
src/menu/menu.c
src/output.c

index 701ead53afd41991243657675589fe30386e7786..efcf48b4dd634786b9774219a13fcf659eb7714b 100644 (file)
@@ -1,12 +1,28 @@
 #ifndef __LABWC_FONT_H
 #define __LABWC_FONT_H
 
+struct server;
+struct wlr_texture;
+struct wlr_box;
+
 /**
  * font_height - get font vertical extents
  * @font_description: string describing font, for example 'sans 10'
  */
 int font_height(const char *font_description);
 
+/**
+ * texture_create - Create ARGB8888 texture using pango
+ * @server: context (for wlr_renderer)
+ * @texture: texture pointer; existing pointer will be freed
+ * @max_width: max allowable width; will be ellipsized if longer
+ * @text: text to be generated as texture
+ * @font: font description
+ * @color: foreground color in rgba format
+ */
+void font_texture_create(struct server *server, struct wlr_texture **texture,
+       int max_width, const char *text, const char *font, float *color);
+
 /**
  * font_finish - free some font related resources
  * Note: use on exit
index 16291cbea5703b8fe40b0260e00fd0ca283bccbd..b0c286ca6f953aa4af94bb2f539a2295930becff 100644 (file)
@@ -7,9 +7,13 @@
 struct menuitem {
        char *action;
        char *command;
-       struct wlr_box geo_box;
-       struct wlr_texture *active_texture;
-       struct wlr_texture *inactive_texture;
+       struct wlr_box box;
+       struct {
+               struct wlr_texture *active;
+               struct wlr_texture *inactive;
+               int offset_x;
+               int offset_y;
+       } texture;
        bool selected;
        struct wl_list link;
 };
index 5053cc1e32fa812f770307dd15e64b032a06de17..2bdfa6eaa8cd326bb44a55bb5067459390a008af 100644 (file)
@@ -1,7 +1,11 @@
 #include <cairo.h>
+#include <drm_fourcc.h>
 #include <pango/pangocairo.h>
-
+#include <wlr/render/wlr_renderer.h>
+#include <wlr/util/box.h>
+#include <wlr/util/log.h>
 #include "common/font.h"
+#include "labwc.h"
 
 static PangoRectangle
 font_extents(const char *font_description, const char *string)
@@ -43,6 +47,53 @@ font_height(const char *font_description)
        return rectangle.height;
 }
 
+void
+font_texture_create(struct server *server, struct wlr_texture **texture,
+               int max_width, const char *text, const char *font, float *color)
+{
+       if (!text || !*text) {
+               return;
+       }
+       if (*texture) {
+               wlr_texture_destroy(*texture);
+               *texture = NULL;
+       }
+
+       PangoRectangle rect = font_extents(font, text);
+       if (max_width && rect.width > max_width) {
+               rect.width = max_width;
+       }
+
+       cairo_surface_t *surf = cairo_image_surface_create(CAIRO_FORMAT_ARGB32,
+               rect.width, rect.height);
+       cairo_t *cairo = cairo_create(surf);
+
+       cairo_set_source_rgba(cairo, color[0], color[1], color[2], color[3]);
+       cairo_move_to(cairo, 0, 0);
+
+       PangoLayout *layout = pango_cairo_create_layout(cairo);
+       pango_layout_set_width(layout, rect.width * PANGO_SCALE);
+       pango_layout_set_text(layout, text, -1);
+       pango_layout_set_ellipsize(layout, PANGO_ELLIPSIZE_END);
+
+       PangoFontDescription *desc = pango_font_description_from_string(font);
+       pango_layout_set_font_description(layout, desc);
+       pango_font_description_free(desc);
+       pango_cairo_update_layout(cairo, layout);
+
+       pango_cairo_show_layout(cairo, layout);
+       g_object_unref(layout);
+
+       cairo_surface_flush(surf);
+       unsigned char *data = cairo_image_surface_get_data(surf);
+       *texture = wlr_texture_from_pixels(server->renderer, DRM_FORMAT_ARGB8888,
+                       cairo_image_surface_get_stride(surf), rect.width,
+                       rect.height, data);
+
+       cairo_destroy(cairo);
+       cairo_surface_destroy(surf);
+}
+
 void
 font_finish(void)
 {
index c2f02a3f82d7e2134c69874c57f88bd54077b7ba..422faf7f88887d74ab4508db223147254c61ba66 100644 (file)
@@ -1,11 +1,8 @@
 #define _POSIX_C_SOURCE 200809L
 #include <assert.h>
-#include <cairo.h>
 #include <ctype.h>
-#include <drm_fourcc.h>
 #include <libxml/parser.h>
 #include <libxml/tree.h>
-#include <pango/pangocairo.h>
 #include <stdio.h>
 #include <stdlib.h>
 #include <string.h>
 #include "menu/menu.h"
 #include "theme.h"
 
-static const char font[] = "Sans 8";
-
 /* state-machine variables for processing <item></item> */
 static bool in_item = false;
 static struct menuitem *current_item;
 
-#define MENUWIDTH (120)
+#define MENUWIDTH (110)
 #define MENUHEIGHT (25)
 #define MENU_PADDING_WIDTH (7)
 
-static void
-texture_create(struct server *server, struct wlr_texture **texture,
-               struct wlr_box *geo, const char *text, float *bg, float *fg)
-{
-       if (*texture) {
-               wlr_texture_destroy(*texture);
-               *texture = NULL;
-       }
-
-       cairo_surface_t *surf = cairo_image_surface_create(CAIRO_FORMAT_ARGB32,
-               geo->width, geo->height);
-       cairo_t *cairo = cairo_create(surf);
-
-       cairo_set_source_rgb(cairo, bg[0], bg[1], bg[2]);
-       cairo_paint(cairo);
-       cairo_set_source_rgba(cairo, fg[0], fg[1], fg[2], fg[3]);
-       cairo_move_to(cairo, 0, 0);
-
-       PangoLayout *layout = pango_cairo_create_layout(cairo);
-       pango_layout_set_width(layout, geo->width * PANGO_SCALE);
-       pango_layout_set_text(layout, text, -1);
-
-       PangoFontDescription *desc = pango_font_description_from_string(font);
-       pango_layout_set_font_description(layout, desc);
-       pango_font_description_free(desc);
-       pango_cairo_update_layout(cairo, layout);
-
-       /* center-align vertically */
-       int height;
-       pango_layout_get_pixel_size(layout, NULL, &height);
-       cairo_move_to(cairo, MENU_PADDING_WIDTH, (geo->height - height) / 2);
-
-       pango_cairo_show_layout(cairo, layout);
-       g_object_unref(layout);
-
-       cairo_surface_flush(surf);
-       unsigned char *data = cairo_image_surface_get_data(surf);
-       *texture = wlr_texture_from_pixels(server->renderer, DRM_FORMAT_ARGB8888,
-                       cairo_image_surface_get_stride(surf), geo->width,
-                       geo->height, data);
-
-       cairo_destroy(cairo);
-       cairo_surface_destroy(surf);
-}
-
 static struct menuitem *
 menuitem_create(struct server *server, struct menu *menu, const char *text)
 {
@@ -84,13 +34,20 @@ menuitem_create(struct server *server, struct menu *menu, const char *text)
                return NULL;
        }
        struct theme *theme = server->theme;
-       menuitem->geo_box.width = MENUWIDTH;
-       menuitem->geo_box.height = MENUHEIGHT;
-       texture_create(server, &menuitem->active_texture, &menuitem->geo_box,
-               text, theme->menu_items_active_bg_color,
-               theme->menu_items_active_text_color);
-       texture_create(server, &menuitem->inactive_texture, &menuitem->geo_box,
-               text, theme->menu_items_bg_color, theme->menu_items_text_color);
+       menuitem->box.width = MENUWIDTH;
+       menuitem->box.height = MENUHEIGHT;
+
+       /* TODO: use rc.font_menu_item */
+       font_texture_create(server, &menuitem->texture.active, MENUWIDTH,
+               text, rc.font_name_activewindow, theme->menu_items_active_text_color);
+       font_texture_create(server, &menuitem->texture.inactive, MENUWIDTH,
+               text, rc.font_name_activewindow, theme->menu_items_text_color);
+
+       /* center align vertically */
+       menuitem->texture.offset_y =
+               (menuitem->box.height - menuitem->texture.active->height) / 2;
+       menuitem->texture.offset_x = MENU_PADDING_WIDTH;
+
        wl_list_insert(&menu->menuitems, &menuitem->link);
        return menuitem;
 }
@@ -267,6 +224,10 @@ menu_finish(struct menu *menu)
        }
 }
 
+/*
+ * TODO: call this menu_configure and return the size of the menu so that
+ * a background color can be rendered
+ */
 void
 menu_move(struct menu *menu, int x, int y)
 {
@@ -276,9 +237,9 @@ menu_move(struct menu *menu, int x, int y)
        int offset = 0;
        struct menuitem *menuitem;
        wl_list_for_each_reverse (menuitem, &menu->menuitems, link) {
-               menuitem->geo_box.x = menu->x;
-               menuitem->geo_box.y = menu->y + offset;
-               offset += menuitem->geo_box.height;
+               menuitem->box.x = menu->x;
+               menuitem->box.y = menu->y + offset;
+               offset += menuitem->box.height;
        }
 }
 
@@ -288,7 +249,7 @@ menu_set_selected(struct menu *menu, int x, int y)
        struct menuitem *menuitem;
        wl_list_for_each (menuitem, &menu->menuitems, link) {
                menuitem->selected =
-                       wlr_box_contains_point(&menuitem->geo_box, x, y);
+                       wlr_box_contains_point(&menuitem->box, x, y);
        }
 }
 
index d4bbcf7daf098fbfa67678060432de6284ff472f..e207fe3c2701eee471b17b7e05ccf2e2ec99b849 100644 (file)
@@ -544,13 +544,13 @@ render_rootmenu(struct output *output, pixman_region32_t *output_damage)
        struct menuitem *menuitem;
        wl_list_for_each (menuitem, &server->rootmenu->menuitems, link) {
                struct wlr_texture *t;
-               t = menuitem->selected ? menuitem->active_texture :
-                       menuitem->inactive_texture;
+               t = menuitem->selected ? menuitem->texture.active :
+                       menuitem->texture.inactive;
                struct wlr_box box = {
-                       .x = menuitem->geo_box.x + ox,
-                       .y = menuitem->geo_box.y + oy,
-                       .width = menuitem->geo_box.width,
-                       .height = menuitem->geo_box.height,
+                       .x = menuitem->box.x + ox + menuitem->texture.offset_x,
+                       .y = menuitem->box.y + oy + menuitem->texture.offset_y,
+                       .width = t->width,
+                       .height = t->height,
                };
                scale_box(&box, output->wlr_output->scale);
                wlr_matrix_project_box(matrix, &box, WL_OUTPUT_TRANSFORM_NORMAL,