mirror of
https://github.com/Kozea/WeasyPrint.git
synced 2024-10-05 00:21:15 +03:00
Cache images to avoid downloading them over and over.
(In particular, page background images were downloaded for each page.)
This commit is contained in:
parent
91f4ad1dba
commit
fc4c4863df
@ -34,6 +34,7 @@ from .css.computed_values import LENGTHS_TO_PIXELS
|
||||
from .formatting_structure.build import build_formatting_structure
|
||||
from .layout import layout
|
||||
from . import draw
|
||||
from .draw import helpers as draw_helpers
|
||||
from . import utils
|
||||
|
||||
|
||||
@ -67,6 +68,7 @@ class Document(object):
|
||||
self._computed_styles = None
|
||||
self._formatting_structure = None
|
||||
self._pages = None
|
||||
self._image_cache = {}
|
||||
|
||||
@property
|
||||
def base_url(self):
|
||||
@ -142,6 +144,18 @@ class Document(object):
|
||||
self._pages = layout(self)
|
||||
return self._pages
|
||||
|
||||
def get_image_surface_from_uri(self, uri):
|
||||
if uri in self._image_cache:
|
||||
return self._image_cache[uri]
|
||||
try:
|
||||
surface = draw_helpers.get_image_surface_from_uri(uri)
|
||||
# TODO: have a more specific list of exception for network errors
|
||||
# and PNG parsing errors.
|
||||
except Exception:
|
||||
surface = None
|
||||
self._image_cache[uri] = surface
|
||||
return surface
|
||||
|
||||
|
||||
class PNGDocument(Document):
|
||||
"""PNG output document."""
|
||||
|
@ -161,11 +161,8 @@ def draw_background(context, box, clip=True):
|
||||
if bg_image.type != 'URI':
|
||||
return
|
||||
|
||||
try:
|
||||
surface = get_image_surface_from_uri(bg_image.absoluteUri)
|
||||
# TODO: have a more specific list of exception for network errors
|
||||
# and PNG parsing errors.
|
||||
except Exception:
|
||||
surface = box.document.get_image_surface_from_uri(bg_image.absoluteUri)
|
||||
if surface is None:
|
||||
return
|
||||
|
||||
image_width = surface.get_width()
|
||||
|
@ -118,14 +118,20 @@ def add_list_marker(box):
|
||||
|
||||
"""
|
||||
image = box.style.list_style_image
|
||||
if get_single_keyword(image) == 'none':
|
||||
if get_single_keyword(image) != 'none':
|
||||
# surface may be None here too, in case the image is not available.
|
||||
surface = box.document.get_image_surface_from_uri(image[0].absoluteUri)
|
||||
else:
|
||||
surface = None
|
||||
|
||||
if surface is None:
|
||||
type_ = get_single_keyword(box.style.list_style_type)
|
||||
if type_ == 'none':
|
||||
return
|
||||
marker = GLYPH_LIST_MARKERS[type_]
|
||||
marker_box = boxes.TextBox(box.document, box.element, marker)
|
||||
else:
|
||||
replacement = html.ImageReplacement(image[0].absoluteUri)
|
||||
replacement = html.ImageReplacement(surface)
|
||||
marker_box = boxes.ImageMarkerBox(
|
||||
box.document, box.element, replacement)
|
||||
|
||||
|
@ -117,11 +117,11 @@ def handle_img(document, element):
|
||||
src = get_url_attribute(element, 'src')
|
||||
alt = element.get('alt')
|
||||
if src:
|
||||
try:
|
||||
replacement = ImageReplacement(src)
|
||||
# TODO: have a more specific list of exception for network errors
|
||||
# and image parsing errors.
|
||||
except Exception:
|
||||
surface = document.get_image_surface_from_uri(src)
|
||||
if surface is not None:
|
||||
replacement = ImageReplacement(surface)
|
||||
return make_replaced_box(document, element, replacement)
|
||||
else:
|
||||
# Invalid image, use the alt-text.
|
||||
if alt:
|
||||
return make_text_box(document, element, alt)
|
||||
@ -133,8 +133,6 @@ def handle_img(document, element):
|
||||
# TODO: find some indicator that an image is missing.
|
||||
# For now, just remove the image.
|
||||
return None
|
||||
else:
|
||||
return make_replaced_box(document, element, replacement)
|
||||
else:
|
||||
if alt:
|
||||
return make_text_box(document, element, alt)
|
||||
@ -172,11 +170,11 @@ class Replacement(object):
|
||||
class ImageReplacement(Replacement):
|
||||
"""Replaced ``<img>`` element.
|
||||
|
||||
:param image_uri: uri where to get the image.
|
||||
:param surface: a cairo :class:`ImageSurface` object.
|
||||
|
||||
"""
|
||||
def __init__(self, image_uri):
|
||||
self.surface = get_image_surface_from_uri(image_uri)
|
||||
def __init__(self, surface):
|
||||
self.surface = surface
|
||||
|
||||
def intrinsic_width(self):
|
||||
if self.surface:
|
||||
|
Loading…
Reference in New Issue
Block a user