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

Emojis in pre tag add an extra line #2324

Open
mfontanini opened this issue Dec 7, 2024 · 1 comment
Open

Emojis in pre tag add an extra line #2324

mfontanini opened this issue Dec 7, 2024 · 1 comment

Comments

@mfontanini
Copy link

It looks like when you use an emoji inside a pre tag this causes a newline to be introduced. The snippets below are similar to what presenterm generates when exporting a presentation to PDF. Content here is a series of lines of a specific height and a page is capped at a height equal to the line height * number of lines in a page, as if it was a capture of a terminal output (which it is).

In this html, there's a first page with 2 lines without any emoji, then the second page is exactly the same as the first one except with an emoji. You can see in this second page that the second line is no longer the expected one but instead is a newline. The content in page 3 is shifted by one line and an extra page is added because of it. If you remove the emoji in page 2 it all works as expected; similarly if you remove the pre tag it also works, but I do want to preserve whitespaces so I need that white-space: pre.

I saw a couple of open issues around white-space: pre-wrap but I don't know if it's related as there shouldn't be any line wrapping here.

Run using:

weasyprint -e utf8 -s styles.css input.html output.pdf

input.html:

<html>
<body style="color: white">
<!-- page 1 -->
    <div class="content-line"><pre>page 1</pre></div>
    <div class="content-line"><pre>1 / 3</pre></div>
<!-- page 2 -->
    <div class="content-line"><pre>page 2 🎓</pre></div>
    <div class="content-line"><pre>2 / 3</pre></div>
<!-- page 3 -->
    <div class="content-line"><pre>page 3</pre></div>
    <div class="content-line"><pre>3 / 3</pre></div>
</body>
</html>

styles.css

pre {
    margin: 0;
    padding: 0;
}

body {
    margin: 0;
    font-size: 10px;
    background-color: #040312;
    width: 248px;
}

.content-line {
    line-height: 12px; 
    margin: 0px;
    width: 248px;
}

@page {
    margin: 0;
    height: 24px;
    width: 248px;
}

Output file bug.pdf

@liZe
Copy link
Member

liZe commented Dec 27, 2024

Hi!

Thanks for the report and the example.

I think that it’s not a bug in WeasyPrint, but a "problem" with line-height that is actually quite common. Short answer: setting line-height is not enough to be sure about the line box height if you have multiple fonts in a line (the font for text, the font for emoji in your example). Here, your line box height is slightly more than 12px, and then the second line doesn’t fit. If you want to be sure, you can set height: 12px on .content-line.

It’s a bit hard to see the same problem in a browser, as there’s no pagination, but here’s a similar example with flex and without an emoji:

<style>
  body {
    display: flex;
    flex-direction: column;
    flex-wrap: wrap;
    font-family: Liberation sans;
    font-size: 30px;
    height: 60px;
  }

  div {
    line-height: 30px;
    width: 200px;
  }
</style>
<div>page 1</div>
<div>1 / 3</div>
<div>page 2 <span style="font-family: Fira Mono">emoji</span></div>
<div>2 / 3</div>
<div>page 3</div>
<div>3 / 3</div>

The result is "broken" in Firefox, the height of "page 2 emoji" is larger than 30px and "2/2" doesn’t fit:
Image

This problem is hard to reproduce reliably, because it depends on the way browsers handle fonts metrics and rounding tricks, so you may get different renderings with different browsers, even on the same computer with the same fonts. But that’s not a bug.

If you want to understand why this problem happens, you can read this really interesting article.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants