+static int
+fc_encode_prop (char *name, FC_vs_M17N_font_prop *table)
+{
+ int i;
+
+ for (i = 0; table[i].m17n_value && strcmp (name, table[i].m17n_value); i++);
+ return table[i].fc_value;
+}
+
+int
+mfont__ft_parse_name (char *name, MFont *font)
+{
+ FcPattern *pat = FcNameParse ((FcChar8 *) name);
+ FcChar8 *str;
+ int val;
+ double size;
+
+ if (! pat)
+ return -1;
+ if (FcPatternGetString (pat, FC_FOUNDRY, 0, &str) == FcResultMatch)
+ mfont__set_property (font, MFONT_FOUNDRY, msymbol ((char *) str));
+ if (FcPatternGetString (pat, FC_FAMILY, 0, &str) == FcResultMatch)
+ mfont__set_property (font, MFONT_FAMILY, msymbol ((char *) str));
+ if (FcPatternGetInteger (pat, FC_WEIGHT, 0, &val) == FcResultMatch)
+ mfont__set_property (font, MFONT_WEIGHT,
+ fc_decode_prop (val, fc_weight_table));
+ if (FcPatternGetInteger (pat, FC_SLANT, 0, &val) == FcResultMatch)
+ mfont__set_property (font, MFONT_STYLE,
+ fc_decode_prop (val, fc_slant_table));
+ if (FcPatternGetInteger (pat, FC_WIDTH, 0, &val) == FcResultMatch)
+ mfont__set_property (font, MFONT_STRETCH,
+ fc_decode_prop (val, fc_width_table));
+ if (FcPatternGetDouble (pat, FC_PIXEL_SIZE, 0, &size) == FcResultMatch)
+ font->property[MFONT_SIZE] = size * 10;
+ FcPatternDestroy (pat);
+ return 0;
+}
+
+char *
+mfont__ft_unparse_name (MFont *font)
+{
+ FcPattern *pat = FcPatternCreate ();
+ MSymbol sym, weight, style, stretch;
+ char *name;
+
+ if ((sym = (MSymbol) FONT_PROPERTY (font, MFONT_FOUNDRY)) != Mnil)
+ FcPatternAddString (pat, FC_FOUNDRY, (FcChar8 *) MSYMBOL_NAME (sym));
+ if ((sym = (MSymbol) FONT_PROPERTY (font, MFONT_FAMILY)) != Mnil)
+ FcPatternAddString (pat, FC_FAMILY, (FcChar8 *) MSYMBOL_NAME (sym));
+ if ((weight = (MSymbol) FONT_PROPERTY (font, MFONT_WEIGHT)) != Mnil)
+ FcPatternAddInteger (pat, FC_WEIGHT, fc_encode_prop (MSYMBOL_NAME (weight),
+ fc_weight_table));
+ if ((style = (MSymbol) FONT_PROPERTY (font, MFONT_STYLE)) != Mnil)
+ FcPatternAddInteger (pat, FC_SLANT, fc_encode_prop (MSYMBOL_NAME (style),
+ fc_slant_table));
+ if ((stretch = (MSymbol) FONT_PROPERTY (font, MFONT_STRETCH)) != Mnil)
+ FcPatternAddInteger (pat, FC_WIDTH, fc_encode_prop (MSYMBOL_NAME (stretch),
+ fc_width_table));
+ name = (char *) FcNameUnparse (pat);
+ FcPatternDestroy (pat);
+ return name;
+}
+#endif /* HAVE_FONTCONFIG */
+
+\f
+#ifdef HAVE_OTF
+
+#define DEVICE_DELTA(table, size) \
+ (((size) >= (table).StartSize && (size) <= (table).EndSize) \
+ ? (table).DeltaValue[(size) >= (table).StartSize] \
+ : 0)
+
+void
+adjust_anchor (OTF_Anchor *anchor, FT_Face ft_face,
+ unsigned code, int size, int *x, int *y)
+{
+ if (anchor->AnchorFormat == 2)
+ {
+ FT_Outline *outline;
+ int ap = anchor->f.f1.AnchorPoint;
+
+ FT_Load_Glyph (ft_face, (FT_UInt) code, FT_LOAD_MONOCHROME);
+ outline = &ft_face->glyph->outline;
+ if (ap < outline->n_points)
+ {
+ *x = outline->points[ap].x;
+ *y = outline->points[ap].y;
+ }
+ }
+ else if (anchor->AnchorFormat == 3)
+ {
+ *x += DEVICE_DELTA (anchor->f.f2.XDeviceTable, size);
+ *y += DEVICE_DELTA (anchor->f.f2.YDeviceTable, size);
+ }
+}