Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Letter spacing regression in 0.55 #1662

Closed
skoczen opened this issue Jun 23, 2022 · 16 comments
Closed

Letter spacing regression in 0.55 #1662

skoczen opened this issue Jun 23, 2022 · 16 comments
Labels
bug Existing features not working as expected
Milestone

Comments

@skoczen
Copy link

skoczen commented Jun 23, 2022

Bonjour WeasyPrint team,

Thanks much for the excellent software. We're seeing a regression in 0.55 (I believe traced back to the pydyf 0.0.3 -> 0.2 change.

Screenshots below, there are no other changes in our stack between these exports than 0.54 -> 0.55. Many thanks!

With 0.54, we get this PDF (as expected)
Screen Shot 2022-06-23 at 11 39 18 AM

With 0.55, we get this PDF (not as expected)
Screen Shot 2022-06-23 at 11 39 26 AM

@liZe
Copy link
Member

liZe commented Jun 23, 2022

Hello!

Thanks for your bug report.

Could you please share the PDF files (and the HTML/CSS if possible)?

@liZe
Copy link
Member

liZe commented Jul 7, 2022

Please reopen the issue if you can provide more information about this.

@liZe liZe closed this as completed Jul 7, 2022
@violuke
Copy link

violuke commented Jul 8, 2022

Bonjour @liZe,

We're having the same problem as @skoczen and I can confirm it's present in both v55 and v56.

We're using https://doc.courtbouillon.org/weasyprint/v52.5/tips-tricks.html#include-header-and-footer-of-arbitrary-complexity-in-a-pdf to handle headers, body and footer.

Here is an example PDF with version 54 version54.pdf and here is the same with version 56 version56.pdf.

We're generating the PDF with:

PdfGenerator(header_html=header, main_html=body, footer_html=footer).render_pdf(target_file, stylesheets=[weasyprint.CSS("normalise.css")])

where normalise.css is https://cdn.jsdelivr.net/npm/modern-normalize/modern-normalize.min.css (this as non-minified may be useful too at https://cdn.jsdelivr.net/npm/modern-normalize/modern-normalize.css)

Then the HTML used is:

Header

<header>
    <table class="invoice-info-container">
        <tr>
            <td>

                    <img style="max-height: 150px; max-width: 275px;" src="data:image/png;base64,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" alt="Test Brewery">
                    <br>


                Issue date: Thursday, 30 June 2022


            </td>
            <td>
                <div class="document-title">
                    Order #570

                </div>

                <strong>Test Brewery</strong>
                <br>
                SG4 8HD<br>
            </td>
        </tr>
    </table>

    <table class="invoice-info-container new_section">
        <tr>
            <td>
                <strong>Bill to:</strong>
                <br>
                The local pub
                <br>
                123 Some road<br>Sometown<br>Someshire<br>AL1 1DG



                    <br>Tel: 07111 111111

            </td>
            <td>

                    <strong>Deliver to:</strong>
                    <br>
                    The local pub
                    <br>
                    123 Some road<br>Sometown<br>Someshire<br>AL1 1DG

            </td>
        </tr>
    </table>
</header><style>header {
    position: fixed;
    top: 0;
    left: 0;
    width: 100%;
    padding-left: 1cm;
    padding-right: 1cm;
    padding-top: 1cm;
}

body {
    font-size: 16px;
    line-height: 1.5;
}

footer {
    position: fixed;
    bottom: 0;
    left: 0;
    width: 100%;
    padding-left: 1cm;
    padding-right: 1cm;
    padding-bottom: 1cm;
}

table {
    width: 100%;
    border-collapse: collapse;
}

table tr td {
    padding: 0;
}

table tr td:last-child {
    text-align: right;
}

.document-title {
    font-weight: bold;
    font-size: 1.2em;
}

.bold {
    font-weight: bold;
}

.right {
    text-align: right;
}

.large {
    font-size: 1.75em;
}

.small {
    font-size: 0.75em;
}

.total {
    font-weight: bold;
    text-align: right;
}

.notes_and_extra_text {
    page-break-inside: avoid;
    margin-top: 10px;
    font-size: 0.75em;
}

