Revert "[Tizen] [GPOS] Avoid O(n^2) behavior in mark-attachment"
[platform/upstream/harfbuzz.git] / src / hb-buffer.hh
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 #ifndef HB_BUFFER_HH
31 #define HB_BUFFER_HH
32
33 #include "hb.hh"
34 #include "hb-unicode.hh"
35
36
37 #ifndef HB_BUFFER_MAX_LEN_FACTOR
38 #define HB_BUFFER_MAX_LEN_FACTOR 64
39 #endif
40 #ifndef HB_BUFFER_MAX_LEN_MIN
41 #define HB_BUFFER_MAX_LEN_MIN 16384
42 #endif
43 #ifndef HB_BUFFER_MAX_LEN_DEFAULT
44 #define HB_BUFFER_MAX_LEN_DEFAULT 0x3FFFFFFF /* Shaping more than a billion chars? Let us know! */
45 #endif
46
47 #ifndef HB_BUFFER_MAX_OPS_FACTOR
48 #define HB_BUFFER_MAX_OPS_FACTOR 1024
49 #endif
50 #ifndef HB_BUFFER_MAX_OPS_MIN
51 #define HB_BUFFER_MAX_OPS_MIN 16384
52 #endif
53 #ifndef HB_BUFFER_MAX_OPS_DEFAULT
54 #define HB_BUFFER_MAX_OPS_DEFAULT 0x1FFFFFFF /* Shaping more than a billion operations? Let us know! */
55 #endif
56
57 static_assert ((sizeof (hb_glyph_info_t) == 20), "");
58 static_assert ((sizeof (hb_glyph_info_t) == sizeof (hb_glyph_position_t)), "");
59
60 HB_MARK_AS_FLAG_T (hb_buffer_flags_t);
61 HB_MARK_AS_FLAG_T (hb_buffer_serialize_flags_t);
62 HB_MARK_AS_FLAG_T (hb_buffer_diff_flags_t);
63
64 enum hb_buffer_scratch_flags_t {
65   HB_BUFFER_SCRATCH_FLAG_DEFAULT                        = 0x00000000u,
66   HB_BUFFER_SCRATCH_FLAG_HAS_NON_ASCII                  = 0x00000001u,
67   HB_BUFFER_SCRATCH_FLAG_HAS_DEFAULT_IGNORABLES         = 0x00000002u,
68   HB_BUFFER_SCRATCH_FLAG_HAS_SPACE_FALLBACK             = 0x00000004u,
69   HB_BUFFER_SCRATCH_FLAG_HAS_GPOS_ATTACHMENT            = 0x00000008u,
70   HB_BUFFER_SCRATCH_FLAG_HAS_CGJ                        = 0x00000010u,
71   HB_BUFFER_SCRATCH_FLAG_HAS_GLYPH_FLAGS                = 0x00000020u,
72
73   /* Reserved for complex shapers' internal use. */
74   HB_BUFFER_SCRATCH_FLAG_COMPLEX0                       = 0x01000000u,
75   HB_BUFFER_SCRATCH_FLAG_COMPLEX1                       = 0x02000000u,
76   HB_BUFFER_SCRATCH_FLAG_COMPLEX2                       = 0x04000000u,
77   HB_BUFFER_SCRATCH_FLAG_COMPLEX3                       = 0x08000000u,
78 };
79 HB_MARK_AS_FLAG_T (hb_buffer_scratch_flags_t);
80
81
82 /*
83  * hb_buffer_t
84  */
85
86 struct hb_buffer_t
87 {
88   hb_object_header_t header;
89
90   /*
91    * Information about how the text in the buffer should be treated.
92    */
93
94   hb_unicode_funcs_t *unicode; /* Unicode functions */
95   hb_buffer_flags_t flags; /* BOT / EOT / etc. */
96   hb_buffer_cluster_level_t cluster_level;
97   hb_codepoint_t replacement; /* U+FFFD or something else. */
98   hb_codepoint_t invisible; /* 0 or something else. */
99   hb_codepoint_t not_found; /* 0 or something else. */
100
101   /*
102    * Buffer contents
103    */
104
105   hb_buffer_content_type_t content_type;
106   hb_segment_properties_t props; /* Script, language, direction */
107
108   bool successful; /* Allocations successful */
109   bool have_output; /* Whether we have an output buffer going on */
110   bool have_positions; /* Whether we have positions */
111
112   unsigned int idx; /* Cursor into ->info and ->pos arrays */
113   unsigned int len; /* Length of ->info and ->pos arrays */
114   unsigned int out_len; /* Length of ->out_info array if have_output */
115
116   unsigned int allocated; /* Length of allocated arrays */
117   hb_glyph_info_t     *info;
118   hb_glyph_info_t     *out_info;
119   hb_glyph_position_t *pos;
120
121   /* Text before / after the main buffer contents.
122    * Always in Unicode, and ordered outward.
123    * Index 0 is for "pre-context", 1 for "post-context". */
124   static constexpr unsigned CONTEXT_LENGTH = 5u;
125   hb_codepoint_t context[2][CONTEXT_LENGTH];
126   unsigned int context_len[2];
127
128
129   /*
130    * Managed by enter / leave
131    */
132
133 #ifndef HB_NDEBUG
134   uint8_t allocated_var_bits;
135 #endif
136   uint8_t serial;
137   hb_buffer_scratch_flags_t scratch_flags; /* Have space-fallback, etc. */
138   unsigned int max_len; /* Maximum allowed len. */
139   int max_ops; /* Maximum allowed operations. */
140   /* The bits here reflect current allocations of the bytes in glyph_info_t's var1 and var2. */
141
142
143   /*
144    * Messaging callback
145    */
146
147 #ifndef HB_NO_BUFFER_MESSAGE
148   hb_buffer_message_func_t message_func;
149   void *message_data;
150   hb_destroy_func_t message_destroy;
151   unsigned message_depth; /* How deeply are we inside a message callback? */
152 #else
153   static constexpr unsigned message_depth = 0u;
154 #endif
155
156
157
158   /* Methods */
159
160   HB_NODISCARD bool in_error () const { return !successful; }
161
162   void allocate_var (unsigned int start, unsigned int count)
163   {
164 #ifndef HB_NDEBUG
165     unsigned int end = start + count;
166     assert (end <= 8);
167     unsigned int bits = (1u<<end) - (1u<<start);
168     assert (0 == (allocated_var_bits & bits));
169     allocated_var_bits |= bits;
170 #endif
171   }
172   void deallocate_var (unsigned int start, unsigned int count)
173   {
174 #ifndef HB_NDEBUG
175     unsigned int end = start + count;
176     assert (end <= 8);
177     unsigned int bits = (1u<<end) - (1u<<start);
178     assert (bits == (allocated_var_bits & bits));
179     allocated_var_bits &= ~bits;
180 #endif
181   }
182   void assert_var (unsigned int start, unsigned int count)
183   {
184 #ifndef HB_NDEBUG
185     unsigned int end = start + count;
186     assert (end <= 8);
187     unsigned int bits = (1u<<end) - (1u<<start);
188     assert (bits == (allocated_var_bits & bits));
189 #endif
190   }
191   void deallocate_var_all ()
192   {
193 #ifndef HB_NDEBUG
194     allocated_var_bits = 0;
195 #endif
196   }
197
198   hb_glyph_info_t &cur (unsigned int i = 0) { return info[idx + i]; }
199   hb_glyph_info_t cur (unsigned int i = 0) const { return info[idx + i]; }
200
201   hb_glyph_position_t &cur_pos (unsigned int i = 0) { return pos[idx + i]; }
202   hb_glyph_position_t cur_pos (unsigned int i = 0) const { return pos[idx + i]; }
203
204   hb_glyph_info_t &prev ()      { return out_info[out_len ? out_len - 1 : 0]; }
205   hb_glyph_info_t prev () const { return out_info[out_len ? out_len - 1 : 0]; }
206
207   HB_INTERNAL void similar (const hb_buffer_t &src);
208   HB_INTERNAL void reset ();
209   HB_INTERNAL void clear ();
210
211   /* Called around shape() */
212   HB_INTERNAL void enter ();
213   HB_INTERNAL void leave ();
214
215 #ifndef HB_NO_BUFFER_VERIFY
216   HB_INTERNAL
217 #endif
218   bool verify (hb_buffer_t        *text_buffer,
219                hb_font_t          *font,
220                const hb_feature_t *features,
221                unsigned int        num_features,
222                const char * const *shapers)
223 #ifndef HB_NO_BUFFER_VERIFY
224   ;
225 #else
226   { return true; }
227 #endif
228
229   unsigned int backtrack_len () const { return have_output ? out_len : idx; }
230   unsigned int lookahead_len () const { return len - idx; }
231   uint8_t next_serial () { return ++serial ? serial : ++serial; }
232
233   HB_INTERNAL void add (hb_codepoint_t  codepoint,
234                         unsigned int    cluster);
235   HB_INTERNAL void add_info (const hb_glyph_info_t &glyph_info);
236
237   void reverse_range (unsigned start, unsigned end)
238   {
239     hb_array_t<hb_glyph_info_t> (info, len).reverse (start, end);
240     if (have_positions)
241       hb_array_t<hb_glyph_position_t> (pos, len).reverse (start, end);
242   }
243   void reverse () { reverse_range (0, len); }
244
245   template <typename FuncType>
246   void reverse_groups (const FuncType& group,
247                        bool merge_clusters = false)
248   {
249     if (unlikely (!len))
250       return;
251
252     unsigned start = 0;
253     unsigned i;
254     for (i = 1; i < len; i++)
255     {
256       if (!group (info[i - 1], info[i]))
257       {
258         if (merge_clusters)
259           this->merge_clusters (start, i);
260         reverse_range (start, i);
261         start = i;
262       }
263     }
264     if (merge_clusters)
265       this->merge_clusters (start, i);
266     reverse_range (start, i);
267
268     reverse ();
269   }
270
271   template <typename FuncType>
272   unsigned group_end (unsigned start, const FuncType& group) const
273   {
274     while (++start < len && group (info[start - 1], info[start]))
275       ;
276
277     return start;
278   }
279
280   static bool _cluster_group_func (const hb_glyph_info_t& a,
281                                    const hb_glyph_info_t& b)
282   { return a.cluster == b.cluster; }
283
284   void reverse_clusters () { reverse_groups (_cluster_group_func); }
285
286   HB_INTERNAL void guess_segment_properties ();
287
288   HB_INTERNAL void sync ();
289   HB_INTERNAL void clear_output ();
290   HB_INTERNAL void clear_positions ();
291
292   template <typename T>
293   HB_NODISCARD bool replace_glyphs (unsigned int num_in,
294                                     unsigned int num_out,
295                                     const T *glyph_data)
296   {
297     if (unlikely (!make_room_for (num_in, num_out))) return false;
298
299     assert (idx + num_in <= len);
300
301     merge_clusters (idx, idx + num_in);
302
303     hb_glyph_info_t &orig_info = idx < len ? cur() : prev();
304
305     hb_glyph_info_t *pinfo = &out_info[out_len];
306     for (unsigned int i = 0; i < num_out; i++)
307     {
308       *pinfo = orig_info;
309       pinfo->codepoint = glyph_data[i];
310       pinfo++;
311     }
312
313     idx  += num_in;
314     out_len += num_out;
315     return true;
316   }
317
318   HB_NODISCARD bool replace_glyph (hb_codepoint_t glyph_index)
319   { return replace_glyphs (1, 1, &glyph_index); }
320
321   /* Makes a copy of the glyph at idx to output and replace glyph_index */
322   HB_NODISCARD bool output_glyph (hb_codepoint_t glyph_index)
323   { return replace_glyphs (0, 1, &glyph_index); }
324
325   HB_NODISCARD bool output_info (const hb_glyph_info_t &glyph_info)
326   {
327     if (unlikely (!make_room_for (0, 1))) return false;
328
329     out_info[out_len] = glyph_info;
330
331     out_len++;
332     return true;
333   }
334   /* Copies glyph at idx to output but doesn't advance idx */
335   HB_NODISCARD bool copy_glyph ()
336   {
337     /* Extra copy because cur()'s return can be freed within
338      * output_info() call if buffer reallocates. */
339     return output_info (hb_glyph_info_t (cur()));
340   }
341
342   /* Copies glyph at idx to output and advance idx.
343    * If there's no output, just advance idx. */
344   HB_NODISCARD bool next_glyph ()
345   {
346     if (have_output)
347     {
348       if (out_info != info || out_len != idx)
349       {
350         if (unlikely (!make_room_for (1, 1))) return false;
351         out_info[out_len] = info[idx];
352       }
353       out_len++;
354     }
355
356     idx++;
357     return true;
358   }
359   /* Copies n glyphs at idx to output and advance idx.
360    * If there's no output, just advance idx. */
361   HB_NODISCARD bool next_glyphs (unsigned int n)
362   {
363     if (have_output)
364     {
365       if (out_info != info || out_len != idx)
366       {
367         if (unlikely (!make_room_for (n, n))) return false;
368         memmove (out_info + out_len, info + idx, n * sizeof (out_info[0]));
369       }
370       out_len += n;
371     }
372
373     idx += n;
374     return true;
375   }
376   /* Advance idx without copying to output. */
377   void skip_glyph () { idx++; }
378   void reset_masks (hb_mask_t mask)
379   {
380     for (unsigned int j = 0; j < len; j++)
381       info[j].mask = mask;
382   }
383   void add_masks (hb_mask_t mask)
384   {
385     for (unsigned int j = 0; j < len; j++)
386       info[j].mask |= mask;
387   }
388   HB_INTERNAL void set_masks (hb_mask_t value, hb_mask_t mask,
389                               unsigned int cluster_start, unsigned int cluster_end);
390
391   void merge_clusters (unsigned int start, unsigned int end)
392   {
393     if (end - start < 2)
394       return;
395     merge_clusters_impl (start, end);
396   }
397   HB_INTERNAL void merge_clusters_impl (unsigned int start, unsigned int end);
398   HB_INTERNAL void merge_out_clusters (unsigned int start, unsigned int end);
399   /* Merge clusters for deleting current glyph, and skip it. */
400   HB_INTERNAL void delete_glyph ();
401
402
403   /* Adds glyph flags in mask to infos with clusters between start and end.
404    * The start index will be from out-buffer if from_out_buffer is true.
405    * If interior is true, then the cluster having the minimum value is skipped. */
406   void _set_glyph_flags (hb_mask_t mask,
407                          unsigned start = 0,
408                          unsigned end = (unsigned) -1,
409                          bool interior = false,
410                          bool from_out_buffer = false)
411   {
412     end = hb_min (end, len);
413
414     if (interior && !from_out_buffer && end - start < 2)
415       return;
416
417     scratch_flags |= HB_BUFFER_SCRATCH_FLAG_HAS_GLYPH_FLAGS;
418
419     if (!from_out_buffer || !have_output)
420     {
421       if (!interior)
422       {
423         for (unsigned i = start; i < end; i++)
424           info[i].mask |= mask;
425       }
426       else
427       {
428         unsigned cluster = _infos_find_min_cluster (info, start, end);
429         _infos_set_glyph_flags (info, start, end, cluster, mask);
430       }
431     }
432     else
433     {
434       assert (start <= out_len);
435       assert (idx <= end);
436
437       if (!interior)
438       {
439         for (unsigned i = start; i < out_len; i++)
440           out_info[i].mask |= mask;
441         for (unsigned i = idx; i < end; i++)
442           info[i].mask |= mask;
443       }
444       else
445       {
446         unsigned cluster = _infos_find_min_cluster (info, idx, end);
447         cluster = _infos_find_min_cluster (out_info, start, out_len, cluster);
448
449         _infos_set_glyph_flags (out_info, start, out_len, cluster, mask);
450         _infos_set_glyph_flags (info, idx, end, cluster, mask);
451       }
452     }
453   }
454
455   void unsafe_to_break (unsigned int start = 0, unsigned int end = -1)
456   {
457     _set_glyph_flags (HB_GLYPH_FLAG_UNSAFE_TO_BREAK | HB_GLYPH_FLAG_UNSAFE_TO_CONCAT,
458                       start, end,
459                       true);
460   }
461   void unsafe_to_concat (unsigned int start = 0, unsigned int end = -1)
462   {
463     _set_glyph_flags (HB_GLYPH_FLAG_UNSAFE_TO_CONCAT,
464                       start, end,
465                       true);
466   }
467   void unsafe_to_break_from_outbuffer (unsigned int start = 0, unsigned int end = -1)
468   {
469     _set_glyph_flags (HB_GLYPH_FLAG_UNSAFE_TO_BREAK | HB_GLYPH_FLAG_UNSAFE_TO_CONCAT,
470                       start, end,
471                       true, true);
472   }
473   void unsafe_to_concat_from_outbuffer (unsigned int start = 0, unsigned int end = -1)
474   {
475     _set_glyph_flags (HB_GLYPH_FLAG_UNSAFE_TO_CONCAT,
476                       start, end,
477                       false, true);
478   }
479
480
481   /* Internal methods */
482   HB_NODISCARD HB_INTERNAL bool move_to (unsigned int i); /* i is output-buffer index. */
483
484   HB_NODISCARD HB_INTERNAL bool enlarge (unsigned int size);
485
486   HB_NODISCARD bool ensure (unsigned int size)
487   { return likely (!size || size < allocated) ? true : enlarge (size); }
488
489   HB_NODISCARD bool ensure_inplace (unsigned int size)
490   { return likely (!size || size < allocated); }
491
492   void assert_glyphs ()
493   {
494     assert ((content_type == HB_BUFFER_CONTENT_TYPE_GLYPHS) ||
495             (!len && (content_type == HB_BUFFER_CONTENT_TYPE_INVALID)));
496   }
497   void assert_unicode ()
498   {
499     assert ((content_type == HB_BUFFER_CONTENT_TYPE_UNICODE) ||
500             (!len && (content_type == HB_BUFFER_CONTENT_TYPE_INVALID)));
501   }
502   HB_NODISCARD bool ensure_glyphs ()
503   {
504     if (unlikely (content_type != HB_BUFFER_CONTENT_TYPE_GLYPHS))
505     {
506       if (content_type != HB_BUFFER_CONTENT_TYPE_INVALID)
507         return false;
508       assert (len == 0);
509       content_type = HB_BUFFER_CONTENT_TYPE_GLYPHS;
510     }
511     return true;
512   }
513   HB_NODISCARD bool ensure_unicode ()
514   {
515     if (unlikely (content_type != HB_BUFFER_CONTENT_TYPE_UNICODE))
516     {
517       if (content_type != HB_BUFFER_CONTENT_TYPE_INVALID)
518         return false;
519       assert (len == 0);
520       content_type = HB_BUFFER_CONTENT_TYPE_UNICODE;
521     }
522     return true;
523   }
524
525   HB_NODISCARD HB_INTERNAL bool make_room_for (unsigned int num_in, unsigned int num_out);
526   HB_NODISCARD HB_INTERNAL bool shift_forward (unsigned int count);
527
528   typedef long scratch_buffer_t;
529   HB_INTERNAL scratch_buffer_t *get_scratch_buffer (unsigned int *size);
530
531   void clear_context (unsigned int side) { context_len[side] = 0; }
532
533   HB_INTERNAL void sort (unsigned int start, unsigned int end, int(*compar)(const hb_glyph_info_t *, const hb_glyph_info_t *));
534
535   bool messaging ()
536   {
537 #ifdef HB_NO_BUFFER_MESSAGE
538     return false;
539 #else
540     return unlikely (message_func);
541 #endif
542   }
543   bool message (hb_font_t *font, const char *fmt, ...) HB_PRINTF_FUNC(3, 4)
544   {
545 #ifdef HB_NO_BUFFER_MESSAGE
546    return true;
547 #else
548     if (!messaging ())
549       return true;
550
551     message_depth++;
552
553     va_list ap;
554     va_start (ap, fmt);
555     bool ret = message_impl (font, fmt, ap);
556     va_end (ap);
557
558     message_depth--;
559
560     return ret;
561 #endif
562   }
563   HB_INTERNAL bool message_impl (hb_font_t *font, const char *fmt, va_list ap) HB_PRINTF_FUNC(3, 0);
564
565   static void
566   set_cluster (hb_glyph_info_t &inf, unsigned int cluster, unsigned int mask = 0)
567   {
568     if (inf.cluster != cluster)
569       inf.mask = (inf.mask & ~HB_GLYPH_FLAG_DEFINED) | (mask & HB_GLYPH_FLAG_DEFINED);
570     inf.cluster = cluster;
571   }
572   void
573   _infos_set_glyph_flags (hb_glyph_info_t *infos,
574                           unsigned int start, unsigned int end,
575                           unsigned int cluster,
576                           hb_mask_t mask)
577   {
578     for (unsigned int i = start; i < end; i++)
579       if (cluster != infos[i].cluster)
580       {
581         scratch_flags |= HB_BUFFER_SCRATCH_FLAG_HAS_GLYPH_FLAGS;
582         infos[i].mask |= mask;
583       }
584   }
585   static unsigned
586   _infos_find_min_cluster (const hb_glyph_info_t *infos,
587                            unsigned start, unsigned end,
588                            unsigned cluster = UINT_MAX)
589   {
590     for (unsigned int i = start; i < end; i++)
591       cluster = hb_min (cluster, infos[i].cluster);
592     return cluster;
593   }
594
595   void clear_glyph_flags (hb_mask_t mask = 0)
596   {
597     for (unsigned int i = 0; i < len; i++)
598       info[i].mask = (info[i].mask & ~HB_GLYPH_FLAG_DEFINED) | (mask & HB_GLYPH_FLAG_DEFINED);
599   }
600 };
601 DECLARE_NULL_INSTANCE (hb_buffer_t);
602
603
604 #define foreach_group(buffer, start, end, group_func) \
605   for (unsigned int \
606        _count = buffer->len, \
607        start = 0, end = _count ? buffer->group_end (0, group_func) : 0; \
608        start < _count; \
609        start = end, end = buffer->group_end (start, group_func))
610
611 #define foreach_cluster(buffer, start, end) \
612         foreach_group (buffer, start, end, hb_buffer_t::_cluster_group_func)
613
614
615 #define HB_BUFFER_XALLOCATE_VAR(b, func, var) \
616   b->func (offsetof (hb_glyph_info_t, var) - offsetof(hb_glyph_info_t, var1), \
617            sizeof (b->info[0].var))
618 #define HB_BUFFER_ALLOCATE_VAR(b, var)          HB_BUFFER_XALLOCATE_VAR (b, allocate_var,   var ())
619 #define HB_BUFFER_DEALLOCATE_VAR(b, var)        HB_BUFFER_XALLOCATE_VAR (b, deallocate_var, var ())
620 #define HB_BUFFER_ASSERT_VAR(b, var)            HB_BUFFER_XALLOCATE_VAR (b, assert_var,     var ())
621
622
623 #endif /* HB_BUFFER_HH */