Line data Source code
1 : /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
2 : /* This Source Code Form is subject to the terms of the Mozilla Public
3 : * License, v. 2.0. If a copy of the MPL was not distributed with this
4 : * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
5 : #include "nsPageContentFrame.h"
6 : #include "nsCSSFrameConstructor.h"
7 : #include "nsPresContext.h"
8 : #include "nsGkAtoms.h"
9 : #include "nsIPresShell.h"
10 : #include "nsSimplePageSequenceFrame.h"
11 :
12 : using namespace mozilla;
13 :
14 : nsPageContentFrame*
15 0 : NS_NewPageContentFrame(nsIPresShell* aPresShell, nsStyleContext* aContext)
16 : {
17 0 : return new (aPresShell) nsPageContentFrame(aContext);
18 : }
19 :
20 0 : NS_IMPL_FRAMEARENA_HELPERS(nsPageContentFrame)
21 :
22 : void
23 0 : nsPageContentFrame::Reflow(nsPresContext* aPresContext,
24 : ReflowOutput& aDesiredSize,
25 : const ReflowInput& aReflowInput,
26 : nsReflowStatus& aStatus)
27 : {
28 0 : MarkInReflow();
29 0 : DO_GLOBAL_REFLOW_COUNT("nsPageContentFrame");
30 0 : DISPLAY_REFLOW(aPresContext, this, aReflowInput, aDesiredSize, aStatus);
31 0 : aStatus.Reset(); // initialize out parameter
32 :
33 0 : if (GetPrevInFlow() && (GetStateBits() & NS_FRAME_FIRST_REFLOW)) {
34 : nsresult rv = aPresContext->PresShell()->FrameConstructor()
35 0 : ->ReplicateFixedFrames(this);
36 0 : if (NS_FAILED(rv)) {
37 0 : return;
38 : }
39 : }
40 :
41 : // Set our size up front, since some parts of reflow depend on it
42 : // being already set. Note that the computed height may be
43 : // unconstrained; that's ok. Consumers should watch out for that.
44 : nsSize maxSize(aReflowInput.ComputedWidth(),
45 0 : aReflowInput.ComputedHeight());
46 0 : SetSize(maxSize);
47 :
48 : // A PageContentFrame must always have one child: the canvas frame.
49 : // Resize our frame allowing it only to be as big as we are
50 : // XXX Pay attention to the page's border and padding...
51 0 : if (mFrames.NotEmpty()) {
52 0 : nsIFrame* frame = mFrames.FirstChild();
53 0 : WritingMode wm = frame->GetWritingMode();
54 0 : LogicalSize logicalSize(wm, maxSize);
55 : ReflowInput kidReflowInput(aPresContext, aReflowInput,
56 0 : frame, logicalSize);
57 0 : kidReflowInput.SetComputedBSize(logicalSize.BSize(wm));
58 :
59 : // Reflow the page content area
60 0 : ReflowChild(frame, aPresContext, aDesiredSize, kidReflowInput, 0, 0, 0, aStatus);
61 :
62 : // The document element's background should cover the entire canvas, so
63 : // take into account the combined area and any space taken up by
64 : // absolutely positioned elements
65 0 : nsMargin padding(0,0,0,0);
66 :
67 : // XXXbz this screws up percentage padding (sets padding to zero
68 : // in the percentage padding case)
69 0 : kidReflowInput.mStylePadding->GetPadding(padding);
70 :
71 : // This is for shrink-to-fit, and therefore we want to use the
72 : // scrollable overflow, since the purpose of shrink to fit is to
73 : // make the content that ought to be reachable (represented by the
74 : // scrollable overflow) fit in the page.
75 0 : if (frame->HasOverflowAreas()) {
76 : // The background covers the content area and padding area, so check
77 : // for children sticking outside the child frame's padding edge
78 0 : nscoord xmost = aDesiredSize.ScrollableOverflow().XMost();
79 0 : if (xmost > aDesiredSize.Width()) {
80 0 : nscoord widthToFit = xmost + padding.right +
81 0 : kidReflowInput.mStyleBorder->GetComputedBorderWidth(eSideRight);
82 0 : float ratio = float(maxSize.width) / widthToFit;
83 0 : NS_ASSERTION(ratio >= 0.0 && ratio < 1.0, "invalid shrink-to-fit ratio");
84 0 : mPD->mShrinkToFitRatio = std::min(mPD->mShrinkToFitRatio, ratio);
85 : }
86 : }
87 :
88 : // Place and size the child
89 0 : FinishReflowChild(frame, aPresContext, aDesiredSize, &kidReflowInput, 0, 0, 0);
90 :
91 0 : NS_ASSERTION(aPresContext->IsDynamic() || !aStatus.IsFullyComplete() ||
92 : !frame->GetNextInFlow(), "bad child flow list");
93 : }
94 :
95 : // Reflow our fixed frames
96 0 : nsReflowStatus fixedStatus;
97 0 : ReflowAbsoluteFrames(aPresContext, aDesiredSize, aReflowInput, fixedStatus);
98 0 : NS_ASSERTION(fixedStatus.IsComplete(), "fixed frames can be truncated, but not incomplete");
99 :
100 : // Return our desired size
101 0 : WritingMode wm = aReflowInput.GetWritingMode();
102 0 : aDesiredSize.ISize(wm) = aReflowInput.ComputedISize();
103 0 : if (aReflowInput.ComputedBSize() != NS_UNCONSTRAINEDSIZE) {
104 0 : aDesiredSize.BSize(wm) = aReflowInput.ComputedBSize();
105 : }
106 0 : FinishAndStoreOverflow(&aDesiredSize);
107 :
108 0 : NS_FRAME_SET_TRUNCATION(aStatus, aReflowInput, aDesiredSize);
109 : }
110 :
111 : void
112 0 : nsPageContentFrame::AppendDirectlyOwnedAnonBoxes(
113 : nsTArray<OwnedAnonBox>& aResult)
114 : {
115 0 : MOZ_ASSERT(mFrames.FirstChild(),
116 : "pageContentFrame must have a canvasFrame child");
117 0 : aResult.AppendElement(mFrames.FirstChild());
118 0 : }
119 :
120 : #ifdef DEBUG_FRAME_DUMP
121 : nsresult
122 0 : nsPageContentFrame::GetFrameName(nsAString& aResult) const
123 : {
124 0 : return MakeFrameName(NS_LITERAL_STRING("PageContent"), aResult);
125 : }
126 : #endif
|