.signature_line {
    page-break-inside: avoid;
    margin-top: 20px;
}

.invoice-info-container {
    font-size: 0.875em;
}

.invoice-info-container td {
    padding: 0 10px;
}

.document-title {
    font-size: 1.5em;
    vertical-align: top;
}

.line-items-container {
    font-size: 0.75em;
}

.line-items-container th {
    text-align: left;
    color: #040404;
    border-bottom: 2px solid #080404;
    font-size: 0.75em;
    text-transform: uppercase;
}

.line-items-container th,
.line-items-container td {
    padding-top: 5px;
}

tr.comments td{
    border-bottom: 1px solid #eee;
    padding: 3px 20px;
}

.line-items-container th:last-child {
    text-align: right;
}

.has-bottom-border tbody tr:last-child td {
    padding-bottom: 25px;
    border-bottom: 2px solid #040404;
}

.has-bottom-border {
    margin-bottom: 10px;
}

.line-items-container th.heading-quantity {
    width: 50px;
}

.line-items-container th.heading-price {
    text-align: right;
    width: 100px;
}

.line-items-container th.heading-subtotal {
    width: 100px;
}

.line-items-container th.heading-item,
.line-items-container td.row-item {
    text-align: left;
}

.new_section {
    margin-top: 30px;
}

.payment-info {
    width: 38%;
    font-size: 0.75em;
}

.paid {
    font-size: 1.125em;
    text-align: center;
    color: darkgreen;
}

.footer-info {
    margin-top: 5px;
    font-size: 0.75em;
    color: #ccc;
}

.footer-info-right {
    text-align: right;
}

.footer-info span {
    padding: 0 5px;
    color: black;
}

.footer-info span:last-child {
    padding-right: 0;
}

.breww {
    margin-top: 10px;
    font-size: 0.8em;
    text-align: center;
}

.human_input {
    color: lightgrey;
}</style>

