This source file includes following definitions.
- hbfont_init_w32_funcs
- hbfont_otf_features
- hbfont_otf_capability
- uni_combining
- uni_general
- uni_mirroring
- get_hb_unicode_funcs
- hbfont_shape
- hbfont_combining_capability
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19 #include <config.h>
20 #include <math.h>
21 #include <hb.h>
22 #include <hb-ot.h>
23
24 #include "lisp.h"
25 #include "frame.h"
26 #include "composite.h"
27 #include "font.h"
28 #include "dispextern.h"
29 #include "buffer.h"
30
31 #ifdef HAVE_NTGUI
32
33 #include "w32common.h"
34
35
36
37
38 DEF_DLL_FN (hb_unicode_funcs_t *, hb_unicode_funcs_create,
39 (hb_unicode_funcs_t *));
40 DEF_DLL_FN (hb_unicode_funcs_t *, hb_unicode_funcs_get_default, (void));
41 DEF_DLL_FN (void, hb_unicode_funcs_set_combining_class_func,
42 (hb_unicode_funcs_t *, hb_unicode_combining_class_func_t,
43 void *, hb_destroy_func_t));
44 DEF_DLL_FN (void, hb_unicode_funcs_set_general_category_func,
45 (hb_unicode_funcs_t *, hb_unicode_general_category_func_t,
46 void *, hb_destroy_func_t));
47 DEF_DLL_FN (void, hb_unicode_funcs_set_mirroring_func,
48 (hb_unicode_funcs_t *, hb_unicode_mirroring_func_t,
49 void *, hb_destroy_func_t));
50 DEF_DLL_FN (hb_buffer_t *, hb_buffer_create, (void));
51 DEF_DLL_FN (void, hb_buffer_set_unicode_funcs,
52 (hb_buffer_t *, hb_unicode_funcs_t *));
53 DEF_DLL_FN (void, hb_buffer_clear_contents, (hb_buffer_t *));
54 DEF_DLL_FN (hb_bool_t, hb_buffer_pre_allocate, (hb_buffer_t *, unsigned int));
55 DEF_DLL_FN (void, hb_buffer_add, (hb_buffer_t *, hb_codepoint_t, unsigned int));
56 DEF_DLL_FN (void, hb_buffer_set_content_type,
57 (hb_buffer_t *, hb_buffer_content_type_t));
58 DEF_DLL_FN (void, hb_buffer_set_cluster_level,
59 (hb_buffer_t *, hb_buffer_cluster_level_t));
60 DEF_DLL_FN (void, hb_buffer_set_direction, (hb_buffer_t *, hb_direction_t));
61 DEF_DLL_FN (void, hb_buffer_set_language, (hb_buffer_t *, hb_language_t));
62 DEF_DLL_FN (hb_language_t, hb_language_from_string, (const char *, int));
63 DEF_DLL_FN (void, hb_buffer_guess_segment_properties, (hb_buffer_t *));
64 DEF_DLL_FN (hb_bool_t, hb_shape_full,
65 (hb_font_t *, hb_buffer_t *, const hb_feature_t *,
66 unsigned int, const char * const *));
67 DEF_DLL_FN (unsigned int, hb_buffer_get_length, (hb_buffer_t *));
68 DEF_DLL_FN (hb_direction_t, hb_buffer_get_direction, (hb_buffer_t *));
69 DEF_DLL_FN (void, hb_buffer_reverse_clusters, (hb_buffer_t *));
70 DEF_DLL_FN (hb_glyph_info_t *, hb_buffer_get_glyph_infos,
71 (hb_buffer_t *, unsigned int *));
72 DEF_DLL_FN (hb_glyph_position_t *, hb_buffer_get_glyph_positions,
73 (hb_buffer_t *, unsigned int *));
74 DEF_DLL_FN (void, hb_tag_to_string, (hb_tag_t, char *));
75 DEF_DLL_FN (hb_face_t *, hb_font_get_face, (hb_font_t *font));
76 DEF_DLL_FN (unsigned int, hb_ot_layout_table_get_script_tags,
77 (hb_face_t *, hb_tag_t, unsigned int, unsigned int *, hb_tag_t *));
78 DEF_DLL_FN (unsigned int, hb_ot_layout_table_get_feature_tags,
79 (hb_face_t *, hb_tag_t, unsigned int, unsigned int *, hb_tag_t *));
80 DEF_DLL_FN (unsigned int, hb_ot_layout_script_get_language_tags,
81 (hb_face_t *, hb_tag_t, unsigned int, unsigned int, unsigned int *,
82 hb_tag_t *));
83 DEF_DLL_FN (unsigned int, hb_ot_layout_language_get_feature_tags,
84 (hb_face_t *, hb_tag_t, unsigned int, unsigned int, unsigned int,
85 unsigned int *, hb_tag_t *));
86
87 #define hb_unicode_funcs_create fn_hb_unicode_funcs_create
88 #define hb_unicode_funcs_get_default fn_hb_unicode_funcs_get_default
89 #define hb_unicode_funcs_set_combining_class_func fn_hb_unicode_funcs_set_combining_class_func
90 #define hb_unicode_funcs_set_general_category_func fn_hb_unicode_funcs_set_general_category_func
91 #define hb_unicode_funcs_set_mirroring_func fn_hb_unicode_funcs_set_mirroring_func
92 #define hb_buffer_create fn_hb_buffer_create
93 #define hb_buffer_set_unicode_funcs fn_hb_buffer_set_unicode_funcs
94 #define hb_buffer_clear_contents fn_hb_buffer_clear_contents
95 #define hb_buffer_pre_allocate fn_hb_buffer_pre_allocate
96 #define hb_buffer_add fn_hb_buffer_add
97 #define hb_buffer_set_content_type fn_hb_buffer_set_content_type
98 #define hb_buffer_set_cluster_level fn_hb_buffer_set_cluster_level
99 #define hb_buffer_set_direction fn_hb_buffer_set_direction
100 #define hb_buffer_set_language fn_hb_buffer_set_language
101 #define hb_language_from_string fn_hb_language_from_string
102 #define hb_buffer_guess_segment_properties fn_hb_buffer_guess_segment_properties
103 #define hb_shape_full fn_hb_shape_full
104 #define hb_buffer_get_length fn_hb_buffer_get_length
105 #define hb_buffer_get_direction fn_hb_buffer_get_direction
106 #define hb_buffer_reverse_clusters fn_hb_buffer_reverse_clusters
107 #define hb_buffer_get_glyph_infos fn_hb_buffer_get_glyph_infos
108 #define hb_buffer_get_glyph_positions fn_hb_buffer_get_glyph_positions
109 #define hb_tag_to_string fn_hb_tag_to_string
110 #define hb_font_get_face fn_hb_font_get_face
111 #define hb_ot_layout_table_get_script_tags fn_hb_ot_layout_table_get_script_tags
112 #define hb_ot_layout_table_get_feature_tags fn_hb_ot_layout_table_get_feature_tags
113 #define hb_ot_layout_script_get_language_tags fn_hb_ot_layout_script_get_language_tags
114 #define hb_ot_layout_language_get_feature_tags fn_hb_ot_layout_language_get_feature_tags
115
116
117
118 bool
119 hbfont_init_w32_funcs (HMODULE library)
120 {
121 LOAD_DLL_FN (library, hb_unicode_funcs_create);
122 LOAD_DLL_FN (library, hb_unicode_funcs_get_default);
123 LOAD_DLL_FN (library, hb_unicode_funcs_set_combining_class_func);
124 LOAD_DLL_FN (library, hb_unicode_funcs_set_general_category_func);
125 LOAD_DLL_FN (library, hb_unicode_funcs_set_mirroring_func);
126 LOAD_DLL_FN (library, hb_buffer_create);
127 LOAD_DLL_FN (library, hb_buffer_set_unicode_funcs);
128 LOAD_DLL_FN (library, hb_buffer_clear_contents);
129 LOAD_DLL_FN (library, hb_buffer_pre_allocate);
130 LOAD_DLL_FN (library, hb_buffer_add);
131 LOAD_DLL_FN (library, hb_buffer_set_content_type);
132 LOAD_DLL_FN (library, hb_buffer_set_cluster_level);
133 LOAD_DLL_FN (library, hb_buffer_set_direction);
134 LOAD_DLL_FN (library, hb_buffer_set_language);
135 LOAD_DLL_FN (library, hb_language_from_string);
136 LOAD_DLL_FN (library, hb_buffer_guess_segment_properties);
137 LOAD_DLL_FN (library, hb_shape_full);
138 LOAD_DLL_FN (library, hb_buffer_get_length);
139 LOAD_DLL_FN (library, hb_buffer_get_direction);
140 LOAD_DLL_FN (library, hb_buffer_reverse_clusters);
141 LOAD_DLL_FN (library, hb_buffer_get_glyph_infos);
142 LOAD_DLL_FN (library, hb_buffer_get_glyph_positions);
143 LOAD_DLL_FN (library, hb_tag_to_string);
144 LOAD_DLL_FN (library, hb_font_get_face);
145 LOAD_DLL_FN (library, hb_ot_layout_table_get_script_tags);
146 LOAD_DLL_FN (library, hb_ot_layout_table_get_feature_tags);
147 LOAD_DLL_FN (library, hb_ot_layout_script_get_language_tags);
148 LOAD_DLL_FN (library, hb_ot_layout_language_get_feature_tags);
149 return true;
150 }
151 #endif
152
153 static Lisp_Object
154 hbfont_otf_features (hb_face_t *face, hb_tag_t table_tag)
155 {
156 hb_tag_t *language_tags = NULL, *feature_tags = NULL;
157 char buf[4];
158 unsigned int script_count
159 = hb_ot_layout_table_get_script_tags (face, table_tag, 0, NULL, NULL);
160 hb_tag_t *script_tags = xnmalloc (script_count, sizeof *script_tags);
161 hb_ot_layout_table_get_script_tags (face, table_tag, 0, &script_count,
162 script_tags);
163 Lisp_Object scripts = Qnil;
164 for (int i = script_count - 1; i >= 0; i--)
165 {
166 unsigned int language_count
167 = hb_ot_layout_script_get_language_tags (face, table_tag, i, 0,
168 NULL, NULL);
169 language_tags = xnrealloc (language_tags, language_count,
170 sizeof *language_tags);
171 hb_ot_layout_script_get_language_tags (face, table_tag, i, 0,
172 &language_count, language_tags);
173 Lisp_Object langsyses = Qnil;
174 for (int j = language_count - 1; j >= -1; j--)
175 {
176 unsigned int language_index
177 = j >= 0 ? j : HB_OT_LAYOUT_DEFAULT_LANGUAGE_INDEX;
178 unsigned int feature_count
179 = hb_ot_layout_language_get_feature_tags (face, table_tag,
180 i, language_index, 0,
181 NULL, NULL);
182 if (feature_count == 0)
183 continue;
184 feature_tags = xnrealloc (feature_tags, feature_count,
185 sizeof *feature_tags);
186 hb_ot_layout_language_get_feature_tags (face, table_tag,
187 i, language_index, 0,
188 &feature_count, feature_tags);
189 Lisp_Object features = Qnil;
190 for (int k = feature_count - 1; k >= 0; k--)
191 {
192 hb_tag_to_string (feature_tags[k], buf);
193 features = Fcons (font_intern_prop (buf, 4, 1), features);
194 }
195
196 Lisp_Object sym = Qnil;
197 if (j >= 0)
198 {
199 hb_tag_to_string (language_tags[j], buf);
200 sym = font_intern_prop (buf, 4, 1);
201 }
202 langsyses = Fcons (Fcons (sym, features), langsyses);
203 }
204
205 hb_tag_to_string (script_tags[i], buf);
206 scripts = Fcons (Fcons (font_intern_prop (buf, 4, 1), langsyses),
207 scripts);
208 }
209 xfree (feature_tags);
210 xfree (language_tags);
211 xfree (script_tags);
212
213 return scripts;
214 }
215
216 Lisp_Object
217 hbfont_otf_capability (struct font *font)
218 {
219 double position_unit;
220 hb_font_t *hb_font
221 = font->driver->begin_hb_font
222 ? font->driver->begin_hb_font (font, &position_unit)
223 : NULL;
224 if (!hb_font)
225 return Qnil;
226
227 Lisp_Object gsub_gpos = Fcons (Qnil, Qnil);
228 hb_face_t *face = hb_font_get_face (hb_font);
229 if (hb_ot_layout_table_get_feature_tags (face, HB_OT_TAG_GSUB, 0, NULL, NULL))
230 XSETCAR (gsub_gpos, hbfont_otf_features (face, HB_OT_TAG_GSUB));
231 if (hb_ot_layout_table_get_feature_tags (face, HB_OT_TAG_GPOS, 0, NULL, NULL))
232 XSETCDR (gsub_gpos, hbfont_otf_features (face, HB_OT_TAG_GPOS));
233
234 if (font->driver->end_hb_font)
235 font->driver->end_hb_font (font, hb_font);
236
237 return gsub_gpos;
238 }
239
240
241
242 static bool combining_class_loaded = false;
243 static Lisp_Object canonical_combining_class_table;
244
245 static hb_unicode_combining_class_t
246 uni_combining (hb_unicode_funcs_t *funcs, hb_codepoint_t ch, void *user_data)
247 {
248
249 if (!combining_class_loaded)
250 {
251 canonical_combining_class_table =
252 uniprop_table (Qcanonical_combining_class);
253 if (NILP (canonical_combining_class_table))
254 emacs_abort ();
255 staticpro (&canonical_combining_class_table);
256 combining_class_loaded = true;
257 }
258
259 Lisp_Object combining =
260 get_unicode_property (canonical_combining_class_table, ch);
261 if (FIXNUMP (combining))
262 return (hb_unicode_combining_class_t) XFIXNUM (combining);
263
264 return HB_UNICODE_COMBINING_CLASS_NOT_REORDERED;
265 }
266
267 static hb_unicode_general_category_t
268 uni_general (hb_unicode_funcs_t *funcs, hb_codepoint_t ch, void *user_data)
269 {
270 Lisp_Object category = CHAR_TABLE_REF (Vunicode_category_table, ch);
271
272 if (INTEGERP (category))
273 {
274 switch (XFIXNUM (category))
275 {
276 case UNICODE_CATEGORY_Cc:
277 return HB_UNICODE_GENERAL_CATEGORY_CONTROL;
278 case UNICODE_CATEGORY_Cf:
279 return HB_UNICODE_GENERAL_CATEGORY_FORMAT;
280 case UNICODE_CATEGORY_Cn:
281 return HB_UNICODE_GENERAL_CATEGORY_UNASSIGNED;
282 case UNICODE_CATEGORY_Co:
283 return HB_UNICODE_GENERAL_CATEGORY_PRIVATE_USE;
284 case UNICODE_CATEGORY_Cs:
285 return HB_UNICODE_GENERAL_CATEGORY_SURROGATE;
286 case UNICODE_CATEGORY_Ll:
287 return HB_UNICODE_GENERAL_CATEGORY_LOWERCASE_LETTER;
288 case UNICODE_CATEGORY_Lm:
289 return HB_UNICODE_GENERAL_CATEGORY_MODIFIER_LETTER;
290 case UNICODE_CATEGORY_Lo:
291 return HB_UNICODE_GENERAL_CATEGORY_OTHER_LETTER;
292 case UNICODE_CATEGORY_Lt:
293 return HB_UNICODE_GENERAL_CATEGORY_TITLECASE_LETTER;
294 case UNICODE_CATEGORY_Lu:
295 return HB_UNICODE_GENERAL_CATEGORY_UPPERCASE_LETTER;
296 case UNICODE_CATEGORY_Mc:
297 return HB_UNICODE_GENERAL_CATEGORY_SPACING_MARK;
298 case UNICODE_CATEGORY_Me:
299 return HB_UNICODE_GENERAL_CATEGORY_ENCLOSING_MARK;
300 case UNICODE_CATEGORY_Mn:
301 return HB_UNICODE_GENERAL_CATEGORY_NON_SPACING_MARK;
302 case UNICODE_CATEGORY_Nd:
303 return HB_UNICODE_GENERAL_CATEGORY_DECIMAL_NUMBER;
304 case UNICODE_CATEGORY_Nl:
305 return HB_UNICODE_GENERAL_CATEGORY_LETTER_NUMBER;
306 case UNICODE_CATEGORY_No:
307 return HB_UNICODE_GENERAL_CATEGORY_OTHER_NUMBER;
308 case UNICODE_CATEGORY_Pc:
309 return HB_UNICODE_GENERAL_CATEGORY_CONNECT_PUNCTUATION;
310 case UNICODE_CATEGORY_Pd:
311 return HB_UNICODE_GENERAL_CATEGORY_DASH_PUNCTUATION;
312 case UNICODE_CATEGORY_Pe:
313 return HB_UNICODE_GENERAL_CATEGORY_CLOSE_PUNCTUATION;
314 case UNICODE_CATEGORY_Pf:
315 return HB_UNICODE_GENERAL_CATEGORY_FINAL_PUNCTUATION;
316 case UNICODE_CATEGORY_Pi:
317 return HB_UNICODE_GENERAL_CATEGORY_INITIAL_PUNCTUATION;
318 case UNICODE_CATEGORY_Po:
319 return HB_UNICODE_GENERAL_CATEGORY_OTHER_PUNCTUATION;
320 case UNICODE_CATEGORY_Ps:
321 return HB_UNICODE_GENERAL_CATEGORY_OPEN_PUNCTUATION;
322 case UNICODE_CATEGORY_Sc:
323 return HB_UNICODE_GENERAL_CATEGORY_CURRENCY_SYMBOL;
324 case UNICODE_CATEGORY_Sk:
325 return HB_UNICODE_GENERAL_CATEGORY_MODIFIER_SYMBOL;
326 case UNICODE_CATEGORY_Sm:
327 return HB_UNICODE_GENERAL_CATEGORY_MATH_SYMBOL;
328 case UNICODE_CATEGORY_So:
329 return HB_UNICODE_GENERAL_CATEGORY_OTHER_SYMBOL;
330 case UNICODE_CATEGORY_Zl:
331 return HB_UNICODE_GENERAL_CATEGORY_LINE_SEPARATOR;
332 case UNICODE_CATEGORY_Zp:
333 return HB_UNICODE_GENERAL_CATEGORY_PARAGRAPH_SEPARATOR;
334 case UNICODE_CATEGORY_Zs:
335 return HB_UNICODE_GENERAL_CATEGORY_SPACE_SEPARATOR;
336 case UNICODE_CATEGORY_UNKNOWN:
337 return HB_UNICODE_GENERAL_CATEGORY_UNASSIGNED;
338 }
339 }
340
341 return HB_UNICODE_GENERAL_CATEGORY_UNASSIGNED;
342 }
343
344 static hb_codepoint_t
345 uni_mirroring (hb_unicode_funcs_t *funcs, hb_codepoint_t ch, void *user_data)
346 {
347 return bidi_mirror_char (ch);
348 }
349
350 static hb_unicode_funcs_t *
351 get_hb_unicode_funcs (void)
352 {
353
354
355
356 hb_unicode_funcs_t *funcs = hb_unicode_funcs_create (hb_unicode_funcs_get_default ());
357
358 hb_unicode_funcs_set_combining_class_func (funcs, uni_combining, NULL, NULL);
359 hb_unicode_funcs_set_general_category_func (funcs, uni_general, NULL, NULL);
360 hb_unicode_funcs_set_mirroring_func (funcs, uni_mirroring, NULL, NULL);
361
362
363
364
365
366
367
368
369
370
371
372
373 return funcs;
374 }
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394 Lisp_Object
395 hbfont_shape (Lisp_Object lgstring, Lisp_Object direction)
396 {
397 struct font *font = CHECK_FONT_GET_OBJECT (LGSTRING_FONT (lgstring));
398 ptrdiff_t glyph_len = 0, text_len = LGSTRING_GLYPH_LEN (lgstring);
399 ptrdiff_t i;
400
401 hb_glyph_info_t *info;
402 hb_glyph_position_t *pos;
403
404
405
406 static hb_buffer_t *hb_buffer = NULL;
407 if (! hb_buffer)
408 {
409 hb_buffer = hb_buffer_create ();
410 hb_unicode_funcs_t* ufuncs = get_hb_unicode_funcs();
411 hb_buffer_set_unicode_funcs(hb_buffer, ufuncs);
412 }
413
414 hb_buffer_clear_contents (hb_buffer);
415 hb_buffer_pre_allocate (hb_buffer, text_len);
416
417
418
419 int *chars = alloca (text_len * sizeof (int));
420 for (i = 0; i < text_len; i++)
421 {
422 Lisp_Object g = LGSTRING_GLYPH (lgstring, i);
423 int c;
424
425 if (NILP (g))
426 break;
427 c = LGLYPH_CHAR (g);
428 hb_buffer_add (hb_buffer, c, i);
429 chars[i] = c;
430 }
431
432 text_len = i;
433 if (!text_len)
434 return Qnil;
435
436 hb_buffer_set_content_type (hb_buffer, HB_BUFFER_CONTENT_TYPE_UNICODE);
437 hb_buffer_set_cluster_level (hb_buffer,
438 HB_BUFFER_CLUSTER_LEVEL_MONOTONE_GRAPHEMES);
439
440
441
442 if (!NILP (direction)
443
444
445
446 && !NILP (BVAR (current_buffer, bidi_display_reordering)))
447 {
448 hb_direction_t dir = HB_DIRECTION_LTR;
449 if (EQ (direction, QL2R))
450 dir = HB_DIRECTION_LTR;
451 else if (EQ (direction, QR2L))
452 dir = HB_DIRECTION_RTL;
453 hb_buffer_set_direction (hb_buffer, dir);
454 }
455
456
457
458 #if 0
459 hb_buffer_set_script (hb_buffer, XXX);
460 #endif
461
462
463
464
465
466
467 Lisp_Object lang = Vcurrent_iso639_language;
468 if (CONSP (Vcurrent_iso639_language))
469 lang = XCAR (Vcurrent_iso639_language);
470 if (SYMBOLP (lang))
471 {
472 Lisp_Object lang_str = SYMBOL_NAME (lang);
473 hb_buffer_set_language (hb_buffer,
474 hb_language_from_string (SSDATA (lang_str),
475 SBYTES (lang_str)));
476 }
477
478
479
480
481
482
483
484 hb_buffer_guess_segment_properties (hb_buffer);
485
486 double position_unit;
487 hb_font_t *hb_font
488 = font->driver->begin_hb_font
489 ? font->driver->begin_hb_font (font, &position_unit)
490 : NULL;
491 if (!hb_font)
492 return make_fixnum (0);
493
494 hb_bool_t success = hb_shape_full (hb_font, hb_buffer, NULL, 0, NULL);
495 if (font->driver->end_hb_font)
496 font->driver->end_hb_font (font, hb_font);
497 if (!success)
498 return Qnil;
499
500 glyph_len = hb_buffer_get_length (hb_buffer);
501 if (glyph_len > LGSTRING_GLYPH_LEN (lgstring))
502 return Qnil;
503
504
505 bool buf_reversed = false;
506 if (HB_DIRECTION_IS_BACKWARD (hb_buffer_get_direction (hb_buffer)))
507 {
508 buf_reversed = true;
509 hb_buffer_reverse_clusters (hb_buffer);
510 }
511 info = hb_buffer_get_glyph_infos (hb_buffer, NULL);
512 pos = hb_buffer_get_glyph_positions (hb_buffer, NULL);
513 ptrdiff_t from = -1, to UNINIT, cluster_offset UNINIT;
514 int incr = buf_reversed ? -1 : 1;
515 for (i = 0; i < glyph_len; i++)
516 {
517 Lisp_Object lglyph = LGSTRING_GLYPH (lgstring, i);
518 struct font_metrics metrics = {.width = 0};
519 int xoff, yoff, wadjust;
520 bool new_lglyph = false;
521
522 if (NILP (lglyph))
523 {
524 new_lglyph = true;
525 lglyph = LGLYPH_NEW ();
526 LGSTRING_SET_GLYPH (lgstring, i, lglyph);
527 }
528
529 if (info[i].cluster != from)
530 {
531 int j;
532
533
534
535
536 from = info[i].cluster;
537
538
539 for (j = i; j < glyph_len && info[j].cluster == from; j++)
540 ;
541 to = (j == glyph_len) ? text_len - 1 : info[j].cluster - 1;
542 cluster_offset = 0;
543
544
545
546
547
548
549
550
551 if (buf_reversed)
552 cluster_offset = to - from;
553 }
554
555
556 LGLYPH_SET_FROM (lglyph, from);
557
558
559
560
561
562
563
564
565
566 if (!(!new_lglyph
567 && to == text_len - 1
568 && LGLYPH_TO (lglyph) > to))
569 LGLYPH_SET_TO (lglyph, to);
570
571
572
573
574
575
576 ptrdiff_t char_idx = from + cluster_offset;
577 cluster_offset += incr;
578 if (char_idx > to)
579 char_idx = to;
580 if (char_idx < from)
581 char_idx = from;
582 LGLYPH_SET_CHAR (lglyph, chars[char_idx]);
583 LGLYPH_SET_CODE (lglyph, info[i].codepoint);
584
585 unsigned code = info[i].codepoint;
586 font->driver->text_extents (font, &code, 1, &metrics);
587 LGLYPH_SET_WIDTH (lglyph, metrics.width);
588 LGLYPH_SET_LBEARING (lglyph, metrics.lbearing);
589 LGLYPH_SET_RBEARING (lglyph, metrics.rbearing);
590 LGLYPH_SET_ASCENT (lglyph, metrics.ascent);
591 LGLYPH_SET_DESCENT (lglyph, metrics.descent);
592
593 xoff = lround (pos[i].x_offset * position_unit);
594 yoff = - lround (pos[i].y_offset * position_unit);
595 wadjust = lround (pos[i].x_advance * position_unit);
596 if (xoff || yoff || wadjust != metrics.width)
597 LGLYPH_SET_ADJUSTMENT (lglyph, CALLN (Fvector,
598 make_fixnum (xoff),
599 make_fixnum (yoff),
600 make_fixnum (wadjust)));
601 }
602
603 return make_fixnum (glyph_len);
604 }
605
606 Lisp_Object
607 hbfont_combining_capability (struct font *font)
608 {
609 return Qt;
610 }