Mercurial > emacs
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; |