From 7d019098ccdc3935bff2cfbfa734f07fa42b2a4c Mon Sep 17 00:00:00 2001 From: Matthias Kruk Date: Sat, 12 Jun 2021 14:31:08 +0900 Subject: [PATCH] =?utf8?q?mwm:=20Implement=20rendering=20text=20vertically?= =?utf8?q?=20(not=20=E7=B8=A6=E6=9B=B8=E3=81=8D)?= MIME-Version: 1.0 Content-Type: text/plain; charset=utf8 Content-Transfer-Encoding: 8bit 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 | 25 +++++++++++++++---------- mwm.c | 53 ++++++++++++++++++++++++++++++++++++++++++++++------- mwm.h | 3 +++ 3 files changed, 64 insertions(+), 17 deletions(-) diff --git a/monitor.c b/monitor.c index d6bf092..0d61c3d 100644 --- 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 52ebe68..4601a41 100644 --- 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 6481e78..306fa2e 100644 --- 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); -- 2.47.3