1
1
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:
Simon Sapin 2011-08-25 22:16:04 +02:00
parent 91f4ad1dba
commit fc4c4863df
4 changed files with 32 additions and 17 deletions

View File

@ -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."""

View File

@ -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()

View File

@ -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)

View File

@ -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: