From 819f74746ffe51a0f087cfe7e25858a5d20e0e70 Mon Sep 17 00:00:00 2001 From: Guillaume Ayoub Date: Sat, 6 Jul 2024 16:45:07 +0200 Subject: [PATCH] Simplify custom Stream creation --- weasyprint/pdf/__init__.py | 27 +++---------- weasyprint/pdf/stream.py | 78 ++++++++++++++------------------------ 2 files changed, 35 insertions(+), 70 deletions(-) diff --git a/weasyprint/pdf/__init__.py b/weasyprint/pdf/__init__.py index 779680487..1feec791d 100644 --- a/weasyprint/pdf/__init__.py +++ b/weasyprint/pdf/__init__.py @@ -129,10 +129,6 @@ def generate_pdf(document, target, zoom, **options): srgb = properties['srgb'] pdf = pydyf.PDF() - states = pydyf.Dictionary() - x_objects = pydyf.Dictionary() - patterns = pydyf.Dictionary() - shadings = pydyf.Dictionary() images = {} color_space = pydyf.Dictionary({ 'lab-d50': pydyf.Array(('/Lab', pydyf.Dictionary({ @@ -146,21 +142,11 @@ def generate_pdf(document, target, zoom, **options): }) pdf.add_object(color_space) resources = pydyf.Dictionary({ - 'ExtGState': states, - 'XObject': x_objects, - 'Pattern': patterns, - 'Shading': shadings, - 'ColorSpace': pydyf.Dictionary({ - 'xyz': pydyf.Array(('/Lab', pydyf.Dictionary({ - 'WhitePoint': pydyf.Array((1, 1, 1)) - }))), - 'xyz-d50': pydyf.Array(('/Lab', pydyf.Dictionary({ - 'WhitePoint': pydyf.Array(D50) - }))), - 'xyz-d65': pydyf.Array(('/Lab', pydyf.Dictionary({ - 'WhitePoint': pydyf.Array(D65) - }))), - }) + 'ExtGState': pydyf.Dictionary(), + 'XObject': pydyf.Dictionary(), + 'Pattern': pydyf.Dictionary(), + 'Shading': pydyf.Dictionary(), + 'ColorSpace': color_space.reference, }) pdf.add_object(resources) pdf_names = [] @@ -189,8 +175,7 @@ def generate_pdf(document, target, zoom, **options): left / scale, top / scale, (right - left) / scale, (bottom - top) / scale) stream = Stream( - document.fonts, page_rectangle, states, x_objects, patterns, - shadings, images, mark, compress=compress) + document.fonts, page_rectangle, resources, images, mark, compress=compress) stream.transform(d=-1, f=(page.height * scale)) pdf.add_object(stream) page_streams.append(stream) diff --git a/weasyprint/pdf/stream.py b/weasyprint/pdf/stream.py index 6f464cad9..844fab11d 100644 --- a/weasyprint/pdf/stream.py +++ b/weasyprint/pdf/stream.py @@ -11,16 +11,12 @@ class Stream(pydyf.Stream): """PDF stream object with extra features.""" - def __init__(self, fonts, page_rectangle, states, x_objects, patterns, - shadings, images, mark, *args, **kwargs): + def __init__(self, fonts, page_rectangle, resources, images, mark, *args, **kwargs): super().__init__(*args, **kwargs) self.page_rectangle = page_rectangle self.marked = [] self._fonts = fonts - self._states = states - self._x_objects = x_objects - self._patterns = patterns - self._shadings = shadings + self._resources = resources self._images = images self._mark = mark self._current_color = self._current_color_stroke = None @@ -39,14 +35,8 @@ def clone(self, **kwargs): kwargs['fonts'] = self._fonts if 'page_rectangle' not in kwargs: kwargs['page_rectangle'] = self.page_rectangle - if 'states' not in kwargs: - kwargs['states'] = self._states - if 'x_objects' not in kwargs: - kwargs['x_objects'] = self._x_objects - if 'patterns' not in kwargs: - kwargs['patterns'] = self._patterns - if 'shadings' not in kwargs: - kwargs['shadings'] = self._shadings + if 'resources' not in kwargs: + kwargs['resources'] = self._resources if 'images' not in kwargs: kwargs['images'] = self._images if 'mark' not in kwargs: @@ -124,8 +114,8 @@ def set_font_size(self, font, size): super().set_font_size(font, size) def set_state(self, state): - key = f's{len(self._states)}' - self._states[key] = state + key = f's{len(self._resources['ExtGState'])}' + self._resources['ExtGState'][key] = state super().set_state(key) def set_alpha(self, alpha, stroke=False, fill=None): @@ -136,16 +126,16 @@ def set_alpha(self, alpha, stroke=False, fill=None): key = f'A{alpha}' if key != self._current_alpha_stroke: self._current_alpha_stroke = key - if key not in self._states: - self._states[key] = pydyf.Dictionary({'CA': alpha}) + if key not in self._resources['ExtGState']: + self._resources['ExtGState'][key] = pydyf.Dictionary({'CA': alpha}) super().set_state(key) if fill: key = f'a{alpha}' if key != self._current_alpha: self._current_alpha = key - if key not in self._states: - self._states[key] = pydyf.Dictionary({'ca': alpha}) + if key not in self._resources['ExtGState']: + self._resources['ExtGState'][key] = pydyf.Dictionary({'ca': alpha}) super().set_state(key) def set_alpha_state(self, x, y, width, height, mode='luminosity'): @@ -176,15 +166,12 @@ def add_font(self, pango_font): return self._fonts[key] def add_group(self, x, y, width, height): - states = pydyf.Dictionary() - x_objects = pydyf.Dictionary() - patterns = pydyf.Dictionary() - shadings = pydyf.Dictionary() resources = pydyf.Dictionary({ - 'ExtGState': states, - 'XObject': x_objects, - 'Pattern': patterns, - 'Shading': shadings, + 'ExtGState': pydyf.Dictionary(), + 'XObject': pydyf.Dictionary(), + 'Pattern': pydyf.Dictionary(), + 'Shading': pydyf.Dictionary(), + 'ColorSpace': self._resources['ColorSpace'], 'Font': None, # Will be set by _use_references }) extra = pydyf.Dictionary({ @@ -199,16 +186,14 @@ def add_group(self, x, y, width, height): 'CS': '/DeviceRGB', }), }) - group = self.clone( - states=states, x_objects=x_objects, patterns=patterns, shadings=shadings, - extra=extra) - group.id = f'x{len(self._x_objects)}' - self._x_objects[group.id] = group + group = self.clone(resources=resources, extra=extra) + group.id = f'x{len(self._resources['XObject'])}' + self._resources['XObject'][group.id] = group return group def add_image(self, image, interpolate, ratio): image_name = f'i{image.id}{int(interpolate)}' - self._x_objects[image_name] = None # Set by write_pdf + self._resources['XObject'][image_name] = None # Set by write_pdf if image_name in self._images: # Reuse image already stored in document self._images[image_name]['dpi_ratios'].add(ratio) @@ -223,15 +208,12 @@ def add_image(self, image, interpolate, ratio): return image_name def add_pattern(self, x, y, width, height, repeat_width, repeat_height, matrix): - states = pydyf.Dictionary() - x_objects = pydyf.Dictionary() - patterns = pydyf.Dictionary() - shadings = pydyf.Dictionary() resources = pydyf.Dictionary({ - 'ExtGState': states, - 'XObject': x_objects, - 'Pattern': patterns, - 'Shading': shadings, + 'ExtGState': pydyf.Dictionary(), + 'XObject': pydyf.Dictionary(), + 'Pattern': pydyf.Dictionary(), + 'Shading': pydyf.Dictionary(), + 'ColorSpace': self._resources['ColorSpace'], 'Font': None, # Will be set by _use_references }) extra = pydyf.Dictionary({ @@ -245,11 +227,9 @@ def add_pattern(self, x, y, width, height, repeat_width, repeat_height, matrix): 'Matrix': pydyf.Array(matrix.values), 'Resources': resources, }) - pattern = self.clone( - states=states, x_objects=x_objects, patterns=patterns, shadings=shadings, - extra=extra) - pattern.id = f'p{len(self._patterns)}' - self._patterns[pattern.id] = pattern + pattern = self.clone(resources=resources, extra=extra) + pattern.id = f'p{len(self._resources['Pattern'])}' + self._resources['Pattern'][pattern.id] = pattern return pattern def add_shading(self, shading_type, color_space, domain, coords, extend, @@ -263,8 +243,8 @@ def add_shading(self, shading_type, color_space, domain, coords, extend, }) if extend: shading['Extend'] = pydyf.Array((b'true', b'true')) - shading.id = f's{len(self._shadings)}' - self._shadings[shading.id] = shading + shading.id = f's{len(self._resources['Shading'])}' + self._resources['Shading'][shading.id] = shading return shading def begin_marked_content(self, box, mcid=False, tag=None):