[HarfBuzz] harfbuzz-ng: Branch 'master' - 11 commits
Behdad Esfahbod
behdad at kemper.freedesktop.org
Tue Oct 12 14:39:38 PDT 2010
src/Makefile.am | 3
src/hb-buffer-private.hh | 11
src/hb-buffer.cc | 5
src/hb-ot-map-private.hh | 43 --
src/hb-ot-map.cc | 47 +-
src/hb-ot-shape-arabic.cc | 706 ------------------------------------
src/hb-ot-shape-complex-arabic.cc | 716 +++++++++++++++++++++++++++++++++++++
src/hb-ot-shape-complex-private.hh | 95 ++++
src/hb-ot-shape-private.hh | 24 -
src/hb-ot-shape.cc | 103 +++--
src/hb-ot-shape.h | 10
11 files changed, 953 insertions(+), 810 deletions(-)
New commits:
commit 758f68b860b44b5a04eb3dde5cb40b1b04cf634a
Author: Behdad Esfahbod <behdad at behdad.org>
Date: Tue Oct 12 17:37:44 2010 -0400
Fix Arabic shaper
It's tested now. It works!
diff --git a/src/hb-ot-shape-complex-arabic.cc b/src/hb-ot-shape-complex-arabic.cc
index d1f9f4a..74d7125 100644
--- a/src/hb-ot-shape-complex-arabic.cc
+++ b/src/hb-ot-shape-complex-arabic.cc
@@ -684,14 +684,15 @@ _hb_ot_shape_complex_setup_masks_arabic (hb_ot_shape_context_t *c)
unsigned int count = c->buffer->len;
unsigned int prev = 0, state = 0;
- for (unsigned int i = 0; i < count; i++) {
+ for (unsigned int i = 0; i < count; i++)
+ {
unsigned int this_type = get_joining_type (c->buffer->info[i].codepoint, c->buffer->unicode->v.get_general_category (c->buffer->info[i].codepoint));
if (unlikely (this_type == JOINING_TYPE_T))
continue;
- const arabic_state_table_entry *entry = arabic_state_table[state];
+ const arabic_state_table_entry *entry = &arabic_state_table[state][this_type];
if (entry->prev_action != NONE)
c->buffer->info[prev].gproperty = entry->prev_action;
@@ -702,7 +703,7 @@ _hb_ot_shape_complex_setup_masks_arabic (hb_ot_shape_context_t *c)
state = entry->next_state;
}
- hb_mask_t mask_array[TOTAL_NUM_FEATURES] = {0};
+ hb_mask_t mask_array[TOTAL_NUM_FEATURES + 1] = {0};
unsigned int num_masks = c->buffer->props.script == HB_SCRIPT_SYRIAC ? SYRIAC_NUM_FEATURES : COMMON_NUM_FEATURES;
for (unsigned int i = 0; i < num_masks; i++)
mask_array[i] = c->plan->map.get_mask (arabic_syriac_features[i]);
commit 13403bc67a01e0d4908fb964093fd02ddd11c580
Author: Behdad Esfahbod <behdad at behdad.org>
Date: Tue Oct 12 17:23:54 2010 -0400
Hookup Arabic shaper!
Not tested yet.
diff --git a/src/hb-ot-shape-complex-arabic.cc b/src/hb-ot-shape-complex-arabic.cc
index 5e6ce05..d1f9f4a 100644
--- a/src/hb-ot-shape-complex-arabic.cc
+++ b/src/hb-ot-shape-complex-arabic.cc
@@ -24,7 +24,7 @@
* Google Author(s): Behdad Esfahbod
*/
-#include "hb-ot-shape-private.hh"
+#include "hb-ot-shape-complex-private.hh"
HB_BEGIN_DECLS
@@ -679,7 +679,7 @@ _hb_ot_shape_complex_collect_features_arabic (hb_ot_shape_plan_t *plan, const hb
}
void
-_hb_ot_analyze_complex_arabic (hb_ot_shape_context_t *c)
+_hb_ot_shape_complex_setup_masks_arabic (hb_ot_shape_context_t *c)
{
unsigned int count = c->buffer->len;
unsigned int prev = 0, state = 0;
@@ -705,7 +705,7 @@ _hb_ot_analyze_complex_arabic (hb_ot_shape_context_t *c)
hb_mask_t mask_array[TOTAL_NUM_FEATURES] = {0};
unsigned int num_masks = c->buffer->props.script == HB_SCRIPT_SYRIAC ? SYRIAC_NUM_FEATURES : COMMON_NUM_FEATURES;
for (unsigned int i = 0; i < num_masks; i++)
- mask_array[i] = 0 /* XXX find_mask */;
+ mask_array[i] = c->plan->map.get_mask (arabic_syriac_features[i]);
for (unsigned int i = 0; i < count; i++)
c->buffer->info[i].mask |= mask_array[c->buffer->info[i].gproperty];
diff --git a/src/hb-ot-shape-complex-private.hh b/src/hb-ot-shape-complex-private.hh
index 1c605bb..a3796b4 100644
--- a/src/hb-ot-shape-complex-private.hh
+++ b/src/hb-ot-shape-complex-private.hh
@@ -29,24 +29,11 @@
#include "hb-private.h"
-#include "hb-ot-map-private.hh"
+#include "hb-ot-shape-private.hh"
HB_BEGIN_DECLS
-enum hb_ot_complex_shaper_t {
- hb_ot_complex_shaper_none,
- hb_ot_complex_shaper_arabic
-};
-
-
-struct hb_ot_shape_plan_t
-{
- hb_ot_map_t map;
- hb_ot_complex_shaper_t shaper;
-};
-
-
static inline hb_ot_complex_shaper_t
hb_ot_shape_complex_categorize (const hb_segment_properties_t *props)
{
@@ -66,7 +53,9 @@ hb_ot_shape_complex_categorize (const hb_segment_properties_t *props)
/*
* collect_features()
*
- * Called during planning. Shapers should call plan->map.add_feature().
+ * Called during shape_plan().
+ *
+ * Shapers should use plan->map to add their features.
*/
HB_INTERNAL void _hb_ot_shape_complex_collect_features_arabic (hb_ot_shape_plan_t *plan, const hb_segment_properties_t *props);
@@ -82,6 +71,24 @@ hb_ot_shape_complex_collect_features (hb_ot_shape_plan_t *plan,
}
+/* setup_masks()
+ *
+ * Called during shape_execute().
+ *
+ * Shapers should use c->plan.map to get feature masks and set on buffer.
+ */
+
+HB_INTERNAL void _hb_ot_shape_complex_setup_masks_arabic (hb_ot_shape_context_t *c);
+
+static inline void
+hb_ot_shape_complex_setup_masks (hb_ot_shape_context_t *c)
+{
+ switch (c->plan->shaper) {
+ case hb_ot_complex_shaper_arabic: _hb_ot_shape_complex_setup_masks_arabic (c); return;
+ case hb_ot_complex_shaper_none: default: return;
+ }
+}
+
HB_END_DECLS
diff --git a/src/hb-ot-shape-private.hh b/src/hb-ot-shape-private.hh
index 772b0cd..0794fbf 100644
--- a/src/hb-ot-shape-private.hh
+++ b/src/hb-ot-shape-private.hh
@@ -31,11 +31,23 @@
#include "hb-ot-shape.h"
-#include "hb-ot-shape-complex-private.hh"
#include "hb-ot-map-private.hh"
HB_BEGIN_DECLS
+enum hb_ot_complex_shaper_t {
+ hb_ot_complex_shaper_none,
+ hb_ot_complex_shaper_arabic
+};
+
+
+struct hb_ot_shape_plan_t
+{
+ hb_ot_map_t map;
+ hb_ot_complex_shaper_t shaper;
+};
+
+
struct hb_ot_shape_context_t
{
/* Input to hb_ot_shape_execute() */
diff --git a/src/hb-ot-shape.cc b/src/hb-ot-shape.cc
index 9eda177..0ce3896 100644
--- a/src/hb-ot-shape.cc
+++ b/src/hb-ot-shape.cc
@@ -27,6 +27,7 @@
*/
#include "hb-ot-shape-private.hh"
+#include "hb-ot-shape-complex-private.hh"
HB_BEGIN_DECLS
@@ -95,7 +96,7 @@ hb_ot_shape_setup_masks (hb_ot_shape_context_t *c)
}
}
- /* complex */
+ hb_ot_shape_complex_setup_masks (c);
}
commit 57ac0ecb7843533b2e6e6d6c8a12b2a44437cc1c
Author: Behdad Esfahbod <behdad at behdad.org>
Date: Tue Oct 12 17:07:02 2010 -0400
Merge clearing masks and setting global masks
diff --git a/src/hb-buffer-private.hh b/src/hb-buffer-private.hh
index d9f3d4d..8154b17 100644
--- a/src/hb-buffer-private.hh
+++ b/src/hb-buffer-private.hh
@@ -102,10 +102,11 @@ _hb_buffer_next_glyph (hb_buffer_t *buffer);
HB_INTERNAL void
-_hb_buffer_clear_masks (hb_buffer_t *buffer);
+_hb_buffer_reset_masks (hb_buffer_t *buffer,
+ hb_mask_t mask);
HB_INTERNAL void
-_hb_buffer_set_masks (hb_buffer_t *buffer,
+_hb_buffer_add_masks (hb_buffer_t *buffer,
hb_mask_t value,
hb_mask_t mask,
unsigned int cluster_start,
@@ -164,12 +165,12 @@ struct _hb_buffer_t {
{ _hb_buffer_add_output_glyph (this, glyph_index, component, ligID); }
inline void replace_glyph (hb_codepoint_t glyph_index) { add_output_glyph (glyph_index); }
- inline void clear_masks (void) { _hb_buffer_clear_masks (this); }
- inline void set_masks (hb_mask_t value,
+ inline void reset_masks (hb_mask_t mask) { _hb_buffer_reset_masks (this, mask); }
+ inline void add_masks (hb_mask_t value,
hb_mask_t mask,
unsigned int cluster_start,
unsigned int cluster_end)
- { _hb_buffer_set_masks (this, value, mask, cluster_start, cluster_end); }
+ { _hb_buffer_add_masks (this, value, mask, cluster_start, cluster_end); }
};
diff --git a/src/hb-buffer.cc b/src/hb-buffer.cc
index 047dafd..800a34d 100644
--- a/src/hb-buffer.cc
+++ b/src/hb-buffer.cc
@@ -460,7 +460,8 @@ _hb_buffer_next_glyph (hb_buffer_t *buffer)
}
void
-_hb_buffer_clear_masks (hb_buffer_t *buffer)
+_hb_buffer_reset_masks (hb_buffer_t *buffer,
+ hb_mask_t mask)
{
unsigned int count = buffer->len;
for (unsigned int i = 0; i < count; i++)
@@ -468,7 +469,7 @@ _hb_buffer_clear_masks (hb_buffer_t *buffer)
}
void
-_hb_buffer_set_masks (hb_buffer_t *buffer,
+_hb_buffer_add_masks (hb_buffer_t *buffer,
hb_mask_t value,
hb_mask_t mask,
unsigned int cluster_start,
diff --git a/src/hb-ot-map.cc b/src/hb-ot-map.cc
index ea11faf..94be14f 100644
--- a/src/hb-ot-map.cc
+++ b/src/hb-ot-map.cc
@@ -63,7 +63,7 @@ void
hb_ot_map_t::compile (hb_face_t *face,
const hb_segment_properties_t *props)
{
- global_mask = 0;
+ global_mask = 1;
lookup_count[0] = lookup_count[1] = 0;
if (!feature_count)
diff --git a/src/hb-ot-shape.cc b/src/hb-ot-shape.cc
index a729c3f..9eda177 100644
--- a/src/hb-ot-shape.cc
+++ b/src/hb-ot-shape.cc
@@ -82,11 +82,8 @@ hb_ot_shape_collect_features (hb_ot_shape_plan_t *plan,
static void
hb_ot_shape_setup_masks (hb_ot_shape_context_t *c)
{
- c->buffer->clear_masks ();
-
hb_mask_t global_mask = c->plan->map.get_global_mask ();
- if (global_mask)
- c->buffer->set_masks (global_mask, global_mask, 0, (unsigned int) -1);
+ c->buffer->reset_masks (global_mask);
for (unsigned int i = 0; i < c->num_user_features; i++)
{
@@ -94,7 +91,7 @@ hb_ot_shape_setup_masks (hb_ot_shape_context_t *c)
if (!(feature->start == 0 && feature->end == (unsigned int)-1)) {
unsigned int shift;
hb_mask_t mask = c->plan->map.get_mask (feature->tag, &shift);
- c->buffer->set_masks (feature->value << shift, mask, feature->start, feature->end);
+ c->buffer->add_masks (feature->value << shift, mask, feature->start, feature->end);
}
}
commit fc96596b7c1c4e62491e951a3c256fb00dcde550
Author: Behdad Esfahbod <behdad at behdad.org>
Date: Tue Oct 12 17:00:25 2010 -0400
Form clusters before setting masks
diff --git a/src/hb-ot-shape.cc b/src/hb-ot-shape.cc
index 36155df..a729c3f 100644
--- a/src/hb-ot-shape.cc
+++ b/src/hb-ot-shape.cc
@@ -277,10 +277,10 @@ hb_ot_shape_execute_internal (hb_ot_shape_context_t *c)
/* Save the original direction, we use it later. */
c->original_direction = c->buffer->props.direction;
- hb_ot_shape_setup_masks (c);
-
hb_form_clusters (c);
+ hb_ot_shape_setup_masks (c);
+
/* SUBSTITUTE */
{
/* Mirroring needs to see the original direction */
commit 1e80782244cdb1dedae9d1e61079d0508e57ca72
Author: Behdad Esfahbod <behdad at behdad.org>
Date: Tue Oct 12 17:00:07 2010 -0400
Clear masks before setting them up, not after!
diff --git a/src/hb-ot-shape.cc b/src/hb-ot-shape.cc
index efa71ba..36155df 100644
--- a/src/hb-ot-shape.cc
+++ b/src/hb-ot-shape.cc
@@ -82,6 +82,8 @@ hb_ot_shape_collect_features (hb_ot_shape_plan_t *plan,
static void
hb_ot_shape_setup_masks (hb_ot_shape_context_t *c)
{
+ c->buffer->clear_masks ();
+
hb_mask_t global_mask = c->plan->map.get_global_mask ();
if (global_mask)
c->buffer->set_masks (global_mask, global_mask, 0, (unsigned int) -1);
@@ -281,8 +283,6 @@ hb_ot_shape_execute_internal (hb_ot_shape_context_t *c)
/* SUBSTITUTE */
{
- c->buffer->clear_masks ();
-
/* Mirroring needs to see the original direction */
hb_mirror_chars (c);
@@ -298,8 +298,6 @@ hb_ot_shape_execute_internal (hb_ot_shape_context_t *c)
/* POSITION */
{
- c->buffer->clear_masks ();
-
hb_position_default (c);
hb_ot_position_complex (c);
commit fd3d32d31cb6d74a9994b6850d539fd0b707d941
Author: Behdad Esfahbod <behdad at behdad.org>
Date: Tue Oct 12 16:57:47 2010 -0400
Add hb_ot_shape_execute()
Not public yet.
diff --git a/src/hb-ot-shape-private.hh b/src/hb-ot-shape-private.hh
index aea52af..772b0cd 100644
--- a/src/hb-ot-shape-private.hh
+++ b/src/hb-ot-shape-private.hh
@@ -38,7 +38,8 @@ HB_BEGIN_DECLS
struct hb_ot_shape_context_t
{
- /* Input to hb_ot_shape() */
+ /* Input to hb_ot_shape_execute() */
+ hb_ot_shape_plan_t *plan;
hb_font_t *font;
hb_face_t *face;
hb_buffer_t *buffer;
@@ -49,8 +50,6 @@ struct hb_ot_shape_context_t
hb_direction_t original_direction;
hb_bool_t applied_substitute_complex;
hb_bool_t applied_position_complex;
-
- hb_ot_shape_plan_t *plan;
};
diff --git a/src/hb-ot-shape.cc b/src/hb-ot-shape.cc
index b6acb22..efa71ba 100644
--- a/src/hb-ot-shape.cc
+++ b/src/hb-ot-shape.cc
@@ -270,7 +270,7 @@ hb_position_complex_fallback_visual (hb_ot_shape_context_t *c)
/* Do it! */
static void
-hb_ot_shape_internal (hb_ot_shape_context_t *c)
+hb_ot_shape_execute_internal (hb_ot_shape_context_t *c)
{
/* Save the original direction, we use it later. */
c->original_direction = c->buffer->props.direction;
@@ -333,6 +333,18 @@ hb_ot_shape_plan_internal (hb_ot_shape_plan_t *plan,
}
void
+hb_ot_shape_execute (hb_ot_shape_plan_t *plan,
+ hb_font_t *font,
+ hb_face_t *face,
+ hb_buffer_t *buffer,
+ const hb_feature_t *user_features,
+ unsigned int num_user_features)
+{
+ hb_ot_shape_context_t c = {plan, font, face, buffer, user_features, num_user_features};
+ hb_ot_shape_execute_internal (&c);
+}
+
+void
hb_ot_shape (hb_font_t *font,
hb_face_t *face,
hb_buffer_t *buffer,
@@ -342,10 +354,7 @@ hb_ot_shape (hb_font_t *font,
hb_ot_shape_plan_t plan;
hb_ot_shape_plan_internal (&plan, face, &buffer->props, user_features, num_user_features);
-
- hb_ot_shape_context_t c = {font, face, buffer, user_features, num_user_features};
- c.plan = &plan;
- hb_ot_shape_internal (&c);
+ hb_ot_shape_execute (&plan, font, face, buffer, user_features, num_user_features);
}
commit 49baa1f69efb0e3c62e45bd59dd88459a84bf390
Author: Behdad Esfahbod <behdad at behdad.org>
Date: Tue Oct 12 16:50:36 2010 -0400
Add hb_ot_complex_shaper_t stuff and start hooking Arabic shaper up
diff --git a/src/Makefile.am b/src/Makefile.am
index 4908876..a542ee7 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -50,8 +50,9 @@ HBSOURCES += \
hb-ot-map.cc \
hb-ot-map-private.hh \
hb-ot-shape.cc \
+ hb-ot-shape-complex-arabic.cc \
+ hb-ot-shape-complex-private.hh \
hb-ot-shape-private.hh \
- hb-ot-shape-arabic.cc \
hb-ot-tag.c \
$(NULL)
HBHEADERS += \
diff --git a/src/hb-ot-map-private.hh b/src/hb-ot-map-private.hh
index 0c05742..8e65f49 100644
--- a/src/hb-ot-map-private.hh
+++ b/src/hb-ot-map-private.hh
@@ -96,7 +96,7 @@ struct hb_ot_map_t {
{ add_feature (tag, 1, global); }
HB_INTERNAL void compile (hb_face_t *face,
- hb_segment_properties_t *props);
+ const hb_segment_properties_t *props);
hb_mask_t get_global_mask (void) const { return global_mask; }
diff --git a/src/hb-ot-map.cc b/src/hb-ot-map.cc
index 2205624..ea11faf 100644
--- a/src/hb-ot-map.cc
+++ b/src/hb-ot-map.cc
@@ -61,7 +61,7 @@ hb_ot_map_t::add_lookups (hb_face_t *face,
void
hb_ot_map_t::compile (hb_face_t *face,
- hb_segment_properties_t *props)
+ const hb_segment_properties_t *props)
{
global_mask = 0;
lookup_count[0] = lookup_count[1] = 0;
diff --git a/src/hb-ot-shape-arabic.cc b/src/hb-ot-shape-arabic.cc
deleted file mode 100644
index fb5182b..0000000
--- a/src/hb-ot-shape-arabic.cc
+++ /dev/null
@@ -1,706 +0,0 @@
-/*
- * Copyright (C) 2010 Google, Inc.
- *
- * This is part of HarfBuzz, a text shaping library.
- *
- * Permission is hereby granted, without written agreement and without
- * license or royalty fees, to use, copy, modify, and distribute this
- * software and its documentation for any purpose, provided that the
- * above copyright notice and the following two paragraphs appear in
- * all copies of this software.
- *
- * IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE TO ANY PARTY FOR
- * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES
- * ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN
- * IF THE COPYRIGHT HOLDER HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
- * DAMAGE.
- *
- * THE COPYRIGHT HOLDER SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING,
- * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
- * FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS
- * ON AN "AS IS" BASIS, AND THE COPYRIGHT HOLDER HAS NO OBLIGATION TO
- * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
- *
- * Google Author(s): Behdad Esfahbod
- */
-
-#include "hb-ot-shape-private.hh"
-
-HB_BEGIN_DECLS
-
-/*
- * Bits used in the joining tables
- */
-enum {
- JOINING_TYPE_U = 0,
- JOINING_TYPE_R = 1,
- JOINING_TYPE_D = 2,
- JOINING_TYPE_C = JOINING_TYPE_D,
- JOINING_GROUP_ALAPH = 3,
- JOINING_GROUP_DALATH_RISH = 4,
- NUM_STATE_MACHINE_COLS = 5,
-
- /* We deliberately don't have a JOINING_TYPE_L since that's unused in Unicode. */
-
- JOINING_TYPE_T = 6,
- JOINING_TYPE_X = 7, /* means: use general-category to choose between U or T. */
-};
-
-/*
- * Joining types:
- */
-
-
-/*
- * Main joining-type table, covering U+0600..U+07FF.
- * Includes Arabic, Syriac, and N'ko.
- */
-static const uint8_t arabic_syriac_nko_joining_types[0x0800 - 0x0600 + 1] =
-{
- /*
- * The following table is generated by running:
- *
- * ./gen-arabic-joining-table.py < ArabicShaping.txt
- *
- * on the ArabicShaping.txt file with the header:
- *
- * # ArabicShaping-6.0.0.txt
- * # Date: 2010-04-30, 13:47:00 PDT [KW]
- */
- /* == Start of generated table == */
- JOINING_TYPE_U, /* 0600; ARABIC NUMBER SIGN; U; No_Joining_Group */
- JOINING_TYPE_U, /* 0601; ARABIC SIGN SANAH; U; No_Joining_Group */
- JOINING_TYPE_U, /* 0602; ARABIC FOOTNOTE MARKER; U; No_Joining_Group */
- JOINING_TYPE_U, /* 0603; ARABIC SIGN SAFHA; U; No_Joining_Group */
- JOINING_TYPE_X, /* 0604 */
- JOINING_TYPE_X, /* 0605 */
- JOINING_TYPE_X, /* 0606 */
- JOINING_TYPE_X, /* 0607 */
- JOINING_TYPE_U, /* 0608; ARABIC RAY; U; No_Joining_Group */
- JOINING_TYPE_X, /* 0609 */
- JOINING_TYPE_X, /* 060A */
- JOINING_TYPE_U, /* 060B; AFGHANI SIGN; U; No_Joining_Group */
- JOINING_TYPE_X, /* 060C */
- JOINING_TYPE_X, /* 060D */
- JOINING_TYPE_X, /* 060E */
- JOINING_TYPE_X, /* 060F */
- JOINING_TYPE_X, /* 0610 */
- JOINING_TYPE_X, /* 0611 */
- JOINING_TYPE_X, /* 0612 */
- JOINING_TYPE_X, /* 0613 */
- JOINING_TYPE_X, /* 0614 */
- JOINING_TYPE_X, /* 0615 */
- JOINING_TYPE_X, /* 0616 */
- JOINING_TYPE_X, /* 0617 */
- JOINING_TYPE_X, /* 0618 */
- JOINING_TYPE_X, /* 0619 */
- JOINING_TYPE_X, /* 061A */
- JOINING_TYPE_X, /* 061B */
- JOINING_TYPE_X, /* 061C */
- JOINING_TYPE_X, /* 061D */
- JOINING_TYPE_X, /* 061E */
- JOINING_TYPE_X, /* 061F */
- JOINING_TYPE_D, /* 0620; YEH WITH RING; D; YEH */
- JOINING_TYPE_U, /* 0621; HAMZA; U; No_Joining_Group */
- JOINING_TYPE_R, /* 0622; MADDA ON ALEF; R; ALEF */
- JOINING_TYPE_R, /* 0623; HAMZA ON ALEF; R; ALEF */
- JOINING_TYPE_R, /* 0624; HAMZA ON WAW; R; WAW */
- JOINING_TYPE_R, /* 0625; HAMZA UNDER ALEF; R; ALEF */
- JOINING_TYPE_D, /* 0626; HAMZA ON YEH; D; YEH */
- JOINING_TYPE_R, /* 0627; ALEF; R; ALEF */
- JOINING_TYPE_D, /* 0628; BEH; D; BEH */
- JOINING_TYPE_R, /* 0629; TEH MARBUTA; R; TEH MARBUTA */
- JOINING_TYPE_D, /* 062A; TEH; D; BEH */
- JOINING_TYPE_D, /* 062B; THEH; D; BEH */
- JOINING_TYPE_D, /* 062C; JEEM; D; HAH */
- JOINING_TYPE_D, /* 062D; HAH; D; HAH */
- JOINING_TYPE_D, /* 062E; KHAH; D; HAH */
- JOINING_TYPE_R, /* 062F; DAL; R; DAL */
- JOINING_TYPE_R, /* 0630; THAL; R; DAL */
- JOINING_TYPE_R, /* 0631; REH; R; REH */
- JOINING_TYPE_R, /* 0632; ZAIN; R; REH */
- JOINING_TYPE_D, /* 0633; SEEN; D; SEEN */
- JOINING_TYPE_D, /* 0634; SHEEN; D; SEEN */
- JOINING_TYPE_D, /* 0635; SAD; D; SAD */
- JOINING_TYPE_D, /* 0636; DAD; D; SAD */
- JOINING_TYPE_D, /* 0637; TAH; D; TAH */
- JOINING_TYPE_D, /* 0638; ZAH; D; TAH */
- JOINING_TYPE_D, /* 0639; AIN; D; AIN */
- JOINING_TYPE_D, /* 063A; GHAIN; D; AIN */
- JOINING_TYPE_D, /* 063B; KEHEH WITH 2 DOTS ABOVE; D; GAF */
- JOINING_TYPE_D, /* 063C; KEHEH WITH 3 DOTS BELOW; D; GAF */
- JOINING_TYPE_D, /* 063D; FARSI YEH WITH INVERTED V; D; FARSI YEH */
- JOINING_TYPE_D, /* 063E; FARSI YEH WITH 2 DOTS ABOVE; D; FARSI YEH */
- JOINING_TYPE_D, /* 063F; FARSI YEH WITH 3 DOTS ABOVE; D; FARSI YEH */
- JOINING_TYPE_C, /* 0640; TATWEEL; C; No_Joining_Group */
- JOINING_TYPE_D, /* 0641; FEH; D; FEH */
- JOINING_TYPE_D, /* 0642; QAF; D; QAF */
- JOINING_TYPE_D, /* 0643; KAF; D; KAF */
- JOINING_TYPE_D, /* 0644; LAM; D; LAM */
- JOINING_TYPE_D, /* 0645; MEEM; D; MEEM */
- JOINING_TYPE_D, /* 0646; NOON; D; NOON */
- JOINING_TYPE_D, /* 0647; HEH; D; HEH */
- JOINING_TYPE_R, /* 0648; WAW; R; WAW */
- JOINING_TYPE_D, /* 0649; ALEF MAKSURA; D; YEH */
- JOINING_TYPE_D, /* 064A; YEH; D; YEH */
- JOINING_TYPE_X, /* 064B */
- JOINING_TYPE_X, /* 064C */
- JOINING_TYPE_X, /* 064D */
- JOINING_TYPE_X, /* 064E */
- JOINING_TYPE_X, /* 064F */
- JOINING_TYPE_X, /* 0650 */
- JOINING_TYPE_X, /* 0651 */
- JOINING_TYPE_X, /* 0652 */
- JOINING_TYPE_X, /* 0653 */
- JOINING_TYPE_X, /* 0654 */
- JOINING_TYPE_X, /* 0655 */
- JOINING_TYPE_X, /* 0656 */
- JOINING_TYPE_X, /* 0657 */
- JOINING_TYPE_X, /* 0658 */
- JOINING_TYPE_X, /* 0659 */
- JOINING_TYPE_X, /* 065A */
- JOINING_TYPE_X, /* 065B */
- JOINING_TYPE_X, /* 065C */
- JOINING_TYPE_X, /* 065D */
- JOINING_TYPE_X, /* 065E */
- JOINING_TYPE_X, /* 065F */
- JOINING_TYPE_X, /* 0660 */
- JOINING_TYPE_X, /* 0661 */
- JOINING_TYPE_X, /* 0662 */
- JOINING_TYPE_X, /* 0663 */
- JOINING_TYPE_X, /* 0664 */
- JOINING_TYPE_X, /* 0665 */
- JOINING_TYPE_X, /* 0666 */
- JOINING_TYPE_X, /* 0667 */
- JOINING_TYPE_X, /* 0668 */
- JOINING_TYPE_X, /* 0669 */
- JOINING_TYPE_X, /* 066A */
- JOINING_TYPE_X, /* 066B */
- JOINING_TYPE_X, /* 066C */
- JOINING_TYPE_X, /* 066D */
- JOINING_TYPE_D, /* 066E; DOTLESS BEH; D; BEH */
- JOINING_TYPE_D, /* 066F; DOTLESS QAF; D; QAF */
- JOINING_TYPE_X, /* 0670 */
- JOINING_TYPE_R, /* 0671; HAMZAT WASL ON ALEF; R; ALEF */
- JOINING_TYPE_R, /* 0672; WAVY HAMZA ON ALEF; R; ALEF */
- JOINING_TYPE_R, /* 0673; WAVY HAMZA UNDER ALEF; R; ALEF */
- JOINING_TYPE_U, /* 0674; HIGH HAMZA; U; No_Joining_Group */
- JOINING_TYPE_R, /* 0675; HIGH HAMZA ALEF; R; ALEF */
- JOINING_TYPE_R, /* 0676; HIGH HAMZA WAW; R; WAW */
- JOINING_TYPE_R, /* 0677; HIGH HAMZA WAW WITH DAMMA; R; WAW */
- JOINING_TYPE_D, /* 0678; HIGH HAMZA YEH; D; YEH */
- JOINING_TYPE_D, /* 0679; TEH WITH SMALL TAH; D; BEH */
- JOINING_TYPE_D, /* 067A; TEH WITH 2 DOTS VERTICAL ABOVE; D; BEH */
- JOINING_TYPE_D, /* 067B; BEH WITH 2 DOTS VERTICAL BELOW; D; BEH */
- JOINING_TYPE_D, /* 067C; TEH WITH RING; D; BEH */
- JOINING_TYPE_D, /* 067D; TEH WITH 3 DOTS ABOVE DOWNWARD; D; BEH */
- JOINING_TYPE_D, /* 067E; TEH WITH 3 DOTS BELOW; D; BEH */
- JOINING_TYPE_D, /* 067F; TEH WITH 4 DOTS ABOVE; D; BEH */
- JOINING_TYPE_D, /* 0680; BEH WITH 4 DOTS BELOW; D; BEH */
- JOINING_TYPE_D, /* 0681; HAMZA ON HAH; D; HAH */
- JOINING_TYPE_D, /* 0682; HAH WITH 2 DOTS VERTICAL ABOVE; D; HAH */
- JOINING_TYPE_D, /* 0683; HAH WITH MIDDLE 2 DOTS; D; HAH */
- JOINING_TYPE_D, /* 0684; HAH WITH MIDDLE 2 DOTS VERTICAL; D; HAH */
- JOINING_TYPE_D, /* 0685; HAH WITH 3 DOTS ABOVE; D; HAH */
- JOINING_TYPE_D, /* 0686; HAH WITH MIDDLE 3 DOTS DOWNWARD; D; HAH */
- JOINING_TYPE_D, /* 0687; HAH WITH MIDDLE 4 DOTS; D; HAH */
- JOINING_TYPE_R, /* 0688; DAL WITH SMALL TAH; R; DAL */
- JOINING_TYPE_R, /* 0689; DAL WITH RING; R; DAL */
- JOINING_TYPE_R, /* 068A; DAL WITH DOT BELOW; R; DAL */
- JOINING_TYPE_R, /* 068B; DAL WITH DOT BELOW AND SMALL TAH; R; DAL */
- JOINING_TYPE_R, /* 068C; DAL WITH 2 DOTS ABOVE; R; DAL */
- JOINING_TYPE_R, /* 068D; DAL WITH 2 DOTS BELOW; R; DAL */
- JOINING_TYPE_R, /* 068E; DAL WITH 3 DOTS ABOVE; R; DAL */
- JOINING_TYPE_R, /* 068F; DAL WITH 3 DOTS ABOVE DOWNWARD; R; DAL */
- JOINING_TYPE_R, /* 0690; DAL WITH 4 DOTS ABOVE; R; DAL */
- JOINING_TYPE_R, /* 0691; REH WITH SMALL TAH; R; REH */
- JOINING_TYPE_R, /* 0692; REH WITH SMALL V; R; REH */
- JOINING_TYPE_R, /* 0693; REH WITH RING; R; REH */
- JOINING_TYPE_R, /* 0694; REH WITH DOT BELOW; R; REH */
- JOINING_TYPE_R, /* 0695; REH WITH SMALL V BELOW; R; REH */
- JOINING_TYPE_R, /* 0696; REH WITH DOT BELOW AND DOT ABOVE; R; REH */
- JOINING_TYPE_R, /* 0697; REH WITH 2 DOTS ABOVE; R; REH */
- JOINING_TYPE_R, /* 0698; REH WITH 3 DOTS ABOVE; R; REH */
- JOINING_TYPE_R, /* 0699; REH WITH 4 DOTS ABOVE; R; REH */
- JOINING_TYPE_D, /* 069A; SEEN WITH DOT BELOW AND DOT ABOVE; D; SEEN */
- JOINING_TYPE_D, /* 069B; SEEN WITH 3 DOTS BELOW; D; SEEN */
- JOINING_TYPE_D, /* 069C; SEEN WITH 3 DOTS BELOW AND 3 DOTS ABOVE; D; SEEN */
- JOINING_TYPE_D, /* 069D; SAD WITH 2 DOTS BELOW; D; SAD */
- JOINING_TYPE_D, /* 069E; SAD WITH 3 DOTS ABOVE; D; SAD */
- JOINING_TYPE_D, /* 069F; TAH WITH 3 DOTS ABOVE; D; TAH */
- JOINING_TYPE_D, /* 06A0; AIN WITH 3 DOTS ABOVE; D; AIN */
- JOINING_TYPE_D, /* 06A1; DOTLESS FEH; D; FEH */
- JOINING_TYPE_D, /* 06A2; FEH WITH DOT MOVED BELOW; D; FEH */
- JOINING_TYPE_D, /* 06A3; FEH WITH DOT BELOW; D; FEH */
- JOINING_TYPE_D, /* 06A4; FEH WITH 3 DOTS ABOVE; D; FEH */
- JOINING_TYPE_D, /* 06A5; FEH WITH 3 DOTS BELOW; D; FEH */
- JOINING_TYPE_D, /* 06A6; FEH WITH 4 DOTS ABOVE; D; FEH */
- JOINING_TYPE_D, /* 06A7; QAF WITH DOT ABOVE; D; QAF */
- JOINING_TYPE_D, /* 06A8; QAF WITH 3 DOTS ABOVE; D; QAF */
- JOINING_TYPE_D, /* 06A9; KEHEH; D; GAF */
- JOINING_TYPE_D, /* 06AA; SWASH KAF; D; SWASH KAF */
- JOINING_TYPE_D, /* 06AB; KAF WITH RING; D; GAF */
- JOINING_TYPE_D, /* 06AC; KAF WITH DOT ABOVE; D; KAF */
- JOINING_TYPE_D, /* 06AD; KAF WITH 3 DOTS ABOVE; D; KAF */
- JOINING_TYPE_D, /* 06AE; KAF WITH 3 DOTS BELOW; D; KAF */
- JOINING_TYPE_D, /* 06AF; GAF; D; GAF */
- JOINING_TYPE_D, /* 06B0; GAF WITH RING; D; GAF */
- JOINING_TYPE_D, /* 06B1; GAF WITH 2 DOTS ABOVE; D; GAF */
- JOINING_TYPE_D, /* 06B2; GAF WITH 2 DOTS BELOW; D; GAF */
- JOINING_TYPE_D, /* 06B3; GAF WITH 2 DOTS VERTICAL BELOW; D; GAF */
- JOINING_TYPE_D, /* 06B4; GAF WITH 3 DOTS ABOVE; D; GAF */
- JOINING_TYPE_D, /* 06B5; LAM WITH SMALL V; D; LAM */
- JOINING_TYPE_D, /* 06B6; LAM WITH DOT ABOVE; D; LAM */
- JOINING_TYPE_D, /* 06B7; LAM WITH 3 DOTS ABOVE; D; LAM */
- JOINING_TYPE_D, /* 06B8; LAM WITH 3 DOTS BELOW; D; LAM */
- JOINING_TYPE_D, /* 06B9; NOON WITH DOT BELOW; D; NOON */
- JOINING_TYPE_D, /* 06BA; DOTLESS NOON; D; NOON */
- JOINING_TYPE_D, /* 06BB; DOTLESS NOON WITH SMALL TAH; D; NOON */
- JOINING_TYPE_D, /* 06BC; NOON WITH RING; D; NOON */
- JOINING_TYPE_D, /* 06BD; NYA; D; NYA */
- JOINING_TYPE_D, /* 06BE; KNOTTED HEH; D; KNOTTED HEH */
- JOINING_TYPE_D, /* 06BF; HAH WITH MIDDLE 3 DOTS DOWNWARD AND DOT ABOVE; D; HAH */
- JOINING_TYPE_R, /* 06C0; HAMZA ON HEH; R; TEH MARBUTA */
- JOINING_TYPE_D, /* 06C1; HEH GOAL; D; HEH GOAL */
- JOINING_TYPE_D, /* 06C2; HAMZA ON HEH GOAL; D; HEH GOAL */
- JOINING_TYPE_R, /* 06C3; TEH MARBUTA GOAL; R; TEH MARBUTA GOAL */
- JOINING_TYPE_R, /* 06C4; WAW WITH RING; R; WAW */
- JOINING_TYPE_R, /* 06C5; WAW WITH BAR; R; WAW */
- JOINING_TYPE_R, /* 06C6; WAW WITH SMALL V; R; WAW */
- JOINING_TYPE_R, /* 06C7; WAW WITH DAMMA; R; WAW */
- JOINING_TYPE_R, /* 06C8; WAW WITH ALEF ABOVE; R; WAW */
- JOINING_TYPE_R, /* 06C9; WAW WITH INVERTED SMALL V; R; WAW */
- JOINING_TYPE_R, /* 06CA; WAW WITH 2 DOTS ABOVE; R; WAW */
- JOINING_TYPE_R, /* 06CB; WAW WITH 3 DOTS ABOVE; R; WAW */
- JOINING_TYPE_D, /* 06CC; FARSI YEH; D; FARSI YEH */
- JOINING_TYPE_R, /* 06CD; YEH WITH TAIL; R; YEH WITH TAIL */
- JOINING_TYPE_D, /* 06CE; FARSI YEH WITH SMALL V; D; FARSI YEH */
- JOINING_TYPE_R, /* 06CF; WAW WITH DOT ABOVE; R; WAW */
- JOINING_TYPE_D, /* 06D0; YEH WITH 2 DOTS VERTICAL BELOW; D; YEH */
- JOINING_TYPE_D, /* 06D1; YEH WITH 3 DOTS BELOW; D; YEH */
- JOINING_TYPE_R, /* 06D2; YEH BARREE; R; YEH BARREE */
- JOINING_TYPE_R, /* 06D3; HAMZA ON YEH BARREE; R; YEH BARREE */
- JOINING_TYPE_X, /* 06D4 */
- JOINING_TYPE_R, /* 06D5; AE; R; TEH MARBUTA */
- JOINING_TYPE_X, /* 06D6 */
- JOINING_TYPE_X, /* 06D7 */
- JOINING_TYPE_X, /* 06D8 */
- JOINING_TYPE_X, /* 06D9 */
- JOINING_TYPE_X, /* 06DA */
- JOINING_TYPE_X, /* 06DB */
- JOINING_TYPE_X, /* 06DC */
- JOINING_TYPE_U, /* 06DD; ARABIC END OF AYAH; U; No_Joining_Group */
- JOINING_TYPE_X, /* 06DE */
- JOINING_TYPE_X, /* 06DF */
- JOINING_TYPE_X, /* 06E0 */
- JOINING_TYPE_X, /* 06E1 */
- JOINING_TYPE_X, /* 06E2 */
- JOINING_TYPE_X, /* 06E3 */
- JOINING_TYPE_X, /* 06E4 */
- JOINING_TYPE_X, /* 06E5 */
- JOINING_TYPE_X, /* 06E6 */
- JOINING_TYPE_X, /* 06E7 */
- JOINING_TYPE_X, /* 06E8 */
- JOINING_TYPE_X, /* 06E9 */
- JOINING_TYPE_X, /* 06EA */
- JOINING_TYPE_X, /* 06EB */
- JOINING_TYPE_X, /* 06EC */
- JOINING_TYPE_X, /* 06ED */
- JOINING_TYPE_R, /* 06EE; DAL WITH INVERTED V; R; DAL */
- JOINING_TYPE_R, /* 06EF; REH WITH INVERTED V; R; REH */
- JOINING_TYPE_X, /* 06F0 */
- JOINING_TYPE_X, /* 06F1 */
- JOINING_TYPE_X, /* 06F2 */
- JOINING_TYPE_X, /* 06F3 */
- JOINING_TYPE_X, /* 06F4 */
- JOINING_TYPE_X, /* 06F5 */
- JOINING_TYPE_X, /* 06F6 */
- JOINING_TYPE_X, /* 06F7 */
- JOINING_TYPE_X, /* 06F8 */
- JOINING_TYPE_X, /* 06F9 */
- JOINING_TYPE_D, /* 06FA; SEEN WITH DOT BELOW AND 3 DOTS ABOVE; D; SEEN */
- JOINING_TYPE_D, /* 06FB; DAD WITH DOT BELOW; D; SAD */
- JOINING_TYPE_D, /* 06FC; GHAIN WITH DOT BELOW; D; AIN */
- JOINING_TYPE_X, /* 06FD */
- JOINING_TYPE_X, /* 06FE */
- JOINING_TYPE_D, /* 06FF; HEH WITH INVERTED V; D; KNOTTED HEH */
- JOINING_TYPE_X, /* 0700 */
- JOINING_TYPE_X, /* 0701 */
- JOINING_TYPE_X, /* 0702 */
- JOINING_TYPE_X, /* 0703 */
- JOINING_TYPE_X, /* 0704 */
- JOINING_TYPE_X, /* 0705 */
- JOINING_TYPE_X, /* 0706 */
- JOINING_TYPE_X, /* 0707 */
- JOINING_TYPE_X, /* 0708 */
- JOINING_TYPE_X, /* 0709 */
- JOINING_TYPE_X, /* 070A */
- JOINING_TYPE_X, /* 070B */
- JOINING_TYPE_X, /* 070C */
- JOINING_TYPE_X, /* 070D */
- JOINING_TYPE_X, /* 070E */
- JOINING_TYPE_X, /* 070F */
- JOINING_GROUP_ALAPH, /* 0710; ALAPH; R; ALAPH */
- JOINING_TYPE_X, /* 0711 */
- JOINING_TYPE_D, /* 0712; BETH; D; BETH */
- JOINING_TYPE_D, /* 0713; GAMAL; D; GAMAL */
- JOINING_TYPE_D, /* 0714; GAMAL GARSHUNI; D; GAMAL */
- JOINING_GROUP_DALATH_RISH, /* 0715; DALATH; R; DALATH RISH */
- JOINING_GROUP_DALATH_RISH, /* 0716; DOTLESS DALATH RISH; R; DALATH RISH */
- JOINING_TYPE_R, /* 0717; HE; R; HE */
- JOINING_TYPE_R, /* 0718; WAW; R; SYRIAC WAW */
- JOINING_TYPE_R, /* 0719; ZAIN; R; ZAIN */
- JOINING_TYPE_D, /* 071A; HETH; D; HETH */
- JOINING_TYPE_D, /* 071B; TETH; D; TETH */
- JOINING_TYPE_D, /* 071C; TETH GARSHUNI; D; TETH */
- JOINING_TYPE_D, /* 071D; YUDH; D; YUDH */
- JOINING_TYPE_R, /* 071E; YUDH HE; R; YUDH HE */
- JOINING_TYPE_D, /* 071F; KAPH; D; KAPH */
- JOINING_TYPE_D, /* 0720; LAMADH; D; LAMADH */
- JOINING_TYPE_D, /* 0721; MIM; D; MIM */
- JOINING_TYPE_D, /* 0722; NUN; D; NUN */
- JOINING_TYPE_D, /* 0723; SEMKATH; D; SEMKATH */
- JOINING_TYPE_D, /* 0724; FINAL SEMKATH; D; FINAL SEMKATH */
- JOINING_TYPE_D, /* 0725; E; D; E */
- JOINING_TYPE_D, /* 0726; PE; D; PE */
- JOINING_TYPE_D, /* 0727; REVERSED PE; D; REVERSED PE */
- JOINING_TYPE_R, /* 0728; SADHE; R; SADHE */
- JOINING_TYPE_D, /* 0729; QAPH; D; QAPH */
- JOINING_GROUP_DALATH_RISH, /* 072A; RISH; R; DALATH RISH */
- JOINING_TYPE_D, /* 072B; SHIN; D; SHIN */
- JOINING_TYPE_R, /* 072C; TAW; R; TAW */
- JOINING_TYPE_D, /* 072D; PERSIAN BHETH; D; BETH */
- JOINING_TYPE_D, /* 072E; PERSIAN GHAMAL; D; GAMAL */
- JOINING_GROUP_DALATH_RISH, /* 072F; PERSIAN DHALATH; R; DALATH RISH */
- JOINING_TYPE_X, /* 0730 */
- JOINING_TYPE_X, /* 0731 */
- JOINING_TYPE_X, /* 0732 */
- JOINING_TYPE_X, /* 0733 */
- JOINING_TYPE_X, /* 0734 */
- JOINING_TYPE_X, /* 0735 */
- JOINING_TYPE_X, /* 0736 */
- JOINING_TYPE_X, /* 0737 */
- JOINING_TYPE_X, /* 0738 */
- JOINING_TYPE_X, /* 0739 */
- JOINING_TYPE_X, /* 073A */
- JOINING_TYPE_X, /* 073B */
- JOINING_TYPE_X, /* 073C */
- JOINING_TYPE_X, /* 073D */
- JOINING_TYPE_X, /* 073E */
- JOINING_TYPE_X, /* 073F */
- JOINING_TYPE_X, /* 0740 */
- JOINING_TYPE_X, /* 0741 */
- JOINING_TYPE_X, /* 0742 */
- JOINING_TYPE_X, /* 0743 */
- JOINING_TYPE_X, /* 0744 */
- JOINING_TYPE_X, /* 0745 */
- JOINING_TYPE_X, /* 0746 */
- JOINING_TYPE_X, /* 0747 */
- JOINING_TYPE_X, /* 0748 */
- JOINING_TYPE_X, /* 0749 */
- JOINING_TYPE_X, /* 074A */
- JOINING_TYPE_X, /* 074B */
- JOINING_TYPE_X, /* 074C */
- JOINING_TYPE_R, /* 074D; SOGDIAN ZHAIN; R; ZHAIN */
- JOINING_TYPE_D, /* 074E; SOGDIAN KHAPH; D; KHAPH */
- JOINING_TYPE_D, /* 074F; SOGDIAN FE; D; FE */
- JOINING_TYPE_D, /* 0750; BEH WITH 3 DOTS HORIZONTALLY BELOW; D; BEH */
- JOINING_TYPE_D, /* 0751; BEH WITH DOT BELOW AND 3 DOTS ABOVE; D; BEH */
- JOINING_TYPE_D, /* 0752; BEH WITH 3 DOTS POINTING UPWARDS BELOW; D; BEH */
- JOINING_TYPE_D, /* 0753; BEH WITH 3 DOTS POINTING UPWARDS BELOW AND 2 DOTS ABOVE; D; BEH */
- JOINING_TYPE_D, /* 0754; BEH WITH 2 DOTS BELOW AND DOT ABOVE; D; BEH */
- JOINING_TYPE_D, /* 0755; BEH WITH INVERTED SMALL V BELOW; D; BEH */
- JOINING_TYPE_D, /* 0756; BEH WITH SMALL V; D; BEH */
- JOINING_TYPE_D, /* 0757; HAH WITH 2 DOTS ABOVE; D; HAH */
- JOINING_TYPE_D, /* 0758; HAH WITH 3 DOTS POINTING UPWARDS BELOW; D; HAH */
- JOINING_TYPE_R, /* 0759; DAL WITH 2 DOTS VERTICALLY BELOW AND SMALL TAH; R; DAL */
- JOINING_TYPE_R, /* 075A; DAL WITH INVERTED SMALL V BELOW; R; DAL */
- JOINING_TYPE_R, /* 075B; REH WITH STROKE; R; REH */
- JOINING_TYPE_D, /* 075C; SEEN WITH 4 DOTS ABOVE; D; SEEN */
- JOINING_TYPE_D, /* 075D; AIN WITH 2 DOTS ABOVE; D; AIN */
- JOINING_TYPE_D, /* 075E; AIN WITH 3 DOTS POINTING DOWNWARDS ABOVE; D; AIN */
- JOINING_TYPE_D, /* 075F; AIN WITH 2 DOTS VERTICALLY ABOVE; D; AIN */
- JOINING_TYPE_D, /* 0760; FEH WITH 2 DOTS BELOW; D; FEH */
- JOINING_TYPE_D, /* 0761; FEH WITH 3 DOTS POINTING UPWARDS BELOW; D; FEH */
- JOINING_TYPE_D, /* 0762; KEHEH WITH DOT ABOVE; D; GAF */
- JOINING_TYPE_D, /* 0763; KEHEH WITH 3 DOTS ABOVE; D; GAF */
- JOINING_TYPE_D, /* 0764; KEHEH WITH 3 DOTS POINTING UPWARDS BELOW; D; GAF */
- JOINING_TYPE_D, /* 0765; MEEM WITH DOT ABOVE; D; MEEM */
- JOINING_TYPE_D, /* 0766; MEEM WITH DOT BELOW; D; MEEM */
- JOINING_TYPE_D, /* 0767; NOON WITH 2 DOTS BELOW; D; NOON */
- JOINING_TYPE_D, /* 0768; NOON WITH SMALL TAH; D; NOON */
- JOINING_TYPE_D, /* 0769; NOON WITH SMALL V; D; NOON */
- JOINING_TYPE_D, /* 076A; LAM WITH BAR; D; LAM */
- JOINING_TYPE_R, /* 076B; REH WITH 2 DOTS VERTICALLY ABOVE; R; REH */
- JOINING_TYPE_R, /* 076C; REH WITH HAMZA ABOVE; R; REH */
- JOINING_TYPE_D, /* 076D; SEEN WITH 2 DOTS VERTICALLY ABOVE; D; SEEN */
- JOINING_TYPE_D, /* 076E; HAH WITH SMALL TAH BELOW; D; HAH */
- JOINING_TYPE_D, /* 076F; HAH WITH SMALL TAH AND 2 DOTS; D; HAH */
- JOINING_TYPE_D, /* 0770; SEEN WITH SMALL TAH AND 2 DOTS; D; SEEN */
- JOINING_TYPE_R, /* 0771; REH WITH SMALL TAH AND 2 DOTS; R; REH */
- JOINING_TYPE_D, /* 0772; HAH WITH SMALL TAH ABOVE; D; HAH */
- JOINING_TYPE_R, /* 0773; ALEF WITH DIGIT TWO ABOVE; R; ALEF */
- JOINING_TYPE_R, /* 0774; ALEF WITH DIGIT THREE ABOVE; R; ALEF */
- JOINING_TYPE_D, /* 0775; FARSI YEH WITH DIGIT TWO ABOVE; D; FARSI YEH */
- JOINING_TYPE_D, /* 0776; FARSI YEH WITH DIGIT THREE ABOVE; D; FARSI YEH */
- JOINING_TYPE_D, /* 0777; YEH WITH DIGIT FOUR BELOW; D; YEH */
- JOINING_TYPE_R, /* 0778; WAW WITH DIGIT TWO ABOVE; R; WAW */
- JOINING_TYPE_R, /* 0779; WAW WITH DIGIT THREE ABOVE; R; WAW */
- JOINING_TYPE_D, /* 077A; YEH BARREE WITH DIGIT TWO ABOVE; D; BURUSHASKI YEH BARREE */
- JOINING_TYPE_D, /* 077B; YEH BARREE WITH DIGIT THREE ABOVE; D; BURUSHASKI YEH BARREE */
- JOINING_TYPE_D, /* 077C; HAH WITH DIGIT FOUR BELOW; D; HAH */
- JOINING_TYPE_D, /* 077D; SEEN WITH DIGIT FOUR ABOVE; D; SEEN */
- JOINING_TYPE_D, /* 077E; SEEN WITH INVERTED V; D; SEEN */
- JOINING_TYPE_D, /* 077F; KAF WITH 2 DOTS ABOVE; D; KAF */
- JOINING_TYPE_X, /* 0780 */
- JOINING_TYPE_X, /* 0781 */
- JOINING_TYPE_X, /* 0782 */
- JOINING_TYPE_X, /* 0783 */
- JOINING_TYPE_X, /* 0784 */
- JOINING_TYPE_X, /* 0785 */
- JOINING_TYPE_X, /* 0786 */
- JOINING_TYPE_X, /* 0787 */
- JOINING_TYPE_X, /* 0788 */
- JOINING_TYPE_X, /* 0789 */
- JOINING_TYPE_X, /* 078A */
- JOINING_TYPE_X, /* 078B */
- JOINING_TYPE_X, /* 078C */
- JOINING_TYPE_X, /* 078D */
- JOINING_TYPE_X, /* 078E */
- JOINING_TYPE_X, /* 078F */
- JOINING_TYPE_X, /* 0790 */
- JOINING_TYPE_X, /* 0791 */
- JOINING_TYPE_X, /* 0792 */
- JOINING_TYPE_X, /* 0793 */
- JOINING_TYPE_X, /* 0794 */
- JOINING_TYPE_X, /* 0795 */
- JOINING_TYPE_X, /* 0796 */
- JOINING_TYPE_X, /* 0797 */
- JOINING_TYPE_X, /* 0798 */
- JOINING_TYPE_X, /* 0799 */
- JOINING_TYPE_X, /* 079A */
- JOINING_TYPE_X, /* 079B */
- JOINING_TYPE_X, /* 079C */
- JOINING_TYPE_X, /* 079D */
- JOINING_TYPE_X, /* 079E */
- JOINING_TYPE_X, /* 079F */
- JOINING_TYPE_X, /* 07A0 */
- JOINING_TYPE_X, /* 07A1 */
- JOINING_TYPE_X, /* 07A2 */
- JOINING_TYPE_X, /* 07A3 */
- JOINING_TYPE_X, /* 07A4 */
- JOINING_TYPE_X, /* 07A5 */
- JOINING_TYPE_X, /* 07A6 */
- JOINING_TYPE_X, /* 07A7 */
- JOINING_TYPE_X, /* 07A8 */
- JOINING_TYPE_X, /* 07A9 */
- JOINING_TYPE_X, /* 07AA */
- JOINING_TYPE_X, /* 07AB */
- JOINING_TYPE_X, /* 07AC */
- JOINING_TYPE_X, /* 07AD */
- JOINING_TYPE_X, /* 07AE */
- JOINING_TYPE_X, /* 07AF */
- JOINING_TYPE_X, /* 07B0 */
- JOINING_TYPE_X, /* 07B1 */
- JOINING_TYPE_X, /* 07B2 */
- JOINING_TYPE_X, /* 07B3 */
- JOINING_TYPE_X, /* 07B4 */
- JOINING_TYPE_X, /* 07B5 */
- JOINING_TYPE_X, /* 07B6 */
- JOINING_TYPE_X, /* 07B7 */
- JOINING_TYPE_X, /* 07B8 */
- JOINING_TYPE_X, /* 07B9 */
- JOINING_TYPE_X, /* 07BA */
- JOINING_TYPE_X, /* 07BB */
- JOINING_TYPE_X, /* 07BC */
- JOINING_TYPE_X, /* 07BD */
- JOINING_TYPE_X, /* 07BE */
- JOINING_TYPE_X, /* 07BF */
- JOINING_TYPE_X, /* 07C0 */
- JOINING_TYPE_X, /* 07C1 */
- JOINING_TYPE_X, /* 07C2 */
- JOINING_TYPE_X, /* 07C3 */
- JOINING_TYPE_X, /* 07C4 */
- JOINING_TYPE_X, /* 07C5 */
- JOINING_TYPE_X, /* 07C6 */
- JOINING_TYPE_X, /* 07C7 */
- JOINING_TYPE_X, /* 07C8 */
- JOINING_TYPE_X, /* 07C9 */
- JOINING_TYPE_D, /* 07CA; NKO A; D; No_Joining_Group */
- JOINING_TYPE_D, /* 07CB; NKO EE; D; No_Joining_Group */
- JOINING_TYPE_D, /* 07CC; NKO I; D; No_Joining_Group */
- JOINING_TYPE_D, /* 07CD; NKO E; D; No_Joining_Group */
- JOINING_TYPE_D, /* 07CE; NKO U; D; No_Joining_Group */
- JOINING_TYPE_D, /* 07CF; NKO OO; D; No_Joining_Group */
- JOINING_TYPE_D, /* 07D0; NKO O; D; No_Joining_Group */
- JOINING_TYPE_D, /* 07D1; NKO DAGBASINNA; D; No_Joining_Group */
- JOINING_TYPE_D, /* 07D2; NKO N; D; No_Joining_Group */
- JOINING_TYPE_D, /* 07D3; NKO BA; D; No_Joining_Group */
- JOINING_TYPE_D, /* 07D4; NKO PA; D; No_Joining_Group */
- JOINING_TYPE_D, /* 07D5; NKO TA; D; No_Joining_Group */
- JOINING_TYPE_D, /* 07D6; NKO JA; D; No_Joining_Group */
- JOINING_TYPE_D, /* 07D7; NKO CHA; D; No_Joining_Group */
- JOINING_TYPE_D, /* 07D8; NKO DA; D; No_Joining_Group */
- JOINING_TYPE_D, /* 07D9; NKO RA; D; No_Joining_Group */
- JOINING_TYPE_D, /* 07DA; NKO RRA; D; No_Joining_Group */
- JOINING_TYPE_D, /* 07DB; NKO SA; D; No_Joining_Group */
- JOINING_TYPE_D, /* 07DC; NKO GBA; D; No_Joining_Group */
- JOINING_TYPE_D, /* 07DD; NKO FA; D; No_Joining_Group */
- JOINING_TYPE_D, /* 07DE; NKO KA; D; No_Joining_Group */
- JOINING_TYPE_D, /* 07DF; NKO LA; D; No_Joining_Group */
- JOINING_TYPE_D, /* 07E0; NKO NA WOLOSO; D; No_Joining_Group */
- JOINING_TYPE_D, /* 07E1; NKO MA; D; No_Joining_Group */
- JOINING_TYPE_D, /* 07E2; NKO NYA; D; No_Joining_Group */
- JOINING_TYPE_D, /* 07E3; NKO NA; D; No_Joining_Group */
- JOINING_TYPE_D, /* 07E4; NKO HA; D; No_Joining_Group */
- JOINING_TYPE_D, /* 07E5; NKO WA; D; No_Joining_Group */
- JOINING_TYPE_D, /* 07E6; NKO YA; D; No_Joining_Group */
- JOINING_TYPE_D, /* 07E7; NKO NYA WOLOSO; D; No_Joining_Group */
- JOINING_TYPE_D, /* 07E8; NKO JONA JA; D; No_Joining_Group */
- JOINING_TYPE_D, /* 07E9; NKO JONA CHA; D; No_Joining_Group */
- JOINING_TYPE_D, /* 07EA; NKO JONA RA; D; No_Joining_Group */
- JOINING_TYPE_X, /* 07EB */
- JOINING_TYPE_X, /* 07EC */
- JOINING_TYPE_X, /* 07ED */
- JOINING_TYPE_X, /* 07EE */
- JOINING_TYPE_X, /* 07EF */
- JOINING_TYPE_X, /* 07F0 */
- JOINING_TYPE_X, /* 07F1 */
- JOINING_TYPE_X, /* 07F2 */
- JOINING_TYPE_X, /* 07F3 */
- JOINING_TYPE_X, /* 07F4 */
- JOINING_TYPE_X, /* 07F5 */
- JOINING_TYPE_X, /* 07F6 */
- JOINING_TYPE_X, /* 07F7 */
- JOINING_TYPE_X, /* 07F8 */
- JOINING_TYPE_X, /* 07F9 */
- JOINING_TYPE_C, /* 07FA; NKO LAJANYALAN; C; No_Joining_Group */
- JOINING_TYPE_X, /* 07FB */
- JOINING_TYPE_X, /* 07FC */
- JOINING_TYPE_X, /* 07FD */
- JOINING_TYPE_X, /* 07FE */
- JOINING_TYPE_X, /* 07FF */
- /* == End of generated table == */
- JOINING_TYPE_X
-};
-
-static unsigned int get_joining_type (hb_codepoint_t u, hb_category_t gen_cat)
-{
- /* TODO Macroize the magic bit operations */
-
- if (likely ((u & ~(0x0600^0x07FF)) == 0x0600)) {
- unsigned int j_type = arabic_syriac_nko_joining_types[u - 0x0600];
- if (likely (j_type != JOINING_TYPE_X))
- return j_type;
- }
-
- if (unlikely ((u & ~(0x200C^0x200D)) == 0x200C)) {
- return u == 0x200C ? JOINING_TYPE_U : JOINING_TYPE_C;
- }
-
- return ((1<<gen_cat) & ((1<<HB_CATEGORY_NON_SPACING_MARK)|(1<<HB_CATEGORY_ENCLOSING_MARK)|(1<<HB_CATEGORY_FORMAT))) ?
- JOINING_TYPE_T : JOINING_TYPE_U;
-}
-
-
-
-static const hb_tag_t arabic_syriac_features[] =
-{
- HB_TAG('i','n','i','t'),
- HB_TAG('m','e','d','i'),
- HB_TAG('f','i','n','a'),
- HB_TAG('i','s','o','l'),
- /* Syriac */
- HB_TAG('m','e','d','2'),
- HB_TAG('f','i','n','2'),
- HB_TAG('f','i','n','3'),
- HB_TAG_NONE
-};
-
-
-/* Same order as the feature array */
-enum {
- INIT,
- MEDI,
- FINA,
- ISOL,
-
- /* Syriac */
- MED2,
- FIN2,
- FIN3,
-
- NONE,
-
- COMMON_NUM_FEATURES = 4,
- SYRIAC_NUM_FEATURES = 7,
- TOTAL_NUM_FEATURES = NONE
-};
-
-static const struct arabic_state_table_entry {
- uint8_t prev_action;
- uint8_t curr_action;
- uint8_t next_state;
- uint8_t padding;
-} arabic_state_table[][NUM_STATE_MACHINE_COLS] =
-{
- /* jt_U, jt_R, jt_D, jg_ALAPH, jg_DALATH_RISH */
-
- /* State 0: prev was U, not willing to join. */
- { {NONE,NONE,0}, {NONE,ISOL,1}, {NONE,ISOL,2}, {NONE,ISOL,1}, {NONE,ISOL,6}, },
-
- /* State 1: prev was R or ISOL/ALAPH, not willing to join. */
- { {NONE,NONE,0}, {NONE,ISOL,1}, {NONE,ISOL,2}, {NONE,FIN2,5}, {NONE,ISOL,6}, },
-
- /* State 2: prev was D/ISOL, willing to join. */
- { {NONE,NONE,0}, {INIT,FINA,1}, {INIT,FINA,3}, {INIT,FINA,4}, {INIT,FINA,6}, },
-
- /* State 3: prev was D/FINA, willing to join. */
- { {NONE,NONE,0}, {MEDI,FINA,1}, {MEDI,FINA,3}, {MEDI,FINA,4}, {MEDI,FINA,6}, },
-
- /* State 4: prev was FINA ALAPH, not willing to join. */
- { {NONE,NONE,0}, {MED2,ISOL,1}, {MED2,ISOL,2}, {MED2,FIN2,5}, {MED2,ISOL,6}, },
-
- /* State 5: prev was FIN2/FIN3 ALAPH, not willing to join. */
- { {NONE,NONE,0}, {ISOL,ISOL,1}, {ISOL,ISOL,2}, {ISOL,FIN2,5}, {ISOL,ISOL,6}, },
-
- /* State 6: prev was DALATH/RISH, not willing to join. */
- { {NONE,NONE,0}, {NONE,ISOL,1}, {NONE,ISOL,2}, {NONE,FIN3,5}, {NONE,ISOL,6}, }
-};
-
-
-void
-_hb_ot_analyze_complex_arabic (hb_ot_shape_context_t *c)
-{
- unsigned int count = c->buffer->len;
- unsigned int prev = 0, state = 0;
-
- for (unsigned int i = 0; i < count; i++) {
-
- unsigned int this_type = get_joining_type (c->buffer->info[i].codepoint, c->buffer->unicode->v.get_general_category (c->buffer->info[i].codepoint));
-
- if (unlikely (this_type == JOINING_TYPE_T))
- continue;
-
- const arabic_state_table_entry *entry = arabic_state_table[state];
-
- if (entry->prev_action != NONE)
- c->buffer->info[prev].gproperty = entry->prev_action;
-
- c->buffer->info[i].gproperty = entry->curr_action;
-
- prev = i;
- state = entry->next_state;
- }
-
- hb_mask_t mask_array[TOTAL_NUM_FEATURES] = {0};
- unsigned int num_masks = c->buffer->props.script == HB_SCRIPT_SYRIAC ? SYRIAC_NUM_FEATURES : COMMON_NUM_FEATURES;
- for (unsigned int i = 0; i < num_masks; i++)
- mask_array[i] = 0 /* XXX find_mask */;
-
- for (unsigned int i = 0; i < count; i++)
- c->buffer->info[i].mask |= mask_array[c->buffer->info[i].gproperty];
-}
-
-
-HB_END_DECLS
diff --git a/src/hb-ot-shape-complex-arabic.cc b/src/hb-ot-shape-complex-arabic.cc
new file mode 100644
index 0000000..5e6ce05
--- /dev/null
+++ b/src/hb-ot-shape-complex-arabic.cc
@@ -0,0 +1,715 @@
+/*
+ * Copyright (C) 2010 Google, Inc.
+ *
+ * This is part of HarfBuzz, a text shaping library.
+ *
+ * Permission is hereby granted, without written agreement and without
+ * license or royalty fees, to use, copy, modify, and distribute this
+ * software and its documentation for any purpose, provided that the
+ * above copyright notice and the following two paragraphs appear in
+ * all copies of this software.
+ *
+ * IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE TO ANY PARTY FOR
+ * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES
+ * ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN
+ * IF THE COPYRIGHT HOLDER HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
+ * DAMAGE.
+ *
+ * THE COPYRIGHT HOLDER SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING,
+ * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
+ * FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS
+ * ON AN "AS IS" BASIS, AND THE COPYRIGHT HOLDER HAS NO OBLIGATION TO
+ * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
+ *
+ * Google Author(s): Behdad Esfahbod
+ */
+
+#include "hb-ot-shape-private.hh"
+
+HB_BEGIN_DECLS
+
+/*
+ * Bits used in the joining tables
+ */
+enum {
+ JOINING_TYPE_U = 0,
+ JOINING_TYPE_R = 1,
+ JOINING_TYPE_D = 2,
+ JOINING_TYPE_C = JOINING_TYPE_D,
+ JOINING_GROUP_ALAPH = 3,
+ JOINING_GROUP_DALATH_RISH = 4,
+ NUM_STATE_MACHINE_COLS = 5,
+
+ /* We deliberately don't have a JOINING_TYPE_L since that's unused in Unicode. */
+
+ JOINING_TYPE_T = 6,
+ JOINING_TYPE_X = 7, /* means: use general-category to choose between U or T. */
+};
+
+/*
+ * Joining types:
+ */
+
+
+/*
+ * Main joining-type table, covering U+0600..U+07FF.
+ * Includes Arabic, Syriac, and N'ko.
+ */
+static const uint8_t arabic_syriac_nko_joining_types[0x0800 - 0x0600 + 1] =
+{
+ /*
+ * The following table is generated by running:
+ *
+ * ./gen-arabic-joining-table.py < ArabicShaping.txt
+ *
+ * on the ArabicShaping.txt file with the header:
+ *
+ * # ArabicShaping-6.0.0.txt
+ * # Date: 2010-04-30, 13:47:00 PDT [KW]
+ */
+ /* == Start of generated table == */
+ JOINING_TYPE_U, /* 0600; ARABIC NUMBER SIGN; U; No_Joining_Group */
+ JOINING_TYPE_U, /* 0601; ARABIC SIGN SANAH; U; No_Joining_Group */
+ JOINING_TYPE_U, /* 0602; ARABIC FOOTNOTE MARKER; U; No_Joining_Group */
+ JOINING_TYPE_U, /* 0603; ARABIC SIGN SAFHA; U; No_Joining_Group */
+ JOINING_TYPE_X, /* 0604 */
+ JOINING_TYPE_X, /* 0605 */
+ JOINING_TYPE_X, /* 0606 */
+ JOINING_TYPE_X, /* 0607 */
+ JOINING_TYPE_U, /* 0608; ARABIC RAY; U; No_Joining_Group */
+ JOINING_TYPE_X, /* 0609 */
+ JOINING_TYPE_X, /* 060A */
+ JOINING_TYPE_U, /* 060B; AFGHANI SIGN; U; No_Joining_Group */
+ JOINING_TYPE_X, /* 060C */
+ JOINING_TYPE_X, /* 060D */
+ JOINING_TYPE_X, /* 060E */
+ JOINING_TYPE_X, /* 060F */
+ JOINING_TYPE_X, /* 0610 */
+ JOINING_TYPE_X, /* 0611 */
+ JOINING_TYPE_X, /* 0612 */
+ JOINING_TYPE_X, /* 0613 */
+ JOINING_TYPE_X, /* 0614 */
+ JOINING_TYPE_X, /* 0615 */
+ JOINING_TYPE_X, /* 0616 */
+ JOINING_TYPE_X, /* 0617 */
+ JOINING_TYPE_X, /* 0618 */
+ JOINING_TYPE_X, /* 0619 */
+ JOINING_TYPE_X, /* 061A */
+ JOINING_TYPE_X, /* 061B */
+ JOINING_TYPE_X, /* 061C */
+ JOINING_TYPE_X, /* 061D */
+ JOINING_TYPE_X, /* 061E */
+ JOINING_TYPE_X, /* 061F */
+ JOINING_TYPE_D, /* 0620; YEH WITH RING; D; YEH */
+ JOINING_TYPE_U, /* 0621; HAMZA; U; No_Joining_Group */
+ JOINING_TYPE_R, /* 0622; MADDA ON ALEF; R; ALEF */
+ JOINING_TYPE_R, /* 0623; HAMZA ON ALEF; R; ALEF */
+ JOINING_TYPE_R, /* 0624; HAMZA ON WAW; R; WAW */
+ JOINING_TYPE_R, /* 0625; HAMZA UNDER ALEF; R; ALEF */
+ JOINING_TYPE_D, /* 0626; HAMZA ON YEH; D; YEH */
+ JOINING_TYPE_R, /* 0627; ALEF; R; ALEF */
+ JOINING_TYPE_D, /* 0628; BEH; D; BEH */
+ JOINING_TYPE_R, /* 0629; TEH MARBUTA; R; TEH MARBUTA */
+ JOINING_TYPE_D, /* 062A; TEH; D; BEH */
+ JOINING_TYPE_D, /* 062B; THEH; D; BEH */
+ JOINING_TYPE_D, /* 062C; JEEM; D; HAH */
+ JOINING_TYPE_D, /* 062D; HAH; D; HAH */
+ JOINING_TYPE_D, /* 062E; KHAH; D; HAH */
+ JOINING_TYPE_R, /* 062F; DAL; R; DAL */
+ JOINING_TYPE_R, /* 0630; THAL; R; DAL */
+ JOINING_TYPE_R, /* 0631; REH; R; REH */
+ JOINING_TYPE_R, /* 0632; ZAIN; R; REH */
+ JOINING_TYPE_D, /* 0633; SEEN; D; SEEN */
+ JOINING_TYPE_D, /* 0634; SHEEN; D; SEEN */
+ JOINING_TYPE_D, /* 0635; SAD; D; SAD */
+ JOINING_TYPE_D, /* 0636; DAD; D; SAD */
+ JOINING_TYPE_D, /* 0637; TAH; D; TAH */
+ JOINING_TYPE_D, /* 0638; ZAH; D; TAH */
+ JOINING_TYPE_D, /* 0639; AIN; D; AIN */
+ JOINING_TYPE_D, /* 063A; GHAIN; D; AIN */
+ JOINING_TYPE_D, /* 063B; KEHEH WITH 2 DOTS ABOVE; D; GAF */
+ JOINING_TYPE_D, /* 063C; KEHEH WITH 3 DOTS BELOW; D; GAF */
+ JOINING_TYPE_D, /* 063D; FARSI YEH WITH INVERTED V; D; FARSI YEH */
+ JOINING_TYPE_D, /* 063E; FARSI YEH WITH 2 DOTS ABOVE; D; FARSI YEH */
+ JOINING_TYPE_D, /* 063F; FARSI YEH WITH 3 DOTS ABOVE; D; FARSI YEH */
+ JOINING_TYPE_C, /* 0640; TATWEEL; C; No_Joining_Group */
+ JOINING_TYPE_D, /* 0641; FEH; D; FEH */
+ JOINING_TYPE_D, /* 0642; QAF; D; QAF */
+ JOINING_TYPE_D, /* 0643; KAF; D; KAF */
+ JOINING_TYPE_D, /* 0644; LAM; D; LAM */
+ JOINING_TYPE_D, /* 0645; MEEM; D; MEEM */
+ JOINING_TYPE_D, /* 0646; NOON; D; NOON */
+ JOINING_TYPE_D, /* 0647; HEH; D; HEH */
+ JOINING_TYPE_R, /* 0648; WAW; R; WAW */
+ JOINING_TYPE_D, /* 0649; ALEF MAKSURA; D; YEH */
+ JOINING_TYPE_D, /* 064A; YEH; D; YEH */
+ JOINING_TYPE_X, /* 064B */
+ JOINING_TYPE_X, /* 064C */
+ JOINING_TYPE_X, /* 064D */
+ JOINING_TYPE_X, /* 064E */
+ JOINING_TYPE_X, /* 064F */
+ JOINING_TYPE_X, /* 0650 */
+ JOINING_TYPE_X, /* 0651 */
+ JOINING_TYPE_X, /* 0652 */
+ JOINING_TYPE_X, /* 0653 */
+ JOINING_TYPE_X, /* 0654 */
+ JOINING_TYPE_X, /* 0655 */
+ JOINING_TYPE_X, /* 0656 */
+ JOINING_TYPE_X, /* 0657 */
+ JOINING_TYPE_X, /* 0658 */
+ JOINING_TYPE_X, /* 0659 */
+ JOINING_TYPE_X, /* 065A */
+ JOINING_TYPE_X, /* 065B */
+ JOINING_TYPE_X, /* 065C */
+ JOINING_TYPE_X, /* 065D */
+ JOINING_TYPE_X, /* 065E */
+ JOINING_TYPE_X, /* 065F */
+ JOINING_TYPE_X, /* 0660 */
+ JOINING_TYPE_X, /* 0661 */
+ JOINING_TYPE_X, /* 0662 */
+ JOINING_TYPE_X, /* 0663 */
+ JOINING_TYPE_X, /* 0664 */
+ JOINING_TYPE_X, /* 0665 */
+ JOINING_TYPE_X, /* 0666 */
+ JOINING_TYPE_X, /* 0667 */
+ JOINING_TYPE_X, /* 0668 */
+ JOINING_TYPE_X, /* 0669 */
+ JOINING_TYPE_X, /* 066A */
+ JOINING_TYPE_X, /* 066B */
+ JOINING_TYPE_X, /* 066C */
+ JOINING_TYPE_X, /* 066D */
+ JOINING_TYPE_D, /* 066E; DOTLESS BEH; D; BEH */
+ JOINING_TYPE_D, /* 066F; DOTLESS QAF; D; QAF */
+ JOINING_TYPE_X, /* 0670 */
+ JOINING_TYPE_R, /* 0671; HAMZAT WASL ON ALEF; R; ALEF */
+ JOINING_TYPE_R, /* 0672; WAVY HAMZA ON ALEF; R; ALEF */
+ JOINING_TYPE_R, /* 0673; WAVY HAMZA UNDER ALEF; R; ALEF */
+ JOINING_TYPE_U, /* 0674; HIGH HAMZA; U; No_Joining_Group */
+ JOINING_TYPE_R, /* 0675; HIGH HAMZA ALEF; R; ALEF */
+ JOINING_TYPE_R, /* 0676; HIGH HAMZA WAW; R; WAW */
+ JOINING_TYPE_R, /* 0677; HIGH HAMZA WAW WITH DAMMA; R; WAW */
+ JOINING_TYPE_D, /* 0678; HIGH HAMZA YEH; D; YEH */
+ JOINING_TYPE_D, /* 0679; TEH WITH SMALL TAH; D; BEH */
+ JOINING_TYPE_D, /* 067A; TEH WITH 2 DOTS VERTICAL ABOVE; D; BEH */
+ JOINING_TYPE_D, /* 067B; BEH WITH 2 DOTS VERTICAL BELOW; D; BEH */
+ JOINING_TYPE_D, /* 067C; TEH WITH RING; D; BEH */
+ JOINING_TYPE_D, /* 067D; TEH WITH 3 DOTS ABOVE DOWNWARD; D; BEH */
+ JOINING_TYPE_D, /* 067E; TEH WITH 3 DOTS BELOW; D; BEH */
+ JOINING_TYPE_D, /* 067F; TEH WITH 4 DOTS ABOVE; D; BEH */
+ JOINING_TYPE_D, /* 0680; BEH WITH 4 DOTS BELOW; D; BEH */
+ JOINING_TYPE_D, /* 0681; HAMZA ON HAH; D; HAH */
+ JOINING_TYPE_D, /* 0682; HAH WITH 2 DOTS VERTICAL ABOVE; D; HAH */
+ JOINING_TYPE_D, /* 0683; HAH WITH MIDDLE 2 DOTS; D; HAH */
+ JOINING_TYPE_D, /* 0684; HAH WITH MIDDLE 2 DOTS VERTICAL; D; HAH */
+ JOINING_TYPE_D, /* 0685; HAH WITH 3 DOTS ABOVE; D; HAH */
+ JOINING_TYPE_D, /* 0686; HAH WITH MIDDLE 3 DOTS DOWNWARD; D; HAH */
+ JOINING_TYPE_D, /* 0687; HAH WITH MIDDLE 4 DOTS; D; HAH */
+ JOINING_TYPE_R, /* 0688; DAL WITH SMALL TAH; R; DAL */
+ JOINING_TYPE_R, /* 0689; DAL WITH RING; R; DAL */
+ JOINING_TYPE_R, /* 068A; DAL WITH DOT BELOW; R; DAL */
+ JOINING_TYPE_R, /* 068B; DAL WITH DOT BELOW AND SMALL TAH; R; DAL */
+ JOINING_TYPE_R, /* 068C; DAL WITH 2 DOTS ABOVE; R; DAL */
+ JOINING_TYPE_R, /* 068D; DAL WITH 2 DOTS BELOW; R; DAL */
+ JOINING_TYPE_R, /* 068E; DAL WITH 3 DOTS ABOVE; R; DAL */
+ JOINING_TYPE_R, /* 068F; DAL WITH 3 DOTS ABOVE DOWNWARD; R; DAL */
+ JOINING_TYPE_R, /* 0690; DAL WITH 4 DOTS ABOVE; R; DAL */
+ JOINING_TYPE_R, /* 0691; REH WITH SMALL TAH; R; REH */
+ JOINING_TYPE_R, /* 0692; REH WITH SMALL V; R; REH */
+ JOINING_TYPE_R, /* 0693; REH WITH RING; R; REH */
+ JOINING_TYPE_R, /* 0694; REH WITH DOT BELOW; R; REH */
+ JOINING_TYPE_R, /* 0695; REH WITH SMALL V BELOW; R; REH */
+ JOINING_TYPE_R, /* 0696; REH WITH DOT BELOW AND DOT ABOVE; R; REH */
+ JOINING_TYPE_R, /* 0697; REH WITH 2 DOTS ABOVE; R; REH */
+ JOINING_TYPE_R, /* 0698; REH WITH 3 DOTS ABOVE; R; REH */
+ JOINING_TYPE_R, /* 0699; REH WITH 4 DOTS ABOVE; R; REH */
+ JOINING_TYPE_D, /* 069A; SEEN WITH DOT BELOW AND DOT ABOVE; D; SEEN */
+ JOINING_TYPE_D, /* 069B; SEEN WITH 3 DOTS BELOW; D; SEEN */
+ JOINING_TYPE_D, /* 069C; SEEN WITH 3 DOTS BELOW AND 3 DOTS ABOVE; D; SEEN */
+ JOINING_TYPE_D, /* 069D; SAD WITH 2 DOTS BELOW; D; SAD */
+ JOINING_TYPE_D, /* 069E; SAD WITH 3 DOTS ABOVE; D; SAD */
+ JOINING_TYPE_D, /* 069F; TAH WITH 3 DOTS ABOVE; D; TAH */
+ JOINING_TYPE_D, /* 06A0; AIN WITH 3 DOTS ABOVE; D; AIN */
+ JOINING_TYPE_D, /* 06A1; DOTLESS FEH; D; FEH */
+ JOINING_TYPE_D, /* 06A2; FEH WITH DOT MOVED BELOW; D; FEH */
+ JOINING_TYPE_D, /* 06A3; FEH WITH DOT BELOW; D; FEH */
+ JOINING_TYPE_D, /* 06A4; FEH WITH 3 DOTS ABOVE; D; FEH */
+ JOINING_TYPE_D, /* 06A5; FEH WITH 3 DOTS BELOW; D; FEH */
+ JOINING_TYPE_D, /* 06A6; FEH WITH 4 DOTS ABOVE; D; FEH */
+ JOINING_TYPE_D, /* 06A7; QAF WITH DOT ABOVE; D; QAF */
+ JOINING_TYPE_D, /* 06A8; QAF WITH 3 DOTS ABOVE; D; QAF */
+ JOINING_TYPE_D, /* 06A9; KEHEH; D; GAF */
+ JOINING_TYPE_D, /* 06AA; SWASH KAF; D; SWASH KAF */
+ JOINING_TYPE_D, /* 06AB; KAF WITH RING; D; GAF */
+ JOINING_TYPE_D, /* 06AC; KAF WITH DOT ABOVE; D; KAF */
+ JOINING_TYPE_D, /* 06AD; KAF WITH 3 DOTS ABOVE; D; KAF */
+ JOINING_TYPE_D, /* 06AE; KAF WITH 3 DOTS BELOW; D; KAF */
+ JOINING_TYPE_D, /* 06AF; GAF; D; GAF */
+ JOINING_TYPE_D, /* 06B0; GAF WITH RING; D; GAF */
+ JOINING_TYPE_D, /* 06B1; GAF WITH 2 DOTS ABOVE; D; GAF */
+ JOINING_TYPE_D, /* 06B2; GAF WITH 2 DOTS BELOW; D; GAF */
+ JOINING_TYPE_D, /* 06B3; GAF WITH 2 DOTS VERTICAL BELOW; D; GAF */
+ JOINING_TYPE_D, /* 06B4; GAF WITH 3 DOTS ABOVE; D; GAF */
+ JOINING_TYPE_D, /* 06B5; LAM WITH SMALL V; D; LAM */
+ JOINING_TYPE_D, /* 06B6; LAM WITH DOT ABOVE; D; LAM */
+ JOINING_TYPE_D, /* 06B7; LAM WITH 3 DOTS ABOVE; D; LAM */
+ JOINING_TYPE_D, /* 06B8; LAM WITH 3 DOTS BELOW; D; LAM */
+ JOINING_TYPE_D, /* 06B9; NOON WITH DOT BELOW; D; NOON */
+ JOINING_TYPE_D, /* 06BA; DOTLESS NOON; D; NOON */
+ JOINING_TYPE_D, /* 06BB; DOTLESS NOON WITH SMALL TAH; D; NOON */
+ JOINING_TYPE_D, /* 06BC; NOON WITH RING; D; NOON */
+ JOINING_TYPE_D, /* 06BD; NYA; D; NYA */
+ JOINING_TYPE_D, /* 06BE; KNOTTED HEH; D; KNOTTED HEH */
+ JOINING_TYPE_D, /* 06BF; HAH WITH MIDDLE 3 DOTS DOWNWARD AND DOT ABOVE; D; HAH */
+ JOINING_TYPE_R, /* 06C0; HAMZA ON HEH; R; TEH MARBUTA */
+ JOINING_TYPE_D, /* 06C1; HEH GOAL; D; HEH GOAL */
+ JOINING_TYPE_D, /* 06C2; HAMZA ON HEH GOAL; D; HEH GOAL */
+ JOINING_TYPE_R, /* 06C3; TEH MARBUTA GOAL; R; TEH MARBUTA GOAL */
+ JOINING_TYPE_R, /* 06C4; WAW WITH RING; R; WAW */
+ JOINING_TYPE_R, /* 06C5; WAW WITH BAR; R; WAW */
+ JOINING_TYPE_R, /* 06C6; WAW WITH SMALL V; R; WAW */
+ JOINING_TYPE_R, /* 06C7; WAW WITH DAMMA; R; WAW */
+ JOINING_TYPE_R, /* 06C8; WAW WITH ALEF ABOVE; R; WAW */
+ JOINING_TYPE_R, /* 06C9; WAW WITH INVERTED SMALL V; R; WAW */
+ JOINING_TYPE_R, /* 06CA; WAW WITH 2 DOTS ABOVE; R; WAW */
+ JOINING_TYPE_R, /* 06CB; WAW WITH 3 DOTS ABOVE; R; WAW */
+ JOINING_TYPE_D, /* 06CC; FARSI YEH; D; FARSI YEH */
+ JOINING_TYPE_R, /* 06CD; YEH WITH TAIL; R; YEH WITH TAIL */
+ JOINING_TYPE_D, /* 06CE; FARSI YEH WITH SMALL V; D; FARSI YEH */
+ JOINING_TYPE_R, /* 06CF; WAW WITH DOT ABOVE; R; WAW */
+ JOINING_TYPE_D, /* 06D0; YEH WITH 2 DOTS VERTICAL BELOW; D; YEH */
+ JOINING_TYPE_D, /* 06D1; YEH WITH 3 DOTS BELOW; D; YEH */
+ JOINING_TYPE_R, /* 06D2; YEH BARREE; R; YEH BARREE */
+ JOINING_TYPE_R, /* 06D3; HAMZA ON YEH BARREE; R; YEH BARREE */
+ JOINING_TYPE_X, /* 06D4 */
+ JOINING_TYPE_R, /* 06D5; AE; R; TEH MARBUTA */
+ JOINING_TYPE_X, /* 06D6 */
+ JOINING_TYPE_X, /* 06D7 */
+ JOINING_TYPE_X, /* 06D8 */
+ JOINING_TYPE_X, /* 06D9 */
+ JOINING_TYPE_X, /* 06DA */
+ JOINING_TYPE_X, /* 06DB */
+ JOINING_TYPE_X, /* 06DC */
+ JOINING_TYPE_U, /* 06DD; ARABIC END OF AYAH; U; No_Joining_Group */
+ JOINING_TYPE_X, /* 06DE */
+ JOINING_TYPE_X, /* 06DF */
+ JOINING_TYPE_X, /* 06E0 */
+ JOINING_TYPE_X, /* 06E1 */
+ JOINING_TYPE_X, /* 06E2 */
+ JOINING_TYPE_X, /* 06E3 */
+ JOINING_TYPE_X, /* 06E4 */
+ JOINING_TYPE_X, /* 06E5 */
+ JOINING_TYPE_X, /* 06E6 */
+ JOINING_TYPE_X, /* 06E7 */
+ JOINING_TYPE_X, /* 06E8 */
+ JOINING_TYPE_X, /* 06E9 */
+ JOINING_TYPE_X, /* 06EA */
+ JOINING_TYPE_X, /* 06EB */
+ JOINING_TYPE_X, /* 06EC */
+ JOINING_TYPE_X, /* 06ED */
+ JOINING_TYPE_R, /* 06EE; DAL WITH INVERTED V; R; DAL */
+ JOINING_TYPE_R, /* 06EF; REH WITH INVERTED V; R; REH */
+ JOINING_TYPE_X, /* 06F0 */
+ JOINING_TYPE_X, /* 06F1 */
+ JOINING_TYPE_X, /* 06F2 */
+ JOINING_TYPE_X, /* 06F3 */
+ JOINING_TYPE_X, /* 06F4 */
+ JOINING_TYPE_X, /* 06F5 */
+ JOINING_TYPE_X, /* 06F6 */
+ JOINING_TYPE_X, /* 06F7 */
+ JOINING_TYPE_X, /* 06F8 */
+ JOINING_TYPE_X, /* 06F9 */
+ JOINING_TYPE_D, /* 06FA; SEEN WITH DOT BELOW AND 3 DOTS ABOVE; D; SEEN */
+ JOINING_TYPE_D, /* 06FB; DAD WITH DOT BELOW; D; SAD */
+ JOINING_TYPE_D, /* 06FC; GHAIN WITH DOT BELOW; D; AIN */
+ JOINING_TYPE_X, /* 06FD */
+ JOINING_TYPE_X, /* 06FE */
+ JOINING_TYPE_D, /* 06FF; HEH WITH INVERTED V; D; KNOTTED HEH */
+ JOINING_TYPE_X, /* 0700 */
+ JOINING_TYPE_X, /* 0701 */
+ JOINING_TYPE_X, /* 0702 */
+ JOINING_TYPE_X, /* 0703 */
+ JOINING_TYPE_X, /* 0704 */
+ JOINING_TYPE_X, /* 0705 */
+ JOINING_TYPE_X, /* 0706 */
+ JOINING_TYPE_X, /* 0707 */
+ JOINING_TYPE_X, /* 0708 */
+ JOINING_TYPE_X, /* 0709 */
+ JOINING_TYPE_X, /* 070A */
+ JOINING_TYPE_X, /* 070B */
+ JOINING_TYPE_X, /* 070C */
+ JOINING_TYPE_X, /* 070D */
+ JOINING_TYPE_X, /* 070E */
+ JOINING_TYPE_X, /* 070F */
+ JOINING_GROUP_ALAPH, /* 0710; ALAPH; R; ALAPH */
+ JOINING_TYPE_X, /* 0711 */
+ JOINING_TYPE_D, /* 0712; BETH; D; BETH */
+ JOINING_TYPE_D, /* 0713; GAMAL; D; GAMAL */
+ JOINING_TYPE_D, /* 0714; GAMAL GARSHUNI; D; GAMAL */
+ JOINING_GROUP_DALATH_RISH, /* 0715; DALATH; R; DALATH RISH */
+ JOINING_GROUP_DALATH_RISH, /* 0716; DOTLESS DALATH RISH; R; DALATH RISH */
+ JOINING_TYPE_R, /* 0717; HE; R; HE */
+ JOINING_TYPE_R, /* 0718; WAW; R; SYRIAC WAW */
+ JOINING_TYPE_R, /* 0719; ZAIN; R; ZAIN */
+ JOINING_TYPE_D, /* 071A; HETH; D; HETH */
+ JOINING_TYPE_D, /* 071B; TETH; D; TETH */
+ JOINING_TYPE_D, /* 071C; TETH GARSHUNI; D; TETH */
+ JOINING_TYPE_D, /* 071D; YUDH; D; YUDH */
+ JOINING_TYPE_R, /* 071E; YUDH HE; R; YUDH HE */
+ JOINING_TYPE_D, /* 071F; KAPH; D; KAPH */
+ JOINING_TYPE_D, /* 0720; LAMADH; D; LAMADH */
+ JOINING_TYPE_D, /* 0721; MIM; D; MIM */
+ JOINING_TYPE_D, /* 0722; NUN; D; NUN */
+ JOINING_TYPE_D, /* 0723; SEMKATH; D; SEMKATH */
+ JOINING_TYPE_D, /* 0724; FINAL SEMKATH; D; FINAL SEMKATH */
+ JOINING_TYPE_D, /* 0725; E; D; E */
+ JOINING_TYPE_D, /* 0726; PE; D; PE */
+ JOINING_TYPE_D, /* 0727; REVERSED PE; D; REVERSED PE */
+ JOINING_TYPE_R, /* 0728; SADHE; R; SADHE */
+ JOINING_TYPE_D, /* 0729; QAPH; D; QAPH */
+ JOINING_GROUP_DALATH_RISH, /* 072A; RISH; R; DALATH RISH */
+ JOINING_TYPE_D, /* 072B; SHIN; D; SHIN */
+ JOINING_TYPE_R, /* 072C; TAW; R; TAW */
+ JOINING_TYPE_D, /* 072D; PERSIAN BHETH; D; BETH */
+ JOINING_TYPE_D, /* 072E; PERSIAN GHAMAL; D; GAMAL */
+ JOINING_GROUP_DALATH_RISH, /* 072F; PERSIAN DHALATH; R; DALATH RISH */
+ JOINING_TYPE_X, /* 0730 */
+ JOINING_TYPE_X, /* 0731 */
+ JOINING_TYPE_X, /* 0732 */
+ JOINING_TYPE_X, /* 0733 */
+ JOINING_TYPE_X, /* 0734 */
+ JOINING_TYPE_X, /* 0735 */
+ JOINING_TYPE_X, /* 0736 */
+ JOINING_TYPE_X, /* 0737 */
+ JOINING_TYPE_X, /* 0738 */
+ JOINING_TYPE_X, /* 0739 */
+ JOINING_TYPE_X, /* 073A */
+ JOINING_TYPE_X, /* 073B */
+ JOINING_TYPE_X, /* 073C */
+ JOINING_TYPE_X, /* 073D */
+ JOINING_TYPE_X, /* 073E */
+ JOINING_TYPE_X, /* 073F */
+ JOINING_TYPE_X, /* 0740 */
+ JOINING_TYPE_X, /* 0741 */
+ JOINING_TYPE_X, /* 0742 */
+ JOINING_TYPE_X, /* 0743 */
+ JOINING_TYPE_X, /* 0744 */
+ JOINING_TYPE_X, /* 0745 */
+ JOINING_TYPE_X, /* 0746 */
+ JOINING_TYPE_X, /* 0747 */
+ JOINING_TYPE_X, /* 0748 */
+ JOINING_TYPE_X, /* 0749 */
+ JOINING_TYPE_X, /* 074A */
+ JOINING_TYPE_X, /* 074B */
+ JOINING_TYPE_X, /* 074C */
+ JOINING_TYPE_R, /* 074D; SOGDIAN ZHAIN; R; ZHAIN */
+ JOINING_TYPE_D, /* 074E; SOGDIAN KHAPH; D; KHAPH */
+ JOINING_TYPE_D, /* 074F; SOGDIAN FE; D; FE */
+ JOINING_TYPE_D, /* 0750; BEH WITH 3 DOTS HORIZONTALLY BELOW; D; BEH */
+ JOINING_TYPE_D, /* 0751; BEH WITH DOT BELOW AND 3 DOTS ABOVE; D; BEH */
+ JOINING_TYPE_D, /* 0752; BEH WITH 3 DOTS POINTING UPWARDS BELOW; D; BEH */
+ JOINING_TYPE_D, /* 0753; BEH WITH 3 DOTS POINTING UPWARDS BELOW AND 2 DOTS ABOVE; D; BEH */
+ JOINING_TYPE_D, /* 0754; BEH WITH 2 DOTS BELOW AND DOT ABOVE; D; BEH */
+ JOINING_TYPE_D, /* 0755; BEH WITH INVERTED SMALL V BELOW; D; BEH */
+ JOINING_TYPE_D, /* 0756; BEH WITH SMALL V; D; BEH */
+ JOINING_TYPE_D, /* 0757; HAH WITH 2 DOTS ABOVE; D; HAH */
+ JOINING_TYPE_D, /* 0758; HAH WITH 3 DOTS POINTING UPWARDS BELOW; D; HAH */
+ JOINING_TYPE_R, /* 0759; DAL WITH 2 DOTS VERTICALLY BELOW AND SMALL TAH; R; DAL */
+ JOINING_TYPE_R, /* 075A; DAL WITH INVERTED SMALL V BELOW; R; DAL */
+ JOINING_TYPE_R, /* 075B; REH WITH STROKE; R; REH */
+ JOINING_TYPE_D, /* 075C; SEEN WITH 4 DOTS ABOVE; D; SEEN */
+ JOINING_TYPE_D, /* 075D; AIN WITH 2 DOTS ABOVE; D; AIN */
+ JOINING_TYPE_D, /* 075E; AIN WITH 3 DOTS POINTING DOWNWARDS ABOVE; D; AIN */
+ JOINING_TYPE_D, /* 075F; AIN WITH 2 DOTS VERTICALLY ABOVE; D; AIN */
+ JOINING_TYPE_D, /* 0760; FEH WITH 2 DOTS BELOW; D; FEH */
+ JOINING_TYPE_D, /* 0761; FEH WITH 3 DOTS POINTING UPWARDS BELOW; D; FEH */
+ JOINING_TYPE_D, /* 0762; KEHEH WITH DOT ABOVE; D; GAF */
+ JOINING_TYPE_D, /* 0763; KEHEH WITH 3 DOTS ABOVE; D; GAF */
+ JOINING_TYPE_D, /* 0764; KEHEH WITH 3 DOTS POINTING UPWARDS BELOW; D; GAF */
+ JOINING_TYPE_D, /* 0765; MEEM WITH DOT ABOVE; D; MEEM */
+ JOINING_TYPE_D, /* 0766; MEEM WITH DOT BELOW; D; MEEM */
+ JOINING_TYPE_D, /* 0767; NOON WITH 2 DOTS BELOW; D; NOON */
+ JOINING_TYPE_D, /* 0768; NOON WITH SMALL TAH; D; NOON */
+ JOINING_TYPE_D, /* 0769; NOON WITH SMALL V; D; NOON */
+ JOINING_TYPE_D, /* 076A; LAM WITH BAR; D; LAM */
+ JOINING_TYPE_R, /* 076B; REH WITH 2 DOTS VERTICALLY ABOVE; R; REH */
+ JOINING_TYPE_R, /* 076C; REH WITH HAMZA ABOVE; R; REH */
+ JOINING_TYPE_D, /* 076D; SEEN WITH 2 DOTS VERTICALLY ABOVE; D; SEEN */
+ JOINING_TYPE_D, /* 076E; HAH WITH SMALL TAH BELOW; D; HAH */
+ JOINING_TYPE_D, /* 076F; HAH WITH SMALL TAH AND 2 DOTS; D; HAH */
+ JOINING_TYPE_D, /* 0770; SEEN WITH SMALL TAH AND 2 DOTS; D; SEEN */
+ JOINING_TYPE_R, /* 0771; REH WITH SMALL TAH AND 2 DOTS; R; REH */
+ JOINING_TYPE_D, /* 0772; HAH WITH SMALL TAH ABOVE; D; HAH */
+ JOINING_TYPE_R, /* 0773; ALEF WITH DIGIT TWO ABOVE; R; ALEF */
+ JOINING_TYPE_R, /* 0774; ALEF WITH DIGIT THREE ABOVE; R; ALEF */
+ JOINING_TYPE_D, /* 0775; FARSI YEH WITH DIGIT TWO ABOVE; D; FARSI YEH */
+ JOINING_TYPE_D, /* 0776; FARSI YEH WITH DIGIT THREE ABOVE; D; FARSI YEH */
+ JOINING_TYPE_D, /* 0777; YEH WITH DIGIT FOUR BELOW; D; YEH */
+ JOINING_TYPE_R, /* 0778; WAW WITH DIGIT TWO ABOVE; R; WAW */
+ JOINING_TYPE_R, /* 0779; WAW WITH DIGIT THREE ABOVE; R; WAW */
+ JOINING_TYPE_D, /* 077A; YEH BARREE WITH DIGIT TWO ABOVE; D; BURUSHASKI YEH BARREE */
+ JOINING_TYPE_D, /* 077B; YEH BARREE WITH DIGIT THREE ABOVE; D; BURUSHASKI YEH BARREE */
+ JOINING_TYPE_D, /* 077C; HAH WITH DIGIT FOUR BELOW; D; HAH */
+ JOINING_TYPE_D, /* 077D; SEEN WITH DIGIT FOUR ABOVE; D; SEEN */
+ JOINING_TYPE_D, /* 077E; SEEN WITH INVERTED V; D; SEEN */
+ JOINING_TYPE_D, /* 077F; KAF WITH 2 DOTS ABOVE; D; KAF */
+ JOINING_TYPE_X, /* 0780 */
+ JOINING_TYPE_X, /* 0781 */
+ JOINING_TYPE_X, /* 0782 */
+ JOINING_TYPE_X, /* 0783 */
+ JOINING_TYPE_X, /* 0784 */
+ JOINING_TYPE_X, /* 0785 */
+ JOINING_TYPE_X, /* 0786 */
+ JOINING_TYPE_X, /* 0787 */
+ JOINING_TYPE_X, /* 0788 */
+ JOINING_TYPE_X, /* 0789 */
+ JOINING_TYPE_X, /* 078A */
+ JOINING_TYPE_X, /* 078B */
+ JOINING_TYPE_X, /* 078C */
+ JOINING_TYPE_X, /* 078D */
+ JOINING_TYPE_X, /* 078E */
+ JOINING_TYPE_X, /* 078F */
+ JOINING_TYPE_X, /* 0790 */
+ JOINING_TYPE_X, /* 0791 */
+ JOINING_TYPE_X, /* 0792 */
+ JOINING_TYPE_X, /* 0793 */
+ JOINING_TYPE_X, /* 0794 */
+ JOINING_TYPE_X, /* 0795 */
+ JOINING_TYPE_X, /* 0796 */
+ JOINING_TYPE_X, /* 0797 */
+ JOINING_TYPE_X, /* 0798 */
+ JOINING_TYPE_X, /* 0799 */
+ JOINING_TYPE_X, /* 079A */
+ JOINING_TYPE_X, /* 079B */
+ JOINING_TYPE_X, /* 079C */
+ JOINING_TYPE_X, /* 079D */
+ JOINING_TYPE_X, /* 079E */
+ JOINING_TYPE_X, /* 079F */
+ JOINING_TYPE_X, /* 07A0 */
+ JOINING_TYPE_X, /* 07A1 */
+ JOINING_TYPE_X, /* 07A2 */
+ JOINING_TYPE_X, /* 07A3 */
+ JOINING_TYPE_X, /* 07A4 */
+ JOINING_TYPE_X, /* 07A5 */
+ JOINING_TYPE_X, /* 07A6 */
+ JOINING_TYPE_X, /* 07A7 */
+ JOINING_TYPE_X, /* 07A8 */
+ JOINING_TYPE_X, /* 07A9 */
+ JOINING_TYPE_X, /* 07AA */
+ JOINING_TYPE_X, /* 07AB */
+ JOINING_TYPE_X, /* 07AC */
+ JOINING_TYPE_X, /* 07AD */
+ JOINING_TYPE_X, /* 07AE */
+ JOINING_TYPE_X, /* 07AF */
+ JOINING_TYPE_X, /* 07B0 */
+ JOINING_TYPE_X, /* 07B1 */
+ JOINING_TYPE_X, /* 07B2 */
+ JOINING_TYPE_X, /* 07B3 */
+ JOINING_TYPE_X, /* 07B4 */
+ JOINING_TYPE_X, /* 07B5 */
+ JOINING_TYPE_X, /* 07B6 */
+ JOINING_TYPE_X, /* 07B7 */
+ JOINING_TYPE_X, /* 07B8 */
+ JOINING_TYPE_X, /* 07B9 */
+ JOINING_TYPE_X, /* 07BA */
+ JOINING_TYPE_X, /* 07BB */
+ JOINING_TYPE_X, /* 07BC */
+ JOINING_TYPE_X, /* 07BD */
+ JOINING_TYPE_X, /* 07BE */
+ JOINING_TYPE_X, /* 07BF */
+ JOINING_TYPE_X, /* 07C0 */
+ JOINING_TYPE_X, /* 07C1 */
+ JOINING_TYPE_X, /* 07C2 */
+ JOINING_TYPE_X, /* 07C3 */
+ JOINING_TYPE_X, /* 07C4 */
+ JOINING_TYPE_X, /* 07C5 */
+ JOINING_TYPE_X, /* 07C6 */
+ JOINING_TYPE_X, /* 07C7 */
+ JOINING_TYPE_X, /* 07C8 */
+ JOINING_TYPE_X, /* 07C9 */
+ JOINING_TYPE_D, /* 07CA; NKO A; D; No_Joining_Group */
+ JOINING_TYPE_D, /* 07CB; NKO EE; D; No_Joining_Group */
+ JOINING_TYPE_D, /* 07CC; NKO I; D; No_Joining_Group */
+ JOINING_TYPE_D, /* 07CD; NKO E; D; No_Joining_Group */
+ JOINING_TYPE_D, /* 07CE; NKO U; D; No_Joining_Group */
+ JOINING_TYPE_D, /* 07CF; NKO OO; D; No_Joining_Group */
+ JOINING_TYPE_D, /* 07D0; NKO O; D; No_Joining_Group */
+ JOINING_TYPE_D, /* 07D1; NKO DAGBASINNA; D; No_Joining_Group */
+ JOINING_TYPE_D, /* 07D2; NKO N; D; No_Joining_Group */
+ JOINING_TYPE_D, /* 07D3; NKO BA; D; No_Joining_Group */
+ JOINING_TYPE_D, /* 07D4; NKO PA; D; No_Joining_Group */
+ JOINING_TYPE_D, /* 07D5; NKO TA; D; No_Joining_Group */
+ JOINING_TYPE_D, /* 07D6; NKO JA; D; No_Joining_Group */
+ JOINING_TYPE_D, /* 07D7; NKO CHA; D; No_Joining_Group */
+ JOINING_TYPE_D, /* 07D8; NKO DA; D; No_Joining_Group */
+ JOINING_TYPE_D, /* 07D9; NKO RA; D; No_Joining_Group */
+ JOINING_TYPE_D, /* 07DA; NKO RRA; D; No_Joining_Group */
+ JOINING_TYPE_D, /* 07DB; NKO SA; D; No_Joining_Group */
+ JOINING_TYPE_D, /* 07DC; NKO GBA; D; No_Joining_Group */
+ JOINING_TYPE_D, /* 07DD; NKO FA; D; No_Joining_Group */
+ JOINING_TYPE_D, /* 07DE; NKO KA; D; No_Joining_Group */
+ JOINING_TYPE_D, /* 07DF; NKO LA; D; No_Joining_Group */
+ JOINING_TYPE_D, /* 07E0; NKO NA WOLOSO; D; No_Joining_Group */
+ JOINING_TYPE_D, /* 07E1; NKO MA; D; No_Joining_Group */
+ JOINING_TYPE_D, /* 07E2; NKO NYA; D; No_Joining_Group */
+ JOINING_TYPE_D, /* 07E3; NKO NA; D; No_Joining_Group */
+ JOINING_TYPE_D, /* 07E4; NKO HA; D; No_Joining_Group */
+ JOINING_TYPE_D, /* 07E5; NKO WA; D; No_Joining_Group */
+ JOINING_TYPE_D, /* 07E6; NKO YA; D; No_Joining_Group */
+ JOINING_TYPE_D, /* 07E7; NKO NYA WOLOSO; D; No_Joining_Group */
+ JOINING_TYPE_D, /* 07E8; NKO JONA JA; D; No_Joining_Group */
+ JOINING_TYPE_D, /* 07E9; NKO JONA CHA; D; No_Joining_Group */
+ JOINING_TYPE_D, /* 07EA; NKO JONA RA; D; No_Joining_Group */
+ JOINING_TYPE_X, /* 07EB */
+ JOINING_TYPE_X, /* 07EC */
+ JOINING_TYPE_X, /* 07ED */
+ JOINING_TYPE_X, /* 07EE */
+ JOINING_TYPE_X, /* 07EF */
+ JOINING_TYPE_X, /* 07F0 */
+ JOINING_TYPE_X, /* 07F1 */
+ JOINING_TYPE_X, /* 07F2 */
+ JOINING_TYPE_X, /* 07F3 */
+ JOINING_TYPE_X, /* 07F4 */
+ JOINING_TYPE_X, /* 07F5 */
+ JOINING_TYPE_X, /* 07F6 */
+ JOINING_TYPE_X, /* 07F7 */
+ JOINING_TYPE_X, /* 07F8 */
+ JOINING_TYPE_X, /* 07F9 */
+ JOINING_TYPE_C, /* 07FA; NKO LAJANYALAN; C; No_Joining_Group */
+ JOINING_TYPE_X, /* 07FB */
+ JOINING_TYPE_X, /* 07FC */
+ JOINING_TYPE_X, /* 07FD */
+ JOINING_TYPE_X, /* 07FE */
+ JOINING_TYPE_X, /* 07FF */
+ /* == End of generated table == */
+ JOINING_TYPE_X
+};
+
+static unsigned int get_joining_type (hb_codepoint_t u, hb_category_t gen_cat)
+{
+ /* TODO Macroize the magic bit operations */
+
+ if (likely ((u & ~(0x0600^0x07FF)) == 0x0600)) {
+ unsigned int j_type = arabic_syriac_nko_joining_types[u - 0x0600];
+ if (likely (j_type != JOINING_TYPE_X))
+ return j_type;
+ }
+
+ if (unlikely ((u & ~(0x200C^0x200D)) == 0x200C)) {
+ return u == 0x200C ? JOINING_TYPE_U : JOINING_TYPE_C;
+ }
+
+ return ((1<<gen_cat) & ((1<<HB_CATEGORY_NON_SPACING_MARK)|(1<<HB_CATEGORY_ENCLOSING_MARK)|(1<<HB_CATEGORY_FORMAT))) ?
+ JOINING_TYPE_T : JOINING_TYPE_U;
+}
+
+
+
+static const hb_tag_t arabic_syriac_features[] =
+{
+ HB_TAG('i','n','i','t'),
+ HB_TAG('m','e','d','i'),
+ HB_TAG('f','i','n','a'),
+ HB_TAG('i','s','o','l'),
+ /* Syriac */
+ HB_TAG('m','e','d','2'),
+ HB_TAG('f','i','n','2'),
+ HB_TAG('f','i','n','3'),
+ HB_TAG_NONE
+};
+
+
+/* Same order as the feature array */
+enum {
+ INIT,
+ MEDI,
+ FINA,
+ ISOL,
+
+ /* Syriac */
+ MED2,
+ FIN2,
+ FIN3,
+
+ NONE,
+
+ COMMON_NUM_FEATURES = 4,
+ SYRIAC_NUM_FEATURES = 7,
+ TOTAL_NUM_FEATURES = NONE
+};
+
+static const struct arabic_state_table_entry {
+ uint8_t prev_action;
+ uint8_t curr_action;
+ uint8_t next_state;
+ uint8_t padding;
+} arabic_state_table[][NUM_STATE_MACHINE_COLS] =
+{
+ /* jt_U, jt_R, jt_D, jg_ALAPH, jg_DALATH_RISH */
+
+ /* State 0: prev was U, not willing to join. */
+ { {NONE,NONE,0}, {NONE,ISOL,1}, {NONE,ISOL,2}, {NONE,ISOL,1}, {NONE,ISOL,6}, },
+
+ /* State 1: prev was R or ISOL/ALAPH, not willing to join. */
+ { {NONE,NONE,0}, {NONE,ISOL,1}, {NONE,ISOL,2}, {NONE,FIN2,5}, {NONE,ISOL,6}, },
+
+ /* State 2: prev was D/ISOL, willing to join. */
+ { {NONE,NONE,0}, {INIT,FINA,1}, {INIT,FINA,3}, {INIT,FINA,4}, {INIT,FINA,6}, },
+
+ /* State 3: prev was D/FINA, willing to join. */
+ { {NONE,NONE,0}, {MEDI,FINA,1}, {MEDI,FINA,3}, {MEDI,FINA,4}, {MEDI,FINA,6}, },
+
+ /* State 4: prev was FINA ALAPH, not willing to join. */
+ { {NONE,NONE,0}, {MED2,ISOL,1}, {MED2,ISOL,2}, {MED2,FIN2,5}, {MED2,ISOL,6}, },
+
+ /* State 5: prev was FIN2/FIN3 ALAPH, not willing to join. */
+ { {NONE,NONE,0}, {ISOL,ISOL,1}, {ISOL,ISOL,2}, {ISOL,FIN2,5}, {ISOL,ISOL,6}, },
+
+ /* State 6: prev was DALATH/RISH, not willing to join. */
+ { {NONE,NONE,0}, {NONE,ISOL,1}, {NONE,ISOL,2}, {NONE,FIN3,5}, {NONE,ISOL,6}, }
+};
+
+
+
+void
+_hb_ot_shape_complex_collect_features_arabic (hb_ot_shape_plan_t *plan, const hb_segment_properties_t *props)
+{
+ unsigned int num_features = props->script == HB_SCRIPT_SYRIAC ? SYRIAC_NUM_FEATURES : COMMON_NUM_FEATURES;
+ for (unsigned int i = 0; i < num_features; i++)
+ plan->map.add_bool_feature (arabic_syriac_features[i], false);
+}
+
+void
+_hb_ot_analyze_complex_arabic (hb_ot_shape_context_t *c)
+{
+ unsigned int count = c->buffer->len;
+ unsigned int prev = 0, state = 0;
+
+ for (unsigned int i = 0; i < count; i++) {
+
+ unsigned int this_type = get_joining_type (c->buffer->info[i].codepoint, c->buffer->unicode->v.get_general_category (c->buffer->info[i].codepoint));
+
+ if (unlikely (this_type == JOINING_TYPE_T))
+ continue;
+
+ const arabic_state_table_entry *entry = arabic_state_table[state];
+
+ if (entry->prev_action != NONE)
+ c->buffer->info[prev].gproperty = entry->prev_action;
+
+ c->buffer->info[i].gproperty = entry->curr_action;
+
+ prev = i;
+ state = entry->next_state;
+ }
+
+ hb_mask_t mask_array[TOTAL_NUM_FEATURES] = {0};
+ unsigned int num_masks = c->buffer->props.script == HB_SCRIPT_SYRIAC ? SYRIAC_NUM_FEATURES : COMMON_NUM_FEATURES;
+ for (unsigned int i = 0; i < num_masks; i++)
+ mask_array[i] = 0 /* XXX find_mask */;
+
+ for (unsigned int i = 0; i < count; i++)
+ c->buffer->info[i].mask |= mask_array[c->buffer->info[i].gproperty];
+}
+
+
+HB_END_DECLS
diff --git a/src/hb-ot-shape-complex-private.hh b/src/hb-ot-shape-complex-private.hh
new file mode 100644
index 0000000..1c605bb
--- /dev/null
+++ b/src/hb-ot-shape-complex-private.hh
@@ -0,0 +1,88 @@
+/*
+ * Copyright (C) 2010 Google, Inc.
+ *
+ * This is part of HarfBuzz, a text shaping library.
+ *
+ * Permission is hereby granted, without written agreement and without
+ * license or royalty fees, to use, copy, modify, and distribute this
+ * software and its documentation for any purpose, provided that the
+ * above copyright notice and the following two paragraphs appear in
+ * all copies of this software.
+ *
+ * IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE TO ANY PARTY FOR
+ * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES
+ * ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN
+ * IF THE COPYRIGHT HOLDER HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
+ * DAMAGE.
+ *
+ * THE COPYRIGHT HOLDER SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING,
+ * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
+ * FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS
+ * ON AN "AS IS" BASIS, AND THE COPYRIGHT HOLDER HAS NO OBLIGATION TO
+ * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
+ *
+ * Google Author(s): Behdad Esfahbod
+ */
+
+#ifndef HB_OT_SHAPE_COMPLEX_PRIVATE_HH
+#define HB_OT_SHAPE_COMPLEX_PRIVATE_HH
+
+#include "hb-private.h"
+
+#include "hb-ot-map-private.hh"
+
+HB_BEGIN_DECLS
+
+
+enum hb_ot_complex_shaper_t {
+ hb_ot_complex_shaper_none,
+ hb_ot_complex_shaper_arabic
+};
+
+
+struct hb_ot_shape_plan_t
+{
+ hb_ot_map_t map;
+ hb_ot_complex_shaper_t shaper;
+};
+
+
+static inline hb_ot_complex_shaper_t
+hb_ot_shape_complex_categorize (const hb_segment_properties_t *props)
+{
+ switch ((int) props->script) {
+ case HB_SCRIPT_ARABIC:
+ case HB_SCRIPT_NKO:
+ case HB_SCRIPT_SYRIAC:
+ return hb_ot_complex_shaper_arabic;
+
+ default:
+ return hb_ot_complex_shaper_none;
+ }
+}
+
+
+
+/*
+ * collect_features()
+ *
+ * Called during planning. Shapers should call plan->map.add_feature().
+ */
+
+HB_INTERNAL void _hb_ot_shape_complex_collect_features_arabic (hb_ot_shape_plan_t *plan, const hb_segment_properties_t *props);
+
+static inline void
+hb_ot_shape_complex_collect_features (hb_ot_shape_plan_t *plan,
+ const hb_segment_properties_t *props)
+{
+ switch (plan->shaper) {
+ case hb_ot_complex_shaper_arabic: _hb_ot_shape_complex_collect_features_arabic (plan, props); return;
+ case hb_ot_complex_shaper_none: default: return;
+ }
+}
+
+
+
+HB_END_DECLS
+
+#endif /* HB_OT_SHAPE_COMPLEX_PRIVATE_HH */
diff --git a/src/hb-ot-shape-private.hh b/src/hb-ot-shape-private.hh
index de1cb3b..aea52af 100644
--- a/src/hb-ot-shape-private.hh
+++ b/src/hb-ot-shape-private.hh
@@ -31,21 +31,11 @@
#include "hb-ot-shape.h"
+#include "hb-ot-shape-complex-private.hh"
#include "hb-ot-map-private.hh"
HB_BEGIN_DECLS
-enum hb_ot_complex_shaper_t {
- hb_ot_complex_shaper_none,
- hb_ot_complex_shaper_arabic
-};
-
-struct hb_ot_shape_plan_t
-{
- hb_ot_map_t map;
- hb_ot_complex_shaper_t shaper;
-};
-
struct hb_ot_shape_context_t
{
/* Input to hb_ot_shape() */
diff --git a/src/hb-ot-shape.cc b/src/hb-ot-shape.cc
index 061c203..b6acb22 100644
--- a/src/hb-ot-shape.cc
+++ b/src/hb-ot-shape.cc
@@ -48,7 +48,7 @@ hb_tag_t default_features[] = {
static void
hb_ot_shape_collect_features (hb_ot_shape_plan_t *plan,
- hb_segment_properties_t *props,
+ const hb_segment_properties_t *props,
const hb_feature_t *user_features,
unsigned int num_user_features)
{
@@ -70,7 +70,7 @@ hb_ot_shape_collect_features (hb_ot_shape_plan_t *plan,
for (unsigned int i = 0; i < ARRAY_LENGTH (default_features); i++)
plan->map.add_bool_feature (default_features[i]);
- /* complex */
+ hb_ot_shape_complex_collect_features (plan, props);
for (unsigned int i = 0; i < num_user_features; i++) {
const hb_feature_t *feature = &user_features[i];
@@ -321,10 +321,12 @@ hb_ot_shape_internal (hb_ot_shape_context_t *c)
void
hb_ot_shape_plan_internal (hb_ot_shape_plan_t *plan,
hb_face_t *face,
- hb_segment_properties_t *props,
+ const hb_segment_properties_t *props,
const hb_feature_t *user_features,
unsigned int num_user_features)
{
+ plan->shaper = hb_ot_shape_complex_categorize (props);
+
hb_ot_shape_collect_features (plan, props, user_features, num_user_features);
plan->map.compile (face, props);
commit 605ed468f380f86d642031f6451447d270cb6de1
Author: Behdad Esfahbod <behdad at behdad.org>
Date: Tue Oct 12 16:19:29 2010 -0400
Add hb_ot_shape_plan_t
This is the object that a separate plan/execute shaping API will use in
between the two stages.
diff --git a/src/hb-ot-shape-private.hh b/src/hb-ot-shape-private.hh
index 3f47fa2..de1cb3b 100644
--- a/src/hb-ot-shape-private.hh
+++ b/src/hb-ot-shape-private.hh
@@ -35,8 +35,16 @@
HB_BEGIN_DECLS
-struct hb_ot_map_t;
+enum hb_ot_complex_shaper_t {
+ hb_ot_complex_shaper_none,
+ hb_ot_complex_shaper_arabic
+};
+struct hb_ot_shape_plan_t
+{
+ hb_ot_map_t map;
+ hb_ot_complex_shaper_t shaper;
+};
struct hb_ot_shape_context_t
{
@@ -52,7 +60,7 @@ struct hb_ot_shape_context_t
hb_bool_t applied_substitute_complex;
hb_bool_t applied_position_complex;
- struct hb_ot_map_t *map;
+ hb_ot_shape_plan_t *plan;
};
diff --git a/src/hb-ot-shape.cc b/src/hb-ot-shape.cc
index f2bf848..061c203 100644
--- a/src/hb-ot-shape.cc
+++ b/src/hb-ot-shape.cc
@@ -28,8 +28,6 @@
#include "hb-ot-shape-private.hh"
-#include "hb-ot-map-private.hh"
-
HB_BEGIN_DECLS
@@ -49,19 +47,19 @@ hb_tag_t default_features[] = {
};
static void
-hb_ot_shape_collect_features (hb_ot_map_t *map,
+hb_ot_shape_collect_features (hb_ot_shape_plan_t *plan,
hb_segment_properties_t *props,
const hb_feature_t *user_features,
unsigned int num_user_features)
{
switch (props->direction) {
case HB_DIRECTION_LTR:
- map->add_bool_feature (HB_TAG ('l','t','r','a'));
- map->add_bool_feature (HB_TAG ('l','t','r','m'));
+ plan->map.add_bool_feature (HB_TAG ('l','t','r','a'));
+ plan->map.add_bool_feature (HB_TAG ('l','t','r','m'));
break;
case HB_DIRECTION_RTL:
- map->add_bool_feature (HB_TAG ('r','t','l','a'));
- map->add_bool_feature (HB_TAG ('r','t','l','m'), false);
+ plan->map.add_bool_feature (HB_TAG ('r','t','l','a'));
+ plan->map.add_bool_feature (HB_TAG ('r','t','l','m'), false);
break;
case HB_DIRECTION_TTB:
case HB_DIRECTION_BTT:
@@ -70,13 +68,13 @@ hb_ot_shape_collect_features (hb_ot_map_t *map,
}
for (unsigned int i = 0; i < ARRAY_LENGTH (default_features); i++)
- map->add_bool_feature (default_features[i]);
+ plan->map.add_bool_feature (default_features[i]);
/* complex */
for (unsigned int i = 0; i < num_user_features; i++) {
const hb_feature_t *feature = &user_features[i];
- map->add_feature (feature->tag, feature->value, (feature->start == 0 && feature->end == (unsigned int) -1));
+ plan->map.add_feature (feature->tag, feature->value, (feature->start == 0 && feature->end == (unsigned int) -1));
}
}
@@ -84,7 +82,7 @@ hb_ot_shape_collect_features (hb_ot_map_t *map,
static void
hb_ot_shape_setup_masks (hb_ot_shape_context_t *c)
{
- hb_mask_t global_mask = c->map->get_global_mask ();
+ hb_mask_t global_mask = c->plan->map.get_global_mask ();
if (global_mask)
c->buffer->set_masks (global_mask, global_mask, 0, (unsigned int) -1);
@@ -93,7 +91,7 @@ hb_ot_shape_setup_masks (hb_ot_shape_context_t *c)
const hb_feature_t *feature = &c->user_features[i];
if (!(feature->start == 0 && feature->end == (unsigned int)-1)) {
unsigned int shift;
- hb_mask_t mask = c->map->get_mask (feature->tag, &shift);
+ hb_mask_t mask = c->plan->map.get_mask (feature->tag, &shift);
c->buffer->set_masks (feature->value << shift, mask, feature->start, feature->end);
}
}
@@ -108,7 +106,7 @@ hb_ot_substitute_complex (hb_ot_shape_context_t *c)
if (!hb_ot_layout_has_substitution (c->face))
return;
- c->map->substitute (c->face, c->buffer);
+ c->plan->map.substitute (c->face, c->buffer);
c->applied_substitute_complex = TRUE;
return;
@@ -121,7 +119,7 @@ hb_ot_position_complex (hb_ot_shape_context_t *c)
if (!hb_ot_layout_has_positioning (c->face))
return;
- c->map->position (c->font, c->face, c->buffer);
+ c->plan->map.position (c->font, c->face, c->buffer);
hb_ot_layout_position_finish (c->font, c->face, c->buffer);
@@ -176,7 +174,7 @@ hb_mirror_chars (hb_ot_shape_context_t *c)
if (HB_DIRECTION_IS_FORWARD (c->buffer->props.direction))
return;
- hb_mask_t rtlm_mask = c->map->get_mask (HB_TAG ('r','t','l','m'));
+ hb_mask_t rtlm_mask = c->plan->map.get_mask (HB_TAG ('r','t','l','m'));
unsigned int count = c->buffer->len;
for (unsigned int i = 0; i < count; i++) {
@@ -321,15 +319,15 @@ hb_ot_shape_internal (hb_ot_shape_context_t *c)
}
void
-hb_ot_shape_plan_internal (hb_ot_map_t *map,
+hb_ot_shape_plan_internal (hb_ot_shape_plan_t *plan,
hb_face_t *face,
hb_segment_properties_t *props,
const hb_feature_t *user_features,
unsigned int num_user_features)
{
- hb_ot_shape_collect_features (map, props, user_features, num_user_features);
+ hb_ot_shape_collect_features (plan, props, user_features, num_user_features);
- map->compile (face, props);
+ plan->map.compile (face, props);
}
void
@@ -339,12 +337,12 @@ hb_ot_shape (hb_font_t *font,
const hb_feature_t *user_features,
unsigned int num_user_features)
{
- hb_ot_map_t map;
+ hb_ot_shape_plan_t plan;
- hb_ot_shape_plan_internal (&map, face, &buffer->props, user_features, num_user_features);
+ hb_ot_shape_plan_internal (&plan, face, &buffer->props, user_features, num_user_features);
hb_ot_shape_context_t c = {font, face, buffer, user_features, num_user_features};
- c.map = ↦
+ c.plan = &plan;
hb_ot_shape_internal (&c);
}
commit 895fb5d364e7ae5d9d2e34b9f68b8651804369ef
Author: Behdad Esfahbod <behdad at behdad.org>
Date: Tue Oct 12 16:00:21 2010 -0400
Refactor, in a different direction
diff --git a/src/hb-ot-map-private.hh b/src/hb-ot-map-private.hh
index abf96f2..0c05742 100644
--- a/src/hb-ot-map-private.hh
+++ b/src/hb-ot-map-private.hh
@@ -29,7 +29,7 @@
#ifndef HB_OT_MAP_PRIVATE_HH
#define HB_OT_MAP_PRIVATE_HH
-#include "hb-ot-shape-private.hh"
+#include "hb-buffer-private.hh"
#include "hb-ot-layout.h"
@@ -73,7 +73,7 @@ struct hb_ot_map_t {
{ return a->index < b->index ? -1 : a->index > b->index ? 1 : 0; }
};
- HB_INTERNAL void add_lookups (hb_ot_shape_plan_context_t *c,
+ HB_INTERNAL void add_lookups (hb_face_t *face,
unsigned int table_index,
unsigned int feature_index,
hb_mask_t mask);
@@ -95,7 +95,8 @@ struct hb_ot_map_t {
inline void add_bool_feature (hb_tag_t tag, bool global = true)
{ add_feature (tag, 1, global); }
- HB_INTERNAL void compile (hb_ot_shape_plan_context_t *c);
+ HB_INTERNAL void compile (hb_face_t *face,
+ hb_segment_properties_t *props);
hb_mask_t get_global_mask (void) const { return global_mask; }
@@ -105,14 +106,14 @@ struct hb_ot_map_t {
return map ? map->mask : 0;
}
- inline void substitute (hb_ot_shape_context_t *c) const {
+ inline void substitute (hb_face_t *face, hb_buffer_t *buffer) const {
for (unsigned int i = 0; i < lookup_count[0]; i++)
- hb_ot_layout_substitute_lookup (c->face, c->buffer, lookup_maps[0][i].index, lookup_maps[0][i].mask);
+ hb_ot_layout_substitute_lookup (face, buffer, lookup_maps[0][i].index, lookup_maps[0][i].mask);
}
- inline void position (hb_ot_shape_context_t *c) const {
+ inline void position (hb_font_t *font, hb_face_t *face, hb_buffer_t *buffer) const {
for (unsigned int i = 0; i < lookup_count[1]; i++)
- hb_ot_layout_position_lookup (c->font, c->face, c->buffer, lookup_maps[1][i].index, lookup_maps[1][i].mask);
+ hb_ot_layout_position_lookup (font, face, buffer, lookup_maps[1][i].index, lookup_maps[1][i].mask);
}
private:
diff --git a/src/hb-ot-map.cc b/src/hb-ot-map.cc
index 84149b8..2205624 100644
--- a/src/hb-ot-map.cc
+++ b/src/hb-ot-map.cc
@@ -34,7 +34,7 @@ HB_BEGIN_DECLS
void
-hb_ot_map_t::add_lookups (hb_ot_shape_plan_context_t *c,
+hb_ot_map_t::add_lookups (hb_face_t *face,
unsigned int table_index,
unsigned int feature_index,
hb_mask_t mask)
@@ -44,7 +44,7 @@ hb_ot_map_t::add_lookups (hb_ot_shape_plan_context_t *c,
unsigned int *lookup_indices = (unsigned int *) lookups;
- hb_ot_layout_feature_get_lookup_indexes (c->face,
+ hb_ot_layout_feature_get_lookup_indexes (face,
table_tags[table_index],
feature_index,
0, &i,
@@ -60,7 +60,8 @@ hb_ot_map_t::add_lookups (hb_ot_shape_plan_context_t *c,
void
-hb_ot_map_t::compile (hb_ot_shape_plan_context_t *c)
+hb_ot_map_t::compile (hb_face_t *face,
+ hb_segment_properties_t *props)
{
global_mask = 0;
lookup_count[0] = lookup_count[1] = 0;
@@ -75,14 +76,14 @@ hb_ot_map_t::compile (hb_ot_shape_plan_context_t *c)
const hb_tag_t *script_tags;
hb_tag_t language_tag;
- script_tags = hb_ot_tags_from_script (c->props->script);
- language_tag = hb_ot_tag_from_language (c->props->language);
+ script_tags = hb_ot_tags_from_script (props->script);
+ language_tag = hb_ot_tag_from_language (props->language);
unsigned int script_index[2], language_index[2];
for (unsigned int table_index = 0; table_index < 2; table_index++) {
hb_tag_t table_tag = table_tags[table_index];
- hb_ot_layout_table_choose_script (c->face, table_tag, script_tags, &script_index[table_index]);
- hb_ot_layout_script_find_language (c->face, table_tag, script_index[table_index], language_tag, &language_index[table_index]);
+ hb_ot_layout_table_choose_script (face, table_tag, script_tags, &script_index[table_index]);
+ hb_ot_layout_script_find_language (face, table_tag, script_index[table_index], language_tag, &language_index[table_index]);
}
@@ -124,7 +125,7 @@ hb_ot_map_t::compile (hb_ot_shape_plan_context_t *c)
bool found = false;
unsigned int feature_index[2];
for (unsigned int table_index = 0; table_index < 2; table_index++)
- found |= hb_ot_layout_language_find_feature (c->face,
+ found |= hb_ot_layout_language_find_feature (face,
table_tags[table_index],
script_index[table_index],
language_index[table_index],
@@ -161,15 +162,15 @@ hb_ot_map_t::compile (hb_ot_shape_plan_context_t *c)
/* Collect lookup indices for features */
unsigned int required_feature_index;
- if (hb_ot_layout_language_get_required_feature_index (c->face,
+ if (hb_ot_layout_language_get_required_feature_index (face,
table_tag,
script_index[table_index],
language_index[table_index],
&required_feature_index))
- add_lookups (c, table_index, required_feature_index, 1);
+ add_lookups (face, table_index, required_feature_index, 1);
for (unsigned i = 0; i < feature_count; i++)
- add_lookups (c, table_index, feature_maps[i].index[table_index], feature_maps[i].mask);
+ add_lookups (face, table_index, feature_maps[i].index[table_index], feature_maps[i].mask);
/* Sort lookups and merge duplicates */
qsort (lookup_maps[table_index], lookup_count[table_index], sizeof (lookup_maps[table_index][0]), (hb_compare_func_t) lookup_map_t::cmp);
diff --git a/src/hb-ot-shape-private.hh b/src/hb-ot-shape-private.hh
index 0d21e88..3f47fa2 100644
--- a/src/hb-ot-shape-private.hh
+++ b/src/hb-ot-shape-private.hh
@@ -31,23 +31,12 @@
#include "hb-ot-shape.h"
-#include "hb-buffer-private.hh"
+#include "hb-ot-map-private.hh"
HB_BEGIN_DECLS
struct hb_ot_map_t;
-struct hb_ot_shape_plan_context_t
-{
- struct hb_ot_map_t *map;
-
- hb_face_t *face;
- hb_segment_properties_t *props;
-
- const hb_feature_t *user_features;
- unsigned int num_user_features;
-};
-
struct hb_ot_shape_context_t
{
diff --git a/src/hb-ot-shape.cc b/src/hb-ot-shape.cc
index b0494c7..f2bf848 100644
--- a/src/hb-ot-shape.cc
+++ b/src/hb-ot-shape.cc
@@ -49,16 +49,19 @@ hb_tag_t default_features[] = {
};
static void
-hb_ot_shape_collect_features (hb_ot_shape_plan_context_t *c)
+hb_ot_shape_collect_features (hb_ot_map_t *map,
+ hb_segment_properties_t *props,
+ const hb_feature_t *user_features,
+ unsigned int num_user_features)
{
- switch (c->props->direction) {
+ switch (props->direction) {
case HB_DIRECTION_LTR:
- c->map->add_bool_feature (HB_TAG ('l','t','r','a'));
- c->map->add_bool_feature (HB_TAG ('l','t','r','m'));
+ map->add_bool_feature (HB_TAG ('l','t','r','a'));
+ map->add_bool_feature (HB_TAG ('l','t','r','m'));
break;
case HB_DIRECTION_RTL:
- c->map->add_bool_feature (HB_TAG ('r','t','l','a'));
- c->map->add_bool_feature (HB_TAG ('r','t','l','m'), false);
+ map->add_bool_feature (HB_TAG ('r','t','l','a'));
+ map->add_bool_feature (HB_TAG ('r','t','l','m'), false);
break;
case HB_DIRECTION_TTB:
case HB_DIRECTION_BTT:
@@ -67,13 +70,13 @@ hb_ot_shape_collect_features (hb_ot_shape_plan_context_t *c)
}
for (unsigned int i = 0; i < ARRAY_LENGTH (default_features); i++)
- c->map->add_bool_feature (default_features[i]);
+ map->add_bool_feature (default_features[i]);
/* complex */
- for (unsigned int i = 0; i < c->num_user_features; i++) {
- const hb_feature_t *feature = &c->user_features[i];
- c->map->add_feature (feature->tag, feature->value, (feature->start == 0 && feature->end == (unsigned int) -1));
+ for (unsigned int i = 0; i < num_user_features; i++) {
+ const hb_feature_t *feature = &user_features[i];
+ map->add_feature (feature->tag, feature->value, (feature->start == 0 && feature->end == (unsigned int) -1));
}
}
@@ -105,7 +108,7 @@ hb_ot_substitute_complex (hb_ot_shape_context_t *c)
if (!hb_ot_layout_has_substitution (c->face))
return;
- c->map->substitute (c);
+ c->map->substitute (c->face, c->buffer);
c->applied_substitute_complex = TRUE;
return;
@@ -118,7 +121,7 @@ hb_ot_position_complex (hb_ot_shape_context_t *c)
if (!hb_ot_layout_has_positioning (c->face))
return;
- c->map->position (c);
+ c->map->position (c->font, c->face, c->buffer);
hb_ot_layout_position_finish (c->font, c->face, c->buffer);
@@ -324,11 +327,9 @@ hb_ot_shape_plan_internal (hb_ot_map_t *map,
const hb_feature_t *user_features,
unsigned int num_user_features)
{
- hb_ot_shape_plan_context_t c = {map, face, props, user_features, num_user_features};
-
- hb_ot_shape_collect_features (&c);
+ hb_ot_shape_collect_features (map, props, user_features, num_user_features);
- map->compile (&c);
+ map->compile (face, props);
}
void
commit d2ba016ca1ba7489537768b619980d5159b5870c
Author: Behdad Esfahbod <behdad at behdad.org>
Date: Tue Oct 12 15:35:45 2010 -0400
More refactoring
diff --git a/src/hb-ot-map-private.hh b/src/hb-ot-map-private.hh
index 816ce4f..abf96f2 100644
--- a/src/hb-ot-map-private.hh
+++ b/src/hb-ot-map-private.hh
@@ -73,32 +73,10 @@ struct hb_ot_map_t {
{ return a->index < b->index ? -1 : a->index > b->index ? 1 : 0; }
};
-
- void
- add_lookups (hb_ot_shape_context_t *c,
- unsigned int table_index,
- unsigned int feature_index,
- hb_mask_t mask)
- {
- unsigned int i = MAX_LOOKUPS - lookup_count[table_index];
- lookup_map_t *lookups = lookup_maps[table_index] + lookup_count[table_index];
-
- unsigned int *lookup_indices = (unsigned int *) lookups;
-
- hb_ot_layout_feature_get_lookup_indexes (c->face,
- table_tags[table_index],
- feature_index,
- 0, &i,
- lookup_indices);
-
- lookup_count[table_index] += i;
-
- while (i--) {
- lookups[i].mask = mask;
- lookups[i].index = lookup_indices[i];
- }
- }
-
+ HB_INTERNAL void add_lookups (hb_ot_shape_plan_context_t *c,
+ unsigned int table_index,
+ unsigned int feature_index,
+ hb_mask_t mask);
public:
@@ -117,7 +95,7 @@ struct hb_ot_map_t {
inline void add_bool_feature (hb_tag_t tag, bool global = true)
{ add_feature (tag, 1, global); }
- HB_INTERNAL void compile (hb_ot_shape_context_t *c);
+ HB_INTERNAL void compile (hb_ot_shape_plan_context_t *c);
hb_mask_t get_global_mask (void) const { return global_mask; }
diff --git a/src/hb-ot-map.cc b/src/hb-ot-map.cc
index 8cf21b4..84149b8 100644
--- a/src/hb-ot-map.cc
+++ b/src/hb-ot-map.cc
@@ -34,7 +34,33 @@ HB_BEGIN_DECLS
void
-hb_ot_map_t::compile (hb_ot_shape_context_t *c)
+hb_ot_map_t::add_lookups (hb_ot_shape_plan_context_t *c,
+ unsigned int table_index,
+ unsigned int feature_index,
+ hb_mask_t mask)
+{
+ unsigned int i = MAX_LOOKUPS - lookup_count[table_index];
+ lookup_map_t *lookups = lookup_maps[table_index] + lookup_count[table_index];
+
+ unsigned int *lookup_indices = (unsigned int *) lookups;
+
+ hb_ot_layout_feature_get_lookup_indexes (c->face,
+ table_tags[table_index],
+ feature_index,
+ 0, &i,
+ lookup_indices);
+
+ lookup_count[table_index] += i;
+
+ while (i--) {
+ lookups[i].mask = mask;
+ lookups[i].index = lookup_indices[i];
+ }
+}
+
+
+void
+hb_ot_map_t::compile (hb_ot_shape_plan_context_t *c)
{
global_mask = 0;
lookup_count[0] = lookup_count[1] = 0;
@@ -49,8 +75,8 @@ hb_ot_map_t::compile (hb_ot_shape_context_t *c)
const hb_tag_t *script_tags;
hb_tag_t language_tag;
- script_tags = hb_ot_tags_from_script (c->buffer->props.script);
- language_tag = hb_ot_tag_from_language (c->buffer->props.language);
+ script_tags = hb_ot_tags_from_script (c->props->script);
+ language_tag = hb_ot_tag_from_language (c->props->language);
unsigned int script_index[2], language_index[2];
for (unsigned int table_index = 0; table_index < 2; table_index++) {
diff --git a/src/hb-ot-shape-private.hh b/src/hb-ot-shape-private.hh
index b00be33..0d21e88 100644
--- a/src/hb-ot-shape-private.hh
+++ b/src/hb-ot-shape-private.hh
@@ -37,14 +37,26 @@ HB_BEGIN_DECLS
struct hb_ot_map_t;
+struct hb_ot_shape_plan_context_t
+{
+ struct hb_ot_map_t *map;
+
+ hb_face_t *face;
+ hb_segment_properties_t *props;
+
+ const hb_feature_t *user_features;
+ unsigned int num_user_features;
+};
+
+
struct hb_ot_shape_context_t
{
/* Input to hb_ot_shape() */
hb_font_t *font;
hb_face_t *face;
hb_buffer_t *buffer;
- hb_feature_t *features;
- unsigned int num_features;
+ const hb_feature_t *user_features;
+ unsigned int num_user_features;
/* Transient stuff */
hb_direction_t original_direction;
diff --git a/src/hb-ot-shape.cc b/src/hb-ot-shape.cc
index 8fc9c4f..b0494c7 100644
--- a/src/hb-ot-shape.cc
+++ b/src/hb-ot-shape.cc
@@ -49,9 +49,9 @@ hb_tag_t default_features[] = {
};
static void
-hb_ot_shape_collect_features (hb_ot_shape_context_t *c)
+hb_ot_shape_collect_features (hb_ot_shape_plan_context_t *c)
{
- switch (c->original_direction) {
+ switch (c->props->direction) {
case HB_DIRECTION_LTR:
c->map->add_bool_feature (HB_TAG ('l','t','r','a'));
c->map->add_bool_feature (HB_TAG ('l','t','r','m'));
@@ -71,8 +71,8 @@ hb_ot_shape_collect_features (hb_ot_shape_context_t *c)
/* complex */
- for (unsigned int i = 0; i < c->num_features; i++) {
- const hb_feature_t *feature = &c->features[i];
+ for (unsigned int i = 0; i < c->num_user_features; i++) {
+ const hb_feature_t *feature = &c->user_features[i];
c->map->add_feature (feature->tag, feature->value, (feature->start == 0 && feature->end == (unsigned int) -1));
}
}
@@ -85,9 +85,9 @@ hb_ot_shape_setup_masks (hb_ot_shape_context_t *c)
if (global_mask)
c->buffer->set_masks (global_mask, global_mask, 0, (unsigned int) -1);
- for (unsigned int i = 0; i < c->num_features; i++)
+ for (unsigned int i = 0; i < c->num_user_features; i++)
{
- hb_feature_t *feature = &c->features[i];
+ const hb_feature_t *feature = &c->user_features[i];
if (!(feature->start == 0 && feature->end == (unsigned int)-1)) {
unsigned int shift;
hb_mask_t mask = c->map->get_mask (feature->tag, &shift);
@@ -271,6 +271,9 @@ hb_position_complex_fallback_visual (hb_ot_shape_context_t *c)
static void
hb_ot_shape_internal (hb_ot_shape_context_t *c)
{
+ /* Save the original direction, we use it later. */
+ c->original_direction = c->buffer->props.direction;
+
hb_ot_shape_setup_masks (c);
hb_form_clusters (c);
@@ -315,22 +318,32 @@ hb_ot_shape_internal (hb_ot_shape_context_t *c)
}
void
+hb_ot_shape_plan_internal (hb_ot_map_t *map,
+ hb_face_t *face,
+ hb_segment_properties_t *props,
+ const hb_feature_t *user_features,
+ unsigned int num_user_features)
+{
+ hb_ot_shape_plan_context_t c = {map, face, props, user_features, num_user_features};
+
+ hb_ot_shape_collect_features (&c);
+
+ map->compile (&c);
+}
+
+void
hb_ot_shape (hb_font_t *font,
hb_face_t *face,
hb_buffer_t *buffer,
- hb_feature_t *features,
- unsigned int num_features)
+ const hb_feature_t *user_features,
+ unsigned int num_user_features)
{
- hb_ot_shape_context_t c = {font, face, buffer, features, num_features};
hb_ot_map_t map;
- /* Setup transient context members */
- c.original_direction = buffer->props.direction;
- c.map = ↦
-
- hb_ot_shape_collect_features (&c);
- c.map->compile (&c);
+ hb_ot_shape_plan_internal (&map, face, &buffer->props, user_features, num_user_features);
+ hb_ot_shape_context_t c = {font, face, buffer, user_features, num_user_features};
+ c.map = ↦
hb_ot_shape_internal (&c);
}
diff --git a/src/hb-ot-shape.h b/src/hb-ot-shape.h
index 182d951..c90e0fe 100644
--- a/src/hb-ot-shape.h
+++ b/src/hb-ot-shape.h
@@ -34,11 +34,11 @@ HB_BEGIN_DECLS
void
-hb_ot_shape (hb_font_t *font,
- hb_face_t *face,
- hb_buffer_t *buffer,
- hb_feature_t *features,
- unsigned int num_features);
+hb_ot_shape (hb_font_t *font,
+ hb_face_t *face,
+ hb_buffer_t *buffer,
+ const hb_feature_t *user_features,
+ unsigned int num_user_features);
HB_END_DECLS
commit 66e487dfbfdccd0c4be8cd11661d412ca27c3425
Author: Behdad Esfahbod <behdad at behdad.org>
Date: Tue Oct 12 13:51:19 2010 -0400
Update Arabic shaping table to Unicode 6.0.0.
diff --git a/src/hb-ot-shape-arabic.cc b/src/hb-ot-shape-arabic.cc
index 7729be1..fb5182b 100644
--- a/src/hb-ot-shape-arabic.cc
+++ b/src/hb-ot-shape-arabic.cc
@@ -64,8 +64,8 @@ static const uint8_t arabic_syriac_nko_joining_types[0x0800 - 0x0600 + 1] =
*
* on the ArabicShaping.txt file with the header:
*
- * # ArabicShaping-5.2.0.txt
- * # Date: 2009-08-17, 11:11:00 PDT [KW]
+ * # ArabicShaping-6.0.0.txt
+ * # Date: 2010-04-30, 13:47:00 PDT [KW]
*/
/* == Start of generated table == */
JOINING_TYPE_U, /* 0600; ARABIC NUMBER SIGN; U; No_Joining_Group */
@@ -100,7 +100,7 @@ static const uint8_t arabic_syriac_nko_joining_types[0x0800 - 0x0600 + 1] =
JOINING_TYPE_X, /* 061D */
JOINING_TYPE_X, /* 061E */
JOINING_TYPE_X, /* 061F */
- JOINING_TYPE_X, /* 0620 */
+ JOINING_TYPE_D, /* 0620; YEH WITH RING; D; YEH */
JOINING_TYPE_U, /* 0621; HAMZA; U; No_Joining_Group */
JOINING_TYPE_R, /* 0622; MADDA ON ALEF; R; ALEF */
JOINING_TYPE_R, /* 0623; HAMZA ON ALEF; R; ALEF */
@@ -263,7 +263,7 @@ static const uint8_t arabic_syriac_nko_joining_types[0x0800 - 0x0600 + 1] =
JOINING_TYPE_R, /* 06C0; HAMZA ON HEH; R; TEH MARBUTA */
JOINING_TYPE_D, /* 06C1; HEH GOAL; D; HEH GOAL */
JOINING_TYPE_D, /* 06C2; HAMZA ON HEH GOAL; D; HEH GOAL */
- JOINING_TYPE_R, /* 06C3; TEH MARBUTA GOAL; R; HAMZA ON HEH GOAL */
+ JOINING_TYPE_R, /* 06C3; TEH MARBUTA GOAL; R; TEH MARBUTA GOAL */
JOINING_TYPE_R, /* 06C4; WAW WITH RING; R; WAW */
JOINING_TYPE_R, /* 06C5; WAW WITH BAR; R; WAW */
JOINING_TYPE_R, /* 06C6; WAW WITH SMALL V; R; WAW */
More information about the HarfBuzz
mailing list