typedef struct {
MFont core;
- unsigned int sizes[2];
+ /* 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;
-#define SET_SIZE(xfont, s) ((xfont)->sizes[(s) / 32] |= (1 << ((s) & 0x1F)))
-#define HAVE_SIZE(xfont, s) ((xfont)->sizes[(s) / 32] & (1 << ((s) & 0x1F)))
+/* 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;
int nfonts;
int i, j;
MXFont font;
- MXFontList *xfont_table;
MFont *bfont = NULL;
plist = mplist_get (font_list, registry);
|| font.core.property[MFONT_RESY] == 0))
{
MSymbol family = FONT_PROPERTY ((MFont *) &font, MFONT_FAMILY);
- int size = font.core.property[MFONT_SIZE] / 10;
+ 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;
- font.sizes[0] = font.sizes[1] = 0;
- SET_SIZE (&font, size);
-
- /* Handle fonts of the same base. */
+ 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);
+ }
+
+ /* 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;
- SET_SIZE (&font, size);
+ 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 (p && MPLIST_KEY (p) != family)
- p = mplist_find_by_key (plist, family);
- if (p)
- xfont_table = MPLIST_VAL (p);
- else
+ for (j = 0, smallest = 0; j < sizes_idx; j++)
{
- p = plist;
- MSTRUCT_MALLOC (xfont_table, MERROR_WIN);
- MLIST_INIT1 (xfont_table, fonts, 4);
- mplist_push (p, family, xfont_table);
+ 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);
+ }
+ }
+
+ 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);
}
- MLIST_APPEND1 (xfont_table, fonts, font, MERROR_WIN);
if (! bfont
|| (font.core.property[MFONT_FOUNDRY]
!= bfont->property[MFONT_FOUNDRY])
{
MSymbol family = FONT_PROPERTY (spec, MFONT_FAMILY);
MSymbol registry = FONT_PROPERTY (spec, MFONT_REGISTRY);
- int requested_size = request->property[MFONT_SIZE];
+ int requested_size = request->property[MFONT_SIZE] / 10;
MRealizedFont *rfont;
MPlist *plist;
int i;
MFont *best_font;
- int best_score, score;
+ int best_size, best_score, score;
if (registry == Mnil
|| ! strchr (MSYMBOL_NAME (registry), '-'))
{
MXFont *xfont = xfont_table->fonts + i;
MFont *font = (MFont *) xfont;
- int size = requested_size / 10, s0, s1;
-
- for (s0 = size; s0 > 0 && ! HAVE_SIZE (xfont, s0); s0--);
- if (s0 * 10 == requested_size)
- /* Exact size match. */
- ;
- else if (xfont->sizes[0] & 1)
- /* Scalable font. */
+ 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 if (s0 == 0)
- {
- /* No smaller size font. Try a larger font. */
- if (limited_size)
- /* We can't use a larger font. */
- continue;
- for (s0 = size + 1; s0 < 64 && ! HAVE_SIZE (xfont, s0); s0++);
- if (s0 == 64)
- continue;
- size = s0;
- }
else
{
- /* Check if there's a better larger size font. */
- int size_limit = size + (size - s0);
- for (s1 = size + 1;
- s1 < size_limit && ! HAVE_SIZE (xfont, s1);
- s1++);
- size = (s1 < size_limit ? s1 : s0);
+ 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;
-
- if ((score = mfont__score (font, spec, request,
- limited_size)) >= 0
- && (best_score < 0 || score < best_score))
- {
- best_score = score;
- best_font = (MFont *) (xfont_table->fonts + i);
- if (best_score == 0)
- break;
- }
+ 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;
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;
}
}
{
- 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;
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);
/***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,