Closed Bug 1108104 Opened 10 years ago Closed 10 years ago

position:fixed element is missing on the first page in Print Preview when styled with downloadable font

Categories

(Core :: Layout, defect)

defect
Not set
normal

Tracking

()

RESOLVED FIXED
mozilla37

People

(Reporter: MatsPalmgren_bugz, Assigned: MatsPalmgren_bugz)

References

(Depends on 1 open bug)

Details

(Keywords: testcase)

Attachments

(9 files)

(deleted), text/html
Details
(deleted), text/html
Details
(deleted), patch
roc
: review+
Details | Diff | Splinter Review
(deleted), patch
roc
: review+
Details | Diff | Splinter Review
(deleted), patch
roc
: review+
Details | Diff | Splinter Review
(deleted), text/html
Details
(deleted), patch
roc
: review+
Details | Diff | Splinter Review
(deleted), patch
roc
: review+
Details | Diff | Splinter Review
(deleted), patch
Details | Diff | Splinter Review
Attached file Testcase #1 (deleted) —
Follow-up from bug 423192 comment 10. (I'm filing this in Layout rather than Print Preview b/c I see that it's the frame tree that is wrong.) STR 1. save the attached testcase to a local file 2. load the file 3. Print Preview ACTUAL RESULT "This is a header!" is missing on the first page (it's present on subsequent pages). EXPECTED RESULT "This is a header!" on all pages. NOTE The bug only occurs when the preference gfx.downloadable_fonts.enabled is true (default).
Attached file frame tree (deleted) —
The out-of-flow frame (red) that should've been on the first page has been placed on the FixedList of the second page for some reason.
FTR, there are also some assertions - when entering Print Preview: ###!!! ASSERTION: style context has old rule node: 'mRoots[i]->RuleNode()->RuleTree() == mRuleTree', layout/style/nsStyleSet.cpp, line 254 ###!!! ASSERTION: old rule tree still referenced: 'Not Reached', layout/style/nsStyleSet.cpp, line 2081 and when closing Print Preview: ###!!! ASSERTION: destroying style context from old rule tree too late: 'styleSet->GetRuleTree() == mRuleNode->RuleTree() || styleSet->IsInRuleTreeReconstruct()', layout/style/nsStyleContext.cpp, line 92 ###!!! ASSERTION: destroying style context from old rule tree too late: 'styleSet->GetRuleTree() == mRuleNode->RuleTree() || styleSet->IsInRuleTreeReconstruct()', layout/style/nsStyleContext.cpp, line 92 ###!!! ASSERTION: destroying style context from old rule tree too late: 'styleSet->GetRuleTree() == mRuleNode->RuleTree() || styleSet->IsInRuleTreeReconstruct()', layout/style/nsStyleContext.cpp, line 92 The assertions may be a separate issue though.
Keywords: testcase
Status: NEW → ASSIGNED
OS: Linux → All
QA Contact: mats
Hardware: x86_64 → All
Assignee: nobody → mats
QA Contact: mats
There are multiple underlying bugs here, I'll describe them one by one. What happens in Print Preview on the testcase is that the (fixed pos) element (see the frame dump above) using the remote font gets a restyle request, which leads to a RecreateFramesForContent call. When inserting the new frame, we create a nsFrameConstructorState and in particular call GetAbsoluteContainingBlock which in this case returns mFixedContainingBlock as the fixed pos. container: http://mxr.mozilla.org/mozilla-central/source/layout/base/nsCSSFrameConstructor.cpp?rev=1ff07cb9adaf#5996 mFixedContainingBlock is assigned when creating a ViewportFrame or PageContentFrame: http://mxr.mozilla.org/mozilla-central/source/layout/base/nsCSSFrameConstructor.cpp?rev=1ff07cb9adaf#2676 http://mxr.mozilla.org/mozilla-central/source/layout/base/nsCSSFrameConstructor.cpp?rev=1ff07cb9adaf#2953 Thus, when printing, it's the PageContentFrame in the last printed page. So that's why RecreateFramesForContent inserts the new fixed pos frame into the last page. The proposed solution is to remove mFixedContainingBlock as a state and instead make GetAbsoluteContainingBlock return the appropriate ancestor frame.
Attachment #8533767 - Flags: review?(roc)
So, with the above fix the frame tree is now correct but it still doesn't render the fixed pos content on the first page. That's because we have intentionally disabled incremental reflows in Print Mode ("until we've taught tables how to do it right in paginated mode"): http://mxr.mozilla.org/mozilla-central/source/layout/generic/nsSimplePageSequenceFrame.cpp?rev=11fa2110679d#172 I suggest that we move that hack to nsTableOuterFrame::Reflow instead so that pages that doesn't use tables isn't crippled by it.
Attachment #8533768 - Flags: review?(roc)
So, with those two fixes we now get a crash in layout/base/crashtests/675246-1.xhtml This testcase creates a frame tree where the placeholder and its out-of-flow are on different pages (even before the earlier patches), but we have never reflowed such a frame tree though (because of the wallpaper removed in part 1). It's a null-pointer crash in CalculateHypotheticalBox because we never find the 'cbrs->frame' in the ancestors on page 2, b/c it's the PageContentFrame on page 1. I think we can just subtract the offset from the root to 'cbrs->frame' at this point to get the correct offset.
Attachment #8533770 - Flags: review?(roc)
And there's another crash in ReflowPushedFloats on layout/reftests/pagination/float-clear-000-print.html (Again, a frame tree we haven't reflowed due to the wallpaper removed in part 1). Here we have two consecutive (sibling) pushed floats in the frame list we're iterating, we save the current frame's next-sibling so we can continue iterating from there, but in this case the next-sibling is also the next-in-flow and it gets pushed. Here are some frame dumps to illustrate what happens.
The fix for that is to keep track of the last iterated frame instead and use that as the reference point where to continue the iteration.
Attachment #8533773 - Flags: review?(roc)
And lastly, there is now a layout error for layout/reftests/pagination/float-clear-000-print.html https://tbpl.mozilla.org/?tree=Try&rev=7ac702469208 This is because our reflow of pushed floats isn't stable (i.e. reflowing it twice yeilds different results). The problem here is that we change the reflow status from COMPLETE to NOT_COMPLETE when our next-in-flow has pushed floats. This is bad since it affects the height of the current frame (we end up in the last 'else' block in ComputeFinalSize). http://mxr.mozilla.org/mozilla-central/source/layout/generic/nsBlockFrame.cpp?rev=1289066eccbe#1548 As the note says, this code is a wallpaper for a columns crash: http://hg.mozilla.org/mozilla-central/rev/2ed966e4fa58 I'm not sure if it's still needed, but relaxing the condition somewhat (making the reflow status OVERFLOW_INCOMPLETE when our next-in-flow is an overflow container) seems safe for now and it fixes the layout bug. https://tbpl.mozilla.org/?tree=Try&rev=0a09d78c8196
Attachment #8533775 - Flags: review?(roc)
Attached patch reftest (deleted) — Splinter Review
Comment on attachment 8533768 [details] [diff] [review] part 2 - Move incremental reflow hack from nsSimplePageSequenceFrame::Reflow to nsTableOuterFrame. This is to avoid breaking pages that don't even use tables. Review of attachment 8533768 [details] [diff] [review]: ----------------------------------------------------------------- This is rather scary since it enables incremental reflows in paginated documents for most content other than tables. A lot of those code paths will have been tested by multicol, but some won't, or not well. This is still the right thing to do but we probably should alert our fuzzers.
Attachment #8533768 - Flags: review?(roc) → review+
(In reply to Robert O'Callahan (:roc) (Mozilla Corporation) from comment #10) > This is rather scary since it enables incremental reflows in paginated > documents for most content other than tables. A lot of those code paths will > have been tested by multicol, but some won't, or not well. This is still the > right thing to do but we probably should alert our fuzzers. For a while we disabled breaking floats in multicol containers because of incremental reflow bugs. I don't remember if we ever re-enabled that. If we did not, then this change exposes us to those bugs again. Please check.
It's still disabled (bug 447660) - I responded there. I think the risk is lower for printing since incremental reflows are rare in this context. I can add back the removed chunk in nsSimplePageSequenceFrame behind a pref if you want -- then we have the option to disable it with a hotfix. If that option isn't needed then we can land it as is I think -- it's trivial to add that chunk back during Beta if we find bugs.
Flags: needinfo?(roc)
Blocks: 447660
OK but please stay alert :-)
Flags: needinfo?(roc)
Depends on: 1152354
Depends on: 1155230
Bug 1152354 added back the incremental reflow hack in nsSimplePageSequenceFrame so I suspect this bug still occurs. I filed bug 1157012.
Depends on: 1157012
(In reply to Mats Palmgren (:mats) from comment #16) > Bug 1152354 added back the incremental reflow hack in > nsSimplePageSequenceFrame > so I suspect this bug still occurs. I filed bug 1157012. Yes, this bug still occurs: zencellose.zenglobalsolutions.com/datasheets/test3.html you can try to print and see that first page is missing. Sometimes in preview it is there, sometimes not, but header and footer never makes it to paper on first page.
You need to log in before you can comment on or make changes to this bug.

Attachment

General

Created:
Updated:
Size: