[HarfBuzz] harfbuzz: Branch 'master' - 18 commits
Behdad Esfahbod
behdad at kemper.freedesktop.org
Thu Oct 17 10:53:16 PDT 2013
src/hb-ot-layout-common-private.hh | 2
src/hb-ot-layout-gsub-table.hh | 20 +--
src/hb-ot-layout-gsubgpos-private.hh | 85 +++++++--------
src/hb-ot-layout.cc | 4
src/hb-ot-shape-complex-indic.cc | 191 +++++++++++++++++++++--------------
src/hb-ot-shape-complex-private.hh | 4
src/hb-ot-shape-complex-sea.cc | 2
7 files changed, 176 insertions(+), 132 deletions(-)
New commits:
commit 8f9ec92dfce5c469fb85ad301296b5dde1b2ab0a
Author: Behdad Esfahbod <behdad at behdad.org>
Date: Thu Oct 17 19:52:47 2013 +0200
[indic] Adjust Javanese base algorithm
diff --git a/src/hb-ot-shape-complex-indic.cc b/src/hb-ot-shape-complex-indic.cc
index 587977b..bc79025 100644
--- a/src/hb-ot-shape-complex-indic.cc
+++ b/src/hb-ot-shape-complex-indic.cc
@@ -323,7 +323,7 @@ static const indic_config_t indic_configs[] =
{HB_SCRIPT_SINHALA, false,0x0DCA,BASE_POS_LAST_SINHALA,
REPH_POS_AFTER_MAIN, REPH_MODE_EXPLICIT, BLWF_MODE_PRE_AND_POST, PREF_LEN_DONT_CARE},
{HB_SCRIPT_KHMER, false,0x17D2,BASE_POS_FIRST,REPH_POS_DONT_CARE, REPH_MODE_VIS_REPHA,BLWF_MODE_PRE_AND_POST, PREF_LEN_2},
- {HB_SCRIPT_JAVANESE, false,0xA9C0,BASE_POS_LAST, REPH_POS_DONT_CARE, REPH_MODE_VIS_REPHA,BLWF_MODE_PRE_AND_POST, PREF_LEN_1},
+ {HB_SCRIPT_JAVANESE, false,0xA9C0,BASE_POS_FIRST,REPH_POS_DONT_CARE, REPH_MODE_VIS_REPHA,BLWF_MODE_PRE_AND_POST, PREF_LEN_1},
};
commit 49901862e36e1c153835877a9f1183729333bbbe
Author: Behdad Esfahbod <behdad at behdad.org>
Date: Thu Oct 17 19:48:51 2013 +0200
[otlayout] Guard against use of ReverseChain through Context
diff --git a/src/hb-ot-layout-gsub-table.hh b/src/hb-ot-layout-gsub-table.hh
index a595a4b..28ba3b9 100644
--- a/src/hb-ot-layout-gsub-table.hh
+++ b/src/hb-ot-layout-gsub-table.hh
@@ -1037,7 +1037,9 @@ struct ReverseChainSingleSubstFormat1
1))
{
c->replace_glyph_inplace (substitute[index]);
- c->buffer->idx--; /* Reverse! */
+ /* Note: We DON'T decrease buffer->idx. The main loop does it
+ * for us. This is useful for preventing surprises if someone
+ * calls us through a Context lookup. */
return TRACE_RETURN (true);
}
diff --git a/src/hb-ot-layout.cc b/src/hb-ot-layout.cc
index 5f3eb57..06c98d2 100644
--- a/src/hb-ot-layout.cc
+++ b/src/hb-ot-layout.cc
@@ -867,8 +867,8 @@ apply_string (OT::hb_apply_context_t *c,
(c->buffer->cur().mask & c->lookup_mask) &&
apply_once (c, lookup))
ret = true;
- else
- c->buffer->idx--;
+ /* The reverse lookup doesn't "advance" cursor (for good reason). */
+ c->buffer->idx--;
}
while ((int) c->buffer->idx >= 0);
commit 74f4bbf0560a5fd2d295e100e96f0c6c7033e852
Author: Behdad Esfahbod <behdad at behdad.org>
Date: Thu Oct 17 19:07:53 2013 +0200
[indic] Towards supporting atomicly-encoded prebase-reorderings
diff --git a/src/hb-ot-shape-complex-indic.cc b/src/hb-ot-shape-complex-indic.cc
index e1f64d1..587977b 100644
--- a/src/hb-ot-shape-complex-indic.cc
+++ b/src/hb-ot-shape-complex-indic.cc
@@ -273,12 +273,12 @@ enum base_position_t {
BASE_POS_LAST
};
enum reph_position_t {
- REPH_POS_DONT_CARE = POS_RA_TO_BECOME_REPH,
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
+ REPH_POS_AFTER_POST = POS_AFTER_POST,
+ REPH_POS_DONT_CARE = POS_RA_TO_BECOME_REPH
};
enum reph_mode_t {
REPH_MODE_IMPLICIT, /* Reph formed out of initial Ra,H sequence. */
@@ -290,6 +290,11 @@ enum blwf_mode_t {
BLWF_MODE_PRE_AND_POST, /* Below-forms feature applied to pre-base and post-base. */
BLWF_MODE_POST_ONLY /* Below-forms feature applied to post-base only. */
};
+enum pref_len_t {
+ PREF_LEN_1 = 1,
+ PREF_LEN_2 = 2,
+ PREF_LEN_DONT_CARE = PREF_LEN_2
+};
struct indic_config_t
{
hb_script_t script;
@@ -299,25 +304,26 @@ struct indic_config_t
reph_position_t reph_pos;
reph_mode_t reph_mode;
blwf_mode_t blwf_mode;
+ pref_len_t pref_len;
};
static const indic_config_t indic_configs[] =
{
/* Default. Should be first. */
- {HB_SCRIPT_INVALID, false, 0,BASE_POS_LAST, REPH_POS_BEFORE_POST,REPH_MODE_IMPLICIT, BLWF_MODE_PRE_AND_POST},
- {HB_SCRIPT_DEVANAGARI,true, 0x094D,BASE_POS_LAST, REPH_POS_BEFORE_POST,REPH_MODE_IMPLICIT, BLWF_MODE_PRE_AND_POST},
- {HB_SCRIPT_BENGALI, true, 0x09CD,BASE_POS_LAST, REPH_POS_AFTER_SUB, REPH_MODE_IMPLICIT, BLWF_MODE_PRE_AND_POST},
- {HB_SCRIPT_GURMUKHI, true, 0x0A4D,BASE_POS_LAST, REPH_POS_BEFORE_SUB, REPH_MODE_IMPLICIT, BLWF_MODE_PRE_AND_POST},
- {HB_SCRIPT_GUJARATI, true, 0x0ACD,BASE_POS_LAST, REPH_POS_BEFORE_POST,REPH_MODE_IMPLICIT, BLWF_MODE_PRE_AND_POST},
- {HB_SCRIPT_ORIYA, true, 0x0B4D,BASE_POS_LAST, REPH_POS_AFTER_MAIN, REPH_MODE_IMPLICIT, BLWF_MODE_PRE_AND_POST},
- {HB_SCRIPT_TAMIL, true, 0x0BCD,BASE_POS_LAST, REPH_POS_AFTER_POST, REPH_MODE_IMPLICIT, BLWF_MODE_PRE_AND_POST},
- {HB_SCRIPT_TELUGU, true, 0x0C4D,BASE_POS_LAST, REPH_POS_AFTER_POST, REPH_MODE_EXPLICIT, BLWF_MODE_POST_ONLY},
- {HB_SCRIPT_KANNADA, true, 0x0CCD,BASE_POS_LAST, REPH_POS_AFTER_POST, REPH_MODE_IMPLICIT, BLWF_MODE_POST_ONLY},
- {HB_SCRIPT_MALAYALAM, true, 0x0D4D,BASE_POS_LAST, REPH_POS_AFTER_MAIN, REPH_MODE_LOG_REPHA,BLWF_MODE_PRE_AND_POST},
+ {HB_SCRIPT_INVALID, false, 0,BASE_POS_LAST, REPH_POS_BEFORE_POST,REPH_MODE_IMPLICIT, BLWF_MODE_PRE_AND_POST, PREF_LEN_1},
+ {HB_SCRIPT_DEVANAGARI,true, 0x094D,BASE_POS_LAST, REPH_POS_BEFORE_POST,REPH_MODE_IMPLICIT, BLWF_MODE_PRE_AND_POST, PREF_LEN_DONT_CARE},
+ {HB_SCRIPT_BENGALI, true, 0x09CD,BASE_POS_LAST, REPH_POS_AFTER_SUB, REPH_MODE_IMPLICIT, BLWF_MODE_PRE_AND_POST, PREF_LEN_DONT_CARE},
+ {HB_SCRIPT_GURMUKHI, true, 0x0A4D,BASE_POS_LAST, REPH_POS_BEFORE_SUB, REPH_MODE_IMPLICIT, BLWF_MODE_PRE_AND_POST, PREF_LEN_DONT_CARE},
+ {HB_SCRIPT_GUJARATI, true, 0x0ACD,BASE_POS_LAST, REPH_POS_BEFORE_POST,REPH_MODE_IMPLICIT, BLWF_MODE_PRE_AND_POST, PREF_LEN_DONT_CARE},
+ {HB_SCRIPT_ORIYA, true, 0x0B4D,BASE_POS_LAST, REPH_POS_AFTER_MAIN, REPH_MODE_IMPLICIT, BLWF_MODE_PRE_AND_POST, PREF_LEN_DONT_CARE},
+ {HB_SCRIPT_TAMIL, true, 0x0BCD,BASE_POS_LAST, REPH_POS_AFTER_POST, REPH_MODE_IMPLICIT, BLWF_MODE_PRE_AND_POST, PREF_LEN_2},
+ {HB_SCRIPT_TELUGU, true, 0x0C4D,BASE_POS_LAST, REPH_POS_AFTER_POST, REPH_MODE_EXPLICIT, BLWF_MODE_POST_ONLY, PREF_LEN_2},
+ {HB_SCRIPT_KANNADA, true, 0x0CCD,BASE_POS_LAST, REPH_POS_AFTER_POST, REPH_MODE_IMPLICIT, BLWF_MODE_POST_ONLY, PREF_LEN_2},
+ {HB_SCRIPT_MALAYALAM, true, 0x0D4D,BASE_POS_LAST, REPH_POS_AFTER_MAIN, REPH_MODE_LOG_REPHA,BLWF_MODE_PRE_AND_POST, PREF_LEN_2},
{HB_SCRIPT_SINHALA, false,0x0DCA,BASE_POS_LAST_SINHALA,
- REPH_POS_AFTER_MAIN, REPH_MODE_EXPLICIT, BLWF_MODE_PRE_AND_POST},
- {HB_SCRIPT_KHMER, false,0x17D2,BASE_POS_FIRST,REPH_POS_DONT_CARE, REPH_MODE_VIS_REPHA,BLWF_MODE_PRE_AND_POST},
- {HB_SCRIPT_JAVANESE, false,0xA9C0,BASE_POS_LAST, REPH_POS_DONT_CARE, REPH_MODE_VIS_REPHA,BLWF_MODE_PRE_AND_POST},
+ REPH_POS_AFTER_MAIN, REPH_MODE_EXPLICIT, BLWF_MODE_PRE_AND_POST, PREF_LEN_DONT_CARE},
+ {HB_SCRIPT_KHMER, false,0x17D2,BASE_POS_FIRST,REPH_POS_DONT_CARE, REPH_MODE_VIS_REPHA,BLWF_MODE_PRE_AND_POST, PREF_LEN_2},
+ {HB_SCRIPT_JAVANESE, false,0xA9C0,BASE_POS_LAST, REPH_POS_DONT_CARE, REPH_MODE_VIS_REPHA,BLWF_MODE_PRE_AND_POST, PREF_LEN_1},
};
@@ -588,8 +594,12 @@ consonant_position_from_face (const indic_shape_plan_t *indic_plan,
if (indic_plan->pstf.would_substitute (glyphs , 2, face) ||
indic_plan->pstf.would_substitute (glyphs+1, 2, face))
return POS_POST_C;
- if (indic_plan->pref.would_substitute (glyphs , 2, face) ||
- indic_plan->pref.would_substitute (glyphs+1, 2, face))
+ unsigned int pref_len = indic_plan->config->pref_len;
+ if ((pref_len == PREF_LEN_2 &&
+ (indic_plan->pref.would_substitute (glyphs , 2, face) ||
+ indic_plan->pref.would_substitute (glyphs+1, 2, face)))
+ || (pref_len == PREF_LEN_1 &&
+ indic_plan->pref.would_substitute (glyphs+1, 1, face)))
return POS_POST_C;
return POS_BASE_C;
}
@@ -1068,15 +1078,19 @@ initial_reordering_consonant_syllable (const hb_ot_shape_plan_t *plan,
}
}
- if (indic_plan->mask_array[PREF] && base + 2 < end)
+ unsigned int pref_len = indic_plan->config->pref_len;
+ if (indic_plan->mask_array[PREF] && base + pref_len < end)
{
+ assert (1 <= pref_len && pref_len <= 2);
/* Find a Halant,Ra sequence and mark it for pre-base reordering processing. */
- for (unsigned int i = base + 1; i + 1 < end; i++) {
- hb_codepoint_t glyphs[2] = {info[i].codepoint, info[i + 1].codepoint};
- if (indic_plan->pref.would_substitute (glyphs, ARRAY_LENGTH (glyphs), face))
+ for (unsigned int i = base + 1; i + pref_len - 1 < end; i++) {
+ hb_codepoint_t glyphs[2];
+ for (unsigned int j = 0; j < pref_len; j++)
+ glyphs[j] = info[i + j].codepoint;
+ if (indic_plan->pref.would_substitute (glyphs, pref_len, face))
{
- info[i++].mask |= indic_plan->mask_array[PREF];
- info[i++].mask |= indic_plan->mask_array[PREF];
+ for (unsigned int j = 0; j < pref_len; j++)
+ info[i++].mask |= indic_plan->mask_array[PREF];
/* Mark the subsequent stuff with 'cfar'. Used in Khmer.
* Read the feature spec.
@@ -1084,8 +1098,9 @@ initial_reordering_consonant_syllable (const hb_ot_shape_plan_t *plan,
* U+1784,U+17D2,U+179A,U+17D2,U+1782
* U+1784,U+17D2,U+1782,U+17D2,U+179A
*/
- for (; i < end; i++)
- info[i].mask |= indic_plan->mask_array[CFAR];
+ if (indic_plan->mask_array[CFAR])
+ for (; i < end; i++)
+ info[i].mask |= indic_plan->mask_array[CFAR];
break;
}
commit efed40b975110d78c9c505441e7e17a8c13e85c8
Author: Behdad Esfahbod <behdad at behdad.org>
Date: Thu Oct 17 18:50:11 2013 +0200
[indic] Minor refactoring of reph handling
diff --git a/src/hb-ot-shape-complex-indic.cc b/src/hb-ot-shape-complex-indic.cc
index 8c3e1e0..e1f64d1 100644
--- a/src/hb-ot-shape-complex-indic.cc
+++ b/src/hb-ot-shape-complex-indic.cc
@@ -273,8 +273,7 @@ enum base_position_t {
BASE_POS_LAST
};
enum reph_position_t {
- REPH_POS_DEFAULT = POS_BEFORE_POST,
-
+ REPH_POS_DONT_CARE = POS_RA_TO_BECOME_REPH,
REPH_POS_AFTER_MAIN = POS_AFTER_MAIN,
REPH_POS_BEFORE_SUB = POS_BEFORE_SUB,
REPH_POS_AFTER_SUB = POS_AFTER_SUB,
@@ -305,7 +304,7 @@ struct indic_config_t
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, BLWF_MODE_PRE_AND_POST},
+ {HB_SCRIPT_INVALID, false, 0,BASE_POS_LAST, REPH_POS_BEFORE_POST,REPH_MODE_IMPLICIT, BLWF_MODE_PRE_AND_POST},
{HB_SCRIPT_DEVANAGARI,true, 0x094D,BASE_POS_LAST, REPH_POS_BEFORE_POST,REPH_MODE_IMPLICIT, BLWF_MODE_PRE_AND_POST},
{HB_SCRIPT_BENGALI, true, 0x09CD,BASE_POS_LAST, REPH_POS_AFTER_SUB, REPH_MODE_IMPLICIT, BLWF_MODE_PRE_AND_POST},
{HB_SCRIPT_GURMUKHI, true, 0x0A4D,BASE_POS_LAST, REPH_POS_BEFORE_SUB, REPH_MODE_IMPLICIT, BLWF_MODE_PRE_AND_POST},
@@ -317,8 +316,8 @@ static const indic_config_t indic_configs[] =
{HB_SCRIPT_MALAYALAM, true, 0x0D4D,BASE_POS_LAST, REPH_POS_AFTER_MAIN, REPH_MODE_LOG_REPHA,BLWF_MODE_PRE_AND_POST},
{HB_SCRIPT_SINHALA, false,0x0DCA,BASE_POS_LAST_SINHALA,
REPH_POS_AFTER_MAIN, REPH_MODE_EXPLICIT, BLWF_MODE_PRE_AND_POST},
- {HB_SCRIPT_KHMER, false,0x17D2,BASE_POS_FIRST,REPH_POS_DEFAULT, REPH_MODE_VIS_REPHA,BLWF_MODE_PRE_AND_POST},
- {HB_SCRIPT_JAVANESE, false,0xA9C0,BASE_POS_LAST, REPH_POS_DEFAULT, REPH_MODE_IMPLICIT, BLWF_MODE_PRE_AND_POST},
+ {HB_SCRIPT_KHMER, false,0x17D2,BASE_POS_FIRST,REPH_POS_DONT_CARE, REPH_MODE_VIS_REPHA,BLWF_MODE_PRE_AND_POST},
+ {HB_SCRIPT_JAVANESE, false,0xA9C0,BASE_POS_LAST, REPH_POS_DONT_CARE, REPH_MODE_VIS_REPHA,BLWF_MODE_PRE_AND_POST},
};
@@ -702,7 +701,8 @@ initial_reordering_consonant_syllable (const hb_ot_shape_plan_t *plan,
* and has more than one consonant, Ra is excluded from candidates for
* base consonants. */
unsigned int limit = start;
- if (indic_plan->mask_array[RPHF] &&
+ if (indic_plan->config->reph_pos != POS_RA_TO_BECOME_REPH &&
+ indic_plan->mask_array[RPHF] &&
start + 3 <= end &&
(
(indic_plan->config->reph_mode == REPH_MODE_IMPLICIT && !is_joiner (info[start + 2])) ||
@@ -816,6 +816,7 @@ initial_reordering_consonant_syllable (const hb_ot_shape_plan_t *plan,
/* The first consonant is always the base. */
assert (indic_plan->config->reph_mode == REPH_MODE_VIS_REPHA);
+ assert (!has_reph);
base = start;
@@ -1394,6 +1395,7 @@ final_reordering_syllable (const hb_ot_shape_plan_t *plan,
unsigned int new_reph_pos;
reph_position_t reph_pos = indic_plan->config->reph_pos;
+ assert (reph_pos != POS_RA_TO_BECOME_REPH);
/* 1. If reph should be positioned after post-base consonant forms,
* proceed to step 5.
diff --git a/src/hb-ot-shape-complex-sea.cc b/src/hb-ot-shape-complex-sea.cc
index 9c0c303..da687ed 100644
--- a/src/hb-ot-shape-complex-sea.cc
+++ b/src/hb-ot-shape-complex-sea.cc
@@ -266,7 +266,7 @@ initial_reordering_syllable (const hb_ot_shape_plan_t *plan,
switch (syllable_type) {
case consonant_syllable: initial_reordering_consonant_syllable (plan, face, buffer, start, end); return;
case broken_cluster: initial_reordering_broken_cluster (plan, face, buffer, start, end); return;
- case non_sea_cluster: initial_reordering_non_sea_cluster (plan, face, buffer, start, end); return;
+ case non_sea_cluster: initial_reordering_non_sea_cluster (plan, face, buffer, start, end); return;
}
}
commit 684fe59ff858a0ecba71b3ed80378afb0b8bbb48
Author: Behdad Esfahbod <behdad at behdad.org>
Date: Thu Oct 17 18:30:06 2013 +0200
[indic] Minor refactoring of would_substitute()
diff --git a/src/hb-ot-shape-complex-indic.cc b/src/hb-ot-shape-complex-indic.cc
index 81079bc..8c3e1e0 100644
--- a/src/hb-ot-shape-complex-indic.cc
+++ b/src/hb-ot-shape-complex-indic.cc
@@ -568,7 +568,8 @@ data_destroy_indic (void *data)
static indic_position_t
consonant_position_from_face (const indic_shape_plan_t *indic_plan,
- const hb_codepoint_t glyphs[2],
+ const hb_codepoint_t consonant,
+ const hb_codepoint_t virama,
hb_face_t *face)
{
/* For old-spec, the order of glyphs is Consonant,Virama,
@@ -581,15 +582,15 @@ consonant_position_from_face (const indic_shape_plan_t *indic_plan,
* 930,94D in 'blwf', not the expected 94D,930 (with new-spec
* table). As such, we simply match both sequences. Seems
* to work. */
- hb_codepoint_t glyphs_r[2] = {glyphs[1], glyphs[0]};
+ hb_codepoint_t glyphs[3] = {virama, consonant, virama};
if (indic_plan->blwf.would_substitute (glyphs , 2, face) ||
- indic_plan->blwf.would_substitute (glyphs_r, 2, face))
+ indic_plan->blwf.would_substitute (glyphs+1, 2, face))
return POS_BELOW_C;
if (indic_plan->pstf.would_substitute (glyphs , 2, face) ||
- indic_plan->pstf.would_substitute (glyphs_r, 2, face))
+ indic_plan->pstf.would_substitute (glyphs+1, 2, face))
return POS_POST_C;
if (indic_plan->pref.would_substitute (glyphs , 2, face) ||
- indic_plan->pref.would_substitute (glyphs_r, 2, face))
+ indic_plan->pref.would_substitute (glyphs+1, 2, face))
return POS_POST_C;
return POS_BASE_C;
}
@@ -652,15 +653,15 @@ update_consonant_positions (const hb_ot_shape_plan_t *plan,
if (indic_plan->config->base_pos != BASE_POS_LAST)
return;
- hb_codepoint_t glyphs[2];
- if (indic_plan->get_virama_glyph (font, &glyphs[0]))
+ hb_codepoint_t virama;
+ if (indic_plan->get_virama_glyph (font, &virama))
{
hb_face_t *face = font->face;
unsigned int count = buffer->len;
for (unsigned int i = 0; i < count; i++)
if (buffer->info[i].indic_position() == POS_BASE_C) {
- glyphs[1] = buffer->info[i].codepoint;
- buffer->info[i].indic_position() = consonant_position_from_face (indic_plan, glyphs, face);
+ hb_codepoint_t consonant = buffer->info[i].codepoint;
+ buffer->info[i].indic_position() = consonant_position_from_face (indic_plan, consonant, virama, face);
}
}
}
commit 321df83fb4f0b8a5310888129cb70bfda8ae0c96
Author: Behdad Esfahbod <behdad at behdad.org>
Date: Thu Oct 17 18:16:14 2013 +0200
Route Buginese through the SEA shaper
Both Indic and SEA seem to do it just fine, but SEA is much
simpler.
diff --git a/src/hb-ot-shape-complex-private.hh b/src/hb-ot-shape-complex-private.hh
index a099e05..ac0072b 100644
--- a/src/hb-ot-shape-complex-private.hh
+++ b/src/hb-ot-shape-complex-private.hh
@@ -279,9 +279,6 @@ hb_ot_shape_complex_categorize (const hb_ot_shape_planner_t *planner)
/* Unicode-3.0 additions */
case HB_SCRIPT_SINHALA:
- /* Unicode-4.1 additions */
- case HB_SCRIPT_BUGINESE:
-
/* Unicode-5.0 additions */
case HB_SCRIPT_BALINESE:
@@ -336,6 +333,7 @@ hb_ot_shape_complex_categorize (const hb_ot_shape_planner_t *planner)
return &_hb_ot_complex_shaper_default;
/* Unicode-4.1 additions */
+ case HB_SCRIPT_BUGINESE:
case HB_SCRIPT_NEW_TAI_LUE:
/* Unicode-5.1 additions */
commit b5a0f69e47ace468b06e21cf069a18ddcfcf6064
Author: Behdad Esfahbod <behdad at behdad.org>
Date: Thu Oct 17 18:04:23 2013 +0200
[indic] Pass zero-context=false to would_substitute for newer scripts
For scripts without an old/new spec distinction, use zero-context=false.
This changes behavior in Sinhala / Khmer, but doesn't seem to regress.
This will be useful and used in Javanese.
diff --git a/src/hb-ot-shape-complex-indic.cc b/src/hb-ot-shape-complex-indic.cc
index 42549ed..81079bc 100644
--- a/src/hb-ot-shape-complex-indic.cc
+++ b/src/hb-ot-shape-complex-indic.cc
@@ -468,8 +468,9 @@ override_features_indic (hb_ot_shape_planner_t *plan)
struct would_substitute_feature_t
{
- inline void init (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, bool zero_context_)
{
+ zero_context = zero_context_;
map->get_stage_lookups (0/*GSUB*/,
map->get_feature_stage (0/*GSUB*/, feature_tag),
&lookups, &count);
@@ -477,7 +478,6 @@ struct would_substitute_feature_t
inline bool would_substitute (const hb_codepoint_t *glyphs,
unsigned int glyphs_count,
- bool zero_context,
hb_face_t *face) const
{
for (unsigned int i = 0; i < count; i++)
@@ -489,6 +489,7 @@ struct would_substitute_feature_t
private:
const hb_ot_map_t::lookup_map_t *lookups;
unsigned int count;
+ bool zero_context;
};
struct indic_shape_plan_t
@@ -544,10 +545,13 @@ data_create_indic (const hb_ot_shape_plan_t *plan)
indic_plan->is_old_spec = indic_plan->config->has_old_spec && ((plan->map.chosen_script[0] & 0x000000FF) != '2');
indic_plan->virama_glyph = (hb_codepoint_t) -1;
- indic_plan->rphf.init (&plan->map, HB_TAG('r','p','h','f'));
- 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'));
+ /* Use zero-context would_substitute() matching for new-spec of the main
+ * Indic scripts, but not for old-spec or scripts with one spec only. */
+ bool zero_context = indic_plan->config->has_old_spec || !indic_plan->is_old_spec;
+ indic_plan->rphf.init (&plan->map, HB_TAG('r','p','h','f'), zero_context);
+ indic_plan->pref.init (&plan->map, HB_TAG('p','r','e','f'), zero_context);
+ indic_plan->blwf.init (&plan->map, HB_TAG('b','l','w','f'), zero_context);
+ indic_plan->pstf.init (&plan->map, HB_TAG('p','s','t','f'), zero_context);
for (unsigned int i = 0; i < ARRAY_LENGTH (indic_plan->mask_array); i++)
indic_plan->mask_array[i] = (indic_features[i].flags & F_GLOBAL) ?
@@ -577,16 +581,15 @@ consonant_position_from_face (const indic_shape_plan_t *indic_plan,
* 930,94D in 'blwf', not the expected 94D,930 (with new-spec
* table). As such, we simply match both sequences. Seems
* to work. */
- bool zero_context = indic_plan->is_old_spec ? false : true;
hb_codepoint_t glyphs_r[2] = {glyphs[1], glyphs[0]};
- if (indic_plan->blwf.would_substitute (glyphs , 2, zero_context, face) ||
- indic_plan->blwf.would_substitute (glyphs_r, 2, zero_context, face))
+ if (indic_plan->blwf.would_substitute (glyphs , 2, face) ||
+ indic_plan->blwf.would_substitute (glyphs_r, 2, face))
return POS_BELOW_C;
- if (indic_plan->pstf.would_substitute (glyphs , 2, zero_context, face) ||
- indic_plan->pstf.would_substitute (glyphs_r, 2, zero_context, face))
+ if (indic_plan->pstf.would_substitute (glyphs , 2, face) ||
+ indic_plan->pstf.would_substitute (glyphs_r, 2, face))
return POS_POST_C;
- if (indic_plan->pref.would_substitute (glyphs , 2, zero_context, face) ||
- indic_plan->pref.would_substitute (glyphs_r, 2, zero_context, face))
+ if (indic_plan->pref.would_substitute (glyphs , 2, face) ||
+ indic_plan->pref.would_substitute (glyphs_r, 2, face))
return POS_POST_C;
return POS_BASE_C;
}
@@ -707,7 +710,7 @@ initial_reordering_consonant_syllable (const hb_ot_shape_plan_t *plan,
{
/* See if it matches the 'rphf' feature. */
hb_codepoint_t glyphs[2] = {info[start].codepoint, info[start + 1].codepoint};
- if (indic_plan->rphf.would_substitute (glyphs, ARRAY_LENGTH (glyphs), true, face))
+ if (indic_plan->rphf.would_substitute (glyphs, ARRAY_LENGTH (glyphs), face))
{
limit += 2;
while (limit < end && is_joiner (info[limit]))
@@ -1068,7 +1071,7 @@ initial_reordering_consonant_syllable (const hb_ot_shape_plan_t *plan,
/* Find a Halant,Ra sequence and mark it for pre-base reordering processing. */
for (unsigned int i = base + 1; i + 1 < end; i++) {
hb_codepoint_t glyphs[2] = {info[i].codepoint, info[i + 1].codepoint};
- if (indic_plan->pref.would_substitute (glyphs, ARRAY_LENGTH (glyphs), true, face))
+ if (indic_plan->pref.would_substitute (glyphs, ARRAY_LENGTH (glyphs), face))
{
info[i++].mask |= indic_plan->mask_array[PREF];
info[i++].mask |= indic_plan->mask_array[PREF];
@@ -1734,7 +1737,7 @@ decompose_indic (const hb_ot_shape_normalize_context_t *c,
if (hb_options ().uniscribe_bug_compatible ||
(c->font->get_glyph (ab, 0, &glyph) &&
- indic_plan->pstf.would_substitute (&glyph, 1, true, c->font->face)))
+ indic_plan->pstf.would_substitute (&glyph, 1, c->font->face)))
{
/* Ok, safe to use Uniscribe-style decomposition. */
*a = 0x0DD9;
commit c4e71ff36d1f86a6ea56539728a964d97217e2b6
Author: Behdad Esfahbod <behdad at behdad.org>
Date: Thu Oct 17 17:04:47 2013 +0200
[indic] Clean up Khmer and Sinhala base finding algorithm
diff --git a/src/hb-ot-shape-complex-indic.cc b/src/hb-ot-shape-complex-indic.cc
index b120a61..42549ed 100644
--- a/src/hb-ot-shape-complex-indic.cc
+++ b/src/hb-ot-shape-complex-indic.cc
@@ -128,14 +128,6 @@ static const hb_codepoint_t ra_chars[] = {
0x179A, /* Khmer */ /* No Reph, Visual Repha */
};
-static inline indic_position_t
-consonant_position (hb_codepoint_t u)
-{
- if ((u & ~0x007F) == 0x1780)
- return POS_BELOW_C; /* In Khmer coeng model, post and below forms should not be reordered. */
- return POS_BASE_C; /* Will recategorize later based on font lookups. */
-}
-
static inline bool
is_ra (hb_codepoint_t u)
{
@@ -241,7 +233,7 @@ set_indic_properties (hb_glyph_info_t &info)
if ((FLAG (cat) & CONSONANT_FLAGS))
{
- pos = consonant_position (u);
+ pos = POS_BASE_C;
if (is_ra (u))
cat = OT_Ra;
}
@@ -654,6 +646,9 @@ update_consonant_positions (const hb_ot_shape_plan_t *plan,
{
const indic_shape_plan_t *indic_plan = (const indic_shape_plan_t *) plan->data;
+ if (indic_plan->config->base_pos != BASE_POS_LAST)
+ return;
+
hb_codepoint_t glyphs[2];
if (indic_plan->get_virama_glyph (font, &glyphs[0]))
{
@@ -786,7 +781,10 @@ initial_reordering_consonant_syllable (const hb_ot_shape_plan_t *plan,
case BASE_POS_LAST_SINHALA:
{
- /* In scripts without half forms (eg. Khmer), the first consonant is always the base. */
+ /* Sinhala base positioning is slightly different from main Indic, in that:
+ * 1. It's ZWJ behavior is different,
+ * 2. We don't need to look into the font for consonant positions.
+ */
if (!has_reph)
base = limit;
@@ -794,7 +792,7 @@ initial_reordering_consonant_syllable (const hb_ot_shape_plan_t *plan,
/* 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 (is_consonant (info[i]))
{
if (limit < i && info[i - 1].indic_category() == OT_ZWJ)
break;
@@ -804,7 +802,7 @@ initial_reordering_consonant_syllable (const hb_ot_shape_plan_t *plan,
/* 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)
+ if (is_consonant (info[i]))
info[i].indic_position() = POS_BELOW_C;
}
break;
@@ -819,7 +817,7 @@ initial_reordering_consonant_syllable (const hb_ot_shape_plan_t *plan,
/* 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)
+ if (is_consonant (info[i]))
info[i].indic_position() = POS_BELOW_C;
}
break;
commit e10453e6fb2544724ccd7ddfdbb9de90ef9274ce
Author: Behdad Esfahbod <behdad at behdad.org>
Date: Thu Oct 17 16:49:06 2013 +0200
[indic] Add BASE_POS_LAST_SINHALA
Previously we planted this into the mode used for Khmer. There's not
really much in common between the two, so separate again.
diff --git a/src/hb-ot-shape-complex-indic.cc b/src/hb-ot-shape-complex-indic.cc
index a0ebfef..b120a61 100644
--- a/src/hb-ot-shape-complex-indic.cc
+++ b/src/hb-ot-shape-complex-indic.cc
@@ -277,6 +277,7 @@ set_indic_properties (hb_glyph_info_t &info)
enum base_position_t {
BASE_POS_FIRST,
+ BASE_POS_LAST_SINHALA,
BASE_POS_LAST
};
enum reph_position_t {
@@ -322,7 +323,8 @@ static const indic_config_t indic_configs[] =
{HB_SCRIPT_TELUGU, true, 0x0C4D,BASE_POS_LAST, REPH_POS_AFTER_POST, REPH_MODE_EXPLICIT, BLWF_MODE_POST_ONLY},
{HB_SCRIPT_KANNADA, true, 0x0CCD,BASE_POS_LAST, REPH_POS_AFTER_POST, REPH_MODE_IMPLICIT, BLWF_MODE_POST_ONLY},
{HB_SCRIPT_MALAYALAM, true, 0x0D4D,BASE_POS_LAST, REPH_POS_AFTER_MAIN, REPH_MODE_LOG_REPHA,BLWF_MODE_PRE_AND_POST},
- {HB_SCRIPT_SINHALA, false,0x0DCA,BASE_POS_FIRST,REPH_POS_AFTER_MAIN, REPH_MODE_EXPLICIT, BLWF_MODE_PRE_AND_POST},
+ {HB_SCRIPT_SINHALA, false,0x0DCA,BASE_POS_LAST_SINHALA,
+ REPH_POS_AFTER_MAIN, REPH_MODE_EXPLICIT, BLWF_MODE_PRE_AND_POST},
{HB_SCRIPT_KHMER, false,0x17D2,BASE_POS_FIRST,REPH_POS_DEFAULT, REPH_MODE_VIS_REPHA,BLWF_MODE_PRE_AND_POST},
{HB_SCRIPT_JAVANESE, false,0xA9C0,BASE_POS_LAST, REPH_POS_DEFAULT, REPH_MODE_IMPLICIT, BLWF_MODE_PRE_AND_POST},
};
@@ -782,7 +784,7 @@ initial_reordering_consonant_syllable (const hb_ot_shape_plan_t *plan,
}
break;
- case BASE_POS_FIRST:
+ case BASE_POS_LAST_SINHALA:
{
/* In scripts without half forms (eg. Khmer), the first consonant is always the base. */
@@ -806,6 +808,21 @@ initial_reordering_consonant_syllable (const hb_ot_shape_plan_t *plan,
info[i].indic_position() = POS_BELOW_C;
}
break;
+
+ case BASE_POS_FIRST:
+ {
+ /* The first consonant is always the base. */
+
+ assert (indic_plan->config->reph_mode == REPH_MODE_VIS_REPHA);
+
+ base = start;
+
+ /* 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;
}
/* -> If the syllable starts with Ra + Halant (in a script that has Reph)
commit 9ac6b01e0cd8e2d66dfc727157f45b615bc77109
Author: Behdad Esfahbod <behdad at behdad.org>
Date: Thu Oct 17 16:27:38 2013 +0200
[indic] Adjust Sinhala cluster merging under uniscribe
Similar to 190c8f2b60af0851bf692f653c1604cfbf0561a5 but for
Sinhala.
diff --git a/src/hb-ot-shape-complex-indic.cc b/src/hb-ot-shape-complex-indic.cc
index 3471aa6..a0ebfef 100644
--- a/src/hb-ot-shape-complex-indic.cc
+++ b/src/hb-ot-shape-complex-indic.cc
@@ -463,7 +463,7 @@ override_features_indic (hb_ot_shape_planner_t *plan)
switch ((hb_tag_t) plan->props.script)
{
case HB_SCRIPT_KHMER:
- plan->map.add_feature (HB_TAG('k','e','r','n'), 0, F_GLOBAL);
+ plan->map.add_feature (HB_TAG('k','e','r','n'), 0, F_GLOBAL);
break;
}
}
@@ -1584,13 +1584,22 @@ final_reordering_syllable (const hb_ot_shape_plan_t *plan,
/*
* Finish off the clusters and go home!
*/
- if (hb_options ().uniscribe_bug_compatible && buffer->props.script != HB_SCRIPT_TAMIL)
+ if (hb_options ().uniscribe_bug_compatible)
{
- /* Uniscribe merges the entire cluster... Except for Tamil.
- * This means, half forms are submerged into the main consonants cluster.
- * This is unnecessary, and makes cursor positioning harder, but that's what
- * Uniscribe does. */
- buffer->merge_clusters (start, end);
+ switch ((hb_tag_t) plan->props.script)
+ {
+ case HB_SCRIPT_TAMIL:
+ case HB_SCRIPT_SINHALA:
+ break;
+
+ default:
+ /* Uniscribe merges the entire cluster... Except for Tamil & Sinhala.
+ * This means, half forms are submerged into the main consonants cluster.
+ * This is unnecessary, and makes cursor positioning harder, but that's what
+ * Uniscribe does. */
+ buffer->merge_clusters (start, end);
+ break;
+ }
}
}
commit 3c3df9cba13fec2c35e0e7ae587d9699ac0c37f5
Author: Behdad Esfahbod <behdad at behdad.org>
Date: Thu Oct 17 13:58:31 2013 +0200
[otlayout] Minor
diff --git a/src/hb-ot-layout-gsubgpos-private.hh b/src/hb-ot-layout-gsubgpos-private.hh
index 2ba9978..f156b98 100644
--- a/src/hb-ot-layout-gsubgpos-private.hh
+++ b/src/hb-ot-layout-gsubgpos-private.hh
@@ -761,7 +761,9 @@ static inline bool match_input (hb_apply_context_t *c,
if (unlikely (count > MAX_CONTEXT_LENGTH)) TRACE_RETURN (false);
- hb_apply_context_t::skipping_forward_iterator_t skippy_iter (c, c->buffer->idx, count - 1);
+ hb_buffer_t *buffer = c->buffer;
+
+ hb_apply_context_t::skipping_forward_iterator_t skippy_iter (c, buffer->idx, count - 1);
skippy_iter.set_match_func (match_func, match_data, input);
if (skippy_iter.has_no_chance ()) return TRACE_RETURN (false);
@@ -783,23 +785,23 @@ static inline bool match_input (hb_apply_context_t *c,
* ligate with a conjunct...)
*/
- bool is_mark_ligature = !!(c->buffer->cur().glyph_props() & HB_OT_LAYOUT_GLYPH_PROPS_MARK);
+ bool is_mark_ligature = !!(buffer->cur().glyph_props() & HB_OT_LAYOUT_GLYPH_PROPS_MARK);
unsigned int total_component_count = 0;
- total_component_count += get_lig_num_comps (c->buffer->cur());
+ total_component_count += get_lig_num_comps (buffer->cur());
- unsigned int first_lig_id = get_lig_id (c->buffer->cur());
- unsigned int first_lig_comp = get_lig_comp (c->buffer->cur());
+ unsigned int first_lig_id = get_lig_id (buffer->cur());
+ unsigned int first_lig_comp = get_lig_comp (buffer->cur());
- match_positions[0] = c->buffer->idx;
+ match_positions[0] = buffer->idx;
for (unsigned int i = 1; i < count; i++)
{
if (!skippy_iter.next ()) return TRACE_RETURN (false);
match_positions[i] = skippy_iter.idx;
- unsigned int this_lig_id = get_lig_id (c->buffer->info[skippy_iter.idx]);
- unsigned int this_lig_comp = get_lig_comp (c->buffer->info[skippy_iter.idx]);
+ unsigned int this_lig_id = get_lig_id (buffer->info[skippy_iter.idx]);
+ unsigned int this_lig_comp = get_lig_comp (buffer->info[skippy_iter.idx]);
if (first_lig_id && first_lig_comp) {
/* If first component was attached to a previous ligature component,
@@ -815,11 +817,11 @@ static inline bool match_input (hb_apply_context_t *c,
return TRACE_RETURN (false);
}
- is_mark_ligature = is_mark_ligature && (c->buffer->info[skippy_iter.idx].glyph_props() & HB_OT_LAYOUT_GLYPH_PROPS_MARK);
- total_component_count += get_lig_num_comps (c->buffer->info[skippy_iter.idx]);
+ is_mark_ligature = is_mark_ligature && (buffer->info[skippy_iter.idx].glyph_props() & HB_OT_LAYOUT_GLYPH_PROPS_MARK);
+ total_component_count += get_lig_num_comps (buffer->info[skippy_iter.idx]);
}
- *end_offset = skippy_iter.idx - c->buffer->idx + 1;
+ *end_offset = skippy_iter.idx - buffer->idx + 1;
if (p_is_mark_ligature)
*p_is_mark_ligature = is_mark_ligature;
@@ -839,7 +841,9 @@ static inline void ligate_input (hb_apply_context_t *c,
{
TRACE_APPLY (NULL);
- c->buffer->merge_clusters (c->buffer->idx, c->buffer->idx + match_length);
+ hb_buffer_t *buffer = c->buffer;
+
+ buffer->merge_clusters (buffer->idx, buffer->idx + match_length);
/*
* - If it *is* a mark ligature, we don't allocate a new ligature id, and leave
@@ -870,46 +874,46 @@ static inline void ligate_input (hb_apply_context_t *c,
*/
unsigned int klass = is_mark_ligature ? 0 : HB_OT_LAYOUT_GLYPH_PROPS_LIGATURE;
- unsigned int lig_id = is_mark_ligature ? 0 : allocate_lig_id (c->buffer);
- unsigned int last_lig_id = get_lig_id (c->buffer->cur());
- unsigned int last_num_components = get_lig_num_comps (c->buffer->cur());
+ unsigned int lig_id = is_mark_ligature ? 0 : allocate_lig_id (buffer);
+ unsigned int last_lig_id = get_lig_id (buffer->cur());
+ unsigned int last_num_components = get_lig_num_comps (buffer->cur());
unsigned int components_so_far = last_num_components;
if (!is_mark_ligature)
{
- set_lig_props_for_ligature (c->buffer->cur(), lig_id, total_component_count);
- if (_hb_glyph_info_get_general_category (&c->buffer->cur()) == HB_UNICODE_GENERAL_CATEGORY_NON_SPACING_MARK)
- _hb_glyph_info_set_general_category (&c->buffer->cur(), HB_UNICODE_GENERAL_CATEGORY_OTHER_LETTER);
+ set_lig_props_for_ligature (buffer->cur(), lig_id, total_component_count);
+ if (_hb_glyph_info_get_general_category (&buffer->cur()) == HB_UNICODE_GENERAL_CATEGORY_NON_SPACING_MARK)
+ _hb_glyph_info_set_general_category (&buffer->cur(), HB_UNICODE_GENERAL_CATEGORY_OTHER_LETTER);
}
c->replace_glyph (lig_glyph, klass);
for (unsigned int i = 1; i < count; i++)
{
- while (c->buffer->idx < match_positions[i])
+ while (buffer->idx < match_positions[i])
{
if (!is_mark_ligature) {
unsigned int new_lig_comp = components_so_far - last_num_components +
- MIN (MAX (get_lig_comp (c->buffer->cur()), 1u), last_num_components);
- set_lig_props_for_mark (c->buffer->cur(), lig_id, new_lig_comp);
+ MIN (MAX (get_lig_comp (buffer->cur()), 1u), last_num_components);
+ set_lig_props_for_mark (buffer->cur(), lig_id, new_lig_comp);
}
- c->buffer->next_glyph ();
+ buffer->next_glyph ();
}
- last_lig_id = get_lig_id (c->buffer->cur());
- last_num_components = get_lig_num_comps (c->buffer->cur());
+ last_lig_id = get_lig_id (buffer->cur());
+ last_num_components = get_lig_num_comps (buffer->cur());
components_so_far += last_num_components;
/* Skip the base glyph */
- c->buffer->idx++;
+ buffer->idx++;
}
if (!is_mark_ligature && last_lig_id) {
/* Re-adjust components for any marks following. */
- for (unsigned int i = c->buffer->idx; i < c->buffer->len; i++) {
- if (last_lig_id == get_lig_id (c->buffer->info[i])) {
+ for (unsigned int i = buffer->idx; i < buffer->len; i++) {
+ if (last_lig_id == get_lig_id (buffer->info[i])) {
unsigned int new_lig_comp = components_so_far - last_num_components +
- MIN (MAX (get_lig_comp (c->buffer->info[i]), 1u), last_num_components);
- set_lig_props_for_mark (c->buffer->info[i], lig_id, new_lig_comp);
+ MIN (MAX (get_lig_comp (buffer->info[i]), 1u), last_num_components);
+ set_lig_props_for_mark (buffer->info[i], lig_id, new_lig_comp);
} else
break;
}
commit 6cc136f7531a45e71ea08a7dc8a2187172cb813d
Author: Behdad Esfahbod <behdad at behdad.org>
Date: Thu Oct 17 13:55:48 2013 +0200
[otlayout] Minor
diff --git a/src/hb-ot-layout-gsubgpos-private.hh b/src/hb-ot-layout-gsubgpos-private.hh
index bc7616b..2ba9978 100644
--- a/src/hb-ot-layout-gsubgpos-private.hh
+++ b/src/hb-ot-layout-gsubgpos-private.hh
@@ -752,8 +752,8 @@ static inline bool match_input (hb_apply_context_t *c,
const USHORT input[], /* Array of input values--start with second glyph */
match_func_t match_func,
const void *match_data,
- unsigned int *end_offset = NULL,
- unsigned int match_positions[MAX_CONTEXT_LENGTH] = NULL,
+ unsigned int *end_offset,
+ unsigned int match_positions[MAX_CONTEXT_LENGTH],
bool *p_is_mark_ligature = NULL,
unsigned int *p_total_component_count = NULL)
{
@@ -791,13 +791,12 @@ static inline bool match_input (hb_apply_context_t *c,
unsigned int first_lig_id = get_lig_id (c->buffer->cur());
unsigned int first_lig_comp = get_lig_comp (c->buffer->cur());
- if (match_positions)
- match_positions[0] = c->buffer->idx;
+ match_positions[0] = c->buffer->idx;
for (unsigned int i = 1; i < count; i++)
{
if (!skippy_iter.next ()) return TRACE_RETURN (false);
- if (match_positions)
- match_positions[i] = skippy_iter.idx;
+
+ match_positions[i] = skippy_iter.idx;
unsigned int this_lig_id = get_lig_id (c->buffer->info[skippy_iter.idx]);
unsigned int this_lig_comp = get_lig_comp (c->buffer->info[skippy_iter.idx]);
@@ -820,8 +819,7 @@ static inline bool match_input (hb_apply_context_t *c,
total_component_count += get_lig_num_comps (c->buffer->info[skippy_iter.idx]);
}
- if (end_offset)
- *end_offset = skippy_iter.idx - c->buffer->idx + 1;
+ *end_offset = skippy_iter.idx - c->buffer->idx + 1;
if (p_is_mark_ligature)
*p_is_mark_ligature = is_mark_ligature;
commit ba6ddc421e5e440231c2ece2db1363f8e6d2ecbf
Author: Behdad Esfahbod <behdad at behdad.org>
Date: Thu Oct 17 13:52:51 2013 +0200
[otlayout] Increase MAX_CONTEXT_LENGTH
It's cheap.
diff --git a/src/hb-ot-layout-common-private.hh b/src/hb-ot-layout-common-private.hh
index 8ef8424..1e75930 100644
--- a/src/hb-ot-layout-common-private.hh
+++ b/src/hb-ot-layout-common-private.hh
@@ -39,7 +39,7 @@ namespace OT {
#define NOT_COVERED ((unsigned int) -1)
#define MAX_NESTING_LEVEL 8
-#define MAX_CONTEXT_LENGTH 32
+#define MAX_CONTEXT_LENGTH 64
commit e714fe6d6a2633494cb1fa7170a32ca2638cbb51
Author: Behdad Esfahbod <behdad at behdad.org>
Date: Thu Oct 17 13:49:51 2013 +0200
[otlayout] Simplify ligate_input()
Shouldn't change behavior at all, but is faster / more robust.
diff --git a/src/hb-ot-layout-gsub-table.hh b/src/hb-ot-layout-gsub-table.hh
index 1588580..a595a4b 100644
--- a/src/hb-ot-layout-gsub-table.hh
+++ b/src/hb-ot-layout-gsub-table.hh
@@ -663,28 +663,26 @@ struct Ligature
unsigned int count = component.len;
if (unlikely (count < 1)) return TRACE_RETURN (false);
- unsigned int end_offset = 0;
bool is_mark_ligature = false;
unsigned int total_component_count = 0;
+ unsigned int match_length = 0;
+ unsigned int match_positions[MAX_CONTEXT_LENGTH];
+
if (likely (!match_input (c, count,
&component[1],
match_glyph,
NULL,
- &end_offset,
- NULL,
+ &match_length,
+ match_positions,
&is_mark_ligature,
&total_component_count)))
return TRACE_RETURN (false);
- /* Deal, we are forming the ligature. */
- c->buffer->merge_clusters (c->buffer->idx, c->buffer->idx + end_offset);
-
ligate_input (c,
count,
- &component[1],
- match_glyph,
- NULL,
+ match_positions,
+ match_length,
ligGlyph,
is_mark_ligature,
total_component_count);
diff --git a/src/hb-ot-layout-gsubgpos-private.hh b/src/hb-ot-layout-gsubgpos-private.hh
index fde6eae..bc7616b 100644
--- a/src/hb-ot-layout-gsubgpos-private.hh
+++ b/src/hb-ot-layout-gsubgpos-private.hh
@@ -832,17 +832,16 @@ static inline bool match_input (hb_apply_context_t *c,
return TRACE_RETURN (true);
}
static inline void ligate_input (hb_apply_context_t *c,
- unsigned int count, /* Including the first glyph (not matched) */
- const USHORT input[], /* Array of input values--start with second glyph */
- match_func_t match_func,
- const void *match_data,
+ unsigned int count, /* Including the first glyph */
+ unsigned int match_positions[MAX_CONTEXT_LENGTH], /* Including the first glyph */
+ unsigned int match_length,
hb_codepoint_t lig_glyph,
bool is_mark_ligature,
unsigned int total_component_count)
{
- hb_apply_context_t::skipping_forward_iterator_t skippy_iter (c, c->buffer->idx, count - 1);
- skippy_iter.set_match_func (match_func, match_data, input);
- if (skippy_iter.has_no_chance ()) return;
+ TRACE_APPLY (NULL);
+
+ c->buffer->merge_clusters (c->buffer->idx, c->buffer->idx + match_length);
/*
* - If it *is* a mark ligature, we don't allocate a new ligature id, and leave
@@ -888,9 +887,7 @@ static inline void ligate_input (hb_apply_context_t *c,
for (unsigned int i = 1; i < count; i++)
{
- if (!skippy_iter.next ()) return;
-
- while (c->buffer->idx < skippy_iter.idx)
+ while (c->buffer->idx < match_positions[i])
{
if (!is_mark_ligature) {
unsigned int new_lig_comp = components_so_far - last_num_components +
commit 6b2abdcd203204131f3017ca85c91de9d43959cd
Author: Behdad Esfahbod <behdad at behdad.org>
Date: Thu Oct 17 13:15:43 2013 +0200
[indic] Improve clusters in presence of reph
diff --git a/src/hb-ot-shape-complex-indic.cc b/src/hb-ot-shape-complex-indic.cc
index 943d1f6..3471aa6 100644
--- a/src/hb-ot-shape-complex-indic.cc
+++ b/src/hb-ot-shape-complex-indic.cc
@@ -1375,7 +1375,6 @@ final_reordering_syllable (const hb_ot_shape_plan_t *plan,
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.
@@ -1417,7 +1416,6 @@ final_reordering_syllable (const hb_ot_shape_plan_t *plan,
if (reph_pos == REPH_POS_AFTER_MAIN)
{
new_reph_pos = base;
- /* XXX Skip potential pre-base reordering Ra. */
while (new_reph_pos + 1 < end && info[new_reph_pos + 1].indic_position() <= POS_AFTER_MAIN)
new_reph_pos++;
if (new_reph_pos < end)
@@ -1490,8 +1488,7 @@ final_reordering_syllable (const hb_ot_shape_plan_t *plan,
reph_move:
{
- /* Yay, one big cluster! Merge before moving. */
- buffer->merge_clusters (start, end);
+ buffer->merge_clusters (start, new_reph_pos + 1);
/* Move */
hb_glyph_info_t reph = info[start];
commit 42d0f55cbc68285e22d713df7062e520af708c82
Author: Behdad Esfahbod <behdad at behdad.org>
Date: Thu Oct 17 13:05:05 2013 +0200
[indic] Apply calt,clig in the same stage as presentation features
Whic means these twp are applied per-syllable now. Apparently
in some Khmer fonts the clig interacts with presentation features.
Test case: U+1781,U+17D2,U+1789,U+17BB,U+17C6 with Mondulkiri-R.ttf
should produce one big ligature.
diff --git a/src/hb-ot-shape-complex-indic.cc b/src/hb-ot-shape-complex-indic.cc
index 75d4cad..943d1f6 100644
--- a/src/hb-ot-shape-complex-indic.cc
+++ b/src/hb-ot-shape-complex-indic.cc
@@ -447,6 +447,10 @@ collect_features_indic (hb_ot_shape_planner_t *plan)
for (; i < INDIC_NUM_FEATURES; i++) {
map->add_feature (indic_features[i].tag, 1, indic_features[i].flags | F_MANUAL_ZWJ);
}
+
+ map->add_global_bool_feature (HB_TAG('c','a','l','t'));
+ map->add_global_bool_feature (HB_TAG('c','l','i','g'));
+
map->add_gsub_pause (clear_syllables);
}
commit ae9a5834df477006686421d494b55a1569789327
Author: Behdad Esfahbod <behdad at behdad.org>
Date: Thu Oct 17 12:24:55 2013 +0200
[indic] Fix pref vs blwf interaction
If a glyph can be both blwf and pref, we were wrongly sorting it
in the post position instead of below position.
diff --git a/src/hb-ot-shape-complex-indic.cc b/src/hb-ot-shape-complex-indic.cc
index 07f231b..75d4cad 100644
--- a/src/hb-ot-shape-complex-indic.cc
+++ b/src/hb-ot-shape-complex-indic.cc
@@ -581,15 +581,15 @@ consonant_position_from_face (const indic_shape_plan_t *indic_plan,
* to work. */
bool zero_context = indic_plan->is_old_spec ? false : true;
hb_codepoint_t glyphs_r[2] = {glyphs[1], glyphs[0]};
- if (indic_plan->pref.would_substitute (glyphs , 2, zero_context, face) ||
- indic_plan->pref.would_substitute (glyphs_r, 2, zero_context, face))
- return POS_POST_C;
if (indic_plan->blwf.would_substitute (glyphs , 2, zero_context, face) ||
indic_plan->blwf.would_substitute (glyphs_r, 2, zero_context, face))
return POS_BELOW_C;
if (indic_plan->pstf.would_substitute (glyphs , 2, zero_context, face) ||
indic_plan->pstf.would_substitute (glyphs_r, 2, zero_context, face))
return POS_POST_C;
+ if (indic_plan->pref.would_substitute (glyphs , 2, zero_context, face) ||
+ indic_plan->pref.would_substitute (glyphs_r, 2, zero_context, face))
+ return POS_POST_C;
return POS_BASE_C;
}
commit c7dacac02cfe8526eaf131ce6c5e7b6df7ca2ccd
Author: Behdad Esfahbod <behdad at behdad.org>
Date: Thu Oct 17 12:20:24 2013 +0200
[indic] Don't apply blwf before base under old-spec mode
Test case: U+09AC,U+09CD,U+09A6 with Lohit-Bengali 2.5.3.
diff --git a/src/hb-ot-shape-complex-indic.cc b/src/hb-ot-shape-complex-indic.cc
index a98c540..07f231b 100644
--- a/src/hb-ot-shape-complex-indic.cc
+++ b/src/hb-ot-shape-complex-indic.cc
@@ -997,7 +997,8 @@ initial_reordering_consonant_syllable (const hb_ot_shape_plan_t *plan,
/* Pre-base */
mask = indic_plan->mask_array[HALF];
- if (indic_plan->config->blwf_mode == BLWF_MODE_PRE_AND_POST)
+ if (!indic_plan->is_old_spec &&
+ indic_plan->config->blwf_mode == BLWF_MODE_PRE_AND_POST)
mask |= indic_plan->mask_array[BLWF];
for (unsigned int i = start; i < base; i++)
info[i].mask |= mask;
More information about the HarfBuzz
mailing list