[HarfBuzz] harfbuzz-ng: Branch 'master' - 8 commits
Behdad Esfahbod
behdad at kemper.freedesktop.org
Thu Aug 2 11:27:00 PDT 2012
src/hb-ot-map-private.hh | 26 -
src/hb-ot-map.cc | 28 -
src/hb-ot-shape-complex-arabic.cc | 27 -
src/hb-ot-shape-complex-indic-machine.rl | 4
src/hb-ot-shape-complex-indic-private.hh | 16
src/hb-ot-shape-complex-indic.cc | 637 ++++++++++++++++---------------
src/hb-ot-shape-complex-misc.cc | 24 -
src/hb-ot-shape-complex-private.hh | 48 +-
src/hb-ot-shape-private.hh | 45 ++
src/hb-ot-shape.cc | 82 +--
src/hb-shape-plan.cc | 2
src/hb-shape.cc | 2
12 files changed, 504 insertions(+), 437 deletions(-)
New commits:
commit 11b0e20ba42bf0b17133c3e1087732802bb4f230
Author: Behdad Esfahbod <behdad at behdad.org>
Date: Thu Aug 2 14:21:40 2012 -0400
[Indic] Add per-script configuration tables
This concludes the Indic shape_plan work. May do for Arabic also...
diff --git a/src/hb-ot-shape-complex-indic-private.hh b/src/hb-ot-shape-complex-indic-private.hh
index d4cfe0d..719d287 100644
--- a/src/hb-ot-shape-complex-indic-private.hh
+++ b/src/hb-ot-shape-complex-indic-private.hh
@@ -157,8 +157,8 @@ enum indic_matra_category_t {
#define IS_DEVA(u) (IN_HALF_BLOCK (u, 0x0900))
#define IS_BENG(u) (IN_HALF_BLOCK (u, 0x0980))
-#define IS_GURM(u) (IN_HALF_BLOCK (u, 0x0A00))
-#define IS_GUJA(u) (IN_HALF_BLOCK (u, 0x0A80))
+#define IS_GURU(u) (IN_HALF_BLOCK (u, 0x0A00))
+#define IS_GUJR(u) (IN_HALF_BLOCK (u, 0x0A80))
#define IS_ORYA(u) (IN_HALF_BLOCK (u, 0x0B00))
#define IS_TAML(u) (IN_HALF_BLOCK (u, 0x0B80))
#define IS_TELU(u) (IN_HALF_BLOCK (u, 0x0C00))
@@ -172,8 +172,8 @@ enum indic_matra_category_t {
#define MATRA_POS_RIGHT(u) ( \
IS_DEVA(u) ? POS_AFTER_SUB : \
IS_BENG(u) ? POS_AFTER_POST : \
- IS_GURM(u) ? POS_AFTER_POST : \
- IS_GUJA(u) ? POS_AFTER_POST : \
+ IS_GURU(u) ? POS_AFTER_POST : \
+ IS_GUJR(u) ? POS_AFTER_POST : \
IS_ORYA(u) ? POS_AFTER_POST : \
IS_TAML(u) ? POS_AFTER_POST : \
IS_TELU(u) ? (u <= 0x0C42 ? POS_BEFORE_SUB : POS_AFTER_SUB) : \
@@ -185,8 +185,8 @@ enum indic_matra_category_t {
)
#define MATRA_POS_TOP(u) ( /* BENG and MLYM don't have top matras. */ \
IS_DEVA(u) ? POS_AFTER_SUB : \
- IS_GURM(u) ? POS_AFTER_POST : /* Deviate from spec */ \
- IS_GUJA(u) ? POS_AFTER_SUB : \
+ IS_GURU(u) ? POS_AFTER_POST : /* Deviate from spec */ \
+ IS_GUJR(u) ? POS_AFTER_SUB : \
IS_ORYA(u) ? POS_AFTER_MAIN : \
IS_TAML(u) ? POS_AFTER_SUB : \
IS_TELU(u) ? POS_BEFORE_SUB : \
@@ -198,8 +198,8 @@ enum indic_matra_category_t {
#define MATRA_POS_BOTTOM(u) ( \
IS_DEVA(u) ? POS_AFTER_SUB : \
IS_BENG(u) ? POS_AFTER_SUB : \
- IS_GURM(u) ? POS_AFTER_POST : \
- IS_GUJA(u) ? POS_AFTER_POST : \
+ IS_GURU(u) ? POS_AFTER_POST : \
+ IS_GUJR(u) ? POS_AFTER_POST : \
IS_ORYA(u) ? POS_AFTER_SUB : \
IS_TAML(u) ? POS_AFTER_POST : \
IS_TELU(u) ? POS_BEFORE_SUB : \
diff --git a/src/hb-ot-shape-complex-indic.cc b/src/hb-ot-shape-complex-indic.cc
index f48abf4..7dde77d 100644
--- a/src/hb-ot-shape-complex-indic.cc
+++ b/src/hb-ot-shape-complex-indic.cc
@@ -25,23 +25,12 @@
*/
#include "hb-ot-shape-complex-indic-private.hh"
-#include "hb-ot-shape-private.hh"
#include "hb-ot-layout-private.hh"
-#define OLD_INDIC_TAG(script) (((hb_tag_t) script) | 0x20000000)
-#define IS_OLD_INDIC_TAG(tag) ( \
- (tag) == OLD_INDIC_TAG (HB_SCRIPT_BENGALI) || \
- (tag) == OLD_INDIC_TAG (HB_SCRIPT_DEVANAGARI) || \
- (tag) == OLD_INDIC_TAG (HB_SCRIPT_GUJARATI) || \
- (tag) == OLD_INDIC_TAG (HB_SCRIPT_GURMUKHI) || \
- (tag) == OLD_INDIC_TAG (HB_SCRIPT_KANNADA) || \
- (tag) == OLD_INDIC_TAG (HB_SCRIPT_MALAYALAM) || \
- (tag) == OLD_INDIC_TAG (HB_SCRIPT_ORIYA) || \
- (tag) == OLD_INDIC_TAG (HB_SCRIPT_TAMIL) || \
- (tag) == OLD_INDIC_TAG (HB_SCRIPT_TELUGU) || \
- 0)
-
+/*
+ * Global Indic shaper options.
+ */
struct indic_options_t
{
@@ -82,6 +71,65 @@ indic_options (void)
}
+/*
+ * Indic configurations. Note that we do not want to keep every single script-specific
+ * behavior in these tables necessarily. This should mainly be used for per-script
+ * properties that are cheaper keeping here, than in the code. Ie. if, say, one and
+ * only one script has an exception, that one script can be if'ed directly in the code,
+ * instead of adding a new flag in these structs.
+ */
+
+enum base_position_t {
+ BASE_POS_FIRST,
+ BASE_POS_LAST
+};
+enum reph_position_t {
+ REPH_POS_DEFAULT = POS_BEFORE_POST,
+
+ REPH_POS_AFTER_MAIN = POS_AFTER_MAIN,
+ REPH_POS_BEFORE_SUB = POS_BEFORE_SUB,
+ REPH_POS_AFTER_SUB = POS_AFTER_SUB,
+ REPH_POS_BEFORE_POST = POS_BEFORE_POST,
+ REPH_POS_AFTER_POST = POS_AFTER_POST
+};
+enum reph_mode_t {
+ REPH_MODE_IMPLICIT, /* Reph formed out of initial Ra,H sequence. */
+ REPH_MODE_EXPLICIT, /* Reph formed out of initial Ra,H,ZWJ sequence. */
+ REPH_MODE_VIS_REPHA, /* Encoded Repha character, no reordering needed. */
+ REPH_MODE_LOG_REPHA /* Encoded Repha character, needs reordering. */
+};
+struct indic_config_t
+{
+ hb_script_t script;
+ bool has_old_spec;
+ hb_codepoint_t virama;
+ base_position_t base_pos;
+ reph_position_t reph_pos;
+ reph_mode_t reph_mode;
+};
+
+static const indic_config_t indic_configs[] =
+{
+ /* Default. Should be first. */
+ {HB_SCRIPT_INVALID, false, 0,BASE_POS_LAST, REPH_POS_DEFAULT, REPH_MODE_IMPLICIT},
+ {HB_SCRIPT_DEVANAGARI,true, 0x094D,BASE_POS_LAST, REPH_POS_BEFORE_POST,REPH_MODE_IMPLICIT},
+ {HB_SCRIPT_BENGALI, true, 0x09CD,BASE_POS_LAST, REPH_POS_AFTER_SUB, REPH_MODE_IMPLICIT},
+ {HB_SCRIPT_GURMUKHI, true, 0x0A4D,BASE_POS_LAST, REPH_POS_BEFORE_SUB, REPH_MODE_IMPLICIT},
+ {HB_SCRIPT_GUJARATI, true, 0x0ACD,BASE_POS_LAST, REPH_POS_BEFORE_POST,REPH_MODE_IMPLICIT},
+ {HB_SCRIPT_ORIYA, true, 0x0B4D,BASE_POS_LAST, REPH_POS_AFTER_MAIN, REPH_MODE_IMPLICIT},
+ {HB_SCRIPT_TAMIL, true, 0x0BCD,BASE_POS_LAST, REPH_POS_AFTER_POST, REPH_MODE_IMPLICIT},
+ {HB_SCRIPT_TELUGU, true, 0x0C4D,BASE_POS_LAST, REPH_POS_AFTER_POST, REPH_MODE_EXPLICIT},
+ {HB_SCRIPT_KANNADA, true, 0x0CCD,BASE_POS_LAST, REPH_POS_AFTER_POST, REPH_MODE_IMPLICIT},
+ {HB_SCRIPT_MALAYALAM, true, 0x0D4D,BASE_POS_LAST, REPH_POS_AFTER_MAIN, REPH_MODE_LOG_REPHA},
+ {HB_SCRIPT_SINHALA, false,0x0DCA,BASE_POS_FIRST,REPH_POS_AFTER_MAIN, REPH_MODE_EXPLICIT},
+ {HB_SCRIPT_KHMER, false,0x17D2,BASE_POS_FIRST,REPH_POS_DEFAULT, REPH_MODE_VIS_REPHA},
+};
+
+
+
+/*
+ * Indic shaper.
+ */
struct feature_list_t {
hb_tag_t tag;
@@ -228,7 +276,7 @@ struct indic_shape_plan_t
hb_codepoint_t glyph = virama_glyph;
if (unlikely (virama_glyph == (hb_codepoint_t) -1))
{
- if (!font->get_glyph (virama, 0, &glyph))
+ if (!config->virama || !font->get_glyph (config->virama, 0, &glyph))
glyph = 0;
/* Technically speaking, the spec says we should apply 'locl' to virama too.
* Maybe one day... */
@@ -242,10 +290,9 @@ struct indic_shape_plan_t
return glyph != 0;
}
+ const indic_config_t *config;
bool is_old_spec;
-
- hb_codepoint_t virama;
hb_codepoint_t virama_glyph;
would_substitute_feature_t pref;
@@ -262,26 +309,15 @@ data_create_indic (const hb_ot_shape_plan_t *plan)
if (unlikely (!indic_plan))
return NULL;
- indic_plan->is_old_spec = IS_OLD_INDIC_TAG (plan->map.get_chosen_script (0));
- {
- hb_codepoint_t virama;
- switch ((int) plan->props.script) {
- case HB_SCRIPT_DEVANAGARI:virama = 0x094D; break;
- case HB_SCRIPT_BENGALI: virama = 0x09CD; break;
- case HB_SCRIPT_GURMUKHI: virama = 0x0A4D; break;
- case HB_SCRIPT_GUJARATI: virama = 0x0ACD; break;
- case HB_SCRIPT_ORIYA: virama = 0x0B4D; break;
- case HB_SCRIPT_TAMIL: virama = 0x0BCD; break;
- case HB_SCRIPT_TELUGU: virama = 0x0C4D; break;
- case HB_SCRIPT_KANNADA: virama = 0x0CCD; break;
- case HB_SCRIPT_MALAYALAM: virama = 0x0D4D; break;
- case HB_SCRIPT_SINHALA: virama = 0x0DCA; break;
- case HB_SCRIPT_KHMER: virama = 0x17D2; break;
- default: virama = 0; break;
+ indic_plan->config = &indic_configs[0];
+ for (unsigned int i = 1; i < ARRAY_LENGTH (indic_configs); i++)
+ if (plan->props.script == indic_configs[i].script) {
+ indic_plan->config = &indic_configs[i];
+ break;
}
- indic_plan->virama = virama;
- }
- indic_plan->virama_glyph = indic_plan->virama ? (hb_codepoint_t) -1 : 0;
+
+ indic_plan->is_old_spec = indic_plan->config->has_old_spec && ((plan->map.get_chosen_script (0) & 0x000000FF) != '2');
+ indic_plan->virama_glyph = (hb_codepoint_t) -1;
indic_plan->pref.init (&plan->map, HB_TAG('p','r','e','f'));
indic_plan->blwf.init (&plan->map, HB_TAG('b','l','w','f'));
@@ -397,9 +433,9 @@ initial_reordering_consonant_syllable (const hb_ot_shape_plan_t *plan, hb_buffer
start + 3 <= end &&
info[start].indic_category() == OT_Ra &&
info[start + 1].indic_category() == OT_H &&
- (unlikely (buffer->props.script == HB_SCRIPT_SINHALA || buffer->props.script == HB_SCRIPT_TELUGU) ?
- info[start + 2].indic_category() == OT_ZWJ /* In Sinhala & Telugu, form Reph only if ZWJ is present */:
- !is_joiner (info[start + 2] /* In other scripts, any joiner blocks Reph formation */ )
+ (/* TODO Handle other Reph modes. */
+ (indic_plan->config->reph_mode == REPH_MODE_IMPLICIT && !is_joiner (info[start + 2])) ||
+ (indic_plan->config->reph_mode == REPH_MODE_EXPLICIT && info[start + 2].indic_category() == OT_ZWJ)
))
{
limit += 2;
@@ -409,92 +445,84 @@ initial_reordering_consonant_syllable (const hb_ot_shape_plan_t *plan, hb_buffer
has_reph = true;
};
- enum base_position_t {
- BASE_FIRST,
- BASE_LAST
- } base_pos;
-
- switch ((hb_tag_t) buffer->props.script)
- {
- case HB_SCRIPT_SINHALA:
- case HB_SCRIPT_KHMER:
- base_pos = BASE_FIRST;
- break;
-
- default:
- base_pos = BASE_LAST;
- break;
- }
-
- if (base_pos == BASE_LAST)
+ switch (indic_plan->config->base_pos == BASE_POS_LAST)
{
- /* -> starting from the end of the syllable, move backwards */
- unsigned int i = end;
- bool seen_below = false;
- do {
- i--;
- /* -> until a consonant is found */
- if (is_consonant (info[i]))
- {
- /* -> that does not have a below-base or post-base form
- * (post-base forms have to follow below-base forms), */
- if (info[i].indic_position() != POS_BELOW_C &&
- (info[i].indic_position() != POS_POST_C || seen_below))
+ case BASE_POS_LAST:
+ {
+ /* -> starting from the end of the syllable, move backwards */
+ unsigned int i = end;
+ bool seen_below = false;
+ do {
+ i--;
+ /* -> until a consonant is found */
+ if (is_consonant (info[i]))
{
+ /* -> that does not have a below-base or post-base form
+ * (post-base forms have to follow below-base forms), */
+ if (info[i].indic_position() != POS_BELOW_C &&
+ (info[i].indic_position() != POS_POST_C || seen_below))
+ {
+ base = i;
+ break;
+ }
+ if (info[i].indic_position() == POS_BELOW_C)
+ seen_below = true;
+
+ /* -> or that is not a pre-base reordering Ra,
+ *
+ * IMPLEMENTATION NOTES:
+ *
+ * Our pre-base reordering Ra's are marked POS_BELOW, so will be skipped
+ * by the logic above already.
+ */
+
+ /* -> or arrive at the first consonant. The consonant stopped at will
+ * be the base. */
base = i;
- break;
}
- if (info[i].indic_position() == POS_BELOW_C)
- seen_below = true;
+ else
+ {
+ /* A ZWJ after a Halant stops the base search, and requests an explicit
+ * half form.
+ * A ZWJ before a Halant, requests a subjoined form instead, and hence
+ * search continues. This is particularly important for Bengali
+ * sequence Ra,H,Ya that shouls form Ya-Phalaa by subjoining Ya. */
+ if (start < i &&
+ info[i].indic_category() == OT_ZWJ &&
+ info[i - 1].indic_category() == OT_H)
+ break;
+ }
+ } while (i > limit);
+ }
+ break;
- /* -> or that is not a pre-base reordering Ra,
- *
- * IMPLEMENTATION NOTES:
- *
- * Our pre-base reordering Ra's are marked POS_BELOW, so will be skipped
- * by the logic above already.
- */
+ case BASE_POS_FIRST:
+ {
+ /* In scripts without half forms (eg. Khmer), the first consonant is always the base. */
- /* -> or arrive at the first consonant. The consonant stopped at will
- * be the base. */
- base = i;
- }
- else
- {
- /* A ZWJ after a Halant stops the base search, and requests an explicit
- * half form.
- * A ZWJ before a Halant, requests a subjoined form instead, and hence
- * search continues. This is particularly important for Bengali
- * sequence Ra,H,Ya that shouls form Ya-Phalaa by subjoining Ya. */
- if (start < i &&
- info[i].indic_category() == OT_ZWJ &&
- info[i - 1].indic_category() == OT_H)
- break;
- }
- } while (i > limit);
- }
- else
- {
- /* In scripts without half forms (eg. Khmer), the first consonant is always the base. */
+ if (!has_reph)
+ base = limit;
- if (!has_reph)
- base = limit;
+ /* Find the last base consonant that is not blocked by ZWJ. If there is
+ * a ZWJ right before a base consonant, that would request a subjoined form. */
+ for (unsigned int i = limit; i < end; i++)
+ if (is_consonant (info[i]) && info[i].indic_position() == POS_BASE_C)
+ {
+ if (limit < i && info[i - 1].indic_category() == OT_ZWJ)
+ break;
+ else
+ base = i;
+ }
- /* Find the last base consonant that is not blocked by ZWJ. If there is
- * a ZWJ right before a base consonant, that would request a subjoined form. */
- for (unsigned int i = limit; i < end; i++)
- if (is_consonant (info[i]) && info[i].indic_position() == POS_BASE_C)
- {
- if (limit < i && info[i - 1].indic_category() == OT_ZWJ)
- break;
- else
- base = i;
- }
+ /* Mark all subsequent consonants as below. */
+ for (unsigned int i = base + 1; i < end; i++)
+ if (is_consonant (info[i]) && info[i].indic_position() == POS_BASE_C)
+ info[i].indic_position() = POS_BELOW_C;
+ }
+ break;
- /* Mark all subsequent consonants as below. */
- for (unsigned int i = base + 1; i < end; i++)
- if (is_consonant (info[i]) && info[i].indic_position() == POS_BASE_C)
- info[i].indic_position() = POS_BELOW_C;
+ default:
+ abort ();
}
/* -> If the syllable starts with Ra + Halant (in a script that has Reph)
@@ -864,50 +892,15 @@ final_reordering_syllable (const hb_ot_shape_plan_t *plan,
info[start].indic_position() == POS_RA_TO_BECOME_REPH &&
info[start + 1].indic_position() != POS_RA_TO_BECOME_REPH)
{
- unsigned int new_reph_pos;
-
- enum reph_position_t {
- REPH_AFTER_MAIN,
- REPH_BEFORE_SUBSCRIPT,
- REPH_AFTER_SUBSCRIPT,
- REPH_BEFORE_POSTSCRIPT,
- REPH_AFTER_POSTSCRIPT
- } reph_pos;
-
- /* XXX Figure out old behavior too */
- switch ((hb_tag_t) buffer->props.script)
- {
- case HB_SCRIPT_MALAYALAM:
- case HB_SCRIPT_ORIYA:
- case HB_SCRIPT_SINHALA:
- reph_pos = REPH_AFTER_MAIN;
- break;
-
- case HB_SCRIPT_GURMUKHI:
- reph_pos = REPH_BEFORE_SUBSCRIPT;
- break;
-
- case HB_SCRIPT_BENGALI:
- reph_pos = REPH_AFTER_SUBSCRIPT;
- break;
-
- default:
- case HB_SCRIPT_DEVANAGARI:
- case HB_SCRIPT_GUJARATI:
- reph_pos = REPH_BEFORE_POSTSCRIPT;
- break;
-
- case HB_SCRIPT_KANNADA:
- case HB_SCRIPT_TAMIL:
- case HB_SCRIPT_TELUGU:
- reph_pos = REPH_AFTER_POSTSCRIPT;
- break;
- }
+ unsigned int new_reph_pos;
+ reph_position_t reph_pos = indic_plan->config->reph_pos;
+
+ /* XXX Figure out old behavior too */
/* 1. If reph should be positioned after post-base consonant forms,
* proceed to step 5.
*/
- if (reph_pos == REPH_AFTER_POSTSCRIPT)
+ if (reph_pos == REPH_POS_AFTER_POST)
{
goto reph_step_5;
}
@@ -940,7 +933,7 @@ final_reordering_syllable (const hb_ot_shape_plan_t *plan,
* first consonant not ligated with main, or find the first
* consonant that is not a potential pre-base reordering Ra.
*/
- if (reph_pos == REPH_AFTER_MAIN)
+ if (reph_pos == REPH_POS_AFTER_MAIN)
{
new_reph_pos = base;
/* XXX Skip potential pre-base reordering Ra. */
@@ -956,7 +949,7 @@ final_reordering_syllable (const hb_ot_shape_plan_t *plan,
* first matra, syllable modifier sign or vedic sign.
*/
/* This is our take on what step 4 is trying to say (and failing, BADLY). */
- if (reph_pos == REPH_AFTER_SUBSCRIPT)
+ if (reph_pos == REPH_POS_AFTER_SUB)
{
new_reph_pos = base;
while (new_reph_pos < end &&
commit 85fc6c483f6d734febbe39270e84701a651f01f1
Author: Behdad Esfahbod <behdad at behdad.org>
Date: Thu Aug 2 12:21:44 2012 -0400
[Indic] Move more stuff to the shape_plan
Almost done. Need to add per-script static tables.
diff --git a/src/hb-ot-shape-complex-indic-machine.rl b/src/hb-ot-shape-complex-indic-machine.rl
index 25c0e65..b6a372e 100644
--- a/src/hb-ot-shape-complex-indic-machine.rl
+++ b/src/hb-ot-shape-complex-indic-machine.rl
@@ -92,14 +92,14 @@ main := |*
if (0) fprintf (stderr, "syllable %d..%d %s\n", last, p+1, #func); \
for (unsigned int i = last; i < p+1; i++) \
info[i].syllable() = syllable_serial; \
- PASTE (initial_reordering_, func) (plan, buffer, mask_array, last, p+1); \
+ PASTE (initial_reordering_, func) (plan, buffer, last, p+1); \
last = p+1; \
syllable_serial++; \
if (unlikely (!syllable_serial)) syllable_serial++; \
} HB_STMT_END
static void
-find_syllables (const hb_ot_shape_plan_t *plan, hb_buffer_t *buffer, hb_mask_t *mask_array)
+find_syllables (const hb_ot_shape_plan_t *plan, hb_buffer_t *buffer)
{
unsigned int p, pe, eof, ts, te, act;
int cs;
diff --git a/src/hb-ot-shape-complex-indic.cc b/src/hb-ot-shape-complex-indic.cc
index 57f3340..f48abf4 100644
--- a/src/hb-ot-shape-complex-indic.cc
+++ b/src/hb-ot-shape-complex-indic.cc
@@ -88,10 +88,13 @@ struct feature_list_t {
hb_bool_t is_global;
};
-/* These features are applied one at a time, given the order in this table. */
static const feature_list_t
-indic_basic_features[] =
+indic_features[] =
{
+ /*
+ * Basic features.
+ * These features are applied in order, one at a time, after initial_reordering.
+ */
{HB_TAG('n','u','k','t'), true},
{HB_TAG('a','k','h','n'), true},
{HB_TAG('r','p','h','f'), false},
@@ -104,9 +107,25 @@ indic_basic_features[] =
{HB_TAG('c','f','a','r'), false},
{HB_TAG('c','j','c','t'), true},
{HB_TAG('v','a','t','u'), true},
+ /*
+ * Other features.
+ * These features are applied all at once, after final_reordering.
+ */
+ {HB_TAG('i','n','i','t'), false},
+ {HB_TAG('p','r','e','s'), true},
+ {HB_TAG('a','b','v','s'), true},
+ {HB_TAG('b','l','w','s'), true},
+ {HB_TAG('p','s','t','s'), true},
+ {HB_TAG('h','a','l','n'), true},
+ /* Positioning features, though we don't care about the types. */
+ {HB_TAG('d','i','s','t'), true},
+ {HB_TAG('a','b','v','m'), true},
+ {HB_TAG('b','l','w','m'), true},
};
-/* Same order as the indic_basic_features array */
+/*
+ * Must be in the same order as the indic_features array.
+ */
enum {
_NUKT,
_AKHN,
@@ -119,26 +138,22 @@ enum {
PSTF,
CFAR,
_CJCT,
- VATU
+ _VATU,
+
+ INIT,
+ _PRES,
+ _ABVS,
+ _BLWS,
+ _PSTS,
+ _HALN,
+ _DIST,
+ _ABVM,
+ _BLWM,
+
+ INDIC_NUM_FEATURES,
+ INDIC_BASIC_FEATURES = INIT /* Don't forget to update this! */
};
-/* These features are applied all at once. */
-static const feature_list_t
-indic_other_features[] =
-{
- {HB_TAG('i','n','i','t'), false},
- {HB_TAG('p','r','e','s'), true},
- {HB_TAG('a','b','v','s'), true},
- {HB_TAG('b','l','w','s'), true},
- {HB_TAG('p','s','t','s'), true},
- {HB_TAG('h','a','l','n'), true},
-
- {HB_TAG('d','i','s','t'), true},
- {HB_TAG('a','b','v','m'), true},
- {HB_TAG('b','l','w','m'), true},
-};
-
-
static void
initial_reordering (const hb_ot_shape_plan_t *plan,
hb_font_t *font,
@@ -158,17 +173,17 @@ collect_features_indic (hb_ot_shape_planner_t *plan)
* there is a use of it, it's typically at the beginning. */
map->add_bool_feature (HB_TAG('c','c','m','p'));
- map->add_gsub_pause (initial_reordering);
- for (unsigned int i = 0; i < ARRAY_LENGTH (indic_basic_features); i++) {
- map->add_bool_feature (indic_basic_features[i].tag, indic_basic_features[i].is_global);
+ unsigned int i = 0;
+ map->add_gsub_pause (initial_reordering);
+ for (; i < INDIC_BASIC_FEATURES; i++) {
+ map->add_bool_feature (indic_features[i].tag, indic_features[i].is_global);
map->add_gsub_pause (NULL);
}
-
map->add_gsub_pause (final_reordering);
-
- for (unsigned int i = 0; i < ARRAY_LENGTH (indic_other_features); i++)
- map->add_bool_feature (indic_other_features[i].tag, indic_other_features[i].is_global);
+ for (; i < INDIC_NUM_FEATURES; i++) {
+ map->add_bool_feature (indic_features[i].tag, indic_features[i].is_global);
+ }
}
static void
@@ -180,9 +195,9 @@ override_features_indic (hb_ot_shape_planner_t *plan)
}
-struct would_apply_feature_t
+struct would_substitute_feature_t
{
- would_apply_feature_t (const hb_ot_map_t *map, hb_tag_t feature_tag)
+ inline void init (const hb_ot_map_t *map, hb_tag_t feature_tag)
{
map->get_stage_lookups (0/*GSUB*/,
map->get_feature_stage (0/*GSUB*/, feature_tag),
@@ -206,35 +221,7 @@ struct would_apply_feature_t
struct indic_shape_plan_t
{
- indic_shape_plan_t (const hb_ot_shape_plan_t *plan) :
- pref (&plan->map, HB_TAG('p','r','e','f')),
- blwf (&plan->map, HB_TAG('b','l','w','f')),
- pstf (&plan->map, HB_TAG('p','s','t','f')),
- is_old_spec (IS_OLD_INDIC_TAG (plan->map.get_chosen_script (0))),
- virama_glyph ((hb_codepoint_t) -1)
- {
- switch ((int) plan->props.script) {
- case HB_SCRIPT_DEVANAGARI:virama = 0x094D; break;
- case HB_SCRIPT_BENGALI: virama = 0x09CD; break;
- case HB_SCRIPT_GURMUKHI: virama = 0x0A4D; break;
- case HB_SCRIPT_GUJARATI: virama = 0x0ACD; break;
- case HB_SCRIPT_ORIYA: virama = 0x0B4D; break;
- case HB_SCRIPT_TAMIL: virama = 0x0BCD; break;
- case HB_SCRIPT_TELUGU: virama = 0x0C4D; break;
- case HB_SCRIPT_KANNADA: virama = 0x0CCD; break;
- case HB_SCRIPT_MALAYALAM: virama = 0x0D4D; break;
- case HB_SCRIPT_SINHALA: virama = 0x0DCA; break;
- case HB_SCRIPT_KHMER: virama = 0x17D2; break;
- default: virama = 0; break;
- }
- }
-
- would_apply_feature_t pref;
- would_apply_feature_t blwf;
- would_apply_feature_t pstf;
- bool is_old_spec;
- hb_codepoint_t virama;
- hb_codepoint_t virama_glyph;
+ ASSERT_POD ();
inline bool get_virama_glyph (hb_font_t *font, hb_codepoint_t *pglyph) const
{
@@ -254,20 +241,56 @@ struct indic_shape_plan_t
*pglyph = glyph;
return glyph != 0;
}
+
+
+ bool is_old_spec;
+
+ hb_codepoint_t virama;
+ hb_codepoint_t virama_glyph;
+
+ would_substitute_feature_t pref;
+ would_substitute_feature_t blwf;
+ would_substitute_feature_t pstf;
+
+ hb_mask_t mask_array[INDIC_NUM_FEATURES];
};
static void *
data_create_indic (const hb_ot_shape_plan_t *plan)
{
- indic_shape_plan_t *data = (indic_shape_plan_t *) calloc (1, sizeof (indic_shape_plan_t));
- if (unlikely (!data))
+ indic_shape_plan_t *indic_plan = (indic_shape_plan_t *) calloc (1, sizeof (indic_shape_plan_t));
+ if (unlikely (!indic_plan))
return NULL;
- /* Mixing C++ and C, oh well... */
- indic_shape_plan_t indic_plan (plan);
+ indic_plan->is_old_spec = IS_OLD_INDIC_TAG (plan->map.get_chosen_script (0));
+ {
+ hb_codepoint_t virama;
+ switch ((int) plan->props.script) {
+ case HB_SCRIPT_DEVANAGARI:virama = 0x094D; break;
+ case HB_SCRIPT_BENGALI: virama = 0x09CD; break;
+ case HB_SCRIPT_GURMUKHI: virama = 0x0A4D; break;
+ case HB_SCRIPT_GUJARATI: virama = 0x0ACD; break;
+ case HB_SCRIPT_ORIYA: virama = 0x0B4D; break;
+ case HB_SCRIPT_TAMIL: virama = 0x0BCD; break;
+ case HB_SCRIPT_TELUGU: virama = 0x0C4D; break;
+ case HB_SCRIPT_KANNADA: virama = 0x0CCD; break;
+ case HB_SCRIPT_MALAYALAM: virama = 0x0D4D; break;
+ case HB_SCRIPT_SINHALA: virama = 0x0DCA; break;
+ case HB_SCRIPT_KHMER: virama = 0x17D2; break;
+ default: virama = 0; break;
+ }
+ indic_plan->virama = virama;
+ }
+ indic_plan->virama_glyph = indic_plan->virama ? (hb_codepoint_t) -1 : 0;
+
+ indic_plan->pref.init (&plan->map, HB_TAG('p','r','e','f'));
+ indic_plan->blwf.init (&plan->map, HB_TAG('b','l','w','f'));
+ indic_plan->pstf.init (&plan->map, HB_TAG('p','s','t','f'));
+
+ for (unsigned int i = 0; i < ARRAY_LENGTH (indic_plan->mask_array); i++)
+ indic_plan->mask_array[i] = indic_features[i].is_global ? 0 : plan->map.get_1_mask (indic_features[i].tag);
- *data = indic_plan;
- return data;
+ return indic_plan;
}
static void
@@ -317,8 +340,8 @@ compare_indic_order (const hb_glyph_info_t *pa, const hb_glyph_info_t *pb)
static void
update_consonant_positions (const hb_ot_shape_plan_t *plan,
- hb_buffer_t *buffer,
- hb_font_t *font)
+ hb_font_t *font,
+ hb_buffer_t *buffer)
{
const indic_shape_plan_t *indic_plan = (const indic_shape_plan_t *) plan->data;
@@ -341,7 +364,7 @@ update_consonant_positions (const hb_ot_shape_plan_t *plan,
* https://www.microsoft.com/typography/otfntdev/devanot/shaping.aspx */
static void
-initial_reordering_consonant_syllable (const hb_ot_shape_plan_t *plan, hb_buffer_t *buffer, hb_mask_t *basic_mask_array,
+initial_reordering_consonant_syllable (const hb_ot_shape_plan_t *plan, hb_buffer_t *buffer,
unsigned int start, unsigned int end)
{
const indic_shape_plan_t *indic_plan = (const indic_shape_plan_t *) plan->data;
@@ -370,7 +393,7 @@ initial_reordering_consonant_syllable (const hb_ot_shape_plan_t *plan, hb_buffer
* and has more than one consonant, Ra is excluded from candidates for
* base consonants. */
unsigned int limit = start;
- if (basic_mask_array[RPHF] &&
+ if (indic_plan->mask_array[RPHF] &&
start + 3 <= end &&
info[start].indic_category() == OT_Ra &&
info[start + 1].indic_category() == OT_H &&
@@ -627,10 +650,10 @@ initial_reordering_consonant_syllable (const hb_ot_shape_plan_t *plan, hb_buffer
/* Reph */
for (unsigned int i = start; i < end && info[i].indic_position() == POS_RA_TO_BECOME_REPH; i++)
- info[i].mask |= basic_mask_array[RPHF];
+ info[i].mask |= indic_plan->mask_array[RPHF];
/* Pre-base */
- mask = basic_mask_array[HALF];
+ mask = indic_plan->mask_array[HALF];
for (unsigned int i = start; i < base; i++)
info[i].mask |= mask;
/* Base */
@@ -638,21 +661,21 @@ initial_reordering_consonant_syllable (const hb_ot_shape_plan_t *plan, hb_buffer
if (base < end)
info[base].mask |= mask;
/* Post-base */
- mask = basic_mask_array[BLWF] | basic_mask_array[ABVF] | basic_mask_array[PSTF];
+ mask = indic_plan->mask_array[BLWF] | indic_plan->mask_array[ABVF] | indic_plan->mask_array[PSTF];
for (unsigned int i = base + 1; i < end; i++)
info[i].mask |= mask;
}
/* XXX This will not match for old-Indic spec since the Halant-Ra order is reversed already. */
- if (basic_mask_array[PREF] && base + 2 < end)
+ if (indic_plan->mask_array[PREF] && base + 2 < end)
{
/* Find a Halant,Ra sequence and mark it for pre-base reordering processing. */
for (unsigned int i = base + 1; i + 1 < end; i++)
if (is_halant_or_coeng (info[i]) &&
info[i + 1].indic_category() == OT_Ra)
{
- info[i++].mask |= basic_mask_array[PREF];
- info[i++].mask |= basic_mask_array[PREF];
+ info[i++].mask |= indic_plan->mask_array[PREF];
+ info[i++].mask |= indic_plan->mask_array[PREF];
/* Mark the subsequent stuff with 'cfar'. Used in Khmer.
* Read the feature spec.
@@ -661,7 +684,7 @@ initial_reordering_consonant_syllable (const hb_ot_shape_plan_t *plan, hb_buffer
* U+1784,U+17D2,U+1782,U+17D2,U+179A
*/
for (; i < end; i++)
- info[i].mask |= basic_mask_array[CFAR];
+ info[i].mask |= indic_plan->mask_array[CFAR];
break;
}
@@ -681,7 +704,7 @@ initial_reordering_consonant_syllable (const hb_ot_shape_plan_t *plan, hb_buffer
/* A ZWNJ disables HALF. */
if (non_joiner)
- info[j].mask &= ~basic_mask_array[HALF];
+ info[j].mask &= ~indic_plan->mask_array[HALF];
} while (j > start && !is_consonant (info[j]));
}
@@ -691,17 +714,15 @@ initial_reordering_consonant_syllable (const hb_ot_shape_plan_t *plan, hb_buffer
static void
initial_reordering_vowel_syllable (const hb_ot_shape_plan_t *plan,
hb_buffer_t *buffer,
- hb_mask_t *basic_mask_array,
unsigned int start, unsigned int end)
{
/* We made the vowels look like consonants. So let's call the consonant logic! */
- initial_reordering_consonant_syllable (plan, buffer, basic_mask_array, start, end);
+ initial_reordering_consonant_syllable (plan, buffer, start, end);
}
static void
initial_reordering_standalone_cluster (const hb_ot_shape_plan_t *plan,
hb_buffer_t *buffer,
- hb_mask_t *basic_mask_array,
unsigned int start, unsigned int end)
{
/* We treat NBSP/dotted-circle as if they are consonants, so we should just chain.
@@ -716,13 +737,12 @@ initial_reordering_standalone_cluster (const hb_ot_shape_plan_t *plan,
return;
}
- initial_reordering_consonant_syllable (plan, buffer, basic_mask_array, start, end);
+ initial_reordering_consonant_syllable (plan, buffer, start, end);
}
static void
initial_reordering_non_indic (const hb_ot_shape_plan_t *plan HB_UNUSED,
hb_buffer_t *buffer HB_UNUSED,
- hb_mask_t *basic_mask_array HB_UNUSED,
unsigned int start HB_UNUSED, unsigned int end HB_UNUSED)
{
/* Nothing to do right now. If we ever switch to using the output
@@ -736,21 +756,16 @@ initial_reordering (const hb_ot_shape_plan_t *plan,
hb_font_t *font,
hb_buffer_t *buffer)
{
- update_consonant_positions (plan, buffer, font);
-
- hb_mask_t basic_mask_array[ARRAY_LENGTH (indic_basic_features)] = {0};
- unsigned int num_masks = ARRAY_LENGTH (indic_basic_features);
- for (unsigned int i = 0; i < num_masks; i++)
- basic_mask_array[i] = plan->map.get_1_mask (indic_basic_features[i].tag);
-
- find_syllables (plan, buffer, basic_mask_array);
+ update_consonant_positions (plan, font, buffer);
+ find_syllables (plan, buffer);
}
static void
-final_reordering_syllable (hb_buffer_t *buffer,
- hb_mask_t init_mask, hb_mask_t pref_mask,
+final_reordering_syllable (const hb_ot_shape_plan_t *plan,
+ hb_buffer_t *buffer,
unsigned int start, unsigned int end)
{
+ const indic_shape_plan_t *indic_plan = (const indic_shape_plan_t *) plan->data;
hb_glyph_info_t *info = buffer->info;
/* 4. Final reordering:
@@ -1017,16 +1032,16 @@ final_reordering_syllable (hb_buffer_t *buffer,
* the following rules:
*/
- if (pref_mask && base + 1 < end) /* Otherwise there can't be any pre-base reordering Ra. */
+ if (indic_plan->mask_array[PREF] && base + 1 < end) /* Otherwise there can't be any pre-base reordering Ra. */
{
for (unsigned int i = base + 1; i < end; i++)
- if ((info[i].mask & pref_mask) != 0)
+ if ((info[i].mask & indic_plan->mask_array[PREF]) != 0)
{
/* 1. Only reorder a glyph produced by substitution during application
* of the <pref> feature. (Note that a font may shape a Ra consonant with
* the feature generally but block it in certain contexts.)
*/
- if (i + 1 == end || (info[i + 1].mask & pref_mask) == 0)
+ if (i + 1 == end || (info[i + 1].mask & indic_plan->mask_array[PREF]) == 0)
{
/*
* 2. Try to find a target position the same way as for pre-base matra.
@@ -1078,7 +1093,7 @@ final_reordering_syllable (hb_buffer_t *buffer,
(!start ||
!(FLAG (_hb_glyph_info_get_general_category (&info[start - 1])) &
FLAG_RANGE (HB_UNICODE_GENERAL_CATEGORY_FORMAT, HB_UNICODE_GENERAL_CATEGORY_NON_SPACING_MARK))))
- info[start].mask |= init_mask;
+ info[start].mask |= indic_plan->mask_array[INIT];
/*
@@ -1097,25 +1112,22 @@ final_reordering_syllable (hb_buffer_t *buffer,
static void
final_reordering (const hb_ot_shape_plan_t *plan,
- hb_font_t *font HB_UNUSED,
+ hb_font_t *font,
hb_buffer_t *buffer)
{
unsigned int count = buffer->len;
if (!count) return;
- hb_mask_t init_mask = plan->map.get_1_mask (HB_TAG('i','n','i','t'));
- hb_mask_t pref_mask = plan->map.get_1_mask (HB_TAG('p','r','e','f'));
-
hb_glyph_info_t *info = buffer->info;
unsigned int last = 0;
unsigned int last_syllable = info[0].syllable();
for (unsigned int i = 1; i < count; i++)
if (last_syllable != info[i].syllable()) {
- final_reordering_syllable (buffer, init_mask, pref_mask, last, i);
+ final_reordering_syllable (plan, buffer, last, i);
last = i;
last_syllable = info[last].syllable();
}
- final_reordering_syllable (buffer, init_mask, pref_mask, last, count);
+ final_reordering_syllable (plan, buffer, last, count);
HB_BUFFER_DEALLOCATE_VAR (buffer, indic_category);
HB_BUFFER_DEALLOCATE_VAR (buffer, indic_position);
commit 914ffaa40fcca020f65bacdd709421e9047afd83
Author: Behdad Esfahbod <behdad at behdad.org>
Date: Thu Aug 2 11:03:39 2012 -0400
[Indic] Move more repeated work into shape_plan
diff --git a/src/hb-ot-shape-complex-indic.cc b/src/hb-ot-shape-complex-indic.cc
index cdfd5b9..57f3340 100644
--- a/src/hb-ot-shape-complex-indic.cc
+++ b/src/hb-ot-shape-complex-indic.cc
@@ -210,12 +210,50 @@ struct indic_shape_plan_t
pref (&plan->map, HB_TAG('p','r','e','f')),
blwf (&plan->map, HB_TAG('b','l','w','f')),
pstf (&plan->map, HB_TAG('p','s','t','f')),
- is_old_spec (IS_OLD_INDIC_TAG (plan->map.get_chosen_script (0))) {}
+ is_old_spec (IS_OLD_INDIC_TAG (plan->map.get_chosen_script (0))),
+ virama_glyph ((hb_codepoint_t) -1)
+ {
+ switch ((int) plan->props.script) {
+ case HB_SCRIPT_DEVANAGARI:virama = 0x094D; break;
+ case HB_SCRIPT_BENGALI: virama = 0x09CD; break;
+ case HB_SCRIPT_GURMUKHI: virama = 0x0A4D; break;
+ case HB_SCRIPT_GUJARATI: virama = 0x0ACD; break;
+ case HB_SCRIPT_ORIYA: virama = 0x0B4D; break;
+ case HB_SCRIPT_TAMIL: virama = 0x0BCD; break;
+ case HB_SCRIPT_TELUGU: virama = 0x0C4D; break;
+ case HB_SCRIPT_KANNADA: virama = 0x0CCD; break;
+ case HB_SCRIPT_MALAYALAM: virama = 0x0D4D; break;
+ case HB_SCRIPT_SINHALA: virama = 0x0DCA; break;
+ case HB_SCRIPT_KHMER: virama = 0x17D2; break;
+ default: virama = 0; break;
+ }
+ }
would_apply_feature_t pref;
would_apply_feature_t blwf;
would_apply_feature_t pstf;
bool is_old_spec;
+ hb_codepoint_t virama;
+ hb_codepoint_t virama_glyph;
+
+ inline bool get_virama_glyph (hb_font_t *font, hb_codepoint_t *pglyph) const
+ {
+ hb_codepoint_t glyph = virama_glyph;
+ if (unlikely (virama_glyph == (hb_codepoint_t) -1))
+ {
+ if (!font->get_glyph (virama, 0, &glyph))
+ glyph = 0;
+ /* Technically speaking, the spec says we should apply 'locl' to virama too.
+ * Maybe one day... */
+
+ /* Our get_glyph() function needs a font, so we can't get the virama glyph
+ * during shape planning... Instead, overwrite it here. It's safe. Don't worry! */
+ (const_cast<indic_shape_plan_t *> (this))->virama_glyph = glyph;
+ }
+
+ *pglyph = glyph;
+ return glyph != 0;
+ }
};
static void *
@@ -282,30 +320,12 @@ update_consonant_positions (const hb_ot_shape_plan_t *plan,
hb_buffer_t *buffer,
hb_font_t *font)
{
- hb_codepoint_t virama;
- switch ((int) buffer->props.script) {
- case HB_SCRIPT_DEVANAGARI: virama = 0x094D; break;
- case HB_SCRIPT_BENGALI: virama = 0x09CD; break;
- case HB_SCRIPT_GURMUKHI: virama = 0x0A4D; break;
- case HB_SCRIPT_GUJARATI: virama = 0x0ACD; break;
- case HB_SCRIPT_ORIYA: virama = 0x0B4D; break;
- case HB_SCRIPT_TAMIL: virama = 0x0BCD; break;
- case HB_SCRIPT_TELUGU: virama = 0x0C4D; break;
- case HB_SCRIPT_KANNADA: virama = 0x0CCD; break;
- case HB_SCRIPT_MALAYALAM: virama = 0x0D4D; break;
- case HB_SCRIPT_SINHALA: virama = 0x0DCA; break;
- case HB_SCRIPT_KHMER: virama = 0x17D2; break;
- default: virama = 0; break;
- }
-
const indic_shape_plan_t *indic_plan = (const indic_shape_plan_t *) plan->data;
unsigned int consonant_pos = indic_plan->is_old_spec ? 0 : 1;
hb_codepoint_t glyphs[2];
- if (virama && font->get_glyph (virama, 0, &glyphs[1 - consonant_pos]))
+ if (indic_plan->get_virama_glyph (font, &glyphs[1 - consonant_pos]))
{
- /* Technically speaking, the spec says we should apply 'locl' to virama too.
- * Maybe one day... */
hb_face_t *face = font->face;
unsigned int count = buffer->len;
for (unsigned int i = 0; i < count; i++)
@@ -324,6 +344,7 @@ static void
initial_reordering_consonant_syllable (const hb_ot_shape_plan_t *plan, hb_buffer_t *buffer, hb_mask_t *basic_mask_array,
unsigned int start, unsigned int end)
{
+ const indic_shape_plan_t *indic_plan = (const indic_shape_plan_t *) plan->data;
hb_glyph_info_t *info = buffer->info;
@@ -526,7 +547,7 @@ initial_reordering_consonant_syllable (const hb_ot_shape_plan_t *plan, hb_buffer
/* For old-style Indic script tags, move the first post-base Halant after
* last consonant. */
- if (IS_OLD_INDIC_TAG (plan->map.get_chosen_script (0))) {
+ if (indic_plan->is_old_spec) {
for (unsigned int i = base + 1; i < end; i++)
if (info[i].indic_category() == OT_H) {
unsigned int j;
commit a8c6da90f4c6e8d27a3a1b758a55476776d9f750
Author: Behdad Esfahbod <behdad at behdad.org>
Date: Thu Aug 2 10:46:34 2012 -0400
[OT] Add per-complex-shaper shape_plan data
Hookup some Indic data to it. More to come.
diff --git a/src/hb-ot-shape-complex-arabic.cc b/src/hb-ot-shape-complex-arabic.cc
index d08d364..b014c74 100644
--- a/src/hb-ot-shape-complex-arabic.cc
+++ b/src/hb-ot-shape-complex-arabic.cc
@@ -296,6 +296,8 @@ const hb_ot_complex_shaper_t _hb_ot_complex_shaper_arabic =
"arabic",
collect_features_arabic,
NULL, /* override_features */
+ NULL, /* data_create */
+ NULL, /* data_destroy */
NULL, /* normalization_preference */
setup_masks_arabic,
true, /* zero_width_attached_marks */
diff --git a/src/hb-ot-shape-complex-indic.cc b/src/hb-ot-shape-complex-indic.cc
index be37cdd..cdfd5b9 100644
--- a/src/hb-ot-shape-complex-indic.cc
+++ b/src/hb-ot-shape-complex-indic.cc
@@ -82,56 +82,6 @@ indic_options (void)
}
-struct indic_shape_plan_t
-{
- struct would_apply_feature_t
- {
- would_apply_feature_t (const hb_ot_map_t *map, hb_tag_t feature_tag)
- {
- map->get_stage_lookups (0/*GSUB*/,
- map->get_feature_stage (0/*GSUB*/, feature_tag),
- &lookups, &count);
- }
-
- inline bool would_substitute (hb_codepoint_t *glyphs,
- unsigned int glyphs_count,
- hb_face_t *face) const
- {
- for (unsigned int i = 0; i < count; i++)
- if (hb_ot_layout_would_substitute_lookup_fast (face, glyphs, glyphs_count, lookups[i].index))
- return true;
- return false;
- }
-
- private:
- const hb_ot_map_t::lookup_map_t *lookups;
- unsigned int count;
- };
-
- indic_shape_plan_t (const hb_ot_shape_plan_t *plan) :
- pref (&plan->map, HB_TAG('p','r','e','f')),
- blwf (&plan->map, HB_TAG('b','l','w','f')),
- pstf (&plan->map, HB_TAG('p','s','t','f')),
- is_old_spec (IS_OLD_INDIC_TAG (plan->map.get_chosen_script (0))) {}
-
- would_apply_feature_t pref;
- would_apply_feature_t blwf;
- would_apply_feature_t pstf;
- bool is_old_spec;
-};
-
-static indic_position_t
-consonant_position_from_font (const indic_shape_plan_t *indic_plan,
- hb_codepoint_t *glyphs, unsigned int glyphs_len,
- hb_face_t *face)
-{
- if (indic_plan->pref.would_substitute (glyphs, ARRAY_LENGTH (glyphs), face)) return POS_BELOW_C;
- if (indic_plan->blwf.would_substitute (glyphs, ARRAY_LENGTH (glyphs), face)) return POS_BELOW_C;
- if (indic_plan->pstf.would_substitute (glyphs, ARRAY_LENGTH (glyphs), face)) return POS_POST_C;
- return POS_BASE_C;
-}
-
-
struct feature_list_t {
hb_tag_t tag;
@@ -230,6 +180,76 @@ override_features_indic (hb_ot_shape_planner_t *plan)
}
+struct would_apply_feature_t
+{
+ would_apply_feature_t (const hb_ot_map_t *map, hb_tag_t feature_tag)
+ {
+ map->get_stage_lookups (0/*GSUB*/,
+ map->get_feature_stage (0/*GSUB*/, feature_tag),
+ &lookups, &count);
+ }
+
+ inline bool would_substitute (hb_codepoint_t *glyphs,
+ unsigned int glyphs_count,
+ hb_face_t *face) const
+ {
+ for (unsigned int i = 0; i < count; i++)
+ if (hb_ot_layout_would_substitute_lookup_fast (face, glyphs, glyphs_count, lookups[i].index))
+ return true;
+ return false;
+ }
+
+ private:
+ const hb_ot_map_t::lookup_map_t *lookups;
+ unsigned int count;
+};
+
+struct indic_shape_plan_t
+{
+ indic_shape_plan_t (const hb_ot_shape_plan_t *plan) :
+ pref (&plan->map, HB_TAG('p','r','e','f')),
+ blwf (&plan->map, HB_TAG('b','l','w','f')),
+ pstf (&plan->map, HB_TAG('p','s','t','f')),
+ is_old_spec (IS_OLD_INDIC_TAG (plan->map.get_chosen_script (0))) {}
+
+ would_apply_feature_t pref;
+ would_apply_feature_t blwf;
+ would_apply_feature_t pstf;
+ bool is_old_spec;
+};
+
+static void *
+data_create_indic (const hb_ot_shape_plan_t *plan)
+{
+ indic_shape_plan_t *data = (indic_shape_plan_t *) calloc (1, sizeof (indic_shape_plan_t));
+ if (unlikely (!data))
+ return NULL;
+
+ /* Mixing C++ and C, oh well... */
+ indic_shape_plan_t indic_plan (plan);
+
+ *data = indic_plan;
+ return data;
+}
+
+static void
+data_destroy_indic (void *data)
+{
+ free (data);
+}
+
+static indic_position_t
+consonant_position_from_face (const indic_shape_plan_t *indic_plan,
+ hb_codepoint_t *glyphs, unsigned int glyphs_len,
+ hb_face_t *face)
+{
+ if (indic_plan->pref.would_substitute (glyphs, ARRAY_LENGTH (glyphs), face)) return POS_BELOW_C;
+ if (indic_plan->blwf.would_substitute (glyphs, ARRAY_LENGTH (glyphs), face)) return POS_BELOW_C;
+ if (indic_plan->pstf.would_substitute (glyphs, ARRAY_LENGTH (glyphs), face)) return POS_POST_C;
+ return POS_BASE_C;
+}
+
+
static void
setup_masks_indic (const hb_ot_shape_plan_t *plan HB_UNUSED,
hb_buffer_t *buffer,
@@ -278,9 +298,9 @@ update_consonant_positions (const hb_ot_shape_plan_t *plan,
default: virama = 0; break;
}
- indic_shape_plan_t indic_plan (plan);
+ const indic_shape_plan_t *indic_plan = (const indic_shape_plan_t *) plan->data;
- unsigned int consonant_pos = indic_plan.is_old_spec ? 0 : 1;
+ unsigned int consonant_pos = indic_plan->is_old_spec ? 0 : 1;
hb_codepoint_t glyphs[2];
if (virama && font->get_glyph (virama, 0, &glyphs[1 - consonant_pos]))
{
@@ -291,7 +311,7 @@ update_consonant_positions (const hb_ot_shape_plan_t *plan,
for (unsigned int i = 0; i < count; i++)
if (buffer->info[i].indic_position() == POS_BASE_C) {
glyphs[consonant_pos] = buffer->info[i].codepoint;
- buffer->info[i].indic_position() = consonant_position_from_font (&indic_plan, glyphs, 2, face);
+ buffer->info[i].indic_position() = consonant_position_from_face (indic_plan, glyphs, 2, face);
}
}
}
@@ -1086,6 +1106,8 @@ const hb_ot_complex_shaper_t _hb_ot_complex_shaper_indic =
"indic",
collect_features_indic,
override_features_indic,
+ data_create_indic,
+ data_destroy_indic,
NULL, /* normalization_preference */
setup_masks_indic,
false, /* zero_width_attached_marks */
diff --git a/src/hb-ot-shape-complex-misc.cc b/src/hb-ot-shape-complex-misc.cc
index 6ae9f50..4f1dd5b 100644
--- a/src/hb-ot-shape-complex-misc.cc
+++ b/src/hb-ot-shape-complex-misc.cc
@@ -88,6 +88,8 @@ const hb_ot_complex_shaper_t _hb_ot_complex_shaper_default =
"default",
collect_features_default,
NULL, /* override_features */
+ NULL, /* data_create */
+ NULL, /* data_destroy */
normalization_preference_default,
NULL, /* setup_masks */
true, /* zero_width_attached_marks */
@@ -196,6 +198,8 @@ const hb_ot_complex_shaper_t _hb_ot_complex_shaper_thai =
"thai",
NULL, /* collect_features */
NULL, /* override_features */
+ NULL, /* data_create */
+ NULL, /* data_destroy */
NULL, /* normalization_preference */
setup_masks_thai,
true, /* zero_width_attached_marks */
diff --git a/src/hb-ot-shape-complex-private.hh b/src/hb-ot-shape-complex-private.hh
index e7f9697..baece32 100644
--- a/src/hb-ot-shape-complex-private.hh
+++ b/src/hb-ot-shape-complex-private.hh
@@ -69,13 +69,27 @@ struct hb_ot_complex_shaper_t
*/
void (*override_features) (hb_ot_shape_planner_t *plan);
+
+ /* data_create()
+ * Called at the end of shape_plan().
+ * Whatever shapers return will be accessible through plan->data later.
+ * If NULL is returned, means a plan failure.
+ * May be NULL. */
+ void *(*data_create) (const hb_ot_shape_plan_t *plan);
+
+ /* data_destroy()
+ * Called when the shape_plan is being destroyed.
+ * plan->data is passed here for destruction.
+ * If NULL is returned, means a plan failure.
+ * May be NULL. */
+ void (*data_destroy) (void *data);
+
/* normalization_preference()
* Called during shape().
*/
hb_ot_shape_normalization_mode_t
(*normalization_preference) (const hb_ot_shape_plan_t *plan);
-
/* setup_masks()
* Called during shape().
* Shapers should use map to get feature masks and set on buffer.
diff --git a/src/hb-ot-shape-private.hh b/src/hb-ot-shape-private.hh
index da8a6db..975665e 100644
--- a/src/hb-ot-shape-private.hh
+++ b/src/hb-ot-shape-private.hh
@@ -44,6 +44,7 @@ struct hb_ot_shape_plan_t
hb_segment_properties_t props;
const struct hb_ot_complex_shaper_t *shaper;
hb_ot_map_t map;
+ const void *data;
inline void substitute_closure (hb_face_t *face, hb_set_t *glyphs) const { map.substitute_closure (this, face, glyphs); }
inline void substitute (hb_font_t *font, hb_buffer_t *buffer) const { map.substitute (this, font, buffer); }
diff --git a/src/hb-ot-shape.cc b/src/hb-ot-shape.cc
index 67330b4..28bb1f9 100644
--- a/src/hb-ot-shape.cc
+++ b/src/hb-ot-shape.cc
@@ -167,8 +167,8 @@ _hb_ot_shaper_shape_plan_data_create (hb_shape_plan_t *shape_plan,
const hb_feature_t *user_features,
unsigned int num_user_features)
{
- hb_ot_shape_plan_t *data = (hb_ot_shape_plan_t *) calloc (1, sizeof (hb_ot_shape_plan_t));
- if (unlikely (!data))
+ hb_ot_shape_plan_t *plan = (hb_ot_shape_plan_t *) calloc (1, sizeof (hb_ot_shape_plan_t));
+ if (unlikely (!plan))
return NULL;
hb_ot_shape_planner_t planner (shape_plan);
@@ -177,17 +177,26 @@ _hb_ot_shaper_shape_plan_data_create (hb_shape_plan_t *shape_plan,
hb_ot_shape_collect_features (&planner, &shape_plan->props, user_features, num_user_features);
- planner.compile (*data);
+ planner.compile (*plan);
- return data;
+ if (plan->shaper->data_create) {
+ plan->data = plan->shaper->data_create (plan);
+ if (unlikely (!plan->data))
+ return NULL;
+ }
+
+ return plan;
}
void
-_hb_ot_shaper_shape_plan_data_destroy (hb_ot_shaper_shape_plan_data_t *data)
+_hb_ot_shaper_shape_plan_data_destroy (hb_ot_shaper_shape_plan_data_t *plan)
{
- data->finish ();
+ if (plan->shaper->data_destroy)
+ plan->shaper->data_destroy (const_cast<void *> (plan->data));
+
+ plan->finish ();
- free (data);
+ free (plan);
}
commit 8bb5deba9630d35878eb6edb4643ecfabf99f15f
Author: Behdad Esfahbod <behdad at behdad.org>
Date: Thu Aug 2 10:07:58 2012 -0400
[OT] Pipe shape_plan down to pause_callbacks
diff --git a/src/hb-ot-map-private.hh b/src/hb-ot-map-private.hh
index 18517c4..b9c6736 100644
--- a/src/hb-ot-map-private.hh
+++ b/src/hb-ot-map-private.hh
@@ -62,7 +62,7 @@ struct hb_ot_map_t
{ return a->index < b->index ? -1 : a->index > b->index ? 1 : 0; }
};
- typedef void (*pause_func_t) (const hb_ot_map_t *map, hb_font_t *font, hb_buffer_t *buffer);
+ typedef void (*pause_func_t) (const struct hb_ot_shape_plan_t *plan, hb_font_t *font, hb_buffer_t *buffer);
struct pause_map_t {
unsigned int num_lookups; /* Cumulative */
@@ -112,9 +112,9 @@ struct hb_ot_map_t
inline hb_tag_t get_chosen_script (unsigned int table_index) const
{ return chosen_script[table_index]; }
- HB_INTERNAL void substitute_closure (hb_face_t *face, hb_set_t *glyphs) const;
- HB_INTERNAL void substitute (hb_font_t *font, hb_buffer_t *buffer) const;
- HB_INTERNAL void position (hb_font_t *font, hb_buffer_t *buffer) const;
+ HB_INTERNAL void substitute_closure (const struct hb_ot_shape_plan_t *plan, hb_face_t *face, hb_set_t *glyphs) const;
+ HB_INTERNAL void substitute (const struct hb_ot_shape_plan_t *plan, hb_font_t *font, hb_buffer_t *buffer) const;
+ HB_INTERNAL void position (const struct hb_ot_shape_plan_t *plan, hb_font_t *font, hb_buffer_t *buffer) const;
inline void finish (void) {
features.finish ();
diff --git a/src/hb-ot-map.cc b/src/hb-ot-map.cc
index 62afdef..7eed624 100644
--- a/src/hb-ot-map.cc
+++ b/src/hb-ot-map.cc
@@ -75,7 +75,7 @@ void hb_ot_map_builder_t::add_feature (hb_tag_t tag, unsigned int value, bool gl
/* Keep the next two functions in sync. */
-void hb_ot_map_t::substitute (hb_font_t *font, hb_buffer_t *buffer) const
+void hb_ot_map_t::substitute (const hb_ot_shape_plan_t *plan, hb_font_t *font, hb_buffer_t *buffer) const
{
const unsigned int table_index = 0;
unsigned int i = 0;
@@ -88,14 +88,14 @@ void hb_ot_map_t::substitute (hb_font_t *font, hb_buffer_t *buffer) const
buffer->clear_output ();
if (pause->callback)
- pause->callback (this, font, buffer);
+ pause->callback (plan, font, buffer);
}
for (; i < lookups[table_index].len; i++)
hb_ot_layout_substitute_lookup (font, buffer, lookups[table_index][i].index, lookups[table_index][i].mask);
}
-void hb_ot_map_t::position (hb_font_t *font, hb_buffer_t *buffer) const
+void hb_ot_map_t::position (const hb_ot_shape_plan_t *plan, hb_font_t *font, hb_buffer_t *buffer) const
{
const unsigned int table_index = 1;
unsigned int i = 0;
@@ -106,15 +106,14 @@ void hb_ot_map_t::position (hb_font_t *font, hb_buffer_t *buffer) const
hb_ot_layout_position_lookup (font, buffer, lookups[table_index][i].index, lookups[table_index][i].mask);
if (pause->callback)
- pause->callback (this, font, buffer);
+ pause->callback (plan, font, buffer);
}
for (; i < lookups[table_index].len; i++)
hb_ot_layout_position_lookup (font, buffer, lookups[table_index][i].index, lookups[table_index][i].mask);
}
-void hb_ot_map_t::substitute_closure (hb_face_t *face,
- hb_set_t *glyphs) const
+void hb_ot_map_t::substitute_closure (const hb_ot_shape_plan_t *plan, hb_face_t *face, hb_set_t *glyphs) const
{
unsigned int table_index = 0;
unsigned int i = 0;
diff --git a/src/hb-ot-shape-complex-indic-machine.rl b/src/hb-ot-shape-complex-indic-machine.rl
index 25e308d..25c0e65 100644
--- a/src/hb-ot-shape-complex-indic-machine.rl
+++ b/src/hb-ot-shape-complex-indic-machine.rl
@@ -92,14 +92,14 @@ main := |*
if (0) fprintf (stderr, "syllable %d..%d %s\n", last, p+1, #func); \
for (unsigned int i = last; i < p+1; i++) \
info[i].syllable() = syllable_serial; \
- PASTE (initial_reordering_, func) (map, buffer, mask_array, last, p+1); \
+ PASTE (initial_reordering_, func) (plan, buffer, mask_array, last, p+1); \
last = p+1; \
syllable_serial++; \
if (unlikely (!syllable_serial)) syllable_serial++; \
} HB_STMT_END
static void
-find_syllables (const hb_ot_map_t *map, hb_buffer_t *buffer, hb_mask_t *mask_array)
+find_syllables (const hb_ot_shape_plan_t *plan, hb_buffer_t *buffer, hb_mask_t *mask_array)
{
unsigned int p, pe, eof, ts, te, act;
int cs;
diff --git a/src/hb-ot-shape-complex-indic.cc b/src/hb-ot-shape-complex-indic.cc
index 6b55fb7..be37cdd 100644
--- a/src/hb-ot-shape-complex-indic.cc
+++ b/src/hb-ot-shape-complex-indic.cc
@@ -108,14 +108,12 @@ struct indic_shape_plan_t
unsigned int count;
};
- indic_shape_plan_t (const hb_ot_map_t *map_) :
- map (map_),
- pref (map_, HB_TAG('p','r','e','f')),
- blwf (map_, HB_TAG('b','l','w','f')),
- pstf (map_, HB_TAG('p','s','t','f')),
- is_old_spec (IS_OLD_INDIC_TAG (map->get_chosen_script (0))) {}
-
- const hb_ot_map_t *map;
+ indic_shape_plan_t (const hb_ot_shape_plan_t *plan) :
+ pref (&plan->map, HB_TAG('p','r','e','f')),
+ blwf (&plan->map, HB_TAG('b','l','w','f')),
+ pstf (&plan->map, HB_TAG('p','s','t','f')),
+ is_old_spec (IS_OLD_INDIC_TAG (plan->map.get_chosen_script (0))) {}
+
would_apply_feature_t pref;
would_apply_feature_t blwf;
would_apply_feature_t pstf;
@@ -192,11 +190,11 @@ indic_other_features[] =
static void
-initial_reordering (const hb_ot_map_t *map,
+initial_reordering (const hb_ot_shape_plan_t *plan,
hb_font_t *font,
hb_buffer_t *buffer);
static void
-final_reordering (const hb_ot_map_t *map,
+final_reordering (const hb_ot_shape_plan_t *plan,
hb_font_t *font,
hb_buffer_t *buffer);
@@ -260,7 +258,7 @@ compare_indic_order (const hb_glyph_info_t *pa, const hb_glyph_info_t *pb)
static void
-update_consonant_positions (const hb_ot_map_t *map,
+update_consonant_positions (const hb_ot_shape_plan_t *plan,
hb_buffer_t *buffer,
hb_font_t *font)
{
@@ -280,7 +278,7 @@ update_consonant_positions (const hb_ot_map_t *map,
default: virama = 0; break;
}
- indic_shape_plan_t indic_plan (map);
+ indic_shape_plan_t indic_plan (plan);
unsigned int consonant_pos = indic_plan.is_old_spec ? 0 : 1;
hb_codepoint_t glyphs[2];
@@ -303,7 +301,7 @@ update_consonant_positions (const hb_ot_map_t *map,
* https://www.microsoft.com/typography/otfntdev/devanot/shaping.aspx */
static void
-initial_reordering_consonant_syllable (const hb_ot_map_t *map, hb_buffer_t *buffer, hb_mask_t *basic_mask_array,
+initial_reordering_consonant_syllable (const hb_ot_shape_plan_t *plan, hb_buffer_t *buffer, hb_mask_t *basic_mask_array,
unsigned int start, unsigned int end)
{
hb_glyph_info_t *info = buffer->info;
@@ -508,7 +506,7 @@ initial_reordering_consonant_syllable (const hb_ot_map_t *map, hb_buffer_t *buff
/* For old-style Indic script tags, move the first post-base Halant after
* last consonant. */
- if (IS_OLD_INDIC_TAG (map->get_chosen_script (0))) {
+ if (IS_OLD_INDIC_TAG (plan->map.get_chosen_script (0))) {
for (unsigned int i = base + 1; i < end; i++)
if (info[i].indic_category() == OT_H) {
unsigned int j;
@@ -650,17 +648,17 @@ initial_reordering_consonant_syllable (const hb_ot_map_t *map, hb_buffer_t *buff
static void
-initial_reordering_vowel_syllable (const hb_ot_map_t *map,
+initial_reordering_vowel_syllable (const hb_ot_shape_plan_t *plan,
hb_buffer_t *buffer,
hb_mask_t *basic_mask_array,
unsigned int start, unsigned int end)
{
/* We made the vowels look like consonants. So let's call the consonant logic! */
- initial_reordering_consonant_syllable (map, buffer, basic_mask_array, start, end);
+ initial_reordering_consonant_syllable (plan, buffer, basic_mask_array, start, end);
}
static void
-initial_reordering_standalone_cluster (const hb_ot_map_t *map,
+initial_reordering_standalone_cluster (const hb_ot_shape_plan_t *plan,
hb_buffer_t *buffer,
hb_mask_t *basic_mask_array,
unsigned int start, unsigned int end)
@@ -677,11 +675,11 @@ initial_reordering_standalone_cluster (const hb_ot_map_t *map,
return;
}
- initial_reordering_consonant_syllable (map, buffer, basic_mask_array, start, end);
+ initial_reordering_consonant_syllable (plan, buffer, basic_mask_array, start, end);
}
static void
-initial_reordering_non_indic (const hb_ot_map_t *map HB_UNUSED,
+initial_reordering_non_indic (const hb_ot_shape_plan_t *plan HB_UNUSED,
hb_buffer_t *buffer HB_UNUSED,
hb_mask_t *basic_mask_array HB_UNUSED,
unsigned int start HB_UNUSED, unsigned int end HB_UNUSED)
@@ -693,18 +691,18 @@ initial_reordering_non_indic (const hb_ot_map_t *map HB_UNUSED,
#include "hb-ot-shape-complex-indic-machine.hh"
static void
-initial_reordering (const hb_ot_map_t *map,
+initial_reordering (const hb_ot_shape_plan_t *plan,
hb_font_t *font,
hb_buffer_t *buffer)
{
- update_consonant_positions (map, buffer, font);
+ update_consonant_positions (plan, buffer, font);
hb_mask_t basic_mask_array[ARRAY_LENGTH (indic_basic_features)] = {0};
unsigned int num_masks = ARRAY_LENGTH (indic_basic_features);
for (unsigned int i = 0; i < num_masks; i++)
- basic_mask_array[i] = map->get_1_mask (indic_basic_features[i].tag);
+ basic_mask_array[i] = plan->map.get_1_mask (indic_basic_features[i].tag);
- find_syllables (map, buffer, basic_mask_array);
+ find_syllables (plan, buffer, basic_mask_array);
}
static void
@@ -1057,15 +1055,15 @@ final_reordering_syllable (hb_buffer_t *buffer,
static void
-final_reordering (const hb_ot_map_t *map,
+final_reordering (const hb_ot_shape_plan_t *plan,
hb_font_t *font HB_UNUSED,
hb_buffer_t *buffer)
{
unsigned int count = buffer->len;
if (!count) return;
- hb_mask_t init_mask = map->get_1_mask (HB_TAG('i','n','i','t'));
- hb_mask_t pref_mask = map->get_1_mask (HB_TAG('p','r','e','f'));
+ hb_mask_t init_mask = plan->map.get_1_mask (HB_TAG('i','n','i','t'));
+ hb_mask_t pref_mask = plan->map.get_1_mask (HB_TAG('p','r','e','f'));
hb_glyph_info_t *info = buffer->info;
unsigned int last = 0;
diff --git a/src/hb-ot-shape-private.hh b/src/hb-ot-shape-private.hh
index 0c26528..da8a6db 100644
--- a/src/hb-ot-shape-private.hh
+++ b/src/hb-ot-shape-private.hh
@@ -44,6 +44,12 @@ struct hb_ot_shape_plan_t
hb_segment_properties_t props;
const struct hb_ot_complex_shaper_t *shaper;
hb_ot_map_t map;
+
+ inline void substitute_closure (hb_face_t *face, hb_set_t *glyphs) const { map.substitute_closure (this, face, glyphs); }
+ inline void substitute (hb_font_t *font, hb_buffer_t *buffer) const { map.substitute (this, font, buffer); }
+ inline void position (hb_font_t *font, hb_buffer_t *buffer) const { map.position (this, font, buffer); }
+
+ void finish (void) { map.finish (); }
};
struct hb_ot_shape_planner_t
diff --git a/src/hb-ot-shape.cc b/src/hb-ot-shape.cc
index c874fb5..67330b4 100644
--- a/src/hb-ot-shape.cc
+++ b/src/hb-ot-shape.cc
@@ -77,14 +77,16 @@ hb_ot_shape_collect_features (hb_ot_shape_planner_t *planner,
const hb_feature_t *user_features,
unsigned int num_user_features)
{
+ hb_ot_map_builder_t *map = &planner->map;
+
switch (props->direction) {
case HB_DIRECTION_LTR:
- planner->map.add_bool_feature (HB_TAG ('l','t','r','a'));
- planner->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:
- planner->map.add_bool_feature (HB_TAG ('r','t','l','a'));
- planner->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:
@@ -96,7 +98,7 @@ hb_ot_shape_collect_features (hb_ot_shape_planner_t *planner,
#define ADD_FEATURES(array) \
HB_STMT_START { \
for (unsigned int i = 0; i < ARRAY_LENGTH (array); i++) \
- planner->map.add_bool_feature (array[i]); \
+ map->add_bool_feature (array[i]); \
} HB_STMT_END
if (planner->shaper->collect_features)
@@ -116,7 +118,7 @@ hb_ot_shape_collect_features (hb_ot_shape_planner_t *planner,
for (unsigned int i = 0; i < num_user_features; i++) {
const hb_feature_t *feature = &user_features[i];
- planner->map.add_feature (feature->tag, feature->value, (feature->start == 0 && feature->end == (unsigned int) -1));
+ map->add_feature (feature->tag, feature->value, (feature->start == 0 && feature->end == (unsigned int) -1));
}
}
@@ -183,7 +185,7 @@ _hb_ot_shaper_shape_plan_data_create (hb_shape_plan_t *shape_plan,
void
_hb_ot_shaper_shape_plan_data_destroy (hb_ot_shaper_shape_plan_data_t *data)
{
- data->map.finish ();
+ data->finish ();
free (data);
}
@@ -211,7 +213,9 @@ struct hb_ot_shape_context_t
static void
hb_ot_shape_setup_masks (hb_ot_shape_context_t *c)
{
- hb_mask_t global_mask = c->plan->map.get_global_mask ();
+ hb_ot_map_t *map = &c->plan->map;
+
+ hb_mask_t global_mask = map->get_global_mask ();
c->buffer->reset_masks (global_mask);
if (c->plan->shaper->setup_masks)
@@ -222,7 +226,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->plan->map.get_mask (feature->tag, &shift);
+ hb_mask_t mask = map->get_mask (feature->tag, &shift);
c->buffer->set_masks (feature->value << shift, mask, feature->start, feature->end);
}
}
@@ -352,7 +356,7 @@ hb_ot_substitute_complex (hb_ot_shape_context_t *c)
hb_synthesize_glyph_classes (c);
if (hb_ot_layout_has_substitution (c->face))
- c->plan->map.substitute (c->font, c->buffer);
+ c->plan->substitute (c->font, c->buffer);
hb_ot_layout_substitute_finish (c->font, c->buffer);
@@ -408,7 +412,7 @@ hb_ot_position_complex (hb_ot_shape_context_t *c)
&c->buffer->pos[i].y_offset);
}
- c->plan->map.position (c->font, c->buffer);
+ c->plan->position (c->font, c->buffer);
for (unsigned int i = 0; i < count; i++) {
c->font->subtract_glyph_origin_for_direction (c->buffer->info[i].codepoint,
@@ -588,7 +592,7 @@ hb_ot_shape_glyphs_closure (hb_font_t *font,
do {
copy.set (glyphs);
- HB_SHAPER_DATA_GET (shape_plan)->map.substitute_closure (font->face, glyphs);
+ HB_SHAPER_DATA_GET (shape_plan)->substitute_closure (font->face, glyphs);
} while (!copy.equal (glyphs));
hb_shape_plan_destroy (shape_plan);
commit 3e38c0f2886c38d2f0a9d80a97a36edf2479d2c7
Author: Behdad Esfahbod <behdad at behdad.org>
Date: Thu Aug 2 09:44:18 2012 -0400
More massaging
diff --git a/src/hb-ot-map-private.hh b/src/hb-ot-map-private.hh
index 648e5df..18517c4 100644
--- a/src/hb-ot-map-private.hh
+++ b/src/hb-ot-map-private.hh
@@ -62,15 +62,11 @@ struct hb_ot_map_t
{ return a->index < b->index ? -1 : a->index > b->index ? 1 : 0; }
};
- typedef void (*pause_func_t) (const hb_ot_map_t *map, hb_font_t *font, hb_buffer_t *buffer, void *user_data);
- typedef struct {
- pause_func_t func;
- void *user_data;
- } pause_callback_t;
+ typedef void (*pause_func_t) (const hb_ot_map_t *map, hb_font_t *font, hb_buffer_t *buffer);
struct pause_map_t {
unsigned int num_lookups; /* Cumulative */
- pause_callback_t callback;
+ pause_func_t callback;
};
@@ -156,10 +152,10 @@ struct hb_ot_map_builder_t
inline void add_bool_feature (hb_tag_t tag, bool global = true)
{ add_feature (tag, 1, global); }
- inline void add_gsub_pause (hb_ot_map_t::pause_func_t pause_func, void *user_data)
- { add_pause (0, pause_func, user_data); }
- inline void add_gpos_pause (hb_ot_map_t::pause_func_t pause_func, void *user_data)
- { add_pause (1, pause_func, user_data); }
+ inline void add_gsub_pause (hb_ot_map_t::pause_func_t pause_func)
+ { add_pause (0, pause_func); }
+ inline void add_gpos_pause (hb_ot_map_t::pause_func_t pause_func)
+ { add_pause (1, pause_func); }
HB_INTERNAL void compile (hb_face_t *face,
const hb_segment_properties_t *props,
@@ -187,10 +183,10 @@ struct hb_ot_map_builder_t
struct pause_info_t {
unsigned int stage;
- hb_ot_map_t::pause_callback_t callback;
+ hb_ot_map_t::pause_func_t callback;
};
- HB_INTERNAL void add_pause (unsigned int table_index, hb_ot_map_t::pause_func_t pause_func, void *user_data);
+ HB_INTERNAL void add_pause (unsigned int table_index, hb_ot_map_t::pause_func_t pause_func);
unsigned int current_stage[2]; /* GSUB/GPOS */
hb_prealloced_array_t<feature_info_t,16> feature_infos;
diff --git a/src/hb-ot-map.cc b/src/hb-ot-map.cc
index 7192c2b..62afdef 100644
--- a/src/hb-ot-map.cc
+++ b/src/hb-ot-map.cc
@@ -87,8 +87,8 @@ void hb_ot_map_t::substitute (hb_font_t *font, hb_buffer_t *buffer) const
buffer->clear_output ();
- if (pause->callback.func)
- pause->callback.func (this, font, buffer, pause->callback.user_data);
+ if (pause->callback)
+ pause->callback (this, font, buffer);
}
for (; i < lookups[table_index].len; i++)
@@ -105,8 +105,8 @@ void hb_ot_map_t::position (hb_font_t *font, hb_buffer_t *buffer) const
for (; i < pause->num_lookups; i++)
hb_ot_layout_position_lookup (font, buffer, lookups[table_index][i].index, lookups[table_index][i].mask);
- if (pause->callback.func)
- pause->callback.func (this, font, buffer, pause->callback.user_data);
+ if (pause->callback)
+ pause->callback (this, font, buffer);
}
for (; i < lookups[table_index].len; i++)
@@ -129,13 +129,12 @@ void hb_ot_map_t::substitute_closure (hb_face_t *face,
hb_ot_layout_substitute_closure_lookup (face, glyphs, lookups[table_index][i].index);
}
-void hb_ot_map_builder_t::add_pause (unsigned int table_index, hb_ot_map_t::pause_func_t pause_func, void *user_data)
+void hb_ot_map_builder_t::add_pause (unsigned int table_index, hb_ot_map_t::pause_func_t pause_func)
{
pause_info_t *p = pauses[table_index].push ();
if (likely (p)) {
p->stage = current_stage[table_index];
- p->callback.func = pause_func;
- p->callback.user_data = user_data;
+ p->callback = pause_func;
}
current_stage[table_index]++;
@@ -249,8 +248,8 @@ hb_ot_map_builder_t::compile (hb_face_t *face,
feature_infos.shrink (0); /* Done with these */
- add_gsub_pause (NULL, NULL);
- add_gpos_pause (NULL, NULL);
+ add_gsub_pause (NULL);
+ add_gpos_pause (NULL);
for (unsigned int table_index = 0; table_index < 2; table_index++) {
hb_tag_t table_tag = table_tags[table_index];
diff --git a/src/hb-ot-shape-complex-arabic.cc b/src/hb-ot-shape-complex-arabic.cc
index 3290ee1..d08d364 100644
--- a/src/hb-ot-shape-complex-arabic.cc
+++ b/src/hb-ot-shape-complex-arabic.cc
@@ -182,19 +182,19 @@ collect_features_arabic (hb_ot_shape_planner_t *plan)
map->add_bool_feature (HB_TAG('c','c','m','p'));
map->add_bool_feature (HB_TAG('l','o','c','l'));
- map->add_gsub_pause (NULL, NULL);
+ map->add_gsub_pause (NULL);
unsigned int num_features = plan->props.script == HB_SCRIPT_SYRIAC ? SYRIAC_NUM_FEATURES : COMMON_NUM_FEATURES;
for (unsigned int i = 0; i < num_features; i++)
map->add_bool_feature (arabic_syriac_features[i], false);
- map->add_gsub_pause (NULL, NULL);
+ map->add_gsub_pause (NULL);
map->add_bool_feature (HB_TAG('r','l','i','g'));
- map->add_gsub_pause (NULL, NULL);
+ map->add_gsub_pause (NULL);
map->add_bool_feature (HB_TAG('c','a','l','t'));
- map->add_gsub_pause (NULL, NULL);
+ map->add_gsub_pause (NULL);
/* ArabicOT spec enables 'cswh' for Arabic where as for basic shaper it's disabled by default. */
map->add_bool_feature (HB_TAG('c','s','w','h'));
diff --git a/src/hb-ot-shape-complex-indic.cc b/src/hb-ot-shape-complex-indic.cc
index 652e4e6..6b55fb7 100644
--- a/src/hb-ot-shape-complex-indic.cc
+++ b/src/hb-ot-shape-complex-indic.cc
@@ -194,13 +194,11 @@ indic_other_features[] =
static void
initial_reordering (const hb_ot_map_t *map,
hb_font_t *font,
- hb_buffer_t *buffer,
- void *user_data HB_UNUSED);
+ hb_buffer_t *buffer);
static void
final_reordering (const hb_ot_map_t *map,
hb_font_t *font,
- hb_buffer_t *buffer,
- void *user_data HB_UNUSED);
+ hb_buffer_t *buffer);
static void
collect_features_indic (hb_ot_shape_planner_t *plan)
@@ -212,14 +210,14 @@ collect_features_indic (hb_ot_shape_planner_t *plan)
* there is a use of it, it's typically at the beginning. */
map->add_bool_feature (HB_TAG('c','c','m','p'));
- map->add_gsub_pause (initial_reordering, NULL);
+ map->add_gsub_pause (initial_reordering);
for (unsigned int i = 0; i < ARRAY_LENGTH (indic_basic_features); i++) {
map->add_bool_feature (indic_basic_features[i].tag, indic_basic_features[i].is_global);
- map->add_gsub_pause (NULL, NULL);
+ map->add_gsub_pause (NULL);
}
- map->add_gsub_pause (final_reordering, NULL);
+ map->add_gsub_pause (final_reordering);
for (unsigned int i = 0; i < ARRAY_LENGTH (indic_other_features); i++)
map->add_bool_feature (indic_other_features[i].tag, indic_other_features[i].is_global);
@@ -697,8 +695,7 @@ initial_reordering_non_indic (const hb_ot_map_t *map HB_UNUSED,
static void
initial_reordering (const hb_ot_map_t *map,
hb_font_t *font,
- hb_buffer_t *buffer,
- void *user_data HB_UNUSED)
+ hb_buffer_t *buffer)
{
update_consonant_positions (map, buffer, font);
@@ -1062,8 +1059,7 @@ final_reordering_syllable (hb_buffer_t *buffer,
static void
final_reordering (const hb_ot_map_t *map,
hb_font_t *font HB_UNUSED,
- hb_buffer_t *buffer,
- void *user_data HB_UNUSED)
+ hb_buffer_t *buffer)
{
unsigned int count = buffer->len;
if (!count) return;
commit 16c6a27b4bffc19026944c7bea9cf0a3a8ff1d8f
Author: Behdad Esfahbod <behdad at behdad.org>
Date: Thu Aug 2 09:38:28 2012 -0400
[OT] Port complex_shaper to planner/plan
diff --git a/src/hb-ot-shape-complex-arabic.cc b/src/hb-ot-shape-complex-arabic.cc
index 4ce09a8..3290ee1 100644
--- a/src/hb-ot-shape-complex-arabic.cc
+++ b/src/hb-ot-shape-complex-arabic.cc
@@ -165,10 +165,10 @@ static const struct arabic_state_table_entry {
static void
-collect_features_arabic (const hb_ot_complex_shaper_t *shaper,
- hb_ot_map_builder_t *map,
- const hb_segment_properties_t *props)
+collect_features_arabic (hb_ot_shape_planner_t *plan)
{
+ hb_ot_map_builder_t *map = &plan->map;
+
/* For Language forms (in ArabicOT speak), we do the iso/fina/medi/init together,
* then rlig and calt each in their own stage. This makes IranNastaliq's ALLAH
* ligature work correctly. It's unfortunate though...
@@ -184,7 +184,7 @@ collect_features_arabic (const hb_ot_complex_shaper_t *shaper,
map->add_gsub_pause (NULL, NULL);
- unsigned int num_features = props->script == HB_SCRIPT_SYRIAC ? SYRIAC_NUM_FEATURES : COMMON_NUM_FEATURES;
+ unsigned int num_features = plan->props.script == HB_SCRIPT_SYRIAC ? SYRIAC_NUM_FEATURES : COMMON_NUM_FEATURES;
for (unsigned int i = 0; i < num_features; i++)
map->add_bool_feature (arabic_syriac_features[i], false);
@@ -236,10 +236,9 @@ arabic_fallback_shape (hb_font_t *font, hb_buffer_t *buffer)
}
static void
-setup_masks_arabic (const hb_ot_complex_shaper_t *shaper,
- const hb_ot_map_t *map,
- hb_buffer_t *buffer,
- hb_font_t *font)
+setup_masks_arabic (const hb_ot_shape_plan_t *plan,
+ hb_buffer_t *buffer,
+ hb_font_t *font)
{
unsigned int count = buffer->len;
unsigned int prev = 0, state = 0;
@@ -270,7 +269,7 @@ setup_masks_arabic (const hb_ot_complex_shaper_t *shaper,
hb_mask_t total_masks = 0;
unsigned int num_masks = buffer->props.script == HB_SCRIPT_SYRIAC ? SYRIAC_NUM_FEATURES : COMMON_NUM_FEATURES;
for (unsigned int i = 0; i < num_masks; i++) {
- mask_array[i] = map->get_1_mask (arabic_syriac_features[i]);
+ mask_array[i] = plan->map.get_1_mask (arabic_syriac_features[i]);
total_masks |= mask_array[i];
}
diff --git a/src/hb-ot-shape-complex-indic.cc b/src/hb-ot-shape-complex-indic.cc
index 19ff048..652e4e6 100644
--- a/src/hb-ot-shape-complex-indic.cc
+++ b/src/hb-ot-shape-complex-indic.cc
@@ -203,10 +203,10 @@ final_reordering (const hb_ot_map_t *map,
void *user_data HB_UNUSED);
static void
-collect_features_indic (const hb_ot_complex_shaper_t *shaper,
- hb_ot_map_builder_t *map,
- const hb_segment_properties_t *props)
+collect_features_indic (hb_ot_shape_planner_t *plan)
{
+ hb_ot_map_builder_t *map = &plan->map;
+
map->add_bool_feature (HB_TAG('l','o','c','l'));
/* The Indic specs do not require ccmp, but we apply it here since if
* there is a use of it, it's typically at the beginning. */
@@ -226,21 +226,18 @@ collect_features_indic (const hb_ot_complex_shaper_t *shaper,
}
static void
-override_features_indic (const hb_ot_complex_shaper_t *shaper,
- hb_ot_map_builder_t *map,
- const hb_segment_properties_t *props)
+override_features_indic (hb_ot_shape_planner_t *plan)
{
/* Uniscribe does not apply 'kern'. */
if (indic_options ().uniscribe_bug_compatible)
- map->add_feature (HB_TAG('k','e','r','n'), 0, true);
+ plan->map.add_feature (HB_TAG('k','e','r','n'), 0, true);
}
static void
-setup_masks_indic (const hb_ot_complex_shaper_t *shaper,
- const hb_ot_map_t *map,
- hb_buffer_t *buffer,
- hb_font_t *font HB_UNUSED)
+setup_masks_indic (const hb_ot_shape_plan_t *plan HB_UNUSED,
+ hb_buffer_t *buffer,
+ hb_font_t *font HB_UNUSED)
{
HB_BUFFER_ALLOCATE_VAR (buffer, indic_category);
HB_BUFFER_ALLOCATE_VAR (buffer, indic_position);
diff --git a/src/hb-ot-shape-complex-misc.cc b/src/hb-ot-shape-complex-misc.cc
index 06b873a..6ae9f50 100644
--- a/src/hb-ot-shape-complex-misc.cc
+++ b/src/hb-ot-shape-complex-misc.cc
@@ -50,13 +50,11 @@ static const hb_tag_t tibetan_features[] =
};
static void
-collect_features_default (const hb_ot_complex_shaper_t *shaper,
- hb_ot_map_builder_t *map,
- const hb_segment_properties_t *props)
+collect_features_default (hb_ot_shape_planner_t *plan)
{
const hb_tag_t *script_features = NULL;
- switch ((hb_tag_t) props->script)
+ switch ((hb_tag_t) plan->props.script)
{
/* Unicode-1.1 additions */
case HB_SCRIPT_HANGUL:
@@ -70,14 +68,13 @@ collect_features_default (const hb_ot_complex_shaper_t *shaper,
}
for (; script_features && *script_features; script_features++)
- map->add_bool_feature (*script_features);
+ plan->map.add_bool_feature (*script_features);
}
static hb_ot_shape_normalization_mode_t
-normalization_preference_default (const hb_ot_complex_shaper_t *shaper,
- const hb_segment_properties_t *props)
+normalization_preference_default (const hb_ot_shape_plan_t *plan)
{
- switch ((hb_tag_t) props->script)
+ switch ((hb_tag_t) plan->props.script)
{
/* Unicode-1.1 additions */
case HB_SCRIPT_HANGUL:
@@ -100,10 +97,9 @@ const hb_ot_complex_shaper_t _hb_ot_complex_shaper_default =
/* Thai / Lao shaper */
static void
-setup_masks_thai (const hb_ot_complex_shaper_t *shaper,
- const hb_ot_map_t *map,
- hb_buffer_t *buffer,
- hb_font_t *font)
+setup_masks_thai (const hb_ot_shape_plan_t *plan HB_UNUSED,
+ hb_buffer_t *buffer,
+ hb_font_t *font HB_UNUSED)
{
/* The following is NOT specified in the MS OT Thai spec, however, it seems
* to be what Uniscribe and other engines implement. According to Eric Muller:
diff --git a/src/hb-ot-shape-complex-private.hh b/src/hb-ot-shape-complex-private.hh
index 9cdafff..e7f9697 100644
--- a/src/hb-ot-shape-complex-private.hh
+++ b/src/hb-ot-shape-complex-private.hh
@@ -29,15 +29,11 @@
#include "hb-private.hh"
-#include "hb-ot-map-private.hh"
+#include "hb-ot-shape-private.hh"
#include "hb-ot-shape-normalize-private.hh"
-/* buffer var allocations, used during the entire shaping process */
-#define unicode_props0() var1.u8[0]
-#define unicode_props1() var1.u8[1]
-
/* buffer var allocations, used by complex shapers */
#define complex_var_persistent_u8_0() var2.u8[2]
#define complex_var_persistent_u8_1() var2.u8[3]
@@ -60,39 +56,33 @@ struct hb_ot_complex_shaper_t
/* collect_features()
* Called during shape_plan().
- * Shapers should use map to add their features and callbacks.
+ * Shapers should use plan->map to add their features and callbacks.
* May be NULL.
*/
- void (*collect_features) (const hb_ot_complex_shaper_t *shaper,
- hb_ot_map_builder_t *map,
- const hb_segment_properties_t *props);
+ void (*collect_features) (hb_ot_shape_planner_t *plan);
/* override_features()
* Called during shape_plan().
- * Shapers should use map to override features and add callbacks after
+ * Shapers should use plan->map to override features and add callbacks after
* common features are added.
* May be NULL.
*/
- void (*override_features) (const hb_ot_complex_shaper_t *shaper,
- hb_ot_map_builder_t *map,
- const hb_segment_properties_t *props);
+ void (*override_features) (hb_ot_shape_planner_t *plan);
/* normalization_preference()
- * Called during shape_execute().
+ * Called during shape().
*/
hb_ot_shape_normalization_mode_t
- (*normalization_preference) (const hb_ot_complex_shaper_t *shaper,
- const hb_segment_properties_t *props);
+ (*normalization_preference) (const hb_ot_shape_plan_t *plan);
/* setup_masks()
- * Called during shape_execute().
+ * Called during shape().
* Shapers should use map to get feature masks and set on buffer.
*/
- void (*setup_masks) (const hb_ot_complex_shaper_t *shaper,
- const hb_ot_map_t *map,
- hb_buffer_t *buffer,
- hb_font_t *font);
+ void (*setup_masks) (const hb_ot_shape_plan_t *plan,
+ hb_buffer_t *buffer,
+ hb_font_t *font);
bool zero_width_attached_marks;
};
diff --git a/src/hb-ot-shape-private.hh b/src/hb-ot-shape-private.hh
index 89f15be..0c26528 100644
--- a/src/hb-ot-shape-private.hh
+++ b/src/hb-ot-shape-private.hh
@@ -30,12 +30,19 @@
#include "hb-private.hh"
#include "hb-ot-map-private.hh"
-#include "hb-ot-shape-complex-private.hh"
+
+
+
+/* buffer var allocations, used during the entire shaping process */
+#define unicode_props0() var1.u8[0]
+#define unicode_props1() var1.u8[1]
+
struct hb_ot_shape_plan_t
{
- const hb_ot_complex_shaper_t *shaper;
+ hb_segment_properties_t props;
+ const struct hb_ot_complex_shaper_t *shaper;
hb_ot_map_t map;
};
@@ -44,7 +51,7 @@ struct hb_ot_shape_planner_t
/* In the order that they are filled in. */
hb_face_t *face;
hb_segment_properties_t props;
- const hb_ot_complex_shaper_t *shaper;
+ const struct hb_ot_complex_shaper_t *shaper;
hb_ot_map_builder_t map;
hb_ot_shape_planner_t (const hb_shape_plan_t *master_plan) :
@@ -56,6 +63,7 @@ struct hb_ot_shape_planner_t
inline void compile (hb_ot_shape_plan_t &plan)
{
+ plan.props = props;
plan.shaper = shaper;
map.compile (face, &props, plan.map);
}
diff --git a/src/hb-ot-shape.cc b/src/hb-ot-shape.cc
index f6d7a83..c874fb5 100644
--- a/src/hb-ot-shape.cc
+++ b/src/hb-ot-shape.cc
@@ -33,6 +33,7 @@
#include "hb-ot-shape-private.hh"
#include "hb-ot-shape-normalize-private.hh"
+#include "hb-ot-shape-complex-private.hh"
#include "hb-ot-layout-private.hh"
#include "hb-set-private.hh"
@@ -99,7 +100,7 @@ hb_ot_shape_collect_features (hb_ot_shape_planner_t *planner,
} HB_STMT_END
if (planner->shaper->collect_features)
- planner->shaper->collect_features (planner->shaper, &planner->map, props);
+ planner->shaper->collect_features (planner);
ADD_FEATURES (common_features);
@@ -109,7 +110,7 @@ hb_ot_shape_collect_features (hb_ot_shape_planner_t *planner,
ADD_FEATURES (vertical_features);
if (planner->shaper->override_features)
- planner->shaper->override_features (planner->shaper, &planner->map, props);
+ planner->shaper->override_features (planner);
#undef ADD_FEATURES
@@ -214,7 +215,7 @@ hb_ot_shape_setup_masks (hb_ot_shape_context_t *c)
c->buffer->reset_masks (global_mask);
if (c->plan->shaper->setup_masks)
- c->plan->shaper->setup_masks (c->plan->shaper, &c->plan->map, c->buffer, c->font);
+ c->plan->shaper->setup_masks (c->plan, c->buffer, c->font);
for (unsigned int i = 0; i < c->num_user_features; i++)
{
@@ -503,7 +504,7 @@ hb_ot_shape_internal (hb_ot_shape_context_t *c)
_hb_ot_shape_normalize (c->font, c->buffer,
c->plan->shaper->normalization_preference ?
- c->plan->shaper->normalization_preference (c->plan->shaper, &c->buffer->props) :
+ c->plan->shaper->normalization_preference (c->plan) :
HB_OT_SHAPE_NORMALIZATION_MODE_DEFAULT);
hb_ot_shape_setup_masks (c);
commit 5393e3a62ba09fd7bcf3767b36225c8f49badb9d
Author: Behdad Esfahbod <behdad at behdad.org>
Date: Thu Aug 2 09:24:35 2012 -0400
[OT] Minor refactoring
diff --git a/src/hb-ot-map.cc b/src/hb-ot-map.cc
index 03c9ba1..7192c2b 100644
--- a/src/hb-ot-map.cc
+++ b/src/hb-ot-map.cc
@@ -28,8 +28,6 @@
#include "hb-ot-map-private.hh"
-#include "hb-ot-shape-private.hh"
-
void
hb_ot_map_t::add_lookups (hb_face_t *face,
@@ -303,5 +301,3 @@ hb_ot_map_builder_t::compile (hb_face_t *face,
}
}
}
-
-
diff --git a/src/hb-ot-shape-private.hh b/src/hb-ot-shape-private.hh
index fd45e2d..89f15be 100644
--- a/src/hb-ot-shape-private.hh
+++ b/src/hb-ot-shape-private.hh
@@ -35,11 +35,37 @@
struct hb_ot_shape_plan_t
{
+ const hb_ot_complex_shaper_t *shaper;
hb_ot_map_t map;
+};
+
+struct hb_ot_shape_planner_t
+{
+ /* In the order that they are filled in. */
+ hb_face_t *face;
+ hb_segment_properties_t props;
const hb_ot_complex_shaper_t *shaper;
+ hb_ot_map_builder_t map;
+
+ hb_ot_shape_planner_t (const hb_shape_plan_t *master_plan) :
+ face (master_plan->face),
+ props (master_plan->props),
+ shaper (NULL),
+ map () {}
+ ~hb_ot_shape_planner_t (void) { map.finish (); }
+
+ inline void compile (hb_ot_shape_plan_t &plan)
+ {
+ plan.shaper = shaper;
+ map.compile (face, &props, plan.map);
+ }
+
+ private:
+ NO_COPY (hb_ot_shape_planner_t);
};
+
inline void
_hb_glyph_info_set_unicode_props (hb_glyph_info_t *info, hb_unicode_funcs_t *unicode)
{
diff --git a/src/hb-ot-shape.cc b/src/hb-ot-shape.cc
index 66664c5..f6d7a83 100644
--- a/src/hb-ot-shape.cc
+++ b/src/hb-ot-shape.cc
@@ -70,26 +70,6 @@ hb_tag_t vertical_features[] = {
-struct hb_ot_shape_planner_t
-{
- hb_ot_map_builder_t map;
- const hb_ot_complex_shaper_t *shaper;
-
- hb_ot_shape_planner_t (void) : map () {}
- ~hb_ot_shape_planner_t (void) { map.finish (); }
-
- inline void compile (hb_face_t *face,
- const hb_segment_properties_t *props,
- hb_ot_shape_plan_t &plan)
- {
- plan.shaper = shaper;
- map.compile (face, props, plan.map);
- }
-
- private:
- NO_COPY (hb_ot_shape_planner_t);
-};
-
static void
hb_ot_shape_collect_features (hb_ot_shape_planner_t *planner,
const hb_segment_properties_t *props,
@@ -188,15 +168,13 @@ _hb_ot_shaper_shape_plan_data_create (hb_shape_plan_t *shape_plan,
if (unlikely (!data))
return NULL;
- hb_ot_shape_planner_t planner;
-
- assert (HB_DIRECTION_IS_VALID (shape_plan->props.direction));
+ hb_ot_shape_planner_t planner (shape_plan);
planner.shaper = hb_ot_shape_complex_categorize (&shape_plan->props);
hb_ot_shape_collect_features (&planner, &shape_plan->props, user_features, num_user_features);
- planner.compile (shape_plan->face, &shape_plan->props, *data);
+ planner.compile (*data);
return data;
}
diff --git a/src/hb-shape-plan.cc b/src/hb-shape-plan.cc
index a478ba5..974c370 100644
--- a/src/hb-shape-plan.cc
+++ b/src/hb-shape-plan.cc
@@ -90,6 +90,8 @@ hb_shape_plan_create (hb_face_t *face,
unsigned int num_user_features,
const char * const *shaper_list)
{
+ assert (props->direction != HB_DIRECTION_INVALID);
+
hb_shape_plan_t *shape_plan;
if (unlikely (!face))
diff --git a/src/hb-shape.cc b/src/hb-shape.cc
index b3d373b..5aa587b 100644
--- a/src/hb-shape.cc
+++ b/src/hb-shape.cc
@@ -87,8 +87,6 @@ hb_shape_full (hb_font_t *font,
buffer->guess_properties ();
- assert (buffer->props.direction != HB_DIRECTION_INVALID);
-
hb_shape_plan_t *shape_plan = hb_shape_plan_create_cached (font->face, &buffer->props, features, num_features, shaper_list);
hb_bool_t res = hb_shape_plan_execute (shape_plan, font, buffer, features, num_features);
hb_shape_plan_destroy (shape_plan);
More information about the HarfBuzz
mailing list