2011-07-12 19:53:15 +04:00
|
|
|
|
# coding: utf8
|
|
|
|
|
|
|
|
|
|
# WeasyPrint converts web documents (HTML, CSS, ...) to PDF.
|
|
|
|
|
# Copyright (C) 2011 Simon Sapin
|
|
|
|
|
#
|
|
|
|
|
# This program is free software: you can redistribute it and/or modify
|
|
|
|
|
# it under the terms of the GNU Affero General Public License as
|
|
|
|
|
# published by the Free Software Foundation, either version 3 of the
|
|
|
|
|
# License, or (at your option) any later version.
|
|
|
|
|
#
|
|
|
|
|
# This program is distributed in the hope that it will be useful,
|
|
|
|
|
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
|
|
|
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
|
|
|
# GNU Affero General Public License for more details.
|
|
|
|
|
#
|
|
|
|
|
# You should have received a copy of the GNU Affero General Public License
|
|
|
|
|
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
|
|
|
|
|
|
|
|
|
2011-07-29 03:14:05 +04:00
|
|
|
|
import os.path
|
2011-07-12 19:53:15 +04:00
|
|
|
|
|
2011-07-29 03:14:05 +04:00
|
|
|
|
import png
|
|
|
|
|
from attest import Tests, assert_hook
|
2011-07-12 19:53:15 +04:00
|
|
|
|
|
2011-08-10 18:19:32 +04:00
|
|
|
|
from . import resource_filename
|
2011-07-29 03:14:05 +04:00
|
|
|
|
from ..document import PNGDocument
|
2011-08-10 18:54:26 +04:00
|
|
|
|
from . import make_expected_results
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
make_expected_results.make_all()
|
2011-07-12 19:53:15 +04:00
|
|
|
|
|
|
|
|
|
|
2011-07-29 03:14:05 +04:00
|
|
|
|
suite = Tests()
|
2011-07-12 19:53:15 +04:00
|
|
|
|
|
|
|
|
|
|
2011-07-29 03:14:05 +04:00
|
|
|
|
def make_filename(dirname, basename):
|
|
|
|
|
return os.path.join(os.path.dirname(__file__), dirname, basename + '.png')
|
2011-07-12 20:27:33 +04:00
|
|
|
|
|
|
|
|
|
|
2011-08-10 21:33:16 +04:00
|
|
|
|
def format_pixel(lines, x, y):
|
|
|
|
|
pixel = lines[y][3 * x:3 * (x + 1)]
|
|
|
|
|
return ('#' + 3 * '%02x') % tuple(pixel)
|
|
|
|
|
|
|
|
|
|
|
2011-07-29 03:14:05 +04:00
|
|
|
|
def test_pixels(name, expected_width, expected_height, html):
|
|
|
|
|
reader = png.Reader(filename=make_filename('expected_results', name))
|
|
|
|
|
width, height, expected_lines, meta = reader.read()
|
|
|
|
|
assert width == expected_width
|
|
|
|
|
assert height == height
|
|
|
|
|
assert meta['greyscale'] == False
|
2011-08-08 23:20:43 +04:00
|
|
|
|
assert meta['alpha'] == False
|
2011-07-29 03:14:05 +04:00
|
|
|
|
assert meta['bitdepth'] == 8
|
|
|
|
|
expected_lines = list(expected_lines)
|
2011-07-12 20:27:33 +04:00
|
|
|
|
|
2011-07-29 03:14:05 +04:00
|
|
|
|
document = PNGDocument.from_string(html)
|
2011-08-10 18:19:32 +04:00
|
|
|
|
# Dummy filename, but in the right directory.
|
|
|
|
|
document.base_url = resource_filename('<test>')
|
2011-07-29 03:14:05 +04:00
|
|
|
|
filename = make_filename('test_results', name)
|
2011-08-05 17:55:34 +04:00
|
|
|
|
document.write_to(filename)
|
2011-07-13 13:31:44 +04:00
|
|
|
|
|
2011-07-12 20:27:33 +04:00
|
|
|
|
|
2011-07-29 03:14:05 +04:00
|
|
|
|
reader = png.Reader(filename=filename)
|
|
|
|
|
width, height, lines, meta = reader.read()
|
|
|
|
|
lines = list(lines)
|
2011-07-12 19:53:15 +04:00
|
|
|
|
|
2011-07-29 03:14:05 +04:00
|
|
|
|
assert width == expected_width
|
|
|
|
|
assert height == height
|
|
|
|
|
assert meta['greyscale'] == False
|
2011-08-08 23:20:43 +04:00
|
|
|
|
assert meta['alpha'] == False
|
2011-07-29 03:14:05 +04:00
|
|
|
|
assert meta['bitdepth'] == 8
|
|
|
|
|
assert len(lines) == height
|
2011-08-08 23:20:43 +04:00
|
|
|
|
assert len(lines[0]) == width * 3
|
|
|
|
|
if lines != expected_lines:
|
|
|
|
|
for y in xrange(height):
|
|
|
|
|
for x in xrange(width):
|
2011-08-10 21:33:16 +04:00
|
|
|
|
pixel = format_pixel(lines, x, y)
|
|
|
|
|
expected_pixel = format_pixel(expected_lines, x, y)
|
|
|
|
|
assert pixel == expected_pixel, \
|
|
|
|
|
'Pixel (%i, %i) does not match in %s' % (x, y, name)
|
2011-07-29 03:14:05 +04:00
|
|
|
|
|
|
|
|
|
@suite.test
|
2011-08-10 18:19:32 +04:00
|
|
|
|
def test_canvas_background():
|
2011-08-08 23:20:43 +04:00
|
|
|
|
test_pixels('all_blue', 10, 10, '''
|
|
|
|
|
<style>
|
|
|
|
|
@page { size: 10px }
|
|
|
|
|
/* body’s background propagates to the whole canvas */
|
|
|
|
|
body { margin: 2px; background: #00f; height: 5px }
|
|
|
|
|
</style>
|
|
|
|
|
<body>
|
|
|
|
|
''')
|
2011-07-29 03:14:05 +04:00
|
|
|
|
test_pixels('blocks', 10, 10, '''
|
|
|
|
|
<style>
|
|
|
|
|
@page { size: 10px }
|
2011-08-08 23:20:43 +04:00
|
|
|
|
/* html’s background propagates to the whole canvas */
|
|
|
|
|
html { margin: 1px; background: #f00 }
|
|
|
|
|
/* html has a background, so body’s does not propagate */
|
|
|
|
|
body { margin: 1px; background: #00f; height: 5px }
|
2011-07-29 03:14:05 +04:00
|
|
|
|
</style>
|
|
|
|
|
<body>
|
|
|
|
|
''')
|
2011-08-10 18:19:32 +04:00
|
|
|
|
|
|
|
|
|
|
2011-08-10 18:52:34 +04:00
|
|
|
|
@suite.test
|
|
|
|
|
def test_background_image():
|
2011-08-11 14:44:37 +04:00
|
|
|
|
for name, css in [
|
2011-08-10 21:33:16 +04:00
|
|
|
|
('repeat', ''),
|
|
|
|
|
('repeat_x', 'repeat-x'),
|
|
|
|
|
('repeat_y', 'repeat-y'),
|
2011-08-11 14:44:37 +04:00
|
|
|
|
|
|
|
|
|
('left_top', 'no-repeat 0 0%'),
|
|
|
|
|
('center_top', 'no-repeat 50% 0px'),
|
|
|
|
|
('right_top', 'no-repeat 6px top'),
|
|
|
|
|
|
|
|
|
|
('left_center', 'no-repeat left center'),
|
|
|
|
|
('center_center', 'no-repeat 3px 3px'),
|
|
|
|
|
('right_center', 'no-repeat 100% 50%'),
|
|
|
|
|
|
|
|
|
|
('left_bottom', 'no-repeat 0% bottom'),
|
|
|
|
|
('center_bottom', 'no-repeat center 6px'),
|
|
|
|
|
('right_bottom', 'no-repeat 6px 100%'),
|
|
|
|
|
]:
|
2011-08-10 21:33:16 +04:00
|
|
|
|
test_pixels('background_' + name, 14, 16, '''
|
|
|
|
|
<style>
|
|
|
|
|
@page { size: 14px 16px }
|
|
|
|
|
html { background: #fff }
|
|
|
|
|
body { margin: 2px; height: 10px;
|
|
|
|
|
background: url(pattern.png) %s }
|
|
|
|
|
</style>
|
|
|
|
|
<body>
|
|
|
|
|
''' % (css,))
|