Skip to content

Commit fa157b0

Browse files
committedMar 14, 2014
Add composer svg export label unit tests
- Fix composer composition setup to near identical output of canvas->image (finally, expect for symbology, which still seems to be double-antialiased) - Rebuild control images for composer->image output
1 parent b6b78ca commit fa157b0

File tree

21 files changed

+73
-48
lines changed

21 files changed

+73
-48
lines changed
 

‎tests/src/python/test_qgspallabeling_composer.py

Lines changed: 60 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -94,44 +94,50 @@ def setUp(self):
9494

9595
def _set_up_composition(self, width, height, dpi):
9696
# set up composition and add map
97-
# TODO: how to keep embedded map from being anti-aliased twice?
98-
# self._MapSettings.setFlag(QgsMapSettings.Antialiasing, False)
99-
# self._MapSettings.setFlag(QgsMapSettings.UseAdvancedEffects, True)
97+
self._TestMapSettings.setFlag(QgsMapSettings.Antialiasing, True)
98+
self._TestMapSettings.setFlag(QgsMapSettings.UseAdvancedEffects, True)
99+
self._TestMapSettings.setFlag(QgsMapSettings.ForceVectorOutput, True)
100100
self._c = QgsComposition(self._TestMapSettings)
101101
""":type: QgsComposition"""
102+
# self._c.setUseAdvancedEffects(False)
102103
self._c.setPrintResolution(dpi)
103104
# 600 x 400 px = 211.67 x 141.11 mm @ 72 dpi
104-
# TODO: figure out why this doesn't work and needs fudging
105-
# probably need sets of fudgyness per dpi group (72, 150, 300)?
106-
paperw = round((width * 25.4 / dpi) + 0.05, 0)
107-
paperh = round((height * 25.4 / dpi) + 0.05, 1)
105+
paperw = width * 25.4 / dpi
106+
paperh = height * 25.4 / dpi
108107
self._c.setPaperSize(paperw, paperh)
109-
self._cmap = QgsComposerMap(
110-
self._c, 0, 0, self._c.paperWidth(), self._c.paperHeight())
108+
# NOTE: do not use QgsComposerMap(self._c, 0, 0, paperw, paperh) since
109+
# it only takes integers as parameters and the composition will grow
110+
# larger based upon union of item scene rectangles and a slight buffer
111+
# see end of QgsComposition::compositionBounds()
112+
# add map as small graphics item first, then set its scene QRectF later
113+
self._cmap = QgsComposerMap(self._c, 10, 10, 10, 10)
111114
""":type: QgsComposerMap"""
115+
self._cmap.setPreviewMode(QgsComposerMap.Render)
112116
self._cmap.setFrameEnabled(False)
113-
self._cmap.setNewExtent(self.aoiExtent())
114117
self._c.addComposerMap(self._cmap)
118+
# now expand map to fill page and set its extent
119+
self._cmap.setSceneRect(QRectF(0, 0, paperw, paperw))
120+
self._cmap.setNewExtent(self.aoiExtent())
121+
# self._cmap.updateCachedImage()
115122
self._c.setPlotStyle(QgsComposition.Print)
116123

117124
# noinspection PyUnusedLocal
118125
def _get_composer_image(self, width, height, dpi):
119-
image = QImage(QSize(width, height), QImage.Format_ARGB32)
120-
image.fill(QColor(152, 219, 249).rgb())
121-
image.setDotsPerMeterX(dpi / 25.4 * 1000)
122-
image.setDotsPerMeterY(dpi / 25.4 * 1000)
123-
124-
p = QPainter(image)
125-
p.setRenderHint(QPainter.Antialiasing, True)
126-
p.setRenderHint(QPainter.HighQualityAntialiasing, True)
127-
self._c.renderPage(p, 0)
128-
p.end()
129-
130-
# image = self._c.printPageAsRaster(0)
131-
# """:type: QImage"""
126+
# image = QImage(QSize(width, height), QImage.Format_ARGB32)
127+
# image.fill(QColor(152, 219, 249).rgb())
128+
# image.setDotsPerMeterX(dpi / 25.4 * 1000)
129+
# image.setDotsPerMeterY(dpi / 25.4 * 1000)
130+
#
131+
# p = QPainter(image)
132+
# p.setRenderHint(QPainter.Antialiasing, False)
133+
# p.setRenderHint(QPainter.HighQualityAntialiasing, False)
134+
# self._c.renderPage(p, 0)
135+
# p.end()
136+
137+
image = self._c.printPageAsRaster(0)
138+
""":type: QImage"""
132139

133140
if image.isNull():
134-
# something went pear-shaped
135141
return False, ''
136142

137143
filepath = getTempfilePath('png')
@@ -144,31 +150,23 @@ def _get_composer_image(self, width, height, dpi):
144150

145151
def _get_composer_svg_image(self, width, height, dpi):
146152
# from qgscomposer.cpp, QgsComposer::on_mActionExportAsSVG_triggered,
147-
# line 1909, near end of function
153+
# near end of function
148154
svgpath = getTempfilePath('svg')
149155
temp_size = os.path.getsize(svgpath)
150156

