Merge lp:~timo-jyrinki/kubuntu-packaging/qtbase_sync_from_archives_and_add_harfbuzz_patches into lp:~kubuntu-packagers/kubuntu-packaging/qtbase-opensource-src

Proposed by Timo Jyrinki
Status: Merged
Approved by: Timo Jyrinki
Approved revision: 163
Merged at revision: 162
Proposed branch: lp:~timo-jyrinki/kubuntu-packaging/qtbase_sync_from_archives_and_add_harfbuzz_patches
Merge into: lp:~kubuntu-packagers/kubuntu-packaging/qtbase-opensource-src
Diff against target: 435 lines (+400/-0)
6 files modified
debian/changelog (+12/-0)
debian/patches/Fix-access-after-delete-with-Harfbuzz-NG-code-path.patch (+33/-0)
debian/patches/Fix-log_clusters-calculation-in-HarfBuzz-NG-code-pat.patch (+112/-0)
debian/patches/HarfBuzz-NG-Hide-characters-that-should-normally-be-.patch (+50/-0)
debian/patches/Minor-optimization-for-QTextEngine-shapeText.patch (+189/-0)
debian/patches/series (+4/-0)
To merge this branch: bzr merge lp:~timo-jyrinki/kubuntu-packaging/qtbase_sync_from_archives_and_add_harfbuzz_patches
Reviewer Review Type Date Requested Status
PS Jenkins bot continuous-integration Approve
Timo Jyrinki Approve
Review via email: mp+211501@code.launchpad.net

Commit message

Release 5.2.1+dfsg-1ubuntu9 for landing

