diff --git a/tests/test_api.py b/tests/test_api.py
index 009b3b71..ad25c3a9 100644
--- a/tests/test_api.py
+++ b/tests/test_api.py
@@ -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', (
('', ['/Tx', '/V ()']),
('', ['/Tx', '/V ()']),
diff --git a/weasyprint/__init__.py b/weasyprint/__init__.py
index 2908524e..03aff07d 100644
--- a/weasyprint/__init__.py
+++ b/weasyprint/__init__.py
@@ -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,
diff --git a/weasyprint/__main__.py b/weasyprint/__main__.py
index fcb3ff05..afb48ab9 100644
--- a/weasyprint/__main__.py
+++ b/weasyprint/__main__.py
@@ -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')
diff --git a/weasyprint/pdf/__init__.py b/weasyprint/pdf/__init__.py
index b6f2b2b2..15d12e81 100644
--- a/weasyprint/pdf/__init__.py
+++ b/weasyprint/pdf/__init__.py
@@ -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(
diff --git a/weasyprint/pdf/pdfa.py b/weasyprint/pdf/pdfa.py
index 974c8acb..4f069e2b 100644
--- a/weasyprint/pdf/pdfa.py
+++ b/weasyprint/pdf/pdfa.py
@@ -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}),
}