weasyprint 68.0__tar.gz → 68.1__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (199) hide show
  1. {weasyprint-68.0 → weasyprint-68.1}/PKG-INFO +1 -1
  2. {weasyprint-68.0 → weasyprint-68.1}/docs/changelog.rst +54 -0
  3. {weasyprint-68.0 → weasyprint-68.1}/tests/css/test_math.py +111 -0
  4. {weasyprint-68.0 → weasyprint-68.1}/tests/draw/svg/test_clip.py +28 -0
  5. {weasyprint-68.0 → weasyprint-68.1}/tests/draw/svg/test_text.py +24 -1
  6. {weasyprint-68.0 → weasyprint-68.1}/tests/draw/test_text.py +56 -0
  7. {weasyprint-68.0 → weasyprint-68.1}/tests/test_api.py +12 -0
  8. {weasyprint-68.0 → weasyprint-68.1}/weasyprint/__init__.py +1 -1
  9. {weasyprint-68.0 → weasyprint-68.1}/weasyprint/css/__init__.py +3 -4
  10. {weasyprint-68.0 → weasyprint-68.1}/weasyprint/draw/text.py +8 -8
  11. {weasyprint-68.0 → weasyprint-68.1}/weasyprint/layout/block.py +22 -16
  12. {weasyprint-68.0 → weasyprint-68.1}/weasyprint/layout/preferred.py +29 -23
  13. {weasyprint-68.0 → weasyprint-68.1}/weasyprint/pdf/stream.py +2 -0
  14. {weasyprint-68.0 → weasyprint-68.1}/weasyprint/svg/__init__.py +1 -2
  15. {weasyprint-68.0 → weasyprint-68.1}/weasyprint/svg/defs.py +0 -6
  16. {weasyprint-68.0 → weasyprint-68.1}/weasyprint/svg/text.py +4 -3
  17. {weasyprint-68.0 → weasyprint-68.1}/weasyprint/text/line_break.py +4 -5
  18. {weasyprint-68.0 → weasyprint-68.1}/weasyprint/urls.py +24 -7
  19. {weasyprint-68.0 → weasyprint-68.1}/LICENSE +0 -0
  20. {weasyprint-68.0 → weasyprint-68.1}/README.rst +0 -0
  21. {weasyprint-68.0 → weasyprint-68.1}/docs/api_reference.rst +0 -0
  22. {weasyprint-68.0 → weasyprint-68.1}/docs/common_use_cases.rst +0 -0
  23. {weasyprint-68.0 → weasyprint-68.1}/docs/conf.py +0 -0
  24. {weasyprint-68.0 → weasyprint-68.1}/docs/contribute.rst +0 -0
  25. {weasyprint-68.0 → weasyprint-68.1}/docs/first_steps.rst +0 -0
  26. {weasyprint-68.0 → weasyprint-68.1}/docs/going_further.rst +0 -0
  27. {weasyprint-68.0 → weasyprint-68.1}/docs/index.rst +0 -0
  28. {weasyprint-68.0 → weasyprint-68.1}/docs/manpage.rst +0 -0
  29. {weasyprint-68.0 → weasyprint-68.1}/docs/support.rst +0 -0
  30. {weasyprint-68.0 → weasyprint-68.1}/pyproject.toml +0 -0
  31. {weasyprint-68.0 → weasyprint-68.1}/tests/__init__.py +0 -0
  32. {weasyprint-68.0 → weasyprint-68.1}/tests/conftest.py +0 -0
  33. {weasyprint-68.0 → weasyprint-68.1}/tests/css/__init__.py +0 -0
  34. {weasyprint-68.0 → weasyprint-68.1}/tests/css/test_common.py +0 -0
  35. {weasyprint-68.0 → weasyprint-68.1}/tests/css/test_counters.py +0 -0
  36. {weasyprint-68.0 → weasyprint-68.1}/tests/css/test_descriptors.py +0 -0
  37. {weasyprint-68.0 → weasyprint-68.1}/tests/css/test_errors.py +0 -0
  38. {weasyprint-68.0 → weasyprint-68.1}/tests/css/test_expanders.py +0 -0
  39. {weasyprint-68.0 → weasyprint-68.1}/tests/css/test_fonts.py +0 -0
  40. {weasyprint-68.0 → weasyprint-68.1}/tests/css/test_layers.py +0 -0
  41. {weasyprint-68.0 → weasyprint-68.1}/tests/css/test_nesting.py +0 -0
  42. {weasyprint-68.0 → weasyprint-68.1}/tests/css/test_pages.py +0 -0
  43. {weasyprint-68.0 → weasyprint-68.1}/tests/css/test_target.py +0 -0
  44. {weasyprint-68.0 → weasyprint-68.1}/tests/css/test_ua.py +0 -0
  45. {weasyprint-68.0 → weasyprint-68.1}/tests/css/test_validation.py +0 -0
  46. {weasyprint-68.0 → weasyprint-68.1}/tests/css/test_variables.py +0 -0
  47. {weasyprint-68.0 → weasyprint-68.1}/tests/draw/__init__.py +0 -0
  48. {weasyprint-68.0 → weasyprint-68.1}/tests/draw/svg/__init__.py +0 -0
  49. {weasyprint-68.0 → weasyprint-68.1}/tests/draw/svg/test_bounding_box.py +0 -0
  50. {weasyprint-68.0 → weasyprint-68.1}/tests/draw/svg/test_defs.py +0 -0
  51. {weasyprint-68.0 → weasyprint-68.1}/tests/draw/svg/test_gradients.py +0 -0
  52. {weasyprint-68.0 → weasyprint-68.1}/tests/draw/svg/test_images.py +0 -0
  53. {weasyprint-68.0 → weasyprint-68.1}/tests/draw/svg/test_markers.py +0 -0
  54. {weasyprint-68.0 → weasyprint-68.1}/tests/draw/svg/test_opacity.py +0 -0
  55. {weasyprint-68.0 → weasyprint-68.1}/tests/draw/svg/test_paths.py +0 -0
  56. {weasyprint-68.0 → weasyprint-68.1}/tests/draw/svg/test_patterns.py +0 -0
  57. {weasyprint-68.0 → weasyprint-68.1}/tests/draw/svg/test_shapes.py +0 -0
  58. {weasyprint-68.0 → weasyprint-68.1}/tests/draw/svg/test_transform.py +0 -0
  59. {weasyprint-68.0 → weasyprint-68.1}/tests/draw/svg/test_units.py +0 -0
  60. {weasyprint-68.0 → weasyprint-68.1}/tests/draw/svg/test_visibility.py +0 -0
  61. {weasyprint-68.0 → weasyprint-68.1}/tests/draw/test_absolute.py +0 -0
  62. {weasyprint-68.0 → weasyprint-68.1}/tests/draw/test_background.py +0 -0
  63. {weasyprint-68.0 → weasyprint-68.1}/tests/draw/test_before_after.py +0 -0
  64. {weasyprint-68.0 → weasyprint-68.1}/tests/draw/test_box.py +0 -0
  65. {weasyprint-68.0 → weasyprint-68.1}/tests/draw/test_cmyk_color_profiles.py +0 -0
  66. {weasyprint-68.0 → weasyprint-68.1}/tests/draw/test_column.py +0 -0
  67. {weasyprint-68.0 → weasyprint-68.1}/tests/draw/test_current_color.py +0 -0
  68. {weasyprint-68.0 → weasyprint-68.1}/tests/draw/test_float.py +0 -0
  69. {weasyprint-68.0 → weasyprint-68.1}/tests/draw/test_footnote.py +0 -0
  70. {weasyprint-68.0 → weasyprint-68.1}/tests/draw/test_footnote_column.py +0 -0
  71. {weasyprint-68.0 → weasyprint-68.1}/tests/draw/test_gradient.py +0 -0
  72. {weasyprint-68.0 → weasyprint-68.1}/tests/draw/test_image.py +0 -0
  73. {weasyprint-68.0 → weasyprint-68.1}/tests/draw/test_leader.py +0 -0
  74. {weasyprint-68.0 → weasyprint-68.1}/tests/draw/test_list.py +0 -0
  75. {weasyprint-68.0 → weasyprint-68.1}/tests/draw/test_opacity.py +0 -0
  76. {weasyprint-68.0 → weasyprint-68.1}/tests/draw/test_overflow.py +0 -0
  77. {weasyprint-68.0 → weasyprint-68.1}/tests/draw/test_page.py +0 -0
  78. {weasyprint-68.0 → weasyprint-68.1}/tests/draw/test_table.py +0 -0
  79. {weasyprint-68.0 → weasyprint-68.1}/tests/draw/test_transform.py +0 -0
  80. {weasyprint-68.0 → weasyprint-68.1}/tests/draw/test_visibility.py +0 -0
  81. {weasyprint-68.0 → weasyprint-68.1}/tests/draw/test_whitespace.py +0 -0
  82. {weasyprint-68.0 → weasyprint-68.1}/tests/layout/__init__.py +0 -0
  83. {weasyprint-68.0 → weasyprint-68.1}/tests/layout/test_block.py +0 -0
  84. {weasyprint-68.0 → weasyprint-68.1}/tests/layout/test_column.py +0 -0
  85. {weasyprint-68.0 → weasyprint-68.1}/tests/layout/test_flex.py +0 -0
  86. {weasyprint-68.0 → weasyprint-68.1}/tests/layout/test_float.py +0 -0
  87. {weasyprint-68.0 → weasyprint-68.1}/tests/layout/test_footnotes.py +0 -0
  88. {weasyprint-68.0 → weasyprint-68.1}/tests/layout/test_grid.py +0 -0
  89. {weasyprint-68.0 → weasyprint-68.1}/tests/layout/test_image.py +0 -0
  90. {weasyprint-68.0 → weasyprint-68.1}/tests/layout/test_inline.py +0 -0
  91. {weasyprint-68.0 → weasyprint-68.1}/tests/layout/test_inline_block.py +0 -0
  92. {weasyprint-68.0 → weasyprint-68.1}/tests/layout/test_list.py +0 -0
  93. {weasyprint-68.0 → weasyprint-68.1}/tests/layout/test_page.py +0 -0
  94. {weasyprint-68.0 → weasyprint-68.1}/tests/layout/test_position.py +0 -0
  95. {weasyprint-68.0 → weasyprint-68.1}/tests/layout/test_preferred.py +0 -0
  96. {weasyprint-68.0 → weasyprint-68.1}/tests/layout/test_table.py +0 -0
  97. {weasyprint-68.0 → weasyprint-68.1}/tests/resources/acid2-reference.html +0 -0
  98. {weasyprint-68.0 → weasyprint-68.1}/tests/resources/acid2-test.html +0 -0
  99. {weasyprint-68.0 → weasyprint-68.1}/tests/resources/blue.jpg +0 -0
  100. {weasyprint-68.0 → weasyprint-68.1}/tests/resources/border.svg +0 -0
  101. {weasyprint-68.0 → weasyprint-68.1}/tests/resources/border2.svg +0 -0
  102. {weasyprint-68.0 → weasyprint-68.1}/tests/resources/cmyk.icc +0 -0
  103. {weasyprint-68.0 → weasyprint-68.1}/tests/resources/cmyk_with_icc.jpg +0 -0
  104. {weasyprint-68.0 → weasyprint-68.1}/tests/resources/cmyk_without_icc.jpg +0 -0
  105. {weasyprint-68.0 → weasyprint-68.1}/tests/resources/doc1.html +0 -0
  106. {weasyprint-68.0 → weasyprint-68.1}/tests/resources/doc1_UTF-16BE.html +0 -0
  107. {weasyprint-68.0 → weasyprint-68.1}/tests/resources/icon.png +0 -0
  108. {weasyprint-68.0 → weasyprint-68.1}/tests/resources/latin1-test.css +0 -0
  109. {weasyprint-68.0 → weasyprint-68.1}/tests/resources/logo_small.png +0 -0
  110. {weasyprint-68.0 → weasyprint-68.1}/tests/resources/mask.svg +0 -0
  111. {weasyprint-68.0 → weasyprint-68.1}/tests/resources/mini_ua.css +0 -0
  112. {weasyprint-68.0 → weasyprint-68.1}/tests/resources/not-optimized-exif.jpg +0 -0
  113. {weasyprint-68.0 → weasyprint-68.1}/tests/resources/not-optimized.jpg +0 -0
  114. {weasyprint-68.0 → weasyprint-68.1}/tests/resources/pattern-transparent.svg +0 -0
  115. {weasyprint-68.0 → weasyprint-68.1}/tests/resources/pattern.gif +0 -0
  116. {weasyprint-68.0 → weasyprint-68.1}/tests/resources/pattern.palette.png +0 -0
  117. {weasyprint-68.0 → weasyprint-68.1}/tests/resources/pattern.png +0 -0
  118. {weasyprint-68.0 → weasyprint-68.1}/tests/resources/pattern.svg +0 -0
  119. {weasyprint-68.0 → weasyprint-68.1}/tests/resources/really-a-png.svg +0 -0
  120. {weasyprint-68.0 → weasyprint-68.1}/tests/resources/really-a-svg.png +0 -0
  121. {weasyprint-68.0 → weasyprint-68.1}/tests/resources/sheet2.css +0 -0
  122. {weasyprint-68.0 → weasyprint-68.1}/tests/resources/sub_directory/sheet1.css +0 -0
  123. {weasyprint-68.0 → weasyprint-68.1}/tests/resources/tests_ua.css +0 -0
  124. {weasyprint-68.0 → weasyprint-68.1}/tests/resources/user.css +0 -0
  125. {weasyprint-68.0 → weasyprint-68.1}/tests/resources/utf8-test.css +0 -0
  126. {weasyprint-68.0 → weasyprint-68.1}/tests/resources/weasyprint.otb +0 -0
  127. {weasyprint-68.0 → weasyprint-68.1}/tests/resources/weasyprint.otf +0 -0
  128. {weasyprint-68.0 → weasyprint-68.1}/tests/resources/weasyprint.woff +0 -0
  129. {weasyprint-68.0 → weasyprint-68.1}/tests/test_acid2.py +0 -0
  130. {weasyprint-68.0 → weasyprint-68.1}/tests/test_boxes.py +0 -0
  131. {weasyprint-68.0 → weasyprint-68.1}/tests/test_fonts.py +0 -0
  132. {weasyprint-68.0 → weasyprint-68.1}/tests/test_pdf.py +0 -0
  133. {weasyprint-68.0 → weasyprint-68.1}/tests/test_presentational_hints.py +0 -0
  134. {weasyprint-68.0 → weasyprint-68.1}/tests/test_stacking.py +0 -0
  135. {weasyprint-68.0 → weasyprint-68.1}/tests/test_text.py +0 -0
  136. {weasyprint-68.0 → weasyprint-68.1}/tests/test_unicode.py +0 -0
  137. {weasyprint-68.0 → weasyprint-68.1}/tests/test_url.py +0 -0
  138. {weasyprint-68.0 → weasyprint-68.1}/tests/testing_utils.py +0 -0
  139. {weasyprint-68.0 → weasyprint-68.1}/weasyprint/__main__.py +0 -0
  140. {weasyprint-68.0 → weasyprint-68.1}/weasyprint/anchors.py +0 -0
  141. {weasyprint-68.0 → weasyprint-68.1}/weasyprint/css/computed_values.py +0 -0
  142. {weasyprint-68.0 → weasyprint-68.1}/weasyprint/css/counters.py +0 -0
  143. {weasyprint-68.0 → weasyprint-68.1}/weasyprint/css/functions.py +0 -0
  144. {weasyprint-68.0 → weasyprint-68.1}/weasyprint/css/html5_ph.css +0 -0
  145. {weasyprint-68.0 → weasyprint-68.1}/weasyprint/css/html5_ua.css +0 -0
  146. {weasyprint-68.0 → weasyprint-68.1}/weasyprint/css/html5_ua_form.css +0 -0
  147. {weasyprint-68.0 → weasyprint-68.1}/weasyprint/css/media_queries.py +0 -0
  148. {weasyprint-68.0 → weasyprint-68.1}/weasyprint/css/properties.py +0 -0
  149. {weasyprint-68.0 → weasyprint-68.1}/weasyprint/css/targets.py +0 -0
  150. {weasyprint-68.0 → weasyprint-68.1}/weasyprint/css/tokens.py +0 -0
  151. {weasyprint-68.0 → weasyprint-68.1}/weasyprint/css/units.py +0 -0
  152. {weasyprint-68.0 → weasyprint-68.1}/weasyprint/css/validation/__init__.py +0 -0
  153. {weasyprint-68.0 → weasyprint-68.1}/weasyprint/css/validation/descriptors.py +0 -0
  154. {weasyprint-68.0 → weasyprint-68.1}/weasyprint/css/validation/expanders.py +0 -0
  155. {weasyprint-68.0 → weasyprint-68.1}/weasyprint/css/validation/properties.py +0 -0
  156. {weasyprint-68.0 → weasyprint-68.1}/weasyprint/document.py +0 -0
  157. {weasyprint-68.0 → weasyprint-68.1}/weasyprint/draw/__init__.py +0 -0
  158. {weasyprint-68.0 → weasyprint-68.1}/weasyprint/draw/border.py +0 -0
  159. {weasyprint-68.0 → weasyprint-68.1}/weasyprint/draw/color.py +0 -0
  160. {weasyprint-68.0 → weasyprint-68.1}/weasyprint/formatting_structure/boxes.py +0 -0
  161. {weasyprint-68.0 → weasyprint-68.1}/weasyprint/formatting_structure/build.py +0 -0
  162. {weasyprint-68.0 → weasyprint-68.1}/weasyprint/html.py +0 -0
  163. {weasyprint-68.0 → weasyprint-68.1}/weasyprint/images.py +0 -0
  164. {weasyprint-68.0 → weasyprint-68.1}/weasyprint/layout/__init__.py +0 -0
  165. {weasyprint-68.0 → weasyprint-68.1}/weasyprint/layout/absolute.py +0 -0
  166. {weasyprint-68.0 → weasyprint-68.1}/weasyprint/layout/background.py +0 -0
  167. {weasyprint-68.0 → weasyprint-68.1}/weasyprint/layout/column.py +0 -0
  168. {weasyprint-68.0 → weasyprint-68.1}/weasyprint/layout/flex.py +0 -0
  169. {weasyprint-68.0 → weasyprint-68.1}/weasyprint/layout/float.py +0 -0
  170. {weasyprint-68.0 → weasyprint-68.1}/weasyprint/layout/grid.py +0 -0
  171. {weasyprint-68.0 → weasyprint-68.1}/weasyprint/layout/inline.py +0 -0
  172. {weasyprint-68.0 → weasyprint-68.1}/weasyprint/layout/leader.py +0 -0
  173. {weasyprint-68.0 → weasyprint-68.1}/weasyprint/layout/min_max.py +0 -0
  174. {weasyprint-68.0 → weasyprint-68.1}/weasyprint/layout/page.py +0 -0
  175. {weasyprint-68.0 → weasyprint-68.1}/weasyprint/layout/percent.py +0 -0
  176. {weasyprint-68.0 → weasyprint-68.1}/weasyprint/layout/replaced.py +0 -0
  177. {weasyprint-68.0 → weasyprint-68.1}/weasyprint/layout/table.py +0 -0
  178. {weasyprint-68.0 → weasyprint-68.1}/weasyprint/logger.py +0 -0
  179. {weasyprint-68.0 → weasyprint-68.1}/weasyprint/matrix.py +0 -0
  180. {weasyprint-68.0 → weasyprint-68.1}/weasyprint/pdf/__init__.py +0 -0
  181. {weasyprint-68.0 → weasyprint-68.1}/weasyprint/pdf/anchors.py +0 -0
  182. {weasyprint-68.0 → weasyprint-68.1}/weasyprint/pdf/debug.py +0 -0
  183. {weasyprint-68.0 → weasyprint-68.1}/weasyprint/pdf/fonts.py +0 -0
  184. {weasyprint-68.0 → weasyprint-68.1}/weasyprint/pdf/metadata.py +0 -0
  185. {weasyprint-68.0 → weasyprint-68.1}/weasyprint/pdf/pdfa.py +0 -0
  186. {weasyprint-68.0 → weasyprint-68.1}/weasyprint/pdf/pdfua.py +0 -0
  187. {weasyprint-68.0 → weasyprint-68.1}/weasyprint/pdf/pdfx.py +0 -0
  188. {weasyprint-68.0 → weasyprint-68.1}/weasyprint/pdf/sRGB2014.icc +0 -0
  189. {weasyprint-68.0 → weasyprint-68.1}/weasyprint/pdf/tags.py +0 -0
  190. {weasyprint-68.0 → weasyprint-68.1}/weasyprint/stacking.py +0 -0
  191. {weasyprint-68.0 → weasyprint-68.1}/weasyprint/svg/bounding_box.py +0 -0
  192. {weasyprint-68.0 → weasyprint-68.1}/weasyprint/svg/css.py +0 -0
  193. {weasyprint-68.0 → weasyprint-68.1}/weasyprint/svg/images.py +0 -0
  194. {weasyprint-68.0 → weasyprint-68.1}/weasyprint/svg/path.py +0 -0
  195. {weasyprint-68.0 → weasyprint-68.1}/weasyprint/svg/shapes.py +0 -0
  196. {weasyprint-68.0 → weasyprint-68.1}/weasyprint/svg/utils.py +0 -0
  197. {weasyprint-68.0 → weasyprint-68.1}/weasyprint/text/constants.py +0 -0
  198. {weasyprint-68.0 → weasyprint-68.1}/weasyprint/text/ffi.py +0 -0
  199. {weasyprint-68.0 → weasyprint-68.1}/weasyprint/text/fonts.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: weasyprint
