summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLars Knoll <lars.knoll@nokia.com>2009-11-04 14:34:29 (GMT)
committerLars Knoll <lars.knoll@nokia.com>2009-11-04 14:36:53 (GMT)
commit106148704ee1e73c7b71c4a1a2dcb64a1ac52727 (patch)
treedb282a194362c6254ed93fb3149a5efa022cede8
parentd14cf629997e6cfc454af257f6f0df8ce5224363 (diff)
downloadQt-106148704ee1e73c7b71c4a1a2dcb64a1ac52727.zip
Qt-106148704ee1e73c7b71c4a1a2dcb64a1ac52727.tar.gz
Qt-106148704ee1e73c7b71c4a1a2dcb64a1ac52727.tar.bz2
update harfbuzz to the latest version from fd.org
This corresponds to commit e8a057fb67a0242e5a125d8cb2c823ad63e01449 in harfbuzz. The changes include fixes for an out of bounds read and QTBUG-5293. Task-Number: QTBUG-5293 Reviewed-by: Eskil
-rw-r--r--src/3rdparty/harfbuzz/src/harfbuzz-arabic.c2
-rw-r--r--src/3rdparty/harfbuzz/src/harfbuzz-gpos.c6
-rw-r--r--src/3rdparty/harfbuzz/src/harfbuzz-hebrew.c3
-rw-r--r--src/3rdparty/harfbuzz/src/harfbuzz-indic.cpp117
-rw-r--r--src/3rdparty/harfbuzz/src/harfbuzz-open.c2
-rw-r--r--src/3rdparty/harfbuzz/src/harfbuzz-shape.h2
-rw-r--r--src/3rdparty/harfbuzz/src/harfbuzz-shaper.h41
-rw-r--r--src/3rdparty/harfbuzz/tests/shaping/main.cpp76
8 files changed, 167 insertions, 82 deletions
diff --git a/src/3rdparty/harfbuzz/src/harfbuzz-arabic.c b/src/3rdparty/harfbuzz/src/harfbuzz-arabic.c
index 0609232..4d85c19 100644
--- a/src/3rdparty/harfbuzz/src/harfbuzz-arabic.c
+++ b/src/3rdparty/harfbuzz/src/harfbuzz-arabic.c
@@ -1009,7 +1009,7 @@ static HB_Bool arabicSyriacOpenTypeShape(HB_ShaperItem *item, HB_Bool *ot_ok)
++l;
++properties;
}
- if (f + l < item->stringLength) {
+ if (f + l + item->item.pos < item->stringLength) {
++l;
}
getArabicProperties(uc+f, l, props);
diff --git a/src/3rdparty/harfbuzz/src/harfbuzz-gpos.c b/src/3rdparty/harfbuzz/src/harfbuzz-gpos.c
index c932ec2..356dc01 100644
--- a/src/3rdparty/harfbuzz/src/harfbuzz-gpos.c
+++ b/src/3rdparty/harfbuzz/src/harfbuzz-gpos.c
@@ -2059,15 +2059,17 @@ static void Free_BaseArray( HB_BaseArray* ba,
HB_BaseRecord *br;
HB_Anchor *bans;
- HB_UNUSED(num_classes);
-
if ( ba->BaseRecord )
{
br = ba->BaseRecord;
if ( ba->BaseCount )
{
+ HB_UShort i, count;
+ count = num_classes * ba->BaseCount;
bans = br[0].BaseAnchor;
+ for (i = 0; i < count; i++)
+ Free_Anchor (&bans[i]);
FREE( bans );
}
diff --git a/src/3rdparty/harfbuzz/src/harfbuzz-hebrew.c b/src/3rdparty/harfbuzz/src/harfbuzz-hebrew.c
index 533a063..2bda386 100644
--- a/src/3rdparty/harfbuzz/src/harfbuzz-hebrew.c
+++ b/src/3rdparty/harfbuzz/src/harfbuzz-hebrew.c
@@ -56,6 +56,8 @@ HB_Bool HB_HebrewShape(HB_ShaperItem *shaper_item)
assert(shaper_item->item.script == HB_Script_Hebrew);
+ HB_HeuristicSetGlyphAttributes(shaper_item);
+
#ifndef NO_OPENTYPE
if (HB_SelectScript(shaper_item, hebrew_features)) {
@@ -64,7 +66,6 @@ HB_Bool HB_HebrewShape(HB_ShaperItem *shaper_item)
return FALSE;
- HB_HeuristicSetGlyphAttributes(shaper_item);
HB_OpenTypeShape(shaper_item, /*properties*/0);
return HB_OpenTypePosition(shaper_item, availableGlyphs, /*doLogClusters*/TRUE);
}
diff --git a/src/3rdparty/harfbuzz/src/harfbuzz-indic.cpp b/src/3rdparty/harfbuzz/src/harfbuzz-indic.cpp
index 7104d2a..48f4f90 100644
--- a/src/3rdparty/harfbuzz/src/harfbuzz-indic.cpp
+++ b/src/3rdparty/harfbuzz/src/harfbuzz-indic.cpp
@@ -419,7 +419,7 @@ static const unsigned char indicForms[0xe00-0x900] = {
Matra, Halant, Invalid, Invalid,
Invalid, Invalid, Invalid, Invalid,
- Invalid, Invalid, Invalid, LengthMark,
+ Invalid, Invalid, Invalid, Matra,
Invalid, Invalid, Invalid, Invalid,
Invalid, Invalid, Invalid, Invalid,
@@ -1050,62 +1050,59 @@ static const IndicOrdering * const indic_order[] = {
// vowel matras that have to be split into two parts.
static const unsigned short split_matras[] = {
- // matra, split1, split2
+ // matra, split1, split2, split3
// bengalis
- 0x9cb, 0x9c7, 0x9be,
- 0x9cc, 0x9c7, 0x9d7,
+ 0x9cb, 0x9c7, 0x9be, 0x0,
+ 0x9cc, 0x9c7, 0x9d7, 0x0,
// oriya
- 0xb48, 0xb47, 0xb56,
- 0xb4b, 0xb47, 0xb3e,
- 0xb4c, 0xb47, 0xb57,
+ 0xb48, 0xb47, 0xb56, 0x0,
+ 0xb4b, 0xb47, 0xb3e, 0x0,
+ 0xb4c, 0xb47, 0xb57, 0x0,
// tamil
- 0xbca, 0xbc6, 0xbbe,
- 0xbcb, 0xbc7, 0xbbe,
- 0xbcc, 0xbc6, 0xbd7,
+ 0xbca, 0xbc6, 0xbbe, 0x0,
+ 0xbcb, 0xbc7, 0xbbe, 0x0,
+ 0xbcc, 0xbc6, 0xbd7, 0x0,
// telugu
- 0xc48, 0xc46, 0xc56,
+ 0xc48, 0xc46, 0xc56, 0x0,
// kannada
- 0xcc0, 0xcbf, 0xcd5,
- 0xcc7, 0xcc6, 0xcd5,
- 0xcc8, 0xcc6, 0xcd6,
- 0xcca, 0xcc6, 0xcc2,
- 0xccb, 0xcca, 0xcd5,
+ 0xcc0, 0xcbf, 0xcd5, 0x0,
+ 0xcc7, 0xcc6, 0xcd5, 0x0,
+ 0xcc8, 0xcc6, 0xcd6, 0x0,
+ 0xcca, 0xcc6, 0xcc2, 0x0,
+ 0xccb, 0xcc6, 0xcc2, 0xcd5,
// malayalam
- 0xd4a, 0xd46, 0xd3e,
- 0xd4b, 0xd47, 0xd3e,
- 0xd4c, 0xd46, 0xd57,
+ 0xd4a, 0xd46, 0xd3e, 0x0,
+ 0xd4b, 0xd47, 0xd3e, 0x0,
+ 0xd4c, 0xd46, 0xd57, 0x0,
// sinhala
- 0xdda, 0xdd9, 0xdca,
- 0xddc, 0xdd9, 0xdcf,
- 0xddd, 0xddc, 0xdca,
- 0xdde, 0xdd9, 0xddf,
+ 0xdda, 0xdd9, 0xdca, 0x0,
+ 0xddc, 0xdd9, 0xdcf, 0x0,
+ 0xddd, 0xdd9, 0xdcf, 0xdca,
+ 0xdde, 0xdd9, 0xddf, 0x0,
0xffff
};
-static inline void splitMatra(unsigned short *reordered, int matra, int &len, int &base)
+static inline void splitMatra(unsigned short *reordered, int matra, int &len)
{
unsigned short matra_uc = reordered[matra];
//qDebug("matra=%d, reordered[matra]=%x", matra, reordered[matra]);
const unsigned short *split = split_matras;
while (split[0] < matra_uc)
- split += 3;
+ split += 4;
assert(*split == matra_uc);
++split;
- if (indic_position(*split) == Pre) {
- reordered[matra] = split[1];
- memmove(reordered + 1, reordered, len*sizeof(unsigned short));
- reordered[0] = split[0];
- base++;
- } else {
- memmove(reordered + matra + 1, reordered + matra, (len-matra)*sizeof(unsigned short));
- reordered[matra] = split[0];
- reordered[matra+1] = split[1];
- }
- len++;
+ int added_chars = split[2] == 0x0 ? 1 : 2;
+
+ memmove(reordered + matra + added_chars, reordered + matra, (len-matra)*sizeof(unsigned short));
+ reordered[matra] = split[0];
+ reordered[matra+1] = split[1];
+ if(added_chars == 2)
+ reordered[matra+2] = split[2];
+ len += added_chars;
}
#ifndef NO_OPENTYPE
@@ -1130,12 +1127,23 @@ static const HB_OpenTypeFeature indic_features[] = {
// #define INDIC_DEBUG
#ifdef INDIC_DEBUG
-#define IDEBUG qDebug
+#define IDEBUG hb_debug
+#include <stdarg.h>
+
+static void hb_debug(const char *msg, ...)
+{
+ va_list ap;
+ va_start(ap, msg); // use variable arg list
+ vfprintf(stderr, msg, ap);
+ va_end(ap);
+ fprintf(stderr, "\n");
+}
+
#else
#define IDEBUG if(0) printf
#endif
-#ifdef INDIC_DEBUG
+#if 0 //def INDIC_DEBUG
static QString propertiesToString(int properties)
{
QString res;
@@ -1386,12 +1394,12 @@ static bool indic_shape_syllable(HB_Bool openType, HB_ShaperItem *item, bool inv
// to be at the beginning of the syllable, so we just move
// them there now.
if (matra_position == Split) {
- splitMatra(uc, matra, len, base);
+ splitMatra(uc, matra, len);
// Handle three-part matras (0xccb in Kannada)
matra_position = indic_position(uc[matra]);
- if (matra_position == Split)
- splitMatra(uc, matra, len, base);
- } else if (matra_position == Pre) {
+ }
+
+ if (matra_position == Pre) {
unsigned short m = uc[matra];
while (matra--)
uc[matra+1] = uc[matra];
@@ -1609,11 +1617,11 @@ static bool indic_shape_syllable(HB_Bool openType, HB_ShaperItem *item, bool inv
// halant always applies
#ifdef INDIC_DEBUG
- {
- IDEBUG("OT properties:");
- for (int i = 0; i < len; ++i)
- qDebug(" i: %s", ::propertiesToString(properties[i]).toLatin1().data());
- }
+// {
+// IDEBUG("OT properties:");
+// for (int i = 0; i < len; ++i)
+// qDebug(" i: %s", ::propertiesToString(properties[i]).toLatin1().data());
+// }
#endif
// initialize
@@ -1731,6 +1739,11 @@ static int indic_nextSyllableBoundary(HB_Script script, const HB_UChar16 *s, int
if (script == HB_Script_Bengali && pos == 1 &&
(uc[0] == 0x0985 || uc[0] == 0x098f))
break;
+ // Sinhala uses the Halant as a component of certain matras. Allow these, but keep the state on Matra.
+ if (script == HB_Script_Sinhala && state == Matra) {
+ ++pos;
+ continue;
+ }
goto finish;
case Nukta:
if (state == Consonant)
@@ -1741,12 +1754,16 @@ static int indic_nextSyllableBoundary(HB_Script script, const HB_UChar16 *s, int
break;
// fall through
case VowelMark:
- if (state == Matra || state == IndependentVowel)
+ if (state == Matra || state == LengthMark || state == IndependentVowel)
break;
// fall through
case Matra:
if (state == Consonant || state == Nukta)
break;
+ if (state == Matra) {
+ // ### needs proper testing for correct two/three part matras
+ break;
+ }
// ### not sure if this is correct. If it is, does it apply only to Bengali or should
// it work for all Indic languages?
// the combination Independent_A + Vowel Sign AA is allowed.
@@ -1762,6 +1779,10 @@ static int indic_nextSyllableBoundary(HB_Script script, const HB_UChar16 *s, int
goto finish;
case LengthMark:
+ if (state == Matra) {
+ // ### needs proper testing for correct two/three part matras
+ break;
+ }
case IndependentVowel:
case Invalid:
case Other:
diff --git a/src/3rdparty/harfbuzz/src/harfbuzz-open.c b/src/3rdparty/harfbuzz/src/harfbuzz-open.c
index cde5465..0fe1e4d 100644
--- a/src/3rdparty/harfbuzz/src/harfbuzz-open.c
+++ b/src/3rdparty/harfbuzz/src/harfbuzz-open.c
@@ -1114,6 +1114,8 @@ _HB_OPEN_Load_EmptyClassDefinition( HB_ClassDefinition* cd )
if ( ALLOC_ARRAY( cd->cd.cd1.ClassValueArray, 1, HB_UShort ) )
return error;
+ cd->loaded = TRUE;
+
return HB_Err_Ok;
}
diff --git a/src/3rdparty/harfbuzz/src/harfbuzz-shape.h b/src/3rdparty/harfbuzz/src/harfbuzz-shape.h
index 4f714a3..e4b5f9a 100644
--- a/src/3rdparty/harfbuzz/src/harfbuzz-shape.h
+++ b/src/3rdparty/harfbuzz/src/harfbuzz-shape.h
@@ -161,7 +161,7 @@ typedef enum {
/*
* Buffer for output
*/
-typedef struct _HB_GlyphBufer HB_GlyphBuffer;
+typedef struct _HB_GlyphBuffer HB_GlyphBuffer;
struct _HB_GlyphBuffer {
int glyph_item_size;
int total_glyphs;
diff --git a/src/3rdparty/harfbuzz/src/harfbuzz-shaper.h b/src/3rdparty/harfbuzz/src/harfbuzz-shaper.h
index e8f5513..d2357f43 100644
--- a/src/3rdparty/harfbuzz/src/harfbuzz-shaper.h
+++ b/src/3rdparty/harfbuzz/src/harfbuzz-shaper.h
@@ -242,27 +242,30 @@ typedef struct HB_Font_ {
void *userData;
} HB_FontRec;
-typedef struct {
- const HB_UChar16 *string;
- hb_uint32 stringLength;
- HB_ScriptItem item;
- HB_Font font;
- HB_Face face;
- int shaperFlags; /* HB_ShaperFlags */
-
- HB_Bool glyphIndicesPresent; /* set to true if the glyph indicies are already setup in the glyphs array */
- hb_uint32 initialGlyphCount;
-
- hb_uint32 num_glyphs; /* in: available glyphs out: glyphs used/needed */
- HB_Glyph *glyphs; /* out parameter */
- HB_GlyphAttributes *attributes; /* out */
- HB_Fixed *advances; /* out */
- HB_FixedPoint *offsets; /* out */
- unsigned short *log_clusters; /* out */
+typedef struct HB_ShaperItem_ HB_ShaperItem;
+
+struct HB_ShaperItem_ {
+ const HB_UChar16 *string; /* input: the Unicode UTF16 text to be shaped */
+ hb_uint32 stringLength; /* input: the length of the input in 16-bit words */
+ HB_ScriptItem item; /* input: the current run to be shaped: a run of text all in the same script that is a substring of <string> */
+ HB_Font font; /* input: the font: scale, units and function pointers supplying glyph indices and metrics */
+ HB_Face face; /* input: the shaper state; current script, access to the OpenType tables , etc. */
+ int shaperFlags; /* input (unused) should be set to 0; intended to support flags defined in HB_ShaperFlag */
+ HB_Bool glyphIndicesPresent; /* input: true if the <glyphs> array contains glyph indices ready to be shaped */
+ hb_uint32 initialGlyphCount; /* input: if glyphIndicesPresent is true, the number of glyph indices in the <glyphs> array */
+
+ hb_uint32 num_glyphs; /* input: capacity of output arrays <glyphs>, <attributes>, <advances>, <offsets>, and <log_clusters>; */
+ /* output: required capacity (may be larger than actual capacity) */
+
+ HB_Glyph *glyphs; /* output: <num_glyphs> indices of shaped glyphs */
+ HB_GlyphAttributes *attributes; /* output: <num_glyphs> glyph attributes */
+ HB_Fixed *advances; /* output: <num_glyphs> advances */
+ HB_FixedPoint *offsets; /* output: <num_glyphs> offsets */
+ unsigned short *log_clusters; /* output: for each output glyph, the index in the input of the start of its logical cluster */
/* internal */
- HB_Bool kerning_applied; /* out: kerning applied by shaper */
-} HB_ShaperItem;
+ HB_Bool kerning_applied; /* output: true if kerning was applied by the shaper */
+};
HB_Bool HB_ShapeItem(HB_ShaperItem *item);
diff --git a/src/3rdparty/harfbuzz/tests/shaping/main.cpp b/src/3rdparty/harfbuzz/tests/shaping/main.cpp
index 1a3ef4f..a7ea417 100644
--- a/src/3rdparty/harfbuzz/tests/shaping/main.cpp
+++ b/src/3rdparty/harfbuzz/tests/shaping/main.cpp
@@ -178,7 +178,7 @@ private slots:
void telugu();
void kannada();
void malayalam();
- // sinhala missing
+ void sinhala();
void khmer();
void linearB();
@@ -510,6 +510,11 @@ void tst_QScriptEngine::bengali()
{ 0x151, 0x276, 0x172, 0x143, 0x0 } },
{ { 0x9b0, 0x9cd, 0x995, 0x9be, 0x983, 0x0 },
{ 0x151, 0x276, 0x172, 0x144, 0x0 } },
+ // test decomposed two parts matras
+ { { 0x995, 0x9c7, 0x9be, 0x0 },
+ { 0x179, 0x151, 0x172, 0x0 } },
+ { { 0x995, 0x9c7, 0x9d7, 0x0 },
+ { 0x179, 0x151, 0x17e, 0x0 } },
{ {0}, {0} }
};
@@ -638,15 +643,15 @@ void tst_QScriptEngine::bengali()
if (face) {
const ShapeTable shape_table [] = {
{ { 0x09a8, 0x09cd, 0x09af, 0x0 },
- { 0x0192, 0x0 } },
+ { 0x01ca, 0x0 } },
{ { 0x09b8, 0x09cd, 0x09af, 0x0 },
- { 0x01d6, 0x0 } },
+ { 0x020e, 0x0 } },
{ { 0x09b6, 0x09cd, 0x09af, 0x0 },
- { 0x01bc, 0x0 } },
+ { 0x01f4, 0x0 } },
{ { 0x09b7, 0x09cd, 0x09af, 0x0 },
- { 0x01c6, 0x0 } },
+ { 0x01fe, 0x0 } },
{ { 0x09b0, 0x09cd, 0x09a8, 0x09cd, 0x200d, 0x0 },
- { 0xd3, 0x12f, 0x0 } },
+ { 0x10b, 0x167, 0x0 } },
{ {0}, {0} }
};
@@ -823,8 +828,9 @@ void tst_QScriptEngine::telugu()
{ 0xe6, 0xb3, 0x83, 0x0 } },
{ { 0xc15, 0xc4d, 0xc30, 0xc48, 0x0 },
{ 0xe6, 0xb3, 0x9f, 0x0 } },
- { {0}, {0} }
-
+ { { 0xc15, 0xc46, 0xc56, 0x0 },
+ { 0xe6, 0xb3, 0x0 } },
+ { {0}, {0} }
};
const ShapeTable *s = shape_table;
@@ -867,7 +873,6 @@ void tst_QScriptEngine::kannada()
{ 0x0036, 0x00c1, 0x0 } },
{ { 0x0cb0, 0x0ccd, 0x200d, 0x0c95, 0x0 },
{ 0x0050, 0x00a7, 0x0 } },
-
{ {0}, {0} }
};
@@ -891,6 +896,17 @@ void tst_QScriptEngine::kannada()
{ 0x00b0, 0x006c, 0x0 } },
{ { 0x0cb7, 0x0ccd, 0x0 },
{ 0x0163, 0x0 } },
+ { { 0xc95, 0xcbf, 0xcd5, 0x0 },
+ { 0x114, 0x73, 0x0 } },
+ { { 0xc95, 0xcc6, 0xcd5, 0x0 },
+ { 0x90, 0x6c, 0x73, 0x0 } },
+ { { 0xc95, 0xcc6, 0xcd6, 0x0 },
+ { 0x90, 0x6c, 0x74, 0x0 } },
+ { { 0xc95, 0xcc6, 0xcc2, 0x0 },
+ { 0x90, 0x6c, 0x69, 0x0 } },
+ { { 0xc95, 0xcca, 0xcd5, 0x0 },
+ { 0x90, 0x6c, 0x69, 0x73, 0x0 } },
+
{ {0}, {0} }
};
@@ -943,7 +959,14 @@ void tst_QScriptEngine::malayalam()
{ 0x009e, 0x0 } },
{ { 0x0d30, 0x0d4d, 0x200d, 0x0 },
{ 0x009e, 0x0 } },
-
+ { { 0xd15, 0xd46, 0xd3e, 0x0 },
+ { 0x5e, 0x34, 0x58, 0x0 } },
+ { { 0xd15, 0xd47, 0xd3e, 0x0 },
+ { 0x5f, 0x34, 0x58, 0x0 } },
+ { { 0xd15, 0xd46, 0xd57, 0x0 },
+ { 0x5e, 0x34, 0x65, 0x0 } },
+ { { 0xd15, 0xd57, 0x0 },
+ { 0x34, 0x65, 0x0 } },
{ {0}, {0} }
};
@@ -962,6 +985,39 @@ void tst_QScriptEngine::malayalam()
}
}
+void tst_QScriptEngine::sinhala()
+{
+ {
+ FT_Face face = loadFace("FM-MalithiUW46.ttf");
+ if (face) {
+ const ShapeTable shape_table [] = {
+ { { 0xd9a, 0xdd9, 0xdcf, 0x0 },
+ { 0x4a, 0x61, 0x42, 0x0 } },
+ { { 0xd9a, 0xdd9, 0xddf, 0x0 },
+ { 0x4a, 0x61, 0x50, 0x0 } },
+ { { 0xd9a, 0xdd9, 0xdca, 0x0 },
+ { 0x4a, 0x62, 0x0 } },
+ { { 0xd9a, 0xddc, 0xdca, 0x0 },
+ { 0x4a, 0x61, 0x42, 0x41, 0x0 } },
+ { { 0xd9a, 0xdda, 0x0 },
+ { 0x4a, 0x62, 0x0 } },
+ { { 0xd9a, 0xddd, 0x0 },
+ { 0x4a, 0x61, 0x42, 0x41, 0x0 } },
+ { {0}, {0} }
+ };
+
+ const ShapeTable *s = shape_table;
+ while (s->unicode[0]) {
+ QVERIFY( shaping(face, s, HB_Script_Sinhala) );
+ ++s;
+ }
+
+ FT_Done_Face(face);
+ } else {
+ QSKIP("couln't find FM-MalithiUW46.ttf", SkipAll);
+ }
+ }
+}
void tst_QScriptEngine::khmer()