Body

 <body>
 <table class="line-items-container">
     <thead>
     <tr>



         <th class="heading-quantity">Qty</th>




         <th class="heading-item">Item</th>



             <th class="heading-price">Unit price</th>




             <th class="heading-price">VAT</th>


             <th class="heading-price">Line price</th>


     </tr>
     </thead>
     <tbody>


         <tr>
             <td>100</td>



             <td class="row-item">Belgian Blonde - 50L Keg</td>


                 <td class="right">£0.10</td>



                 <td class="right">23%</td>

                 <td class="right bold">£10.00</td>

         </tr>










         <tr class="total">
             <td colspan="4">Total (ex. VAT):</td>
             <td>£10.00</td>
         </tr>


             <tr class="total">
                 <td colspan="4">VAT 23%:</td>
                 <td>£2.30</td>
             </tr>


         <tr class="total">
             <td colspan="4">Total:</td>
             <td>£12.30</td>
         </tr>



                 <tr class="total">
                     <td colspan="4">Less amount paid:</td>
                     <td>£12.30</td>
                 </tr>




             <tr class="total">
                 <td colspan="4">Amount due:</td>
                 <td>£0.00</td>
             </tr>


     </tbody>
 </table>





         <div class="paid">
             ✓ Paid in full, thank you!
         </div>












     <div class="notes_and_extra_text">
         Containers remain the property of the brewery and customers are asked to ensure their safe return. Company containers are not measures, however every care is taken to ensure that they contain not less than their reported quantity. Lost containers will be invoiced at 80% of original cost. The goods remain the property of the brewery until paid for in full.
     </div>



     <div class="signature_line">
         <strong>Name:</strong>

             <span class="human_input">__________________</span>


         <strong>Signature:</strong>

             <span class="human_input">__________________</span>


         <strong>Date:</strong>

            <span class="human_input">__________________</span>

     </div>



 </body><style>header {
     position: fixed;
     top: 0;
     left: 0;
     width: 100%;
     padding-left: 1cm;
     padding-right: 1cm;
     padding-top: 1cm;
 }

 body {
     font-size: 16px;
     line-height: 1.5;
 }

 footer {
     position: fixed;
     bottom: 0;
     left: 0;
     width: 100%;
     padding-left: 1cm;
     padding-right: 1cm;
     padding-bottom: 1cm;
 }

 table {
     width: 100%;
     border-collapse: collapse;
 }

 table tr td {
     padding: 0;
 }

 table tr td:last-child {
     text-align: right;
 }

 .document-title {
     font-weight: bold;
     font-size: 1.2em;
 }

 .bold {
     font-weight: bold;
 }

 .right {
     text-align: right;
 }

 .large {
     font-size: 1.75em;
 }

 .small {
     font-size: 0.75em;
 }

 .total {
     font-weight: bold;
     text-align: right;
 }

 .notes_and_extra_text {
     page-break-inside: avoid;
     margin-top: 10px;
     font-size: 0.75em;
 }

 .signature_line {
     page-break-inside: avoid;
     margin-top: 20px;
 }

 .invoice-info-container {
     font-size: 0.875em;
 }

 .invoice-info-container td {
     padding: 0 10px;
 }

 .document-title {
     font-size: 1.5em;
     vertical-align: top;
 }

 .line-items-container {
     font-size: 0.75em;
 }

 .line-items-container th {
     text-align: left;
     color: #040404;
     border-bottom: 2px solid #080404;
     font-size: 0.75em;
     text-transform: uppercase;
 }

 .line-items-container th,
 .line-items-container td {
     padding-top: 5px;
 }

 tr.comments td{
     border-bottom: 1px solid #eee;
     padding: 3px 20px;
 }

 .line-items-container th:last-child {
     text-align: right;
 }

 .has-bottom-border tbody tr:last-child td {
     padding-bottom: 25px;
     border-bottom: 2px solid #040404;
 }

 .has-bottom-border {
     margin-bottom: 10px;
 }

 .line-items-container th.heading-quantity {
     width: 50px;
 }

 .line-items-container th.heading-price {
     text-align: right;
     width: 100px;
 }

 .line-items-container th.heading-subtotal {
     width: 100px;
 }

 .line-items-container th.heading-item,
 .line-items-container td.row-item {
     text-align: left;
 }

 .new_section {
     margin-top: 30px;
 }

 .payment-info {
     width: 38%;
     font-size: 0.75em;
 }

 .paid {
     font-size: 1.125em;
     text-align: center;
     color: darkgreen;
 }

 .footer-info {
     margin-top: 5px;
     font-size: 0.75em;
     color: #ccc;
 }

 .footer-info-right {
     text-align: right;
 }

 .footer-info span {
     padding: 0 5px;
     color: black;
 }

 .footer-info span:last-child {
     padding-right: 0;
 }

 .breww {
     margin-top: 10px;
     font-size: 0.8em;
     text-align: center;
 }

 .human_input {
     color: lightgrey;
 }</style>