3
- Version: 68.0
3
+ Version: 68.1
4
4
  Summary: The Awesome Document Factory
5
5
  Keywords: html,css,pdf,converter
6
6
  Author-email: Simon Sapin <simon.sapin@exyr.org>
@@ -2,6 +2,60 @@ Changelog
2
2
  =========
3
3
 
4
4
 
5
+ Version 68.1
6
+ ------------
7
+
8
+ Released on 2026-02-06.
9
+
10
+ Bug fixes:
11
+
12
+ * `#2662 <https://github.com/Kozea/WeasyPrint/issues/2662>`_:
13
+ Don’t crash when SVG clip paths are not in defs tags
14
+ * `#2665 <https://github.com/Kozea/WeasyPrint/issues/2665>`_:
15
+ Fix position of box bounding box
16
+ * `#2663 <https://github.com/Kozea/WeasyPrint/issues/2663>`_:
17
+ Fix transparency with Acrobat and Edge
18
+ * `#2666 <https://github.com/Kozea/WeasyPrint/issues/2666>`_:
19
+ Don’t rely on random default font to define test page size
20
+ * `#2670 <https://github.com/Kozea/WeasyPrint/issues/2670>`_:
21
+ Fix pattern detection of URL schemes
22
+ * `#2671 <https://github.com/Kozea/WeasyPrint/pull/2671>`_:
23
+ Improve API compatibility between URLFetcherResponse and addinfourl
24
+ * `#2672 <https://github.com/Kozea/WeasyPrint/issues/2672>`_:
25
+ Fix charset for old URL fetcher requests
26
+ * `#2675 <https://github.com/Kozea/WeasyPrint/pull/2675>`_,
27
+ `#2673 <https://github.com/Kozea/WeasyPrint/issues/2673>`_:
28
+ Fix calc for many properties
29
+
30
+ Contributors:
31
+
32
+ * Guillaume Ayoub
33
+
34
+ Backers and sponsors:
35
+
36
+ * Spacinov
37
+ * Syslifters
38
+ * Kobalt
39
+ * Simon Sapin
40
+ * Grip Angebotssoftware
41
+ * Manuel Barkhau
42
+ * Simonsoft
43
+ * KontextWork
44
+ * Menutech
45
+ * TrainingSparkle
46
+ * Healthchecks.io
47
+ * Method B
48
+ * FieldHub
49
+ * Hammerbacher
50
+ * Yanal-Yves Fargialla
51
+ * Morntag
52
+ * Piloterr
53
+ * Xavid
54
+ * Charlie S.
55
+ * Prothesis Dental Solutions
56
+ * Kai DeLorenzo
57
+
58
+
5
59
  Version 68.0
