X-Git-Url: http://git.chise.org/gitweb/?a=blobdiff_plain;f=src%2Fm17n-X.c;h=469b8963cf73995141fb8e0a146588305f7f7daf;hb=9e2820bc75b5631b7b8a34c709f537716299bf0f;hp=ef4627383d2e3285f96f210408c303d2bb6629c0;hpb=78694746412ff04ee44865fab47793b9ea9d4bf8;p=m17n%2Fm17n-lib.git diff --git a/src/m17n-X.c b/src/m17n-X.c index ef46273..469b896 100644 --- a/src/m17n-X.c +++ b/src/m17n-X.c @@ -56,6 +56,24 @@ #include "fontset.h" #include "face.h" +typedef struct { + MFont core; + /* Nth bit tells the existence of a font of size (N+1). + core.property[MFONT_SIZE] holds the smallest size. */ + unsigned int sizes; + /* If sizes is not 0, smallest and largest sizes. */ + unsigned short smallest, largest; +} MXFont; + +/* S must satisfy the condition (S > 0 && S <= 32). */ +#define SET_SIZE(sizes, s) ((sizes) |= (1 << ((s) - 1))) +#define HAVE_SIZE(sizes, s) ((sizes) & (1 << ((s) - 1))) + +typedef struct { + int size, inc, used; + MXFont *fonts; +} MXFontList; + typedef struct { /* Common header for the m17n object. */ @@ -67,18 +85,19 @@ typedef struct be closed on freeing this structure. */ int auto_display; - /** List of available fonts on the display (except for iso8859-1 and - iso10646-1 fonts). Keys are font registries, values are - (MFontList *). */ - MPlist *font_registry_list; - - MPlist *iso8859_1_family_list; + /** List of available X-core fonts on the display. Keys are + registries and values are plists whose keys are families and + values are pointers to MXFontList. */ + MPlist *font_list; - MPlist *iso10646_1_family_list; + /** List of available X-core fonts on the display. Keys are + families and values are pointers to MFont. For each MFont, only + these properties are important; FOUNDRY, FAMILY, REGISTRY. */ + MPlist *base_font_list; - /* List of information about each font. Keys are font registries, - values are (MFontInfo *). */ - MPlist *realized_font_list; + /** Nonzero means that already contains all available + fonts on the display. */ + int all_fonts_scaned; /** Modifier bit masks of the display. */ int meta_mask; @@ -146,6 +165,10 @@ typedef struct /** List of pointers to realized faces on the frame. */ MPlist *realized_face_list; + /* List of information about each font. Keys are font registries, + values are (MFontInfo *). */ + MPlist *realized_font_list; + /** List of pointers to realized fontsets on the frame. */ MPlist *realized_fontset_list; @@ -179,41 +202,18 @@ static void free_display_info (void *object) { MDisplayInfo *disp_info = (MDisplayInfo *) object; - MPlist *plist; + MPlist *plist, *p; - MPLIST_DO (plist, disp_info->font_registry_list) + MPLIST_DO (plist, disp_info->font_list) { - MFontList *registry_list = MPLIST_VAL (plist); - - if (registry_list->fonts) - free (registry_list->fonts); - free (registry_list); - } - M17N_OBJECT_UNREF (disp_info->font_registry_list); - - MPLIST_DO (plist, disp_info->iso8859_1_family_list) - { - MFontList *family_list = MPLIST_VAL (plist); - - if (family_list->fonts) - free (family_list->fonts); - free (family_list); - } - M17N_OBJECT_UNREF (disp_info->iso8859_1_family_list); - - MPLIST_DO (plist, disp_info->iso10646_1_family_list) - { - MFontList *family_list = MPLIST_VAL (plist); - - if (family_list->fonts) - free (family_list->fonts); - free (family_list); + MPLIST_DO (p, MPLIST_VAL (plist)) + free (MPLIST_VAL (p)); + M17N_OBJECT_UNREF (MPLIST_VAL (plist)); } - M17N_OBJECT_UNREF (disp_info->iso10646_1_family_list); - - MPLIST_DO (plist, disp_info->realized_font_list) - mfont__free_realized ((MRealizedFont *) MPLIST_VAL (plist)); - M17N_OBJECT_UNREF (disp_info->realized_font_list); + M17N_OBJECT_UNREF (disp_info->font_list); + MPLIST_DO (plist, disp_info->base_font_list) + free (MPLIST_VAL (plist)); + M17N_OBJECT_UNREF (disp_info->base_font_list); if (disp_info->auto_display) XCloseDisplay (disp_info->display); @@ -232,6 +232,10 @@ free_device (void *object) mfont__free_realized_fontset ((MRealizedFontset *) mplist_value (plist)); M17N_OBJECT_UNREF (device->realized_fontset_list); + MPLIST_DO (plist, device->realized_font_list) + mfont__free_realized ((MRealizedFont *) MPLIST_VAL (plist)); + M17N_OBJECT_UNREF (device->realized_font_list); + MPLIST_DO (plist, device->realized_face_list) { MRealizedFace *rface = MPLIST_VAL (plist); @@ -428,138 +432,264 @@ static void xfont_find_metric (MRealizedFont *, MGlyphString *, int, int); static unsigned xfont_encode_char (MRealizedFont *, unsigned); static void xfont_render (MDrawWindow, int, int, MGlyphString *, MGlyph *, MGlyph *, int, MDrawRegion); +static int xfont_list (MFrame *frame, MPlist *plist, + MFont *font, MSymbol language, int maxnum); + static MFontDriver xfont_driver = { xfont_select, xfont_open, - xfont_find_metric, xfont_encode_char, xfont_render }; + xfont_find_metric, xfont_encode_char, xfont_render, xfont_list }; -typedef struct +static int +font_compare (const void *p1, const void *p2) { - M17NObject control; - Display *display; - XFontStruct *xfont; -} MXFontInfo; + return strcmp (*(char **) p1, *(char **) p2); +} -static MFontList * -build_font_list (MFrame *frame, MSymbol family, MSymbol registry, - MPlist *plist) +static MPlist * +xfont_registry_list (MFrame *frame, MSymbol registry) { + MDisplayInfo *disp_info = FRAME_DEVICE (frame)->display_info; + MPlist *font_list = disp_info->font_list; + MPlist *base_font_list = disp_info->base_font_list; + MPlist *plist, *p; char pattern[1024]; - MFontList *font_list; - char **fontnames; + char **font_names, **names; int nfonts; int i, j; + MXFont font; + MFont *bfont = NULL; + + plist = mplist_get (font_list, registry); + if (plist) + return plist; + plist = mplist (); + mplist_add (font_list, registry, plist); + sprintf (pattern, "-*-*-*-*-*-*-*-*-*-*-*-*-%s", msymbol_name (registry)); + font_names = XListFonts (disp_info->display, pattern, 0x8000, &nfonts); + if (nfonts == 0) + return plist; + names = alloca (sizeof (char *) * nfonts); + memcpy (names, font_names, sizeof (char *) * nfonts); + qsort (names, nfonts, sizeof (char *), font_compare); + for (i = 0, p = NULL; i < nfonts; i++) + if (mfont__parse_name_into_font (names[i], Mx, (MFont *) &font) == 0 + && (font.core.property[MFONT_SIZE] > 0 + || font.core.property[MFONT_RESY] == 0)) + { + MSymbol family = FONT_PROPERTY ((MFont *) &font, MFONT_FAMILY); + MXFontList *xfont_table; + int sizes[256]; + int sizes_idx = 0; + int size, smallest, largest; + int have_scalable; + unsigned int size_bits = 0; + char *base_end; + int base_len; + int fields; + + if (p && MPLIST_KEY (p) != family) + p = mplist_find_by_key (plist, family); + if (p) + xfont_table = MPLIST_VAL (p); + else + { + p = plist; + MSTRUCT_MALLOC (xfont_table, MERROR_WIN); + MLIST_INIT1 (xfont_table, fonts, 4); + mplist_push (p, family, xfont_table); + } - MSTRUCT_CALLOC (font_list, MERROR_WIN); + /* Calculate how many bytes to compare to detect fonts of the + same base name. */ + for (base_end = names[i], fields = 0; *base_end; base_end++) + if (*base_end == '-' + && ++fields == 7 /* PIXEL_SIZE */) + break; + base_len = base_end - names[i] + 1; + + size = font.core.property[MFONT_SIZE] / 10; + have_scalable = size == 0; + sizes[sizes_idx++] = size; + for (j = i + 1; j < nfonts && ! strncmp (names[i], names[j], base_len); + i = j++) + if (mfont__parse_name_into_font (names[j], Mx, (MFont *) &font) == 0 + && (font.core.property[MFONT_SIZE] > 0 + || font.core.property[MFONT_RESY] == 0)) + { + int k; + + size = font.core.property[MFONT_SIZE] / 10; + if (! have_scalable) + have_scalable = size == 0; + for (k = 0; k < sizes_idx && sizes[k] != size; k++); + if (k == sizes_idx && sizes_idx < 256) + sizes[sizes_idx++] = size; + } - if (family == Mnil) - { - sprintf (pattern, "-*-*-*-*-*-*-*-*-*-*-*-*-%s", - msymbol_name (registry)); - font_list->tag = registry; - } - else - { - sprintf (pattern, "-*-%s-*-*-*-*-*-*-*-*-*-*-%s", - msymbol_name (family), msymbol_name (registry)); - font_list->tag = family; - } + for (j = 0, smallest = 0; j < sizes_idx; j++) + { + size = sizes[j]; + if (size <= 32) + { + if (size != 0) + { + if (smallest == 0) + smallest = largest = size; + else if (size < smallest) + smallest = size; + else if (size > largest) + largest = size; + SET_SIZE (size_bits, size); + } + } + else + { + font.core.property[MFONT_SIZE] = size * 10; + font.sizes = 0; + MLIST_APPEND1 (xfont_table, fonts, font, MERROR_WIN); + } + } - fontnames = XListFonts (FRAME_DISPLAY (frame), pattern, 0x8000, &nfonts); - if (nfonts > 0) - { - MTABLE_MALLOC (font_list->fonts, nfonts, MERROR_WIN); - for (i = j = 0; i < nfonts; i++) - if ((mfont__parse_name_into_font (fontnames[i], Mx, - font_list->fonts + j) - == 0) - && (font_list->fonts[j].property[MFONT_SIZE] != 0 - || font_list->fonts[j].property[MFONT_RESY] == 0)) - j++; - XFreeFontNames (fontnames); - font_list->nfonts = j; - } - mplist_add (plist, font_list->tag, font_list); - return (nfonts > 0 ? font_list : NULL); + if (size_bits || have_scalable == 1) + { + font.sizes = size_bits; + font.smallest = smallest; + font.largest = largest; + font.core.property[MFONT_SIZE] = have_scalable ? 0 : smallest * 10; + MLIST_APPEND1 (xfont_table, fonts, font, MERROR_WIN); + } + if (! bfont + || (font.core.property[MFONT_FOUNDRY] + != bfont->property[MFONT_FOUNDRY]) + || (font.core.property[MFONT_FAMILY] + != bfont->property[MFONT_FAMILY])) + { + MSTRUCT_MALLOC (bfont, MERROR_WIN); + *bfont = font.core; + for (j = MFONT_WEIGHT; j <= MFONT_ADSTYLE; j++) + bfont->property[j] = 0; + bfont->property[MFONT_SIZE] = bfont->property[MFONT_RESY] = 0; + mplist_push (base_font_list, family, bfont); + } + } + XFreeFontNames (font_names); + return plist; +} + +static void +xfont_list_all (MFrame *frame) +{ + MDisplayInfo *disp_info = FRAME_DEVICE (frame)->display_info; + MPlist *font_encoding_list, *p; + + if (disp_info->all_fonts_scaned) + return; + disp_info->all_fonts_scaned = 1; + font_encoding_list = mfont__encoding_list (); + if (! font_encoding_list) + return; + MPLIST_DO (p, font_encoding_list) + xfont_registry_list (frame, MPLIST_KEY (p)); } + +typedef struct +{ + M17NObject control; + Display *display; + XFontStruct *xfont; +} MXFontInfo; + /* The X font driver function SELECT. */ static MRealizedFont * xfont_select (MFrame *frame, MFont *spec, MFont *request, int limited_size) { + MSymbol family = FONT_PROPERTY (spec, MFONT_FAMILY); MSymbol registry = FONT_PROPERTY (spec, MFONT_REGISTRY); + int requested_size = request->property[MFONT_SIZE] / 10; MRealizedFont *rfont; - MFontList *font_list = NULL; + MPlist *plist; int i; MFont *best_font; - int best_score, score; + int best_size, best_score, score; if (registry == Mnil || ! strchr (MSYMBOL_NAME (registry), '-')) return NULL; - /* We handles iso8859-1 and iso10646-1 fonts specially because there - exists so many such fonts. */ - if (registry == M_iso8859_1 || registry == M_iso10646_1) - { - MPlist *family_list - = (registry == M_iso8859_1 - ? FRAME_DEVICE (frame)->display_info->iso8859_1_family_list - : FRAME_DEVICE (frame)->display_info->iso10646_1_family_list); - MSymbol family = FONT_PROPERTY (spec, MFONT_FAMILY); - - if (family != Mnil) - { - font_list = (MFontList *) mplist_get (family_list, family); - if (! font_list) - font_list = build_font_list (frame, family, registry, family_list); - } - if (! font_list) - { - family = FONT_PROPERTY (request, MFONT_FAMILY); - font_list = (MFontList *) mplist_get (family_list, family); - if (! font_list) - font_list = build_font_list (frame, family, registry, family_list); - } - } - if (! font_list) - { - MPlist *registry_list - = FRAME_DEVICE (frame)->display_info->font_registry_list; - - font_list = (MFontList *) mplist_get (registry_list, registry); - if (! font_list) - font_list = build_font_list (frame, Mnil, registry, registry_list); - } - if (! font_list) - return NULL; - - for (i = 0, best_score = -1, best_font = NULL; i < font_list->nfonts; i++) - if ((best_score = mfont__score (font_list->fonts + i, spec, request, - limited_size)) >= 0) - break; - if (best_score < 0) + plist = xfont_registry_list (frame, registry); + if (MPLIST_TAIL_P (plist)) return NULL; - best_font = font_list->fonts + i; - for (; best_score > 0 && i < font_list->nfonts ; i++) + best_score = -1, best_font = NULL; + MPLIST_DO (plist, plist) { - score = mfont__score (font_list->fonts + i, spec, request, - limited_size); - if (score >= 0 && score < best_score) + if (family == Mnil || family == MPLIST_KEY (plist)) { - best_font = font_list->fonts + i; - best_score = score; + MXFontList *xfont_table = MPLIST_VAL (plist); + + for (i = 0; i < xfont_table->used; i++) + { + MXFont *xfont = xfont_table->fonts + i; + MFont *font = (MFont *) xfont; + unsigned int sizes = xfont->sizes; + int orig_size = font->property[MFONT_SIZE]; + int size; + + if (sizes == 0) + size = orig_size / 10; + else if (requested_size < xfont->smallest) + size = orig_size == 0 ? 0 : xfont->smallest; + else if (requested_size > xfont->largest) + size = orig_size == 0 ? 0 : xfont->largest; + else if (HAVE_SIZE (sizes, requested_size)) + size = requested_size; + else if (orig_size == 0) + size = 0; + else + { + for (size = requested_size - 1; + size > xfont->smallest && ! HAVE_SIZE (sizes, size); + size--); + if (! limited_size) + { + int s; + for (s = requested_size; + s < xfont->largest && ! HAVE_SIZE (sizes, s); + s++); + if (s - requested_size < requested_size - size) + size = s; + } + } + font->property[MFONT_SIZE] = size * 10; + score = mfont__score (font, spec, request, limited_size); + font->property[MFONT_SIZE] = orig_size; + if (score >= 0 && (best_score < 0 || score < best_score)) + { + best_size = size * 10; + best_score = score; + best_font = (MFont *) (xfont_table->fonts + i); + if (best_score == 0) + break; + } + } + if (best_score == 0) + break; } } + if (! best_font) + return NULL; MSTRUCT_CALLOC (rfont, MERROR_WIN); rfont->frame = frame; rfont->spec = *spec; rfont->request = *request; rfont->font = *best_font; - if (best_font->property[MFONT_SIZE] == 0) + if (best_size == 0) rfont->font.property[MFONT_SIZE] = request->property[MFONT_SIZE]; + else + rfont->font.property[MFONT_SIZE] = best_size; rfont->score = best_score; return rfont; } @@ -607,6 +737,8 @@ xfont_open (MRealizedFont *rfont) rfont->status = 1; rfont->ascent = xfont_info->xfont->ascent; rfont->descent = xfont_info->xfont->descent; + rfont->type = Mx; + rfont->fontp = xfont_info->xfont; return 0; } @@ -823,6 +955,78 @@ xfont_render (MDrawWindow win, int x, int y, MGlyphString *gstring, } } +static int +xfont_list (MFrame *frame, MPlist *plist, MFont *font, MSymbol language, + int maxnum) +{ + MDisplayInfo *disp_info = FRAME_DEVICE (frame)->display_info; + MSymbol registry = font ? FONT_PROPERTY (font, MFONT_REGISTRY) : Mnil; + MSymbol family = font ? FONT_PROPERTY (font, MFONT_FAMILY) : Mnil; + MPlist *p, *pl; + int num = 0; + + if (registry != Mnil) + xfont_registry_list (frame, registry); + else + xfont_list_all (frame); + + /* As we have not yet implemented the language check, return all + base fonts. */ + if (! font) + MPLIST_DO (p, disp_info->base_font_list) + { + mplist_add (plist, MPLIST_KEY (p), MPLIST_VAL (p)); + num++; + if (num == maxnum) + return num; + } + else + { + MXFontList *xfontlist; + MXFont *xfont; + int i; + + pl = disp_info->font_list; + if (registry != Mnil) + { + pl = mplist_find_by_key (pl, registry); + if (! pl) + return 0; + } + + MPLIST_DO (pl, pl) + { + p = MPLIST_VAL (pl); + if (family != Mnil) + { + p = mplist_find_by_key (p, family); + if (! p) + return 0; + } + MPLIST_DO (p, p) + { + xfontlist = MPLIST_VAL (p); + for (i = 0; i < xfontlist->used; i++) + { + xfont = xfontlist->fonts + i; + if (mfont__match_p (&xfont->core, font, MFONT_REGISTRY)) + { + mplist_add (plist, MPLIST_KEY (p), &xfont->core); + num++; + if (num == maxnum) + return num; + } + } + if (family != Mnil) + break; + } + if (registry != Mnil) + break; + } + } + return num; +} + /* Xft Handler */ @@ -845,7 +1049,9 @@ MFontDriver xft_driver = { NULL, /* Set to ft_select in device_init (). */ xft_open, xft_find_metric, NULL, /* Set to ft_encode_char in device_init (). */ - xft_render }; + xft_render, + NULL /* Set to ft_list in device_init (). */ + }; static void @@ -902,7 +1108,11 @@ xft_open (MRealizedFont *rfont) { font_info->font_no_aa = xft_open_font (frame, ft_info, size, 0); if (font_info->font_no_aa) - return 0; + { + rfont->type = Mxft; + rfont->fontp = font_info->font_no_aa; + return 0; + } XftFontClose (FRAME_DISPLAY (rfont->frame), font_info->font_aa); } free (font_info); @@ -935,7 +1145,7 @@ xft_find_metric (MRealizedFont *rfont, MGlyphString *gstring, { XGlyphInfo extents; - XftGlyphExtents (FRAME_DISPLAY (rfont->frame), + XftGlyphExtents (FRAME_DISPLAY (gstring->frame), font_info->font_aa, &g->code, 1, &extents); g->lbearing = - extents.x; g->rbearing = extents.width - extents.x; @@ -977,7 +1187,7 @@ xft_render (MDrawWindow win, int x, int y, glyphs = alloca (sizeof (FT_UInt) * (to - from)); for (last_x = x, nglyphs = 0, g = from; g < to; x += g++->width) { - if (g->xoff == 0 && g->yoff == 0) + if (g->xoff == 0 && g->yoff == 0 && !g->left_padding && !g->right_padding) glyphs[nglyphs++] = g->code; else { @@ -1587,7 +1797,7 @@ mwin__parse_event (MFrame *frame, void *arg, int *modifiers) int len; char buf[512]; KeySym keysym; - MSymbol key; + MSymbol key = Mnil; *modifiers = 0; if (event->xany.type != KeyPress @@ -1616,7 +1826,7 @@ mwin__parse_event (MFrame *frame, void *arg, int *modifiers) } else if (keysym >= XK_Shift_L && keysym <= XK_Hyper_R) return Mnil; - else + if (key == Mnil) { char *str = XKeysymToString (keysym); @@ -1700,6 +1910,7 @@ device_init () #ifdef HAVE_XFT2 xft_driver.select = mfont__ft_driver.select; xft_driver.encode_char = mfont__ft_driver.encode_char; + xft_driver.list = mfont__ft_driver.list; #endif Mxim = msymbol ("xim"); @@ -1741,6 +1952,7 @@ device_open (MFrame *frame, MPlist *param) MPlist *plist; AppData app_data; MFace *face; + int use_xfont = 0, use_freetype = 0, use_xft = 0; for (plist = param; (key = mplist_key (plist)) != Mnil; plist = mplist_next (plist)) @@ -1757,8 +1969,27 @@ device_open (MFrame *frame, MPlist *param) widget = (Widget) mplist_value (plist); else if (key == Mcolormap) cmap = (Colormap) mplist_value (plist); + else if (key == Mfont) + { + MSymbol val = MPLIST_SYMBOL (plist); + + if (val == Mx) + use_xfont = 1; +#ifdef HAVE_FREETYPE + else if (val == Mfreetype) + use_freetype = 1; +#ifdef HAVE_XFT2 + else if (val == Mxft) + use_xft = 1; +#endif +#endif + } } + /* If none of them is specified, use all of them. */ + if (! use_xfont && ! use_freetype && ! use_xft) + use_xfont = use_freetype = use_xft = 1; + if (widget) { display = XtDisplay (widget); @@ -1816,10 +2047,8 @@ device_open (MFrame *frame, MPlist *param) M17N_OBJECT (disp_info, free_display_info, MERROR_WIN); disp_info->display = display; disp_info->auto_display = auto_display; - disp_info->font_registry_list = mplist (); - disp_info->iso8859_1_family_list = mplist (); - disp_info->iso10646_1_family_list = mplist (); - disp_info->realized_font_list = mplist (); + disp_info->font_list = mplist (); + disp_info->base_font_list = mplist (); find_modifier_bits (disp_info); mplist_add (display_info_list, Mt, disp_info); } @@ -1851,6 +2080,7 @@ device_open (MFrame *frame, MPlist *param) device->depth = depth; device->cmap = cmap; device->realized_face_list = mplist (); + device->realized_font_list = mplist (); device->realized_fontset_list = mplist (); device->gc_list = mplist (); values.foreground = BlackPixel (display, screen_num); @@ -1867,13 +2097,21 @@ device_open (MFrame *frame, MPlist *param) frame->device_type = MDEVICE_SUPPORT_OUTPUT | MDEVICE_SUPPORT_INPUT; frame->driver = &x_driver; frame->font_driver_list = mplist (); - mplist_add (frame->font_driver_list, Mx, &xfont_driver); #ifdef HAVE_XFT2 - mplist_add (frame->font_driver_list, Mfreetype, &xft_driver); -#elif HAVE_FREETYPE - mplist_add (frame->font_driver_list, Mfreetype, &mfont__ft_driver); -#endif - frame->realized_font_list = disp_info->realized_font_list; + if (use_xft) + { + mplist_add (frame->font_driver_list, Mfreetype, &xft_driver); + use_freetype = 0; + } +#endif /* HAVE_XFT2 */ +#ifdef HAVE_FREETYPE + if (use_freetype) + mplist_add (frame->font_driver_list, Mfreetype, &mfont__ft_driver); +#endif /* HAVE_FREETYPE */ + if (use_xfont || MPLIST_TAIL_P (frame->font_driver_list)) + mplist_push (frame->font_driver_list, Mx, &xfont_driver); + + frame->realized_font_list = device->realized_font_list; frame->realized_face_list = device->realized_face_list; frame->realized_fontset_list = device->realized_fontset_list; @@ -1905,18 +2143,20 @@ device_open (MFrame *frame, MPlist *param) } { - int nfonts; - char **names = XListFonts (display, app_data.font, 1, &nfonts); + int nfonts, i; + /* Try at least 32 fonts to obtain a non-autoscaled font. */ + char **names = XListFonts (display, app_data.font, 32, &nfonts); + MFont *font = NULL; - if (nfonts > 0) + for (i = 0; ! font && i < nfonts; i++) { - if (! (frame->font = mfont_parse_name (names[0], Mx))) + font = mfont_parse_name (names[i], Mx); + if (!font) { /* The font name does not conform to XLFD. Try to open the font and get XA_FONT property. */ - XFontStruct *xfont = XLoadQueryFont (display, names[0]); + XFontStruct *xfont = XLoadQueryFont (display, names[i]); - nfonts = 0; if (xfont) { unsigned long value; @@ -1925,17 +2165,20 @@ device_open (MFrame *frame, MPlist *param) if (XGetFontProperty (xfont, XA_FONT, &value) && (name = ((char *) XGetAtomName (display, (Atom) value)))) - { - if ((frame->font = mfont_parse_name (name, Mx))) - nfonts = 1; - } + font = mfont_parse_name (name, Mx); XFreeFont (display, xfont); } } - XFreeFontNames (names); + if (font && + font->property[MFONT_SIZE] == 0 && font->property[MFONT_RESY] > 0) + { + free (font); + font = NULL; + } } - if (! nfonts) - frame->font = mfont_parse_name (FALLBACK_FONT, Mx); + if (nfonts) + XFreeFontNames (names); + frame->font = font ? font : mfont_parse_name (FALLBACK_FONT, Mx); } face = mface_from_font (frame->font); @@ -2210,31 +2453,27 @@ x_io_error_handler (Display *display) /***ja @brief XIMÍÑÆþÎϥɥ饤¥Ð. - ¥É¥é¥¤¥Ð #minput_xim_driver ¤Ï #Mxim ¤ò̾Á°¤È¤·¤Æ»ý¤Ä³°ÉôÆþÎϥ᥽¥Ã - ¥ÉÍѤǤ¢¤ê¡¢ XIM (X Input Methods) ¤ò¥Ð¥Ã¥¯¥°¥é¥¦¥ó¥É¤ÎÆþÎÏ¥¨¥ó¥¸ - ¥ó¤È¤·¤Æ»ÈÍѤ¹¤ë¡£ + ¥É¥é¥¤¥Ð #minput_xim_driver ¤Ï #Mxim ¤ò̾Á°¤È¤·¤Æ»ý¤Ä³°ÉôÆþÎϥ᥽¥Ã¥ÉÍѤǤ¢¤ê¡¢ + XIM (X Input Methods) ¤ò¥Ð¥Ã¥¯¥°¥é¥¦¥ó¥É¤ÎÆþÎÏ¥¨¥ó¥¸¥ó¤È¤·¤Æ»ÈÍѤ¹¤ë¡£ ¥·¥ó¥Ü¥ë #Mxim ¤Ï¤³¤Î¥É¥é¥¤¥Ð¤Ø¤Î¥Ý¥¤¥ó¥¿¤òÃͤȤ¹¤ë¥×¥í¥Ñ¥Æ¥£ - #Minput_driver ¤ò»ý¤Á¡¢LANGUAGE ¤¬ #Mnil ¤Ç̾Á°¤¬ #Mxim ¤Ç¤¢¤ëÆþÎÏ - ¥á¥½¥Ã¥É¤Ï¤³¤Î¥É¥é¥¤¥Ð¤òÍøÍѤ¹¤ë¡£ + #Minput_driver ¤ò»ý¤Á¡¢LANGUAGE ¤¬ #Mnil ¤Ç̾Á°¤¬ #Mxim + ¤Ç¤¢¤ëÆþÎϥ᥽¥Ã¥É¤Ï¤³¤Î¥É¥é¥¤¥Ð¤òÍøÍѤ¹¤ë¡£ - ¤·¤¿¤¬¤Ã¤Æ¡¢¤½¤ì¤é¤ÎÆþÎϥ᥽¥Ã¥É¤Ç¤Ï¡¢minput_ ¤Ç»Ï¤Þ¤ë̾Á°¤ò»ý¤Ä´Ø - ¿ô¤Î¥É¥é¥¤¥Ð¤Ë°Í¸¤¹¤ë°ú¿ô¤Ï¼¡¤Î¤è¤¦¤Ê¤â¤Î¤Ç¤Ê¤¯¤Æ¤Ï¤Ê¤é¤Ê¤¤¡£ + ¤·¤¿¤¬¤Ã¤Æ¡¢¤½¤ì¤é¤ÎÆþÎϥ᥽¥Ã¥É¤Ç¤Ï¡¢minput_ + ¤Ç»Ï¤Þ¤ë̾Á°¤ò»ý¤Ä´Ø¿ô¤Î¥É¥é¥¤¥Ð¤Ë°Í¸¤¹¤ë°ú¿ô¤Ï¼¡¤Î¤è¤¦¤Ê¤â¤Î¤Ç¤Ê¤¯¤Æ¤Ï¤Ê¤é¤Ê¤¤¡£ - ´Ø¿ô minput_open_im () ¤Î°ú¿ô $ARG ¤Ï¹½Â¤ÂÎ #MInputXIMArgIM ¤Ø¤Î¥Ý - ¥¤¥ó¥¿¤Ç¤Ê¤¯¤Æ¤Ï¤Ê¤é¤Ê¤¤¡£¾ÜºÙ¤Ë¤Ä¤¤¤Æ¤Ï #MInputXIMArgIM ¤ÎÀâÌÀ¤ò - »²¾È¡£ + ´Ø¿ô minput_open_im () ¤Î°ú¿ô $ARG ¤Ï¹½Â¤ÂÎ #MInputXIMArgIM + ¤Ø¤Î¥Ý¥¤¥ó¥¿¤Ç¤Ê¤¯¤Æ¤Ï¤Ê¤é¤Ê¤¤¡£¾ÜºÙ¤Ë¤Ä¤¤¤Æ¤Ï #MInputXIMArgIM ¤ÎÀâÌÀ¤ò»²¾È¡£ - ´Ø¿ô minput_create_ic () ¤Î°ú¿ô $ARG ¤Ï¹½Â¤ÂÎ #MInputXIMArgIC ¤Ø¤Î - ¥Ý¥¤¥ó¥¿¤Ç¤Ê¤¯¤Æ¤Ï¤Ê¤é¤Ê¤¤¡£¾ÜºÙ¤Ë¤Ä¤¤¤Æ¤Ï #MInputXIMArgIC ¤ÎÀâÌÀ - ¤ò»²¾È¡£ + ´Ø¿ô minput_create_ic () ¤Î°ú¿ô $ARG ¤Ï¹½Â¤ÂÎ #MInputXIMArgIC + ¤Ø¤Î¥Ý¥¤¥ó¥¿¤Ç¤Ê¤¯¤Æ¤Ï¤Ê¤é¤Ê¤¤¡£¾ÜºÙ¤Ë¤Ä¤¤¤Æ¤Ï #MInputXIMArgIC ¤ÎÀâÌÀ¤ò»²¾È¡£ - ´Ø¿ô minput_filter () ¤Î°ú¿ô $ARG ¤Ï¹½Â¤ÂÎ @c XEvent ¤Ø¤Î¥Ý¥¤¥ó¥¿ - ¤Ç¤Ê¤¯¤Æ¤Ï¤Ê¤é¤Ê¤¤¡£°ú¿ô $KEY ¤Ï̵»ë¤µ¤ì¤ë¡£ + ´Ø¿ô minput_filter () ¤Î°ú¿ô $ARG ¤Ï¹½Â¤ÂÎ @c XEvent + ¤Ø¤Î¥Ý¥¤¥ó¥¿¤Ç¤Ê¤¯¤Æ¤Ï¤Ê¤é¤Ê¤¤¡£°ú¿ô $KEY ¤Ï̵»ë¤µ¤ì¤ë¡£ ´Ø¿ô minput_lookup () ¤Î°ú¿ô $ARG ¤Ï´Ø¿ô function minput_filter () - ¤Î°ú¿ô $ARG ¤ÈƱ¤¸¤â¤Î¤Ç¤Ê¤¯¤Æ¤Ï¤Ê¤é¤Ê¤¤¡£ °ú¿ô $KEY ¤Ï¡¢Ìµ»ë¤µ¤ì - ¤ë¡£ */ + ¤Î°ú¿ô $ARG ¤ÈƱ¤¸¤â¤Î¤Ç¤Ê¤¯¤Æ¤Ï¤Ê¤é¤Ê¤¤¡£ °ú¿ô $KEY ¤Ï¡¢Ìµ»ë¤µ¤ì¤ë¡£ */ MInputDriver minput_xim_driver = { xim_open_im, xim_close_im, xim_create_ic, xim_destroy_ic,