Footer

 <footer>
     <div class="footer-info footer-info-right">

             <span>Tel: 07595461234</span> |

         <span>Email: hello@gmail.com</span>
     </div>
     <div class="footer-info footer-info-right">

             <span>Company Reg: 1819181</span> |



             <span>VAT: GB01919181</span> |

         <span>AWRS URN: 191019181910191</span>
     </div>

     <div class="footer-info breww">
         Generated with Breww - Modern brewery management software - breww.com
     </div>
 </footer><style>header {
     position: fixed;
     top: 0;
     left: 0;
     width: 100%;
     padding-left: 1cm;
     padding-right: 1cm;
     padding-top: 1cm;
 }

 body {
     font-size: 16px;
     line-height: 1.5;
 }

 footer {
     position: fixed;
     bottom: 0;
     left: 0;
     width: 100%;
     padding-left: 1cm;
     padding-right: 1cm;
     padding-bottom: 1cm;
 }

 table {
     width: 100%;
     border-collapse: collapse;
 }

 table tr td {
     padding: 0;
 }

 table tr td:last-child {
     text-align: right;
 }

 .document-title {
     font-weight: bold;
     font-size: 1.2em;
 }

 .bold {
     font-weight: bold;
 }

 .right {
     text-align: right;
 }

 .large {
     font-size: 1.75em;
 }

 .small {
     font-size: 0.75em;
 }

 .total {
     font-weight: bold;
     text-align: right;
 }

 .notes_and_extra_text {
     page-break-inside: avoid;
     margin-top: 10px;
     font-size: 0.75em;
 }

 .signature_line {
     page-break-inside: avoid;
     margin-top: 20px;
 }

 .invoice-info-container {
     font-size: 0.875em;
 }

 .invoice-info-container td {
     padding: 0 10px;
 }

 .document-title {
     font-size: 1.5em;
     vertical-align: top;
 }

 .line-items-container {
     font-size: 0.75em;
 }

 .line-items-container th {
     text-align: left;
     color: #040404;
     border-bottom: 2px solid #080404;
     font-size: 0.75em;
     text-transform: uppercase;
 }

 .line-items-container th,
 .line-items-container td {
     padding-top: 5px;
 }

 tr.comments td{
     border-bottom: 1px solid #eee;
     padding: 3px 20px;
 }

 .line-items-container th:last-child {
     text-align: right;
 }

 .has-bottom-border tbody tr:last-child td {
     padding-bottom: 25px;
     border-bottom: 2px solid #040404;
 }

 .has-bottom-border {
     margin-bottom: 10px;
 }

 .line-items-container th.heading-quantity {
     width: 50px;
 }

 .line-items-container th.heading-price {
     text-align: right;
     width: 100px;
 }

 .line-items-container th.heading-subtotal {
     width: 100px;
 }

 .line-items-container th.heading-item,
 .line-items-container td.row-item {
     text-align: left;
 }

 .new_section {
     margin-top: 30px;
 }

 .payment-info {
     width: 38%;
     font-size: 0.75em;
 }

 .paid {
     font-size: 1.125em;
     text-align: center;
     color: darkgreen;
 }

 .footer-info {
     margin-top: 5px;
     font-size: 0.75em;
     color: #ccc;
 }

 .footer-info-right {
     text-align: right;
 }

 .footer-info span {
     padding: 0 5px;
     color: black;
 }

 .footer-info span:last-child {
     padding-right: 0;
 }

 .breww {
     margin-top: 10px;
     font-size: 0.8em;
     text-align: center;
 }

 .human_input {
     color: lightgrey;
 }</style>

Apologies for the duplicate code and somewhat strange indenting/new-lines/etc in the header/body/footer. This is from templates that our users can customise, so I've provided as-is so that you can hopefully replicate.

Any help would be much appreciated and if you need anything more from me, please let me know. If I make any progress on the problem, I'll let you know, but I haven't yet! Thank you!

@liZe liZe reopened this Jul 8, 2022
@grewn0uille grewn0uille added the bug Existing features not working as expected label Jul 8, 2022
@liZe
Copy link
Member

liZe commented Jul 14, 2022

The problem is caused by the code of PdfGenerator, that’s not in the documentation anymore because running elements are now supported. Adding children to the page after rendering the whole document was more a hack than a real solution, and I’m not sure that we’ll support that in the future 😒.

The best solution for you is probably to use running elements that are now supported in WeasyPrint. It doesn’t require Python code anymore, you "just" have to update the stylesheet

Could you please try this solution? Don’t hesitate to ask if you have any problem.

@violuke
Copy link

violuke commented Jul 25, 2022

Thanks @liZe. I've been trying to get this to work, but with limited success.

I've been able to get the header/footer to sit at the right places and repeat on each page, but I need to manually specify the margin for the header/footer for them to work, otherwise, the body content may be positioned over the top of the header/footer. I've had a good look at the docs and can't find anything to help with this. The height of the header/footer will be unknown to us in all cases, so specifying the height isn't really possible.

Is there some CSS to allow this to be calculated on the fly?

Also, we need a full-width header/footer, but I can only seem to use @top-center (or the left/right), but I can't seem to find a way to do full-width (I tried @top even though this doesn't seem to be an option)

Any help or suggestions would be much appreciated. Thank you.

@liZe
Copy link
Member

liZe commented Aug 10, 2022

Is there some CSS to allow this to be calculated on the fly?

I don’t think so :/.

Also, we need a full-width header/footer, but I can only seem to use @top-center (or the left/right), but I can't seem to find a way to do full-width (I tried @top even though this doesn't seem to be an option)

