summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLars Knoll <lars.knoll@nokia.com>2010-04-14 17:01:49 +0200
committerLars Knoll <lars.knoll@nokia.com>2010-04-14 17:01:49 +0200
commitc638ddc70f6a8196f2c8b11808ab01510233a0ee (patch)
tree226b50b9eab3283288b1c5f8562809e155ddeaba
parent33b9cde6a08293d26047734e046c6677a2959adb (diff)
Fix a bug in malayalam shaping
See http://bugreports.qt.nokia.com/browse/QTBUG-1887. We were not finding the base character correctly in the case where the syllable contained a ZWJ. In addition, the indic OT specs require us to also apply the 'loca', 'cjct' and 'calt' features. They seem to be mostly unused by todays fonts, but we should better apply them anyways.
-rw-r--r--src/harfbuzz-indic.cpp23
-rw-r--r--src/harfbuzz-shaper-private.h55
-rw-r--r--tests/shaping/main.cpp2
3 files changed, 52 insertions, 28 deletions
diff --git a/src/harfbuzz-indic.cpp b/src/harfbuzz-indic.cpp
index 3c9df93..4d8418b 100644
--- a/src/harfbuzz-indic.cpp
+++ b/src/harfbuzz-indic.cpp
@@ -1107,6 +1107,7 @@ static inline void splitMatra(unsigned short *reordered, int matra, int &len)
#ifndef NO_OPENTYPE
static const HB_OpenTypeFeature indic_features[] = {
+ { HB_MAKE_TAG('l', 'o', 'c', 'a'), LocaProperty },
{ HB_MAKE_TAG('c', 'c', 'm', 'p'), CcmpProperty },
{ HB_MAKE_TAG('i', 'n', 'i', 't'), InitProperty },
{ HB_MAKE_TAG('n', 'u', 'k', 't'), NuktaProperty },
@@ -1115,12 +1116,14 @@ static const HB_OpenTypeFeature indic_features[] = {
{ HB_MAKE_TAG('b', 'l', 'w', 'f'), BelowFormProperty },
{ HB_MAKE_TAG('h', 'a', 'l', 'f'), HalfFormProperty },
{ HB_MAKE_TAG('p', 's', 't', 'f'), PostFormProperty },
+ { HB_MAKE_TAG('c', 'j', 'c', 't'), ConjunctFormProperty },
{ HB_MAKE_TAG('v', 'a', 't', 'u'), VattuProperty },
{ HB_MAKE_TAG('p', 'r', 'e', 's'), PreSubstProperty },
{ HB_MAKE_TAG('b', 'l', 'w', 's'), BelowSubstProperty },
{ HB_MAKE_TAG('a', 'b', 'v', 's'), AboveSubstProperty },
{ HB_MAKE_TAG('p', 's', 't', 's'), PostSubstProperty },
{ HB_MAKE_TAG('h', 'a', 'l', 'n'), HalantProperty },
+ { HB_MAKE_TAG('c', 'a', 'l', 't'), IndicCaltProperty },
{ 0, 0 }
};
#endif
@@ -1148,6 +1151,8 @@ static QString propertiesToString(int properties)
{
QString res;
properties = ~properties;
+ if (properties & LocaProperty)
+ res += "Loca ";
if (properties & CcmpProperty)
res += "Ccmp ";
if (properties & InitProperty)
@@ -1168,6 +1173,8 @@ static QString propertiesToString(int properties)
res += "HalfForm ";
if (properties & PostFormProperty)
res += "PostForm ";
+ if (properties & ConjunctFormProperty)
+ res += "PostForm ";
if (properties & VattuProperty)
res += "Vattu ";
if (properties & PreSubstProperty)
@@ -1182,6 +1189,8 @@ static QString propertiesToString(int properties)
res += "Halant ";
if (properties & CligProperty)
res += "Clig ";
+ if (properties & IndicCaltProperty)
+ res += "Calt ";
return res;
}
#endif
@@ -1296,10 +1305,15 @@ static bool indic_shape_syllable(HB_Bool openType, HB_ShaperItem *item, bool inv
}
int skipped = 0;
Position pos = Post;
- for (i = len-1; i > base; i--) {
+ for (i = len-1; i >= base; i--) {
if (position[i] != Consonant && (position[i] != Control || script == HB_Script_Kannada))
continue;
+ if (i < len-1 && position[i] == Control && position[i+1] == Consonant) {
+ base = i+1;
+ break;
+ }
+
Position charPosition = indic_position(uc[i]);
if (pos == Post && charPosition == Post) {
pos = Post;
@@ -1545,16 +1559,20 @@ static bool indic_shape_syllable(HB_Bool openType, HB_ShaperItem *item, bool inv
// features we should always apply
for (i = 0; i < len; ++i)
- properties[i] = ~(CcmpProperty
+ properties[i] = ~(LocaProperty
+ | CcmpProperty
| NuktaProperty
| VattuProperty
+ | ConjunctFormProperty
| PreSubstProperty
| BelowSubstProperty
| AboveSubstProperty
| PostSubstProperty
| HalantProperty
+ | IndicCaltProperty
| PositioningProperties);
+ // Loca always applies
// Ccmp always applies
// Init
if (item->item.pos == 0
@@ -1611,6 +1629,7 @@ static bool indic_shape_syllable(HB_Bool openType, HB_ShaperItem *item, bool inv
// abvs always applies
// psts always applies
// halant always applies
+ // calt always applies
#ifdef INDIC_DEBUG
// {
diff --git a/src/harfbuzz-shaper-private.h b/src/harfbuzz-shaper-private.h
index 11ed753..e1360c7 100644
--- a/src/harfbuzz-shaper-private.h
+++ b/src/harfbuzz-shaper-private.h
@@ -57,34 +57,37 @@ typedef enum
} HB_CombiningClass;
typedef enum {
- CcmpProperty = 0x1,
- InitProperty = 0x2,
- IsolProperty = 0x4,
- FinaProperty = 0x8,
- MediProperty = 0x10,
- RligProperty = 0x20,
- CaltProperty = 0x40,
- LigaProperty = 0x80,
- DligProperty = 0x100,
- CswhProperty = 0x200,
- MsetProperty = 0x400,
+ LocaProperty = 0x1,
+ CcmpProperty = 0x2,
+ InitProperty = 0x4,
+ IsolProperty = 0x8,
+ FinaProperty = 0x10,
+ MediProperty = 0x20,
+ RligProperty = 0x40,
+ CaltProperty = 0x80,
+ LigaProperty = 0x100,
+ DligProperty = 0x200,
+ CswhProperty = 0x400,
+ MsetProperty = 0x800,
/* used by indic and myanmar shaper */
- NuktaProperty = 0x4,
- AkhantProperty = 0x8,
- RephProperty = 0x10,
- PreFormProperty = 0x20,
- BelowFormProperty = 0x40,
- AboveFormProperty = 0x80,
- HalfFormProperty = 0x100,
- PostFormProperty = 0x200,
- VattuProperty = 0x400,
- PreSubstProperty = 0x800,
- BelowSubstProperty = 0x1000,
- AboveSubstProperty = 0x2000,
- PostSubstProperty = 0x4000,
- HalantProperty = 0x8000,
- CligProperty = 0x10000
+ NuktaProperty = 0x8,
+ AkhantProperty = 0x10,
+ RephProperty = 0x20,
+ PreFormProperty = 0x40,
+ BelowFormProperty = 0x80,
+ AboveFormProperty = 0x100,
+ HalfFormProperty = 0x200,
+ PostFormProperty = 0x400,
+ ConjunctFormProperty = 0x800,
+ VattuProperty = 0x1000,
+ PreSubstProperty = 0x2000,
+ BelowSubstProperty = 0x4000,
+ AboveSubstProperty = 0x8000,
+ PostSubstProperty = 0x10000,
+ HalantProperty = 0x20000,
+ CligProperty = 0x40000,
+ IndicCaltProperty = 0x80000
} HB_OpenTypeProperty;
diff --git a/tests/shaping/main.cpp b/tests/shaping/main.cpp
index 320e8ee..28f8e07 100644
--- a/tests/shaping/main.cpp
+++ b/tests/shaping/main.cpp
@@ -1130,6 +1130,8 @@ void tst_QScriptEngine::malayalam()
{ 0x3f8, 0x0 } },
{ { 0xd2f, 0xd4d, 0xd15, 0xd4d, 0xd15, 0xd41, 0x0 },
{ 0x2ff, 0x0 } },
+ { { 0xd30, 0xd4d, 0x200d, 0xd35, 0xd4d, 0xd35, 0x0 },
+ { 0xf3, 0x350, 0x0 } },
{ {0}, {0} }
};