6
60
  ------------
7
61
 
@@ -94,6 +94,7 @@ def test_math_functions(width):
94
94
  'calc(100px, 100px)',
95
95
  'calc(100px * 100px)',
96
96
  'calc(100 * 100)',
97
+ 'calc(calc(100vw))',
97
98
  'calc(0.1)',
98
99
  'calc(-1)',
99
100
  'min()',
@@ -106,6 +107,7 @@ def test_math_functions(width):
106
107
  'max("10px")',
107
108
  'max(10, 50px)',
108
109
  'calc(max(100, 5px) * 10px)',
110
+ 'calc(100* - max(56px, 1rem)',
109
111
  'clamp()',
110
112
  'clamp(10px)',
111
113
  'clamp(10px, 50px)',
@@ -236,6 +238,37 @@ def test_math_functions_percentage_and_font_unit(css_property):
236
238
  assert len(math_logs) == len(logs)
237
239
 
238
240
 
241
+ @pytest.mark.parametrize('display', [
242
+ 'block', 'inline', 'flex', 'grid',
243
+ 'list', 'list-item',
244
+ 'table', 'table-row-group', 'table-cell',
245
+ 'inline-block', 'inline-table', 'inline-flex', 'inline-grid',
246
+ ])
247
+ def test_math_functions_display_size(display):
248
+ # Regression test for #2673.
249
+ render_pages(f'''
250
+ <div style="display: {display};
251
+ min-width: calc(50% + 1em); max-width: calc(50% + 1em); width: calc(50% + 1em);
252
+ min-height: calc(50% + 1em); max-height: calc(50% + 1em); height: calc(50% + 1em)
253
+ ">
254
+ <div style="
255
+ min-width: calc(50% + 1em); max-width: calc(50% + 1em); width: calc(50% + 1em);
256
+ min-height: calc(50% + 1em); max-height: calc(50% + 1em); height: calc(50% + 1em)
257
+ "></div>
258
+ </div>
259
+ ''')
260
+
261
+
262
+ @assert_no_logs
263
+ def test_math_functions_hyphenate():
264
+ render_pages('''
265
+ <div lang="en"
266
+ style="hyphens: auto; hyphenate-limit-zone: calc(1em + 100%); width: 2em">
267
+ absolute
268
+ </div>
269
+ ''')
270
+
271
+
239
272
  @assert_no_logs
