Merge lp:~ubuntu-sdk-team/ubuntu-ui-toolkit/trunk-fix-icon-svg-image-loading into lp:ubuntu-ui-toolkit/staging
- trunk-fix-icon-svg-image-loading
- Merge into staging
Status: | Rejected | ||||||||
---|---|---|---|---|---|---|---|---|---|
Rejected by: | Michał Sawicz | ||||||||
Proposed branch: | lp:~ubuntu-sdk-team/ubuntu-ui-toolkit/trunk-fix-icon-svg-image-loading | ||||||||
Merge into: | lp:ubuntu-ui-toolkit/staging | ||||||||
Diff against target: |
280 lines (+77/-66) 3 files modified
src/Ubuntu/Components/plugin/unitythemeiconprovider.cpp (+61/-51) src/Ubuntu/Components/plugin/unitythemeiconprovider.h (+1/-1) tests/unit_x11/tst_iconprovider/tst_iconprovider.cpp (+15/-14) |
||||||||
To merge this branch: | bzr merge lp:~ubuntu-sdk-team/ubuntu-ui-toolkit/trunk-fix-icon-svg-image-loading | ||||||||
Related bugs: |
|
Reviewer | Review Type | Date Requested | Status |
---|---|---|---|
Michał Sawicz | Disapprove | ||
ubuntu-sdk-build-bot | continuous-integration | Approve | |
Review via email: mp+292509@code.launchpad.net |
Commit message
Adjust the UnityThemeIconP
Description of the change
The Pixmap->Image thing might be unnecessary, but
1) I wanted to duplicate exactly Qt's behaviour and
2) Qt converts the QPixmap to a QImage internally before uploading to texture
ubuntu-sdk-build-bot (ubuntu-sdk-build-bot) wrote : | # |
ubuntu-sdk-build-bot (ubuntu-sdk-build-bot) wrote : | # |
FAILED: Continuous integration, rev:1282
https:/
Executed test runs:
None: https:/
Click here to trigger a rebuild:
https:/
ubuntu-sdk-build-bot (ubuntu-sdk-build-bot) wrote : | # |
PASSED: Continuous integration, rev:1282
https:/
Executed test runs:
None: https:/
Click here to trigger a rebuild:
https:/
ubuntu-sdk-build-bot (ubuntu-sdk-build-bot) wrote : | # |
FAILED: Continuous integration, rev:1282
https:/
Executed test runs:
None: https:/
Click here to trigger a rebuild:
https:/
ubuntu-sdk-build-bot (ubuntu-sdk-build-bot) wrote : | # |
FAILED: Continuous integration, rev:1282
https:/
Executed test runs:
SUCCESS: https:/
deb: https:/
FAILURE: https:/
FAILURE: https:/
FAILURE: https:/
None: https:/
SUCCESS: https:/
SUCCESS: https:/
SUCCESS: https:/
SUCCESS: https:/
Click here to trigger a rebuild:
https:/
- 1283. By Michał Sawicz
-
Make tst_IconProvider talk in QImage
ubuntu-sdk-build-bot (ubuntu-sdk-build-bot) wrote : | # |
FAILED: Continuous integration, rev:1283
https:/
Executed test runs:
None: https:/
Click here to trigger a rebuild:
https:/
ubuntu-sdk-build-bot (ubuntu-sdk-build-bot) wrote : | # |
FAILED: Continuous integration, rev:1283
https:/
Executed test runs:
None: https:/
Click here to trigger a rebuild:
https:/
ubuntu-sdk-build-bot (ubuntu-sdk-build-bot) wrote : | # |
FAILED: Continuous integration, rev:1283
https:/
Executed test runs:
None: https:/
Click here to trigger a rebuild:
https:/
ubuntu-sdk-build-bot (ubuntu-sdk-build-bot) wrote : | # |
PASSED: Continuous integration, rev:1283
https:/
Executed test runs:
None: https:/
Click here to trigger a rebuild:
https:/
ubuntu-sdk-build-bot (ubuntu-sdk-build-bot) wrote : | # |
FAILED: Continuous integration, rev:1283
https:/
Executed test runs:
SUCCESS: https:/
deb: https:/
FAILURE: https:/
FAILURE: https:/
FAILURE: https:/
None: https:/
SUCCESS: https:/
SUCCESS: https:/
SUCCESS: https:/
SUCCESS: https:/
Click here to trigger a rebuild:
https:/
- 1284. By Lukáš Tinkl
-
fix loading & scaling SVGs
ubuntu-sdk-build-bot (ubuntu-sdk-build-bot) wrote : | # |
PASSED: Continuous integration, rev:1284
https:/
Executed test runs:
None: https:/
Click here to trigger a rebuild:
https:/
ubuntu-sdk-build-bot (ubuntu-sdk-build-bot) wrote : | # |
PASSED: Continuous integration, rev:1284
https:/
Executed test runs:
None: https:/
Click here to trigger a rebuild:
https:/
ubuntu-sdk-build-bot (ubuntu-sdk-build-bot) wrote : | # |
PASSED: Continuous integration, rev:1284
https:/
Executed test runs:
None: https:/
Click here to trigger a rebuild:
https:/
ubuntu-sdk-build-bot (ubuntu-sdk-build-bot) wrote : | # |
PASSED: Continuous integration, rev:1284
https:/
Executed test runs:
None: https:/
Click here to trigger a rebuild:
https:/
ubuntu-sdk-build-bot (ubuntu-sdk-build-bot) wrote : | # |
PASSED: Continuous integration, rev:1284
https:/
Executed test runs:
SUCCESS: https:/
deb: https:/
SUCCESS: https:/
SUCCESS: https:/
SUCCESS: https:/
None: https:/
SUCCESS: https:/
SUCCESS: https:/
SUCCESS: https:/
SUCCESS: https:/
Click here to trigger a rebuild:
https:/
- 1285. By Lukáš Tinkl
-
add a test with wrong aspect ratio that returns a correct one
- 1286. By Lukáš Tinkl
-
add a test that passes here and fails with trunk
ubuntu-sdk-build-bot (ubuntu-sdk-build-bot) wrote : | # |
PASSED: Continuous integration, rev:1286
https:/
Executed test runs:
None: https:/
Click here to trigger a rebuild:
https:/
ubuntu-sdk-build-bot (ubuntu-sdk-build-bot) wrote : | # |
PASSED: Continuous integration, rev:1286
https:/
Executed test runs:
None: https:/
Click here to trigger a rebuild:
https:/
ubuntu-sdk-build-bot (ubuntu-sdk-build-bot) wrote : | # |
PASSED: Continuous integration, rev:1286
https:/
Executed test runs:
None: https:/
Click here to trigger a rebuild:
https:/
ubuntu-sdk-build-bot (ubuntu-sdk-build-bot) wrote : | # |
PASSED: Continuous integration, rev:1286
https:/
Executed test runs:
None: https:/
Click here to trigger a rebuild:
https:/
ubuntu-sdk-build-bot (ubuntu-sdk-build-bot) wrote : | # |
PASSED: Continuous integration, rev:1286
https:/
Executed test runs:
SUCCESS: https:/
deb: https:/
SUCCESS: https:/
SUCCESS: https:/
SUCCESS: https:/
None: https:/
SUCCESS: https:/
SUCCESS: https:/
SUCCESS: https:/
SUCCESS: https:/
Click here to trigger a rebuild:
https:/
Unmerged revisions
Preview Diff
1 | === modified file 'src/Ubuntu/Components/plugin/unitythemeiconprovider.cpp' |
2 | --- src/Ubuntu/Components/plugin/unitythemeiconprovider.cpp 2016-03-16 14:24:15 +0000 |
3 | +++ src/Ubuntu/Components/plugin/unitythemeiconprovider.cpp 2016-04-27 16:15:41 +0000 |
4 | @@ -21,8 +21,7 @@ |
5 | #include <QDir> |
6 | #include <QFileInfo> |
7 | #include <QSettings> |
8 | -#include <QSvgRenderer> |
9 | -#include <QPainter> |
10 | +#include <QImageReader> |
11 | #include <QStandardPaths> |
12 | #include <QtDebug> |
13 | |
14 | @@ -48,27 +47,27 @@ |
15 | // Does a breadth-first search for an icon with any name in @names. Parent |
16 | // themes are only looked at if the current theme doesn't contain any icon |
17 | // in @names. |
18 | - QPixmap findBestIcon(const QStringList &names, const QSize &size, QSet<QString> *alreadySearchedThemes) |
19 | + QImage findBestIcon(const QStringList &names, QSize *impsize, const QSize &size, QSet<QString> *alreadySearchedThemes) |
20 | { |
21 | if (alreadySearchedThemes) { |
22 | if (alreadySearchedThemes->contains(name)) |
23 | - return QPixmap(); |
24 | + return QImage(); |
25 | alreadySearchedThemes->insert(name); |
26 | } |
27 | |
28 | Q_FOREACH(const QString &name, names) { |
29 | - QPixmap pixmap = lookupIcon(name, size); |
30 | - if (!pixmap.isNull()) |
31 | - return pixmap; |
32 | + QImage image = lookupIcon(name, impsize, size); |
33 | + if (!image.isNull()) |
34 | + return image; |
35 | } |
36 | |
37 | Q_FOREACH(IconThemePointer theme, parents) { |
38 | - QPixmap pixmap = theme->findBestIcon(names, size, alreadySearchedThemes); |
39 | - if (!pixmap.isNull()) |
40 | - return pixmap; |
41 | + QImage image = theme->findBestIcon(names, impsize, size, alreadySearchedThemes); |
42 | + if (!image.isNull()) |
43 | + return image; |
44 | } |
45 | |
46 | - return QPixmap(); |
47 | + return QImage(); |
48 | } |
49 | |
50 | private: |
51 | @@ -82,7 +81,7 @@ |
52 | |
53 | IconTheme(const QString &name): name(name) |
54 | { |
55 | - QStringList paths = QStandardPaths::standardLocations(QStandardPaths::GenericDataLocation); |
56 | + const QStringList paths = QStandardPaths::standardLocations(QStandardPaths::GenericDataLocation); |
57 | |
58 | Q_FOREACH(const QString &path, paths) { |
59 | QDir dir(path + "/icons/" + name); |
60 | @@ -130,30 +129,42 @@ |
61 | return Fixed; |
62 | } |
63 | |
64 | - static QPixmap loadIcon(const QString &filename, const QSize &size) |
65 | + static QImage loadIcon(const QString &filename, QSize *impsize, const QSize &requestSize) |
66 | { |
67 | - QPixmap pixmap; |
68 | - |
69 | - const bool anyZero = size.width() <= 0 || size.height() <= 0; |
70 | - const Qt::AspectRatioMode scaleMode = anyZero ? Qt::KeepAspectRatioByExpanding : Qt::KeepAspectRatio; |
71 | - |
72 | - if (filename.endsWith(QLatin1String(".png"))) { |
73 | - pixmap = QPixmap(filename); |
74 | - if (!pixmap.isNull() && !size.isNull() && (pixmap.width() != size.width() || pixmap.height() != size.height())) { |
75 | - const QSize newSize = pixmap.size().scaled(size.width(), size.height(), scaleMode); |
76 | - pixmap = pixmap.scaled(newSize); |
77 | - } |
78 | - } |
79 | - else if (filename.endsWith(QLatin1String(".svg"))) { |
80 | - QSvgRenderer renderer(filename); |
81 | - pixmap = QPixmap(renderer.defaultSize().scaled(size.width(), size.height(), scaleMode)); |
82 | - pixmap.fill(Qt::transparent); |
83 | - QPainter painter(&pixmap); |
84 | - renderer.render(&painter); |
85 | - painter.end(); |
86 | - } |
87 | - |
88 | - return pixmap; |
89 | + QImage image; |
90 | + QImageReader imgio(filename); |
91 | + |
92 | + const bool force_scale = imgio.format() == QStringLiteral("svg") |
93 | + || imgio.format() == QStringLiteral("svgz"); |
94 | + |
95 | + if (requestSize.width() > 0 || requestSize.height() > 0) { |
96 | + QSize s = imgio.size(); |
97 | + qreal ratio = 0.0; |
98 | + if (requestSize.width() > 0 && (force_scale || requestSize.width() < s.width())) { |
99 | + ratio = qreal(requestSize.width())/s.width(); |
100 | + } |
101 | + if (requestSize.height() > 0 && (force_scale || requestSize.height() < s.height())) { |
102 | + qreal hr = qreal(requestSize.height())/s.height(); |
103 | + if (ratio == 0.0 || hr < ratio) |
104 | + ratio = hr; |
105 | + } |
106 | + if (ratio > 0.0) { |
107 | + s.setHeight(qRound(s.height() * ratio)); |
108 | + s.setWidth(qRound(s.width() * ratio)); |
109 | + imgio.setScaledSize(s); |
110 | + } |
111 | + } |
112 | + |
113 | + if (impsize) |
114 | + *impsize = imgio.scaledSize(); |
115 | + |
116 | + if (imgio.read(&image)) { |
117 | + if (impsize) |
118 | + *impsize = image.size(); |
119 | + return image; |
120 | + } else { |
121 | + return QImage(); |
122 | + } |
123 | } |
124 | |
125 | QString lookupIconFile(const QString &dir, const QString &name) |
126 | @@ -174,16 +185,16 @@ |
127 | return QString(); |
128 | } |
129 | |
130 | - QPixmap lookupIcon(const QString &iconName, const QSize &size) |
131 | + QImage lookupIcon(const QString &iconName, QSize *impsize, const QSize &size) |
132 | { |
133 | const int iconSize = qMax(size.width(), size.height()); |
134 | if (iconSize > 0) |
135 | - return lookupBestMatchingIcon(iconName, size); |
136 | + return lookupBestMatchingIcon(iconName, impsize, size); |
137 | else |
138 | - return lookupLargestIcon(iconName); |
139 | + return lookupLargestIcon(iconName, impsize); |
140 | } |
141 | |
142 | - QPixmap lookupBestMatchingIcon(const QString &iconName, const QSize &size) |
143 | + QImage lookupBestMatchingIcon(const QString &iconName, QSize *impsize, const QSize &size) |
144 | { |
145 | int minDistance = 10000; |
146 | QString bestFilename; |
147 | @@ -205,12 +216,12 @@ |
148 | } |
149 | |
150 | if (!bestFilename.isNull()) |
151 | - return loadIcon(bestFilename, size); |
152 | + return loadIcon(bestFilename, impsize, size); |
153 | |
154 | - return QPixmap(); |
155 | + return QImage(); |
156 | } |
157 | |
158 | - QPixmap lookupLargestIcon(const QString &iconName) |
159 | + QImage lookupLargestIcon(const QString &iconName, QSize *impsize) |
160 | { |
161 | int maxSize = 0; |
162 | QString bestFilename; |
163 | @@ -228,9 +239,9 @@ |
164 | } |
165 | |
166 | if (!bestFilename.isNull()) |
167 | - return loadIcon(bestFilename, QSize(maxSize, maxSize)); |
168 | + return loadIcon(bestFilename, impsize, QSize(maxSize, maxSize)); |
169 | |
170 | - return QPixmap(); |
171 | + return QImage(); |
172 | } |
173 | |
174 | int directorySizeDistance(const Directory &dir, const QSize &iconSize) |
175 | @@ -258,24 +269,23 @@ |
176 | }; |
177 | |
178 | UnityThemeIconProvider::UnityThemeIconProvider(const QString &themeName): |
179 | - QQuickImageProvider(QQuickImageProvider::Pixmap) |
180 | + QQuickImageProvider(QQuickImageProvider::Image) |
181 | { |
182 | theme = IconTheme::get(themeName); |
183 | } |
184 | |
185 | -QPixmap UnityThemeIconProvider::requestPixmap(const QString &id, QSize *size, const QSize &requestedSize) |
186 | +QImage UnityThemeIconProvider::requestImage(const QString &id, QSize *size, const QSize &requestedSize) |
187 | { |
188 | // The hicolor theme will be searched last as per |
189 | // https://specifications.freedesktop.org/icon-theme-spec/icon-theme-spec-latest.html |
190 | QSet<QString> alreadySearchedThemes; |
191 | const QStringList names = id.split(QLatin1Char(','), QString::SkipEmptyParts); |
192 | - QPixmap pixmap = theme->findBestIcon(names, requestedSize, &alreadySearchedThemes); |
193 | + QImage image = theme->findBestIcon(names, size, requestedSize, &alreadySearchedThemes); |
194 | |
195 | - if (pixmap.isNull()) { |
196 | + if (image.isNull()) { |
197 | IconTheme::IconThemePointer theme = IconTheme::get(QStringLiteral("hicolor")); |
198 | - return theme->findBestIcon(names, requestedSize, nullptr); |
199 | + return theme->findBestIcon(names, size, requestedSize, nullptr); |
200 | } |
201 | |
202 | - *size = pixmap.size(); |
203 | - return pixmap; |
204 | + return image; |
205 | } |
206 | |
207 | === modified file 'src/Ubuntu/Components/plugin/unitythemeiconprovider.h' |
208 | --- src/Ubuntu/Components/plugin/unitythemeiconprovider.h 2016-03-16 14:24:15 +0000 |
209 | +++ src/Ubuntu/Components/plugin/unitythemeiconprovider.h 2016-04-27 16:15:41 +0000 |
210 | @@ -25,7 +25,7 @@ |
211 | { |
212 | public: |
213 | UnityThemeIconProvider(const QString &themeName = QStringLiteral("suru")); |
214 | - QPixmap requestPixmap(const QString &id, QSize *size, const QSize &requestedSize); |
215 | + QImage requestImage(const QString &id, QSize *size, const QSize &requestedSize); |
216 | |
217 | private: |
218 | QSharedPointer<class IconTheme> theme; |
219 | |
220 | === modified file 'tests/unit_x11/tst_iconprovider/tst_iconprovider.cpp' |
221 | --- tests/unit_x11/tst_iconprovider/tst_iconprovider.cpp 2016-03-16 15:02:35 +0000 |
222 | +++ tests/unit_x11/tst_iconprovider/tst_iconprovider.cpp 2016-04-27 16:15:41 +0000 |
223 | @@ -39,14 +39,15 @@ |
224 | QTest::addColumn<QSize>("requestSize"); |
225 | QTest::addColumn<QSize>("resultSize"); |
226 | |
227 | - QTest::newRow("battery0") << "battery-100-charging" << QSize(-1, -1) << QSize(256, 165); |
228 | - QTest::newRow("battery1") << "battery-100-charging" << QSize(-1, 16) << QSize(24, 16); |
229 | + QTest::newRow("battery0") << "battery-100-charging" << QSize(-1, -1) << QSize(256, 166); |
230 | + QTest::newRow("battery1") << "battery-100-charging" << QSize(-1, 16) << QSize(25, 16); |
231 | QTest::newRow("battery2") << "battery-100-charging" << QSize(16, -1) << QSize(16, 10); |
232 | - QTest::newRow("battery3") << "battery-100-charging" << QSize(0, 16) << QSize(24, 16); |
233 | + QTest::newRow("battery3") << "battery-100-charging" << QSize(0, 16) << QSize(25, 16); |
234 | QTest::newRow("battery4") << "battery-100-charging" << QSize(16, 0) << QSize(16, 10); |
235 | QTest::newRow("battery5") << "battery-100-charging" << QSize(24, 16) << QSize(24, 16); |
236 | - QTest::newRow("battery6") << "battery-100-charging" << QSize(24, 24) << QSize(24, 15); |
237 | + QTest::newRow("battery6") << "battery-100-charging" << QSize(24, 24) << QSize(24, 16); |
238 | QTest::newRow("battery7") << "battery-100-charging" << QSize(37, 24) << QSize(37, 24); |
239 | + QTest::newRow("battery8") << "battery-100-charging" << QSize(15, 512) << QSize(15, 10); |
240 | |
241 | QTest::newRow("gallery0") << "gallery-app" << QSize(-1, -1) << QSize(512, 512); |
242 | QTest::newRow("gallery1") << "gallery-app" << QSize(-1, 16) << QSize(16, 16); |
243 | @@ -65,13 +66,13 @@ |
244 | |
245 | UnityThemeIconProvider provider("mockTheme"); |
246 | QSize returnedSize; |
247 | - QPixmap p = provider.requestPixmap(icon, &returnedSize, requestSize); |
248 | - QCOMPARE(p.size(), resultSize); |
249 | + QImage i = provider.requestImage(icon, &returnedSize, requestSize); |
250 | + QCOMPARE(i.size(), resultSize); |
251 | QCOMPARE(returnedSize, resultSize); |
252 | |
253 | // Search again to make sure subsequent searches still work |
254 | - p = provider.requestPixmap(icon, &returnedSize, requestSize); |
255 | - QCOMPARE(p.size(), resultSize); |
256 | + i = provider.requestImage(icon, &returnedSize, requestSize); |
257 | + QCOMPARE(i.size(), resultSize); |
258 | QCOMPARE(returnedSize, resultSize); |
259 | } |
260 | |
261 | @@ -82,14 +83,14 @@ |
262 | |
263 | // myapp is in MockTheme3 (white) and hicolor (black) |
264 | // MockTheme3 one is returned since hicolor is last per spec |
265 | - QPixmap p = provider.requestPixmap("myapp", &returnedSize, QSize(-1, -1)); |
266 | - QVERIFY(!p.isNull()); |
267 | - QCOMPARE(QColor(p.toImage().pixel(0,0)), QColor(Qt::white)); |
268 | + QImage i = provider.requestImage("myapp", &returnedSize, QSize(-1, -1)); |
269 | + QVERIFY(!i.isNull()); |
270 | + QCOMPARE(QColor(i.pixel(0,0)), QColor(Qt::white)); |
271 | |
272 | // myapp2 is only in hicolor (black) so that's the one returned |
273 | - p = provider.requestPixmap("myapp2", &returnedSize, QSize(-1, -1)); |
274 | - QVERIFY(!p.isNull()); |
275 | - QCOMPARE(QColor(p.toImage().pixel(0,0)), QColor(Qt::black)); |
276 | + i = provider.requestImage("myapp2", &returnedSize, QSize(-1, -1)); |
277 | + QVERIFY(!i.isNull()); |
278 | + QCOMPARE(QColor(i.pixel(0,0)), QColor(Qt::black)); |
279 | } |
280 | }; |
281 |
FAILED: Continuous integration, rev:1282 /jenkins. ubuntu. com/ubuntu- sdk/job/ ubuntu- ui-toolkit- ci-amd64- devel/501/ /jenkins. ubuntu. com/ubuntu- sdk/job/ generic- update- mp/2794/ console
https:/
Executed test runs:
None: https:/
Click here to trigger a rebuild: /jenkins. ubuntu. com/ubuntu- sdk/job/ ubuntu- ui-toolkit- ci-amd64- devel/501/ rebuild
https:/