@top-center’s width can be set to match your requirements.

@liZe
Copy link
Member

liZe commented Aug 15, 2022

As explained in #1517, there’s a problem when we generate a PDF out of a document that includes content that wasn’t originally present during the layout. It happens when we add new elements (as in this issue) or use a document to render other document’s pages (as in #1517’s last comment).

To be honest, even if these two cases are not explicitly prevented in the documentation (the one here was even in a snippet that’s been now removed), they push the current API to its limits:

  • Using a document to render another document’s pages is logically broken in many ways: metadata, fonts, URL fetcher used for attachments… Merging PDF files should probably be done using another tool, like Ghostscript or Poppler.
  • Adding elements after the layout just seems bad. It’s definitely useful, but I’m sure that it causes other problems that are waiting to be found.

Even if we find a solution to fix these two cases, it’s probably better for you to find a more stable solution.

@skoczen: I can’t think of a solution for your case right now, because of the height that has to be calculated on the fly. Maybe there’s a feature hidden somewhere in the CSS specification.

@SchrodingersGat: could you use a more adapted third-party tool like Ghostscript or Poppler to merge your PDF files?

@SchrodingersGat
Copy link

@liZe tbh the easiest path on our end is reverting to an older version of weasyprint where this "feature" works as "expected"

@rongxin-liu
Copy link

rongxin-liu commented Aug 24, 2022

We ran into a similar issue when merging multiple documents, as mentioned in #1517. We ended up rendering each of the documents and merging them separately which works well:

from PyPDF2 import PdfFileMerger
...
merger = PdfFileMerger()
for document in documents:
    merger.append(PdfFileReader(io.BytesIO(document.write_pdf())))

merger.write("output.pdf")
...

@liZe
Copy link
Member

liZe commented Aug 24, 2022

We ended up rendering each of the documents and merging them separately which works well:

That’s probably the best way to reliably do this!

@kavdev
Copy link

kavdev commented Aug 24, 2022

Piggy-backing off of @rongxin-liu's solution, here's document merge using weasyprint==56.1 and pypdf2==2.10.3 in a django view:

from PyPDF2 import PdfMerger

...

def get(self, request, *args, **kwargs):
    pdf_stream = BytesIO()

    with PdfMerger(strict=True, fileobj=pdf_stream) as merger:
        for document in self.get_documents():
            merger.append(BytesIO(document.write_pdf()))

    response = HttpResponse(pdf_stream.getvalue(), content_type="application/pdf")
    response["Content-Disposition"] = f"attachment; filename=<filename>.pdf"

    return response

@liZe liZe added this to the 57.0 milestone Oct 4, 2022
@liZe liZe closed this as completed in cd09a5e Oct 4, 2022
@liZe
Copy link
Member

liZe commented Oct 4, 2022

This bug has been fixed and the old PdfGenerator code should work again. As explained above, use it at your own risk for desperate cases only!

If you want to use a repeated header or footer with a maximum height, you should use running elements.

If you want to merge different PDF files into one PDF file, you should use a third-party library such as PyPDF2.

@violuke
Copy link

violuke commented Oct 13, 2022

Thank you! We will give this a try and let you know if we have any trouble. I really appreciate this being fixed, so thank you!

@violuke
Copy link

violuke commented Oct 18, 2022

Would it be possible to do a patch release on PyPi with this fix in it? Thank you.

Could I also request that versioning is switched to SemVer (I realise this is a separate request)?

Thanks for all your help.

@liZe
Copy link
Member

liZe commented Oct 18, 2022

Would it be possible to do a patch release on PyPi with this fix in it? Thank you.

Version 57 will be (hopefully) released today.

Could I also request that versioning is switched to SemVer (I realise this is a separate request)?

That’s a fair request, but there’s a chapter in the documentation explaining why we won’t.

@violuke
Copy link

violuke commented Oct 18, 2022

Thank you and apologies for not seeing the bit on SemVer before 👍

netbsd-srcmastr pushed a commit to NetBSD/pkgsrc that referenced this issue Jun 30, 2023
Version 59.0
------------

Released on 2023-05-11.