240
273
  def test_math_functions_gradient():
241
274
  render_pages('''
@@ -262,3 +295,81 @@ def test_math_functions_gradient_color():
262
295
  rgba(10, 20, calc(30), calc(80%)) 10%,
263
296
  hsl(calc(10 + 10), 20%, 20%) 80%"></div>
264
297
  ''')
298
+
299
+
300
+ @assert_no_logs
301
+ def test_math_image_min_content_calc():
302
+ render_pages('''
303
+ <table>
304
+ <td>
305
+ <img src="pattern.png" style="
306
+ height: calc(10% + 1em);
307
+ width: calc(10% + 1em);
308
+ max-height: calc(10% + 1em);
309
+ max-width: calc(10% + 1em);
310
+ min-height: calc(10% + 1em);
311
+ min-width: calc(10% + 1em);
312
+ ">
313
+ ''')
314
+
315
+
316
+ @assert_no_logs
317
+ def test_math_image_min_content_auto_width_calc():
318
+ render_pages('''
319
+ <table>
320
+ <td>
321
+ <img src="pattern.png" style="
322
+ height: calc(10% + 1em);
323
+ max-height: calc(10% + 1em);
324
+ max-width: calc(10% + 1em);
325
+ min-height: calc(10% + 1em);
326
+ min-width: calc(10% + 1em);
327
+ ">
328
+ ''')
329
+
330
+
331
+ @assert_no_logs
332
+ def test_math_image_min_content_auto_width_height_calc():
333
+ render_pages('''
334
+ <table>
335
+ <td>
336
+ <img src="pattern.png" style="
337
+ max-height: calc(10% + 1em);
338
+ max-width: calc(10% + 1em);
339
+ min-height: calc(10% + 1em);
340
+ min-width: calc(10% + 1em);
341
+ ">
342
+ ''')
343
+
344
+
345
+ @assert_no_logs
346
+ def test_math_table_margin():
347
+ render_pages('<table style="margin: calc(1em + 10%)">')
348
+
349
+
350
+ @assert_no_logs
351
+ def test_math_grid_padding():
352
+ render_pages('''
353
+ <article style="display: grid">
354
+ <div style="box-sizing: border-box; border: 1px solid;
355
+ padding: calc(2px + 10%); width: 7px">a</div>
356
+ </article>
357
+ ''')
358
+
359
+
360
+ @assert_no_logs
361
+ def test_math_table_column():
362
+ render_pages('''
363
+ <table style="width: 200px">
364
+ <colgroup style="width: calc(1em + 10%)">
365
+ <col />
366
+ </colgroup>
367
+ <col style="width: calc(1em + 10%)" />
368
+ <tbody>
369
+ <tr>
370
+ <td>a</td>
371
+ <td>a</td>
372
+ </tr>
373
+ </tbody>
374
+ </table>
375
+ ''')
@@ -96,3 +96,31 @@ def test_clip_path_group_on_group(assert_pixels):
96
96
  </g>
