src/java.desktop/share/native/libfontmanager/harfbuzz/hb-buffer-private.hh
branchniosocketimpl-branch
changeset 57278 bf925a3ee68a
parent 57277 d2b2a4edbfe7
parent 54246 f04e3492fd88
child 57279 7ac883a2d8f5
equal deleted inserted replaced
57277:d2b2a4edbfe7 57278:bf925a3ee68a
     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_PRIVATE_HH
       
    31 #define HB_BUFFER_PRIVATE_HH
       
    32 
       
    33 #include "hb-private.hh"
       
    34 #include "hb-object-private.hh"
       
    35 #include "hb-unicode-private.hh"
       
    36 
       
    37 
       
    38 #ifndef HB_BUFFER_MAX_LEN_FACTOR
       
    39 #define HB_BUFFER_MAX_LEN_FACTOR 32
       
    40 #endif
       
    41 #ifndef HB_BUFFER_MAX_LEN_MIN
       
    42 #define HB_BUFFER_MAX_LEN_MIN 8192
       
    43 #endif
       
    44 #ifndef HB_BUFFER_MAX_LEN_DEFAULT
       
    45 #define HB_BUFFER_MAX_LEN_DEFAULT 0x3FFFFFFF /* Shaping more than a billion chars? Let us know! */
       
    46 #endif
       
    47 
       
    48 #ifndef HB_BUFFER_MAX_OPS_FACTOR
       
    49 #define HB_BUFFER_MAX_OPS_FACTOR 64
       
    50 #endif
       
    51 #ifndef HB_BUFFER_MAX_OPS_MIN
       
    52 #define HB_BUFFER_MAX_OPS_MIN 1024
       
    53 #endif
       
    54 #ifndef HB_BUFFER_MAX_OPS_DEFAULT
       
    55 #define HB_BUFFER_MAX_OPS_DEFAULT 0x1FFFFFFF /* Shaping more than a billion operations? Let us know! */
       
    56 #endif
       
    57 
       
    58 static_assert ((sizeof (hb_glyph_info_t) == 20), "");
       
    59 static_assert ((sizeof (hb_glyph_info_t) == sizeof (hb_glyph_position_t)), "");
       
    60 
       
    61 HB_MARK_AS_FLAG_T (hb_buffer_flags_t);
       
    62 HB_MARK_AS_FLAG_T (hb_buffer_serialize_flags_t);
       
    63 HB_MARK_AS_FLAG_T (hb_buffer_diff_flags_t);
       
    64 
       
    65 enum hb_buffer_scratch_flags_t {
       
    66   HB_BUFFER_SCRATCH_FLAG_DEFAULT                        = 0x00000000u,
       
    67   HB_BUFFER_SCRATCH_FLAG_HAS_NON_ASCII                  = 0x00000001u,
       
    68   HB_BUFFER_SCRATCH_FLAG_HAS_DEFAULT_IGNORABLES         = 0x00000002u,
       
    69   HB_BUFFER_SCRATCH_FLAG_HAS_SPACE_FALLBACK             = 0x00000004u,
       
    70   HB_BUFFER_SCRATCH_FLAG_HAS_GPOS_ATTACHMENT            = 0x00000008u,
       
    71   HB_BUFFER_SCRATCH_FLAG_HAS_UNSAFE_TO_BREAK            = 0x00000010u,
       
    72   HB_BUFFER_SCRATCH_FLAG_HAS_CGJ                        = 0x00000020u,
       
    73 
       
    74   /* Reserved for complex shapers' internal use. */
       
    75   HB_BUFFER_SCRATCH_FLAG_COMPLEX0                       = 0x01000000u,
       
    76   HB_BUFFER_SCRATCH_FLAG_COMPLEX1                       = 0x02000000u,
       
    77   HB_BUFFER_SCRATCH_FLAG_COMPLEX2                       = 0x04000000u,
       
    78   HB_BUFFER_SCRATCH_FLAG_COMPLEX3                       = 0x08000000u,
       
    79 };
       
    80 HB_MARK_AS_FLAG_T (hb_buffer_scratch_flags_t);
       
    81 
       
    82 
       
    83 /*
       
    84  * hb_buffer_t
       
    85  */
       
    86 
       
    87 struct hb_buffer_t {
       
    88   hb_object_header_t header;
       
    89   ASSERT_POD ();
       
    90 
       
    91   /* Information about how the text in the buffer should be treated */
       
    92   hb_unicode_funcs_t *unicode; /* Unicode functions */
       
    93   hb_buffer_flags_t flags; /* BOT / EOT / etc. */
       
    94   hb_buffer_cluster_level_t cluster_level;
       
    95   hb_codepoint_t replacement; /* U+FFFD or something else. */
       
    96   hb_buffer_scratch_flags_t scratch_flags; /* Have space-fallback, etc. */
       
    97   unsigned int max_len; /* Maximum allowed len. */
       
    98   int max_ops; /* Maximum allowed operations. */
       
    99 
       
   100   /* Buffer contents */
       
   101   hb_buffer_content_type_t content_type;
       
   102   hb_segment_properties_t props; /* Script, language, direction */
       
   103 
       
   104   bool successful; /* Allocations successful */
       
   105   bool have_output; /* Whether we have an output buffer going on */
       
   106   bool have_positions; /* Whether we have positions */
       
   107 
       
   108   unsigned int idx; /* Cursor into ->info and ->pos arrays */
       
   109   unsigned int len; /* Length of ->info and ->pos arrays */
       
   110   unsigned int out_len; /* Length of ->out array if have_output */
       
   111 
       
   112   unsigned int allocated; /* Length of allocated arrays */
       
   113   hb_glyph_info_t     *info;
       
   114   hb_glyph_info_t     *out_info;
       
   115   hb_glyph_position_t *pos;
       
   116 
       
   117   unsigned int serial;
       
   118 
       
   119   /* Text before / after the main buffer contents.
       
   120    * Always in Unicode, and ordered outward.
       
   121    * Index 0 is for "pre-context", 1 for "post-context". */
       
   122   static const unsigned int CONTEXT_LENGTH = 5;
       
   123   hb_codepoint_t context[2][CONTEXT_LENGTH];
       
   124   unsigned int context_len[2];
       
   125 
       
   126   /* Debugging API */
       
   127   hb_buffer_message_func_t message_func;
       
   128   void *message_data;
       
   129   hb_destroy_func_t message_destroy;
       
   130 
       
   131   /* Internal debugging. */
       
   132   /* The bits here reflect current allocations of the bytes in glyph_info_t's var1 and var2. */
       
   133 #ifndef HB_NDEBUG
       
   134   uint8_t allocated_var_bits;
       
   135 #endif
       
   136 
       
   137 
       
   138   /* Methods */
       
   139 
       
   140   inline void allocate_var (unsigned int start, unsigned int count)
       
   141   {
       
   142 #ifndef HB_NDEBUG
       
   143     unsigned int end = start + count;
       
   144     assert (end <= 8);
       
   145     unsigned int bits = (1u<<end) - (1u<<start);
       
   146     assert (0 == (allocated_var_bits & bits));
       
   147     allocated_var_bits |= bits;
       
   148 #endif
       
   149   }
       
   150   inline void deallocate_var (unsigned int start, unsigned int count)
       
   151   {
       
   152 #ifndef HB_NDEBUG
       
   153     unsigned int end = start + count;
       
   154     assert (end <= 8);
       
   155     unsigned int bits = (1u<<end) - (1u<<start);
       
   156     assert (bits == (allocated_var_bits & bits));
       
   157     allocated_var_bits &= ~bits;
       
   158 #endif
       
   159   }
       
   160   inline void assert_var (unsigned int start, unsigned int count)
       
   161   {
       
   162 #ifndef HB_NDEBUG
       
   163     unsigned int end = start + count;
       
   164     assert (end <= 8);
       
   165     unsigned int bits = (1u<<end) - (1u<<start);
       
   166     assert (bits == (allocated_var_bits & bits));
       
   167 #endif
       
   168   }
       
   169   inline void deallocate_var_all (void)
       
   170   {
       
   171 #ifndef HB_NDEBUG
       
   172     allocated_var_bits = 0;
       
   173 #endif
       
   174   }
       
   175 
       
   176   inline hb_glyph_info_t &cur (unsigned int i = 0) { return info[idx + i]; }
       
   177   inline hb_glyph_info_t cur (unsigned int i = 0) const { return info[idx + i]; }
       
   178 
       
   179   inline hb_glyph_position_t &cur_pos (unsigned int i = 0) { return pos[idx + i]; }
       
   180   inline hb_glyph_position_t cur_pos (unsigned int i = 0) const { return pos[idx + i]; }
       
   181 
       
   182   inline hb_glyph_info_t &prev (void) { return out_info[out_len ? out_len - 1 : 0]; }
       
   183   inline hb_glyph_info_t prev (void) const { return out_info[out_len ? out_len - 1 : 0]; }
       
   184 
       
   185   inline bool has_separate_output (void) const { return info != out_info; }
       
   186 
       
   187 
       
   188   HB_INTERNAL void reset (void);
       
   189   HB_INTERNAL void clear (void);
       
   190 
       
   191   inline unsigned int backtrack_len (void) const
       
   192   { return have_output? out_len : idx; }
       
   193   inline unsigned int lookahead_len (void) const
       
   194   { return len - idx; }
       
   195   inline unsigned int next_serial (void) { return serial++; }
       
   196 
       
   197   HB_INTERNAL void add (hb_codepoint_t  codepoint,
       
   198                         unsigned int    cluster);
       
   199   HB_INTERNAL void add_info (const hb_glyph_info_t &glyph_info);
       
   200 
       
   201   HB_INTERNAL void reverse_range (unsigned int start, unsigned int end);
       
   202   HB_INTERNAL void reverse (void);
       
   203   HB_INTERNAL void reverse_clusters (void);
       
   204   HB_INTERNAL void guess_segment_properties (void);
       
   205 
       
   206   HB_INTERNAL void swap_buffers (void);
       
   207   HB_INTERNAL void remove_output (void);
       
   208   HB_INTERNAL void clear_output (void);
       
   209   HB_INTERNAL void clear_positions (void);
       
   210 
       
   211   HB_INTERNAL void replace_glyphs (unsigned int num_in,
       
   212                                    unsigned int num_out,
       
   213                                    const hb_codepoint_t *glyph_data);
       
   214 
       
   215   HB_INTERNAL void replace_glyph (hb_codepoint_t glyph_index);
       
   216   /* Makes a copy of the glyph at idx to output and replace glyph_index */
       
   217   HB_INTERNAL void output_glyph (hb_codepoint_t glyph_index);
       
   218   HB_INTERNAL void output_info (const hb_glyph_info_t &glyph_info);
       
   219   /* Copies glyph at idx to output but doesn't advance idx */
       
   220   HB_INTERNAL void copy_glyph (void);
       
   221   HB_INTERNAL bool move_to (unsigned int i); /* i is output-buffer index. */
       
   222   /* Copies glyph at idx to output and advance idx.
       
   223    * If there's no output, just advance idx. */
       
   224   inline void
       
   225   next_glyph (void)
       
   226   {
       
   227     if (have_output)
       
   228     {
       
   229       if (unlikely (out_info != info || out_len != idx)) {
       
   230         if (unlikely (!make_room_for (1, 1))) return;
       
   231         out_info[out_len] = info[idx];
       
   232       }
       
   233       out_len++;
       
   234     }
       
   235 
       
   236     idx++;
       
   237   }
       
   238 
       
   239   /* Advance idx without copying to output. */
       
   240   inline void skip_glyph (void) { idx++; }
       
   241 
       
   242   inline void reset_masks (hb_mask_t mask)
       
   243   {
       
   244     for (unsigned int j = 0; j < len; j++)
       
   245       info[j].mask = mask;
       
   246   }
       
   247   inline void add_masks (hb_mask_t mask)
       
   248   {
       
   249     for (unsigned int j = 0; j < len; j++)
       
   250       info[j].mask |= mask;
       
   251   }
       
   252   HB_INTERNAL void set_masks (hb_mask_t value, hb_mask_t mask,
       
   253                               unsigned int cluster_start, unsigned int cluster_end);
       
   254 
       
   255   inline void merge_clusters (unsigned int start, unsigned int end)
       
   256   {
       
   257     if (end - start < 2)
       
   258       return;
       
   259     merge_clusters_impl (start, end);
       
   260   }
       
   261   HB_INTERNAL void merge_clusters_impl (unsigned int start, unsigned int end);
       
   262   HB_INTERNAL void merge_out_clusters (unsigned int start, unsigned int end);
       
   263   /* Merge clusters for deleting current glyph, and skip it. */
       
   264   HB_INTERNAL void delete_glyph (void);
       
   265 
       
   266   inline void unsafe_to_break (unsigned int start,
       
   267                                unsigned int end)
       
   268   {
       
   269     if (end - start < 2)
       
   270       return;
       
   271     unsafe_to_break_impl (start, end);
       
   272   }
       
   273   HB_INTERNAL void unsafe_to_break_impl (unsigned int start, unsigned int end);
       
   274   HB_INTERNAL void unsafe_to_break_from_outbuffer (unsigned int start, unsigned int end);
       
   275 
       
   276 
       
   277   /* Internal methods */
       
   278   HB_INTERNAL bool enlarge (unsigned int size);
       
   279 
       
   280   inline bool ensure (unsigned int size)
       
   281   { return likely (!size || size < allocated) ? true : enlarge (size); }
       
   282 
       
   283   inline bool ensure_inplace (unsigned int size)
       
   284   { return likely (!size || size < allocated); }
       
   285 
       
   286   HB_INTERNAL bool make_room_for (unsigned int num_in, unsigned int num_out);
       
   287   HB_INTERNAL bool shift_forward (unsigned int count);
       
   288 
       
   289   typedef long scratch_buffer_t;
       
   290   HB_INTERNAL scratch_buffer_t *get_scratch_buffer (unsigned int *size);
       
   291 
       
   292   inline void clear_context (unsigned int side) { context_len[side] = 0; }
       
   293 
       
   294   HB_INTERNAL void sort (unsigned int start, unsigned int end, int(*compar)(const hb_glyph_info_t *, const hb_glyph_info_t *));
       
   295 
       
   296   inline bool messaging (void) { return unlikely (message_func); }
       
   297   inline bool message (hb_font_t *font, const char *fmt, ...) HB_PRINTF_FUNC(3, 4)
       
   298   {
       
   299     if (!messaging ())
       
   300       return true;
       
   301     va_list ap;
       
   302     va_start (ap, fmt);
       
   303     bool ret = message_impl (font, fmt, ap);
       
   304     va_end (ap);
       
   305     return ret;
       
   306   }
       
   307   HB_INTERNAL bool message_impl (hb_font_t *font, const char *fmt, va_list ap) HB_PRINTF_FUNC(3, 0);
       
   308 
       
   309   static inline void
       
   310   set_cluster (hb_glyph_info_t &inf, unsigned int cluster, unsigned int mask = 0)
       
   311   {
       
   312     if (inf.cluster != cluster)
       
   313     {
       
   314       if (mask & HB_GLYPH_FLAG_UNSAFE_TO_BREAK)
       
   315         inf.mask |= HB_GLYPH_FLAG_UNSAFE_TO_BREAK;
       
   316       else
       
   317         inf.mask &= ~HB_GLYPH_FLAG_UNSAFE_TO_BREAK;
       
   318     }
       
   319     inf.cluster = cluster;
       
   320   }
       
   321 
       
   322   inline int
       
   323   _unsafe_to_break_find_min_cluster (const hb_glyph_info_t *infos,
       
   324                                      unsigned int start, unsigned int end,
       
   325                                      unsigned int cluster) const
       
   326   {
       
   327     for (unsigned int i = start; i < end; i++)
       
   328       cluster = MIN<unsigned int> (cluster, infos[i].cluster);
       
   329     return cluster;
       
   330   }
       
   331   inline void
       
   332   _unsafe_to_break_set_mask (hb_glyph_info_t *infos,
       
   333                              unsigned int start, unsigned int end,
       
   334                              unsigned int cluster)
       
   335   {
       
   336     for (unsigned int i = start; i < end; i++)
       
   337       if (cluster != infos[i].cluster)
       
   338       {
       
   339         scratch_flags |= HB_BUFFER_SCRATCH_FLAG_HAS_UNSAFE_TO_BREAK;
       
   340         infos[i].mask |= HB_GLYPH_FLAG_UNSAFE_TO_BREAK;
       
   341       }
       
   342   }
       
   343 
       
   344   inline void
       
   345   unsafe_to_break_all (void)
       
   346   {
       
   347     unsafe_to_break_impl (0, len);
       
   348   }
       
   349   inline void
       
   350   safe_to_break_all (void)
       
   351   {
       
   352     for (unsigned int i = 0; i < len; i++)
       
   353       info[i].mask &= ~HB_GLYPH_FLAG_UNSAFE_TO_BREAK;
       
   354   }
       
   355 };
       
   356 
       
   357 
       
   358 /* Loop over clusters. Duplicated in foreach_syllable(). */
       
   359 #define foreach_cluster(buffer, start, end) \
       
   360   for (unsigned int \
       
   361        _count = buffer->len, \
       
   362        start = 0, end = _count ? _next_cluster (buffer, 0) : 0; \
       
   363        start < _count; \
       
   364        start = end, end = _next_cluster (buffer, start))
       
   365 
       
   366 static inline unsigned int
       
   367 _next_cluster (hb_buffer_t *buffer, unsigned int start)
       
   368 {
       
   369   hb_glyph_info_t *info = buffer->info;
       
   370   unsigned int count = buffer->len;
       
   371 
       
   372   unsigned int cluster = info[start].cluster;
       
   373   while (++start < count && cluster == info[start].cluster)
       
   374     ;
       
   375 
       
   376   return start;
       
   377 }
       
   378 
       
   379 
       
   380 #define HB_BUFFER_XALLOCATE_VAR(b, func, var) \
       
   381   b->func (offsetof (hb_glyph_info_t, var) - offsetof(hb_glyph_info_t, var1), \
       
   382            sizeof (b->info[0].var))
       
   383 #define HB_BUFFER_ALLOCATE_VAR(b, var)          HB_BUFFER_XALLOCATE_VAR (b, allocate_var,   var ())
       
   384 #define HB_BUFFER_DEALLOCATE_VAR(b, var)        HB_BUFFER_XALLOCATE_VAR (b, deallocate_var, var ())
       
   385 #define HB_BUFFER_ASSERT_VAR(b, var)            HB_BUFFER_XALLOCATE_VAR (b, assert_var,     var ())
       
   386 
       
   387 
       
   388 #endif /* HB_BUFFER_PRIVATE_HH */