This version also includes the changes from unstable b1 version listed
below.

Bug fixes:

* `#1864 <https://github.com/Kozea/WeasyPrint/issues/1864>`_:
  Handle overflow for svg and symbol tags in SVG images
* `#1867 <https://github.com/Kozea/WeasyPrint/pull/1867>`_:
  Remove duplicate compression of attachments
* `d0ad5c1 <https://github.com/Kozea/WeasyPrint/commit/d0ad5c1>`_:
  Override use tag children instead of drawing their references
* `93df1a5 <https://github.com/Kozea/WeasyPrint/commit/93df1a5>`_:
  Don’t resize the same image twice when the --dpi option is set
* `#1874 <https://github.com/Kozea/WeasyPrint/pull/1874>`_:
  Drawn underline and overline behind text


Version 59.0b1
--------------

Released on 2023-04-14.

**This version is experimental, don't use it in production. If you find bugs,
please report them!**

Command-line API:

* The ``--optimize-size`` option and its short equivalent ``-O`` have been
  deprecated. To activate or deactivate different size optimizations, you can
  now use:

  * ``--uncompressed-pdf``,
  * ``--optimize-images``,
  * ``--full-fonts``,
  * ``--hinting``,
  * ``--dpi <resolution>``, and
  * ``--jpeg-quality <quality>``.

* A new ``--cache-folder <folder>`` option has been added to store temporary
  data in the given folder on the disk instead of keeping them in memory.

Python API:

* Global rendering options are now given in ``**options`` instead of dedicated
  parameters, with slightly different names. It means that the signature of the
  ``HTML.render()``, ``HTML.write_pdf()`` and ``Document.write_pdf()`` has
  changed. Here are the steps to port your Python code to v59.0:

  1. Use named parameters for these functions, not positioned parameters.
  2. Rename some the parameters:

     * ``image_cache`` becomes ``cache`` (see below),
     * ``identifier`` becomes ``pdf_identifier``,
     * ``variant`` becomes ``pdf_variant``,
     * ``version`` becomes ``pdf_version``,
     * ``forms`` becomes ``pdf_forms``.

* The ``optimize_size`` parameter of ``HTML.render()``, ``HTML.write_pdf()``
  and ``Document()`` has been removed and will be ignored. You can now use the
  ``uncompressed_pdf``, ``full_fonts``, ``hinting``, ``dpi`` and
  ``jpeg_quality`` parameters that are included in ``**options``.

* The ``cache`` parameter can be included in ``**options`` to replace
  ``image_cache``. If it is a dictionary, this dictionary will be used to store
  temporary data in memory, and can be even shared between multiple documents.
  If it’s a folder Path or string, WeasyPrint stores temporary data in the
  given temporary folder on disk instead of keeping them in memory.

New features:

* `#1853 <https://github.com/Kozea/WeasyPrint/pull/1853>`_,
  `#1854 <https://github.com/Kozea/WeasyPrint/issues/1854>`_:
  Reduce PDF size, with financial support from Code & Co.
* `#1824 <https://github.com/Kozea/WeasyPrint/issues/1824>`_,
  `#1829 <https://github.com/Kozea/WeasyPrint/pull/1829>`_:
  Reduce memory use for images
* `#1858 <https://github.com/Kozea/WeasyPrint/issues/1858>`_:
  Add an option to keep hinting information in embedded fonts

Bug fixes:

* `#1855 <https://github.com/Kozea/WeasyPrint/issues/1855>`_:
  Fix position of emojis in justified text
* `#1852 <https://github.com/Kozea/WeasyPrint/issues/1852>`_:
  Don’t crash when line can be split before trailing spaces
* `#1843 <https://github.com/Kozea/WeasyPrint/issues/1843>`_:
  Fix syntax of dates in metadata
* `#1827 <https://github.com/Kozea/WeasyPrint/issues/1827>`_,
  `#1832 <https://github.com/Kozea/WeasyPrint/pull/1832>`_:
  Fix word-spacing problems with nested tags

Documentation:

* `#1841 <https://github.com/Kozea/WeasyPrint/issues/1841>`_:
  Add a paragraph about unsupported calc() function


Version 58.1
------------

