OLD | NEW |
1 diff --git a/contrib/harfbuzz-unicode.c b/contrib/harfbuzz-unicode.c | 1 diff --git a/contrib/harfbuzz-unicode.c b/contrib/harfbuzz-unicode.c |
2 index 51dd4ea..cb7a85b 100644 | 2 index 049e0ca..86458d0 100644 |
3 --- a/contrib/harfbuzz-unicode.c | 3 --- a/contrib/harfbuzz-unicode.c |
4 +++ b/contrib/harfbuzz-unicode.c | 4 +++ b/contrib/harfbuzz-unicode.c |
5 @@ -171,7 +171,10 @@ hb_utf16_script_run_prev(unsigned *num_code_points, HB_Scri
ptItem *output, | 5 @@ -120,7 +120,6 @@ hb_utf16_script_run_next(unsigned *num_code_points, HB_Scrip
tItem *output, |
6 current_script = script; | 6 current_script = script; |
7 continue; | 7 continue; |
8 } else if (script == HB_Script_Inherited) { | 8 } else if (script == HB_Script_Inherited) { |
| 9 - current_script = script; |
| 10 continue; |
| 11 } else { |
| 12 *iter = prev_iter; |
| 13 @@ -171,7 +170,10 @@ hb_utf16_script_run_prev(unsigned *num_code_points, HB_Scri
ptItem *output, |
| 14 current_script = script; |
| 15 continue; |
| 16 } else if (script == HB_Script_Inherited) { |
9 - current_script = script; | 17 - current_script = script; |
10 + // Just assume that whatever follows this combining character is within | 18 + // Just assume that whatever follows this combining character is within |
11 + // the same script. This is incorrect if you had language1 + combining | 19 + // the same script. This is incorrect if you had language1 + combining |
12 + // char + language 2, but that is rare and this code is suspicious | 20 + // char + language 2, but that is rare and this code is suspicious |
13 + // anyway. | 21 + // anyway. |
14 continue; | 22 continue; |
15 } else { | 23 } else { |
16 *iter = prev_iter; | 24 *iter = prev_iter; |
| 25 diff --git a/src/harfbuzz-arabic.c b/src/harfbuzz-arabic.c |
| 26 index 3837087..ce2ca6c 100644 |
| 27 --- a/src/harfbuzz-arabic.c |
| 28 +++ b/src/harfbuzz-arabic.c |
| 29 @@ -1107,6 +1107,7 @@ HB_Bool HB_ArabicShape(HB_ShaperItem *item) |
| 30 assert(item->item.script == HB_Script_Arabic || item->item.script == HB_Scr
ipt_Syriac |
| 31 || item->item.script == HB_Script_Nko); |
| 32 |
| 33 + item->shaperFlags |= HB_ShaperFlag_ForceMarksToZeroWidth; |
| 34 #ifndef NO_OPENTYPE |
| 35 |
| 36 if (HB_SelectScript(item, item->item.script == HB_Script_Arabic ? arabic_fe
atures : syriac_features)) { |
17 diff --git a/src/harfbuzz-gpos.c b/src/harfbuzz-gpos.c | 37 diff --git a/src/harfbuzz-gpos.c b/src/harfbuzz-gpos.c |
18 index 356dc01..db5ea0a 100644 | 38 index a216005..7bd3b3b 100644 |
19 --- a/src/harfbuzz-gpos.c | 39 --- a/src/harfbuzz-gpos.c |
20 +++ b/src/harfbuzz-gpos.c | 40 +++ b/src/harfbuzz-gpos.c |
21 @@ -2976,6 +2976,9 @@ static HB_Error Lookup_MarkMarkPos( GPOS_Instance* gpi
, | 41 @@ -3012,6 +3012,9 @@ static HB_Error Lookup_MarkMarkPos( GPOS_Instance* gpi
, |
22 j--; | 42 j--; |
23 } | 43 } |
24 | 44 |
25 + if ( i > buffer->in_pos ) | 45 + if ( i > buffer->in_pos ) |
26 + return HB_Err_Not_Covered; | 46 + return HB_Err_Not_Covered; |
27 + | 47 + |
28 error = _HB_OPEN_Coverage_Index( &mmp->Mark2Coverage, IN_GLYPH( j ), | 48 error = _HB_OPEN_Coverage_Index( &mmp->Mark2Coverage, IN_GLYPH( j ), |
29 &mark2_index ); | 49 &mark2_index ); |
30 if ( error ) | 50 if ( error ) |
31 diff --git a/src/harfbuzz-shaper.cpp b/src/harfbuzz-shaper.cpp | 51 diff --git a/src/harfbuzz-shaper.cpp b/src/harfbuzz-shaper.cpp |
32 index f3ec8e1..2b52221 100644 | 52 index ce4d4ac..0f50799 100644 |
33 --- a/src/harfbuzz-shaper.cpp | 53 --- a/src/harfbuzz-shaper.cpp |
34 +++ b/src/harfbuzz-shaper.cpp | 54 +++ b/src/harfbuzz-shaper.cpp |
35 @@ -433,7 +433,7 @@ void HB_HeuristicSetGlyphAttributes(HB_ShaperItem *item) | 55 @@ -430,7 +430,7 @@ void HB_HeuristicSetGlyphAttributes(HB_ShaperItem *item) |
36 | 56 |
37 // ### zeroWidth and justification are missing here!!!!! | 57 // ### zeroWidth and justification are missing here!!!!! |
38 | 58 |
39 - assert(item->num_glyphs <= length); | 59 - assert(item->num_glyphs <= length); |
40 + assert(length <= item->num_glyphs); | 60 + assert(length <= item->num_glyphs); |
41 | 61 |
42 // qDebug("QScriptEngine::heuristicSetGlyphAttributes, num_glyphs=%d", item
->num_glyphs); | 62 // qDebug("QScriptEngine::heuristicSetGlyphAttributes, num_glyphs=%d", item
->num_glyphs); |
43 HB_GlyphAttributes *attributes = item->attributes; | 63 HB_GlyphAttributes *attributes = item->attributes; |
44 @@ -451,7 +451,6 @@ void HB_HeuristicSetGlyphAttributes(HB_ShaperItem *item) | 64 @@ -448,7 +448,6 @@ void HB_HeuristicSetGlyphAttributes(HB_ShaperItem *item) |
45 } | 65 } |
46 ++glyph_pos; | 66 ++glyph_pos; |
47 } | 67 } |
48 - assert(glyph_pos == item->num_glyphs); | 68 - assert(glyph_pos == item->num_glyphs); |
49 | 69 |
50 // first char in a run is never (treated as) a mark | 70 // first char in a run is never (treated as) a mark |
51 int cStart = 0; | 71 int cStart = 0; |
52 @@ -1151,10 +1150,11 @@ HB_Bool HB_OpenTypeShape(HB_ShaperItem *item, const hb_u
int32 *properties) | 72 @@ -1151,10 +1150,12 @@ HB_Bool HB_OpenTypeShape(HB_ShaperItem *item, const hb_u
int32 *properties) |
53 return false; | 73 return false; |
54 face->tmpLogClusters = tmpLogClusters; | 74 face->tmpLogClusters = tmpLogClusters; |
55 | 75 |
56 + const int itemLength = item->item.length; | 76 + const int itemLength = item->item.length; |
| 77 + assert(itemLength > 0); |
57 for (int i = 0; i < face->length; ++i) { | 78 for (int i = 0; i < face->length; ++i) { |
58 hb_buffer_add_glyph(face->buffer, item->glyphs[i], properties ? propert
ies[i] : 0, i); | 79 hb_buffer_add_glyph(face->buffer, item->glyphs[i], properties ? propert
ies[i] : 0, i); |
59 face->tmpAttributes[i] = item->attributes[i]; | 80 face->tmpAttributes[i] = item->attributes[i]; |
60 - face->tmpLogClusters[i] = item->log_clusters[i]; | 81 - face->tmpLogClusters[i] = item->log_clusters[i]; |
61 + face->tmpLogClusters[i] = i < itemLength ? item->log_clusters[i] : item
->log_clusters[itemLength - 1]; | 82 + face->tmpLogClusters[i] = i < itemLength ? item->log_clusters[i] : item
->log_clusters[itemLength - 1]; |
62 } | 83 } |
63 | 84 |
64 #ifdef OT_DEBUG | 85 #ifdef OT_DEBUG |
| 86 @@ -1190,6 +1191,24 @@ HB_Bool HB_OpenTypeShape(HB_ShaperItem *item, const hb_ui
nt32 *properties) |
| 87 return true; |
| 88 } |
| 89 |
| 90 +/* See comments near the definition of HB_ShaperFlag_ForceMarksToZeroWidth for
a description |
| 91 + of why this function exists. */ |
| 92 +void HB_FixupZeroWidth(HB_ShaperItem *item) |
| 93 +{ |
| 94 + HB_UShort property; |
| 95 + |
| 96 + if (!item->face->gdef) |
| 97 + return; |
| 98 + |
| 99 + for (unsigned int i = 0; i < item->num_glyphs; ++i) { |
| 100 + /* If the glyph is a mark, force its advance to zero. */ |
| 101 + if (HB_GDEF_Get_Glyph_Property (item->face->gdef, item->glyphs[i], &pro
perty) == HB_Err_Ok && |
| 102 + property == HB_GDEF_MARK) { |
| 103 + item->advances[i] = 0; |
| 104 + } |
| 105 + } |
| 106 +} |
| 107 + |
| 108 HB_Bool HB_OpenTypePosition(HB_ShaperItem *item, int availableGlyphs, HB_Bool d
oLogClusters) |
| 109 { |
| 110 HB_Face face = item->face; |
| 111 @@ -1204,6 +1223,8 @@ HB_Bool HB_OpenTypePosition(HB_ShaperItem *item, int avail
ableGlyphs, HB_Bool do |
| 112 |
| 113 if (!face->glyphs_substituted && !glyphs_positioned) { |
| 114 HB_GetGlyphAdvances(item); |
| 115 + if (item->face->current_flags & HB_ShaperFlag_ForceMarksToZeroWidth) |
| 116 + HB_FixupZeroWidth(item); |
| 117 return true; // nothing to do for us |
| 118 } |
| 119 |
| 120 diff --git a/src/harfbuzz-shaper.h b/src/harfbuzz-shaper.h |
| 121 index ab5c07a..72c9aa3 100644 |
| 122 --- a/src/harfbuzz-shaper.h |
| 123 +++ b/src/harfbuzz-shaper.h |
| 124 @@ -170,7 +170,11 @@ typedef enum { |
| 125 typedef enum { |
| 126 HB_ShaperFlag_Default = 0, |
| 127 HB_ShaperFlag_NoKerning = 1, |
| 128 - HB_ShaperFlag_UseDesignMetrics = 2 |
| 129 + HB_ShaperFlag_UseDesignMetrics = 1 << 1, |
| 130 + /* Arabic vowels in some fonts (Times New Roman, at least) have |
| 131 + non-zero advances, when they should be zero. Setting this shaper |
| 132 + flag causes us to zero out the advances for mark glyphs. */ |
| 133 + HB_ShaperFlag_ForceMarksToZeroWidth = 1 << 2 |
| 134 } HB_ShaperFlag; |
| 135 |
| 136 /* |
OLD | NEW |