/* font.c -- font module.
- Copyright (C) 2003, 2004
+ Copyright (C) 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010
National Institute of Advanced Industrial Science and Technology (AIST)
Registration Number H15PRO112
You should have received a copy of the GNU Lesser General Public
License along with the m17n library; if not, write to the Free
- Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
02111-1307, USA. */
/***en
When the key of a font property is @c Msize or @c Mresolution, its
value is an integer. Otherwise the value is a symbol.
- "The font property that belongs to font F and whose key is @c
- Mxxx" may be shortened to "the xxx property of F".
+ The notation "xxx property of F" means the font property that
+ belongs to font F and whose key is @c Mxxx.
The value of a foundry property is a symbol representing font
foundry information, e.g. adobe, misc, etc.
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
+#include <ctype.h>
#include "m17n-gui.h"
#include "m17n-misc.h"
#include "symbol.h"
#include "plist.h"
#include "charset.h"
+#include "language.h"
#include "internal-gui.h"
#include "font.h"
#include "face.h"
| (! p[2] ? 0
: (p[2] << 8) | p[3]))));
}
-#endif /* not HAVE_OTF */
-
-static MPlist *otf_script_list;
-
-static int
-load_otf_script_list ()
-{
- MDatabase *mdb;
- MPlist *plist, *pl;
-
- otf_script_list = mplist ();
- mdb = mdatabase_find (msymbol ("standard"), Mscript, msymbol ("otf"), Mnil);
- if (! mdb
- || ! (plist = mdatabase_load (mdb)))
- MERROR (MERROR_FONT, -1);
- MPLIST_DO (pl, plist)
- {
- MPlist *p;
- MSymbol script, otf_script;
- OTF_Tag tag;
- if (! MPLIST_PLIST_P (pl))
- continue;
- p = MPLIST_PLIST (pl);
- if (! MPLIST_SYMBOL_P (p))
- continue;
- script = MPLIST_SYMBOL (p);
- p = MPLIST_NEXT (p);
- if (! MPLIST_SYMBOL_P (p))
- continue;
- otf_script = MPLIST_SYMBOL (p);
- tag = OTF_tag (MSYMBOL_NAME (otf_script));
- mplist_push (otf_script_list, script, (void *) tag);
- }
- M17N_OBJECT_UNREF (plist);
- return 0;
-}
-
-static MSymbol
-find_script_from_otf_tag (OTF_Tag tag)
+void
+OTF_tag_name (OTF_Tag tag, char *name)
{
- MPlist *plist;
-
- if (! otf_script_list)
- load_otf_script_list ();
- plist = mplist_find_by_value (otf_script_list, (void *) tag);
- return (plist ? MPLIST_KEY (plist) : Mnil);
+ name[0] = (char) (tag >> 24);
+ name[1] = (char) ((tag >> 16) & 0xFF);
+ name[2] = (char) ((tag >> 8) & 0xFF);
+ name[3] = (char) (tag & 0xFF);
+ name[4] = '\0';
}
+#endif /* not HAVE_OTF */
/* XLFD parser/generator */
char copy[513];
int i;
char *p;
+ MSymbol sym;
if (name[0] != '-')
return -1;
size = atoi (field[XLFD_PIXEL]) * 10;
if (field[XLFD_FOUNDRY])
- mfont__set_property (font, MFONT_FOUNDRY, msymbol (field[XLFD_FOUNDRY]));
+ {
+ sym = msymbol (field[XLFD_FOUNDRY]);
+ if (! sym)
+ sym = msymbol ("Nil");
+ mfont__set_property (font, MFONT_FOUNDRY, sym);
+ }
if (field[XLFD_FAMILY])
- mfont__set_property (font, MFONT_FAMILY, msymbol (field[XLFD_FAMILY]));
+ {
+ sym = msymbol (field[XLFD_FAMILY]);
+ if (! sym)
+ sym = msymbol ("Nil");
+ mfont__set_property (font, MFONT_FAMILY, sym);
+ }
if (field[XLFD_WEIGHT])
mfont__set_property (font, MFONT_WEIGHT, msymbol (field[XLFD_WEIGHT]));
if (field[XLFD_SLANT])
int len, i;
char spacing;
int size, resy;
+ int all_nil = 1;
prop[0] = (MSymbol) mfont_get_prop (font, Mfoundry);
prop[1] = (MSymbol) mfont_get_prop (font, Mfamily);
{
str[i] = msymbol_name (prop[i]);
len += strlen (str[i]);
+ all_nil = 0;
}
else
{
size = font->size;
if (size >= 0)
{
- if ((size % 10) < 5)
+ if (font->multiple_sizes)
+ {
+ for (size = 0; size < 24; size++)
+ if (font->size & (1 << size))
+ break;
+ size += 6;
+ }
+ else if ((size % 10) < 5)
size /= 10;
else
size = size / 10 + 1;
str[0], str[1], str[2], str[3], str[4], str[5],
size, resy, resy, spacing, str[6]);
}
+ else if (all_nil && size == 0)
+ sprintf (name, "*");
else
{
char *p = name;
{
if (font->size && request->size)
{
- val = font->size - request->size;
+ if (font->multiple_sizes)
+ {
+ int j, closest = 23;
+
+ for (j = 23; j >= 0; j--)
+ if (font->size & (1 << j))
+ {
+ closest = j;
+ if (request->size >= (j + 6) * 10)
+ break;
+ }
+ val = request->size - (closest + 6) * 10;
+ }
+ else
+ val = font->size - request->size;
if (val)
{
if (val < 0)
return score;
}
+static MSymbol
+merge_capability (MSymbol capability, MSymbol key, MSymbol val, int overwrite)
+{
+ MFontCapability *cap = NULL;
+ char *lang = NULL, *script = NULL, *otf = NULL, *buf, *p;
+ int lang_len = 0, script_len = 0, otf_len = 0;
+
+ if (key == Mlanguage)
+ lang = MSYMBOL_NAME (val), lang_len = MSYMBOL_NAMELEN (val) + 6;
+ else if (key == Mscript)
+ script = MSYMBOL_NAME (val), script_len = MSYMBOL_NAMELEN (val) + 7;
+ else if (key == Motf)
+ otf = MSYMBOL_NAME (val), otf_len = MSYMBOL_NAMELEN (val) + 5;
+ else
+ return capability;
+
+ if (capability != Mnil)
+ {
+ cap = mfont__get_capability (capability);
+ if (! overwrite)
+ {
+ if (cap->language)
+ lang = NULL;
+ if (cap->script)
+ script = NULL;
+ if (cap->script_tag)
+ otf = NULL;
+ if (! lang && !script && !otf)
+ return capability;
+ }
+ }
+
+ if (! lang && cap && cap->language)
+ {
+ lang_len = MSYMBOL_NAMELEN (cap->language);
+ lang = MSYMBOL_NAME (cap->language);
+ }
+ if (! script && cap && cap->script != Mnil)
+ {
+ script_len = MSYMBOL_NAMELEN (cap->script);
+ script = MSYMBOL_NAME (cap->script);
+ }
+ if (! otf && cap && cap->script_tag)
+ {
+ int i;
+
+ otf_len = 4; /* for script_tag */
+ if (cap->langsys_tag)
+ otf_len += 5; /* for "/XXXX */
+ for (i = 0; i < MFONT_OTT_MAX; i++)
+ if (cap->features[i].str)
+ otf_len += strlen (cap->features[i].str) + 1; /* for "[=+]..." */
+ otf = p = alloca (otf_len + 1);
+ OTF_tag_name (cap->script_tag, otf);
+ p += 4;
+ if (cap->langsys_tag)
+ {
+ *p++ = '/';
+ OTF_tag_name (cap->langsys_tag, p);
+ p += 4;
+ }
+ if (cap->features[MFONT_OTT_GSUB].str)
+ p += sprintf (p, "=%s", cap->features[MFONT_OTT_GSUB].str);
+ if (cap->features[MFONT_OTT_GPOS].str)
+ p += sprintf (p, "=%s", cap->features[MFONT_OTT_GSUB].str);
+ }
+ buf = p = alloca (lang_len + script_len + otf_len + 1);
+ if (lang_len)
+ p += sprintf (p, ":lang=%s", lang);
+ if (script_len)
+ p += sprintf (p, ":script=%s", script);
+ if (otf_len)
+ p += sprintf (p, ":otf=%s", otf);
+ return msymbol (buf);
+}
+
\f
/* Internal API */
Municode_full = msymbol ("unicode-full");
Mapple_roman = msymbol ("apple-roman");
+ Motf = msymbol ("otf");
+
/* 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++)
default_encoding.repertory_name = Mnil;
default_encoding.repertory_charset = NULL;
{
- char *path, *buf;
+ char *path, *buf = NULL;
int bufsize;
USE_SAFE_ALLOCA;
if (mfont__ft_init () < 0)
return -1;
#endif /* HAVE_FREETYPE */
- if (mfont__flt_init () < 0)
- return -1;
return 0;
}
MPlist *plist;
int i;
- mfont__flt_fini ();
#ifdef HAVE_FREETYPE
mfont__ft_fini ();
#endif /* HAVE_FREETYPE */
M17N_OBJECT_UNREF (font_encoding_list);
font_encoding_list = NULL;
}
- if (otf_script_list)
- {
- M17N_OBJECT_UNREF (otf_script_list);
- otf_script_list = NULL;
- }
for (i = 0; i <= MFONT_REGISTRY; i++)
MLIST_FREE1 (&mfont__property_table[i], names);
MSymbol
mfont__id (MFont *font)
{
- char *buf, *p;
+ char *buf = NULL, *p;
int i;
int file_len = (font->file == Mnil ? 0 : MSYMBOL_NAMELEN (font->file));
int capability_len = (font->capability == Mnil ? 0
mfont__match_p (MFont *font, MFont *spec, int prop)
{
if (spec->capability != font->capability
- && spec->capability != Mnil && font->capability != Mnil)
- return 0;
+ && spec->capability != Mnil)
+ {
+ MRealizedFont *rfont;
+
+ if (font->type != MFONT_TYPE_REALIZED)
+ return (font->capability == Mnil);
+ rfont = (MRealizedFont *) font;
+ return (rfont->driver->check_capability
+ && (rfont->driver->check_capability (rfont, spec->capability)
+ >= 0));
+ }
if (spec->file != font->file
&& spec->file != Mnil && font->file != Mnil)
return 0;
mfont__set_property (spec, i, face->property[i]);
spec->property[MFONT_REGISTRY] = 0;
spec->property[MFONT_RESY] = 0;
+ spec->multiple_sizes = 0;
spec->size = (int) (face->property[MFACE_SIZE]);
spec->type = MFONT_TYPE_SPEC;
spec->source = MFONT_SOURCE_UNDECIDED;
MTABLE_MALLOC (list->fonts, num, MERROR_FONT);
for (i = 0; num > 0; num--, pl = MPLIST_NEXT (pl))
{
- MFont *font = MPLIST_VAL (pl);
+ MFont *font = MPLIST_VAL (pl), *adjusted = font;
if (max_size == 0
|| font->size == 0
|| font->size < max_size)
{
list->fonts[i].font = font;
- list->fonts[i].score
- = spec == request ? 0 : font_score (font, request);
+ if (spec == request)
+ list->fonts[i].score = 0;
+ else
+ {
+ int resize_ratio;
+ MFont resized;
+
+ if (font->size > 0
+ && (resize_ratio = mfont_resize_ratio (font)) != 100)
+ {
+ resized = *font;
+ resized.size = font->size * 100 / resize_ratio;
+ adjusted = &resized;
+ }
+ list->fonts[i].score = font_score (adjusted, request);
+ }
i++;
}
}
return (driver->open) (frame, font, spec, rfont);
}
-void
-mfont__resize (MFont *spec, MFont *request)
-{
- MSymbol registry = FONT_PROPERTY (spec, MFONT_REGISTRY);
- MFontResize *resize;
- MPlist *plist;
-
- if (! font_resize_list)
- load_font_resize_table ();
- if (! MPLIST_TAIL_P (font_resize_list))
- while (1)
- {
- plist = font_resize_list;
- while (registry ? (plist = mplist_find_by_key (plist, registry))
- : plist)
- {
- resize = (MFontResize *) MPLIST_VAL (plist);
- if (mfont__match_p (spec, &resize->spec, MFONT_ADSTYLE))
- {
- request->size = request->size * resize->resize / 100;
- return;
- }
- plist = MPLIST_NEXT (plist);
- }
- if (registry == Mt)
- break;
- registry = Mt;
- }
-}
-
-
int
mfont__has_char (MFrame *frame, MFont *font, MFont *spec, int c)
{
MGlyph *from_g = MGLYPH (from), *to_g = MGLYPH (to), *g;
MRealizedFont *rfont = from_g->rface->rfont;
- for (g = from_g; g != to_g; g++)
- if (g->rface->rfont != rfont)
+ for (g = from_g; ; g++)
+ if (g == to_g || g->rface->rfont != rfont)
{
int idx = GLYPH_INDEX (g);
(rfont->driver->find_metric) (rfont, gstring, from, idx);
- from_g = g;
+ while (from_g < g)
+ {
+ from_g->g.xadv >>= 6;
+ from_g->g.yadv >>= 6;
+ from_g->g.xoff >>= 6;
+ from_g->g.yoff >>= 6;
+ from_g->g.ascent >>= 6;
+ from_g->g.descent >>= 6;
+ from_g->g.lbearing >>= 6;
+ from_g->g.rbearing >>= 6;
+ from_g++;
+ }
+ if (g == to_g)
+ break;
rfont = g->rface->rfont;
from = idx;
}
- (rfont->driver->find_metric) (rfont, gstring, from, GLYPH_INDEX (g));
}
+int
+mfont__get_glyph_id (MFLTFont *font, MFLTGlyphString *gstring,
+ int from, int to)
+{
+ MFont *mfont = (MFont *) ((MFLTFontForRealized *) font)->rfont;
+ MRealizedFont *rfont = ((MFLTFontForRealized *) font)->rfont;
+ MFontEncoding *encoding;
+ MFontDriver *driver = NULL;
+ MGlyph *glyphs = (MGlyph *) gstring->glyphs;
+ int result = 0;
+
+ encoding = mfont->encoding ? mfont->encoding : find_encoding (mfont);
+ for (; from < to; from++)
+ {
+ MGlyph *g = glyphs + from;
+
+ if (g->g.encoded)
+ continue;
+ if (mfont->source == MFONT_SOURCE_X && encoding->repertory_charset)
+ g->g.code = ENCODE_CHAR (encoding->repertory_charset, g->g.c);
+ else
+ {
+ unsigned code;
+
+ if (encoding->encoding_charset)
+ code = ENCODE_CHAR (encoding->encoding_charset, g->g.c);
+ else
+ code = g->g.code;
+
+ if (code != MCHAR_INVALID_CODE)
+ {
+ if (! driver)
+ {
+ if (mfont->type == MFONT_TYPE_REALIZED)
+ driver = rfont->driver;
+ else
+ {
+ driver = mplist_get (rfont->frame->font_driver_list,
+ mfont->source == MFONT_SOURCE_X
+ ? Mx : Mfreetype);
+ if (! driver)
+ MFATAL (MERROR_FONT);
+ }
+ }
+ g->g.code = (driver->encode_char) (rfont->frame, rfont->font,
+ mfont, code);
+ }
+ }
+ g->g.encoded = 1;
+ if (g->g.code == MCHAR_INVALID_CODE)
+ result = -1;
+ }
+ return result;
+}
+
+int
+mfont__get_metrics (MFLTFont *font, MFLTGlyphString *gstring,
+ int from, int to)
+{
+ MRealizedFont *rfont = ((MFLTFontForRealized *) font)->rfont;
+ MGlyphString gstr;
+
+ gstr.glyphs = (MGlyph *) gstring->glyphs;
+ (rfont->driver->find_metric) (rfont, &gstr, from, to);
+ return 0;
+}
/* KEY <= MFONT_REGISTRY */
{
MFontCapability *cap = object;
- if (cap->lang)
- free (cap->lang);
- if (cap->script)
+ if (cap->script_tag)
{
int i;
for (i = 0; i < MFONT_OTT_MAX; i++)
{
if (*str++ != ':')
continue;
- if (str[0] == 'o' && str[1] == 't' && str[2] == 'f' && str[3] == '=')
+ if (str[0] == 'o' && strncmp (str + 1, "tf=", 3) == 0)
{
+ char *beg;
+ MSymbol sym;
int i;
str += 4;
+ beg = str;
for (i = 0, p = str; i < 4 && p < endp; i++, p++);
if (i < 4)
break;
+ sym = msymbol__with_len (str, 4);
+ cap->script = mscript__from_otf_tag (sym);
+ if (cap->script == Mnil)
+ break;
cap->script_tag = OTF_tag (str);
- cap->script = find_script_from_otf_tag (cap->script_tag);
if (*p == '/')
{
for (i = 0, str = ++p; i < 4 && p < endp; i++, p++);
if (i < 4)
{
cap->script = Mnil;
+ cap->script_tag = 0;
break;
}
cap->langsys_tag = OTF_tag (str);
cap->features[i].tags = malloc (sizeof (OTF_Tag));
cap->features[i].tags[0] = 0;
}
+ cap->otf = msymbol__with_len (beg, p - beg);
str = p;
}
- else if (str[0] == 'l' && str[1] == 'a' && str[2] == 'n' && str[3] == 'g'
- && str[4] == '=')
+ else if (str[0] == 'l' && strncmp (str + 1, "ang=", 4) == 0)
{
- int count;
-
str += 5;
- for (p = str, count = 2; p < endp && *p != ':'; p++)
- if (*p == ',')
- count++;
- MTABLE_MALLOC (cap->lang, count, MERROR_FONT);
- for (p = str, count = 0; p < endp && *p != ':'; p++)
- if (*p == ',')
- {
- MSymbol lang = msymbol__with_len (str, p - str), sym;
-
- if (msymbol_get (lang, Miso639_2))
- cap->lang[count++] = lang;
- else if ((sym = msymbol_get (lang, Miso639_1)) != Mnil)
- cap->lang[count++] = sym;
- else if (msymbol_get (lang, Mlanguage))
- cap->lang[count++] = lang;
- str = p + 1;
- }
+ for (p = str; p < endp && *p != ':'; p++);
if (str < p)
- cap->lang[count++] = msymbol__with_len (str, p - str);
- cap->lang[count] = Mnil;
+ cap->language = msymbol__with_len (str, p - str);
str = p;
}
- else if (str[0] == 's' && str[1] == 'c' && str[2] == 'r' && str[3] == 'i'
- && str[4] == 'p' && str[5] == 't' && str[6] == '=')
+ else if (str[0] == 's' && strncmp (str + 1, "cript=", 6) == 0)
{
str += 7;
for (p = str; p < endp && *p != ':'; p++);
/***ja
@brief ³«È¯¸µ¤ò»ØÄꤹ¤ë¥Õ¥©¥ó¥È¥×¥í¥Ñ¥Æ¥£¤Î¥¡¼.
- ÊÑ¿ô #Mfoundry ¤Ï <tt>"fonudry"</tt>
+ ÊÑ¿ô #Mfoundry ¤Ï <tt>"foundry"</tt>
¤È¤¤¤¦Ì¾Á°¤ò»ý¤Ä¥·¥ó¥Ü¥ë¤Ç¤¢¤ê¡¢¥Õ¥©¥ó¥È¥×¥í¥Ñ¥Æ¥£¤È¥Õ¥§¡¼¥¹¥×¥í¥Ñ¥Æ¥£¤Î¥¡¼¤È¤·¤ÆÍѤ¤¤é¤ì¤ë¡£
Ãͤϡ¢¥Õ¥©¥ó¥È¤Î³«È¯¸µÌ¾¤ò̾Á°¤È¤·¤Æ»ý¤Ä¥·¥ó¥Ü¥ë¤Ç¤¢¤ë¡£ */
The variable #Mfontfile is a symbol of name <tt>"fontfile"</tt>
and is used as a key of font property. The property value must be
a symbol whose name is a font file name. */
+MSymbol Motf;
+
+/***en
+ @brief Key of font property specifying file name.
+
+ The variable #Mfontfile is a symbol of name <tt>"fontfile"</tt>
+ and is used as a key of font property. The property value must be
+ a symbol whose name is a font file name. */
/***ja
@brief ¥Õ¥©¥ó¥È¥Õ¥¡¥¤¥ë¤ò»ØÄꤹ¤ë¥Õ¥©¥ó¥È¥×¥í¥Ñ¥Æ¥£¤Î¥¡¼.
/***en
@brief Symbol of name "x".
- The variable #Mx is to be used for a value of <type> member of the
- structure #MDrawGlyph to specify the type of <fontp> member is
+ The variable #Mx is to be used for a value of \<type\> member of the
+ structure #MDrawGlyph to specify the type of \<fontp\> member is
actually (XFontStruct *). */
/***ja
@brief "x" ¤È¤¤¤¦Ì¾Á°¤ò»ý¤Ä¥·¥ó¥Ü¥ë.
- ÊÑ¿ô #Mx ¤Ï¹½Â¤ #MDrawGlyph ¤Î¥á¥ó¥Ð <type>
- ¤ÎÃͤȤ·¤ÆÍѤ¤¤é¤ì¡¢¥á¥ó¥Ð <fontp> ¤Î·¿¤¬¼ÂºÝ¤Ë¤Ï (XFontStruct *) ¤Ç¤¢¤ë¤³¤È¤òɽ¤¹. */
+ ÊÑ¿ô #Mx ¤Ï¹½Â¤ #MDrawGlyph ¤Î¥á¥ó¥Ð \<type\>
+ ¤ÎÃͤȤ·¤ÆÍѤ¤¤é¤ì¡¢¥á¥ó¥Ð \<fontp\> ¤Î·¿¤¬¼ÂºÝ¤Ë¤Ï (XFontStruct *) ¤Ç¤¢¤ë¤³¤È¤òɽ¤¹. */
MSymbol Mx;
/***en
@brief Symbol of name "freetype".
- The variable #Mfreetype is to be used for a value of <type> member
- of the structure #MDrawGlyph to specify the type of <fontp> member
+ The variable #Mfreetype is to be used for a value of \<type\> member
+ of the structure #MDrawGlyph to specify the type of \<fontp\> member
is actually FT_Face. */
/***ja
@brief "freetype" ¤È¤¤¤¦Ì¾Á°¤ò»ý¤Ä¥·¥ó¥Ü¥ë.
- ÊÑ¿ô #Mfreetype ¤Ï¹½Â¤ #MDrawGlyph ¤Î¥á¥ó¥Ð <type>
- ¤ÎÃͤȤ·¤ÆÍѤ¤¤é¤ì¡¢¥á¥ó¥Ð <fontp> ¤Î·¿¤¬¼ÂºÝ¤Ë¤Ï FT_Face ¤Ç¤¢¤ë¤³¤È¤òɽ¤¹¡£ */
+ ÊÑ¿ô #Mfreetype ¤Ï¹½Â¤ #MDrawGlyph ¤Î¥á¥ó¥Ð \<type\>
+ ¤ÎÃͤȤ·¤ÆÍѤ¤¤é¤ì¡¢¥á¥ó¥Ð \<fontp\> ¤Î·¿¤¬¼ÂºÝ¤Ë¤Ï FT_Face ¤Ç¤¢¤ë¤³¤È¤òɽ¤¹¡£ */
MSymbol Mfreetype;
/***en
@brief Symbol of name "xft".
- The variable #Mxft is to be used for a value of <type> member of the
- structure #MDrawGlyph to specify the type of <fontp> member
+ The variable #Mxft is to be used for a value of \<type\> member of the
+ structure #MDrawGlyph to specify the type of \<fontp\> member
is actually (XftFont *). */
/***ja
@brief "xft" ¤È¤¤¤¦Ì¾Á°¤ò»ý¤Ä¥·¥ó¥Ü¥ë.
- ÊÑ¿ô #Mxft ¤Ï¹½Â¤ #MDrawGlyph ¤Î¥á¥ó¥Ð <type>
- ¤ÎÃͤȤ·¤ÆÍѤ¤¤é¤ì¡¢¥á¥ó¥Ð <fontp> ¤Î·¿¤¬¼ÂºÝ¤Ë¤Ï (XftFont *) ¤Ç¤¢¤ë¤³¤È¤òɽ¤¹¡£ */
+ ÊÑ¿ô #Mxft ¤Ï¹½Â¤ #MDrawGlyph ¤Î¥á¥ó¥Ð \<type\>
+ ¤ÎÃͤȤ·¤ÆÍѤ¤¤é¤ì¡¢¥á¥ó¥Ð \<fontp\> ¤Î·¿¤¬¼ÂºÝ¤Ë¤Ï (XftFont *) ¤Ç¤¢¤ë¤³¤È¤òɽ¤¹¡£ */
MSymbol Mxft;
The mfont_get_prop () function gets the value of $KEY property of
font $FONT. $KEY must be one of the following symbols:
- @c Mfamily, @c Mweight, @c Mstyle, @c Mstretch, @c Madstyle,
- @c Mregistry, @c Msize, @c Mresolution, @c Mspacing.
+ @c Mfoundry, @c Mfamily, @c Mweight, @c Mstyle, @c Mstretch,
+ @c Madstyle, @c Mregistry, @c Msize, @c Mresolution, @c Mspacing.
If $FONT is a return value of mfont_find (), $KEY can also be one
of the following symbols:
- #Mfont_ascent, #Mfont_descent, #Mmax_advance.
-
- @return If $KEY is @c Mfamily, @c Mweight, @c Mstyle, @c Mstretch,
- @c Madstyle, @c Mregistry, or @c Mspacing, this function returns
- the corresponding value as a symbol. If the font does not have
- $KEY property, it returns @c Mnil. If $KEY is @c Msize, @c
- Mresolution, #Mfont_ascent, Mfont_descent, or #Mmax_advance, this
- function returns the corresponding value as an integer. If the
- font does not have $KEY property, it returns 0. If $KEY is
- something else, it returns @c NULL and assigns an error code to
- the external variable #merror_code. */
+ @b Mfont_ascent, @b Mfont_descent, #Mmax_advance.
+
+ @return
+ If $KEY is @c Mfoundry, @c Mfamily, @c Mweight, @c Mstyle,
+ @c Mstretch, @c Madstyle, @c Mregistry, or @c Mspacing, this
+ function returns the corresponding value as a symbol. If the font
+ does not have $KEY property, it returns @c Mnil. If $KEY is @c
+ Msize, @c Mresolution, @b Mfont_ascent, Mfont_descent, or
+ #Mmax_advance, this function returns the corresponding value as an
+ integer. If the font does not have $KEY property, it returns 0.
+ If $KEY is something else, it returns @c NULL and assigns an error
+ code to the external variable #merror_code. */
/***ja
@brief ¥Õ¥©¥ó¥È¤Î¥×¥í¥Ñ¥Æ¥£¤ÎÃͤòÆÀ¤ë.
$KEY ¤Ç¤¢¤ë¤â¤Î¤ÎÃͤòÊÖ¤¹¡£$KEY ¤Ï°Ê²¼¤Î¥·¥ó¥Ü¥ë¤Î¤¤¤º¤ì¤«¤Ç¤Ê¤±¤ì
¤Ð¤Ê¤é¤Ê¤¤¡£
- @c Mfamily, @c Mweight, @c Mstyle, @c Mstretch,
+ @c Mfoundry, @c Mfamily, @c Mweight, @c Mstyle, @c Mstretch,
@c Madstyle, @c Mregistry, @c Msize, @c Mresolution, @c Mspacing.
- @return $KEY ¤¬ @c Mfamily, @c Mweight, @c Mstyle, @c Mstretch, @c
- Madstyle, @c Mregistry, @c Mspacing ¤Î¤¤¤º¤ì¤«¤Ç¤¢¤ì¤Ð¡¢ÁêÅö¤¹¤ëÃÍ
- ¤ò¥·¥ó¥Ü¥ë¤È¤·¤ÆÊÖ¤¹¡£¥Õ¥©¥ó¥È¤¬¤½¤Î¥×¥í¥Ñ¥Æ¥£¤ò»ý¤¿¤Ê¤¤¾ì¹ç¤Ë¤Ï
- @c Mnil ¤òÊÖ¤¹¡£$KEY ¤¬ @c Msize ¤¢¤ë¤¤¤Ï @c Mresolution ¤Î¾ì¹ç¤Ë¤Ï¡¢
- ÁêÅö¤¹¤ëÃͤò¤ÏÀ°¿ôÃͤȤ·¤ÆÊÖ¤¹¡£¥Õ¥©¥ó¥È¤¬¤½¤Î¥×¥í¥Ñ¥Æ¥£¤ò»ý¤¿¤Ê¤¤
- ¾ì¹ç¤Ë¤Ï 0 ¤òÊÖ¤¹¡£$KEY ¤¬¤½¤ì°Ê³°¤Î¤â¤Î¤Ç¤¢¤ì¤Ð¡¢@c NULL ¤òÊÖ¤·¡¢
- ³°ÉôÊÑ¿ô #merror_code ¤Ë¥¨¥é¡¼¥³¡¼¥É¤òÀßÄꤹ¤ë¡£ */
+ @return
+ $KEY ¤¬ @c Mfoundry, @c Mfamily, @c Mweight, @c Mstyle, @c
+ Mstretch, @c Madstyle, @c Mregistry, @c Mspacing ¤Î¤¤¤º¤ì¤«¤Ç¤¢¤ì¤Ð¡¢
+ ÁêÅö¤¹¤ëÃͤò¥·¥ó¥Ü¥ë¤È¤·¤ÆÊÖ¤¹¡£¥Õ¥©¥ó¥È¤¬¤½¤Î¥×¥í¥Ñ¥Æ¥£¤ò»ý¤¿¤Ê¤¤
+ ¾ì¹ç¤Ë¤Ï@c Mnil ¤òÊÖ¤¹¡£$KEY ¤¬ @c Msize ¤¢¤ë¤¤¤Ï @c Mresolution ¤Î
+ ¾ì¹ç¤Ë¤Ï¡¢ÁêÅö¤¹¤ëÃͤò¤ÏÀ°¿ôÃͤȤ·¤ÆÊÖ¤¹¡£¥Õ¥©¥ó¥È¤¬¤½¤Î¥×¥í¥Ñ¥Æ¥£
+ ¤ò»ý¤¿¤Ê¤¤¾ì¹ç¤Ë¤Ï 0 ¤òÊÖ¤¹¡£$KEY ¤¬¤½¤ì°Ê³°¤Î¤â¤Î¤Ç¤¢¤ì¤Ð¡¢@c
+ NULL ¤òÊÖ¤·¡¢³°ÉôÊÑ¿ô #merror_code ¤Ë¥¨¥é¡¼¥³¡¼¥É¤òÀßÄꤹ¤ë¡£ */
void *
mfont_get_prop (MFont *font, MSymbol key)
int resy = font->property[MFONT_RESY];
return (void *) resy;
}
+ if (key == Mlanguage || key == Mscript || key == Motf)
+ {
+ MFontCapability *cap;
+
+ if (! font->capability)
+ return NULL;
+ cap = mfont__get_capability (font->capability);
+ if (key == Mlanguage)
+ return cap->language;
+ if (key == Mscript)
+ return cap->script;
+ return cap->otf;
+ }
+
if (key == Mfontfile)
return (void *) font->file;
if (key == Mspacing)
$KEY and value is $VAL to font $FONT. $KEY must be one of the
following symbols:
- @c Mfamily, @c Mweight, @c Mstyle, @c Mstretch,
+ @c Mfoundry, @c Mfamily, @c Mweight, @c Mstyle, @c Mstretch,
@c Madstyle, @c Mregistry, @c Msize, @c Mresolution.
If $KEY is @c Msize or @c Mresolution, $VAL must be an integer.
- Otherwise, $VAL must be a symbol. */
+ Otherwise, $VAL must be a symbol of a property value name. But,
+ if the name is "nil", a symbol of name "Nil" must be
+ specified. */
/***ja
@brief ¥Õ¥©¥ó¥È¤Î¥×¥í¥Ñ¥Æ¥£¤ËÃͤòÀßÄꤹ¤ë.
- ´Ø¿ô mfont_put_prop () ¤Ï¡¢¥Õ¥©¥ó¥È $FONT ¤Î¥¡¼¤¬$KEY
- ¤Ç¤¢¤ë¥×¥í¥Ñ¥Æ¥£¤ÎÃͤò $VAL ¤ËÀßÄꤹ¤ë¡£$KEY ¤Ï°Ê²¼¤Î¥·¥ó¥Ü¥ë¤Î¤¤¤º¤ì¤«¤Ç¤¢¤ë¡£
+ ´Ø¿ô mfont_put_prop () ¤Ï¡¢¥Õ¥©¥ó¥È $FONT ¤Î¥¡¼¤¬$KEY ¤Ç¤¢¤ë¥×¥í¥Ñ
+ ¥Æ¥£¤ÎÃͤò $VAL ¤ËÀßÄꤹ¤ë¡£$KEY ¤Ï°Ê²¼¤Î¥·¥ó¥Ü¥ë¤Î¤¤¤º¤ì¤«¤Ç¤¢¤ë¡£
- @c Mfamily, @c Mweight, @c Mstyle, @c Mstretch,
+ @c Mfoundry, @c Mfamily, @c Mweight, @c Mstyle, @c Mstretch,
@c Madstyle, @c Mregistry, @c Msize, @c Mresolution.
- $KEY ¤¬ @c Msize ¤« @c Mresolution ¤Ç¤¢¤ì¤Ð $VAL
- ¤ÏÀ°¿ôÃͤǤʤ¯¤Æ¤Ï¤é¤Ê¤¤¡£¤½¤ì°Ê³°¤Î¾ì¹ç¡¢$VAL ¤Ï¥·¥ó¥Ü¥ë¤Ç¤Ê¤¯¤Æ¤Ï¤Ê¤é¤Ê¤¤¡£*/
+ $KEY ¤¬ @c Msize ¤« @c Mresolution ¤Ç¤¢¤ì¤Ð $VAL ¤ÏÀ°¿ôÃͤǤʤ¯¤Æ¤Ï
+ ¤é¤Ê¤¤¡£¤½¤ì°Ê³°¤Î¾ì¹ç¡¢$VAL ¤Ï¥×¥í¥Ñ¥Æ¥£ÃͤÎ̾Á°¤Î¥·¥ó¥Ü¥ë¤Ç¤Ê¤¯¤Æ
+ ¤Ï¤Ê¤é¤Ê¤¤¡£¤¿¤À¤·¤â¤·¤½¤Î̾Á°¤¬ "nil" ¤Î¾ì¹ç¤Ï¡¢Ì¾Á°¤¬ "Nil" ¤Î¥·
+ ¥ó¥Ü¥ë¤Ç¤Ê¤¯¤Æ¤Ï¤Ê¤é¤Ê¤¤¡£*/
int
mfont_put_prop (MFont *font, MSymbol key, void *val)
unsigned resy = (unsigned) val;
font->property[MFONT_RESY] = resy;
}
- else if (key == Mlanguage)
+ else if (key == Mlanguage || key == Mscript || key == Motf)
{
- char *langname = MSYMBOL_NAME ((MSymbol) val);
- int len = MSYMBOL_NAMELEN ((MSymbol) val);
-
- if (len <= 3)
- {
- char buf[10];
-
- sprintf (buf, ":lang=%s", langname);
- font->capability = msymbol (buf);
- }
+ font->capability = merge_capability (font->capability,
+ key, (MSymbol) val, 1);
}
else if (key == Mfontfile)
{
int
mfont_resize_ratio (MFont *font)
{
- MFont request = *font;
+ MSymbol registry = FONT_PROPERTY (font, MFONT_REGISTRY);
+ MFontResize *resize;
+ MPlist *plist;
- mfont__resize (font, &request);
- return (font->size * 100 / request.size);
+ if (! font_resize_list)
+ load_font_resize_table ();
+ if (! MPLIST_TAIL_P (font_resize_list))
+ while (1)
+ {
+ plist = font_resize_list;
+ while (registry ? (plist = mplist_find_by_key (plist, registry))
+ : plist)
+ {
+ resize = (MFontResize *) MPLIST_VAL (plist);
+ if (mfont__match_p (font, &resize->spec, MFONT_ADSTYLE))
+ return resize->resize;
+ plist = MPLIST_NEXT (plist);
+ }
+ if (registry == Mt)
+ break;
+ registry = Mt;
+ }
+ return 100;
}
/*=*/
ones that support $LANGUAGE. $MAXNUM, if greater than 0, limits
the number of fonts.
+ $LANGUAGE argument exists just for backward compatibility, and the
+ use is deprecated. Use #Mlanguage font property instead. If
+ $FONT already has #Mlanguage property, $LANGUAGE is ignored.
+
@return
This function returns a plist whose keys are family names and
values are pointers to the object MFont. The plist must be freed
/***ja
@brief ¥Õ¥©¥ó¥È¤Î¥ê¥¹¥È¤òÆÀ¤ë
- ´Ø¿ô mfont_list () ¤Ï¥Õ¥ì¡¼¥à $FRAME ¤ÇÍøÍѲÄǽ¤Ê¥Õ¥©¥ó¥È¤Î¥ê¥¹¥È¤òÊÖ¤¹¡£
- $FONT ¤¬ NULL ¤Ç¤Ê¤±¤ì¤Ð¡¢$FONT ¤È¹çÃפ¹¤ëÍøÍѲÄǽ¤Ê¥Õ¥©¥ó¥È¤Î¥ê¥¹¥È¤òÊÖ¤¹¡£
- $LANGUAGE ¤¬ @c Mnil ¤Ç¤Ê¤±¤ì¤Ð¡¢$LANGUAGE ¤ò¥µ¥Ý¡¼¥È¤¹¤ëÍøÍѲÄǽ¤Ê¥Õ¥©¥ó¥È¤Î¥ê¥¹¥È¤òÊÖ¤¹¡£
- $MAXNUM ¤Ï¡¢0 ¤è¤êÂ礤¤¾ì¹ç¤Ë¤Ï¡¢ÊÖ¤¹¥Õ¥©¥ó¥È¤Î¿ô¤Î¾å¸Â¤Ç¤¢¤ë¡£
+ ´Ø¿ô mfont_list () ¤Ï¥Õ¥ì¡¼¥à $FRAME ¤ÇÍøÍѲÄǽ¤Ê¥Õ¥©¥ó¥È¤Î¥ê¥¹¥È¤ò
+ ÊÖ¤¹¡£$FONT ¤¬ NULL ¤Ç¤Ê¤±¤ì¤Ð¡¢$FONT ¤È¹çÃפ¹¤ëÍøÍѲÄǽ¤Ê¥Õ¥©¥ó¥È
+ ¤Î¥ê¥¹¥È¤òÊÖ¤¹¡£$LANGUAGE ¤¬ @c Mnil ¤Ç¤Ê¤±¤ì¤Ð¡¢$LANGUAGE ¤ò¥µ¥Ý¡¼
+ ¥È¤¹¤ëÍøÍѲÄǽ¤Ê¥Õ¥©¥ó¥È¤Î¥ê¥¹¥È¤òÊÖ¤¹¡£$MAXNUM ¤Ï¡¢0 ¤è¤êÂ礤¤¾ì
+ ¹ç¤Ë¤Ï¡¢ÊÖ¤¹¥Õ¥©¥ó¥È¤Î¿ô¤Î¾å¸Â¤Ç¤¢¤ë¡£
+
+ ¤¿¤À¤·¡¢°ú¿ô $LANGUAGE ¤ÏµìÈǤȤÎÀ°¹çÀ¤Î¤¿¤á¤À¤±¤Ë¤¢¤ê¡¢¤½¤Î»ÈÍѤÏ
+ ´«¤á¤é¤ì¤Ê¤¤¡£¥Õ¥©¥ó¥È¤Î #Mlanguage ¥×¥í¥Ñ¥Æ¥£¤ò»È¤¦¤Ù¤¤Ç¤¢¤ë¡£¤â
+ ¤· $FONT ¤¬¤¹¤Ç¤Ë¤³¤Î¥×¥í¥Ñ¥Æ¥£¤ò»ý¤Ã¤Æ¤¤¤¿¤é¡¢°ú¿ô $LANGUAGE ¤Ï̵
+
@return
- ¤³¤Î´Ø¿ô¤Ï¥¡¼¤¬¥Õ¥©¥ó¥È¥Õ¥¡¥ß¥ê̾¤Ç¤¢¤êÃͤ¬ MFont ¥ª¥Ö¥¸¥§¥¯¥È¤Ø¤Î¥Ý¥¤¥ó¥¿¤Ç¤¢¤ë¤è¤¦¤Ê
- plist ¤òÊÖ¤¹¡£plist ¤Ï m17n_object_unref ()
- ¤Ç²òÊü¤¹¤ëɬÍפ¬¤¢¤ë¡£¥Õ¥©¥ó¥È¤¬¸«¤Ä¤«¤é¤Ê¤±¤ì¤ÐNULL ¤òÊÖ¤¹¡£ */
+ ¤³¤Î´Ø¿ô¤Ï¥¡¼¤¬¥Õ¥©¥ó¥È¥Õ¥¡¥ß¥ê̾¤Ç¤¢¤êÃͤ¬ MFont ¥ª¥Ö¥¸¥§¥¯¥È¤Ø¤Î
+ ¥Ý¥¤¥ó¥¿¤Ç¤¢¤ë¤è¤¦¤Êplist ¤òÊÖ¤¹¡£plist ¤Ï m17n_object_unref () ¤Ç
+ ²òÊü¤¹¤ëɬÍפ¬¤¢¤ë¡£¥Õ¥©¥ó¥È¤¬¸«¤Ä¤«¤é¤Ê¤±¤ì¤ÐNULL ¤òÊÖ¤¹¡£ */
MPlist *
mfont_list (MFrame *frame, MFont *font, MSymbol language, int maxnum)
}
if (language != Mnil)
- {
- /* ":lang=XXX" */
- char *buf = alloca (MSYMBOL_NAMELEN (language) + 7);
-
- sprintf (buf, ":lang=%s", MSYMBOL_NAME (language));
- spec.capability = msymbol (buf);
- }
+ spec.capability = merge_capability (spec.capability, Mlanguage, language,
+ 0);
font_list = mfont__list (frame, &spec, &spec, 0);
if (! font_list)
return plist;
}
+/***en
+ @brief Get a list of font famiy names.
+
+ The mfont_list_family_names () functions returns a list of font
+ family names available on frame $FRAME.
+
+ @return
+
+ This function returns a plist whose keys are #Msymbol and values
+ are symbols representing font family names. The elements are
+ sorted by alphabetical order. The plist must be freed by
+ m17n_object_unref (). If not font is found, it returns NULL. */
+
+MPlist *
+mfont_list_family_names (MFrame *frame)
+{
+ MPlist *plist = mplist (), *p;
+
+ MPLIST_DO (p, frame->font_driver_list)
+ {
+ MFontDriver *driver = MPLIST_VAL (p);
+
+ (driver->list_family_names) (frame, plist);
+ }
+ return plist;
+}
+
/*=*/
/***en
@brief Check the usability of a font.
- The function mfont_check () checkes if $FONT can be used for
+ The mfont_check () function checkes if $FONT can be used for
$SCRIPT and $LANGUAGE in $FONTSET on $FRAME.
- @return If the font is usable, return 1. Otherwise return 0.
+ @return
+ If the font is usable, return 1. Otherwise return 0.
*/
int
return (score == 0 ? 2 : 1);
}
+/*=*/
+
+/***en
+ @brief Check is a font matches with a font spec.
+
+ The mfont_match_p () function checks if $FONT matches with the
+ font-spec $SPEC.
+
+ @return
+ If the font matches, 1 is returned. Otherwise 0 is returned. */
+
+int
+mfont_match_p (MFont *font, MFont *spec)
+{
+ return mfont__match_p (font, spec, MFONT_REGISTRY);
+}
+
+/*=*/
+/***en
+ @brief Open a font.
+
+ The mfont_open () function opens $FONT on $FRAME, and returns a
+ realized font.
+
+ @return
+ If the font was successfully opened, a realized font is returned.
+ Otherwize NULL is returned.
+
+ @seealso
+ mfont_close (). */
+
+
+MFont *
+mfont_open (MFrame *frame, MFont *font)
+{
+ enum MFontType font_type = font->type;
+
+ if (font_type == MFONT_TYPE_SPEC)
+ return mfont_find (frame, font, NULL, 0);
+ if (font_type == MFONT_TYPE_OBJECT)
+ return (MFont *) mfont__open (frame, font, font);
+ if (font_type == MFONT_TYPE_REALIZED)
+ return font;
+ MERROR (MERROR_FONT, NULL);
+}
+
+/*=*/
+/***en
+ @brief Encapusulate a font.
+
+ The mfont_encapsulate () functions realizes a font by
+ encapusulating data $DATA or type $DATA_TYPE on $FRAME. Currently
+ $DATA_TAPE is #Mfontconfig or #Mfreetype, and $DATA points to an
+ object of FcPattern or FT_Face respectively.
+
+ @return
+ If the operation was successful, a realized font is returned.
+ Otherwise NULL is return.
+
+ @seealso
+ mfont_close (). */
+
+
+MFont *
+mfont_encapsulate (MFrame *frame, MSymbol data_type, void *data)
+{
+ MPlist *p;
+
+ MPLIST_DO (p, frame->font_driver_list)
+ {
+ MFontDriver *driver = MPLIST_VAL (p);
+ MRealizedFont *rfont;
+
+ if (driver->encapsulate
+ && (rfont = driver->encapsulate (frame, data_type, data)))
+ return (MFont *) rfont;
+ }
+
+ return NULL;
+}
+
+/*=*/
+/***en
+ @brief Close a font.
+
+ The mfont_close () function close a realized font $FONT. $FONT
+ must be opened previously by mfont_open () or mfont_encapsulate
+ ().
+
+ @return
+ If the operation was successful, 0 is returned. Otherwise, -1 is
+ returned.
+
+ @seealso
+ mfont_open (), mfont_encapsulate (). */
+
+int
+mfont_close (MFont *font)
+{
+ enum MFontType font_type = font->type;
+ MRealizedFont *rfont;
+
+ if (font_type != MFONT_TYPE_REALIZED)
+ MERROR (MERROR_FONT, -1);
+ rfont = (MRealizedFont *) font;
+ if (rfont->encapsulating
+ && rfont->driver->close)
+ rfont->driver->close (rfont);
+ return 0;
+}
+
/*** @} */
/*** @addtogroup m17nDebug */