Released on 2023-03-07.

Bug fixes:

* `#1815 <https://github.com/Kozea/WeasyPrint/issues/1815>`_:
  Fix bookmarks coordinates
* `#1822 <https://github.com/Kozea/WeasyPrint/issues/1822>`_,
  `#1823 <https://github.com/Kozea/WeasyPrint/pull/1823>`_:
  Fix vertical positioning for absolute replaced elements

Documentation:

* `#1814 <https://github.com/Kozea/WeasyPrint/pull/1814>`_:
  Fix broken link pointing to samples


Version 58.0
------------

Released on 2023-02-17.

This version also includes the changes from unstable b1 version listed
below.

Bug fixes:

* `#1807 <https://github.com/Kozea/WeasyPrint/issues/1807>`_:
  Don’t crash when out-of-flow box is split in out-of-flow parent
* `#1806 <https://github.com/Kozea/WeasyPrint/issues/1806>`_:
  Don’t crash when fixed elements aren’t displayed yet in aborted line
* `#1809 <https://github.com/Kozea/WeasyPrint/issues/1809>`_:
  Fix background drawing for out-of-the-page transformed boxes


Version 58.0b1
--------------

Released on 2023-02-03.

**This version is experimental, don't use it in production. If you find bugs,
please report them!**

New features:

* `#61 <https://github.com/Kozea/WeasyPrint/issues/61>`_,
  `#1796 <https://github.com/Kozea/WeasyPrint/pull/1796>`_:
  Support PDF forms, with financial support from Personalkollen
* `#1173 <https://github.com/Kozea/WeasyPrint/issues/1173>`_:
  Add style for form fields

Bug fixes:

* `#1777 <https://github.com/Kozea/WeasyPrint/issues/1777>`_:
  Detect JPEG/MPO images as normal JPEG files
* `#1771 <https://github.com/Kozea/WeasyPrint/pull/1771>`_:
  Improve SVG gradients


Version 57.2
------------

Released on 2022-12-23.

Bug fixes:

* `0f2e377 <https://github.com/Kozea/WeasyPrint/commit/0f2e377>`_:
  Print annotations with PDF/A
* `0e9426f <https://github.com/Kozea/WeasyPrint/commit/0e9426f>`_:
  Hide annotations with PDF/UA
* `#1764 <https://github.com/Kozea/WeasyPrint/issues/1764>`_:
  Use reference instead of stream for annotation appearance stream
* `#1783 <https://github.com/Kozea/WeasyPrint/pull/1783>`_:
  Fix multiple font weights for @font-face declarations


Version 57.1
------------

Released on 2022-11-04.

Dependencies:

* `#1754 <https://github.com/Kozea/WeasyPrint/pull/1754>`_:
  Pillow 9.1.0 is now needed

Bug fixes:

* `#1756 <https://github.com/Kozea/WeasyPrint/pull/1756>`_:
  Fix rem font size for SVG images
* `#1755 <https://github.com/Kozea/WeasyPrint/issues/1755>`_:
  Keep format when transposing images
* `#1753 <https://github.com/Kozea/WeasyPrint/issues/1753>`_:
  Don’t use deprecated ``read_text`` function when ``files`` is available
* `#1741 <https://github.com/Kozea/WeasyPrint/issues/1741>`_:
  Generate better manpage
* `#1747 <https://github.com/Kozea/WeasyPrint/issues/1747>`_:
  Correctly set target counters in pages’ absolute elements
* `#1748 <https://github.com/Kozea/WeasyPrint/issues/1748>`_:
  Always set font size when font is changed in line
* `2b05137 <https://github.com/Kozea/WeasyPrint/commit/2b05137>`_:
  Fix stability of font identifiers

Documentation:

* `#1750 <https://github.com/Kozea/WeasyPrint/pull/1750>`_:
  Fix documentation spelling


Version 57.0
------------

Released on 2022-10-18.

This version also includes the changes from unstable b1 version listed
below.

New features:

* `a4fc7a1 <https://github.com/Kozea/WeasyPrint/commit/a4fc7a1>`_:
  Support image-orientation

Bug fixes:

