]> git.corax.cc Git - mwm/commitdiff
mwm: Implement rendering text vertically (not 縦書き)
authorMatthias Kruk <m@m10k.eu>
Sat, 12 Jun 2021 05:31:08 +0000 (14:31 +0900)
committerMatthias Kruk <m@m10k.eu>
Sat, 12 Jun 2021 05:31:08 +0000 (14:31 +0900)
To write status messages on vertical client indicators, we need to
be able to render text vertically.
This commit adds the mwm_render_text_vertical() function, which
renders text and rotates it 90 degrees clockwise.

monitor.c
mwm.c
mwm.h

index d6bf0920dbed34b49cb01835b6a93249172d1a76..0d61c3d161dfd31caf1ceeb78531ae531ff28f48 100644 (file)
--- a/monitor.c
+++ b/monitor.c
@@ -128,10 +128,13 @@ void _redraw_indicator(struct indicator *indicator, struct monitor *monitor)
 
        if(focused) {
                struct geom focus_pos;
+               struct geom client_pos;
                unsigned long fg_color;
                unsigned long bg_color;
+               char status[512];
 
                client_get_geometry(focused, &focus_pos);
+               memcpy(&client_pos, &focus_pos, sizeof(client_pos));
 
                fg_color = mwm_get_color(monitor->mwm, palette, MWM_COLOR_INDICATOR_FILL);
                bg_color = mwm_get_color(monitor->mwm, palette, MWM_COLOR_INDICATOR_BORDER);
@@ -153,19 +156,21 @@ void _redraw_indicator(struct indicator *indicator, struct monitor *monitor)
                XDrawRectangle(display, indicator->window, indicator->gfx_context,
                               focus_pos.x, focus_pos.y, focus_pos.w, focus_pos.h);
 
-               if(indicator->orientation == HINDICATOR) {
-                       char caption[256];
-                       struct geom client_pos;
-
-                       client_get_geometry(focused, &client_pos);
-
-                       snprintf(caption, sizeof(caption), "W=0x%lx %dx%d+%d+%d",
-                                client_get_window(focused), client_pos.x, client_pos.y,
-                                client_pos.w, client_pos.h);
+               snprintf(status, sizeof(status), "W=0x%lx %dx%d+%d+%d",
+                        client_get_window(focused),
+                        client_pos.w, client_pos.h,
+                        client_pos.x, client_pos.y);
 
-                       mwm_render_text(monitor->mwm, indicator->xft_context, palette, caption,
+               if(indicator->orientation == HINDICATOR) {
+                       mwm_render_text(monitor->mwm, indicator->xft_context,
+                                       palette, status,
                                        focus_pos.x + font_padding,
                                        focus_pos.y + font_padding);
+               } else {
+                       mwm_render_text_vertical(monitor->mwm, indicator->xft_context,
+                                                palette, status,
+                                                focus_pos.x + font_padding,
+                                                focus_pos.y + font_padding);
                }
        }
 
diff --git a/mwm.c b/mwm.c
index 52ebe68f19a40e4b36e903d4d3c16e21ff608ae5..4601a41fcf579ae79be9c5867f59e018df9c1b4c 100644 (file)
--- a/mwm.c
+++ b/mwm.c
@@ -57,6 +57,7 @@ struct mwm {
 
        struct {
                PangoLayout *layout;
+               PangoLayout *vlayout;
                int ascent;
                int descent;
                int height;
@@ -367,7 +368,7 @@ static void _mwm_expose(struct mwm *mwm, XExposeEvent *event)
        struct monitor *monitor;
 
 #if MWM_DEBUG
-       fprintf(stderr, "%s(%p, %p)\n", __func__, (void*)mwm, (void*)event);
+       fprintf(stderr, "%s(%p, %p) W=0x%lx\n", __func__, (void*)mwm, (void*)event, event->window);
 #endif /* MWM_DEBUG */
 
        /* redraw the status bar, if we have one */
@@ -1034,8 +1035,8 @@ static void _find_existing_clients(struct mwm *mwm)
 int mwm_init(struct mwm *mwm)
 {
        extern struct theme config_theme;
-       PangoFontMap *fontmap;
        PangoContext *context;
+       PangoFontMap *fontmap;
        PangoFontDescription *fontdesc;
        PangoFontMetrics *fontmetrics;
 
@@ -1078,24 +1079,31 @@ int mwm_init(struct mwm *mwm)
        x_configure_notify(mwm->display, mwm->root, NULL, 0);
 
        fontmap = pango_xft_get_font_map(mwm->display, mwm->screen);
-       context = pango_font_map_create_context(fontmap);
        fontdesc = pango_font_description_from_string(config_theme.statusbar_font);
+
+       /* set up the pango context/layout for horizontal text */
+       context = pango_font_map_create_context(fontmap);
        mwm->font.layout = pango_layout_new(context);
        pango_layout_set_font_description(mwm->font.layout, fontdesc);
-
        fontmetrics = pango_context_get_metrics(context, fontdesc, NULL);
+       g_object_unref(context);
+
        mwm->font.ascent = pango_font_metrics_get_ascent(fontmetrics) / PANGO_SCALE;
        mwm->font.descent = pango_font_metrics_get_descent(fontmetrics) / PANGO_SCALE;
        mwm->font.height = mwm->font.ascent + mwm->font.descent;
+       pango_font_metrics_unref(fontmetrics);
+
+       /* set up the pango context/layout for vertical text */
+       context = pango_font_map_create_context(fontmap);
+       mwm->font.vlayout = pango_layout_new(context);
+       pango_layout_set_font_description(mwm->font.vlayout, fontdesc);
+       g_object_unref(context);
 
        _palette_init(mwm, &(mwm->palette[MWM_PALETTE_ACTIVE]),
                      &config_theme.active);
        _palette_init(mwm, &(mwm->palette[MWM_PALETTE_INACTIVE]),
                      &config_theme.inactive);
 
-       pango_font_metrics_unref(fontmetrics);
-       g_object_unref(context);
-
        mwm->commands[MWM_CMD_QUIT] = _cmd_quit;
        mwm->commands[MWM_CMD_SPAWN] = _cmd_spawn;
        mwm->commands[MWM_CMD_SHOW_WORKSPACE] = _cmd_show_workspace;
@@ -1136,6 +1144,37 @@ int mwm_render_text(struct mwm *mwm, XftDraw *drawable,
        return(0);
 }
 
+int mwm_render_text_vertical(struct mwm *mwm, XftDraw *drawable,
+                            mwm_palette_t palette, const char *text,
+                            const int x, const int y)
+{
+       PangoMatrix matrix = PANGO_MATRIX_INIT;
+       PangoContext *context;
+       XftColor *color;
+       PangoRectangle extents;
+
+       if(!mwm || ! drawable || !text) {
+               return(-EINVAL);
+       }
+
+       context = pango_layout_get_context(mwm->font.vlayout);
+       color = &mwm->palette[palette].xcolor[MWM_COLOR_TEXT];
+
+       pango_matrix_translate(&matrix, x, y);
+       pango_matrix_rotate(&matrix, -90.0);
+       pango_context_set_matrix(context, &matrix);
+       pango_context_set_base_gravity(context, PANGO_GRAVITY_EAST);
+
+       pango_layout_set_attributes(mwm->font.vlayout, NULL);
+       pango_layout_set_markup(mwm->font.vlayout, text, -1);
+       pango_layout_get_extents(mwm->font.vlayout, NULL, &extents);
+
+       pango_xft_render_layout(drawable, color, mwm->font.vlayout,
+                               0, -1.0 * extents.height);
+
+       return(0);
+}
+
 int mwm_run(struct mwm *mwm)
 {
        XEvent event;
diff --git a/mwm.h b/mwm.h
index 6481e781579106ce216099cf7c75ce31575c13c7..306fa2e796e82c7c9e95109b598ead224949b605 100644 (file)
--- a/mwm.h
+++ b/mwm.h
@@ -69,6 +69,9 @@ XftDraw* mwm_create_xft_context(struct mwm *mwm, Drawable drawable);
 int mwm_render_text(struct mwm *mwm, XftDraw *drawable,
                    mwm_palette_t palette, const char *text,
                    const int x, const int y);
+int mwm_render_text_vertical(struct mwm *mwm, XftDraw *drawable,
+                            mwm_palette_t palette, const char *text,
+                            const int x, const int y);
 int mwm_get_font_height(struct mwm *mwm);
 int mwm_get_text_width(struct mwm *mwm, const char *text);
 unsigned long mwm_get_color(struct mwm *mwm, mwm_palette_t palette, mwm_color_t color);