Skip to content

Commit

Permalink
Add option to include default sRGB profile for RGB colors
Browse files Browse the repository at this point in the history
  • Loading branch information
liZe committed Jul 10, 2024
1 parent dd7cee2 commit 5c8b3a2
Show file tree
Hide file tree
Showing 5 changed files with 45 additions and 31 deletions.
10 changes: 10 additions & 0 deletions tests/test_api.py
Original file line number Diff line number Diff line change
Expand Up @@ -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 ()']),
Expand Down
4 changes: 4 additions & 0 deletions weasyprint/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,9 @@
#: 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.
Expand All @@ -71,6 +74,7 @@
'uncompressed_pdf': False,
'custom_metadata': False,
'presentational_hints': False,
'srgb': False,
'optimize_images': False,
'jpeg_quality': None,
'dpi': None,
Expand Down
3 changes: 3 additions & 0 deletions weasyprint/__main__.py
Original file line number Diff line number Diff line change
Expand Up @@ -98,6 +98,9 @@ def docstring(self):
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')
Expand Down
21 changes: 21 additions & 0 deletions weasyprint/pdf/__init__.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
"""PDF generation management."""

from importlib.resources import files

import pydyf

from .. import VERSION, Attachment
Expand Down Expand Up @@ -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()
Expand Down Expand Up @@ -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(
Expand Down
38 changes: 7 additions & 31 deletions weasyprint/pdf/pdfa.py
Original file line number Diff line number Diff line change
@@ -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
Expand All @@ -20,20 +10,6 @@ def read_binary(package, resource):
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:
Expand Down Expand Up @@ -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}),
}

0 comments on commit 5c8b3a2

Please sign in to comment.