* `#1739 <https://github.com/Kozea/WeasyPrint/issues/1739>`_:
  Set baseline on all flex containers
* `#1740 <https://github.com/Kozea/WeasyPrint/issues/1740>`_:
  Don’t crash when currentColor is set on root svg tag
* `#1718 <https://github.com/Kozea/WeasyPrint/issues/1718>`_:
  Don’t crash with empty bitmap glyphs
* `#1736 <https://github.com/Kozea/WeasyPrint/issues/1736>`_:
  Always use the font’s vector variant when possible
* `eef8b4d <https://github.com/Kozea/WeasyPrint/commit/eef8b4d>`_:
  Always set color and state before drawing
* `#1662 <https://github.com/Kozea/WeasyPrint/issues/1662>`_:
  Use a stable key to store stream fonts
* `#1733 <https://github.com/Kozea/WeasyPrint/issues/1733>`_:
  Don’t remove attachments when adding internal anchors
* `3c4fa50 <https://github.com/Kozea/WeasyPrint/commit/3c4fa50>`_,
  `c215697 <https://github.com/Kozea/WeasyPrint/commit/c215697>`_,
  `d275dac <https://github.com/Kozea/WeasyPrint/commit/d275dac>`_,
  `b04bfff <https://github.com/Kozea/WeasyPrint/commit/b04bfff>`_:
  Fix many bugs related to PDF/UA structure

Performance:

* `dfccf1b <https://github.com/Kozea/WeasyPrint/commit/dfccf1b>`_:
  Use faces as fonts dictionary keys
* `0dc12b6 <https://github.com/Kozea/WeasyPrint/commit/0dc12b6>`_:
  Cache add_font to avoid calling get_face too often
* `75e17bf <https://github.com/Kozea/WeasyPrint/commit/75e17bf>`_:
  Don’t call process_whitespace twice on many children
* `498d3e1 <https://github.com/Kozea/WeasyPrint/commit/498d3e1>`_:
  Optimize __missing__ functions

Documentation:

* `863b3d6 <https://github.com/Kozea/WeasyPrint/commit/863b3d6>`_:
  Update documentation of installation on macOS with Homebrew


Version 57.0b1
--------------

Released on 2022-09-22.

**This version is experimental, don't use it in production. If you find bugs,
please report them!**

New features:

* `#1704 <https://github.com/Kozea/WeasyPrint/pull/1704>`_:
  Support PDF/UA, with financial support from Novareto
* `#1454 <https://github.com/Kozea/WeasyPrint/issues/1454>`_:
  Support variable fonts

Bug fixes:

* `#1058 <https://github.com/Kozea/WeasyPrint/issues/1058>`_:
  Fix bullet position after page break, with financial support from OpenZeppelin
* `#1707 <https://github.com/Kozea/WeasyPrint/issues/1707>`_:
  Fix footnote positioning in multicolumn layout, with financial support from Code & Co.
* `#1722 <https://github.com/Kozea/WeasyPrint/issues/1722>`_:
  Handle skew transformation with only one parameter
* `#1715 <https://github.com/Kozea/WeasyPrint/issues/1715>`_:
  Don’t crash when images are truncated
* `#1697 <https://github.com/Kozea/WeasyPrint/issues/1697>`_:
  Don’t crash when attr() is used in text-decoration-color
* `#1695 <https://github.com/Kozea/WeasyPrint/pull/1695>`_:
  Include language information in PDF metadata
* `#1612 <https://github.com/Kozea/WeasyPrint/issues/1612>`_:
  Don’t lowercase letters when capitalizing text
* `#1700 <https://github.com/Kozea/WeasyPrint/issues/1700>`_:
  Fix crash when rendering footnote with repagination
* `#1667 <https://github.com/Kozea/WeasyPrint/issues/1667>`_:
  Follow EXIF metadata for image rotation
* `#1669 <https://github.com/Kozea/WeasyPrint/issues/1669>`_:
  Take care of floats when remvoving placeholders
* `#1638 <https://github.com/Kozea/WeasyPrint/issues/1638>`_:
  Use the original box when breaking waiting children
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Existing features not working as expected
Projects
None yet
Development

No branches or pull requests

7 participants