QtBase  v6.3.1
hb-ot-shape-complex-myanmar.cc
Go to the documentation of this file.
1 /*
2  * Copyright © 2011,2012,2013 Google, Inc.
3  *
4  * This is part of HarfBuzz, a text shaping library.
5  *
6  * Permission is hereby granted, without written agreement and without
7  * license or royalty fees, to use, copy, modify, and distribute this
8  * software and its documentation for any purpose, provided that the
9  * above copyright notice and the following two paragraphs appear in
10  * all copies of this software.
11  *
12  * IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE TO ANY PARTY FOR
13  * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES
14  * ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN
15  * IF THE COPYRIGHT HOLDER HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
16  * DAMAGE.
17  *
18  * THE COPYRIGHT HOLDER SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING,
19  * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
20  * FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS
21  * ON AN "AS IS" BASIS, AND THE COPYRIGHT HOLDER HAS NO OBLIGATION TO
22  * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
23  *
24  * Google Author(s): Behdad Esfahbod
25  */
26 
27 #include "hb.hh"
28 
29 #ifndef HB_NO_OT_SHAPE
30 
33 
34 
35 /*
36  * Myanmar shaper.
37  */
38 
39 static const hb_tag_t
40 myanmar_basic_features[] =
41 {
42  /*
43  * Basic features.
44  * These features are applied in order, one at a time, after reordering,
45  * constrained to the syllable.
46  */
47  HB_TAG('r','p','h','f'),
48  HB_TAG('p','r','e','f'),
49  HB_TAG('b','l','w','f'),
50  HB_TAG('p','s','t','f'),
51 };
52 static const hb_tag_t
53 myanmar_other_features[] =
54 {
55  /*
56  * Other features.
57  * These features are applied all at once, after clearing syllables.
58  */
59  HB_TAG('p','r','e','s'),
60  HB_TAG('a','b','v','s'),
61  HB_TAG('b','l','w','s'),
62  HB_TAG('p','s','t','s'),
63 };
64 
65 static void
66 setup_syllables_myanmar (const hb_ot_shape_plan_t *plan,
67  hb_font_t *font,
69 static void
70 reorder_myanmar (const hb_ot_shape_plan_t *plan,
71  hb_font_t *font,
73 
74 static void
75 collect_features_myanmar (hb_ot_shape_planner_t *plan)
76 {
77  hb_ot_map_builder_t *map = &plan->map;
78 
79  /* Do this before any lookups have been applied. */
80  map->add_gsub_pause (setup_syllables_myanmar);
81 
82  map->enable_feature (HB_TAG('l','o','c','l'), F_PER_SYLLABLE);
83  /* The Indic specs do not require ccmp, but we apply it here since if
84  * there is a use of it, it's typically at the beginning. */
85  map->enable_feature (HB_TAG('c','c','m','p'), F_PER_SYLLABLE);
86 
87 
88  map->add_gsub_pause (reorder_myanmar);
89 
90  for (unsigned int i = 0; i < ARRAY_LENGTH (myanmar_basic_features); i++)
91  {
92  map->enable_feature (myanmar_basic_features[i], F_MANUAL_ZWJ | F_PER_SYLLABLE);
93  map->add_gsub_pause (nullptr);
94  }
95 
96  for (unsigned int i = 0; i < ARRAY_LENGTH (myanmar_other_features); i++)
97  map->enable_feature (myanmar_other_features[i], F_MANUAL_ZWJ);
98 }
99 
100 static void
101 setup_masks_myanmar (const hb_ot_shape_plan_t *plan HB_UNUSED,
104 {
107 
108  /* No masks, we just save information about characters. */
109 
110  unsigned int count = buffer->len;
111  hb_glyph_info_t *info = buffer->info;
112  for (unsigned int i = 0; i < count; i++)
113  set_myanmar_properties (info[i]);
114 }
115 
116 static void
117 setup_syllables_myanmar (const hb_ot_shape_plan_t *plan HB_UNUSED,
120 {
121  find_syllables_myanmar (buffer);
123  buffer->unsafe_to_break (start, end);
124 }
125 
126 static int
127 compare_myanmar_order (const hb_glyph_info_t *pa, const hb_glyph_info_t *pb)
128 {
129  int a = pa->myanmar_position();
130  int b = pb->myanmar_position();
131 
132  return a < b ? -1 : a == b ? 0 : +1;
133 }
134 
135 
136 /* Rules from:
137  * https://docs.microsoft.com/en-us/typography/script-development/myanmar */
138 
139 static void
140 initial_reordering_consonant_syllable (hb_buffer_t *buffer,
141  unsigned int start, unsigned int end)
142 {
143  hb_glyph_info_t *info = buffer->info;
144 
145  unsigned int base = end;
146  bool has_reph = false;
147 
148  {
149  unsigned int limit = start;
150  if (start + 3 <= end &&
151  info[start ].myanmar_category() == OT_Ra &&
152  info[start+1].myanmar_category() == OT_As &&
154  {
155  limit += 3;
156  base = start;
157  has_reph = true;
158  }
159 
160  {
161  if (!has_reph)
162  base = limit;
163 
164  for (unsigned int i = limit; i < end; i++)
165  if (is_consonant (info[i]))
166  {
167  base = i;
168  break;
169  }
170  }
171  }
172 
173  /* Reorder! */
174  {
175  unsigned int i = start;
176  for (; i < start + (has_reph ? 3 : 0); i++)
178  for (; i < base; i++)
180  if (i < end)
181  {
182  info[i].myanmar_position() = POS_BASE_C;
183  i++;
184  }
186  /* The following loop may be ugly, but it implements all of
187  * Myanmar reordering! */
188  for (; i < end; i++)
189  {
190  if (info[i].myanmar_category() == OT_MR) /* Pre-base reordering */
191  {
192  info[i].myanmar_position() = POS_PRE_C;
193  continue;
194  }
195  if (info[i].myanmar_position() < POS_BASE_C) /* Left matra */
196  {
197  continue;
198  }
199  if (info[i].myanmar_category() == OT_VS)
200  {
201  info[i].myanmar_position() = info[i - 1].myanmar_position();
202  continue;
203  }
204 
206  {
207  pos = POS_BELOW_C;
208  info[i].myanmar_position() = pos;
209  continue;
210  }
211 
212  if (pos == POS_BELOW_C && info[i].myanmar_category() == OT_A)
213  {
214  info[i].myanmar_position() = POS_BEFORE_SUB;
215  continue;
216  }
217  if (pos == POS_BELOW_C && info[i].myanmar_category() == OT_VBlw)
218  {
219  info[i].myanmar_position() = pos;
220  continue;
221  }
222  if (pos == POS_BELOW_C && info[i].myanmar_category() != OT_A)
223  {
224  pos = POS_AFTER_SUB;
225  info[i].myanmar_position() = pos;
226  continue;
227  }
228  info[i].myanmar_position() = pos;
229  }
230  }
231 
232  /* Sit tight, rock 'n roll! */
233  buffer->sort (start, end, compare_myanmar_order);
234 }
235 
236 static void
237 reorder_syllable_myanmar (const hb_ot_shape_plan_t *plan HB_UNUSED,
240  unsigned int start, unsigned int end)
241 {
242  myanmar_syllable_type_t syllable_type = (myanmar_syllable_type_t) (buffer->info[start].syllable() & 0x0F);
243  switch (syllable_type) {
244 
245  case myanmar_broken_cluster: /* We already inserted dotted-circles, so just call the consonant_syllable. */
247  initial_reordering_consonant_syllable (buffer, start, end);
248  break;
249 
252  break;
253  }
254 }
255 
256 static void
257 reorder_myanmar (const hb_ot_shape_plan_t *plan,
258  hb_font_t *font,
260 {
261  if (buffer->message (font, "start reordering myanmar"))
262  {
265  OT_GB);
266 
268  reorder_syllable_myanmar (plan, font->face, buffer, start, end);
269  (void) buffer->message (font, "end reordering myanmar");
270  }
271 
274 }
275 
276 
278 {
279  collect_features_myanmar,
280  nullptr, /* override_features */
281  nullptr, /* data_create */
282  nullptr, /* data_destroy */
283  nullptr, /* preprocess_text */
284  nullptr, /* postprocess_glyphs */
286  nullptr, /* decompose */
287  nullptr, /* compose */
288  setup_masks_myanmar,
289  HB_TAG_NONE, /* gpos_tag */
290  nullptr, /* reorder_marks */
292  false, /* fallback_position */
293 };
294 
295 
296 /* Ugly Zawgyi encoding.
297  * Disable all auto processing.
298  * https://github.com/harfbuzz/harfbuzz/issues/1162 */
300 {
301  nullptr, /* collect_features */
302  nullptr, /* override_features */
303  nullptr, /* data_create */
304  nullptr, /* data_destroy */
305  nullptr, /* preprocess_text */
306  nullptr, /* postprocess_glyphs */
308  nullptr, /* decompose */
309  nullptr, /* compose */
310  nullptr, /* setup_masks */
311  HB_TAG_NONE, /* gpos_tag */
312  nullptr, /* reorder_marks */
314  false, /* fallback_position */
315 };
316 
317 
318 #endif
small capitals from c petite p scientific i
[1]
Definition: afcover.h:80
Definition: base.h:37
QMap< QString, QString > map
[6]
#define HB_BUFFER_DEALLOCATE_VAR(b, var)
Definition: hb-buffer.hh:623
#define HB_BUFFER_ALLOCATE_VAR(b, var)
Definition: hb-buffer.hh:622
void const void *obj HB_UNUSED
Definition: hb-debug.hh:180
#define foreach_syllable(buffer, start, end)
@ F_MANUAL_ZWJ
Definition: hb-ot-map.hh:183
@ F_PER_SYLLABLE
Definition: hb-ot-map.hh:189
const hb_ot_complex_shaper_t _hb_ot_complex_shaper_myanmar_zawgyi
const hb_ot_complex_shaper_t _hb_ot_complex_shaper_myanmar
#define myanmar_position()
#define myanmar_category()
void hb_syllabic_insert_dotted_circles(hb_font_t *font, hb_buffer_t *buffer, unsigned int broken_syllable_type, unsigned int dottedcircle_category, int repha_category, int dottedcircle_position)
@ HB_OT_SHAPE_ZERO_WIDTH_MARKS_BY_GDEF_EARLY
@ HB_OT_SHAPE_ZERO_WIDTH_MARKS_NONE
@ HB_OT_SHAPE_NORMALIZATION_MODE_NONE
@ HB_OT_SHAPE_NORMALIZATION_MODE_COMPOSED_DIACRITICS_NO_SHORT_CIRCUIT
backing_store_ptr info
[4]
Definition: jmemsys.h:161
void
Definition: png.h:1080
#define ARRAY_LENGTH(a)
Definition: qkmsdevice.cpp:52
GLboolean GLboolean GLboolean b
GLboolean GLboolean GLboolean GLboolean a
[7]
GLuint GLuint end
GLenum GLenum GLsizei count
GLenum face
GLenum GLuint buffer
GLuint start
GLint limit
Definition: qopenglext.h:9975
#define HB_TAG(c1, c2, c3, c4)
Definition: hb-common.h:169
uint32_t hb_tag_t
Definition: hb-common.h:157
#define HB_TAG_NONE
Definition: hb-common.h:187
QString base
hb_ot_map_builder_t map
Definition: hb-ot-shape.hh:152
QCommandLinkButton * pb