116 changes: 59 additions & 57 deletions tests/src/python/test_qgspallabeling_composer.py
Original file line number Diff line number Diff line change
Expand Up @@ -77,9 +77,6 @@ def setUpClass(cls):
cls._CheckMismatch = 0 # mismatch expected for crosscheck
cls._TestImage = ''
cls._TestKind = '' # img|svg|pdf
cls._ImgW = 600
cls._ImgH = 400
cls._ImgDpi = 72

@classmethod
def tearDownClass(cls):
Expand All @@ -93,21 +90,15 @@ def setUp(self):
TestQgsPalLabeling.setDefaultEngineSettings()
self.lyr = self.defaultLayerSettings()
self._TestImage = ''

# noinspection PyUnusedLocal
def checkTest(self, **kwargs):
self.lyr.writeToLayer(self.layer)
res_m, self._TestImage = self.get_composer_output(self._TestKind)
self.saveContolImage(self._TestImage)
self.assertTrue(res_m, 'Failed to retrieve/save output from composer')
self.assertTrue(*self.renderCheck(mismatch=self._CheckMismatch,
imgpath=self._TestImage))
# ensure per test map settings stay encapsulated
self._TestMapSettings = self.cloneMapSettings(self._MapSettings)

def _set_up_composition(self, width, height, dpi):
# set up composition and add map
# TODO: how to keep embedded map from being anti-aliased twice?
# self._MapSettings.setFlag(QgsMapSettings.Antialiasing, False)
self._c = QgsComposition(self._MapSettings)
# self._MapSettings.setFlag(QgsMapSettings.UseAdvancedEffects, True)
self._c = QgsComposition(self._TestMapSettings)
""":type: QgsComposition"""
self._c.setPrintResolution(dpi)
# 600 x 400 px = 211.67 x 141.11 mm @ 72 dpi
Expand All @@ -120,34 +111,30 @@ def _set_up_composition(self, width, height, dpi):
self._c, 0, 0, self._c.paperWidth(), self._c.paperHeight())
""":type: QgsComposerMap"""
self._cmap.setFrameEnabled(False)
self._c.addComposerMap(self._cmap)
self._cmap.setNewExtent(self.aoiExtent())
self._c.addComposerMap(self._cmap)
self._c.setPlotStyle(QgsComposition.Print)

# noinspection PyUnusedLocal
def _get_composer_image(self, width, height, dpi):
# dpi = self._c.printResolution() # why did I add this before?
dpmm = dpi / 25.4
img_width = int(dpmm * self._c.paperWidth())
img_height = int(dpmm * self._c.paperHeight())

# create output image and initialize it
image = QImage(QSize(img_width, img_height), QImage.Format_ARGB32)
image.setDotsPerMeterX(dpmm * 1000)
image.setDotsPerMeterY(dpmm * 1000)
image = QImage(QSize(width, height), QImage.Format_ARGB32)
image.fill(QColor(152, 219, 249).rgb())
image.setDotsPerMeterX(dpi / 25.4 * 1000)
image.setDotsPerMeterY(dpi / 25.4 * 1000)

# render the composition
p = QPainter(image)
p.setRenderHint(QPainter.HighQualityAntialiasing, False)
p.setRenderHint(QPainter.SmoothPixmapTransform, False)
p.setRenderHint(QPainter.Antialiasing, False)
p.setRenderHint(QPainter.TextAntialiasing, False)
src = QRectF(0, 0, self._c.paperWidth(), self._c.paperHeight())
trgt = QRectF(0, 0, img_width, img_height)
self._c.render(p, trgt, src)
p.setRenderHint(QPainter.Antialiasing, True)
p.setRenderHint(QPainter.HighQualityAntialiasing, True)
self._c.renderPage(p, 0)
p.end()

# image = self._c.printPageAsRaster(0)
# """:type: QImage"""

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

filepath = getTempfilePath('png')
res = image.save(filepath, 'png')
if not res:
Expand All @@ -161,17 +148,21 @@ def _get_composer_svg_image(self, width, height, dpi):
# line 1909, near end of function
svgpath = getTempfilePath('svg')
temp_size = os.path.getsize(svgpath)

svg_g = QSvgGenerator()
# noinspection PyArgumentList
svg_g.setTitle(QgsProject.instance().title())
svg_g.setFileName(svgpath)
# width and height in pixels
svg_w = int(self._c.paperWidth() * self._c.printResolution() / 25.4)
svg_h = int(self._c.paperHeight() * self._c.printResolution() / 25.4)
# svg_w = int(self._c.paperWidth() * self._c.printResolution() / 25.4)
# svg_h = int(self._c.paperHeight() * self._c.printResolution() / 25.4)
svg_w = width
svg_h = height
svg_g.setSize(QSize(svg_w, svg_h))
svg_g.setViewBox(QRect(0, 0, svg_w, svg_h))
# because the rendering is done in mm, convert the dpi
svg_g.setResolution(self._c.printResolution())
# svg_g.setResolution(self._c.printResolution())
svg_g.setResolution(dpi)

sp = QPainter(svg_g)
self._c.renderPage(sp, 0)
Expand All @@ -181,11 +172,12 @@ def _get_composer_svg_image(self, width, height, dpi):
# something went pear-shaped
return False, ''

