commit python-weasyprint for openSUSE:Factory
Script 'mail_helper' called by obssrc Hello community, here is the log from the commit of package python-weasyprint for openSUSE:Factory checked in at 2024-07-01 11:21:02 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Comparing /work/SRC/openSUSE:Factory/python-weasyprint (Old) and /work/SRC/openSUSE:Factory/.python-weasyprint.new.18349 (New) ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Package is "python-weasyprint" Mon Jul 1 11:21:02 2024 rev:14 rq:1184080 version:62.3 Changes: -------- --- /work/SRC/openSUSE:Factory/python-weasyprint/python-weasyprint.changes 2024-06-10 17:38:42.921354784 +0200 +++ /work/SRC/openSUSE:Factory/.python-weasyprint.new.18349/python-weasyprint.changes 2024-07-01 11:21:41.109934422 +0200 @@ -1,0 +2,20 @@ +Sun Jun 30 08:16:19 UTC 2024 - Dirk Müller <dmueller@suse.com> + +- update to 62.3: + * #2174: Fix extra width distribution for auto table layout + * #2175: Don’t compress PDF metadata for PDF/A-1 + * Set default PDF variant values in options before + generating PDF + * Avoid PDF artifacts when drawing 0-width borders + * Don’t duplicate column when container is split on + multiple pages + * Don’t set default Fontconfig values for unset + properties + * Fix layout when all footnotes are removed from the + footnote area + * Make items overflowing grid wrap to the next + row/column + * Don’t append useless tracks when grid elements are + positioned + +------------------------------------------------------------------- Old: ---- weasyprint-62.2.tar.gz New: ---- weasyprint-62.3.tar.gz ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Other differences: ------------------ ++++++ python-weasyprint.spec ++++++ --- /var/tmp/diff_new_pack.UHuHBa/_old 2024-07-01 11:21:41.985966336 +0200 +++ /var/tmp/diff_new_pack.UHuHBa/_new 2024-07-01 11:21:41.989966482 +0200 @@ -29,7 +29,7 @@ %{?sle15_python_module_pythons} Name: python-weasyprint -Version: 62.2 +Version: 62.3 Release: 0 Summary: Python module to convert web documents to PDF License: BSD-3-Clause ++++++ weasyprint-62.2.tar.gz -> weasyprint-62.3.tar.gz ++++++ diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/weasyprint-62.2/PKG-INFO new/weasyprint-62.3/PKG-INFO --- old/weasyprint-62.2/PKG-INFO 1970-01-01 01:00:00.000000000 +0100 +++ new/weasyprint-62.3/PKG-INFO 1970-01-01 01:00:00.000000000 +0100 @@ -1,6 +1,6 @@ Metadata-Version: 2.1 Name: weasyprint -Version: 62.2 +Version: 62.3 Summary: The Awesome Document Factory Keywords: html,css,pdf,converter Author-email: Simon Sapin <simon.sapin@exyr.org> diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/weasyprint-62.2/docs/changelog.rst new/weasyprint-62.3/docs/changelog.rst --- old/weasyprint-62.2/docs/changelog.rst 2024-06-04 16:15:52.039573200 +0200 +++ new/weasyprint-62.3/docs/changelog.rst 2024-06-21 17:45:25.688718300 +0200 @@ -2,6 +2,57 @@ ========= +Version 62.3 +------------ + +Released on 2024-06-21. + +Bug fixes: + +* `#2174 <https://github.com/Kozea/WeasyPrint/issues/2174>`_: + Fix extra width distribution for auto table layout +* `#2175 <https://github.com/Kozea/WeasyPrint/issues/2175>`_: + Don’t compress PDF metadata for PDF/A-1 +* `61f8bb3 <https://github.com/Kozea/WeasyPrint/commit/61f8bb3>`_: + Set default PDF variant values in options before generating PDF +* `2c4351e <https://github.com/Kozea/WeasyPrint/commit/2c4351e>`_: + Avoid PDF artifacts when drawing 0-width borders +* `d9d7f62 <https://github.com/Kozea/WeasyPrint/commit/d9d7f62>`_: + Don’t duplicate column when container is split on multiple pages +* `4617b94 <https://github.com/Kozea/WeasyPrint/commit/4617b94>`_: + Don’t set default Fontconfig values for unset properties +* `4c81663 <https://github.com/Kozea/WeasyPrint/commit/4c81663>`_: + Fix layout when all footnotes are removed from the footnote area +* `#2184 <https://github.com/Kozea/WeasyPrint/issues/2184>`_: + Make items overflowing grid wrap to the next row/column +* `#2187 <https://github.com/Kozea/WeasyPrint/issues/2187>`_: + Don’t append useless tracks when grid elements are positioned + +Contributors: + +* Guillaume Ayoub + +Backers and sponsors: + +* Spacinov +* Kobalt +* Grip Angebotssoftware +* Manuel Barkhau +* SimonSoft +* Menutech +* KontextWork +* Simon Sapin +* René Fritz +* TrainingSparkle +* Healthchecks.io +* Hammerbacher +* Docraptor +* Yanal-Yvez Fargialla +* Douwe van Loenen +* Morntag +* Xavid + + Version 62.2 ------------ diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/weasyprint-62.2/tests/draw/test_footnote.py new/weasyprint-62.3/tests/draw/test_footnote.py --- old/weasyprint-62.2/tests/draw/test_footnote.py 2024-02-18 21:57:44.177647400 +0100 +++ new/weasyprint-62.3/tests/draw/test_footnote.py 2024-06-21 17:37:15.485403300 +0200 @@ -124,6 +124,57 @@ @assert_no_logs +def test_footnote_multiple_margin(assert_pixels): + assert_pixels(''' + RRRR___ + RRRR___ + RRRR___ + RRRR___ + RRRR___ + RRRR___ + RRRRRR_ + RRRRRR_ + _______ + _______ + + RRRR___ + RRRR___ + _______ + _______ + _______ + _______ + RRRRRR_ + RRRRRR_ + RRRRRR_ + RRRRRR_ + ''', ''' + <style> + @font-face {src: url(weasyprint.otf); font-family: weasyprint} + @page { + size: 7px 10px; + + @footnote { + margin-top: 1px; + } + } + div { + color: red; + font-family: weasyprint; + font-size: 2px; + line-height: 1; + } + span { + float: footnote; + } + </style> + <div>ab</div> + <div>ab</div> + <div>ab</div> + <div>a<span>d</span><span>e</span></div> + <div>ab</div>''') + + +@assert_no_logs def test_footnote_with_absolute(assert_pixels): assert_pixels(''' _RRRR____ diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/weasyprint-62.2/tests/layout/test_column.py new/weasyprint-62.3/tests/layout/test_column.py --- old/weasyprint-62.2/tests/layout/test_column.py 2024-05-27 10:15:26.140362500 +0200 +++ new/weasyprint-62.3/tests/layout/test_column.py 2024-06-21 17:37:15.486403200 +0200 @@ -1057,3 +1057,29 @@ </style> <div style="columns: 2; column-width: 100px; width: 10px">abc def</div> ''') + + +@assert_no_logs +def test_columns_regression_7(): + page1, page2 = render_pages(''' + <style> + @page { size: 50px 10px } + body { font-size: 2px; line-height: 1 } + </style> + <div style="height: 8px"></div> + <div style="column-count: 2"> + <div>a</div> + <div style="break-inside: avoid">b<br>c<br>d</div> + </div> + ''') + html, = page1.children + body, = html.children + div, = body.children + assert div.position_y == 0 + assert not div.children + html, = page2.children + body, = html.children + div, = body.children + column1, column2 = div.children + assert column1.position_y == 0 + assert column2.position_y == 0 diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/weasyprint-62.2/tests/layout/test_grid.py new/weasyprint-62.3/tests/layout/test_grid.py --- old/weasyprint-62.2/tests/layout/test_grid.py 2024-06-03 16:31:53.664926500 +0200 +++ new/weasyprint-62.3/tests/layout/test_grid.py 2024-06-21 17:37:15.486403200 +0200 @@ -281,6 +281,40 @@ @assert_no_logs +def test_grid_template_areas_span_overflow(): + page, = render_pages(''' + <style> + @font-face { src: url(weasyprint.otf); font-family: weasyprint } + article { + display: grid; + font-family: weasyprint; + font-size: 2px; + grid-template-columns: 50% 50%; + line-height: 1; + width: 10px; + } + </style> + <article> + <div style="">a</div> + <div style="grid-column: span 2">a</div> + <div style="">a</div> + </article> + ''') + html, = page.children + body, = html.children + article, = body.children + div_a1, div_a2, div_a3 = article.children + assert div_a1.position_x == div_a2.position_x == div_a3.position_x == 0 + assert div_a1.position_y == 0 + assert div_a2.position_y == 2 + assert div_a3.position_y == 4 + assert div_a1.width == div_a3.width == 5 + assert div_a2.width == 10 + assert div_a1.height == div_a2.height == div_a3.height == 2 + assert article.width == 10 + + +@assert_no_logs def test_grid_template_areas_extra_span(): page, = render_pages(''' <style> @@ -954,3 +988,35 @@ assert div_e.height == 4 assert article.height == 4 assert article.width == 12 + + +@assert_no_logs +def test_grid_gap_explicit_grid_column(): + # Regression test for https://github.com/Kozea/WeasyPrint/issues/2187 + page, = render_pages(''' + <style> + @font-face { src: url(weasyprint.otf); font-family: weasyprint } + article { + display: grid; + font-family: weasyprint; + font-size: 2px; + gap: 2px; + grid-template-columns: 1fr; + line-height: 1; + width: 12px; + } + </style> + <article> + <div>a</div> + <div style="grid-column: 1">b</div> + </article> + ''') + html, = page.children + body, = html.children + article, = body.children + div_a, div_b = article.children + assert div_a.position_x == div_b.position_x == 0 + assert div_a.position_y == 0 + assert div_b.position_y == 4 + assert article.height == 6 + assert article.width == 12 diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/weasyprint-62.2/tests/layout/test_table.py new/weasyprint-62.3/tests/layout/test_table.py --- old/weasyprint-62.2/tests/layout/test_table.py 2024-05-27 10:15:26.141362700 +0200 +++ new/weasyprint-62.3/tests/layout/test_table.py 2024-06-21 17:37:15.487403400 +0200 @@ -1298,11 +1298,14 @@ def test_layout_table_auto_42(): # Cell width as percentage in auto-width table page, = render_pages(''' - <table> + <style> + @font-face { src: url(weasyprint.otf); font-family: weasyprint } + </style> + <table style="font-family: weasyprint"> <tbody> <tr> - <td style="width: 70px">a a a a a a a a</td> - <td style="width: 30%">a a a a a a a a</td> + <td style="width: 70px">aaa</td> + <td style="width: 25%">aaa</td> </tr> </tbody> </table> @@ -1314,9 +1317,9 @@ row_group, = table.children row, = row_group.children td_1, td_2 = row.children - assert td_1.width == 70 - assert td_2.width == 30 - assert table.width == 100 + assert td_2.width == 16 * 3 # Percentage column is set to max-width + assert td_1.width == (16 * 3) * 3 # Pixel column constraint is ignored + assert table.width == (16 * 3) * 4 @assert_no_logs @@ -1555,6 +1558,32 @@ @assert_no_logs +def test_layout_table_auto_51(): + # Test regression: + # https://github.com/Kozea/WeasyPrint/issues/2174 + page, = render_pages(''' + <style> + @font-face { src: url(weasyprint.otf); font-family: weasyprint } + </style> + <table style="font-family: weasyprint; width: 100px"> + <tr> + <td style="width: 29.9999%">a</td> + <td style="width: 70%">a</td> + </tr> + </table> + ''') + html, = page.children + body, = html.children + table_wrapper, = body.children + table, = table_wrapper.children + row_group, = table.children + row_1, = row_group.children + td_1, td_2 = row_1.children + assert abs(td_1.width - 30) < 0.1 + assert abs(td_2.width - 70) < 0.1 + + +@assert_no_logs @pytest.mark.parametrize( 'body_width, table_width, check_width, positions, widths', ( ('500px', '230px', 220, [170, 5], [45, 155]), diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/weasyprint-62.2/tests/test_api.py new/weasyprint-62.3/tests/test_api.py --- old/weasyprint-62.2/tests/test_api.py 2024-06-04 16:04:34.852718000 +0200 +++ new/weasyprint-62.3/tests/test_api.py 2024-06-21 17:37:15.488403300 +0200 @@ -464,6 +464,12 @@ _run(f'--pdf-variant=pdf/a-{version}b - -', b'test') +def test_pdfa1b_cidset(): + stdout = _run('--pdf-variant=pdf/a-1b --uncompressed-pdf - -', b'test') + assert b'PDF-1.4' in stdout + assert b'CIDSet' in stdout + + def test_pdfua(): stdout = _run('--pdf-variant=pdf/ua-1 --uncompressed-pdf - -', b'test') assert b'part="1"' in stdout diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/weasyprint-62.2/weasyprint/__init__.py new/weasyprint-62.3/weasyprint/__init__.py --- old/weasyprint-62.2/weasyprint/__init__.py 2024-06-04 16:04:46.491948600 +0200 +++ new/weasyprint-62.3/weasyprint/__init__.py 2024-06-21 17:37:27.972615000 +0200 @@ -15,7 +15,7 @@ import html5lib import tinycss2 -VERSION = __version__ = '62.2' +VERSION = __version__ = '62.3' #: Default values for command-line and Python API options. See #: :func:`__main__.main` to learn more about specific options for diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/weasyprint-62.2/weasyprint/document.py new/weasyprint-62.3/weasyprint/document.py --- old/weasyprint-62.2/weasyprint/document.py 2024-06-04 16:04:34.854718200 +0200 +++ new/weasyprint-62.3/weasyprint/document.py 2024-06-21 17:37:15.489403200 +0200 @@ -388,24 +388,24 @@ new_options = DEFAULT_OPTIONS.copy() new_options.update(options) options = new_options - pdf = generate_pdf(self, target, zoom, **options) - - identifier = options['pdf_identifier'] - compress = not options['uncompressed_pdf'] - version = options['pdf_version'] - variant = options['pdf_variant'] # Set default PDF version for PDF variants. - if version is None and variant: + if variant := options['pdf_variant']: _, properties = VARIANTS[variant] - if 'version' in properties: - version = properties['version'] - if 'identifier' in properties and not identifier: - identifier = properties['identifier'] + if 'version' in properties and not options['pdf_version']: + options['pdf_version'] = properties['version'] + if 'identifier' in properties and not options['pdf_identifier']: + options['pdf_identifier'] = properties['identifier'] + + pdf = generate_pdf(self, target, zoom, **options) if finisher: finisher(self, pdf) + identifier = options['pdf_identifier'] + compress = not options['uncompressed_pdf'] + version = options['pdf_version'] + if target is None: output = io.BytesIO() pdf.write(output, version, identifier, compress) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/weasyprint-62.2/weasyprint/draw.py new/weasyprint-62.3/weasyprint/draw.py --- old/weasyprint-62.2/weasyprint/draw.py 2024-05-27 11:51:46.653930200 +0200 +++ new/weasyprint-62.3/weasyprint/draw.py 2024-06-21 17:37:15.490403400 +0200 @@ -401,63 +401,53 @@ def draw_border(stream, box): - """Draw the box border to a ``document.Stream``.""" - # We need a plan to draw beautiful borders, and that's difficult, no need - # to lie. Let's try to find the cases that we can handle in a smart way. + """Draw the box borders and column rules to a ``document.Stream``.""" - def get_columns_with_rule(): - """Yield columns that have a rule drawn on the left.""" + # The box is hidden, easy. + if box.style['visibility'] != 'visible': + return + + # Draw column borders. + columns = ( + isinstance(box, boxes.BlockContainerBox) and ( + box.style['column_width'] != 'auto' or + box.style['column_count'] != 'auto')) + if columns and box.style['column_rule_width']: + border_widths = (0, 0, 0, box.style['column_rule_width']) skip_next = True for child in box.children: if child.style['column_span'] == 'all': skip_next = True + continue elif skip_next: skip_next = False - else: - yield child - - def draw_column_border(): - """Draw column borders.""" - columns = ( - isinstance(box, boxes.BlockContainerBox) and ( - box.style['column_width'] != 'auto' or - box.style['column_count'] != 'auto')) - if columns and box.style['column_rule_width']: - border_widths = (0, 0, 0, box.style['column_rule_width']) - for child in get_columns_with_rule(): - with stacked(stream): - gap = percentage(box.style['column_gap'], box.width) - position_x = (child.position_x - ( - box.style['column_rule_width'] + gap) / 2) - border_box = ( - position_x, child.position_y, - box.style['column_rule_width'], child.height) - clip_border_segment( - stream, box.style['column_rule_style'], - box.style['column_rule_width'], 'left', border_box, - border_widths) - draw_rect_border( - stream, border_box, border_widths, - box.style['column_rule_style'], styled_color( - box.style['column_rule_style'], - get_color(box.style, 'column_rule_color'), 'left')) - - # The box is hidden, easy. - if box.style['visibility'] != 'visible': - draw_column_border() - return + continue + with stacked(stream): + gap = percentage(box.style['column_gap'], box.width) + position_x = (child.position_x - ( + box.style['column_rule_width'] + gap) / 2) + border_box = ( + position_x, child.position_y, + box.style['column_rule_width'], child.height) + clip_border_segment( + stream, box.style['column_rule_style'], + box.style['column_rule_width'], 'left', border_box, + border_widths) + draw_rect_border( + stream, border_box, border_widths, + box.style['column_rule_style'], styled_color( + box.style['column_rule_style'], + get_color(box.style, 'column_rule_color'), 'left')) # If there's a border image, that takes precedence. if box.style['border_image_source'][0] != 'none' and box.border_image is not None: draw_border_image(box, stream) - draw_column_border() return widths = [getattr(box, f'border_{side}_width') for side in SIDES] - # No border, return early. - if all(width == 0 for width in widths): - draw_column_border() + if set(widths) == {0}: + # No border, return early. return colors = [get_color(box.style, f'border_{side}_color') for side in SIDES] @@ -465,14 +455,15 @@ colors[i].alpha and box.style[f'border_{side}_style'] for (i, side) in enumerate(SIDES)] - # The 4 sides are solid or double, and they have the same color. Oh yeah! - # We can draw them so easily! - if set(styles) in (set(('solid',)), set(('double',))) and (len(set(colors)) == 1): + simple_style = set(styles) in ({'solid'}, {'double'}) # one style, simple lines + single_color = len(set(colors)) == 1 # one color + four_sides = 0 not in widths # no 0-width border, to avoid PDF artifacts + if simple_style and single_color and four_sides: + # Simple case, we only draw rounded rectangles. draw_rounded_border(stream, box, styles[0], colors[0]) - draw_column_border() return - # We're not smart enough to find a good way to draw the borders :/. We must + # We're not smart enough to find a good way to draw the borders, we must # draw them side by side. Order is not specified, but this one seems to be # close to what other browsers do. values = tuple(zip(SIDES, widths, colors, styles)) @@ -487,8 +478,6 @@ draw_rounded_border( stream, box, style, styled_color(style, color, side)) - draw_column_border() - def draw_border_image(box, stream): """Draw ``box`` border image on ``stream``.""" diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/weasyprint-62.2/weasyprint/layout/__init__.py new/weasyprint-62.3/weasyprint/layout/__init__.py --- old/weasyprint-62.2/weasyprint/layout/__init__.py 2024-04-29 21:13:11.555732300 +0200 +++ new/weasyprint-62.3/weasyprint/layout/__init__.py 2024-06-18 11:56:18.353362800 +0200 @@ -379,4 +379,6 @@ return overflow else: self.current_footnote_area.height = 0 + if not self.in_column: + self.page_bottom -= self.current_footnote_area.margin_height() return False diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/weasyprint-62.2/weasyprint/layout/column.py new/weasyprint-62.3/weasyprint/layout/column.py --- old/weasyprint-62.2/weasyprint/layout/column.py 2024-05-27 10:15:26.147362700 +0200 +++ new/weasyprint-62.3/weasyprint/layout/column.py 2024-06-18 11:56:18.354363000 +0200 @@ -306,6 +306,7 @@ containing_block, original_page_is_empty, absolute_boxes, fixed_boxes, None, discard=False, max_lines=None)) if new_child is None: + columns = [] break_page = True break next_page = column_next_page diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/weasyprint-62.2/weasyprint/layout/grid.py new/weasyprint-62.3/weasyprint/layout/grid.py --- old/weasyprint-62.2/weasyprint/layout/grid.py 2024-06-03 16:31:53.664926500 +0200 +++ new/weasyprint-62.3/weasyprint/layout/grid.py 2024-06-21 11:06:07.022056600 +0200 @@ -658,7 +658,6 @@ second_flow = 'row' if 'column' in flow else 'column' # other axis first_tracks = rows if first_flow == 'row' else columns second_tracks = rows if second_flow == 'row' else columns - auto_tracks = auto_rows if first_flow == 'row' else auto_columns # 1.1 Position anything that’s not auto-positioned. children_positions = {} @@ -797,10 +796,7 @@ break first_diff = first_i + first_size - implicit_first_2 if first_diff > 0: - for _ in range(first_diff): - first_tracks.append(next(auto_tracks)) - first_tracks.append([]) - implicit_first_2 = first_i + first_size + implicit_first_2 += first_diff # 3. Set the item’s row-start line. if first_flow == 'row': x, y = second_i, first_i @@ -842,8 +838,9 @@ width, height = first_size, second_size intersect = _intersect_with_children( x, y, width, height, children_positions.values()) - if intersect: - # Child intersects with a positioned child. + overflow = second_i + second_size > implicit_second_2 + if intersect or overflow: + # Child intersects with a positioned child or overflows. continue else: # Free place found. @@ -911,10 +908,7 @@ break first_diff = first_i + first_size - implicit_first_2 if first_diff > 0: - for _ in range(first_diff): - first_tracks.append(next(auto_tracks)) - first_tracks.append([]) - implicit_first_2 = y + height + implicit_first_2 += first_diff # 3. Set the item’s row-start line. children_positions[child] = (x, y, width, height) else: @@ -947,8 +941,9 @@ width, height = first_size, second_size intersect = _intersect_with_children( x, y, width, height, children_positions.values()) - if intersect: - # Child intersects with a positioned child. + overflow = second_i + second_size > implicit_second_2 + if intersect or overflow: + # Child intersects with a positioned child or overflows. continue else: # Free place found. diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/weasyprint-62.2/weasyprint/layout/table.py new/weasyprint-62.3/weasyprint/layout/table.py --- old/weasyprint-62.2/weasyprint/layout/table.py 2024-06-04 16:04:12.746271600 +0200 +++ new/weasyprint-62.3/weasyprint/layout/table.py 2024-06-21 17:37:15.491403300 +0200 @@ -7,7 +7,7 @@ from ..formatting_structure import boxes from ..logger import LOGGER from .percent import resolve_one_percentage, resolve_percentages -from .preferred import max_content_width, table_and_columns_preferred_widths +from .preferred import table_and_columns_preferred_widths def table_layout(context, table, bottom_space, skip_stack, containing_block, @@ -797,19 +797,9 @@ else: table.column_widths = max_content_guess excess_width = assignable_width - sum(max_content_guess) - excess_width = distribute_excess_width( + distribute_excess_width( context, grid, excess_width, table.column_widths, constrainedness, column_intrinsic_percentages, column_max_content_widths) - if excess_width: - if table_min_content_width < table.width - excess_width: - # Reduce the width of the size from the excess width that has - # not been distributed. - table.width -= excess_width - else: - # Break rules - columns = [i for i, column in enumerate(grid) if any(column)] - for i in columns: - table.column_widths[i] += excess_width / len(columns) def table_wrapper_width(context, wrapper, containing_block): @@ -866,38 +856,26 @@ column_slice=slice(0, None)): """Distribute available width to columns. - Return excess width left when it's impossible without breaking rules. - - See https://dbaron.org/css/intrinsic/#distributetocols + See https://www.w3.org/TR/css-tables-3/#distributing-width-to-columns """ # First group columns = [ - (i + column_slice.start, column) - for i, column in enumerate(grid[column_slice]) - if not constrainedness[i + column_slice.start] and - column_intrinsic_percentages[i + column_slice.start] == 0 and - column_max_content_widths[i + column_slice.start] > 0] + i for i, _ in enumerate(grid[column_slice], start=column_slice.start) + if not constrainedness[i] and + column_intrinsic_percentages[i] == 0 and + column_max_content_widths[i] > 0] if columns: - current_widths = [column_widths[i] for i, column in columns] - differences = [ - max(0, width[0] - width[1]) - for width in zip(column_max_content_widths, current_widths)] - if sum(differences) > excess_width: - differences = [ - difference / sum(differences) * excess_width - for difference in differences] - excess_width -= sum(differences) - for i, difference in enumerate(differences): - column_widths[columns[i][0]] += difference - if excess_width <= 0: + sum_max_content_widths = sum(column_max_content_widths[i] for i in columns) + ratio = excess_width / sum_max_content_widths + for i in columns: + column_widths[i] += column_max_content_widths[i] * ratio return # Second group columns = [ - i + column_slice.start for i, column in enumerate(grid[column_slice]) - if not constrainedness[i + column_slice.start] and - column_intrinsic_percentages[i + column_slice.start] == 0] + i for i, _ in enumerate(grid[column_slice], start=column_slice.start) + if not constrainedness[i] and column_intrinsic_percentages[i] == 0] if columns: for i in columns: column_widths[i] += excess_width / len(columns) @@ -905,85 +883,42 @@ # Third group columns = [ - (i + column_slice.start, column) - for i, column in enumerate(grid[column_slice]) - if constrainedness[i + column_slice.start] and - column_intrinsic_percentages[i + column_slice.start] == 0 and - column_max_content_widths[i + column_slice.start] > 0] + i for i, _ in enumerate(grid[column_slice], start=column_slice.start) + if constrainedness[i] and + column_intrinsic_percentages[i] == 0 and + column_max_content_widths[i] > 0] if columns: - current_widths = [column_widths[i] for i, column in columns] - differences = [ - max(0, width[0] - width[1]) - for width in zip(column_max_content_widths, current_widths)] - if sum(differences) > excess_width: - differences = [ - difference / sum(differences) * excess_width - for difference in differences] - excess_width -= sum(differences) - for i, difference in enumerate(differences): - column_widths[columns[i][0]] += difference - if excess_width <= 0: + sum_max_content_widths = sum(column_max_content_widths[i] for i in columns) + ratio = excess_width / sum_max_content_widths + for i in columns: + column_widths[i] += column_max_content_widths[i] * ratio return # Fourth group columns = [ - (i + column_slice.start, column) - for i, column in enumerate(grid[column_slice]) - if column_intrinsic_percentages[i + column_slice.start] > 0] + i for i, _ in enumerate(grid[column_slice], start=column_slice.start) + if column_intrinsic_percentages[i] > 0 and column_max_content_widths[i] > 0] if columns: - fixed_width = sum( - column_widths[j] for j in range(len(grid)) - if j not in [i for i, column in columns]) - percentage_width = sum( - column_intrinsic_percentages[i] - for i, column in columns) - if fixed_width and percentage_width >= 100: - # Sum of the percentages are greater than 100% - ratio = excess_width - elif fixed_width == 0: - # No fixed width, let's take the whole excess width - ratio = excess_width - else: - ratio = fixed_width / (100 - percentage_width) - - widths = [ - column_intrinsic_percentages[i] * ratio for i, column in columns] - current_widths = [column_widths[i] for i, column in columns] - # Allow to reduce the size of the columns to respect the percentage - differences = [ - width[0] - width[1] - for width in zip(widths, current_widths)] - if sum(differences) > excess_width: - differences = [ - difference / sum(differences) * excess_width - for difference in differences] - excess_width -= sum(differences) - for i, difference in enumerate(differences): - column_widths[columns[i][0]] += difference - if excess_width <= 0: + sum_intrinsic_percentages = sum( + column_intrinsic_percentages[i] for i in columns) + ratio = excess_width / sum_intrinsic_percentages + for i in columns: + column_widths[i] += column_intrinsic_percentages[i] * ratio return - # Bonus: we've tried our best to distribute the extra size, but we - # failed. Instead of blindly distributing the size among all the colums - # and breaking all the rules (as said in the draft), let's try to - # change the columns with no constraint at all, then resize the table, - # and at least break the rules to make the columns fill the table. - - # Fifth group, part 1 + # Fifth group columns = [ - i + column_slice.start for i, column in enumerate(grid[column_slice]) - if any(column) and - column_intrinsic_percentages[i + column_slice.start] == 0 and - not any( - max_content_width(context, cell) - for cell in column if cell)] + i for i, column in enumerate(grid[column_slice], start=column_slice.start) + if column] if columns: for i in columns: column_widths[i] += excess_width / len(columns) return - # Fifth group, part 2, aka abort - return excess_width + # Sixth group + columns = [i for i, _ in enumerate(grid[column_slice], start=column_slice.start)] + for i in columns: + column_widths[i] += excess_width / len(columns) TRANSPARENT = tinycss2.color3.parse_color('transparent') diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/weasyprint-62.2/weasyprint/pdf/pdfa.py new/weasyprint-62.3/weasyprint/pdf/pdfa.py --- old/weasyprint-62.2/weasyprint/pdf/pdfa.py 2024-04-29 21:13:11.558732300 +0200 +++ new/weasyprint-62.3/weasyprint/pdf/pdfa.py 2024-06-18 11:56:18.357363000 +0200 @@ -86,6 +86,9 @@ pdf_object['F'] = 2 ** (3 - 1) # Common PDF metadata stream. + if version == 1: + # Metadata compression is forbidden for version 1. + compress = False add_metadata(pdf, metadata, 'a', version, variant, compress) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/weasyprint-62.2/weasyprint/text/fonts.py new/weasyprint-62.3/weasyprint/text/fonts.py --- old/weasyprint-62.2/weasyprint/text/fonts.py 2024-05-27 10:15:26.150362700 +0200 +++ new/weasyprint-62.3/weasyprint/text/fonts.py 2024-06-21 17:37:15.492403500 +0200 @@ -117,12 +117,13 @@ features_string = ''.join( f'<string>{key} {value}</string>' for key, value in font_features(**features).items()) - fontconfig_style = FONTCONFIG_STYLE[ - rule_descriptors.get('font_style', 'normal')] - fontconfig_weight = FONTCONFIG_WEIGHT[ - rule_descriptors.get('font_weight', 'normal')] - fontconfig_stretch = FONTCONFIG_STRETCH[ - rule_descriptors.get('font_stretch', 'normal')] + fontconfig_style = fontconfig_weight = fontconfig_stretch = None + if 'font_style' in rule_descriptors: + fontconfig_style = FONTCONFIG_STYLE[rule_descriptors['font_style']] + if 'font_weight' in rule_descriptors: + fontconfig_weight = FONTCONFIG_WEIGHT[rule_descriptors['font_weight']] + if 'font_stretch' in rule_descriptors: + fontconfig_stretch = FONTCONFIG_STRETCH[rule_descriptors['font_stretch']] config_key = ( f'{rule_descriptors["font_family"]}-{fontconfig_style}-' f'{fontconfig_weight}-{features_string}').encode() @@ -213,7 +214,7 @@ font_path.write_bytes(font) xml_path = self._folder / f'{config_digest}.xml' - xml_path.write_text(f'''<?xml version="1.0"?> + xml = ''.join((f'''<?xml version="1.0"?> <!DOCTYPE fontconfig SYSTEM "fonts.dtd"> <fontconfig> <match target="scan"> @@ -222,16 +223,23 @@ </test> <edit name="family" mode="assign_replace"> <string>{rule_descriptors['font_family']}</string> - </edit> + </edit>''', + f''' <edit name="slant" mode="assign_replace"> <const>{fontconfig_style}</const> </edit> + ''' if fontconfig_style else '', + f''' <edit name="weight" mode="assign_replace"> <int>{fontconfig_weight}</int> </edit> + ''' if fontconfig_weight else '', + f''' <edit name="width" mode="assign_replace"> <const>{fontconfig_stretch}</const> </edit> + ''' if fontconfig_stretch else '', + f''' </match> <match target="font"> <test name="file" compare="eq"> @@ -240,7 +248,8 @@ <edit name="fontfeatures" mode="assign_replace">{features_string}</edit> </match> - </fontconfig>''') + </fontconfig>''')) + xml_path.write_text(xml) # TODO: We should mask local fonts with the same name # too as explained in Behdad's blog entry.
participants (1)
-
Source-Sync