97
97
  </svg>
98
98
  ''')
99
+
100
+
101
+ @assert_no_logs
102
+ def test_clip_path_outside_defs(assert_pixels):
103
+ # Regression test for #2662.
104
+ assert_pixels('''
105
+ _________
106
+ _________
107
+ __RRRRR__
108
+ __RBBBR__
109
+ __RBBBR__
110
+ __RBBBR__
111
+ __RRRRR__
112
+ _________
113
+ _________
114
+ ''', '''
115
+ <style>
116
+ @page { size: 9px }
117
+ svg { display: block }
118
+ </style>
119
+ <svg width="9px" height="9px" xmlns="http://www.w3.org/2000/svg">
120
+ <clipPath id="clip">
121
+ <rect x="2" y="2" width="5" height="5" />
122
+ </clipPath>
123
+ <rect x="2" y="2" width="5" height="5" stroke-width="2"
124
+ stroke="red" fill="blue" clip-path="url(#clip)" />
125
+ </svg>
126
+ ''')
@@ -30,7 +30,7 @@ def test_text_stroke(assert_pixels):
30
30
  _BBBBBBBBBBBB_______
31
31
  ''', '''
32
32
  <style>
33
- @page { font-size: 1px; size: 20em 8ex }
33
+ @page { font-size: 1px; size: 20em 4em }
34
34
  svg { display: block }
35
35
  </style>
36
36
  <svg width="20px" height="4px" xmlns="http://www.w3.org/2000/svg">
@@ -687,3 +687,26 @@ def test_mixed_explicit_and_shorthand_across_levels(assert_pixels):
687
687
  </svg>
688
688
  ''',
689
689
  )
