1
1
mirror of https://github.com/Kozea/WeasyPrint.git synced 2024-08-17 16:40:45 +03:00

Add option to include default sRGB profile for RGB colors

This commit is contained in:
Guillaume Ayoub 2024-07-09 11:54:38 +02:00
parent dd7cee28a0
commit 5c8b3a2433
5 changed files with 45 additions and 31 deletions

View File

@ -521,6 +521,16 @@ def test_partial_pdf_custom_metadata():
assert b'value' in stdout
def test_pdf_srgb():
stdout = _run('--srgb --uncompressed-pdf - -', b'test')
assert b'sRGB' in stdout
def test_pdf_no_srgb():
stdout = _run('--uncompressed-pdf - -', b'test')
assert b'sRGB' not in stdout
@pytest.mark.parametrize('html, fields', (
('<input>', ['/Tx', '/V ()']),
('<input value="">', ['/Tx', '/V ()']),

View File

@ -45,6 +45,9 @@ VERSION = __version__ = '62.3'
#: Whether custom HTML metadata should be stored in the generated PDF.
#: :param bool presentational_hints:
#: Whether HTML presentational hints are followed.
#: :param bool srgb:
#: Whether sRGB color profile should be included and set as default for
#: device-dependant RGB colors.
#: :param bool optimize_images:
#: Whether size of embedded images should be optimized, with no quality
#: loss.
@ -71,6 +74,7 @@ DEFAULT_OPTIONS = {
'uncompressed_pdf': False,
'custom_metadata': False,
'presentational_hints': False,
'srgb': False,
'optimize_images': False,
'jpeg_quality': None,
'dpi': None,

View File

@ -98,6 +98,9 @@ PARSER.add_argument(
PARSER.add_argument(
'-p', '--presentational-hints', action='store_true',
help='follow HTML presentational hints')
PARSER.add_argument(
'--srgb', action='store_true',
help='include sRGB color profile')
PARSER.add_argument(
'--optimize-images', action='store_true',
help='optimize size of embedded images with no quality loss')

View File

@ -1,5 +1,7 @@
"""PDF generation management."""
from importlib.resources import files
import pydyf
from .. import VERSION, Attachment
@ -116,11 +118,14 @@ def generate_pdf(document, target, zoom, **options):
# Set properties according to PDF variants
mark = False
srgb = options['srgb']
variant = options['pdf_variant']
if variant:
variant_function, properties = VARIANTS[variant]
if 'mark' in properties:
mark = properties['mark']
if 'srgb' in properties:
srgb = properties['srgb']
pdf = pydyf.PDF()
states = pydyf.Dictionary()
@ -294,6 +299,22 @@ def generate_pdf(document, target, zoom, **options):
pdf.catalog['Names'] = pydyf.Dictionary()
pdf.catalog['Names']['Dests'] = dests
if srgb:
# Add ICC profile.
profile = pydyf.Stream(
[(files(__package__) / 'sRGB2014.icc').read_bytes()],
pydyf.Dictionary({'N': 3, 'Alternate': '/DeviceRGB'}),
compress=compress)
pdf.add_object(profile)
pdf.catalog['OutputIntents'] = pydyf.Array([
pydyf.Dictionary({
'Type': '/OutputIntent',
'S': '/GTS_PDFA1',
'OutputConditionIdentifier': pydyf.String('sRGB IEC61966-2.1'),
'DestOutputProfile': profile.reference,
}),
])
# Apply PDF variants functions
if variant:
variant_function(

View File

@ -1,15 +1,5 @@
"""PDF/A generation."""
try:
# Available in Python 3.9+
from importlib.resources import files
except ImportError:
# Deprecated in Python 3.11+
from importlib.resources import read_binary
else:
def read_binary(package, resource):
return (files(package) / resource).read_bytes()
from functools import partial
import pydyf
@ -20,20 +10,6 @@ from .metadata import add_metadata
def pdfa(pdf, metadata, document, page_streams, attachments, compress,
version, variant):
"""Set metadata for PDF/A documents."""
# Add ICC profile.
profile = pydyf.Stream(
[read_binary(__package__, 'sRGB2014.icc')],
pydyf.Dictionary({'N': 3, 'Alternate': '/DeviceRGB'}),
compress=compress)
pdf.add_object(profile)
pdf.catalog['OutputIntents'] = pydyf.Array([
pydyf.Dictionary({
'Type': '/OutputIntent',
'S': '/GTS_PDFA1',
'OutputConditionIdentifier': pydyf.String('sRGB IEC61966-2.1'),
'DestOutputProfile': profile.reference,
}),
])
# Handle attachments.
if version == 1:
@ -95,23 +71,23 @@ def pdfa(pdf, metadata, document, page_streams, attachments, compress,
VARIANTS = {
'pdf/a-1b': (
partial(pdfa, version=1, variant='B'),
{'version': '1.4', 'identifier': True}),
{'version': '1.4', 'identifier': True, 'srgb': True}),
'pdf/a-2b': (
partial(pdfa, version=2, variant='B'),
{'version': '1.7', 'identifier': True}),
{'version': '1.7', 'identifier': True, 'srgb': True}),
'pdf/a-3b': (
partial(pdfa, version=3, variant='B'),
{'version': '1.7', 'identifier': True}),
{'version': '1.7', 'identifier': True, 'srgb': True}),
'pdf/a-4b': (
partial(pdfa, version=4, variant='B'),
{'version': '2.0', 'identifier': True}),
{'version': '2.0', 'identifier': True, 'srgb': True}),
'pdf/a-2u': (
partial(pdfa, version=2, variant='U'),
{'version': '1.7', 'identifier': True}),
{'version': '1.7', 'identifier': True, 'srgb': True}),
'pdf/a-3u': (
partial(pdfa, version=3, variant='U'),
{'version': '1.7', 'identifier': True}),
{'version': '1.7', 'identifier': True, 'srgb': True}),
'pdf/a-4u': (
partial(pdfa, version=4, variant='U'),
{'version': '2.0', 'identifier': True}),
{'version': '2.0', 'identifier': True, 'srgb': True}),
}