1
1
mirror of https://github.com/Kozea/WeasyPrint.git synced 2024-10-05 08:27:22 +03:00
WeasyPrint/fireweasy/serialize.py
2012-03-15 20:00:23 +01:00

96 lines
2.9 KiB
Python

from __future__ import division, unicode_literals
import functools
from io import BytesIO
import cairo
BOX_ATTRIBUTES = '''
position_x position_y
width height
margin_top margin_bottom margin_left margin_right
padding_top padding_bottom padding_left padding_right
border_top_width border_bottom_width border_left_width border_right_width
'''.split()
PAGE_BOX_ATTRIBUTES = BOX_ATTRIBUTES + ['outer_width', 'outer_height']
def serialize(document):
"""
Serialize a WeasyPrint Document object to JSON-compatible data types
for in-browser rendering.
"""
return {'pages': [
serialize_page_box(document, page)
for page in document.pages]}
def serialize_box(document, box, attributes=BOX_ATTRIBUTES):
rv = {name: getattr(box, name) for name in attributes}
rv['style'] = serialize_style(document, box.style)
children = getattr(box, 'children', None)
if children is not None:
rv['children'] = [serialize_box(document, child) for child in children]
marker = getattr(box, 'outside_list_marker', None)
if marker is not None:
rv['children'].append(serialize_box(document, marker))
text = getattr(box, 'text', None)
if text is not None:
rv['text'] = text
replacement = getattr(box, 'replacement', None)
if replacement is not None:
width = int(box.width)
height = int(box.height)
rv['width'] = width
rv['height'] = height
rv['image'] = serialize_replacement(replacement, width, height)
return rv
def serialize_replacement(replacement, scaled_width=None, scaled_height=None):
pattern, width, height = replacement
if scaled_width is None:
scaled_width = width
if scaled_height is None:
scaled_height = height
surface = cairo.ImageSurface(
cairo.FORMAT_ARGB32, scaled_width, scaled_height)
context = cairo.Context(surface)
context.scale(scaled_width / width, scaled_height / height)
context.set_source(pattern)
context.paint()
file_like = BytesIO()
surface.write_to_png(file_like)
return file_like.getvalue().encode('base64').replace('\n', '')
serialize_page_box = functools.partial(
serialize_box, attributes=PAGE_BOX_ATTRIBUTES)
def serialize_style(document, style):
style = style.as_dict()
for key, value in style.iteritems():
if getattr(value, 'type', None) == 'COLOR_VALUE':
style[key] = value.cssText
bg_image = style['background_image']
if bg_image == 'None':
bg_image = None
else:
bg_image = document.get_image_from_uri(style['background_image'])
if bg_image is not None:
bg_image = serialize_replacement(bg_image)
style['background_image'] = bg_image
for key in ['background_position', 'transform_origin']:
style[key] = [getattr(v, 'cssText', v) for v in style[key]]
style['text_decoration'] = ' '.join(style['text_decoration']) or 'none'
return style