690
+
691
+
692
+ @assert_no_logs
693
+ def test_text_fill_opacity(assert_pixels):
694
+ # Regression text for #2665.
695
+ assert_pixels('''
696
+ ______
697
+ _ssss_
698
+ _ssss_
699
+ _ssss_
700
+ _ssss_
701
+ ______
702
+ ''', '''
703
+ <style>
704
+ @page { size: 6px 6px }
705
+ svg { display: block }
706
+ </style>
707
+ <svg width="6px" height="6px" xmlns="http://www.w3.org/2000/svg">
708
+ <text x="1" y="4" font="4px weasyprint" fill="red" opacity="0.5">
709
+ A
710
+ </text>
711
+ </svg>
712
+ ''')
@@ -667,6 +667,34 @@ def test_text_underline_offset_percentage(assert_pixels):
667
667
  <div>abc</div>''')
668
668
 
669
669
 
670
+ def test_text_underline_offset_calc(assert_pixels):
671
+ assert_pixels('''
672
+ _____________
673
+ _zzzzzzzzzzz_
674
+ _zRRRRRRRRRz_
675
+ _zRRRRRRRRRz_
676
+ _zzzzzzzzzzz_
677
+ _zzzzzzzzzzz_
678
+ _zBBBBBBBBBz_
679
+ _zzzzzzzzzzz_
680
+ _____________
681
+ ''', '''
682
+ <style>
683
+ @page {
684
+ size: 13px 9px;
685
+ margin: 2px;
686
+ }
687
+ body {
688
+ color: red;
689
+ font-family: weasyprint;
690
+ font-size: 3px;
691
+ text-decoration: underline blue;
692
+ text-underline-offset: calc(0.5em + 20%);
693
+ }
694
+ </style>
695
+ <div>abc</div>''')
696
+
697
+
670
698
  def test_text_underline_thickness(assert_pixels):
671
699
  assert_pixels('''
672
700
  _____________