svgr = QSvgRenderer(svgpath)
image = QImage(width, height, QImage.Format_ARGB32)
image.fill(QColor(152, 219, 249).rgb())
image.setDotsPerMeterX(dpi/25.4 * 1000)
image.setDotsPerMeterY(dpi/25.4 * 1000)
image.setDotsPerMeterX(dpi / 25.4 * 1000)
image.setDotsPerMeterY(dpi / 25.4 * 1000)

svgr = QSvgRenderer(svgpath)
p = QPainter(image)
svgr.render(p)
p.end()
Expand All @@ -202,6 +194,7 @@ def _get_composer_svg_image(self, width, height, dpi):
def _get_composer_pdf_image(self, width, height, dpi):
pdfpath = getTempfilePath('pdf')
temp_size = os.path.getsize(pdfpath)

p = QPrinter()
p.setOutputFormat(QPrinter.PdfFormat)
p.setOutputFileName(pdfpath)
Expand All @@ -212,36 +205,34 @@ def _get_composer_pdf_image(self, width, height, dpi):
p.setResolution(self._c.printResolution())

pdf_p = QPainter(p)
page_mm = p.pageRect(QPrinter.Millimeter)
page_px = p.pageRect(QPrinter.DevicePixel)
self._c.render(pdf_p, page_px, page_mm)
# page_mm = p.pageRect(QPrinter.Millimeter)
# page_px = p.pageRect(QPrinter.DevicePixel)
# self._c.render(pdf_p, page_px, page_mm)
self._c.renderPage(pdf_p, 0)
pdf_p.end()

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

filepath = getTempfilePath('png')
filebase = os.path.join(os.path.dirname(filepath),
os.path.splitext(os.path.basename(filepath))[0])
# pdftoppm -singlefile -r 72 -x 0 -y 0 -W 600 -H 400 -png in.pdf pngbase
# mudraw -o out.png -r 72 -w 600 -h 400 -c rgb[a] in.pdf
if PDFUTIL == 'pdftoppm':
filebase = os.path.join(
os.path.dirname(filepath),
os.path.splitext(os.path.basename(filepath))[0]
)
call = [
'pdftoppm', '-singlefile',
'-r', str(dpi),
'-x', str(0), '-y', str(0),
'-W', str(width), '-H', str(height),
'pdftoppm', '-singlefile', '-r', str(dpi),
'-x', str(0), '-y', str(0), '-W', str(width), '-H', str(height),
'-png', pdfpath, filebase
]
elif PDFUTIL == 'mudraw':
call = [
'mudraw'
'-o', filepath,
'-c', 'rgba',
'-r', str(dpi),
'-w', str(width), '-h', str(height),
pdfpath
'mudraw', '-c', 'rgba',
'-r', str(dpi), '-w', str(width), '-h', str(height),
'-o', filepath, pdfpath
]
else:
return False, ''
Expand All @@ -255,25 +246,36 @@ def _get_composer_pdf_image(self, width, height, dpi):
return res, filepath

def get_composer_output(self, kind):
width, height, dpi = self._ImgW, self._ImgH, self._ImgDpi
ms = self._TestMapSettings
osize = ms.outputSize()
width, height, dpi = osize.width(), osize.height(), ms.outputDpi()
self._set_up_composition(width, height, dpi)
if kind == OutputKind.Svg:
return self._get_composer_svg_image(width, height, dpi)
elif kind == OutputKind.Pdf:
return self._get_composer_pdf_image(width, height, dpi)
else: # 'img'
else: # OutputKind.Img
return self._get_composer_image(width, height, dpi)

# noinspection PyUnusedLocal
def checkTest(self, **kwargs):
self.lyr.writeToLayer(self.layer)
res_m, self._TestImage = self.get_composer_output(self._TestKind)
self.saveControlImage(self._TestImage)
self.assertTrue(res_m, 'Failed to retrieve/save output from composer')
self.assertTrue(*self.renderCheck(mismatch=self._CheckMismatch,
imgpath=self._TestImage))


class TestComposerPointBase(TestComposerBase, TestPointBase):
class TestComposerPointBase(TestComposerBase):

@classmethod
def setUpClass(cls):
TestComposerBase.setUpClass()
cls.layer = TestQgsPalLabeling.loadFeatureLayer('point')


class TestComposerImagePoint(TestComposerPointBase):
class TestComposerImagePoint(TestComposerPointBase, TestPointBase):

def setUp(self):
"""Run before each test."""
Expand All @@ -284,7 +286,7 @@ def setUp(self):
self._CheckMismatch = 2700 # comment to PAL_REPORT difference


class TestComposerImageVsCanvasPoint(TestComposerPointBase):
class TestComposerImageVsCanvasPoint(TestComposerPointBase, TestPointBase):

def setUp(self):
"""Run before each test."""
Expand Down
2 changes: 1 addition & 1 deletion tests/src/python/test_qgspallabeling_server.py
Original file line number Diff line number Diff line change
Expand Up @@ -168,7 +168,7 @@ def checkTest(self, **kwargs):
# print self.params.__repr__()
res_m, self._TestImage = MAPSERV.get_map(self.params, False)
# print self._TestImage.__repr__()
self.saveContolImage(self._TestImage)
self.saveControlImage(self._TestImage)
self.assertTrue(res_m, 'Failed to retrieve/save image from test server')
self.assertTrue(*self.renderCheck(mismatch=self._CheckMismatch,
imgpath=self._TestImage))
Expand Down
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.