w32tex
About: TeX Live provides a comprehensive TeX system including all the major TeX-related programs, macro packages, and fonts that are free software. Windows sources.
  Fossies Dox: w32tex-src.tar.xz  ("unofficial" and yet experimental doxygen-generated source code documentation)  

hb-buffer.cc
Go to the documentation of this file.
1 /*
2  * Copyright © 1998-2004 David Turner and Werner Lemberg
3  * Copyright © 2004,2007,2009,2010 Red Hat, Inc.
4  * Copyright © 2011,2012 Google, Inc.
5  *
6  * This is part of HarfBuzz, a text shaping library.
7  *
8  * Permission is hereby granted, without written agreement and without
9  * license or royalty fees, to use, copy, modify, and distribute this
10  * software and its documentation for any purpose, provided that the
11  * above copyright notice and the following two paragraphs appear in
12  * all copies of this software.
13  *
14  * IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE TO ANY PARTY FOR
15  * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES
16  * ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN
17  * IF THE COPYRIGHT HOLDER HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
18  * DAMAGE.
19  *
20  * THE COPYRIGHT HOLDER SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING,
21  * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
22  * FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS
23  * ON AN "AS IS" BASIS, AND THE COPYRIGHT HOLDER HAS NO OBLIGATION TO
24  * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
25  *
26  * Red Hat Author(s): Owen Taylor, Behdad Esfahbod
27  * Google Author(s): Behdad Esfahbod
28  */
29 
30 #include "hb-buffer.hh"
31 #include "hb-utf.hh"
32 
33 
34 /**
35  * SECTION: hb-buffer
36  * @title: hb-buffer
37  * @short_description: Input and output buffers
38  * @include: hb.h
39  *
40  * Buffers serve a dual role in HarfBuzz; before shaping, they hold
41  * the input characters that are passed to hb_shape(), and after
42  * shaping they hold the output glyphs.
43  **/
44 
45 
46 /**
47  * hb_segment_properties_equal:
48  * @a: first #hb_segment_properties_t to compare.
49  * @b: second #hb_segment_properties_t to compare.
50  *
51  * Checks the equality of two #hb_segment_properties_t's.
52  *
53  * Return value:
54  * %true if all properties of @a equal those of @b, %false otherwise.
55  *
56  * Since: 0.9.7
57  **/
61 {
62  return a->direction == b->direction &&
63  a->script == b->script &&
64  a->language == b->language &&
65  a->reserved1 == b->reserved1 &&
66  a->reserved2 == b->reserved2;
67 
68 }
69 
70 /**
71  * hb_segment_properties_hash:
72  * @p: #hb_segment_properties_t to hash.
73  *
74  * Creates a hash representing @p.
75  *
76  * Return value:
77  * A hash of @p.
78  *
79  * Since: 0.9.7
80  **/
81 unsigned int
83 {
84  return (unsigned int) p->direction ^
85  (unsigned int) p->script ^
86  (intptr_t) (p->language);
87 }
88 
89 
90 
91 /* Here is how the buffer works internally:
92  *
93  * There are two info pointers: info and out_info. They always have
94  * the same allocated size, but different lengths.
95  *
96  * As an optimization, both info and out_info may point to the
97  * same piece of memory, which is owned by info. This remains the
98  * case as long as out_len doesn't exceed i at any time.
99  * In that case, swap_buffers() is no-op and the glyph operations operate
100  * mostly in-place.
101  *
102  * As soon as out_info gets longer than info, out_info is moved over
103  * to an alternate buffer (which we reuse the pos buffer for!), and its
104  * current contents (out_len entries) are copied to the new place.
105  * This should all remain transparent to the user. swap_buffers() then
106  * switches info and out_info.
107  */
108 
109 
110 
111 /* Internal API */
112 
113 bool
115 {
116  if (unlikely (!successful))
117  return false;
118  if (unlikely (size > max_len))
119  {
120  successful = false;
121  return false;
122  }
123 
124  unsigned int new_allocated = allocated;
125  hb_glyph_position_t *new_pos = nullptr;
126  hb_glyph_info_t *new_info = nullptr;
127  bool separate_out = out_info != info;
128 
129  if (unlikely (hb_unsigned_mul_overflows (size, sizeof (info[0]))))
130  goto done;
131 
132  while (size >= new_allocated)
133  new_allocated += (new_allocated >> 1) + 32;
134 
135  static_assert ((sizeof (info[0]) == sizeof (pos[0])), "");
136  if (unlikely (hb_unsigned_mul_overflows (new_allocated, sizeof (info[0]))))
137  goto done;
138 
139  new_pos = (hb_glyph_position_t *) realloc (pos, new_allocated * sizeof (pos[0]));
140  new_info = (hb_glyph_info_t *) realloc (info, new_allocated * sizeof (info[0]));
141 
142 done:
143  if (unlikely (!new_pos || !new_info))
144  successful = false;
145 
146  if (likely (new_pos))
147  pos = new_pos;
148 
149  if (likely (new_info))
150  info = new_info;
151 
152  out_info = separate_out ? (hb_glyph_info_t *) pos : info;
153  if (likely (successful))
154  allocated = new_allocated;
155 
156  return likely (successful);
157 }
158 
159 bool
160 hb_buffer_t::make_room_for (unsigned int num_in,
161  unsigned int num_out)
162 {
163  if (unlikely (!ensure (out_len + num_out))) return false;
164 
165  if (out_info == info &&
166  out_len + num_out > idx + num_in)
167  {
169 
171  memcpy (out_info, info, out_len * sizeof (out_info[0]));
172  }
173 
174  return true;
175 }
176 
177 bool
179 {
181  if (unlikely (!ensure (len + count))) return false;
182 
183  memmove (info + idx + count, info + idx, (len - idx) * sizeof (info[0]));
184  if (idx + count > len)
185  {
186  /* Under memory failure we might expose this area. At least
187  * clean it up. Oh well...
188  *
189  * Ideally, we should at least set Default_Ignorable bits on
190  * these, as well as consistent cluster values. But the former
191  * is layering violation... */
192  memset (info + len, 0, (idx + count - len) * sizeof (info[0]));
193  }
194  len += count;
195  idx += count;
196 
197  return true;
198 }
199 
202 {
203  have_output = false;
204  have_positions = false;
205 
206  out_len = 0;
207  out_info = info;
208 
209  assert ((uintptr_t) pos % sizeof (scratch_buffer_t) == 0);
210  *size = allocated * sizeof (pos[0]) / sizeof (scratch_buffer_t);
211  return (scratch_buffer_t *) (void *) pos;
212 }
213 
214 
215 
216 /* HarfBuzz-Internal API */
217 
218 void
220 {
221  if (unlikely (hb_object_is_immutable (this)))
222  return;
223 
228  invisible = 0;
229 
230  clear ();
231 }
232 
233 void
235 {
236  if (unlikely (hb_object_is_immutable (this)))
237  return;
238 
240  props = default_props;
242 
244  successful = true;
245  have_output = false;
246  have_positions = false;
247 
248  idx = 0;
249  len = 0;
250  out_len = 0;
251  out_info = info;
252 
253  serial = 0;
254 
255  memset (context, 0, sizeof context);
256  memset (context_len, 0, sizeof context_len);
257 
259 }
260 
261 void
263  unsigned int cluster)
264 {
266 
267  if (unlikely (!ensure (len + 1))) return;
268 
269  glyph = &info[len];
270 
271  memset (glyph, 0, sizeof (*glyph));
272  glyph->codepoint = codepoint;
273  glyph->mask = 0;
274  glyph->cluster = cluster;
275 
276  len++;
277 }
278 
279 void
281 {
282  if (unlikely (!ensure (len + 1))) return;
283 
284  info[len] = glyph_info;
285 
286  len++;
287 }
288 
289 
290 void
292 {
293  if (unlikely (hb_object_is_immutable (this)))
294  return;
295 
296  have_output = false;
297  have_positions = false;
298 
299  out_len = 0;
300  out_info = info;
301 }
302 
303 void
305 {
306  if (unlikely (hb_object_is_immutable (this)))
307  return;
308 
309  have_output = true;
310  have_positions = false;
311 
312  out_len = 0;
313  out_info = info;
314 }
315 
316 void
318 {
319  if (unlikely (hb_object_is_immutable (this)))
320  return;
321 
322  have_output = false;
323  have_positions = true;
324 
325  out_len = 0;
326  out_info = info;
327 
328  hb_memset (pos, 0, sizeof (pos[0]) * len);
329 }
330 
331 void
333 {
334  if (unlikely (!successful)) return;
335 
337  have_output = false;
338 
339  if (out_info != info)
340  {
341  hb_glyph_info_t *tmp_string;
342  tmp_string = info;
343  info = out_info;
344  out_info = tmp_string;
346  }
347 
348  unsigned int tmp;
349  tmp = len;
350  len = out_len;
351  out_len = tmp;
352 
353  idx = 0;
354 }
355 
356 
357 void
358 hb_buffer_t::replace_glyphs (unsigned int num_in,
359  unsigned int num_out,
360  const uint32_t *glyph_data)
361 {
362  if (unlikely (!make_room_for (num_in, num_out))) return;
363 
364  assert (idx + num_in <= len);
365 
366  merge_clusters (idx, idx + num_in);
367 
368  hb_glyph_info_t orig_info = info[idx];
370  for (unsigned int i = 0; i < num_out; i++)
371  {
372  *pinfo = orig_info;
373  pinfo->codepoint = glyph_data[i];
374  pinfo++;
375  }
376 
377  idx += num_in;
378  out_len += num_out;
379 }
380 
381 bool
382 hb_buffer_t::move_to (unsigned int i)
383 {
384  if (!have_output)
385  {
386  assert (i <= len);
387  idx = i;
388  return true;
389  }
390  if (unlikely (!successful))
391  return false;
392 
393  assert (i <= out_len + (len - idx));
394 
395  if (out_len < i)
396  {
397  unsigned int count = i - out_len;
398  if (unlikely (!make_room_for (count, count))) return false;
399 
400  memmove (out_info + out_len, info + idx, count * sizeof (out_info[0]));
401  idx += count;
402  out_len += count;
403  }
404  else if (out_len > i)
405  {
406  /* Tricky part: rewinding... */
407  unsigned int count = out_len - i;
408 
409  /* This will blow in our face if memory allocation fails later
410  * in this same lookup...
411  *
412  * We used to shift with extra 32 items, instead of the 0 below.
413  * But that would leave empty slots in the buffer in case of allocation
414  * failures. Setting to zero for now to avoid other problems (see
415  * comments in shift_forward(). This can cause O(N^2) behavior more
416  * severely than adding 32 empty slots can... */
417  if (unlikely (idx < count && !shift_forward (count + 0))) return false;
418 
419  assert (idx >= count);
420 
421  idx -= count;
422  out_len -= count;
423  memmove (info + idx, out_info + out_len, count * sizeof (out_info[0]));
424  }
425 
426  return true;
427 }
428 
429 
430 void
432  hb_mask_t mask,
433  unsigned int cluster_start,
434  unsigned int cluster_end)
435 {
436  hb_mask_t not_mask = ~~mask;
437  value &= mask;
438 
439  if (!mask)
440  return;
441 
442  unsigned int count = len;
443  for (unsigned int i = 0; i < count; i++)
444  if (cluster_start <= info[i].cluster && info[i].cluster < cluster_end)
445  info[i].mask = (info[i].mask & not_mask) | value;
446 }
447 
448 void
450  unsigned int end)
451 {
452  if (end - start < 2)
453  return;
454 
456 
457  if (have_positions) {
459  }
460 }
461 
462 void
464 {
465  if (unlikely (!len))
466  return;
467 
468  reverse_range (0, len);
469 }
470 
471 void
473 {
474  unsigned int i, start, count, last_cluster;
475 
476  if (unlikely (!len))
477  return;
478 
479  reverse ();
480 
481  count = len;
482  start = 0;
483  last_cluster = info[0].cluster;
484  for (i = 1; i < count; i++) {
485  if (last_cluster != info[i].cluster) {
486  reverse_range (start, i);
487  start = i;
488  last_cluster = info[i].cluster;
489  }
490  }
491  reverse_range (start, i);
492 }
493 
494 void
496  unsigned int end)
497 {
499  {
501  return;
502  }
503 
504  unsigned int cluster = info[start].cluster;
505 
506  for (unsigned int i = start + 1; i < end; i++)
508 
509  /* Extend end */
510  while (end < len && info[end - 1].cluster == info[end].cluster)
511  end++;
512 
513  /* Extend start */
514  while (idx < start && info[start - 1].cluster == info[start].cluster)
515  start--;
516 
517  /* If we hit the start of buffer, continue in out-buffer. */
518  if (idx == start)
519  for (unsigned int i = out_len; i && out_info[i - 1].cluster == info[start].cluster; i--)
520  set_cluster (out_info[i - 1], cluster);
521 
522  for (unsigned int i = start; i < end; i++)
524 }
525 void
527  unsigned int end)
528 {
530  return;
531 
532  if (unlikely (end - start < 2))
533  return;
534 
535  unsigned int cluster = out_info[start].cluster;
536 
537  for (unsigned int i = start + 1; i < end; i++)
539 
540  /* Extend start */
541  while (start && out_info[start - 1].cluster == out_info[start].cluster)
542  start--;
543 
544  /* Extend end */
545  while (end < out_len && out_info[end - 1].cluster == out_info[end].cluster)
546  end++;
547 
548  /* If we hit the end of out-buffer, continue in buffer. */
549  if (end == out_len)
550  for (unsigned int i = idx; i < len && info[i].cluster == out_info[end - 1].cluster; i++)
552 
553  for (unsigned int i = start; i < end; i++)
555 }
556 void
558 {
559  /* The logic here is duplicated in hb_ot_hide_default_ignorables(). */
560 
561  unsigned int cluster = info[idx].cluster;
562  if (idx + 1 < len && cluster == info[idx + 1].cluster)
563  {
564  /* Cluster survives; do nothing. */
565  goto done;
566  }
567 
568  if (out_len)
569  {
570  /* Merge cluster backward. */
571  if (cluster < out_info[out_len - 1].cluster)
572  {
573  unsigned int mask = info[idx].mask;
574  unsigned int old_cluster = out_info[out_len - 1].cluster;
575  for (unsigned i = out_len; i && out_info[i - 1].cluster == old_cluster; i--)
576  set_cluster (out_info[i - 1], cluster, mask);
577  }
578  goto done;
579  }
580 
581  if (idx + 1 < len)
582  {
583  /* Merge cluster forward. */
584  merge_clusters (idx, idx + 2);
585  goto done;
586  }
587 
588 done:
589  skip_glyph ();
590 }
591 
592 void
593 hb_buffer_t::unsafe_to_break_impl (unsigned int start, unsigned int end)
594 {
595  unsigned int cluster = UINT_MAX;
598 }
599 void
601 {
602  if (!have_output)
603  {
605  return;
606  }
607 
608  assert (start <= out_len);
609  assert (idx <= end);
610 
611  unsigned int cluster = UINT_MAX;
616 }
617 
618 void
620 {
621  assert_unicode ();
622 
623  /* If script is set to INVALID, guess from buffer contents */
624  if (props.script == HB_SCRIPT_INVALID) {
625  for (unsigned int i = 0; i < len; i++) {
627  if (likely (script != HB_SCRIPT_COMMON &&
630  props.script = script;
631  break;
632  }
633  }
634  }
635 
636  /* If direction is set to INVALID, guess from script */
641  }
642 
643  /* If language is not set, use default language from locale */
645  /* TODO get_default_for_script? using $LANGUAGE */
647  }
648 }
649 
650 
651 /* Public API */
652 
654 {
656 
661  0, /* invisible */
665 
668  false, /* successful */
669  true, /* have_output */
670  true /* have_positions */
671 
672  /* Zero is good enough for everything else. */
673 };
674 
675 
676 /**
677  * hb_buffer_create: (Xconstructor)
678  *
679  * Creates a new #hb_buffer_t with all properties to defaults.
680  *
681  * Return value: (transfer full):
682  * A newly allocated #hb_buffer_t with a reference count of 1. The initial
683  * reference count should be released with hb_buffer_destroy() when you are done
684  * using the #hb_buffer_t. This function never returns %NULL. If memory cannot
685  * be allocated, a special #hb_buffer_t object will be returned on which
686  * hb_buffer_allocation_successful() returns %false.
687  *
688  * Since: 0.9.2
689  **/
690 hb_buffer_t *
692 {
694 
695  if (!(buffer = hb_object_create<hb_buffer_t> ()))
696  return hb_buffer_get_empty ();
697 
700 
701  buffer->reset ();
702 
703  return buffer;
704 }
705 
706 /**
707  * hb_buffer_get_empty:
708  *
709  * Fetches an empty #hb_buffer_t.
710  *
711  * Return value: (transfer full): The empty buffer
712  *
713  * Since: 0.9.2
714  **/
715 hb_buffer_t *
717 {
718  return const_cast<hb_buffer_t *> (&Null (hb_buffer_t));
719 }
720 
721 /**
722  * hb_buffer_reference: (skip)
723  * @buffer: An #hb_buffer_t
724  *
725  * Increases the reference count on @buffer by one. This prevents @buffer from
726  * being destroyed until a matching call to hb_buffer_destroy() is made.
727  *
728  * Return value: (transfer full):
729  * The referenced #hb_buffer_t.
730  *
731  * Since: 0.9.2
732  **/
733 hb_buffer_t *
735 {
736  return hb_object_reference (buffer);
737 }
738 
739 /**
740  * hb_buffer_destroy: (skip)
741  * @buffer: An #hb_buffer_t
742  *
743  * Deallocate the @buffer.
744  * Decreases the reference count on @buffer by one. If the result is zero, then
745  * @buffer and all associated resources are freed. See hb_buffer_reference().
746  *
747  * Since: 0.9.2
748  **/
749 void
751 {
752  if (!hb_object_destroy (buffer)) return;
753 
754  hb_unicode_funcs_destroy (buffer->unicode);
755 
756  free (buffer->info);
757  free (buffer->pos);
758 #ifndef HB_NO_BUFFER_MESSAGE
759  if (buffer->message_destroy)
760  buffer->message_destroy (buffer->message_data);
761 #endif
762 
763  free (buffer);
764 }
765 
766 /**
767  * hb_buffer_set_user_data: (skip)
768  * @buffer: An #hb_buffer_t
769  * @key: The user-data key
770  * @data: A pointer to the user data
771  * @destroy: (optional): A callback to call when @data is not needed anymore
772  * @replace: Whether to replace an existing data with the same key
773  *
774  * Attaches a user-data key/data pair to the specified buffer.
775  *
776  * Return value: %true if success, %false otherwise
777  *
778  * Since: 0.9.2
779  **/
780 hb_bool_t
783  void * data,
784  hb_destroy_func_t destroy,
786 {
787  return hb_object_set_user_data (buffer, key, data, destroy, replace);
788 }
789 
790 /**
791  * hb_buffer_get_user_data: (skip)
792  * @buffer: An #hb_buffer_t
793  * @key: The user-data key to query
794  *
795  * Fetches the user data associated with the specified key,
796  * attached to the specified buffer.
797  *
798  * Return value: (transfer-none): A pointer to the user data
799  *
800  * Since: 0.9.2
801  **/
802 void *
805 {
807 }
808 
809 
810 /**
811  * hb_buffer_set_content_type:
812  * @buffer: An #hb_buffer_t
813  * @content_type: The type of buffer contents to set
814  *
815  * Sets the type of @buffer contents. Buffers are either empty, contain
816  * characters (before shaping), or contain glyphs (the result of shaping).
817  *
818  * Since: 0.9.5
819  **/
820 void
822  hb_buffer_content_type_t content_type)
823 {
824  buffer->content_type = content_type;
825 }
826 
827 /**
828  * hb_buffer_get_content_type:
829  * @buffer: An #hb_buffer_t
830  *
831  * Fetches the type of @buffer contents. Buffers are either empty, contain
832  * characters (before shaping), or contain glyphs (the result of shaping).
833  *
834  * Return value:
835  * The type of @buffer contents
836  *
837  * Since: 0.9.5
838  **/
841 {
842  return buffer->content_type;
843 }
844 
845 
846 /**
847  * hb_buffer_set_unicode_funcs:
848  * @buffer: An #hb_buffer_t
849  * @unicode_funcs: The Unicode-functions structure
850  *
851  * Sets the Unicode-functions structure of a buffer to
852  * @unicode_funcs.
853  *
854  * Since: 0.9.2
855  **/
856 void
858  hb_unicode_funcs_t *unicode_funcs)
859 {
861  return;
862 
863  if (!unicode_funcs)
864  unicode_funcs = hb_unicode_funcs_get_default ();
865 
866  hb_unicode_funcs_reference (unicode_funcs);
867  hb_unicode_funcs_destroy (buffer->unicode);
868  buffer->unicode = unicode_funcs;
869 }
870 
871 /**
872  * hb_buffer_get_unicode_funcs:
873  * @buffer: An #hb_buffer_t
874  *
875  * Fetches the Unicode-functions structure of a buffer.
876  *
877  * Return value: The Unicode-functions structure
878  *
879  * Since: 0.9.2
880  **/
883 {
884  return buffer->unicode;
885 }
886 
887 /**
888  * hb_buffer_set_direction:
889  * @buffer: An #hb_buffer_t
890  * @direction: the #hb_direction_t of the @buffer
891  *
892  * Set the text flow direction of the buffer. No shaping can happen without
893  * setting @buffer direction, and it controls the visual direction for the
894  * output glyphs; for RTL direction the glyphs will be reversed. Many layout
895  * features depend on the proper setting of the direction, for example,
896  * reversing RTL text before shaping, then shaping with LTR direction is not
897  * the same as keeping the text in logical order and shaping with RTL
898  * direction.
899  *
900  * Since: 0.9.2
901  **/
902 void
905 
906 {
908  return;
909 
910  buffer->props.direction = direction;
911 }
912 
913 /**
914  * hb_buffer_get_direction:
915  * @buffer: An #hb_buffer_t
916  *
917  * See hb_buffer_set_direction()
918  *
919  * Return value:
920  * The direction of the @buffer.
921  *
922  * Since: 0.9.2
923  **/
926 {
927  return buffer->props.direction;
928 }
929 
930 /**
931  * hb_buffer_set_script:
932  * @buffer: An #hb_buffer_t
933  * @script: An #hb_script_t to set.
934  *
935  * Sets the script of @buffer to @script.
936  *
937  * Script is crucial for choosing the proper shaping behaviour for scripts that
938  * require it (e.g. Arabic) and the which OpenType features defined in the font
939  * to be applied.
940  *
941  * You can pass one of the predefined #hb_script_t values, or use
942  * hb_script_from_string() or hb_script_from_iso15924_tag() to get the
943  * corresponding script from an ISO 15924 script tag.
944  *
945  * Since: 0.9.2
946  **/
947 void
950 {
952  return;
953 
954  buffer->props.script = script;
955 }
956 
957 /**
958  * hb_buffer_get_script:
959  * @buffer: An #hb_buffer_t
960  *
961  * Fetches the script of @buffer.
962  *
963  * Return value:
964  * The #hb_script_t of the @buffer
965  *
966  * Since: 0.9.2
967  **/
970 {
971  return buffer->props.script;
972 }
973 
974 /**
975  * hb_buffer_set_language:
976  * @buffer: An #hb_buffer_t
977  * @language: An hb_language_t to set
978  *
979  * Sets the language of @buffer to @language.
980  *
981  * Languages are crucial for selecting which OpenType feature to apply to the
982  * buffer which can result in applying language-specific behaviour. Languages
983  * are orthogonal to the scripts, and though they are related, they are
984  * different concepts and should not be confused with each other.
985  *
986  * Use hb_language_from_string() to convert from BCP 47 language tags to
987  * #hb_language_t.
988  *
989  * Since: 0.9.2
990  **/
991 void
994 {
996  return;
997 
998  buffer->props.language = language;
999 }
1000 
1001 /**
1002  * hb_buffer_get_language:
1003  * @buffer: An #hb_buffer_t
1004  *
1005  * See hb_buffer_set_language().
1006  *
1007  * Return value: (transfer none):
1008  * The #hb_language_t of the buffer. Must not be freed by the caller.
1009  *
1010  * Since: 0.9.2
1011  **/
1014 {
1015  return buffer->props.language;
1016 }
1017 
1018 /**
1019  * hb_buffer_set_segment_properties:
1020  * @buffer: An #hb_buffer_t
1021  * @props: An #hb_segment_properties_t to use
1022  *
1023  * Sets the segment properties of the buffer, a shortcut for calling
1024  * hb_buffer_set_direction(), hb_buffer_set_script() and
1025  * hb_buffer_set_language() individually.
1026  *
1027  * Since: 0.9.7
1028  **/
1029 void
1031  const hb_segment_properties_t *props)
1032 {
1034  return;
1035 
1036  buffer->props = *props;
1037 }
1038 
1039 /**
1040  * hb_buffer_get_segment_properties:
1041  * @buffer: An #hb_buffer_t
1042  * @props: (out): The output #hb_segment_properties_t
1043  *
1044  * Sets @props to the #hb_segment_properties_t of @buffer.
1045  *
1046  * Since: 0.9.7
1047  **/
1048 void
1050  hb_segment_properties_t *props)
1051 {
1052  *props = buffer->props;
1053 }
1054 
1055 
1056 /**
1057  * hb_buffer_set_flags:
1058  * @buffer: An #hb_buffer_t
1059  * @flags: The buffer flags to set
1060  *
1061  * Sets @buffer flags to @flags. See #hb_buffer_flags_t.
1062  *
1063  * Since: 0.9.7
1064  **/
1065 void
1068 {
1070  return;
1071 
1072  buffer->flags = flags;
1073 }
1074 
1075 /**
1076  * hb_buffer_get_flags:
1077  * @buffer: An #hb_buffer_t
1078  *
1079  * Fetches the #hb_buffer_flags_t of @buffer.
1080  *
1081  * Return value:
1082  * The @buffer flags
1083  *
1084  * Since: 0.9.7
1085  **/
1088 {
1089  return buffer->flags;
1090 }
1091 
1092 /**
1093  * hb_buffer_set_cluster_level:
1094  * @buffer: An #hb_buffer_t
1095  * @cluster_level: The cluster level to set on the buffer
1096  *
1097  * Sets the cluster level of a buffer. The #hb_buffer_cluster_level_t
1098  * dictates one aspect of how HarfBuzz will treat non-base characters
1099  * during shaping.
1100  *
1101  * Since: 0.9.42
1102  **/
1103 void
1105  hb_buffer_cluster_level_t cluster_level)
1106 {
1108  return;
1109 
1110  buffer->cluster_level = cluster_level;
1111 }
1112 
1113 /**
1114  * hb_buffer_get_cluster_level:
1115  * @buffer: An #hb_buffer_t
1116  *
1117  * Fetches the cluster level of a buffer. The #hb_buffer_cluster_level_t
1118  * dictates one aspect of how HarfBuzz will treat non-base characters
1119  * during shaping.
1120  *
1121  * Return value: The cluster level of @buffer
1122  *
1123  * Since: 0.9.42
1124  **/
1127 {
1128  return buffer->cluster_level;
1129 }
1130 
1131 
1132 /**
1133  * hb_buffer_set_replacement_codepoint:
1134  * @buffer: An #hb_buffer_t
1135  * @replacement: the replacement #hb_codepoint_t
1136  *
1137  * Sets the #hb_codepoint_t that replaces invalid entries for a given encoding
1138  * when adding text to @buffer.
1139  *
1140  * Default is %HB_BUFFER_REPLACEMENT_CODEPOINT_DEFAULT.
1141  *
1142  * Since: 0.9.31
1143  **/
1144 void
1146  hb_codepoint_t replacement)
1147 {
1149  return;
1150 
1151  buffer->replacement = replacement;
1152 }
1153 
1154 /**
1155  * hb_buffer_get_replacement_codepoint:
1156  * @buffer: An #hb_buffer_t
1157  *
1158  * Fetches the #hb_codepoint_t that replaces invalid entries for a given encoding
1159  * when adding text to @buffer.
1160  *
1161  * Return value:
1162  * The @buffer replacement #hb_codepoint_t
1163  *
1164  * Since: 0.9.31
1165  **/
1168 {
1169  return buffer->replacement;
1170 }
1171 
1172 
1173 /**
1174  * hb_buffer_set_invisible_glyph:
1175  * @buffer: An #hb_buffer_t
1176  * @invisible: the invisible #hb_codepoint_t
1177  *
1178  * Sets the #hb_codepoint_t that replaces invisible characters in
1179  * the shaping result. If set to zero (default), the glyph for the
1180  * U+0020 SPACE character is used. Otherwise, this value is used
1181  * verbatim.
1182  *
1183  * Since: 2.0.0
1184  **/
1185 void
1187  hb_codepoint_t invisible)
1188 {
1190  return;
1191 
1192  buffer->invisible = invisible;
1193 }
1194 
1195 /**
1196  * hb_buffer_get_invisible_glyph:
1197  * @buffer: An #hb_buffer_t
1198  *
1199  * See hb_buffer_set_invisible_glyph().
1200  *
1201  * Return value:
1202  * The @buffer invisible #hb_codepoint_t
1203  *
1204  * Since: 2.0.0
1205  **/
1208 {
1209  return buffer->invisible;
1210 }
1211 
1212 
1213 /**
1214  * hb_buffer_reset:
1215  * @buffer: An #hb_buffer_t
1216  *
1217  * Resets the buffer to its initial status, as if it was just newly created
1218  * with hb_buffer_create().
1219  *
1220  * Since: 0.9.2
1221  **/
1222 void
1224 {
1225  buffer->reset ();
1226 }
1227 
1228 /**
1229  * hb_buffer_clear_contents:
1230  * @buffer: An #hb_buffer_t
1231  *
1232  * Similar to hb_buffer_reset(), but does not clear the Unicode functions and
1233  * the replacement code point.
1234  *
1235  * Since: 0.9.11
1236  **/
1237 void
1239 {
1240  buffer->clear ();
1241 }
1242 
1243 /**
1244  * hb_buffer_pre_allocate:
1245  * @buffer: An #hb_buffer_t
1246  * @size: Number of items to pre allocate.
1247  *
1248  * Pre allocates memory for @buffer to fit at least @size number of items.
1249  *
1250  * Return value:
1251  * %true if @buffer memory allocation succeeded, %false otherwise
1252  *
1253  * Since: 0.9.2
1254  **/
1255 hb_bool_t
1257 {
1258  return buffer->ensure (size);
1259 }
1260 
1261 /**
1262  * hb_buffer_allocation_successful:
1263  * @buffer: An #hb_buffer_t
1264  *
1265  * Check if allocating memory for the buffer succeeded.
1266  *
1267  * Return value:
1268  * %true if @buffer memory allocation succeeded, %false otherwise.
1269  *
1270  * Since: 0.9.2
1271  **/
1272 hb_bool_t
1274 {
1275  return buffer->successful;
1276 }
1277 
1278 /**
1279  * hb_buffer_add:
1280  * @buffer: An #hb_buffer_t
1281  * @codepoint: A Unicode code point.
1282  * @cluster: The cluster value of @codepoint.
1283  *
1284  * Appends a character with the Unicode value of @codepoint to @buffer, and
1285  * gives it the initial cluster value of @cluster. Clusters can be any thing
1286  * the client wants, they are usually used to refer to the index of the
1287  * character in the input text stream and are output in
1288  * #hb_glyph_info_t.cluster field.
1289  *
1290  * This function does not check the validity of @codepoint, it is up to the
1291  * caller to ensure it is a valid Unicode code point.
1292  *
1293  * Since: 0.9.7
1294  **/
1295 void
1298  unsigned int cluster)
1299 {
1300  buffer->add (codepoint, cluster);
1301  buffer->clear_context (1);
1302 }
1303 
1304 /**
1305  * hb_buffer_set_length:
1306  * @buffer: An #hb_buffer_t
1307  * @length: The new length of @buffer
1308  *
1309  * Similar to hb_buffer_pre_allocate(), but clears any new items added at the
1310  * end.
1311  *
1312  * Return value:
1313  * %true if @buffer memory allocation succeeded, %false otherwise.
1314  *
1315  * Since: 0.9.2
1316  **/
1317 hb_bool_t
1319  unsigned int length)
1320 {
1322  return length == 0;
1323 
1324  if (!buffer->ensure (length))
1325  return false;
1326 
1327  /* Wipe the new space */
1328  if (length > buffer->len) {
1329  memset (buffer->info + buffer->len, 0, sizeof (buffer->info[0]) * (length - buffer->len));
1330  if (buffer->have_positions)
1331  memset (buffer->pos + buffer->len, 0, sizeof (buffer->pos[0]) * (length - buffer->len));
1332  }
1333 
1334  buffer->len = length;
1335 
1336  if (!length)
1337  {
1338  buffer->content_type = HB_BUFFER_CONTENT_TYPE_INVALID;
1339  buffer->clear_context (0);
1340  }
1341  buffer->clear_context (1);
1342 
1343  return true;
1344 }
1345 
1346 /**
1347  * hb_buffer_get_length:
1348  * @buffer: An #hb_buffer_t
1349  *
1350  * Returns the number of items in the buffer.
1351  *
1352  * Return value:
1353  * The @buffer length.
1354  * The value valid as long as buffer has not been modified.
1355  *
1356  * Since: 0.9.2
1357  **/
1358 unsigned int
1360 {
1361  return buffer->len;
1362 }
1363 
1364 /**
1365  * hb_buffer_get_glyph_infos:
1366  * @buffer: An #hb_buffer_t
1367  * @length: (out): The output-array length.
1368  *
1369  * Returns @buffer glyph information array. Returned pointer
1370  * is valid as long as @buffer contents are not modified.
1371  *
1372  * Return value: (transfer none) (array length=length):
1373  * The @buffer glyph information array.
1374  * The value valid as long as buffer has not been modified.
1375  *
1376  * Since: 0.9.2
1377  **/
1380  unsigned int *length)
1381 {
1382  if (length)
1383  *length = buffer->len;
1384 
1385  return (hb_glyph_info_t *) buffer->info;
1386 }
1387 
1388 /**
1389  * hb_buffer_get_glyph_positions:
1390  * @buffer: An #hb_buffer_t
1391  * @length: (out): The output length
1392  *
1393  * Returns @buffer glyph position array. Returned pointer
1394  * is valid as long as @buffer contents are not modified.
1395  *
1396  * Return value: (transfer none) (array length=length):
1397  * The @buffer glyph position array.
1398  * The value valid as long as buffer has not been modified.
1399  *
1400  * Since: 0.9.2
1401  **/
1404  unsigned int *length)
1405 {
1406  if (!buffer->have_positions)
1407  buffer->clear_positions ();
1408 
1409  if (length)
1410  *length = buffer->len;
1411 
1412  return (hb_glyph_position_t *) buffer->pos;
1413 }
1414 
1415 /**
1416  * hb_buffer_has_positions:
1417  * @buffer: an #hb_buffer_t.
1418  *
1419  * Returns whether @buffer has glyph position data.
1420  * A buffer gains position data when hb_buffer_get_glyph_positions() is called on it,
1421  * and cleared of position data when hb_buffer_clear_contents() is called.
1422  *
1423  * Return value:
1424  * %true if the @buffer has position array, %false otherwise.
1425  *
1426  * Since: 2.7.3
1427  **/
1430 {
1431  return buffer->have_positions;
1432 }
1433 
1434 /**
1435  * hb_glyph_info_get_glyph_flags:
1436  * @info: a #hb_glyph_info_t
1437  *
1438  * Returns glyph flags encoded within a #hb_glyph_info_t.
1439  *
1440  * Return value:
1441  * The #hb_glyph_flags_t encoded within @info
1442  *
1443  * Since: 1.5.0
1444  **/
1447 {
1449 }
1450 
1451 /**
1452  * hb_buffer_reverse:
1453  * @buffer: An #hb_buffer_t
1454  *
1455  * Reverses buffer contents.
1456  *
1457  * Since: 0.9.2
1458  **/
1459 void
1461 {
1462  buffer->reverse ();
1463 }
1464 
1465 /**
1466  * hb_buffer_reverse_range:
1467  * @buffer: An #hb_buffer_t
1468  * @start: start index
1469  * @end: end index
1470  *
1471  * Reverses buffer contents between @start and @end.
1472  *
1473  * Since: 0.9.41
1474  **/
1475 void
1477  unsigned int start, unsigned int end)
1478 {
1479  buffer->reverse_range (start, end);
1480 }
1481 
1482 /**
1483  * hb_buffer_reverse_clusters:
1484  * @buffer: An #hb_buffer_t
1485  *
1486  * Reverses buffer clusters. That is, the buffer contents are
1487  * reversed, then each cluster (consecutive items having the
1488  * same cluster number) are reversed again.
1489  *
1490  * Since: 0.9.2
1491  **/
1492 void
1494 {
1495  buffer->reverse_clusters ();
1496 }
1497 
1498 /**
1499  * hb_buffer_guess_segment_properties:
1500  * @buffer: An #hb_buffer_t
1501  *
1502  * Sets unset buffer segment properties based on buffer Unicode
1503  * contents. If buffer is not empty, it must have content type
1504  * %HB_BUFFER_CONTENT_TYPE_UNICODE.
1505  *
1506  * If buffer script is not set (ie. is %HB_SCRIPT_INVALID), it
1507  * will be set to the Unicode script of the first character in
1508  * the buffer that has a script other than %HB_SCRIPT_COMMON,
1509  * %HB_SCRIPT_INHERITED, and %HB_SCRIPT_UNKNOWN.
1510  *
1511  * Next, if buffer direction is not set (ie. is %HB_DIRECTION_INVALID),
1512  * it will be set to the natural horizontal direction of the
1513  * buffer script as returned by hb_script_get_horizontal_direction().
1514  * If hb_script_get_horizontal_direction() returns %HB_DIRECTION_INVALID,
1515  * then %HB_DIRECTION_LTR is used.
1516  *
1517  * Finally, if buffer language is not set (ie. is %HB_LANGUAGE_INVALID),
1518  * it will be set to the process's default language as returned by
1519  * hb_language_get_default(). This may change in the future by
1520  * taking buffer script into consideration when choosing a language.
1521  * Note that hb_language_get_default() is NOT threadsafe the first time
1522  * it is called. See documentation for that function for details.
1523  *
1524  * Since: 0.9.7
1525  **/
1526 void
1528 {
1529  buffer->guess_segment_properties ();
1530 }
1531 
1532 template <typename utf_t>
1533 static inline void
1535  const typename utf_t::codepoint_t *text,
1536  int text_length,
1537  unsigned int item_offset,
1538  int item_length)
1539 {
1540  typedef typename utf_t::codepoint_t T;
1541  const hb_codepoint_t replacement = buffer->replacement;
1542 
1543  buffer->assert_unicode ();
1544 
1546  return;
1547 
1548  if (text_length == -1)
1549  text_length = utf_t::strlen (text);
1550 
1551  if (item_length == -1)
1552  item_length = text_length - item_offset;
1553 
1554  buffer->ensure (buffer->len + item_length * sizeof (T) / 4);
1555 
1556  /* If buffer is empty and pre-context provided, install it.
1557  * This check is written this way, to make sure people can
1558  * provide pre-context in one add_utf() call, then provide
1559  * text in a follow-up call. See:
1560  *
1561  * https://bugzilla.mozilla.org/show_bug.cgi?id=801410#c13
1562  */
1563  if (!buffer->len && item_offset > 0)
1564  {
1565  /* Add pre-context */
1566  buffer->clear_context (0);
1567  const T *prev = text + item_offset;
1568  const T *start = text;
1569  while (start < prev && buffer->context_len[0] < buffer->CONTEXT_LENGTH)
1570  {
1571  hb_codepoint_t u;
1572  prev = utf_t::prev (prev, start, &u, replacement);
1573  buffer->context[0][buffer->context_len[0]++] = u;
1574  }
1575  }
1576 
1577  const T *next = text + item_offset;
1578  const T *end = next + item_length;
1579  while (next < end)
1580  {
1581  hb_codepoint_t u;
1582  const T *old_next = next;
1583  next = utf_t::next (next, end, &u, replacement);
1584  buffer->add (u, old_next - (const T *) text);
1585  }
1586 
1587  /* Add post-context */
1588  buffer->clear_context (1);
1589  end = text + text_length;
1590  while (next < end && buffer->context_len[1] < buffer->CONTEXT_LENGTH)
1591  {
1592  hb_codepoint_t u;
1593  next = utf_t::next (next, end, &u, replacement);
1594  buffer->context[1][buffer->context_len[1]++] = u;
1595  }
1596 
1597  buffer->content_type = HB_BUFFER_CONTENT_TYPE_UNICODE;
1598 }
1599 
1600 /**
1601  * hb_buffer_add_utf8:
1602  * @buffer: An #hb_buffer_t
1603  * @text: (array length=text_length) (element-type uint8_t): An array of UTF-8
1604  * characters to append.
1605  * @text_length: The length of the @text, or -1 if it is %NULL terminated.
1606  * @item_offset: The offset of the first character to add to the @buffer.
1607  * @item_length: The number of characters to add to the @buffer, or -1 for the
1608  * end of @text (assuming it is %NULL terminated).
1609  *
1610  * See hb_buffer_add_codepoints().
1611  *
1612  * Replaces invalid UTF-8 characters with the @buffer replacement code point,
1613  * see hb_buffer_set_replacement_codepoint().
1614  *
1615  * Since: 0.9.2
1616  **/
1617 void
1619  const char *text,
1620  int text_length,
1621  unsigned int item_offset,
1622  int item_length)
1623 {
1624  hb_buffer_add_utf<hb_utf8_t> (buffer, (const uint8_t *) text, text_length, item_offset, item_length);
1625 }
1626 
1627 /**
1628  * hb_buffer_add_utf16:
1629  * @buffer: An #hb_buffer_t
1630  * @text: (array length=text_length): An array of UTF-16 characters to append
1631  * @text_length: The length of the @text, or -1 if it is %NULL terminated
1632  * @item_offset: The offset of the first character to add to the @buffer
1633  * @item_length: The number of characters to add to the @buffer, or -1 for the
1634  * end of @text (assuming it is %NULL terminated)
1635  *
1636  * See hb_buffer_add_codepoints().
1637  *
1638  * Replaces invalid UTF-16 characters with the @buffer replacement code point,
1639  * see hb_buffer_set_replacement_codepoint().
1640  *
1641  * Since: 0.9.2
1642  **/
1643 void
1645  const uint16_t *text,
1646  int text_length,
1647  unsigned int item_offset,
1648  int item_length)
1649 {
1650  hb_buffer_add_utf<hb_utf16_t> (buffer, text, text_length, item_offset, item_length);
1651 }
1652 
1653 /**
1654  * hb_buffer_add_utf32:
1655  * @buffer: An #hb_buffer_t
1656  * @text: (array length=text_length): An array of UTF-32 characters to append
1657  * @text_length: The length of the @text, or -1 if it is %NULL terminated
1658  * @item_offset: The offset of the first character to add to the @buffer
1659  * @item_length: The number of characters to add to the @buffer, or -1 for the
1660  * end of @text (assuming it is %NULL terminated)
1661  *
1662  * See hb_buffer_add_codepoints().
1663  *
1664  * Replaces invalid UTF-32 characters with the @buffer replacement code point,
1665  * see hb_buffer_set_replacement_codepoint().
1666  *
1667  * Since: 0.9.2
1668  **/
1669 void
1671  const uint32_t *text,
1672  int text_length,
1673  unsigned int item_offset,
1674  int item_length)
1675 {
1676  hb_buffer_add_utf<hb_utf32_t> (buffer, text, text_length, item_offset, item_length);
1677 }
1678 
1679 /**
1680  * hb_buffer_add_latin1:
1681  * @buffer: An #hb_buffer_t
1682  * @text: (array length=text_length) (element-type uint8_t): an array of UTF-8
1683  * characters to append
1684  * @text_length: the length of the @text, or -1 if it is %NULL terminated
1685  * @item_offset: the offset of the first character to add to the @buffer
1686  * @item_length: the number of characters to add to the @buffer, or -1 for the
1687  * end of @text (assuming it is %NULL terminated)
1688  *
1689  * Similar to hb_buffer_add_codepoints(), but allows only access to first 256
1690  * Unicode code points that can fit in 8-bit strings.
1691  *
1692  * <note>Has nothing to do with non-Unicode Latin-1 encoding.</note>
1693  *
1694  * Since: 0.9.39
1695  **/
1696 void
1698  const uint8_t *text,
1699  int text_length,
1700  unsigned int item_offset,
1701  int item_length)
1702 {
1703  hb_buffer_add_utf<hb_latin1_t> (buffer, text, text_length, item_offset, item_length);
1704 }
1705 
1706 /**
1707  * hb_buffer_add_codepoints:
1708  * @buffer: a #hb_buffer_t to append characters to.
1709  * @text: (array length=text_length): an array of Unicode code points to append.
1710  * @text_length: the length of the @text, or -1 if it is %NULL terminated.
1711  * @item_offset: the offset of the first code point to add to the @buffer.
1712  * @item_length: the number of code points to add to the @buffer, or -1 for the
1713  * end of @text (assuming it is %NULL terminated).
1714  *
1715  * Appends characters from @text array to @buffer. The @item_offset is the
1716  * position of the first character from @text that will be appended, and
1717  * @item_length is the number of character. When shaping part of a larger text
1718  * (e.g. a run of text from a paragraph), instead of passing just the substring
1719  * corresponding to the run, it is preferable to pass the whole
1720  * paragraph and specify the run start and length as @item_offset and
1721  * @item_length, respectively, to give HarfBuzz the full context to be able,
1722  * for example, to do cross-run Arabic shaping or properly handle combining
1723  * marks at stat of run.
1724  *
1725  * This function does not check the validity of @text, it is up to the caller
1726  * to ensure it contains a valid Unicode code points.
1727  *
1728  * Since: 0.9.31
1729  **/
1730 void
1732  const hb_codepoint_t *text,
1733  int text_length,
1734  unsigned int item_offset,
1735  int item_length)
1736 {
1737  hb_buffer_add_utf<hb_utf32_novalidate_t> (buffer, text, text_length, item_offset, item_length);
1738 }
1739 
1740 
1741 /**
1742  * hb_buffer_append:
1743  * @buffer: An #hb_buffer_t
1744  * @source: source #hb_buffer_t
1745  * @start: start index into source buffer to copy. Use 0 to copy from start of buffer.
1746  * @end: end index into source buffer to copy. Use @HB_FEATURE_GLOBAL_END to copy to end of buffer.
1747  *
1748  * Append (part of) contents of another buffer to this buffer.
1749  *
1750  * Since: 1.5.0
1751  **/
1752 HB_EXTERN void
1755  unsigned int start,
1756  unsigned int end)
1757 {
1758  assert (!buffer->have_output && !source->have_output);
1759  assert (buffer->have_positions == source->have_positions ||
1760  !buffer->len || !source->len);
1761  assert (buffer->content_type == source->content_type ||
1762  !buffer->len || !source->len);
1763 
1764  if (end > source->len)
1765  end = source->len;
1766  if (start > end)
1767  start = end;
1768  if (start == end)
1769  return;
1770 
1771  if (!buffer->len)
1772  buffer->content_type = source->content_type;
1773  if (!buffer->have_positions && source->have_positions)
1774  buffer->clear_positions ();
1775 
1776  if (buffer->len + (end - start) < buffer->len) /* Overflows. */
1777  {
1778  buffer->successful = false;
1779  return;
1780  }
1781 
1782  unsigned int orig_len = buffer->len;
1783  hb_buffer_set_length (buffer, buffer->len + (end - start));
1784  if (unlikely (!buffer->successful))
1785  return;
1786 
1787  memcpy (buffer->info + orig_len, source->info + start, (end - start) * sizeof (buffer->info[0]));
1788  if (buffer->have_positions)
1789  memcpy (buffer->pos + orig_len, source->pos + start, (end - start) * sizeof (buffer->pos[0]));
1790 }
1791 
1792 
1793 static int
1795  const hb_glyph_info_t *pb)
1796 {
1797  return (int) pb->codepoint - (int) pa->codepoint;
1798 }
1799 
1800 static inline void
1802  unsigned int start,
1803  unsigned int end,
1804  bool backward)
1805 {
1806  hb_glyph_position_t *pos = buffer->pos;
1807 
1808  /* Total cluster advance */
1809  hb_position_t total_x_advance = 0, total_y_advance = 0;
1810  for (unsigned int i = start; i < end; i++)
1811  {
1812  total_x_advance += pos[i].x_advance;
1813  total_y_advance += pos[i].y_advance;
1814  }
1815 
1816  hb_position_t x_advance = 0, y_advance = 0;
1817  for (unsigned int i = start; i < end; i++)
1818  {
1819  pos[i].x_offset += x_advance;
1820  pos[i].y_offset += y_advance;
1821 
1822  x_advance += pos[i].x_advance;
1823  y_advance += pos[i].y_advance;
1824 
1825  pos[i].x_advance = 0;
1826  pos[i].y_advance = 0;
1827  }
1828 
1829  if (backward)
1830  {
1831  /* Transfer all cluster advance to the last glyph. */
1832  pos[end - 1].x_advance = total_x_advance;
1833  pos[end - 1].y_advance = total_y_advance;
1834 
1836  } else {
1837  /* Transfer all cluster advance to the first glyph. */
1838  pos[start].x_advance += total_x_advance;
1839  pos[start].y_advance += total_y_advance;
1840  for (unsigned int i = start + 1; i < end; i++) {
1841  pos[i].x_offset -= total_x_advance;
1842  pos[i].y_offset -= total_y_advance;
1843  }
1844  hb_stable_sort (buffer->info + start + 1, end - start - 1, compare_info_codepoint, buffer->pos + start + 1);
1845  }
1846 }
1847 
1848 /**
1849  * hb_buffer_normalize_glyphs:
1850  * @buffer: An #hb_buffer_t
1851  *
1852  * Reorders a glyph buffer to have canonical in-cluster glyph order / position.
1853  * The resulting clusters should behave identical to pre-reordering clusters.
1854  *
1855  * <note>This has nothing to do with Unicode normalization.</note>
1856  *
1857  * Since: 0.9.2
1858  **/
1859 void
1861 {
1862  assert (buffer->have_positions);
1863 
1864  buffer->assert_glyphs ();
1865 
1866  bool backward = HB_DIRECTION_IS_BACKWARD (buffer->props.direction);
1867 
1869  normalize_glyphs_cluster (buffer, start, end, backward);
1870 }
1871 
1872 void
1873 hb_buffer_t::sort (unsigned int start, unsigned int end, int(*compar)(const hb_glyph_info_t *, const hb_glyph_info_t *))
1874 {
1876  for (unsigned int i = start + 1; i < end; i++)
1877  {
1878  unsigned int j = i;
1879  while (j > start && compar (&info[j - 1], &info[i]) > 0)
1880  j--;
1881  if (i == j)
1882  continue;
1883  /* Move item i to occupy place for item j, shift what's in between. */
1884  merge_clusters (j, i + 1);
1885  {
1886  hb_glyph_info_t t = info[i];
1887  memmove (&info[j + 1], &info[j], (i - j) * sizeof (hb_glyph_info_t));
1888  info[j] = t;
1889  }
1890  }
1891 }
1892 
1893 
1894 /*
1895  * Comparing buffers.
1896  */
1897 
1898 /**
1899  * hb_buffer_diff:
1900  * @buffer: a buffer.
1901  * @reference: other buffer to compare to.
1902  * @dottedcircle_glyph: glyph id of U+25CC DOTTED CIRCLE, or (hb_codepont_t) -1.
1903  * @position_fuzz: allowed absolute difference in position values.
1904  *
1905  * If dottedcircle_glyph is (hb_codepoint_t) -1 then %HB_BUFFER_DIFF_FLAG_DOTTED_CIRCLE_PRESENT
1906  * and %HB_BUFFER_DIFF_FLAG_NOTDEF_PRESENT are never returned. This should be used by most
1907  * callers if just comparing two buffers is needed.
1908  *
1909  * Since: 1.5.0
1910  **/
1913  hb_buffer_t *reference,
1914  hb_codepoint_t dottedcircle_glyph,
1915  unsigned int position_fuzz)
1916 {
1917  if (buffer->content_type != reference->content_type && buffer->len && reference->len)
1919 
1921  bool contains = dottedcircle_glyph != (hb_codepoint_t) -1;
1922 
1923  unsigned int count = reference->len;
1924 
1925  if (buffer->len != count)
1926  {
1927  /*
1928  * we can't compare glyph-by-glyph, but we do want to know if there
1929  * are .notdef or dottedcircle glyphs present in the reference buffer
1930  */
1931  const hb_glyph_info_t *info = reference->info;
1932  unsigned int i;
1933  for (i = 0; i < count; i++)
1934  {
1935  if (contains && info[i].codepoint == dottedcircle_glyph)
1937  if (contains && info[i].codepoint == 0)
1939  }
1941  return hb_buffer_diff_flags_t (result);
1942  }
1943 
1944  if (!count)
1945  return hb_buffer_diff_flags_t (result);
1946 
1947  const hb_glyph_info_t *buf_info = buffer->info;
1948  const hb_glyph_info_t *ref_info = reference->info;
1949  for (unsigned int i = 0; i < count; i++)
1950  {
1951  if (buf_info->codepoint != ref_info->codepoint)
1953  if (buf_info->cluster != ref_info->cluster)
1955  if ((buf_info->mask & ~ref_info->mask & HB_GLYPH_FLAG_DEFINED))
1957  if (contains && ref_info->codepoint == dottedcircle_glyph)
1959  if (contains && ref_info->codepoint == 0)
1961  buf_info++;
1962  ref_info++;
1963  }
1964 
1965  if (buffer->content_type == HB_BUFFER_CONTENT_TYPE_GLYPHS)
1966  {
1967  assert (buffer->have_positions);
1968  const hb_glyph_position_t *buf_pos = buffer->pos;
1969  const hb_glyph_position_t *ref_pos = reference->pos;
1970  for (unsigned int i = 0; i < count; i++)
1971  {
1972  if ((unsigned int) abs (buf_pos->x_advance - ref_pos->x_advance) > position_fuzz ||
1973  (unsigned int) abs (buf_pos->y_advance - ref_pos->y_advance) > position_fuzz ||
1974  (unsigned int) abs (buf_pos->x_offset - ref_pos->x_offset) > position_fuzz ||
1975  (unsigned int) abs (buf_pos->y_offset - ref_pos->y_offset) > position_fuzz)
1976  {
1978  break;
1979  }
1980  buf_pos++;
1981  ref_pos++;
1982  }
1983  }
1984 
1985  return result;
1986 }
1987 
1988 
1989 /*
1990  * Debugging.
1991  */
1992 
1993 #ifndef HB_NO_BUFFER_MESSAGE
1994 /**
1995  * hb_buffer_set_message_func:
1996  * @buffer: An #hb_buffer_t
1997  * @func: (closure user_data) (destroy destroy) (scope notified):
1998  * @user_data:
1999  * @destroy:
2000  *
2001  *
2002  *
2003  * Since: 1.1.3
2004  **/
2005 void
2008  void *user_data, hb_destroy_func_t destroy)
2009 {
2010  if (buffer->message_destroy)
2011  buffer->message_destroy (buffer->message_data);
2012 
2013  if (func) {
2014  buffer->message_func = func;
2015  buffer->message_data = user_data;
2016  buffer->message_destroy = destroy;
2017  } else {
2018  buffer->message_func = nullptr;
2019  buffer->message_data = nullptr;
2020  buffer->message_destroy = nullptr;
2021  }
2022 }
2023 bool
2025 {
2026  char buf[100];
2027  vsnprintf (buf, sizeof (buf), fmt, ap);
2028  return (bool) this->message_func (this, font, buf, this->message_data);
2029 }
2030 #endif
#define count(a)
Definition: aptex-macros.h:781
#define new_pos
#define language
Definition: aptex-macros.h:837
#define text(a)
Definition: aptex-macros.h:925
#define next(a)
Definition: aptex-macros.h:924
#define static_assert(c, msg)
Definition: cff.cc:31
#define b
Definition: jpegint.h:372
#define ap
#define free(a)
Definition: decNumber.cpp:310
#define info
Definition: dviinfo.c:42
struct rect data
Definition: dvipdfm.c:64
void replace(char *, char *)
Definition: dvispc.c:2100
#define T
Definition: fmt.h:20
#define t
Definition: afcover.h:96
static FIELD_PTR prev
Definition: genind.c:36
#define a(n)
Definition: gpos-common.c:148
#define memmove(d, s, n)
Definition: gsftopk.c:65
#define memcpy(d, s, n)
Definition: gsftopk.c:64
PICINFO * pinfo
Definition: in_pcx.cpp:129
assert(pcxLoadImage24((char *)((void *) 0), fp, pinfo, hdr))
#define likely(x)
Definition: jbig2arith.cc:115
#define unlikely(x)
Definition: jbig2arith.cc:116
small capitals from c petite p scientific f u
Definition: afcover.h:88
small capitals from c petite p
Definition: afcover.h:72
small capitals from c petite p scientific i
Definition: afcover.h:80
sizeof(AF_ModuleRec)
xD9 x84 xD8 xAD xD9 x80 xF0 x90 xAC x9A xE0 xA7 xA6 xE0 xA7 xAA xF0 x91 x84 xA4 xF0 x91 x84 x89 xF0 x91 x84 x9B xF0 x90 x8A xAB xF0 x90 x8B x89 xE2 xB2 x9E xE2 xB2 x9F xD0 xBE xD0 x9E xF0 x90 x90 x84 xF0 x90 x90 xAC xE1 x83 x98 xE1 x83 x94 xE1 x83 x90 xE1 xB2 xBF xE2 xB0 x95 xE2 xB1 x85 xCE xBF xCE x9F xE0 xA8 xA0 xE0 xA8 xB0 xE0 xA9 xA6 Kayah xEA xA4 x8D xEA xA4 x80 Khmer xE1 xA7 xA1 xE1 xA7 xAA xE0 xBB x90 Latin Subscript xE2 x82 x92 xE2 x82 x80 xEA x93 xB3 xF0 x96 xB9 xA1 xF0 x96 xB9 x9B xF0 x96 xB9 xAF xE1 x80 x9D xE1 x80 x84 xE1 x80 x82 no script
Definition: afscript.h:271
xD9 x84 xD8 xAD xD9 x80 xF0 x90 xAC x9A xE0 xA7 xA6 xE0 xA7 xAA xF0 x91 x84 xA4 xF0 x91 x84 x89 xF0 x91 x84 x9B xF0 x90 x8A xAB xF0 x90 x8B x89 xE2 xB2 x9E xE2 xB2 x9F xD0 xBE xD0 x9E xF0 x90 x90 x84 xF0 x90 x90 xAC xE1 x83 x98 xE1 x83 x94 xE1 x83 x90 xE1 xB2 xBF xE2 xB0 x95 xE2 xB1 x85 xCE xBF xCE x9F xE0 xA8 xA0 xE0 xA8 xB0 xE0 xA9 xA6 Kayah xEA xA4 x8D xEA xA4 x80 Khmer HB_SCRIPT_INVALID
Definition: afscript.h:199
unsigned short uint16_t
Definition: stdint.h:79
unsigned int uint32_t
Definition: stdint.h:80
unsigned int uintptr_t
Definition: stdint.h:119
signed int intptr_t
Definition: stdint.h:118
unsigned char uint8_t
Definition: stdint.h:78
#define buf
#define UINT_MAX
Definition: c-minmax.h:56
#define length(c)
Definition: ctangleboot.c:65
#define vsnprintf
Definition: snprintf.c:40
const int * pos
Definition: combiners.h:905
static luaL_Reg func[]
Definition: except.c:32
#define realloc
Definition: glob.c:206
#define abs(a)
Definition: pbmplus.h:225
static int size
Definition: ppmlabel.c:24
static int cluster
Definition: ppmtopjxl.c:40
bstring c int memset(void *s, int c, int length)
#define flags
struct @1024 hb_min
static void hb_stable_sort(T *array, unsigned int len, int(*compar)(const T2 *, const T2 *), T3 *array2)
Definition: hb-algs.hh:943
static void * hb_memset(void *s, int c, unsigned int n)
Definition: hb-algs.hh:609
static bool hb_unsigned_mul_overflows(unsigned int count, unsigned int size)
Definition: hb-algs.hh:649
void hb_buffer_add_utf8(hb_buffer_t *buffer, const char *text, int text_length, unsigned int item_offset, int item_length)
Definition: hb-buffer.cc:1618
void hb_buffer_reset(hb_buffer_t *buffer)
Definition: hb-buffer.cc:1223
void hb_buffer_add_utf16(hb_buffer_t *buffer, const uint16_t *text, int text_length, unsigned int item_offset, int item_length)
Definition: hb-buffer.cc:1644
void hb_buffer_reverse(hb_buffer_t *buffer)
Definition: hb-buffer.cc:1460
hb_bool_t hb_buffer_set_user_data(hb_buffer_t *buffer, hb_user_data_key_t *key, void *data, hb_destroy_func_t destroy, hb_bool_t replace)
Definition: hb-buffer.cc:781
hb_glyph_flags_t() hb_glyph_info_get_glyph_flags(const hb_glyph_info_t *info)
Definition: hb-buffer.cc:1446
hb_bool_t hb_buffer_has_positions(hb_buffer_t *buffer)
Definition: hb-buffer.cc:1429
void hb_buffer_normalize_glyphs(hb_buffer_t *buffer)
Definition: hb-buffer.cc:1860
hb_codepoint_t hb_buffer_get_invisible_glyph(hb_buffer_t *buffer)
Definition: hb-buffer.cc:1207
void hb_buffer_set_script(hb_buffer_t *buffer, hb_script_t script)
Definition: hb-buffer.cc:948
hb_buffer_cluster_level_t hb_buffer_get_cluster_level(hb_buffer_t *buffer)
Definition: hb-buffer.cc:1126
hb_codepoint_t hb_buffer_get_replacement_codepoint(hb_buffer_t *buffer)
Definition: hb-buffer.cc:1167
void * hb_buffer_get_user_data(hb_buffer_t *buffer, hb_user_data_key_t *key)
Definition: hb-buffer.cc:803
void hb_buffer_set_invisible_glyph(hb_buffer_t *buffer, hb_codepoint_t invisible)
Definition: hb-buffer.cc:1186
void hb_buffer_set_replacement_codepoint(hb_buffer_t *buffer, hb_codepoint_t replacement)
Definition: hb-buffer.cc:1145
void hb_buffer_set_content_type(hb_buffer_t *buffer, hb_buffer_content_type_t content_type)
Definition: hb-buffer.cc:821
hb_bool_t hb_buffer_pre_allocate(hb_buffer_t *buffer, unsigned int size)
Definition: hb-buffer.cc:1256
hb_script_t hb_buffer_get_script(hb_buffer_t *buffer)
Definition: hb-buffer.cc:969
hb_buffer_content_type_t hb_buffer_get_content_type(hb_buffer_t *buffer)
Definition: hb-buffer.cc:840
void hb_buffer_clear_contents(hb_buffer_t *buffer)
Definition: hb-buffer.cc:1238
void hb_buffer_set_message_func(hb_buffer_t *buffer, hb_buffer_message_func_t func, void *user_data, hb_destroy_func_t destroy)
Definition: hb-buffer.cc:2006
hb_unicode_funcs_t * hb_buffer_get_unicode_funcs(hb_buffer_t *buffer)
Definition: hb-buffer.cc:882
void hb_buffer_get_segment_properties(hb_buffer_t *buffer, hb_segment_properties_t *props)
Definition: hb-buffer.cc:1049
void hb_buffer_guess_segment_properties(hb_buffer_t *buffer)
Definition: hb-buffer.cc:1527
static void normalize_glyphs_cluster(hb_buffer_t *buffer, unsigned int start, unsigned int end, bool backward)
Definition: hb-buffer.cc:1801
hb_buffer_t * hb_buffer_reference(hb_buffer_t *buffer)
Definition: hb-buffer.cc:734
static int compare_info_codepoint(const hb_glyph_info_t *pa, const hb_glyph_info_t *pb)
Definition: hb-buffer.cc:1794
void hb_buffer_append(hb_buffer_t *buffer, hb_buffer_t *source, unsigned int start, unsigned int end)
Definition: hb-buffer.cc:1753
void hb_buffer_set_segment_properties(hb_buffer_t *buffer, const hb_segment_properties_t *props)
Definition: hb-buffer.cc:1030
void hb_buffer_add_codepoints(hb_buffer_t *buffer, const hb_codepoint_t *text, int text_length, unsigned int item_offset, int item_length)
Definition: hb-buffer.cc:1731
void hb_buffer_add_latin1(hb_buffer_t *buffer, const uint8_t *text, int text_length, unsigned int item_offset, int item_length)
Definition: hb-buffer.cc:1697
hb_direction_t hb_buffer_get_direction(hb_buffer_t *buffer)
Definition: hb-buffer.cc:925
void hb_buffer_reverse_clusters(hb_buffer_t *buffer)
Definition: hb-buffer.cc:1493
unsigned int hb_segment_properties_hash(const hb_segment_properties_t *p)
Definition: hb-buffer.cc:82
unsigned int hb_buffer_get_length(hb_buffer_t *buffer)
Definition: hb-buffer.cc:1359
hb_buffer_t * hb_buffer_create()
Definition: hb-buffer.cc:691
void hb_buffer_add(hb_buffer_t *buffer, hb_codepoint_t codepoint, unsigned int cluster)
Definition: hb-buffer.cc:1296
void hb_buffer_add_utf32(hb_buffer_t *buffer, const uint32_t *text, int text_length, unsigned int item_offset, int item_length)
Definition: hb-buffer.cc:1670
void hb_buffer_set_flags(hb_buffer_t *buffer, hb_buffer_flags_t flags)
Definition: hb-buffer.cc:1066
void hb_buffer_set_language(hb_buffer_t *buffer, hb_language_t language)
Definition: hb-buffer.cc:992
hb_buffer_t * hb_buffer_get_empty()
Definition: hb-buffer.cc:716
hb_bool_t hb_segment_properties_equal(const hb_segment_properties_t *a, const hb_segment_properties_t *b)
Definition: hb-buffer.cc:59
void hb_buffer_set_direction(hb_buffer_t *buffer, hb_direction_t direction)
Definition: hb-buffer.cc:903
hb_buffer_flags_t hb_buffer_get_flags(hb_buffer_t *buffer)
Definition: hb-buffer.cc:1087
hb_glyph_position_t * hb_buffer_get_glyph_positions(hb_buffer_t *buffer, unsigned int *length)
Definition: hb-buffer.cc:1403
hb_buffer_diff_flags_t hb_buffer_diff(hb_buffer_t *buffer, hb_buffer_t *reference, hb_codepoint_t dottedcircle_glyph, unsigned int position_fuzz)
Definition: hb-buffer.cc:1912
hb_language_t hb_buffer_get_language(hb_buffer_t *buffer)
Definition: hb-buffer.cc:1013
hb_bool_t hb_buffer_set_length(hb_buffer_t *buffer, unsigned int length)
Definition: hb-buffer.cc:1318
void hb_buffer_destroy(hb_buffer_t *buffer)
Definition: hb-buffer.cc:750
void hb_buffer_set_cluster_level(hb_buffer_t *buffer, hb_buffer_cluster_level_t cluster_level)
Definition: hb-buffer.cc:1104
hb_bool_t hb_buffer_allocation_successful(hb_buffer_t *buffer)
Definition: hb-buffer.cc:1273
void hb_buffer_set_unicode_funcs(hb_buffer_t *buffer, hb_unicode_funcs_t *unicode_funcs)
Definition: hb-buffer.cc:857
void hb_buffer_reverse_range(hb_buffer_t *buffer, unsigned int start, unsigned int end)
Definition: hb-buffer.cc:1476
static void hb_buffer_add_utf(hb_buffer_t *buffer, const typename utf_t::codepoint_t *text, int text_length, unsigned int item_offset, int item_length)
Definition: hb-buffer.cc:1534
hb_glyph_info_t * hb_buffer_get_glyph_infos(hb_buffer_t *buffer, unsigned int *length)
Definition: hb-buffer.cc:1379
hb_glyph_flags_t
Definition: hb-buffer.h:95
@ HB_GLYPH_FLAG_DEFINED
Definition: hb-buffer.h:98
hb_buffer_cluster_level_t
Definition: hb-buffer.h:337
@ HB_BUFFER_CLUSTER_LEVEL_CHARACTERS
Definition: hb-buffer.h:340
@ HB_BUFFER_CLUSTER_LEVEL_DEFAULT
Definition: hb-buffer.h:341
#define HB_SEGMENT_PROPERTIES_DEFAULT
Definition: hb-buffer.h:153
#define HB_BUFFER_REPLACEMENT_CODEPOINT_DEFAULT
Definition: hb-buffer.h:359
hb_buffer_content_type_t
Definition: hb-buffer.h:207
@ HB_BUFFER_CONTENT_TYPE_GLYPHS
Definition: hb-buffer.h:210
@ HB_BUFFER_CONTENT_TYPE_UNICODE
Definition: hb-buffer.h:209
@ HB_BUFFER_CONTENT_TYPE_INVALID
Definition: hb-buffer.h:208
hb_buffer_flags_t
Definition: hb-buffer.h:293
@ HB_BUFFER_FLAG_DEFAULT
Definition: hb-buffer.h:294
hb_buffer_diff_flags_t
Definition: hb-buffer.h:582
@ HB_BUFFER_DIFF_FLAG_LENGTH_MISMATCH
Definition: hb-buffer.h:592
@ HB_BUFFER_DIFF_FLAG_NOTDEF_PRESENT
Definition: hb-buffer.h:597
@ HB_BUFFER_DIFF_FLAG_CLUSTER_MISMATCH
Definition: hb-buffer.h:603
@ HB_BUFFER_DIFF_FLAG_CONTENT_TYPE_MISMATCH
Definition: hb-buffer.h:587
@ HB_BUFFER_DIFF_FLAG_DOTTED_CIRCLE_PRESENT
Definition: hb-buffer.h:598
@ HB_BUFFER_DIFF_FLAG_CODEPOINT_MISMATCH
Definition: hb-buffer.h:602
@ HB_BUFFER_DIFF_FLAG_POSITION_MISMATCH
Definition: hb-buffer.h:605
@ HB_BUFFER_DIFF_FLAG_EQUAL
Definition: hb-buffer.h:583
@ HB_BUFFER_DIFF_FLAG_GLYPH_FLAGS_MISMATCH
Definition: hb-buffer.h:604
hb_bool_t(* hb_buffer_message_func_t)(hb_buffer_t *buffer, hb_font_t *font, const char *message, void *user_data)
Definition: hb-buffer.h:621
#define HB_BUFFER_MAX_OPS_DEFAULT
Definition: hb-buffer.hh:54
@ HB_BUFFER_SCRATCH_FLAG_DEFAULT
Definition: hb-buffer.hh:65
#define HB_BUFFER_MAX_LEN_DEFAULT
Definition: hb-buffer.hh:44
#define foreach_cluster(buffer, start, end)
Definition: hb-buffer.hh:455
hb_language_t hb_language_get_default()
Definition: hb-common.cc:415
hb_direction_t hb_script_get_horizontal_direction(hb_script_t script)
Definition: hb-common.cc:536
#define HB_LANGUAGE_INVALID
Definition: hb-common.h:274
void(* hb_destroy_func_t)(void *user_data)
Definition: hb-common.h:690
uint32_t hb_codepoint_t
Definition: hb-common.h:106
uint32_t hb_mask_t
Definition: hb-common.h:122
int32_t hb_position_t
Definition: hb-common.h:115
int hb_bool_t
Definition: hb-common.h:97
hb_script_t
Definition: hb-common.h:448
@ HB_SCRIPT_UNKNOWN
Definition: hb-common.h:451
@ HB_SCRIPT_COMMON
Definition: hb-common.h:449
@ HB_SCRIPT_INHERITED
Definition: hb-common.h:450
#define HB_DIRECTION_IS_BACKWARD(dir)
Definition: hb-common.h:252
hb_direction_t
Definition: hb-common.h:193
@ HB_DIRECTION_INVALID
Definition: hb-common.h:194
@ HB_DIRECTION_LTR
Definition: hb-common.h:195
#define HB_EXTERN
Definition: hb-common.h:37
#define Null(Type)
Definition: hb-null.hh:94
#define DEFINE_NULL_INSTANCE(Type)
Definition: hb-null.hh:121
static void * hb_object_get_user_data(Type *obj, hb_user_data_key_t *key)
Definition: hb-object.hh:329
#define HB_OBJECT_HEADER_STATIC
Definition: hb-object.hh:203
static bool hb_object_destroy(Type *obj)
Definition: hb-object.hh:274
static bool hb_object_is_immutable(const Type *obj)
Definition: hb-object.hh:254
static Type * hb_object_reference(Type *obj)
Definition: hb-object.hh:264
static bool hb_object_set_user_data(Type *obj, hb_user_data_key_t *key, void *data, hb_destroy_func_t destroy, hb_bool_t replace)
Definition: hb-object.hh:299
void hb_unicode_funcs_destroy(hb_unicode_funcs_t *ufuncs)
Definition: hb-unicode.cc:260
hb_unicode_funcs_t * hb_unicode_funcs_get_default()
Definition: hb-unicode.cc:152
const hb_unicode_funcs_t _hb_Null_hb_unicode_funcs_t
Definition: hb-unicode.cc:206
hb_unicode_funcs_t * hb_unicode_funcs_reference(hb_unicode_funcs_t *ufuncs)
Definition: hb-unicode.cc:244
#define mask(n)
Definition: lbitlib.c:93
static int codepoint(lua_State *L)
Definition: lutf8lib.c:100
#define direction(p, c)
Definition: sh12.c:109
Definition: utils.c:300
Definition: pbmfont.h:11
Definition: pbmfont.h:4
void reverse(unsigned start=0, unsigned end=-1)
Definition: hb-array.hh:184
unsigned int idx
Definition: hb-buffer.hh:108
hb_buffer_flags_t flags
Definition: hb-buffer.hh:92
hb_codepoint_t invisible
Definition: hb-buffer.hh:95
void reverse_clusters()
Definition: hb-buffer.cc:472
void deallocate_var_all()
Definition: hb-buffer.hh:173
void merge_out_clusters(unsigned int start, unsigned int end)
Definition: hb-buffer.cc:526
void sort(unsigned int start, unsigned int end, int(*compar)(const hb_glyph_info_t *, const hb_glyph_info_t *))
Definition: hb-buffer.cc:1873
void reverse_range(unsigned int start, unsigned int end)
Definition: hb-buffer.cc:449
hb_glyph_info_t * info
Definition: hb-buffer.hh:113
void clear()
Definition: hb-buffer.cc:234
unsigned int serial
Definition: hb-buffer.hh:117
void unsafe_to_break_impl(unsigned int start, unsigned int end)
Definition: hb-buffer.cc:593
hb_codepoint_t replacement
Definition: hb-buffer.hh:94
void reset()
Definition: hb-buffer.cc:219
unsigned int len
Definition: hb-buffer.hh:109
bool ensure(unsigned int size)
Definition: hb-buffer.hh:336
hb_buffer_scratch_flags_t scratch_flags
Definition: hb-buffer.hh:96
hb_segment_properties_t props
Definition: hb-buffer.hh:102
void guess_segment_properties()
Definition: hb-buffer.cc:619
void merge_clusters_impl(unsigned int start, unsigned int end)
Definition: hb-buffer.cc:495
hb_glyph_position_t * pos
Definition: hb-buffer.hh:115
hb_glyph_info_t * out_info
Definition: hb-buffer.hh:114
static void set_cluster(hb_glyph_info_t &inf, unsigned int cluster, unsigned int mask=0)
Definition: hb-buffer.hh:410
bool shift_forward(unsigned int count)
Definition: hb-buffer.cc:178
void unsafe_to_break_from_outbuffer(unsigned int start, unsigned int end)
Definition: hb-buffer.cc:600
long scratch_buffer_t
Definition: hb-buffer.hh:378
unsigned int max_len
Definition: hb-buffer.hh:97
bool have_positions
Definition: hb-buffer.hh:106
bool message_impl(hb_font_t *font, const char *fmt, va_list ap)
Definition: hb-buffer.cc:2024
void swap_buffers()
Definition: hb-buffer.cc:332
bool make_room_for(unsigned int num_in, unsigned int num_out)
Definition: hb-buffer.cc:160
unsigned int allocated
Definition: hb-buffer.hh:112
void clear_output()
Definition: hb-buffer.cc:304
hb_buffer_cluster_level_t cluster_level
Definition: hb-buffer.hh:93
void remove_output()
Definition: hb-buffer.cc:291
void reverse()
Definition: hb-buffer.cc:463
scratch_buffer_t * get_scratch_buffer(unsigned int *size)
Definition: hb-buffer.cc:201
hb_buffer_message_func_t message_func
Definition: hb-buffer.hh:128
bool enlarge(unsigned int size)
Definition: hb-buffer.cc:114
hb_buffer_content_type_t content_type
Definition: hb-buffer.hh:101
void unsafe_to_break(unsigned int start, unsigned int end)
Definition: hb-buffer.hh:320
void set_masks(hb_mask_t value, hb_mask_t mask, unsigned int cluster_start, unsigned int cluster_end)
Definition: hb-buffer.cc:431
unsigned int context_len[2]
Definition: hb-buffer.hh:124
void assert_unicode()
Definition: hb-buffer.hh:347
void _unsafe_to_break_set_mask(hb_glyph_info_t *infos, unsigned int start, unsigned int end, unsigned int cluster)
Definition: hb-buffer.hh:432
void * message_data
Definition: hb-buffer.hh:129
void clear_positions()
Definition: hb-buffer.cc:317
unsigned int _unsafe_to_break_find_min_cluster(const hb_glyph_info_t *infos, unsigned int start, unsigned int end, unsigned int cluster) const
Definition: hb-buffer.hh:423
hb_unicode_funcs_t * unicode
Definition: hb-buffer.hh:91
unsigned int out_len
Definition: hb-buffer.hh:110
void delete_glyph()
Definition: hb-buffer.cc:557
bool have_output
Definition: hb-buffer.hh:105
void merge_clusters(unsigned int start, unsigned int end)
Definition: hb-buffer.hh:309
void add(hb_codepoint_t codepoint, unsigned int cluster)
Definition: hb-buffer.cc:262
void skip_glyph()
Definition: hb-buffer.hh:295
void add_info(const hb_glyph_info_t &glyph_info)
Definition: hb-buffer.cc:280
void replace_glyphs(unsigned int num_in, unsigned int num_out, const hb_codepoint_t *glyph_data)
Definition: hb-buffer.cc:358
bool move_to(unsigned int i)
Definition: hb-buffer.cc:382
bool successful
Definition: hb-buffer.hh:104
hb_codepoint_t codepoint
Definition: hb-buffer.h:63
hb_mask_t mask
Definition: hb-buffer.h:65
uint32_t cluster
Definition: hb-buffer.h:67
hb_position_t y_offset
Definition: hb-buffer.h:128
hb_position_t y_advance
Definition: hb-buffer.h:126
hb_position_t x_advance
Definition: hb-buffer.h:125
hb_position_t x_offset
Definition: hb-buffer.h:127
hb_direction_t direction
Definition: hb-buffer.h:145
hb_language_t language
Definition: hb-buffer.h:147
hb_unicode_script_func_t script
Definition: hb-unicode.hh:248
Definition: sh.h:1345
Definition: dvips.h:235
int j
Definition: t4ht.c:1589
*job_name strlen((char *) job_name) - 4)
#define key
Definition: tex2xindy.c:753
char fmt[256]
Definition: tex4ht.c:3925
return() int(((double) *(font_tbl[cur_fnt].wtbl+(int)(*(font_tbl[cur_fnt].char_wi+(int)(ch - font_tbl[cur_fnt].char_f)% 256)))/(double)(1L<< 20)) *(double) font_tbl[cur_fnt].scale)
TT_Glyph glyph
Definition: ttf2pfb.c:162
Definition: obx.h:51
@ start
Definition: preamble.c:52
char * va_list
Definition: varargs.h:22
#define buffer
Definition: xmlparse.c:611
#define end(cp)
Definition: zic.c:71