summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLars Knoll <lars.knoll@nokia.com>2010-03-26 21:54:54 +0100
committerLars Knoll <lars.knoll@nokia.com>2010-03-26 21:54:54 +0100
commit33b9cde6a08293d26047734e046c6677a2959adb (patch)
treed3b6bf24993d9dfa7ef0f81190db0bdc28b38096
parentb6951137d935535319829de616938cf558fb7a70 (diff)
fix a bug in the greek shaper that could lead to an endless loop.
availableGlyphs has to be initialized before we call stringToCMap. Added a test case that triggered the problem.
-rw-r--r--src/harfbuzz-greek.c27
-rw-r--r--tests/shaping/main.cpp40
2 files changed, 54 insertions, 13 deletions
diff --git a/src/harfbuzz-greek.c b/src/harfbuzz-greek.c
index 59f3077..2e9b858 100644
--- a/src/harfbuzz-greek.c
+++ b/src/harfbuzz-greek.c
@@ -77,10 +77,12 @@ static HB_UChar16 compose_0x300(HB_UChar16 base)
return 0x1fdd;
return 0;
}
- const hb_greek_decomposition *d = decompose_0x300;
- while (d->base && d->base != base)
- ++d;
- return d->composed;
+ {
+ const hb_greek_decomposition *d = decompose_0x300;
+ while (d->base && d->base != base)
+ ++d;
+ return d->composed;
+ }
}
static const hb_greek_decomposition decompose_0x301[] = {
@@ -115,10 +117,12 @@ static HB_UChar16 compose_0x301(HB_UChar16 base)
if (base == 0x1ffe)
return 0x1fde;
}
- const hb_greek_decomposition *d = decompose_0x301;
- while (d->base && d->base != base)
- ++d;
- return d->composed;
+ {
+ const hb_greek_decomposition *d = decompose_0x301;
+ while (d->base && d->base != base)
+ ++d;
+ return d->composed;
+ }
}
static const hb_greek_decomposition decompose_0x304[] = {
@@ -351,8 +355,7 @@ static HB_UChar16 compose_0x345(HB_UChar16 base)
*/
HB_Bool HB_GreekShape(HB_ShaperItem *shaper_item)
{
- assert(shaper_item->item.script == HB_Script_Greek);
-
+ const int availableGlyphs = shaper_item->num_glyphs;
const HB_UChar16 *uc = shaper_item->string + shaper_item->item.pos;
unsigned short *logClusters = shaper_item->log_clusters;
HB_GlyphAttributes *attributes = shaper_item->attributes;
@@ -363,6 +366,9 @@ HB_Bool HB_GreekShape(HB_ShaperItem *shaper_item)
hb_uint32 i;
HB_STACKARRAY(HB_UChar16, shapedChars, 2 * shaper_item->item.length);
+
+ assert(shaper_item->item.script == HB_Script_Greek);
+
*shapedChars = *uc;
logClusters[0] = 0;
@@ -430,7 +436,6 @@ HB_Bool HB_GreekShape(HB_ShaperItem *shaper_item)
#ifndef NO_OPENTYPE
if (HB_SelectScript(shaper_item, greek_features)) {
- const int availableGlyphs = shaper_item->num_glyphs;
HB_OpenTypeShape(shaper_item, /*properties*/0);
return HB_OpenTypePosition(shaper_item, availableGlyphs, /*doLogClusters*/TRUE);
}
diff --git a/tests/shaping/main.cpp b/tests/shaping/main.cpp
index b48b0a9..320e8ee 100644
--- a/tests/shaping/main.cpp
+++ b/tests/shaping/main.cpp
@@ -272,7 +272,6 @@ Shaper::Shaper(FT_Face face, HB_Script script, const QString &str)
}
-#if defined(Q_WS_X11)
static bool decomposedShaping(FT_Face face, HB_Script script, const QChar &ch)
{
QString uc = QString().append(ch);
@@ -318,7 +317,6 @@ static bool decomposedShaping(FT_Face face, HB_Script script, const QChar &ch)
qDebug(" decomposed glyph result = %s", str.toLatin1().constData());
return false;
}
-#endif
struct ShapeTable {
unsigned short unicode[16];
@@ -382,6 +380,44 @@ void tst_QScriptEngine::greek()
continue;
QVERIFY( decomposedShaping(face, HB_Script_Greek, QChar(uc)) );
}
+ FT_Done_Face(face);
+ } else {
+ QSKIP("couln't find DejaVu Sans", SkipAll);
+ }
+
+
+ face = loadFace("SBL_grk.ttf");
+ if (face) {
+ for (int uc = 0x1f00; uc <= 0x1fff; ++uc) {
+ QString str;
+ str.append(uc);
+ if (str.normalized(QString::NormalizationForm_D).normalized(QString::NormalizationForm_C) != str) {
+ //qDebug() << "skipping" << hex << uc;
+ continue;
+ }
+ if (uc == 0x1fc1 || uc == 0x1fed)
+ continue;
+ QVERIFY( decomposedShaping(face, HB_Script_Greek, QChar(uc)) );
+
+ }
+
+ const ShapeTable shape_table [] = {
+ { { 0x3b1, 0x300, 0x313, 0x0 },
+ { 0xb8, 0x3d3, 0x3c7, 0x0 } },
+ { { 0x3b1, 0x313, 0x300, 0x0 },
+ { 0xd4, 0x0 } },
+
+ { {0}, {0} }
+ };
+
+
+ const ShapeTable *s = shape_table;
+ while (s->unicode[0]) {
+ QVERIFY( shaping(face, s, HB_Script_Greek) );
+ ++s;
+ }
+
+ FT_Done_Face(face);
} else {
QSKIP("couln't find DejaVu Sans", SkipAll);
}