comparison src/ftfont.c @ 91137:00323e98bffb

Don't include Freetype headers. Include "ftfont.h". (struct ftfont_info) [HAVE_LIBOTF]: New members maybe_otf and otf. (ftfont_open) [HAVE_LIBOTF]: Initialize the above members. (ftfont_driver) [HAVE_LIBOTF, HAVE_M17N_FLT]: Don't set font_otf_capability and font_drive_otf, set ftfont_shape. (ftfont_list): Adjusted for the change of :otf property value. (struct MFLTFontFT) [HAVE_LIBOTF, HAVE_M17N_FLT]: New struct. (ftfont_get_glyph_id, ftfont_get_metrics, ftfont_check_otf) (adjust_anchor, ftfont_drive_otf, ftfont_shape_by_flt) (ftfont_shape) [HAVE_LIBOTF, HAVE_M17N_FLT]: New function.s (DEVICE_DELTA) [HAVE_LIBOTF, HAVE_M17N_FLT]: New macro. (otf_gstring, gstring, m17n_flt_initialized): New variables.
author Kenichi Handa <handa@m17n.org>
date Sat, 01 Dec 2007 02:39:27 +0000
parents 6da57551efb7
children 2b263ef46651
comparison
equal deleted inserted replaced
91136:d54684fee154 91137:00323e98bffb
22 Boston, MA 02110-1301, USA. */ 22 Boston, MA 02110-1301, USA. */
23 23
24 #include <config.h> 24 #include <config.h>
25 #include <stdio.h> 25 #include <stdio.h>
26 26
27 #include <ft2build.h>
28 #include FT_FREETYPE_H
29 #include FT_SIZES_H
30 #include <fontconfig/fontconfig.h> 27 #include <fontconfig/fontconfig.h>
31 #include <fontconfig/fcfreetype.h> 28 #include <fontconfig/fcfreetype.h>
32 29
33 #include "lisp.h" 30 #include "lisp.h"
34 #include "dispextern.h" 31 #include "dispextern.h"
37 #include "character.h" 34 #include "character.h"
38 #include "charset.h" 35 #include "charset.h"
39 #include "coding.h" 36 #include "coding.h"
40 #include "fontset.h" 37 #include "fontset.h"
41 #include "font.h" 38 #include "font.h"
39 #include "ftfont.h"
42 40
43 /* Symbolic type of this font-driver. */ 41 /* Symbolic type of this font-driver. */
44 Lisp_Object Qfreetype; 42 Lisp_Object Qfreetype;
45 43
46 /* Fontconfig's generic families and their aliases. */ 44 /* Fontconfig's generic families and their aliases. */
64 62
65 struct ftfont_info 63 struct ftfont_info
66 { 64 {
67 struct font font; 65 struct font font;
68 FT_Size ft_size; 66 FT_Size ft_size;
67 #ifdef HAVE_LIBOTF
68 int maybe_otf; /* Flag to tell if this may be OTF or not. */
69 OTF *otf;
70 #endif /* HAVE_LIBOTF */
69 }; 71 };
70 72
71 static int ftfont_build_basic_charsets P_ ((void)); 73 static int ftfont_build_basic_charsets P_ ((void));
72 static Lisp_Object ftfont_pattern_entity P_ ((FcPattern *, 74 static Lisp_Object ftfont_pattern_entity P_ ((FcPattern *,
73 Lisp_Object, Lisp_Object)); 75 Lisp_Object, Lisp_Object));
273 struct font_metrics *)); 275 struct font_metrics *));
274 static int ftfont_get_bitmap P_ ((struct font *, unsigned, 276 static int ftfont_get_bitmap P_ ((struct font *, unsigned,
275 struct font_bitmap *, int)); 277 struct font_bitmap *, int));
276 static int ftfont_anchor_point P_ ((struct font *, unsigned, int, 278 static int ftfont_anchor_point P_ ((struct font *, unsigned, int,
277 int *, int *)); 279 int *, int *));
280 static Lisp_Object ftfont_shape P_ ((Lisp_Object));
278 281
279 struct font_driver ftfont_driver = 282 struct font_driver ftfont_driver =
280 { 283 {
281 0, /* Qfreetype */ 284 0, /* Qfreetype */
282 ftfont_get_cache, 285 ftfont_get_cache,
297 ftfont_get_bitmap, 300 ftfont_get_bitmap,
298 NULL, 301 NULL,
299 NULL, 302 NULL,
300 NULL, 303 NULL,
301 ftfont_anchor_point, 304 ftfont_anchor_point,
302 #ifdef HAVE_LIBOTF
303 font_otf_capability,
304 font_drive_otf,
305 #else
306 NULL, 305 NULL,
307 NULL, 306 NULL,
307 NULL,
308 NULL,
309 #ifdef HAVE_M17N_FLT
310 ftfont_shape
311 #else /* not HAVE_M17N_FLT */
308 NULL 312 NULL
309 #endif /* HAVE_LIBOTF */ 313 #endif /* not HAVE_M17N_FLT */
310 }; 314 };
311 315
312 extern Lisp_Object QCname; 316 extern Lisp_Object QCname;
313 317
314 static Lisp_Object 318 static Lisp_Object
378 382
379 tmp = XCAR (extra); 383 tmp = XCAR (extra);
380 key = XCAR (tmp), val = XCDR (tmp); 384 key = XCAR (tmp), val = XCDR (tmp);
381 if (EQ (key, QCotf)) 385 if (EQ (key, QCotf))
382 { 386 {
383 script = assq_no_quit (val, Votf_script_alist); 387 tmp = XCAR (val);
384 if (CONSP (script) && SYMBOLP (XCDR (script))) 388 if (NILP (tmp))
385 script = XCDR (script); 389 strcpy (otf_script, "otlayout:DFLT");
386 tmp = SYMBOL_NAME (val); 390 else
387 sprintf (otf_script, "otlayout:%s", (char *) SDATA (tmp)); 391 {
392 val = assq_no_quit (tmp, Votf_script_alist);
393 if (CONSP (val) && SYMBOLP (XCDR (val)))
394 {
395 sprintf (otf_script, "otlayout:%s",
396 (char *) SDATA (SYMBOL_NAME (tmp)));
397 script = XCDR (val);
398 }
399 }
388 } 400 }
389 else if (EQ (key, QClanguage)) 401 else if (EQ (key, QClanguage))
390 { 402 {
391 langset = FcLangSetCreate (); 403 langset = FcLangSetCreate ();
392 if (! langset) 404 if (! langset)
721 733
722 ftfont_info = malloc (sizeof (struct ftfont_info)); 734 ftfont_info = malloc (sizeof (struct ftfont_info));
723 if (! ftfont_info) 735 if (! ftfont_info)
724 return NULL; 736 return NULL;
725 ftfont_info->ft_size = ft_size; 737 ftfont_info->ft_size = ft_size;
738 ftfont_info->maybe_otf = ft_face->face_flags & FT_FACE_FLAG_SFNT;
739 ftfont_info->otf = NULL;
726 740
727 font = (struct font *) ftfont_info; 741 font = (struct font *) ftfont_info;
728 font->format = ftfont_font_format (pattern); 742 font->format = ftfont_font_format (pattern);
729 font->entity = entity; 743 font->entity = entity;
730 font->pixel_size = size; 744 font->pixel_size = size;
800 Lisp_Object entity = font->entity; 814 Lisp_Object entity = font->entity;
801 Lisp_Object val = AREF (entity, FONT_EXTRA_INDEX); 815 Lisp_Object val = AREF (entity, FONT_EXTRA_INDEX);
802 816
803 (XSAVE_VALUE (val)->integer)--; 817 (XSAVE_VALUE (val)->integer)--;
804 if (XSAVE_VALUE (val)->integer == 0) 818 if (XSAVE_VALUE (val)->integer == 0)
805 FT_Done_Face (ftfont_info->ft_size->face); 819 {
820 FT_Done_Face (ftfont_info->ft_size->face);
821 #ifdef HAVE_LIBOTF
822 if (ftfont_info->otf)
823 OTF_close (ftfont_info->otf);
824 #endif
825 }
806 else 826 else
807 FT_Done_Size (ftfont_info->ft_size); 827 FT_Done_Size (ftfont_info->ft_size);
808 828
809 free (font); 829 free (font);
810 } 830 }
954 return -1; 974 return -1;
955 *x = ft_face->glyph->outline.points[index].x; 975 *x = ft_face->glyph->outline.points[index].x;
956 *y = ft_face->glyph->outline.points[index].y; 976 *y = ft_face->glyph->outline.points[index].y;
957 return 0; 977 return 0;
958 } 978 }
979
980 #ifdef HAVE_LIBOTF
981 #ifdef HAVE_M17N_FLT
982
983 struct MFLTFontFT
984 {
985 MFLTFont flt_font;
986 struct font *font;
987 FT_Face ft_face;
988 OTF *otf;
989 };
990
991 static int
992 ftfont_get_glyph_id (font, gstring, from, to)
993 MFLTFont *font;
994 MFLTGlyphString *gstring;
995 int from, to;
996 {
997 struct MFLTFontFT *flt_font_ft = (struct MFLTFontFT *) font;
998 FT_Face ft_face = flt_font_ft->ft_face;
999 MFLTGlyph *g;
1000
1001 for (g = gstring->glyphs + from; from < to; g++, from++)
1002 if (! g->encoded)
1003 {
1004 FT_UInt code = FT_Get_Char_Index (ft_face, g->code);
1005
1006 g->code = code > 0 ? code : FONT_INVALID_CODE;
1007 g->encoded = 1;
1008 }
1009 return 0;
1010 }
1011
1012 static int
1013 ftfont_get_metrics (font, gstring, from, to)
1014 MFLTFont *font;
1015 MFLTGlyphString *gstring;
1016 int from, to;
1017 {
1018 struct MFLTFontFT *flt_font_ft = (struct MFLTFontFT *) font;
1019 FT_Face ft_face = flt_font_ft->ft_face;
1020 MFLTGlyph *g;
1021
1022 for (g = gstring->glyphs + from; from < to; g++, from++)
1023 if (! g->measured)
1024 {
1025 if (g->code != FONT_INVALID_CODE)
1026 {
1027 FT_Glyph_Metrics *m;
1028
1029 if (FT_Load_Glyph (ft_face, g->code, FT_LOAD_DEFAULT) != 0)
1030 abort ();
1031 m = &ft_face->glyph->metrics;
1032
1033 g->lbearing = m->horiBearingX;
1034 g->rbearing = m->horiBearingX + m->width;
1035 g->ascent = m->horiBearingY;
1036 g->descent = m->height - m->horiBearingY;
1037 g->xadv = m->horiAdvance;
1038 }
1039 else
1040 {
1041 g->lbearing = 0;
1042 g->rbearing = g->xadv = flt_font_ft->font->font.space_width << 6;
1043 g->ascent = flt_font_ft->font->ascent << 6;
1044 g->descent = flt_font_ft->font->descent << 6;
1045 }
1046 g->yadv = 0;
1047 g->measured = 1;
1048 }
1049 return 0;
1050 }
1051
1052 static int
1053 ftfont_check_otf (MFLTFont *font, MFLTOtfSpec *spec)
1054 {
1055 struct MFLTFontFT *flt_font_ft = (struct MFLTFontFT *) font;
1056 OTF *otf = flt_font_ft->otf;
1057 OTF_Tag *tags;
1058 int i, n, negative;
1059
1060 for (i = 0; i < 2; i++)
1061 {
1062 if (! spec->features[i])
1063 continue;
1064 for (n = 0; spec->features[i][n]; n++);
1065 tags = alloca (sizeof (OTF_Tag) * n);
1066 for (n = 0, negative = 0; spec->features[i][n]; n++)
1067 {
1068 if (spec->features[i][n] == 0xFFFFFFFF)
1069 negative = 1;
1070 else if (negative)
1071 tags[n - 1] = spec->features[i][n] | 0x80000000;
1072 else
1073 tags[n] = spec->features[i][n];
1074 }
1075 if (n - negative > 0
1076 && OTF_check_features (otf, i == 0, spec->script, spec->langsys,
1077 tags, n - negative) != 1)
1078 return 0;
1079 }
1080 return 1;
1081 }
1082
1083 #define DEVICE_DELTA(table, size) \
1084 (((size) >= (table).StartSize && (size) <= (table).EndSize) \
1085 ? (table).DeltaValue[(size) - (table).StartSize] << 6 \
1086 : 0)
1087
1088 static void
1089 adjust_anchor (FT_Face ft_face, OTF_Anchor *anchor,
1090 unsigned code, int x_ppem, int y_ppem, int *x, int *y)
1091 {
1092 if (anchor->AnchorFormat == 2)
1093 {
1094 FT_Outline *outline;
1095 int ap = anchor->f.f1.AnchorPoint;
1096
1097 FT_Load_Glyph (ft_face, (FT_UInt) code, FT_LOAD_MONOCHROME);
1098 outline = &ft_face->glyph->outline;
1099 if (ap < outline->n_points)
1100 {
1101 *x = outline->points[ap].x << 6;
1102 *y = outline->points[ap].y << 6;
1103 }
1104 }
1105 else if (anchor->AnchorFormat == 3)
1106 {
1107 if (anchor->f.f2.XDeviceTable.offset)
1108 *x += DEVICE_DELTA (anchor->f.f2.XDeviceTable, x_ppem);
1109 if (anchor->f.f2.YDeviceTable.offset)
1110 *y += DEVICE_DELTA (anchor->f.f2.YDeviceTable, y_ppem);
1111 }
1112 }
1113
1114 static OTF_GlyphString otf_gstring;
1115
1116 static int
1117 ftfont_drive_otf (font, spec, in, from, to, out, adjustment)
1118 MFLTFont *font;
1119 MFLTOtfSpec *spec;
1120 MFLTGlyphString *in;
1121 int from, to;
1122 MFLTGlyphString *out;
1123 MFLTGlyphAdjustment *adjustment;
1124 {
1125 struct MFLTFontFT *flt_font_ft = (struct MFLTFontFT *) font;
1126 FT_Face ft_face = flt_font_ft->ft_face;
1127 OTF *otf = flt_font_ft->otf;
1128 int len = to - from;
1129 int i, j, gidx;
1130 OTF_Glyph *otfg;
1131 char script[5], *langsys = NULL;
1132 char *gsub_features = NULL, *gpos_features = NULL;
1133
1134 if (len == 0)
1135 return from;
1136 OTF_tag_name (spec->script, script);
1137 if (spec->langsys)
1138 {
1139 langsys = alloca (5);
1140 OTF_tag_name (spec->langsys, langsys);
1141 }
1142 for (i = 0; i < 2; i++)
1143 {
1144 char *p;
1145
1146 if (spec->features[i] && spec->features[i][1] != 0xFFFFFFFF)
1147 {
1148 for (j = 0; spec->features[i][j]; j++);
1149 if (i == 0)
1150 p = gsub_features = alloca (6 * j);
1151 else
1152 p = gpos_features = alloca (6 * j);
1153 for (j = 0; spec->features[i][j]; j++)
1154 {
1155 if (spec->features[i][j] == 0xFFFFFFFF)
1156 *p++ = '*', *p++ = ',';
1157 else
1158 {
1159 OTF_tag_name (spec->features[i][j], p);
1160 p[4] = ',';
1161 p += 5;
1162 }
1163 }
1164 *--p = '\0';
1165 }
1166 }
1167
1168 if (otf_gstring.size == 0)
1169 {
1170 otf_gstring.glyphs = (OTF_Glyph *) malloc (sizeof (OTF_Glyph) * len);
1171 otf_gstring.size = len;
1172 }
1173 else if (otf_gstring.size < len)
1174 {
1175 otf_gstring.glyphs = (OTF_Glyph *) realloc (otf_gstring.glyphs,
1176 sizeof (OTF_Glyph) * len);
1177 otf_gstring.size = len;
1178 }
1179 otf_gstring.used = len;
1180 memset (otf_gstring.glyphs, 0, sizeof (OTF_Glyph) * len);
1181 for (i = 0; i < len; i++)
1182 {
1183 otf_gstring.glyphs[i].c = in->glyphs[from + i].c;
1184 otf_gstring.glyphs[i].glyph_id = in->glyphs[from + i].code;
1185 }
1186
1187 OTF_drive_gdef (otf, &otf_gstring);
1188 gidx = out->used;
1189
1190 if (gsub_features)
1191 {
1192 if (OTF_drive_gsub (otf, &otf_gstring, script, langsys, gsub_features)
1193 < 0)
1194 goto simple_copy;
1195 if (out->allocated < out->used + otf_gstring.used)
1196 return -2;
1197 for (i = 0, otfg = otf_gstring.glyphs; i < otf_gstring.used; i++, otfg++)
1198 {
1199 MFLTGlyph *g = out->glyphs + out->used;
1200 int j;
1201
1202 *g = in->glyphs[from + otfg->f.index.from];
1203 g->c = 0;
1204 for (j = from + otfg->f.index.from; j <= from + otfg->f.index.to; j++)
1205 if (in->glyphs[j].code == otfg->glyph_id)
1206 {
1207 g->c = in->glyphs[j].c;
1208 break;
1209 }
1210 if (g->code != otfg->glyph_id)
1211 {
1212 g->code = otfg->glyph_id;
1213 g->measured = 0;
1214 }
1215 out->used++;
1216 }
1217 }
1218 else
1219 {
1220 if (out->allocated < out->used + len)
1221 return -2;
1222 for (i = 0; i < len; i++)
1223 out->glyphs[out->used++] = in->glyphs[from + i];
1224 }
1225
1226 if (gpos_features)
1227 {
1228 MFLTGlyph *base = NULL, *mark = NULL, *g;
1229 int x_ppem, y_ppem, x_scale, y_scale;
1230
1231 if (OTF_drive_gpos (otf, &otf_gstring, script, langsys, gpos_features)
1232 < 0)
1233 return to;
1234
1235 x_ppem = ft_face->size->metrics.x_ppem;
1236 y_ppem = ft_face->size->metrics.y_ppem;
1237 x_scale = ft_face->size->metrics.x_scale;
1238 y_scale = ft_face->size->metrics.y_scale;
1239
1240 for (i = 0, otfg = otf_gstring.glyphs, g = out->glyphs + gidx;
1241 i < otf_gstring.used; i++, otfg++, g++)
1242 {
1243 MFLTGlyph *prev;
1244
1245 if (! otfg->glyph_id)
1246 continue;
1247 switch (otfg->positioning_type)
1248 {
1249 case 0:
1250 break;
1251 case 1: /* Single */
1252 case 2: /* Pair */
1253 {
1254 int format = otfg->f.f1.format;
1255
1256 if (format & OTF_XPlacement)
1257 adjustment[i].xoff
1258 = otfg->f.f1.value->XPlacement * x_scale / 0x10000;
1259 if (format & OTF_XPlaDevice)
1260 adjustment[i].xoff
1261 += DEVICE_DELTA (otfg->f.f1.value->XPlaDevice, x_ppem);
1262 if (format & OTF_YPlacement)
1263 adjustment[i].yoff
1264 = - (otfg->f.f1.value->YPlacement * y_scale / 0x10000);
1265 if (format & OTF_YPlaDevice)
1266 adjustment[i].yoff
1267 -= DEVICE_DELTA (otfg->f.f1.value->YPlaDevice, y_ppem);
1268 if (format & OTF_XAdvance)
1269 adjustment[i].xadv
1270 += otfg->f.f1.value->XAdvance * x_scale / 0x10000;
1271 if (format & OTF_XAdvDevice)
1272 adjustment[i].xadv
1273 += DEVICE_DELTA (otfg->f.f1.value->XAdvDevice, x_ppem);
1274 if (format & OTF_YAdvance)
1275 adjustment[i].yadv
1276 += otfg->f.f1.value->YAdvance * y_scale / 0x10000;
1277 if (format & OTF_YAdvDevice)
1278 adjustment[i].yadv
1279 += DEVICE_DELTA (otfg->f.f1.value->YAdvDevice, y_ppem);
1280 adjustment[i].set = 1;
1281 }
1282 break;
1283 case 3: /* Cursive */
1284 /* Not yet supported. */
1285 break;
1286 case 4: /* Mark-to-Base */
1287 case 5: /* Mark-to-Ligature */
1288 if (! base)
1289 break;
1290 prev = base;
1291 goto label_adjust_anchor;
1292 default: /* i.e. case 6 Mark-to-Mark */
1293 if (! mark)
1294 break;
1295 prev = mark;
1296
1297 label_adjust_anchor:
1298 {
1299 int base_x, base_y, mark_x, mark_y;
1300 int this_from, this_to;
1301
1302 base_x = otfg->f.f4.base_anchor->XCoordinate * x_scale / 0x10000;
1303 base_y = otfg->f.f4.base_anchor->YCoordinate * y_scale / 0x10000;
1304 mark_x = otfg->f.f4.mark_anchor->XCoordinate * x_scale / 0x10000;
1305 mark_y = otfg->f.f4.mark_anchor->YCoordinate * y_scale / 0x10000;;
1306
1307 if (otfg->f.f4.base_anchor->AnchorFormat != 1)
1308 adjust_anchor (ft_face, otfg->f.f4.base_anchor,
1309 prev->code, x_ppem, y_ppem, &base_x, &base_y);
1310 if (otfg->f.f4.mark_anchor->AnchorFormat != 1)
1311 adjust_anchor (ft_face, otfg->f.f4.mark_anchor, g->code,
1312 x_ppem, y_ppem, &mark_x, &mark_y);
1313 adjustment[i].xoff = (base_x - mark_x);
1314 adjustment[i].yoff = - (base_y - mark_y);
1315 adjustment[i].back = (g - prev);
1316 adjustment[i].xadv = 0;
1317 adjustment[i].advance_is_absolute = 1;
1318 adjustment[i].set = 1;
1319 this_from = g->from;
1320 this_to = g->to;
1321 for (j = 0; prev + j < g; j++)
1322 {
1323 if (this_from > prev[j].from)
1324 this_from = prev[j].from;
1325 if (this_to < prev[j].to)
1326 this_to = prev[j].to;
1327 }
1328 for (; prev <= g; prev++)
1329 {
1330 prev->from = this_from;
1331 prev->to = this_to;
1332 }
1333 }
1334 }
1335 if (otfg->GlyphClass == OTF_GlyphClass0)
1336 base = mark = g;
1337 else if (otfg->GlyphClass == OTF_GlyphClassMark)
1338 mark = g;
1339 else
1340 base = g;
1341 }
1342 }
1343 return to;
1344
1345 simple_copy:
1346 if (out->allocated < out->used + len)
1347 return -2;
1348 font->get_metrics (font, in, from, to);
1349 memcpy (out->glyphs + out->used, in->glyphs + from,
1350 sizeof (MFLTGlyph) * len);
1351 out->used += len;
1352 return to;
1353 }
1354
1355 static MFLTGlyphString gstring;
1356
1357 static int m17n_flt_initialized;
1358
1359 extern Lisp_Object QCfamily;
1360
1361 Lisp_Object
1362 ftfont_shape_by_flt (lgstring, font, ft_face, otf)
1363 Lisp_Object lgstring;
1364 struct font *font;
1365 FT_Face ft_face;
1366 OTF *otf;
1367 {
1368 EMACS_UINT len = LGSTRING_LENGTH (lgstring);
1369 EMACS_UINT i;
1370 struct MFLTFontFT flt_font_ft;
1371
1372 if (! m17n_flt_initialized)
1373 {
1374 M17N_INIT ();
1375 m17n_flt_initialized = 1;
1376 }
1377
1378 for (i = 0; i < len; i++)
1379 if (NILP (LGSTRING_GLYPH (lgstring, i)))
1380 break;
1381 len = i;
1382
1383 if (gstring.allocated == 0)
1384 {
1385 gstring.allocated = len * 2;
1386 gstring.glyph_size = sizeof (MFLTGlyph);
1387 gstring.glyphs = malloc (sizeof (MFLTGlyph) * gstring.allocated);
1388 }
1389 else if (gstring.allocated < len * 2)
1390 {
1391 gstring.allocated = len * 2;
1392 gstring.glyphs = realloc (gstring.glyphs,
1393 sizeof (MFLTGlyph) * gstring.allocated);
1394 }
1395 for (i = 0; i < len; i++)
1396 gstring.glyphs[i].c = LGLYPH_CHAR (LGSTRING_GLYPH (lgstring, i));
1397 gstring.used = len;
1398 gstring.r2l = 0;
1399
1400 {
1401 Lisp_Object family = Ffont_get (LGSTRING_FONT (lgstring), QCfamily);
1402
1403 if (NILP (family))
1404 flt_font_ft.flt_font.family = Mnil;
1405 else
1406 flt_font_ft.flt_font.family = msymbol (SDATA (SYMBOL_NAME (family)));
1407 }
1408 flt_font_ft.flt_font.x_ppem = ft_face->size->metrics.x_ppem;
1409 flt_font_ft.flt_font.y_ppem = ft_face->size->metrics.y_ppem;
1410 flt_font_ft.flt_font.get_glyph_id = ftfont_get_glyph_id;
1411 flt_font_ft.flt_font.get_metrics = ftfont_get_metrics;
1412 flt_font_ft.flt_font.check_otf = ftfont_check_otf;
1413 flt_font_ft.flt_font.drive_otf = ftfont_drive_otf;
1414 flt_font_ft.flt_font.internal = NULL;
1415 flt_font_ft.font = font;
1416 flt_font_ft.ft_face = ft_face;
1417 flt_font_ft.otf = otf;
1418 for (i = 0; i < 3; i++)
1419 {
1420 int result = mflt_run (&gstring, 0, len, &flt_font_ft.flt_font, NULL);
1421 if (result != -2)
1422 break;
1423 gstring.allocated += gstring.allocated;
1424 gstring.glyphs = realloc (gstring.glyphs,
1425 sizeof (MFLTGlyph) * gstring.allocated);
1426 }
1427 if (gstring.used > LGSTRING_LENGTH (lgstring))
1428 return Qnil;
1429 for (i = 0; i < gstring.used; i++)
1430 {
1431 MFLTGlyph *g = gstring.glyphs + i;
1432
1433 g->from = LGLYPH_FROM (LGSTRING_GLYPH (lgstring, g->from));
1434 g->to = LGLYPH_TO (LGSTRING_GLYPH (lgstring, g->to));
1435 }
1436
1437 for (i = 0; i < gstring.used; i++)
1438 {
1439 Lisp_Object lglyph = LGSTRING_GLYPH (lgstring, i);
1440 MFLTGlyph *g = gstring.glyphs + i;
1441
1442 LGLYPH_SET_FROM (lglyph, g->from);
1443 LGLYPH_SET_TO (lglyph, g->to);
1444 LGLYPH_SET_CHAR (lglyph, g->c);
1445 LGLYPH_SET_CODE (lglyph, g->code);
1446 LGLYPH_SET_WIDTH (lglyph, g->xadv >> 6);
1447 LGLYPH_SET_LBEARING (lglyph, g->lbearing >> 6);
1448 LGLYPH_SET_RBEARING (lglyph, g->rbearing >> 6);
1449 LGLYPH_SET_ASCENT (lglyph, g->ascent >> 6);
1450 LGLYPH_SET_DESCENT (lglyph, g->descent >> 6);
1451 if (g->adjusted)
1452 {
1453 Lisp_Object vec;
1454
1455 vec = Fmake_vector (make_number (3), Qnil);
1456 ASET (vec, 0, make_number (g->xoff >> 6));
1457 ASET (vec, 1, make_number (g->yoff >> 6));
1458 ASET (vec, 2, make_number (g->xadv >> 6));
1459 LGLYPH_SET_ADJUSTMENT (lglyph, vec);
1460 }
1461 }
1462 return make_number (i);
1463 }
1464
1465 Lisp_Object
1466 ftfont_shape (lgstring)
1467 Lisp_Object lgstring;
1468 {
1469 struct font *font;
1470 struct ftfont_info *ftfont_info;
1471
1472 CHECK_FONT_GET_OBJECT (LGSTRING_FONT (lgstring), font);
1473 ftfont_info = (struct ftfont_info *) font;
1474 if (! ftfont_info->maybe_otf)
1475 return 0;
1476 if (! ftfont_info->otf)
1477 {
1478 OTF *otf = OTF_open_ft_face (ftfont_info->ft_size->face);
1479
1480 if (! otf || OTF_get_table (otf, "head") < 0)
1481 {
1482 if (otf)
1483 OTF_close (otf);
1484 ftfont_info->maybe_otf = 0;
1485 return 0;
1486 }
1487
1488 ftfont_info->otf = otf;
1489 }
1490
1491 return ftfont_shape_by_flt (lgstring, font, ftfont_info->ft_size->face,
1492 ftfont_info->otf);
1493 }
1494
1495 #endif /* HAVE_M17N_FLT */
1496 #endif /* HAVE_LIBOTF */
959 1497
960 Lisp_Object 1498 Lisp_Object
961 ftfont_font_format (FcPattern *pattern) 1499 ftfont_font_format (FcPattern *pattern)
962 { 1500 {
963 FcChar8 *str; 1501 FcChar8 *str;