From 423a3f5901387c12590ae1cbe389a3b9926a9195 Mon Sep 17 00:00:00 2001 From: Stefan Monnier Date: Fri, 18 Mar 2005 04:19:41 +0000 Subject: [PATCH] Add support for I18N to Lucid menus. * xlwmenuP.h (struct _XlwMenu_part) [HAVE_X_I18N]: Change `font' to be a fontset. Add a `font_extents' element. * xlwmenu.c (xlwMenuResources) [HAVE_X_I18N]: Use a fontset for the `font' resource. (string_width) [HAVE_X_I18N]: Use XmbTextExtents; (MENU_FONT_HEIGHT, MENU_FONT_ASCENT): New macros. (arrow_width, toggle_button_width, size_menu_item, draw_arrow) (draw_toggle, draw_radio, display_menu_item): Use them. (display_menu_item) [HAVE_X_I18N]: Use XmbDrawString. (make_drawing_gcs) [HAVE_X_I18N]: Don't mess with fonts. (XlwMenuInitialize) [HAVE_X_I18N]: Initialize font_extents. (XlwMenuSetValues) [HAVE_X_I18N]: Refresh font_extents if font changes. --- lwlib/ChangeLog | 16 ++++++ lwlib/xlwmenu.c | 125 +++++++++++++++++++++++++++++++++++++---------- lwlib/xlwmenuP.h | 5 ++ 3 files changed, 120 insertions(+), 26 deletions(-) diff --git a/lwlib/ChangeLog b/lwlib/ChangeLog index 70de6541928..61cb6babc90 100644 --- a/lwlib/ChangeLog +++ b/lwlib/ChangeLog @@ -1,5 +1,21 @@ 2005-03-17 Stefan Monnier + Add support for I18N to Lucid menus. + + * xlwmenuP.h (struct _XlwMenu_part) [HAVE_X_I18N]: Change `font' to be + a fontset. Add a `font_extents' element. + + * xlwmenu.c (xlwMenuResources) [HAVE_X_I18N]: Use a fontset for the + `font' resource. + (string_width) [HAVE_X_I18N]: Use XmbTextExtents; + (MENU_FONT_HEIGHT, MENU_FONT_ASCENT): New macros. + (arrow_width, toggle_button_width, size_menu_item, draw_arrow) + (draw_toggle, draw_radio, display_menu_item): Use them. + (display_menu_item) [HAVE_X_I18N]: Use XmbDrawString. + (make_drawing_gcs) [HAVE_X_I18N]: Don't mess with fonts. + (XlwMenuInitialize) [HAVE_X_I18N]: Initialize font_extents. + (XlwMenuSetValues) [HAVE_X_I18N]: Refresh font_extents if font changes. + * lwlib-Xm.c (xm_update_label, xm_update_list): Use the recommended XmStringCreateLocalized function. Add missing copyright. diff --git a/lwlib/xlwmenu.c b/lwlib/xlwmenu.c index 43ae8ee2ea0..b011786ef8d 100644 --- a/lwlib/xlwmenu.c +++ b/lwlib/xlwmenu.c @@ -1,6 +1,6 @@ /* Implements a lightweight menubar widget. Copyright (C) 1992 Lucid, Inc. - Copyright (C) 2002 Free Software Foundation, Inc. + Copyright (C) 2002, 2005 Free Software Foundation, Inc. This file is part of the Lucid Widget Library. @@ -135,8 +135,13 @@ xlwMenuTranslations [] = static XtResource xlwMenuResources[] = { +#ifdef HAVE_X_I18N + {XtNfont, XtCFont, XtRFontSet, sizeof(XFontSet), + offset(menu.font), XtRString, "XtDefaultFontSet"}, +#else {XtNfont, XtCFont, XtRFontStruct, sizeof(XFontStruct *), - offset(menu.font),XtRString, "XtDefaultFont"}, + offset(menu.font), XtRString, "XtDefaultFont"}, +#endif {XtNforeground, XtCForeground, XtRPixel, sizeof(Pixel), offset(menu.foreground), XtRString, "XtDefaultForeground"}, {XtNdisabledForeground, XtCDisabledForeground, XtRPixel, sizeof(Pixel), @@ -235,7 +240,7 @@ XlwMenuClassRec xlwMenuClassRec = XtNumber(xlwMenuResources), /* resource_count */ NULLQUARK, /* xrm_class */ TRUE, /* compress_motion */ - TRUE, /* compress_exposure */ + XtExposeCompressMaximal, /* compress_exposure */ TRUE, /* compress_enterleave */ FALSE, /* visible_interest */ XlwMenuDestroy, /* destroy */ @@ -353,18 +358,34 @@ string_width (mw, s) XlwMenuWidget mw; char *s; { +#ifdef HAVE_X_I18N + XRectangle ink, logical; + XmbTextExtents (mw->menu.font, s, strlen (s), &ink, &logical); + return logical.width; +#else XCharStruct xcs; int drop; XTextExtents (mw->menu.font, s, strlen (s), &drop, &drop, &drop, &xcs); return xcs.width; +#endif } +#ifdef HAVE_X_I18N +#define MENU_FONT_HEIGHT(mw) \ + ((mw)->menu.font_extents->max_logical_extent.height) +#define MENU_FONT_ASCENT(mw) (MENU_FONT_HEIGHT(mw) * 9 / 10) +#else +#define MENU_FONT_HEIGHT(mw) \ + ((mw)->menu.font->ascent + (mw)->menu.font->descent) +#define MENU_FONT_ASCENT(mw) ((mw)->menu.font->ascent) +#endif + static int arrow_width (mw) XlwMenuWidget mw; { - return (mw->menu.font->ascent * 3/4) | 1; + return (MENU_FONT_ASCENT (mw) * 3/4) | 1; } /* Return the width of toggle buttons of widget MW. */ @@ -373,7 +394,7 @@ static int toggle_button_width (mw) XlwMenuWidget mw; { - return ((mw->menu.font->ascent + mw->menu.font->descent) * 2 / 3) | 1; + return (MENU_FONT_HEIGHT (mw) * 2 / 3) | 1; } @@ -454,9 +475,8 @@ size_menu_item (mw, val, horizontal_p, label_width, rest_width, button_width, } else { - *height = - mw->menu.font->ascent + mw->menu.font->descent - + 2 * mw->menu.vertical_spacing + 2 * mw->menu.shadow_thickness; + *height = MENU_FONT_HEIGHT (mw) + + 2 * mw->menu.vertical_spacing + 2 * mw->menu.shadow_thickness; *label_width = string_width (mw, resource_widget_value (mw, val)) @@ -571,7 +591,7 @@ draw_arrow (mw, window, gc, x, y, width, down_p) double factor = 1.62; int thickness2 = thickness * factor; - y += (mw->menu.font->ascent + mw->menu.font->descent - height) / 2; + y += (MENU_FONT_HEIGHT (mw) - height) / 2; if (down_p) { @@ -757,7 +777,7 @@ draw_toggle (mw, window, x, y, selected_p) width = toggle_button_width (mw); height = width; x += mw->menu.horizontal_spacing; - y += (mw->menu.font->ascent - height) / 2; + y += (MENU_FONT_ASCENT (mw) - height) / 2; draw_shadow_rectangle (mw, window, x, y, width, height, False, selected_p); } @@ -777,7 +797,7 @@ draw_radio (mw, window, x, y, selected_p) width = radio_button_width (mw); height = width; x += mw->menu.horizontal_spacing; - y += (mw->menu.font->ascent - height) / 2; + y += (MENU_FONT_ASCENT (mw) - height) / 2; draw_shadow_rhombus (mw, window, x, y, width, height, False, selected_p); } @@ -954,8 +974,8 @@ display_menu_item (mw, val, ws, where, highlighted_p, horizontal_p, { GC deco_gc; GC text_gc; - int font_ascent = mw->menu.font->ascent; - int font_descent = mw->menu.font->descent; + int font_height = MENU_FONT_HEIGHT (mw); + int font_ascent = MENU_FONT_ASCENT (mw); int shadow = mw->menu.shadow_thickness; int margin = mw->menu.margin; int h_spacing = mw->menu.horizontal_spacing; @@ -1028,7 +1048,12 @@ display_menu_item (mw, val, ws, where, highlighted_p, horizontal_p, x_offset += ws->button_width; - XDrawString (XtDisplay (mw), ws->window, text_gc, x_offset, +#ifdef HAVE_X_I18N + XmbDrawString (XtDisplay (mw), ws->window, mw->menu.font, +#else + XDrawString (XtDisplay (mw), ws->window, +#endif + text_gc, x_offset, y + v_spacing + shadow + font_ascent, display_string, strlen (display_string)); @@ -1053,7 +1078,12 @@ display_menu_item (mw, val, ws, where, highlighted_p, horizontal_p, } else if (val->key) { - XDrawString (XtDisplay (mw), ws->window, text_gc, +#ifdef HAVE_X_I18N + XmbDrawString (XtDisplay (mw), ws->window, mw->menu.font, +#else + XDrawString (XtDisplay (mw), ws->window, +#endif + text_gc, x + label_width + mw->menu.arrow_spacing, y + v_spacing + shadow + font_ascent, val->key, strlen (val->key)); @@ -1065,7 +1095,7 @@ display_menu_item (mw, val, ws, where, highlighted_p, horizontal_p, mw->menu.background_gc, x + shadow, y + shadow, label_width + h_spacing - 1, - font_ascent + font_descent + 2 * v_spacing - 1); + font_height + 2 * v_spacing - 1); draw_shadow_rectangle (mw, ws->window, x, y, width, height, True, False); } @@ -1460,21 +1490,33 @@ make_drawing_gcs (mw) XGCValues xgcv; float scale; +#ifndef HAVE_X_I18N xgcv.font = mw->menu.font->fid; +#endif xgcv.foreground = mw->menu.foreground; xgcv.background = mw->core.background_pixel; mw->menu.foreground_gc = XtGetGC ((Widget)mw, - GCFont | GCForeground | GCBackground, +#ifndef HAVE_X_I18N + GCFont | +#endif + GCForeground | GCBackground, &xgcv); +#ifndef HAVE_X_I18N xgcv.font = mw->menu.font->fid; +#endif xgcv.foreground = mw->menu.button_foreground; xgcv.background = mw->core.background_pixel; mw->menu.button_gc = XtGetGC ((Widget)mw, - GCFont | GCForeground | GCBackground, +#ifndef HAVE_X_I18N + GCFont | +#endif + GCForeground | GCBackground, &xgcv); +#ifndef HAVE_X_I18N xgcv.font = mw->menu.font->fid; +#endif xgcv.background = mw->core.background_pixel; #define BRIGHTNESS(color) (((color) & 0xff) + (((color) >> 8) & 0xff) + (((color) >> 16) & 0xff)) @@ -1500,31 +1542,47 @@ make_drawing_gcs (mw) xgcv.fill_style = FillStippled; xgcv.stipple = mw->menu.gray_pixmap; mw->menu.disabled_gc = XtGetGC ((Widget)mw, - (GCFont | GCForeground | GCBackground - | GCFillStyle | GCStipple), &xgcv); +#ifndef HAVE_X_I18N + GCFont | +#endif + GCForeground | GCBackground + | GCFillStyle | GCStipple, &xgcv); } else { /* Many colors available, use disabled pixel. */ xgcv.foreground = mw->menu.disabled_foreground; mw->menu.disabled_gc = XtGetGC ((Widget)mw, - (GCFont | GCForeground | GCBackground), &xgcv); +#ifndef HAVE_X_I18N + GCFont | +#endif + GCForeground | GCBackground, &xgcv); } +#ifndef HAVE_X_I18N xgcv.font = mw->menu.font->fid; +#endif xgcv.foreground = mw->menu.button_foreground; xgcv.background = mw->core.background_pixel; xgcv.fill_style = FillStippled; xgcv.stipple = mw->menu.gray_pixmap; mw->menu.inactive_button_gc = XtGetGC ((Widget)mw, - (GCFont | GCForeground | GCBackground - | GCFillStyle | GCStipple), &xgcv); +#ifndef HAVE_X_I18N + GCFont | +#endif + GCForeground | GCBackground + | GCFillStyle | GCStipple, &xgcv); +#ifndef HAVE_X_I18N xgcv.font = mw->menu.font->fid; +#endif xgcv.foreground = mw->core.background_pixel; xgcv.background = mw->menu.foreground; mw->menu.background_gc = XtGetGC ((Widget)mw, - GCFont | GCForeground | GCBackground, +#ifndef HAVE_X_I18N + GCFont | +#endif + GCForeground | GCBackground, &xgcv); } @@ -1731,12 +1789,16 @@ XlwMenuInitialize (request, mw, args, num_args) gray_bitmap_width, gray_bitmap_height, (unsigned long)1, (unsigned long)0, 1); +#ifndef HAVE_X_I18N /* I don't understand why this ends up 0 sometimes, but it does. This kludge works around it. Can anyone find a real fix? -- rms. */ if (mw->menu.font == 0) mw->menu.font = xlwmenu_default_font; - +#else + mw->menu.font_extents = XExtentsOfFontSet (mw->menu.font); +#endif + make_drawing_gcs (mw); make_shadow_gcs (mw); @@ -1903,7 +1965,10 @@ XlwMenuSetValues (current, request, new) if (newmw->core.background_pixel != oldmw->core.background_pixel || newmw->menu.foreground != oldmw->menu.foreground - || newmw->menu.font != oldmw->menu.font) +#ifndef HAVE_X_I18N + || newmw->menu.font != oldmw->menu.font +#endif + ) { release_drawing_gcs (newmw); make_drawing_gcs (newmw); @@ -1929,6 +1994,14 @@ XlwMenuSetValues (current, request, new) } } +#ifdef HAVE_X_I18N + if (newmw->menu.font != oldmw->menu.font) + { + redisplay = True; + newmw->menu.font_extents = XExtentsOfFontSet (newmw->menu.font); + } +#endif + return redisplay; } diff --git a/lwlib/xlwmenuP.h b/lwlib/xlwmenuP.h index 38bce796941..9937aa174ef 100644 --- a/lwlib/xlwmenuP.h +++ b/lwlib/xlwmenuP.h @@ -43,7 +43,12 @@ typedef struct _window_state typedef struct _XlwMenu_part { /* slots set by the resources */ +#ifdef HAVE_X_I18N + XFontSet font; + XFontSetExtents *font_extents; +#else XFontStruct* font; +#endif Pixel foreground; Pixel disabled_foreground; Pixel button_foreground; -- 2.39.2