@@ -723,6 +751,34 @@ def test_text_underline_thickness_percentage(assert_pixels):
723
751
  <div>abc</div>''')
724
752
 
725
753
 
754
+ def test_text_underline_thickness_calc(assert_pixels):
755
+ assert_pixels('''
756
+ _____________
757
+ _zzzzzzzzzzz_
758
+ _zRRRRRRRRRz_
759
+ _zRRRRRRRRRz_
760
+ _zzzzzzzzzzz_
761
+ _zzzzzzzzzzz_
762
+ _zBBBBBBBBBz_
763
+ _zBBBBBBBBBz_
764
+ _zzzzzzzzzzz_
765
+ ''', '''
766
+ <style>
767
+ @page {
768
+ size: 13px 9px;
769
+ margin: 2px;
770
+ }
771
+ body {
772
+ color: red;
773
+ font-family: weasyprint;
774
+ font-size: 3px;
775
+ text-decoration: underline blue calc(0.5em + 50%);
776
+ text-underline-offset: 2px;
777
+ }
778
+ </style>
779
+ <div>abc</div>''')
780
+
781
+
726
782
  def test_text_overline(assert_pixels):
727
783
  # Ascent value seems to be a bit random, don’t try to get the exact
728
784
  # position of the line
@@ -10,6 +10,7 @@ import threading
10
10
  import unicodedata
11
11
  import wsgiref.simple_server
12
12
  import zlib
13
+ from base64 import b64encode
13
14
  from functools import partial
14
15
  from pathlib import Path
15
16
  from urllib.parse import urljoin, uses_relative
@@ -704,6 +705,17 @@ def test_allowed_protocols(command):
704
705
  _run(command, f'<img src="{path2url(resource_path("pattern.png"))}">'.encode())
705
706
 
706
707
 
708
+ @assert_no_logs
709
+ @pytest.mark.parametrize('command', [
710
+ '- -',
711
+ '--allowed-protocols data - -',
712
+ '--allowed-protocols File,Data - -',
713
+ ])
714
+ def test_allowed_protocols_data(command):
715
+ data = b64encode(resource_path('pattern.png').read_bytes()).decode()
716
+ _run(command, f'<img src="data:image/png;base64,{data}">'.encode())
717
+
718
+
707
719
  @pytest.mark.parametrize('command', [
708
720
  '--allowed-protocols http - -',
709
721
  '--allowed-protocols http,https - -',
@@ -14,7 +14,7 @@ import cssselect2
14
14
  import tinycss2
15
15
  import tinyhtml5
16
16
 
17
- VERSION = __version__ = '68.0'
17
+ VERSION = __version__ = '68.1'
18
18
 
19
19
  #: Default values for command-line and Python API rendering options. See
20
20
  #: :func:`__main__.main` to learn more about specific options for
@@ -779,7 +779,6 @@ def resolve_math(token, computed=None, property_name=None, refer_to=None):
779
779
  return
780
780
 
781
781
  args = []
782
- original_token = token
783
782
  function = Function(token)
784
783
  if function.name is None:
785
784
  return
@@ -795,7 +794,7 @@ def resolve_math(token, computed=None, property_name=None, refer_to=None):
795
794
  if function.name == 'calc':
796
795
  result = _resolve_calc_sum(computed, args[0], property_name, refer_to)
797
796
  if result is None:
798
- return original_token
797
+ return
799
798
  else:
800
799
  return tokenize(result)
801
800
 
@@ -1194,10 +1193,10 @@ class ComputedStyle(dict):
1194
1193
  try:
1195
1194
  token = resolve_math(function, self, key)
1196
1195
  except PercentageInMath:
1197
- token = None
1198
- if token is None:
1199
1196
  solved_tokens.append(function)
1200
1197
  else:
1198
+ if token is None:
1199
+ raise Exception
1201
1200
  solved_tokens.append(token)
1202
1201
  original_key = key.replace('_', '-')
1203
1202
  value = validate_non_shorthand(solved_tokens, original_key)[0][1]
@@ -17,6 +17,8 @@ from .color import get_color
17
17
 
18
18
  def draw_text(stream, textbox, offset_x, text_overflow, block_ellipsis):
19
19
  """Draw a textbox to a pydyf stream."""
20
+ from ..layout.percent import percentage
21
+
20
22
  # Pango crashes with font-size: 0.
21
23
  assert textbox.style['font_size']
22
24
 
@@ -30,11 +32,10 @@ def draw_text(stream, textbox, offset_x, text_overflow, block_ellipsis):
30
32
  if 'underline' in text_decoration_values or 'overline' in text_decoration_values:
31
33
  if textbox.style['text_decoration_thickness'] in ('auto', 'from-font'):
32
34
  thickness = textbox.pango_layout.underline_thickness
33
- elif textbox.style['text_decoration_thickness'].unit == '%':
34
- ratio = textbox.style['text_decoration_thickness'].value / 100
35
- thickness = textbox.style['font_size'] * ratio
36
35
  else:
37
- thickness = textbox.style['text_decoration_thickness'].value
36
+ thickness = percentage(
37
+ textbox.style['text_decoration_thickness'], textbox.style,
38
+ textbox.style['font_size'])
38
39
  if 'overline' in text_decoration_values:
39
40
  offset_y = (
40
41
  textbox.baseline - textbox.pango_layout.ascent + thickness / 2)
@@ -44,11 +45,10 @@ def draw_text(stream, textbox, offset_x, text_overflow, block_ellipsis):
44
45
  if 'underline' in text_decoration_values:
45
46
  if textbox.style['text_underline_offset'] == 'auto':
46
47
  underline_offset = - textbox.pango_layout.underline_position
47
- elif textbox.style['text_underline_offset'].unit == '%':
48
- ratio = textbox.style['text_underline_offset'].value / 100
49
- underline_offset = textbox.style['font_size'] * ratio
50
48
  else:
51
- underline_offset = textbox.style['text_underline_offset'].value
49
+ underline_offset = percentage(
50
+ textbox.style['text_underline_offset'], textbox.style,
51
+ textbox.style['font_size'])
52
52
  offset_y = textbox.baseline + underline_offset + thickness / 2
53
53
  draw_text_decoration(
54
54
  stream, textbox, offset_x, offset_y, thickness,
@@ -301,7 +301,7 @@ def _out_of_flow_layout(context, box, index, child, new_children,
301
301
  return stop, resume_at, new_child, out_of_flow_resume_at
302
302
 
303
303
 
304
- def _break_line(context, box, line, new_children, next_lines, page_is_empty, index,
304
+ def _break_line(context, box, line, new_children, needed, page_is_empty, index,
305
305
  skip_stack, resume_at, absolute_boxes, fixed_boxes):
306
306
  """Break line where allowed by orphans and widows.
307
307
 
@@ -316,7 +316,6 @@ def _break_line(context, box, line, new_children, next_lines, page_is_empty, ind
316
316
  return True, False, resume_at
317
317
  # How many lines we need on the next page to satisfy widows
318
318
  # -1 for the current line.
319
- needed = max(box.style['widows'] - 1 - next_lines, 0)
320
319
  if needed > over_orphans and not page_is_empty:
321
320
  # Total number of lines < orphans + widows
322
321
  remove_placeholders(context, line.children, absolute_boxes, fixed_boxes)
@@ -377,15 +376,21 @@ def _linebox_layout(context, box, index, child, new_children, page_is_empty,
377
376
  # If we couldn’t break the line before but can break now, first try to
378
377
  # report footnotes and see if we don’t overflow.
379
378
  could_break_before = can_break_now = True
380
- next_lines = len(tuple(lines_iterator))
379
+ needed = box.style['widows'] - 1
380
+ for _ in lines_iterator:
381
+ needed -= 1
382
+ # Don’t iterate over all lines as it can be long.
383
+ if needed == -1:
384
+ break
381
385
  if len(new_children) + 1 < box.style['orphans']:
382
386
  can_break_now = False
383
- elif next_lines < box.style['widows']:
387
+ elif needed >= 0:
384
388
  can_break_now = False
385
389
  if len(new_children) < box.style['orphans']:
386
390
  could_break_before = False
387
- elif next_lines + 1 < box.style['widows']:
391
+ elif needed > 0:
388
392
  could_break_before = False
393
+ needed = max(0, needed)
389
394
  report = not context.in_column and can_break_now and not could_break_before
390
395
  reported_footnotes = 0
391
396
  while report and context.current_page_footnotes:
@@ -397,9 +402,8 @@ def _linebox_layout(context, box, index, child, new_children, page_is_empty,
397
402
  break
398
403
  else:
399
404
  abort, stop, resume_at = _break_line(
400
- context, box, line, new_children, next_lines,
401
- page_is_empty, index, skip_stack, resume_at, absolute_boxes,
402
- fixed_boxes)
405
+ context, box, line, new_children, needed, page_is_empty, index,
406
+ skip_stack, resume_at, absolute_boxes, fixed_boxes)
403
407
 
404
408
  # Revert reported footnotes, as they’ve been reported starting from the last
405
409
  # one.
@@ -414,8 +418,7 @@ def _linebox_layout(context, box, index, child, new_children, page_is_empty,
414
418
  # "When an unforced page break occurs here, both the adjoining
415
419
  # ‘margin-top’ and ‘margin-bottom’ are set to zero."
416
420
  # See issue #115.
417
- elif page_is_empty and context.overflows_page(
418
- bottom_space, new_position_y):
421
+ elif page_is_empty and context.overflows_page(bottom_space, new_position_y):
419
422
  # Remove the top border when a page is empty and the box is
420
423
  # too high to be drawn in one page
421
424
  new_position_y -= box.margin_top
@@ -433,8 +436,7 @@ def _linebox_layout(context, box, index, child, new_children, page_is_empty,
433
436
  overflow = (
434
437
  overflow or
435
438
  context.reported_footnotes or
436
- context.overflows_page(
437
- bottom_space, new_position_y + offset_y))
439
+ context.overflows_page(bottom_space, new_position_y + offset_y))
438
440
  if overflow:
439
441
  context.report_footnote(footnote)
440
442
  # If we've put other content on this page, then we may want
@@ -443,11 +445,15 @@ def _linebox_layout(context, box, index, child, new_children, page_is_empty,
443
445
  # even try.
444
446
  if new_children or not page_is_empty:
445
447
  if footnote.style['footnote_policy'] == 'line':
446
- next_lines = len(tuple(lines_iterator))
448
+ if needed := box.style['widows'] - 1:
449
+ for _ in lines_iterator:
450
+ needed -= 1
451
+ # Don’t iterate over all lines as it can be long.
452
+ if needed == 0:
453
+ break
447
454
  abort, stop, resume_at = _break_line(
448
- context, box, line, new_children,
449
- next_lines, page_is_empty, index,
450
- skip_stack, resume_at, absolute_boxes,
455
+ context, box, line, new_children, needed, page_is_empty,
456
+ index, skip_stack, resume_at, absolute_boxes,
451
457
  fixed_boxes)
452
458
  break_linebox = True
453
459
  break
@@ -109,7 +109,7 @@ def _block_content_width(context, box, function, outer):
109
109
 
110
110
  for value in ('padding_left', 'padding_right'):
111
111
  style_value = box.style[value]
112
- if style_value != 'auto':
112
+ if style_value != 'auto' and not check_math(style_value):
113
113
  if style_value.unit.lower() == 'px':
114
114
  width -= style_value.value
115
115
  else:
@@ -175,7 +175,7 @@ def margin_width(box, width, left=True, right=True):
175
175
  (['margin_right', 'padding_right'] if right else [])
176
176
  ):
177
177
  style_value = box.style[value]
178
- if style_value != 'auto':
178
+ if style_value != 'auto' and not check_math(style_value):
179
179
  if style_value.unit.lower() == 'px':
180
180
  width += style_value.value
181
181
  else:
@@ -263,7 +263,7 @@ def inline_max_content_width(context, box, outer=True, is_line_start=False):
263
263
  def column_group_content_width(context, box):
264
264
  """Return the *-content width for a ``TableColumnGroupBox``."""
265
265
  width = box.style['width']
266
- if width == 'auto' or width.unit == '%':
266
+ if width == 'auto' or check_math(width) or width.unit == '%':
267
267
  width = 0
268
268
  else:
269
269
  assert width.unit.lower() == 'px'
@@ -597,21 +597,22 @@ def table_and_columns_preferred_widths(context, box, outer=True):
597
597
  # Define constrainedness
598
598
  constrainedness = [False for i in range(grid_width)]
599
599
  for i in range(grid_width):
600
- if (column_groups[i] and column_groups[i].style['width'] != 'auto' and
601
- column_groups[i].style['width'].unit != '%'):
602
- constrainedness[i] = True
603
- continue
604
- if (columns[i] and columns[i].style['width'] != 'auto' and
605
- columns[i].style['width'].unit != '%'):
606
- constrainedness[i] = True
607
- continue
608
- for cell in zipped_grid[i]:
609
- if (cell and cell.colspan == 1 and
610
- cell.style['width'] != 'auto' and
611
- not check_math(cell.style['width']) and
612
- cell.style['width'].unit != '%'):
600
+ if column_groups[i]:
601
+ width = column_groups[i].style['width']
602
+ if width != 'auto' and not check_math(width) and width.unit != '%':
613
603
  constrainedness[i] = True
614
- break
604
+ continue
605
+ if columns[i]:
606
+ width = columns[i].style['width']
607
+ if width != 'auto' and not check_math(width) and width.unit != '%':
608
+ constrainedness[i] = True
609
+ continue
610
+ for cell in zipped_grid[i]:
611
+ if cell and cell.colspan == 1:
612
+ width = cell.style['width']
613
+ if width != 'auto' and not check_math(width) and width.unit != '%':
614
+ constrainedness[i] = True
615
+ break
615
616
 
616
617
  intrinsic_percentages = [
617
618
  min(percentage, 100 - sum(intrinsic_percentages[:i]))
@@ -679,7 +680,8 @@ def table_and_columns_preferred_widths(context, box, outer=True):
679
680
  sum(max_content_widths), large_percentage_contribution,
680
681
  *small_percentage_contributions]))
681
682
 
682
- if table.style['width'] != 'auto' and table.style['width'].unit.lower() == 'px':
683
+ width = table.style['width']
684
+ if width != 'auto' and not check_math(width) and width.unit.lower() == 'px':
683
685
  # "percentages on the following properties are treated instead as
684
686
  # though they were the following: width: auto"
685
687
  # https://dbaron.org/css/intrinsic/#outer-intrinsic
@@ -714,12 +716,16 @@ def replaced_min_content_width(box, outer=True):
714
716
  width = box.style['width']
715
717
  if width == 'auto':
716
718
  height = box.style['height']
717
- if height == 'auto' or height.unit == '%':
719
+ if height == 'auto' or check_math(height) or height.unit == '%':
718
720
  height = 'auto'
719
721
  else:
720
722
  assert height.unit.lower() == 'px'
721
723
  height = height.value
722
- if box.style['max_width'] != 'auto' and box.style['max_width'].unit == '%':
724
+ unknown_max_width = (
725
+ box.style['max_width'] != 'auto' and
726
+ not check_math(box.style['max_width']) and
727
+ box.style['max_width'].unit == '%')
728
+ if unknown_max_width:
723
729
  # See https://drafts.csswg.org/css-sizing/#intrinsic-contribution
724
730
  width = 0
725
731
  else:
@@ -730,7 +736,7 @@ def replaced_min_content_width(box, outer=True):
730
736
  width, _ = default_image_sizing(
731
737
  intrinsic_width, intrinsic_height, intrinsic_ratio, 'auto',
732
738
  height, default_width=0, default_height=0)
733
- elif box.style['width'].unit == '%':
739
+ elif check_math(box.style['width']) or box.style['width'].unit == '%':
734
740
  # See https://drafts.csswg.org/css-sizing/#intrinsic-contribution
735
741
  width = 0
736
742
  else:
@@ -744,7 +750,7 @@ def replaced_max_content_width(box, outer=True):
744
750
  width = box.style['width']
745
751
  if width == 'auto':
746
752
  height = box.style['height']
747
- if height == 'auto' or height.unit == '%':
753
+ if height == 'auto' or check_math(height) or height.unit == '%':
748
754
  height = 'auto'
749
755
  else:
750
756
  assert height.unit.lower() == 'px'
@@ -756,7 +762,7 @@ def replaced_max_content_width(box, outer=True):
756
762
  width, _ = default_image_sizing(
757
763
  intrinsic_width, intrinsic_height, intrinsic_ratio, 'auto', height,
758
764
  default_width=300, default_height=150)
759
- elif box.style['width'].unit == '%':
765
+ elif check_math(box.style['width']) or box.style['width'].unit == '%':
760
766
  # See https://drafts.csswg.org/css-sizing/#intrinsic-contribution
761
767
  width = 0
762
768
  else:
@@ -201,6 +201,8 @@ class Stream(pydyf.Stream):
201
201
  'Group': pydyf.Dictionary({
202
202
  'Type': '/Group',
203
203
  'S': '/Transparency',
204
+ 'I': 'true',
205
+ 'CS': '/DeviceRGB',
204
206
  }),
205
207
  })
206
208
  group = self.clone(resources=resources, extra=extra)