return &default_encoding;
}
+/* XLFD parser/generator */
+
+/** Indices to each field of split font name. */
+
+enum xlfd_field_idx
+ {
+ XLFD_FOUNDRY,
+ XLFD_FAMILY,
+ XLFD_WEIGHT,
+ XLFD_SLANT,
+ XLFD_SWIDTH,
+ XLFD_ADSTYLE,
+ XLFD_PIXEL,
+ XLFD_POINT,
+ XLFD_RESX,
+ XLFD_RESY,
+ XLFD_SPACING,
+ XLFD_AVGWIDTH,
+ XLFD_REGISTRY, /* This contains ENCODING. */
+ /* anchor */
+ XLFD_FIELD_MAX
+ };
+
+static int
+xlfd_parse_name (char *name, MFont *font)
+{
+ char *field[XLFD_FIELD_MAX];
+ unsigned short size, resy;
+ MSymbol attrs[MFONT_PROPERTY_MAX];
+ char copy[513];
+ int i;
+ char *p;
+
+ if (name[0] != '-')
+ return -1;
+
+ field[0] = copy;
+ for (i = 1, p = copy, name++; *name; p++, name++)
+ {
+ if (p - copy > 512)
+ return -1;
+ if (*name == '-'
+ && i < XLFD_FIELD_MAX)
+ {
+ *p = '\0';
+ if (field[i - 1][0] == '*')
+ field[i - 1] = NULL;
+ field[i++] = p + 1;
+ }
+ else
+ *p = tolower (*name);
+ }
+ *p = '\0';
+ if (field[i - 1][0] == '*')
+ field[i - 1] = NULL;
+ while (i < XLFD_FIELD_MAX)
+ field[i++] = NULL;
+
+ resy = field[XLFD_RESY] ? atoi (field[XLFD_RESY]) : 0;
+ if (! field[XLFD_PIXEL])
+ size = field[XLFD_POINT] ? atoi (field[XLFD_POINT]) * resy / 72 : 0;
+ else if (field[XLFD_PIXEL][0] == '[')
+ {
+ /* The pixel size field specifies a transformation matrix of the
+ form "[A B C D]". The XLFD spec says that the scalar value N
+ for the pixel size is equivalent to D. */
+ char *p0 = field[XLFD_PIXEL] + 1, *p1;
+ double d;
+
+ for (i = 0; i < 4; i++, p0 = p1)
+ d = strtod (p0, &p1);
+ size = d * 10;
+ }
+ else
+ size = atoi (field[XLFD_PIXEL]) * 10;
+
+ attrs[MFONT_FOUNDRY]
+ = field[XLFD_FOUNDRY] ? msymbol (field[XLFD_FOUNDRY]) : Mnil;
+ attrs[MFONT_FAMILY]
+ = field[XLFD_FAMILY] ? msymbol (field[XLFD_FAMILY]) : Mnil;
+ attrs[MFONT_WEIGHT]
+ = field[XLFD_WEIGHT] ? msymbol (field[XLFD_WEIGHT]) : Mnil;
+ attrs[MFONT_STYLE]
+ = field[XLFD_SLANT] ? msymbol (field[XLFD_SLANT]) : Mnil;
+ attrs[MFONT_STRETCH]
+ = field[XLFD_SWIDTH] ? msymbol (field[XLFD_SWIDTH]) : Mnil;
+ attrs[MFONT_ADSTYLE]
+ = field[XLFD_ADSTYLE] ? msymbol (field[XLFD_ADSTYLE]) : Mnil;
+ attrs[MFONT_REGISTRY]
+ = field[XLFD_REGISTRY] ? msymbol (field[XLFD_REGISTRY]) : Mnil;
+ mfont__set_spec (font, attrs, size, resy);
+ return 0;
+}
+
+static char *
+xlfd_unparse_name (MFont *font)
+{
+ MSymbol prop[7];
+ char name[513];
+ char *str[7];
+ int len, i;
+ unsigned short size, resy;
+
+ prop[0] = (MSymbol) mfont_get_prop (font, Mfoundry);
+ prop[1] = (MSymbol) mfont_get_prop (font, Mfamily);
+ prop[2] = (MSymbol) mfont_get_prop (font, Mweight);
+ prop[3] = (MSymbol) mfont_get_prop (font, Mstyle);
+ prop[4] = (MSymbol) mfont_get_prop (font, Mstretch);
+ prop[5] = (MSymbol) mfont_get_prop (font, Madstyle);
+ prop[6] = (MSymbol) mfont_get_prop (font, Mregistry);
+ for (len = 0, i = 0; i < 7; i++)
+ {
+ if (prop[i] != Mnil)
+ {
+ str[i] = msymbol_name (prop[i]);
+ len += strlen (str[i]);
+ }
+ else
+ {
+ str[i] = "*";
+ len++;
+ }
+ }
+ if ((len
+ + 12 /* 12 dashes */
+ + 3 /* 3 asterisks */
+ + 30 /* 3 integers (each 10 digits) */
+ + 1) /* '\0' terminal */
+ > 513)
+ return NULL;
+
+ size = (int) mfont_get_prop (font, Msize);
+ if ((size % 10) < 5)
+ size /= 10;
+ else
+ size = size / 10 + 1;
+ resy = (int) mfont_get_prop (font, Mresolution);
+
+ sprintf (name, "-%s-%s-%s-%s-%s-%s-%d-*-%d-%d-*-*-%s",
+ str[0], str[1], str[2], str[3], str[4], str[5],
+ size, resy, resy, str[6]);
+ return strdup (name);
+}
\f
/* Internal API */
Msize = msymbol ("size");
Mresolution = msymbol ("resolution");
+ Mfontconfig = msymbol ("fontconfig");
+
/* The first entry of each mfont__property_table must be Mnil so
that actual properties get positive numeric numbers. */
for (i = 0; i <= MFONT_REGISTRY; i++)
void
mfont__free_realized (MRealizedFont *rfont)
{
- if (rfont->info)
- M17N_OBJECT_UNREF (rfont->info);
+ M17N_OBJECT_UNREF (rfont->info);
free (rfont);
}
MSTRUCT_MALLOC (copy, MERROR_FONT);
*copy = *best;
copy->layouter = layouter;
+ mplist_add (frame->realized_font_list, registry, copy);
if (copy->info)
M17N_OBJECT_REF (copy->info);
- mplist_add (frame->realized_font_list, registry, copy);
best = copy;
}
return best;
{
this->driver = driver;
if (! best
- || best->score < this->score)
+ || this->score < best->score)
{
if (best)
mfont__free_realized (best);
if (this->score == 0)
break;
}
+ else
+ mfont__free_realized (this);
}
}
int
mfont__open (MRealizedFont *rfont)
{
- MPlist *realized_font_list;
- MSymbol registry = FONT_PROPERTY (&rfont->font, MFONT_REGISTRY);
-
- if (rfont->status)
- mdebug_hook ();
-
- MPLIST_DO (realized_font_list, rfont->frame->realized_font_list)
- {
- MRealizedFont *this_rfont = MPLIST_VAL (realized_font_list);
-
- if (this_rfont->status != 0
- && MPLIST_KEY (realized_font_list) == registry
- && ! memcmp (&this_rfont->font, &rfont->font, sizeof (MFont)))
- {
- if (rfont->info)
- M17N_OBJECT_UNREF (rfont->info);
- rfont->info = this_rfont->info;
- M17N_OBJECT_REF (this_rfont->info);
- rfont->status = this_rfont->status;
- return (this_rfont->status > 0 ? 0 : -1);
- }
- }
-
return (rfont->driver->open) (rfont);
}
font->property[MFONT_RESY] = resy;
}
+int
+mfont__parse_name_into_font (char *name, MSymbol format, MFont *font)
+{
+ int result = -1;
+
+ if (format == Mx || format == Mnil)
+ result = xlfd_parse_name (name, font);
+#ifdef HAVE_FONTCONFIG
+ if (format == Mfontconfig || (! result && format == Mnil))
+ result = mfont__ft_parse_name (name, font);
+#endif
+ return result;
+}
+
/*** @} */
#endif /* !FOR_DOXYGEN || DOXYGEN_INTERNAL_MODULE */
MSymbol Mresolution;
+/***en
+ @brief Symobl of name "fontconfig".
+
+ The variable #Mfontconfig is to be used as an argument of the
+ functions mfont_parse_name () and mfont_unparse_name (). */
+
+MSymbol Mfontconfig;
+
/*=*/
/*** @} */
/*=*/
/*=*/
/***en
- @brief Create a new font from fontname.
+ @brief Create a font by parsing a fontname.
- The mfont_from_name () function creates a new font object. The
+ The mfont_parse_name () function creates a new font object. The
properties are extracted fontname $NAME.
- How to extract properties is window system dependent. The m17n-X
- library parses $NAME as XLFD (X Logical Font Description).
+ $FORMAT specifies the format of $NAME. If $FORMAT is #Mx, $NAME
+ is parsed as XLFD (X Logical Font Description). If $FORMAT is
+ #Mfontconfig, $NAME is parsed as Fontconfig's textual
+ representation of font. If $FORMAT is #Mnil, $NAME is at first
+ parsed as XLFD, and it it fails, parsed as Fontconfig's
+ representation.
@return
If the operation was successful, this function returns a pointer
/***ja
@brief ¥Õ¥©¥ó¥È̾¤«¤é¥Õ¥©¥ó¥È¤òºî¤ë.
- ´Ø¿ô mfont_from_name () ¤Ï¡¢¥Õ¥©¥ó¥È̾ $NAME ¤«¤é¼è¤ê½Ð¤µ¤ì¤¿¥×¥í¥Ñ
+ ´Ø¿ô mfont_parse_name () ¤Ï¡¢¥Õ¥©¥ó¥È̾ $NAME ¤«¤é¼è¤ê½Ð¤µ¤ì¤¿¥×¥í¥Ñ
¥Æ¥£¤ò»ý¤Ä¡¢¿·¤·¤¤¥Õ¥©¥ó¥È¥ª¥Ö¥¸¥§¥¯¥È¤òºî¤ë¡£
- ¤É¤Î¤è¤¦¤Ë¥×¥í¥Ñ¥Æ¥£¤ò¼è¤ê½Ð¤¹¤«¤Ï¥¦¥£¥ó¥É¥¦¥·¥¹¥Æ¥à¤Ë°Í¸¤¹¤ë¡£
- m17n-X ¥é¥¤¥Ö¥é¥ê¤Î¾ì¹ç¤Ï XLFD (X Logical Font Description) ¤Ë½¾¤Ã¤Æ
- $NAME ¤ò²òÀϤ¹¤ë¡£
+ $FORMAT ¤Ï $NAME ¤Î¥Õ¥©¡¼¥Þ¥Ã¥È¤ò»ØÄꤹ¤ë¡£$FORMAT ¤¬ #Mx ¤Ç¤¢¤ì¤Ð¡¢
+ $NAME ¤Ï XLFD (X Logical Font Description) ¤Ë½¾¤Ã¤Æ²òÀϤµ¤ì¤ë¡£
+ $FORMAT ¤¬ #Mfontconfig ¤Ç¤¢¤ì¤Ð $NAME ¤Ï Fontfonfig ¤Î¥Õ¥©¥ó¥È¥Æ¥
+ ¥¹¥Èɽ¸½¤Ë½¾¤Ã¤Æ²òÀϤµ¤ì¤ë¡£$FORMAT ¤¬ #Mnil ¤Ç¤¢¤ì¤Ð¡¢¤Þ¤º XLFD ¤Ë
+ ½¾¤Ã¤Æ²òÀϤµ¤ì¡¢¤½¤ì¤Ë¼ºÇÔ¤·¤¿¤é Fontconfig ¤Ë½¾¤Ã¤Æ²òÀϤµ¤ì¤ë¡£
@return
- ½èÍý¤¬À®¸ù¤¹¤ì¤Ð mfont_from_name () ¤Ï¿·¤·¤¯ºî¤é¤ì¤¿¥Õ¥©¥ó¥È¤Ø¤Î
+ ½èÍý¤¬À®¸ù¤¹¤ì¤Ð mfont_parse_name () ¤Ï¿·¤·¤¯ºî¤é¤ì¤¿¥Õ¥©¥ó¥È¤Ø¤Î
¥Ý¥¤¥ó¥¿¤òÊÖ¤¹¡£¤½¤¦¤Ç¤Ê¤±¤ì¤Ð @c NULL ¤òÊÖ¤¹¡£ */
MFont *
-mfont_from_name (char *name)
+mfont_parse_name (char *name, MSymbol format)
{
- MFontDriver *driver;
MFont template, *font;
- MPlist *plist;
- if (! mframe_default)
- return NULL;
- MPLIST_DO (plist, mframe_default->font_driver_list)
- {
- driver = MPLIST_VAL (plist);
- if (driver->parse_name)
- break;
- }
- if (MPLIST_TAIL_P (plist))
- return NULL;
-
- if ((*driver->parse_name) (name, &template))
- return NULL;
+ MFONT_INIT (&template);
+ if (mfont__parse_name_into_font (name, format, &template) < 0)
+ MERROR (MERROR_FONT, NULL);
MSTRUCT_CALLOC (font, MERROR_FONT);
*font = template;
return font;
/*=*/
/***en
- @brief Make a copy of a font.
+ @brief Create a fontname from a font.
+
+ The mfont_unparse_name () function creates a fontname string
+ from font $FONT according to $FORMAT.
+
+ $FORMAT must be #Mx or #Mfontconfig. If it is #Mx, the fontname
+ is in XLFD (X Logical Font Description) format. If it is
+ #Mfontconfig, the fontname is in the style of Fontconfig's text
+ representation.
+
+ @return
+ This function returns a newly allocated fontname string, which is
+ not freed unless the user explicitly does so by free (). */
- The mfont_copy () function returns a new copy of font $FONT. */
/***ja
- @brief ¥Õ¥©¥ó¥È¤Î¥³¥Ô¡¼¤òºî¤ë.
+ @brief ¥Õ¥©¥ó¥È̾¤«¤é¥Õ¥©¥ó¥È¤òºî¤ë.
- ´Ø¿ô Mfont_copy () ¤Ï¥Õ¥©¥ó¥È $FONT ¤Î¥³¥Ô¡¼¤òºî¤ê¡¢¤½¤ì¤òÊÖ¤¹¡£ */
+ ´Ø¿ô mfont_unparse_name () ¤Ï $FORMAT ¤Ë¤·¤¿¤¬¤Ã¤¿¥Õ¥©¥ó¥È̾¤Îʸ»ú
+ Îó¤ò¥Õ¥©¥ó¥È$FONT ¤ò¸µ¤Ëºî¤ë¡£
-MFont *
-mfont_copy (MFont *font)
+ $FORMAT ¤Ï #Mx ¤Þ¤¿¤Ï #Mfontconfig ¤Ç¤Ê¤±¤ì¤Ð¤Ê¤é¤Ê¤¤¡£#Mx ¤Ê¤é¤Ð¥Õ¥©
+ ¥ó¥È̾¤Ï XLFD (X Logical Font Description) ¤Ë½¾¤¦¡£#Mfontconfig ¤Ê
+ ¤é¤Ð¥Õ¥©¥ó¥È̾¤Ï Fontconfig ¤Î¥Õ¥©¥ó¥È¥Æ¥¥¹¥Èɽ¸½¤Ë½¾¤¦¡£
+
+ @return
+ ¤³¤Î´Ø¿ô¤Ï¿·¤¿¤Ë¥¢¥í¥±¡¼¥È¤·¤¿¥Õ¥©¥ó¥È̾¤Îʸ»úÎó¤òÊÖ¤¹¡£Ê¸»úÎó¤Ï¡¢
+ ¥æ¡¼¥¶¤¬ free () ¤Ë¤è¤Ã¤ÆÌÀ¼¨Åª¤Ë²òÊü¤·¤Ê¤¤¸Â¤ê²òÊü¤µ¤ì¤Ê¤¤¡£ */
+
+char *
+mfont_unparse_name (MFont *font, MSymbol format)
{
- MFont *copy;
+ char *name;
- MSTRUCT_MALLOC (copy, MERROR_FONT);
- *copy = *font;
- return copy;
+ if (format == Mx)
+ name = xlfd_unparse_name (font);
+#ifdef HAVE_FONTCONFIG
+ else if (format == Mfontconfig)
+ name = mfont__ft_unparse_name (font);
+#endif
+ else
+ MERROR (MERROR_FONT, NULL);
+ return name;
}
/*=*/
/***en
- @brief Create a fontname from a font.
-
- The mfont_name () function creates a fontname string created from
- font $FONT.
-
- The syntax of fontname is window system dependent. The m17n-X
- library returns a fontname conforming to XLFD (X Logical Font
- Description).
+ @brief Make a copy of a font.
- @return
- This function returns the created fontname string, which is not freed
- unless the user explicitly does so by free (). */
+ The mfont_copy () function returns a new copy of font $FONT. */
/***ja
- @brief ¥Õ¥©¥ó¥È̾¤«¤é¥Õ¥©¥ó¥È¤òºî¤ë.
-
- ´Ø¿ô mfont_name () ¤Ï¥Õ¥©¥ó¥È̾¤Îʸ»úÎó¤ò¥Õ¥©¥ó¥È
- $FONT ¤ò¸µ¤Ëºî¤ë¡£
-
- ¥Õ¥©¥ó¥È̾¤Îʸˡ¤Ï¥¦¥£¥ó¥É¥¦¥·¥¹¥Æ¥à¤Ë°Í¸¤¹¤ë¡£m17n-X ¥é¥¤¥Ö¥é¥ê
- ¤Ï XLFD (X Logical Font Description) ¤Ë½¾¤¦¥Õ¥©¥ó¥È̾¤òÊÖ¤¹¡£
+ @brief ¥Õ¥©¥ó¥È¤Î¥³¥Ô¡¼¤òºî¤ë.
- @return
- ¤³¤Î´Ø¿ô¤Ïºî¤Ã¤¿¥Õ¥©¥ó¥È̾¤Îʸ»úÎó¤òÊÖ¤¹¡£Ê¸»úÎó¤Ï¡¢¥æ¡¼¥¶
- ¤¬ free () ¤Ë¤è¤Ã¤ÆÌÀ¼¨Åª¤Ë²òÊü¤·¤Ê¤¤¸Â¤ê²òÊü¤µ¤ì¤Ê¤¤¡£ */
+ ´Ø¿ô Mfont_copy () ¤Ï¥Õ¥©¥ó¥È $FONT ¤Î¥³¥Ô¡¼¤òºî¤ê¡¢¤½¤ì¤òÊÖ¤¹¡£ */
-char *
-mfont_name (MFont *font)
+MFont *
+mfont_copy (MFont *font)
{
- MFontDriver *driver;
- MPlist *plist;
-
- if (! mframe_default)
- return NULL;
- MPLIST_DO (plist, mframe_default->font_driver_list)
- {
- driver = MPLIST_VAL (plist);
- if (driver->build_name)
- break;
- }
- if (MPLIST_TAIL_P (plist))
- return NULL;
+ MFont *copy;
- return (*driver->build_name) (font);
+ MSTRUCT_MALLOC (copy, MERROR_FONT);
+ *copy = *font;
+ return copy;
}
/*=*/
return 0;
}
+/*=*/
+
+/***en
+ @brief Create a fontname from a font.
+
+ This function is obsolete. Use mfont_unparse_name instead. */
+/***ja
+ @brief ¥Õ¥©¥ó¥È̾¤«¤é¥Õ¥©¥ó¥È¤òºî¤ë.
+
+ ¤³¤Î´Ø¿ô¤ÏÇÑ»ßͽÄê¤Ç¤¢¤ë¡£ mfont_unparse_name () ¤ò»ÈÍѤΤ³¤È¡£ */
+
+char *
+mfont_name (MFont *font)
+{
+ return mfont_unparse_name (font, Mx);
+}
+
+/*=*/
+
+/***en
+ @brief Create a new font from fontname.
+
+ This function is obsolete. Use mfont_parse_name () instead. */
+
+/***ja
+ @brief ¥Õ¥©¥ó¥È̾¤«¤é¥Õ¥©¥ó¥È¤òºî¤ë.
+
+ ¤³¤ì¤Ï´Ø¿ô¤ÏÇÑ»ßͽÄê¤Ç¤¢¤ë¡£ mfont_parse_name () ¤ò»ÈÍѤΤ³¤È¡£ */
+
+MFont *
+mfont_from_name (char *name)
+{
+ return mfont_parse_name (name, Mx);
+}
+
/*** @} */
/*** @addtogroup m17nDebug */
MFont *
mdebug_dump_font (MFont *font)
{
- MFontDriver *driver;
- MPlist *plist;
char *name;
- if (! mframe_default)
- return NULL;
- MPLIST_DO (plist, mframe_default->font_driver_list)
+ name = mfont_unparse_name (font, Mx);
+ if (name)
{
- driver = MPLIST_VAL (plist);
- if (driver->build_name)
- break;
+ fprintf (stderr, "%s", name);
+ free (name);
}
- if (MPLIST_TAIL_P (plist))
- return NULL;
-
- name = (*driver->build_name) (font);
- fprintf (stderr, "%s", name);
- free (name);
return font;
}