From affdacf925e743f6a290da24a585ba7e9271cab4 Mon Sep 17 00:00:00 2001 From: Daniel Baumann Date: Sun, 3 Mar 2024 15:08:09 +0100 Subject: Merging upstream version 0.9.0. Signed-off-by: Daniel Baumann --- pydyf/__init__.py | 53 +++++++++++++++++++++++++++++++++++++++++++++++------ 1 file changed, 47 insertions(+), 6 deletions(-) (limited to 'pydyf') diff --git a/pydyf/__init__.py b/pydyf/__init__.py index 3d0b122..d8e1d7b 100755 --- a/pydyf/__init__.py +++ b/pydyf/__init__.py @@ -3,28 +3,27 @@ A low-level PDF generator. """ +import base64 import re import zlib from codecs import BOM_UTF16_BE from hashlib import md5 from math import ceil, log -VERSION = __version__ = '0.7.0' +VERSION = __version__ = '0.9.0' def _to_bytes(item): """Convert item to bytes.""" if isinstance(item, bytes): return item - elif isinstance(item, Object): - return item.data elif isinstance(item, float): if item.is_integer(): - return f'{int(item):d}'.encode('ascii') + return str(int(item)).encode('ascii') else: return f'{item:f}'.rstrip('0').encode('ascii') - elif isinstance(item, int): - return f'{item:d}'.encode('ascii') + elif isinstance(item, Object): + return item.data return str(item).encode('ascii') @@ -280,6 +279,10 @@ class Stream(Object): """Set text rendering mode.""" self.stream.append(_to_bytes(mode) + b' Tr') + def set_text_rise(self, height): + """Set text rise.""" + self.stream.append(_to_bytes(height) + b' Ts') + def set_line_cap(self, line_cap): """Set line cap style.""" self.stream.append(_to_bytes(line_cap) + b' J') @@ -362,6 +365,44 @@ class Stream(Object): _to_bytes(a), _to_bytes(b), _to_bytes(c), _to_bytes(d), _to_bytes(e), _to_bytes(f), b'cm'))) + def inline_image(self, width, height, color_space, bpc, raw_data): + """Add an inline image. + + :param width: The width of the image. + :type width: :obj:`int` + :param height: The height of the image. + :type height: :obj:`int` + :param colorspace: The color space of the image, f.e. RGB, Gray. + :type colorspace: :obj:`str` + :param bpc: The bits per component. 1 for BW, 8 for grayscale. + :type bpc: :obj:`int` + :param raw_data: The raw pixel data. + + """ + if self.compress: + data = zlib.compress(raw_data) + else: + data = raw_data + enc_data = base64.a85encode(data) + self.stream.append( + b' '.join( + ( + b'BI', + b'/W', _to_bytes(width), + b'/H', _to_bytes(height), + b'/BPC', _to_bytes(bpc), + b'/CS', + b'/Device' + color_space.encode(), + b'/F', + b'[/A85 /Fl]' if self.compress else b'/A85', + b'/L', _to_bytes(len(enc_data) + 2), + b'ID', + enc_data + b'~>', + b'EI', + ) + ) + ) + @property def data(self): stream = b'\n'.join(_to_bytes(item) for item in self.stream) -- cgit v1.2.3