* debian/patches/Fix-access-after-delete-with-Harfbuzz-NG-code-path.patch
* debian/patches/Fix-log_clusters-calculation-in-HarfBuzz-NG-code-pat.patch
* debian/patches/HarfBuzz-NG-Hide-characters-that-should-normally-be-.patch
* debian/patches/Minor-optimization-for-QTextEngine-shapeText.patch
  - Cherry-pick latest HarfBuzz-NG changes from upstream including the one
    fixing the glyph issue https://codereview.qt-project.org/#change,81150
    (LP: #1285184)

Description of the change

Release 5.2.1+dfsg-1ubuntu9 for landing

* debian/patches/Fix-access-after-delete-with-Harfbuzz-NG-code-path.patch
* debian/patches/Fix-log_clusters-calculation-in-HarfBuzz-NG-code-pat.patch
* debian/patches/HarfBuzz-NG-Hide-characters-that-should-normally-be-.patch
* debian/patches/Minor-optimization-for-QTextEngine-shapeText.patch
  - Cherry-pick latest HarfBuzz-NG changes from upstream including the one
    fixing the glyph issue https://codereview.qt-project.org/#change,81150
    (LP: #1285184)

To post a comment you must log in.
Revision history for this message
Timo Jyrinki (timo-jyrinki) wrote :

Passed for all archs at: https://launchpad.net/~ci-train-ppa-service/+archive/landing-002/+sourcepub/4027738/+listing-archive-extra

All AP:s passing too (one last running at the moment), releasing via CI Train soon.

review: Approve
Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :

FAILED: Autolanding.
No commit message was specified in the merge proposal. Hit 'Add commit message' on the merge proposal web page or follow the link below. You can approve the merge proposal yourself to rerun.
https://code.launchpad.net/~timo-jyrinki/kubuntu-packaging/qtbase_sync_from_archives_and_add_harfbuzz_patches/+merge/211501/+edit-commit-message

review: Needs Fixing (continuous-integration)
Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :
review: Approve (continuous-integration)

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'debian/changelog'
2--- debian/changelog 2014-03-18 05:45:20 +0000
3+++ debian/changelog 2014-03-18 11:57:21 +0000
4@@ -1,3 +1,15 @@
5+qtbase-opensource-src (5.2.1+dfsg-1ubuntu9) trusty; urgency=medium
6+
7+ * debian/patches/Fix-access-after-delete-with-Harfbuzz-NG-code-path.patch
8+ * debian/patches/Fix-log_clusters-calculation-in-HarfBuzz-NG-code-pat.patch
9+ * debian/patches/HarfBuzz-NG-Hide-characters-that-should-normally-be-.patch
10+ * debian/patches/Minor-optimization-for-QTextEngine-shapeText.patch
11+ - Cherry-pick latest HarfBuzz-NG changes from upstream including the one
12+ fixing the glyph issue https://codereview.qt-project.org/#change,81150
13+ (LP: #1285184)
14+
15+ -- Timo Jyrinki <timo-jyrinki@ubuntu.com> Tue, 18 Mar 2014 06:00:49 +0000
16+
17 qtbase-opensource-src (5.2.1+dfsg-1ubuntu8) trusty; urgency=medium
18
19 * debian/patches/Add-workaround-for-GL-on-Android-emulator.patch:
20
21=== added file 'debian/patches/Fix-access-after-delete-with-Harfbuzz-NG-code-path.patch'
22--- debian/patches/Fix-access-after-delete-with-Harfbuzz-NG-code-path.patch 1970-01-01 00:00:00 +0000
23+++ debian/patches/Fix-access-after-delete-with-Harfbuzz-NG-code-path.patch 2014-03-18 11:57:21 +0000
24@@ -0,0 +1,33 @@
25+From de6d260ace56f7245ebd1e2e4454ff1c84f5f89a Mon Sep 17 00:00:00 2001
26+From: Allan Sandfeld Jensen <allan.jensen@digia.com>
27+Date: Wed, 29 Jan 2014 16:47:08 +0100
28+Subject: [PATCH] Fix access after delete with Harfbuzz NG code path.
29+
30+Remove reference to released font-engine so we don't risk returning it
31+later.
32+
33+Change-Id: I741a741567a079818c7f414ac1f9c0b5a9677322
34+Task-number: QTBUG-36522
35+---
36+ src/gui/text/qtextengine.cpp | 4 +++-
37+ 1 file changed, 3 insertions(+), 1 deletion(-)
38+
39+diff --git a/src/gui/text/qtextengine.cpp b/src/gui/text/qtextengine.cpp
40+index 06c5e24..c2e352e 100644
41+--- a/src/gui/text/qtextengine.cpp
42++++ b/src/gui/text/qtextengine.cpp
43+@@ -1875,8 +1875,10 @@ QFontEngine *QTextEngine::fontEngine(const QScriptItem &si, QFixed *ascent, QFix
44+ feCache.prevFontEngine = engine;
45+ feCache.prevScript = script;
46+ engine->ref.ref();
47+- if (feCache.prevScaledFontEngine)
48++ if (feCache.prevScaledFontEngine) {
49+ releaseCachedFontEngine(feCache.prevScaledFontEngine);
50++ feCache.prevScaledFontEngine = 0;
51++ }
52+ }
53+ if (si.analysis.flags & QFont::SmallCaps) {
54+ if (feCache.prevScaledFontEngine) {
55+--
56+1.9.0
57+
58
59=== added file 'debian/patches/Fix-log_clusters-calculation-in-HarfBuzz-NG-code-pat.patch'
60--- debian/patches/Fix-log_clusters-calculation-in-HarfBuzz-NG-code-pat.patch 1970-01-01 00:00:00 +0000
61+++ debian/patches/Fix-log_clusters-calculation-in-HarfBuzz-NG-code-pat.patch 2014-03-18 11:57:21 +0000
62@@ -0,0 +1,112 @@
63+From ba1113881910e3e7a6a79dd723a822638b3818c1 Mon Sep 17 00:00:00 2001
64+From: Konstantin Ritt <ritt.ks@gmail.com>
65+Date: Sun, 9 Feb 2014 00:46:40 +0200
66+Subject: [PATCH] Fix log_clusters calculation in HarfBuzz-NG code path
67+
68+The old code wasn't good enough to catch all the glyph (de)composition cases,
69+thus leading to an assertion in QTextLayout's addNextCluster() helper.
70+
71+The new code catches all the corner cases and introduces somewhat
72+better performance to the HB-NG shaper backend.
73+
74+Change-Id: I5b6c673395a4a039dc55b200abbf74b0ba5d0829
75+---
76+ src/gui/text/qtextengine.cpp | 53 +++++++++++++-------------------------------
77+ 1 file changed, 16 insertions(+), 37 deletions(-)
78+
79+diff --git a/src/gui/text/qtextengine.cpp b/src/gui/text/qtextengine.cpp
80+index c2e352e..607fe95 100644
81+--- a/src/gui/text/qtextengine.cpp
82++++ b/src/gui/text/qtextengine.cpp
83+@@ -1105,18 +1105,6 @@ int QTextEngine::shapeTextWithHarfbuzzNG(const QScriptItem &si, const ushort *st
84+ buffer_flags |= HB_BUFFER_FLAG_PRESERVE_DEFAULT_IGNORABLES;
85+ hb_buffer_set_flags(buffer, hb_buffer_flags_t(buffer_flags));
86+
87+- const uint num_codes = hb_buffer_get_length(buffer);
88+- {
89+- // adjust clusters
90+- hb_glyph_info_t *infos = hb_buffer_get_glyph_infos(buffer, 0);
91+- const ushort *uc = string + item_pos;
92+- for (uint i = 0, code_pos = 0; i < item_length; ++i, ++code_pos) {
93+- if (QChar::isHighSurrogate(uc[i]) && i + 1 < item_length && QChar::isLowSurrogate(uc[i + 1]))
94+- ++i;
95+- infos[code_pos].cluster = code_pos + item_glyph_pos;
96+- }
97+- }
98+-
99+
100+ // shape
101+ bool shapedOk = false;
102+@@ -1139,8 +1127,7 @@ int QTextEngine::shapeTextWithHarfbuzzNG(const QScriptItem &si, const ushort *st
103+ if (si.analysis.bidiLevel % 2)
104+ hb_buffer_reverse(buffer);
105+
106+-
107+- remaining_glyphs -= num_codes;
108++ remaining_glyphs -= item_glyph_pos;
109+
110+ // ensure we have enough space for shaped glyphs and metrics
111+ const uint num_glyphs = hb_buffer_get_length(buffer);
112+@@ -1151,44 +1138,36 @@ int QTextEngine::shapeTextWithHarfbuzzNG(const QScriptItem &si, const ushort *st
113+
114+ // fetch the shaped glyphs and metrics
115+ QGlyphLayout g = availableGlyphs(&si).mid(glyphs_shaped, num_glyphs);
116+- if (num_glyphs > num_codes)
117+- moveGlyphData(g.mid(num_glyphs), g.mid(num_codes), remaining_glyphs);
118++ if (num_glyphs != item_glyph_pos)
119++ moveGlyphData(g.mid(num_glyphs), g.mid(item_glyph_pos), remaining_glyphs);
120+ ushort *log_clusters = logClusters(&si) + item_pos;
121+
122+ hb_glyph_info_t *infos = hb_buffer_get_glyph_infos(buffer, 0);
123+ hb_glyph_position_t *positions = hb_buffer_get_glyph_positions(buffer, 0);
124+- uint last_cluster = -1;
125++ uint str_pos = 0;
126++ uint last_cluster = ~0u;
127++ uint last_glyph_pos = glyphs_shaped;
128+ for (uint i = 0; i < num_glyphs; ++i) {
129+ g.glyphs[i] = infos[i].codepoint;
130+- log_clusters[i] = infos[i].cluster;
131+
132+ g.advances_x[i] = QFixed::fromFixed(positions[i].x_advance);
133+ g.advances_y[i] = QFixed::fromFixed(positions[i].y_advance);
134+ g.offsets[i].x = QFixed::fromFixed(positions[i].x_offset);
135+ g.offsets[i].y = QFixed::fromFixed(positions[i].y_offset);
136+
137+- if (infos[i].cluster != last_cluster) {
138+- last_cluster = infos[i].cluster;
139++ uint cluster = infos[i].cluster;
140++ if (last_cluster != cluster) {
141++ // fix up clusters so that the cluster indices will be monotonic
142++ // and thus we never return out-of-order indices
143++ while (last_cluster++ < cluster && str_pos < item_length)
144++ log_clusters[str_pos++] = last_glyph_pos;
145++ last_glyph_pos = i + glyphs_shaped;
146++ last_cluster = cluster;
147+ g.attributes[i].clusterStart = true;
148+ }
149+ }
150+-
151+- {
152+- // adjust clusters
153+- uint glyph_pos = 0;
154+- for (uint i = 0; i < item_length; ++i) {
155+- if (i + item_pos != infos[glyph_pos].cluster) {
156+- for (uint j = glyph_pos + 1; j < num_glyphs; ++j) {
157+- if (i + item_pos <= infos[j].cluster) {
158+- if (i + item_pos == infos[j].cluster)
159+- glyph_pos = j;
160+- break;
161+- }
162+- }
163+- }
164+- log_clusters[i] = glyph_pos + item_glyph_pos;
165+- }
166+- }
167++ while (str_pos < item_length)
168++ log_clusters[str_pos++] = last_glyph_pos;
169+
170+ if (engineIdx != 0) {
171+ for (quint32 i = 0; i < num_glyphs; ++i)
172+--
173+1.9.0
174+
175
176=== added file 'debian/patches/HarfBuzz-NG-Hide-characters-that-should-normally-be-.patch'
177--- debian/patches/HarfBuzz-NG-Hide-characters-that-should-normally-be-.patch 1970-01-01 00:00:00 +0000
178+++ debian/patches/HarfBuzz-NG-Hide-characters-that-should-normally-be-.patch 2014-03-18 11:57:21 +0000
179@@ -0,0 +1,50 @@
180+From 80588b02d81bed0ed225054055075505a9096d84 Mon Sep 17 00:00:00 2001
181+From: Konstantin Ritt <ritt.ks@gmail.com>
182+Date: Tue, 18 Mar 2014 02:42:47 +0200
183+Subject: [PATCH] HarfBuzz-NG: Hide characters that should normally be
184+ invisible
185+
186+These are non-ambigue NLF characters that should only imply the
187+sctructure of the document.
188+For details, see http://www.unicode.org/reports/tr13/ .
189+
190+The issue could be reproduced with use of multi-line QML Text element.
191+
192+This is a backport of 6a7747f30cc853f07501770a8704 from 5.3
193+
194+Task-number: QTBUG-37475
195+
196+Change-Id: Ie32bdf18f4a0225496895d5d29e94e4497dcc150
197+---
198+ src/gui/text/qtextengine.cpp | 15 +++++++++++++++
199+ 1 file changed, 15 insertions(+)
200+
201+diff --git a/src/gui/text/qtextengine.cpp b/src/gui/text/qtextengine.cpp
202+index febdaaa..84197af 100644
203+--- a/src/gui/text/qtextengine.cpp
204++++ b/src/gui/text/qtextengine.cpp
205+@@ -1146,6 +1146,21 @@ int QTextEngine::shapeTextWithHarfbuzzNG(const QScriptItem &si, const ushort *st
206+
207+ uint cluster = infos[i].cluster;
208+ if (last_cluster != cluster) {
209++ if (Q_UNLIKELY(g.glyphs[i] == 0)) {
210++ // hide characters that should normally be invisible
211++ switch (string[item_pos + str_pos]) {
212++ case QChar::LineFeed:
213++ case 0x000c: // FormFeed
214++ case QChar::CarriageReturn:
215++ case QChar::LineSeparator:
216++ case QChar::ParagraphSeparator:
217++ g.attributes[i].dontPrint = true;
218++ break;
219++ default:
220++ break;
221++ }
222++ }
223++
224+ // fix up clusters so that the cluster indices will be monotonic
225+ // and thus we never return out-of-order indices
226+ while (last_cluster++ < cluster && str_pos < item_length)
227+--
228+1.9.0
229+
230
231=== added file 'debian/patches/Minor-optimization-for-QTextEngine-shapeText.patch'
232--- debian/patches/Minor-optimization-for-QTextEngine-shapeText.patch 1970-01-01 00:00:00 +0000
233+++ debian/patches/Minor-optimization-for-QTextEngine-shapeText.patch 2014-03-18 11:57:21 +0000
234@@ -0,0 +1,189 @@
235+From f5dab563288de0d834225a51b03fd7043c5339cf Mon Sep 17 00:00:00 2001
236+From: Konstantin Ritt <ritt.ks@gmail.com>
237+Date: Sun, 9 Feb 2014 06:37:51 +0200
238+Subject: [PATCH] Minor optimization for QTextEngine::shapeText()
239+
240+Remember the engine index for each sub-item and avoid moveGlyphData()
241+where possible (ie. when there are no glyph indexes to care about).
242+Also don't memmove data we didn't ever initialize.
243+
244+Change-Id: Ib8e5fd937a10e4e3c8c0e18961a2e2c1a4167924
245+---
246+ src/gui/text/qtextengine.cpp | 79 ++++++++++++++++++++------------------------
247+ 1 file changed, 36 insertions(+), 43 deletions(-)
248+
249+diff --git a/src/gui/text/qtextengine.cpp b/src/gui/text/qtextengine.cpp
250+index 607fe95..febdaaa 100644
251+--- a/src/gui/text/qtextengine.cpp
252++++ b/src/gui/text/qtextengine.cpp
253+@@ -918,12 +918,9 @@ void QTextEngine::shapeText(int item) const
254+ QFontEngine *fontEngine = this->fontEngine(si, &si.ascent, &si.descent, &si.leading);
255+
256+ // split up the item into parts that come from different font engines
257++ // k * 3 entries, array[k] == index in string, array[k + 1] == index in glyphs, array[k + 2] == engine index
258+ QVector<uint> itemBoundaries;
259+- itemBoundaries.reserve(16);
260+- // k * 2 entries, array[k] == index in string, array[k + 1] == index in glyphs
261+- itemBoundaries.append(0);
262+- itemBoundaries.append(0);
263+-
264++ itemBoundaries.reserve(24);
265+ if (fontEngine->type() == QFontEngine::Multi) {
266+ // ask the font engine to find out which glyphs (as an index in the specific font)
267+ // to use for the text in one item.
268+@@ -947,22 +944,31 @@ void QTextEngine::shapeText(int item) const
269+ }
270+ }
271+
272+- uint lastEngine = 0;
273++ uint lastEngine = ~0u;
274+ for (int i = 0, glyph_pos = 0; i < itemLength; ++i, ++glyph_pos) {
275+ const uint engineIdx = initialGlyphs.glyphs[glyph_pos] >> 24;
276+- if (lastEngine != engineIdx && glyph_pos > 0) {
277++ if (lastEngine != engineIdx) {
278+ itemBoundaries.append(i);
279+ itemBoundaries.append(glyph_pos);
280++ itemBoundaries.append(engineIdx);
281++
282++ if (engineIdx != 0) {
283++ QFontEngine *actualFontEngine = static_cast<QFontEngineMulti *>(fontEngine)->engine(engineIdx);
284++ si.ascent = qMax(actualFontEngine->ascent(), si.ascent);
285++ si.descent = qMax(actualFontEngine->descent(), si.descent);
286++ si.leading = qMax(actualFontEngine->leading(), si.leading);
287++ }
288+
289+- QFontEngine *actualFontEngine = static_cast<QFontEngineMulti *>(fontEngine)->engine(engineIdx);
290+- si.ascent = qMax(actualFontEngine->ascent(), si.ascent);
291+- si.descent = qMax(actualFontEngine->descent(), si.descent);
292+- si.leading = qMax(actualFontEngine->leading(), si.leading);
293++ lastEngine = engineIdx;
294+ }
295+- lastEngine = engineIdx;
296++
297+ if (QChar::isHighSurrogate(string[i]) && i + 1 < itemLength && QChar::isLowSurrogate(string[i + 1]))
298+ ++i;
299+ }
300++ } else {
301++ itemBoundaries.append(0);
302++ itemBoundaries.append(0);
303++ itemBoundaries.append(0);
304+ }
305+
306+ bool kerningEnabled;
307+@@ -1039,16 +1045,6 @@ void QTextEngine::shapeText(int item) const
308+ si.width += glyphs.advances_x[i] * !glyphs.attributes[i].dontPrint;
309+ }
310+
311+-static inline void moveGlyphData(const QGlyphLayout &destination, const QGlyphLayout &source, int num)
312+-{
313+- if (num > 0 && destination.glyphs != source.glyphs) {
314+- memmove(destination.glyphs, source.glyphs, num * sizeof(glyph_t));
315+- memmove(destination.attributes, source.attributes, num * sizeof(QGlyphAttributes));
316+- memmove(destination.advances_x, source.advances_x, num * sizeof(QFixed));
317+- memmove(destination.offsets, source.offsets, num * sizeof(QFixedPoint));
318+- }
319+-}
320+-
321+ #ifdef QT_ENABLE_HARFBUZZ_NG
322+
323+ QT_BEGIN_INCLUDE_NAMESPACE
324+@@ -1075,20 +1071,15 @@ int QTextEngine::shapeTextWithHarfbuzzNG(const QScriptItem &si, const ushort *st
325+ uint glyphs_shaped = 0;
326+ int remaining_glyphs = itemLength;
327+
328+- for (int k = 0; k < itemBoundaries.size(); k += 2) { // for the +2, see the comment at the definition of itemBoundaries
329++ for (int k = 0; k < itemBoundaries.size(); k += 3) {
330+ uint item_pos = itemBoundaries[k];
331+- uint item_length = itemLength;
332++ uint item_length = (k + 4 < itemBoundaries.size() ? itemBoundaries[k + 3] : itemLength) - item_pos;
333+ uint item_glyph_pos = itemBoundaries[k + 1];
334+- if (k + 3 < itemBoundaries.size())
335+- item_length = itemBoundaries[k + 2];
336+- item_length -= item_pos;
337++ uint engineIdx = itemBoundaries[k + 2];
338+
339+ QFontEngine *actualFontEngine = fontEngine;
340+- uint engineIdx = 0;
341+- if (fontEngine->type() == QFontEngine::Multi) {
342+- engineIdx = availableGlyphs(&si).glyphs[glyphs_shaped] >> 24;
343++ if (fontEngine->type() == QFontEngine::Multi)
344+ actualFontEngine = static_cast<QFontEngineMulti *>(fontEngine)->engine(engineIdx);
345+- }
346+
347+
348+ // prepare buffer
349+@@ -1138,8 +1129,6 @@ int QTextEngine::shapeTextWithHarfbuzzNG(const QScriptItem &si, const ushort *st
350+
351+ // fetch the shaped glyphs and metrics
352+ QGlyphLayout g = availableGlyphs(&si).mid(glyphs_shaped, num_glyphs);
353+- if (num_glyphs != item_glyph_pos)
354+- moveGlyphData(g.mid(num_glyphs), g.mid(item_glyph_pos), remaining_glyphs);
355+ ushort *log_clusters = logClusters(&si) + item_pos;
356+
357+ hb_glyph_info_t *infos = hb_buffer_get_glyph_infos(buffer, 0);
358+@@ -1196,6 +1185,12 @@ Q_STATIC_ASSERT(sizeof(HB_GlyphAttributes) == sizeof(QGlyphAttributes));
359+ Q_STATIC_ASSERT(sizeof(HB_Fixed) == sizeof(QFixed));
360+ Q_STATIC_ASSERT(sizeof(HB_FixedPoint) == sizeof(QFixedPoint));
361+
362++static inline void moveGlyphData(const QGlyphLayout &destination, const QGlyphLayout &source, int num)
363++{
364++ if (num > 0 && destination.glyphs != source.glyphs)
365++ memmove(destination.glyphs, source.glyphs, num * sizeof(glyph_t));
366++}
367++
368+ int QTextEngine::shapeTextWithHarfbuzz(const QScriptItem &si, const ushort *string, int itemLength, QFontEngine *fontEngine, const QVector<uint> &itemBoundaries, bool kerningEnabled) const
369+ {
370+ HB_ShaperItem entire_shaper_item;
371+@@ -1224,14 +1219,12 @@ int QTextEngine::shapeTextWithHarfbuzz(const QScriptItem &si, const ushort *stri
372+ int remaining_glyphs = entire_shaper_item.num_glyphs;
373+ int glyph_pos = 0;
374+ // for each item shape using harfbuzz and store the results in our layoutData's glyphs array.
375+- for (int k = 0; k < itemBoundaries.size(); k += 2) { // for the +2, see the comment at the definition of itemBoundaries
376+-
377++ for (int k = 0; k < itemBoundaries.size(); k += 3) {
378+ HB_ShaperItem shaper_item = entire_shaper_item;
379+-
380+ shaper_item.item.pos = itemBoundaries[k];
381+- if (k < itemBoundaries.size() - 3) {
382+- shaper_item.item.length = itemBoundaries[k + 2] - shaper_item.item.pos;
383+- shaper_item.num_glyphs = itemBoundaries[k + 3] - itemBoundaries[k + 1];
384++ if (k + 4 < itemBoundaries.size()) {
385++ shaper_item.item.length = itemBoundaries[k + 3] - shaper_item.item.pos;
386++ shaper_item.num_glyphs = itemBoundaries[k + 4] - itemBoundaries[k + 1];
387+ } else { // last combo in the list, avoid out of bounds access.
388+ shaper_item.item.length -= shaper_item.item.pos - entire_shaper_item.item.pos;
389+ shaper_item.num_glyphs -= itemBoundaries[k + 1];
390+@@ -1240,10 +1233,9 @@ int QTextEngine::shapeTextWithHarfbuzz(const QScriptItem &si, const ushort *stri
391+ if (shaper_item.num_glyphs < shaper_item.item.length)
392+ shaper_item.num_glyphs = shaper_item.item.length;
393+
394++ uint engineIdx = itemBoundaries[k + 2];
395+ QFontEngine *actualFontEngine = fontEngine;
396+- uint engineIdx = 0;
397+ if (fontEngine->type() == QFontEngine::Multi) {
398+- engineIdx = uint(availableGlyphs(&si).glyphs[glyph_pos] >> 24);
399+ actualFontEngine = static_cast<QFontEngineMulti *>(fontEngine)->engine(engineIdx);
400+
401+ shaper_item.glyphIndicesPresent = true;
402+@@ -1259,7 +1251,7 @@ int QTextEngine::shapeTextWithHarfbuzz(const QScriptItem &si, const ushort *stri
403+ return 0;
404+
405+ const QGlyphLayout g = availableGlyphs(&si).mid(glyph_pos);
406+- if (shaper_item.num_glyphs > shaper_item.item.length)
407++ if (fontEngine->type() == QFontEngine::Multi && shaper_item.num_glyphs > shaper_item.item.length)
408+ moveGlyphData(g.mid(shaper_item.num_glyphs), g.mid(shaper_item.initialGlyphCount), remaining_glyphs);
409+
410+ shaper_item.glyphs = reinterpret_cast<HB_Glyph *>(g.glyphs);
411+@@ -1276,7 +1268,8 @@ int QTextEngine::shapeTextWithHarfbuzz(const QScriptItem &si, const ushort *stri
412+ } while (!qShapeItem(&shaper_item)); // this does the actual shaping via harfbuzz.
413+
414+ QGlyphLayout g = availableGlyphs(&si).mid(glyph_pos, shaper_item.num_glyphs);
415+- moveGlyphData(g.mid(shaper_item.num_glyphs), g.mid(shaper_item.initialGlyphCount), remaining_glyphs);
416++ if (fontEngine->type() == QFontEngine::Multi)
417++ moveGlyphData(g.mid(shaper_item.num_glyphs), g.mid(shaper_item.initialGlyphCount), remaining_glyphs);
418+
419+ for (quint32 i = 0; i < shaper_item.item.length; ++i)
420+ shaper_item.log_clusters[i] += glyph_pos;
421+--
422+1.9.0
423+
424
425=== modified file 'debian/patches/series'
426--- debian/patches/series 2014-03-18 05:45:20 +0000
427+++ debian/patches/series 2014-03-18 11:57:21 +0000
428@@ -24,3 +24,7 @@
429 Add-workaround-for-GL-on-Android-emulator.patch
430
431 enable-tests.patch
432+Fix-access-after-delete-with-Harfbuzz-NG-code-path.patch
433+Fix-log_clusters-calculation-in-HarfBuzz-NG-code-pat.patch
434+Minor-optimization-for-QTextEngine-shapeText.patch
435+HarfBuzz-NG-Hide-characters-that-should-normally-be-.patch

Subscribers

People subscribed via source and target branches