-
Notifications
You must be signed in to change notification settings - Fork 1.8k
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
Improve vertical alignment and related adjustments #2762
base: master
Are you sure you want to change the base?
Conversation
General logic and rendering of the test file look really promising, nice work! That said, it seems all lines are shifted compared to the old rendering, depending on the font and line height. For the standard fonts, the position seems to be to high, touching the top of the line in some instances; for custom fonts, at least DejaVu, the position looks to low now. I think the old logic was in part trying to work around inaccuracies or limitations with the baseline calculations. Needs more investigation. Rendering the test file on PHP 8.1.2, I get a For the implementation: Maybe split out the logic for establishing the common baseline and final line height so that it would be done while adding frames to the line ( Just some quick notes for now, hope to find time for a more in-depth look on the weekend. |
Ah, yes. I wasn't taking into account the line height when determining the baseline. I look into it and update the logic to take that into account.
Interesting, I didn't run into that on 8.1.0. I think maybe this error is something that XDebug raises when it's enabled? Anyway it's definitely due to the lack of strict comparison on objects. Will add the missing parameter. |
Both with XDebug and without for me. |
d82a425
to
e59d881
Compare
In addition to the line height issue I noticed an alignment problem when an inline-block element has multiple lines. Based on some testing vertical alignment should be against, nominally, the baseline of the last line of the element. Current logic doesn't even consider that there may need to be a height adjustment on top of the baseline calculation. I updated the test file to include some additional use cases. |
e59d881
to
850fb1b
Compare
OK I pushed an updated commit that, though there are some placements that aren't quite right, I think gets us close enough to the expected rendering. I do think some improvements can be made in when the calculations are performed. I don't know that we can fully prevent calling the move method multiple times since the actual vertical positioning is partially dependent on the alignment of all the frames within the line. But pre-calculating some things before we get to this point should be possible. One change I did make that should help with performance is to cache the "outside baseline height" since that shouldn't change at the point where it's calculated right now. |
I did find an issue but I'm not sure, yet, if it's because one of the calculations is bad or because a value isn't updated. The calculation to determine if an adjustment is needed to the line height because of frame alignment is producing an incorrect result for positioned frames. You can see the issue by rendering the following:
Additionally, it looks like unnecessary calculations and/or operations are being performed because of float imprecision. I'll probably go ahead and use the new helpers from 271c651 to do a more precise comparison and avoid the extra work. |
It looks like the issue was due to a missing adjustment to the line y position when a block is re-positioned during reflow. Pushing a change for that as a separate commit since it's not directly related to the change in vertical alignment calculations. |
661a0a1
to
89a689f
Compare
OK, I think I've done enough with this for the next release. |
Great work @bsweeney! I am noticing a difference compared to the current HTML: <html>
<head>
<style type="text/css">
body {
font-family: serif;
line-height: 100%;
}
.border {
border: 1pt solid black;
}
h1 {
font-size: 18pt;
margin: 0.67em 0;
}
</style>
</head>
<body>
<div class="border">
<h1>Header</h1>
</div>
</body>
</html> Which renders like this on And for comparison, this is how it renders in Chrome: With the images stacked like this it may not be particularly clear, but depending on the other styles and surrounding elements, the difference can become quite big. Setting the margin to |
89a689f
to
af89205
Compare
It looks like the issue was that a change in the baseline due to a modified line height was only applied if it was positive. I think the updated branch does a better job in that situation now. |
af89205
to
125e0f6
Compare
OK, this latest branch refresh addresses those issues. There is one regression in the branch for which I don't see an easy resolution. The minimum height of a frame enclosing a line is now the height of the line. This is incorrect when the line-height is less than 1. You can see it in the following:
I'm trying to decide whether to release now without this branch (lots of good fixes already, including PHP 8.1 support), release now with this branch in its current state (noting the regression in the release notes), or delay the next release a little longer. Because the resolution of this regression is not obvious to me yet I'm leaning toward releasing now (with or without the branch), and following up with a 1.2.1 release as soon as the regression is addressed. |
✔️ Confirmed - thank you so much for your patience with these issues I reported! 🙏 Regarding the release: for me personally, the fixes from this branch would be more than welcome, also considering that a line height of less than 1 is not a very sensible/normal value (more like a hack if you ask me), so I would say the positive effect on 'normal' situations would outweigh the negative effect on more 'exotic' situations. |
Yeah, I think combining the height adjustment and line positioning adjustment is causing problems. So that we can go ahead and release the PHP compatibility updates I'm going to go ahead and push this change off for a 1.2.1 release. That'll give us a bit of time to re-assess the logic. |
87028a2
to
9d95dcb
Compare
9d95dcb
to
3d0692a
Compare
This change simplifies the vertical alignment logic by using a consistent frame of reference for djustments. 1. Determine the line baseline by calculating the "outer baseline" of the frames contained on the line. 2. For each frame on a line calculate the vertical alignment adjustment 3. Add the line height difference to the previous calculation 4. Re-position the frame per the calculated adjustment 4. Determine if the line height is adjusted after the frame is aligned 5. Re-position any following lines if the previous line height was adjusted The outer baseline height calculation is cached to aid in performance since this operation is performed inside-out after the frame has reflowed.
WIP ... need more descriptive commit and write-up here. Basically just re-wrote the logic so that vertical alignment is evaluated consistently. Addresses previously reported alignment issues, plus a few more.
Probably could use some optimization.
test file