151157
svg_g = QSvgGenerator()
152158
# noinspection PyArgumentList
153159
svg_g.setTitle(QgsProject.instance().title())
154160
svg_g.setFileName(svgpath)
155-
# width and height in pixels
156-
# svg_w = int(self._c.paperWidth() * self._c.printResolution() / 25.4)
157-
# svg_h = int(self._c.paperHeight() * self._c.printResolution() / 25.4)
158-
svg_w = width
159-
svg_h = height
160-
svg_g.setSize(QSize(svg_w, svg_h))
161-
svg_g.setViewBox(QRect(0, 0, svg_w, svg_h))
162-
# because the rendering is done in mm, convert the dpi
163-
# svg_g.setResolution(self._c.printResolution())
161+
svg_g.setSize(QSize(width, height))
162+
svg_g.setViewBox(QRect(0, 0, width, height))
164163
svg_g.setResolution(dpi)
165164

166165
sp = QPainter(svg_g)
167166
self._c.renderPage(sp, 0)
168167
sp.end()
169168

170169
if temp_size == os.path.getsize(svgpath):
171-
# something went pear-shaped
172170
return False, ''
173171

174172
image = QImage(width, height, QImage.Format_ARGB32)
@@ -211,7 +209,6 @@ def _get_composer_pdf_image(self, width, height, dpi):
211209
pdf_p.end()
212210

213211
if temp_size == os.path.getsize(pdfpath):
214-
# something went pear-shaped
215212
return False, ''
216213

217214
filepath = getTempfilePath('png')
@@ -260,10 +257,11 @@ def get_composer_output(self, kind):
260257
def checkTest(self, **kwargs):
261258
self.lyr.writeToLayer(self.layer)
262259
res_m, self._TestImage = self.get_composer_output(self._TestKind)
263-
self.saveControlImage(self._TestImage)
264260
self.assertTrue(res_m, 'Failed to retrieve/save output from composer')
261+
self.saveControlImage(self._TestImage)
265262
mismatch = self._Mismatch
266-
if self._TestGroup in self._Mismatches:
263+
if (self._TestGroup in self._Mismatches
264+
and 'PAL_NO_MISMATCH' not in os.environ):
267265
mismatch = self._Mismatches[self._TestGroup]
268266
self.assertTrue(*self.renderCheck(mismatch=mismatch,
269267
imgpath=self._TestImage))
@@ -295,15 +293,39 @@ def setUp(self):
295293
self.configTest('pal_canvas', 'sp')
296294

297295

296+
class TestComposerSvgPoint(TestComposerPointBase, TestPointBase):
297+
298+
def setUp(self):
299+
"""Run before each test."""
300+
super(TestComposerSvgPoint, self).setUp()
301+
self._TestKind = OutputKind.Svg
302+
self.configTest('pal_composer', 'sp_svg')
303+
304+
305+
class TestComposerSvgVsComposerPoint(TestComposerPointBase, TestPointBase):
306+
"""
307+
Compare only to composer image, which is already compared to canvas point
308+
"""
309+
def setUp(self):
310+
"""Run before each test."""
311+
super(TestComposerSvgVsComposerPoint, self).setUp()
312+
self._TestKind = OutputKind.Svg
313+
self.configTest('pal_composer', 'sp_img')
314+
315+
298316
if __name__ == '__main__':
299317
# NOTE: unless PAL_SUITE env var is set all test class methods will be run
300318
# SEE: test_qgspallabeling_tests.suiteTests() to define suite
301319
st = suiteTests()
302320
sp_i = ['TestComposerImagePoint.' + t for t in st['sp_suite']]
303321
sp_ivs = ['TestComposerImageVsCanvasPoint.' + t for t in st['sp_vs_suite']]
322+
sp_s = ['TestComposerSvgPoint.' + t for t in st['sp_suite']]
323+
sp_svs = ['TestComposerSvgVsComposerPoint.' + t for t in st['sp_vs_suite']]
304324
suite = []
305325
# extended separately for finer control of PAL_SUITE (comment-out undesired)
306326
suite.extend(sp_i)
307327
suite.extend(sp_ivs)
328+
suite.extend(sp_s)
329+
suite.extend(sp_svs)
308330
res = runSuite(sys.modules[__name__], suite)
309331
sys.exit(not res.wasSuccessful())

‎tests/src/python/test_qgspallabeling_server.py

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -82,7 +82,9 @@ def setUpClass(cls):
8282
settings = QSettings()
8383
# noinspection PyArgumentList
8484
cls._CacheDir = settings.value(
85-
"cache/directory", QgsApplication.qgisSettingsDirPath() + "cache")
85+
"cache/directory",
86+
os.path.join(QgsApplication.qgisSettingsDirPath(), "cache"),
87+
type=unicode)
8688

8789
@classmethod
8890
def tearDownClass(cls):

