mirror of
https://github.com/Kozea/WeasyPrint.git
synced 2024-10-04 07:57:52 +03:00
becd494f91
Fix #359.
90 lines
2.8 KiB
Python
90 lines
2.8 KiB
Python
"""
|
||
weasyprint.tests.conftest
|
||
-------------------------
|
||
|
||
Configuration for WeasyPrint tests.
|
||
|
||
This module adds a PNG export based on Ghostscript.
|
||
|
||
Note that Ghostscript is released under AGPL.
|
||
|
||
"""
|
||
|
||
import io
|
||
import os
|
||
import shutil
|
||
from subprocess import PIPE, run
|
||
from tempfile import NamedTemporaryFile
|
||
|
||
import pytest
|
||
from PIL import Image
|
||
from weasyprint import HTML
|
||
from weasyprint.document import Document
|
||
|
||
MAGIC_NUMBER = b'\x89\x50\x4e\x47\x0d\x0a\x1a\x0a'
|
||
|
||
|
||
def document_write_png(self, target=None, resolution=96, antialiasing=1,
|
||
zoom=4/30):
|
||
# Use temporary files because gs on Windows doesn’t accept binary on stdin
|
||
with NamedTemporaryFile(delete=False) as pdf:
|
||
pdf.write(self.write_pdf(zoom=zoom))
|
||
command = [
|
||
'gs', '-q', '-dNOPAUSE', f'-dTextAlphaBits={antialiasing}',
|
||
f'-dGraphicsAlphaBits={antialiasing}', '-sDEVICE=png16m',
|
||
f'-r{resolution / zoom}', '-sOutputFile=-', pdf.name]
|
||
pngs = run(command, stdout=PIPE).stdout
|
||
os.remove(pdf.name)
|
||
|
||
assert pngs.startswith(MAGIC_NUMBER), (
|
||
'Ghostscript error: '
|
||
f'{pngs.split(MAGIC_NUMBER)[0].decode("ascii").strip()}')
|
||
|
||
# TODO: use a different way to find PNG files in stream
|
||
magic_numbers = pngs.count(MAGIC_NUMBER)
|
||
if magic_numbers == 1:
|
||
if target is None:
|
||
return pngs
|
||
png = io.BytesIO(pngs)
|
||
else:
|
||
images = []
|
||
for i, png in enumerate(pngs[8:].split(MAGIC_NUMBER)):
|
||
images.append(Image.open(io.BytesIO(MAGIC_NUMBER + png)))
|
||
|
||
width = max(image.width for image in images)
|
||
height = sum(image.height for image in images)
|
||
output_image = Image.new('RGBA', (width, height))
|
||
top = 0
|
||
for image in images:
|
||
output_image.paste(image, (int((width - image.width) / 2), top))
|
||
top += image.height
|
||
png = io.BytesIO()
|
||
output_image.save(png, format='png')
|
||
|
||
png.seek(0)
|
||
|
||
if target is None:
|
||
return png.read()
|
||
|
||
if hasattr(target, 'write'):
|
||
shutil.copyfileobj(png, target)
|
||
else:
|
||
with open(target, 'wb') as fd:
|
||
shutil.copyfileobj(png, fd)
|
||
|
||
|
||
def html_write_png(self, target=None, stylesheets=None, resolution=96,
|
||
presentational_hints=False, optimize_size=('fonts',),
|
||
font_config=None, counter_style=None, image_cache=None):
|
||
return self.render(
|
||
stylesheets, presentational_hints=presentational_hints,
|
||
optimize_size=optimize_size, font_config=font_config,
|
||
counter_style=counter_style, image_cache=image_cache).write_png(
|
||
target, resolution)
|
||
|
||
|
||
@pytest.fixture(autouse=True)
|
||
def monkey_write_png(monkeypatch):
|
||
Document.write_png = document_write_png
|
||
HTML.write_png = html_write_png
|