‎tests/src/python/test_qgspallabeling_tests.py

Lines changed: 10 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,6 @@
1515
__revision__ = '$Format:%H$'
1616

1717
import os
18-
import sys
1918
from PyQt4.QtCore import *
2019
from PyQt4.QtGui import *
2120

@@ -44,9 +43,14 @@ def __init__(self):
4443
# e.g. self._Mismatches['TestClassName'] = 300
4544
self._Mismatches = dict()
4645

46+
# noinspection PyMethodMayBeStatic
47+
def checkTest(self, **kwargs):
48+
"""Intended to be overridden in subclasses"""
49+
pass
50+
4751
def test_default_label(self):
4852
# Default label placement, with text size in points
49-
self._Mismatches['TestComposerImageVsCanvasPoint'] = 2034
53+
self._Mismatches['TestComposerSvgVsComposerPoint'] = 500
5054
self.checkTest()
5155

5256
def test_text_size_map_unit(self):
@@ -55,18 +59,17 @@ def test_text_size_map_unit(self):
5559
font = QFont(self._TestFont)
5660
font.setPointSizeF(460)
5761
self.lyr.textFont = font
58-
self._Mismatches['TestComposerImageVsCanvasPoint'] = 1877
5962
self.checkTest()
6063

6164
def test_text_color(self):
6265
# Label color change
6366
self.lyr.textColor = Qt.blue
64-
self._Mismatches['TestComposerImageVsCanvasPoint'] = 2034
67+
self._Mismatches['TestComposerSvgVsComposerPoint'] = 500
6568
self.checkTest()
6669

6770
def test_background_rect(self):
6871
self.lyr.shapeDraw = True
69-
self._Mismatches['TestComposerImageVsCanvasPoint'] = 2751
72+
self._Mismatches['TestComposerSvgVsComposerPoint'] = 1100
7073
self.checkTest()
7174

7275
def test_background_rect_w_offset(self):
@@ -82,7 +85,7 @@ def test_background_rect_w_offset(self):
8285
self.lyr.shapeDraw = True
8386
self.lyr.shapeOffsetUnits = QgsPalLayerSettings.MapUnits
8487
self.lyr.shapeOffset = QPointF(-2900.0, -450.0)
85-
self._Mismatches['TestComposerImageVsCanvasPoint'] = 2530
88+
self._Mismatches['TestComposerSvgVsComposerPoint'] = 750
8689
self.checkTest()
8790

8891
def test_background_svg(self):
@@ -100,7 +103,6 @@ def test_background_svg(self):
100103
self.lyr.shapeSizeUnits = QgsPalLayerSettings.MapUnits
101104
self.lyr.shapeSizeType = QgsPalLayerSettings.SizeBuffer
102105
self.lyr.shapeSize = QPointF(100.0, 0.0)
103-
self._Mismatches['TestComposerImageVsCanvasPoint'] = 2882
104106
self.checkTest()
105107

106108
def test_background_svg_w_offset(self):
@@ -121,7 +123,6 @@ def test_background_svg_w_offset(self):
121123

122124
self.lyr.shapeOffsetUnits = QgsPalLayerSettings.MapUnits
123125
self.lyr.shapeOffset = QPointF(-2850.0, 500.0)
124-
self._Mismatches['TestComposerImageVsCanvasPoint'] = 2901
125126
self.checkTest()
126127

127128
def test_partials_labels_enabled(self):
@@ -132,7 +133,7 @@ def test_partials_labels_enabled(self):
132133
# Enable partials labels
133134
self._Pal.setShowingPartialsLabels(True)
134135
self._Pal.saveEngineSettings()
135-
self._Mismatches['TestComposerImageVsCanvasPoint'] = 2250
136+
self._Mismatches['TestComposerSvgVsComposerPoint'] = 600
136137
self.checkTest()
137138

138139
def test_partials_labels_disabled(self):
80 Bytes

Error rendering embedded code

Invalid image source.

Error rendering embedded code

Invalid image source.

-43 Bytes

Error rendering embedded code

Invalid image source.

-51 Bytes

Error rendering embedded code

Invalid image source.

0 Bytes

Error rendering embedded code

Invalid image source.

Error rendering embedded code

Invalid image source.

Error rendering embedded code

Invalid image source.

-65 Bytes

Error rendering embedded code

Invalid image source.

-51 Bytes

Error rendering embedded code

Invalid image source.

8.77 KB

Error rendering embedded code

Invalid image source.

Error rendering embedded code

Invalid image source.

8.64 KB

Error rendering embedded code

Invalid image source.

Error rendering embedded code

Invalid image source.

8.96 KB

Error rendering embedded code

Invalid image source.

Error rendering embedded code

Invalid image source.

Error rendering embedded code

Invalid image source.

8.15 KB

Error rendering embedded code

Invalid image source.

8.72 KB

Error rendering embedded code

Invalid image source.

0 commit comments

Comments
 (0)
Please sign in to comment.