1 /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
2 /* ***** BEGIN LICENSE BLOCK *****
3 * Version: MPL 1.1/GPL 2.0/LGPL 2.1
5 * The contents of this file are subject to the Mozilla Public License Version
6 * 1.1 (the "License"); you may not use this file except in compliance with
7 * the License. You may obtain a copy of the License at
8 * http://www.mozilla.org/MPL/
10 * Software distributed under the License is distributed on an "AS IS" basis,
11 * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
12 * for the specific language governing rights and limitations under the
15 * The Original Code is mozilla.org code.
17 * The Initial Developer of the Original Code is
18 * Netscape Communications Corporation.
19 * Portions created by the Initial Developer are Copyright (C) 1998
20 * the Initial Developer. All Rights Reserved.
24 * Alternatively, the contents of this file may be used under the terms of
25 * either of the GNU General Public License Version 2 or later (the "GPL"),
26 * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
27 * in which case the provisions of the GPL or the LGPL are applicable instead
28 * of those above. If you wish to allow use of your version of this file only
29 * under the terms of either the GPL or the LGPL, and not to allow others to
30 * use your version of this file under the terms of the MPL, indicate your
31 * decision by deleting the provisions above and replace them with the notice
32 * and other provisions required by the GPL or the LGPL. If you do not delete
33 * the provisions above, a recipient may use your version of this file under
34 * the terms of any one of the MPL, the GPL or the LGPL.
36 * ***** END LICENSE BLOCK ***** */
38 #include "nsPageFrame.h"
39 #include "nsPresContext.h"
40 #include "nsStyleContext.h"
41 #include "nsIRenderingContext.h"
42 #include "nsGkAtoms.h"
43 #include "nsIPresShell.h"
44 #include "nsCSSFrameConstructor.h"
45 #include "nsIDeviceContext.h"
46 #include "nsReadableUtils.h"
47 #include "nsPageContentFrame.h"
48 #include "nsDisplayList.h"
49 #include "nsLayoutUtils.h" // for function BinarySearchForPosition
50 #include "nsCSSRendering.h"
51 #include "nsSimplePageSequence.h" // for nsSharedPageData
52 #include "nsTextFormatter.h" // for page number localization formatting
54 #include "nsBidiUtils.h"
56 #include "nsIFontMetrics.h"
57 #include "nsIPrintSettings.h"
62 extern PRLogModuleInfo
* kLayoutPrintingLogMod
;
63 #define PR_PL(_p1) PR_LOG(kLayoutPrintingLogMod, PR_LOG_DEBUG, _p1)
69 NS_NewPageFrame(nsIPresShell
* aPresShell
, nsStyleContext
* aContext
)
71 return new (aPresShell
) nsPageFrame(aContext
);
74 nsPageFrame::nsPageFrame(nsStyleContext
* aContext
)
75 : nsContainerFrame(aContext
)
79 nsPageFrame::~nsPageFrame()
83 NS_IMETHODIMP
nsPageFrame::Reflow(nsPresContext
* aPresContext
,
84 nsHTMLReflowMetrics
& aDesiredSize
,
85 const nsHTMLReflowState
& aReflowState
,
86 nsReflowStatus
& aStatus
)
88 DO_GLOBAL_REFLOW_COUNT("nsPageFrame");
89 DISPLAY_REFLOW(aPresContext
, this, aReflowState
, aDesiredSize
, aStatus
);
90 aStatus
= NS_FRAME_COMPLETE
; // initialize out parameter
92 NS_ASSERTION(mFrames
.FirstChild() &&
93 nsGkAtoms::pageContentFrame
== mFrames
.FirstChild()->GetType(),
94 "pageFrame must have a pageContentFrame child");
96 // Resize our frame allowing it only to be as big as we are
97 // XXX Pay attention to the page's border and padding...
98 if (mFrames
.NotEmpty()) {
99 nsIFrame
* frame
= mFrames
.FirstChild();
100 // When the reflow size is NS_UNCONSTRAINEDSIZE it means we are reflowing
101 // a single page to print selection. So this means we want to use
102 // NS_UNCONSTRAINEDSIZE without altering it
104 if (mPD
->mReflowSize
.height
== NS_UNCONSTRAINEDSIZE
) {
105 avHeight
= NS_UNCONSTRAINEDSIZE
;
107 avHeight
= mPD
->mReflowSize
.height
- mPD
->mReflowMargin
.TopBottom();
109 nsSize
maxSize(mPD
->mReflowSize
.width
- mPD
->mReflowMargin
.LeftRight(),
111 float scale
= aPresContext
->GetPageScale();
112 maxSize
.width
= NSToCoordCeil(maxSize
.width
/ scale
);
113 if (maxSize
.height
!= NS_UNCONSTRAINEDSIZE
) {
114 maxSize
.height
= NSToCoordCeil(maxSize
.height
/ scale
);
116 // Get the number of Twips per pixel from the PresContext
117 nscoord onePixelInTwips
= nsPresContext::CSSPixelsToAppUnits(1);
118 // insurance against infinite reflow, when reflowing less than a pixel
119 // XXX Shouldn't we do something more friendly when invalid margins
121 if (maxSize
.width
< onePixelInTwips
|| maxSize
.height
< onePixelInTwips
) {
122 aDesiredSize
.width
= 0;
123 aDesiredSize
.height
= 0;
124 NS_WARNING("Reflow aborted; no space for content");
128 nsHTMLReflowState
kidReflowState(aPresContext
, aReflowState
, frame
, maxSize
);
129 kidReflowState
.mFlags
.mIsTopOfPage
= PR_TRUE
;
130 kidReflowState
.mFlags
.mTableIsSplittable
= PR_TRUE
;
132 // calc location of frame
133 nscoord xc
= mPD
->mReflowMargin
.left
+ mPD
->mExtraMargin
.left
;
134 nscoord yc
= mPD
->mReflowMargin
.top
+ mPD
->mExtraMargin
.top
;
136 // Get the child's desired size
137 ReflowChild(frame
, aPresContext
, aDesiredSize
, kidReflowState
, xc
, yc
, 0, aStatus
);
139 // Place and size the child
140 FinishReflowChild(frame
, aPresContext
, &kidReflowState
, aDesiredSize
, xc
, yc
, 0);
142 NS_ASSERTION(!NS_FRAME_IS_FULLY_COMPLETE(aStatus
) ||
143 !frame
->GetNextInFlow(), "bad child flow list");
145 PR_PL(("PageFrame::Reflow %p ", this));
146 PR_PL(("[%d,%d][%d,%d]\n", aDesiredSize
.width
, aDesiredSize
.height
, aReflowState
.availableWidth
, aReflowState
.availableHeight
));
148 // Return our desired size
149 aDesiredSize
.width
= aReflowState
.availableWidth
;
150 if (aReflowState
.availableHeight
!= NS_UNCONSTRAINEDSIZE
) {
151 aDesiredSize
.height
= aReflowState
.availableHeight
;
153 PR_PL(("PageFrame::Reflow %p ", this));
154 PR_PL(("[%d,%d]\n", aReflowState
.availableWidth
, aReflowState
.availableHeight
));
156 NS_FRAME_SET_TRUNCATION(aStatus
, aReflowState
, aDesiredSize
);
161 nsPageFrame::GetType() const
163 return nsGkAtoms::pageFrame
;
168 nsPageFrame::GetFrameName(nsAString
& aResult
) const
170 return MakeFrameName(NS_LITERAL_STRING("Page"), aResult
);
175 nsPageFrame::IsContainingBlock() const
181 nsPageFrame::ProcessSpecialCodes(const nsString
& aStr
, nsString
& aNewStr
)
186 // Search to see if the &D code is in the string
187 // then subst in the current date/time
188 NS_NAMED_LITERAL_STRING(kDate
, "&D");
189 if (aStr
.Find(kDate
) != kNotFound
) {
190 if (mPD
->mDateTimeStr
!= nsnull
) {
191 aNewStr
.ReplaceSubstring(kDate
.get(), mPD
->mDateTimeStr
);
193 aNewStr
.ReplaceSubstring(kDate
.get(), EmptyString().get());
197 // NOTE: Must search for &PT before searching for &P
199 // Search to see if the "page number and page" total code are in the string
200 // and replace the page number and page total code with the actual
202 NS_NAMED_LITERAL_STRING(kPageAndTotal
, "&PT");
203 if (aStr
.Find(kPageAndTotal
) != kNotFound
) {
204 PRUnichar
* uStr
= nsTextFormatter::smprintf(mPD
->mPageNumAndTotalsFormat
, mPageNum
, mTotNumPages
);
205 aNewStr
.ReplaceSubstring(kPageAndTotal
.get(), uStr
);
206 nsMemory::Free(uStr
);
209 // Search to see if the page number code is in the string
210 // and replace the page number code with the actual value
211 NS_NAMED_LITERAL_STRING(kPage
, "&P");
212 if (aStr
.Find(kPage
) != kNotFound
) {
213 PRUnichar
* uStr
= nsTextFormatter::smprintf(mPD
->mPageNumFormat
, mPageNum
);
214 aNewStr
.ReplaceSubstring(kPage
.get(), uStr
);
215 nsMemory::Free(uStr
);
218 NS_NAMED_LITERAL_STRING(kTitle
, "&T");
219 if (aStr
.Find(kTitle
) != kNotFound
) {
220 if (mPD
->mDocTitle
!= nsnull
) {
221 aNewStr
.ReplaceSubstring(kTitle
.get(), mPD
->mDocTitle
);
223 aNewStr
.ReplaceSubstring(kTitle
.get(), EmptyString().get());
227 NS_NAMED_LITERAL_STRING(kDocURL
, "&U");
228 if (aStr
.Find(kDocURL
) != kNotFound
) {
229 if (mPD
->mDocURL
!= nsnull
) {
230 aNewStr
.ReplaceSubstring(kDocURL
.get(), mPD
->mDocURL
);
232 aNewStr
.ReplaceSubstring(kDocURL
.get(), EmptyString().get());
236 NS_NAMED_LITERAL_STRING(kPageTotal
, "&L");
237 if (aStr
.Find(kPageTotal
) != kNotFound
) {
238 PRUnichar
* uStr
= nsTextFormatter::smprintf(mPD
->mPageNumFormat
, mTotNumPages
);
239 aNewStr
.ReplaceSubstring(kPageTotal
.get(), uStr
);
240 nsMemory::Free(uStr
);
245 //------------------------------------------------------------------------------
246 nscoord
nsPageFrame::GetXPosition(nsIRenderingContext
& aRenderingContext
,
249 const nsString
& aStr
)
251 nscoord width
= nsLayoutUtils::GetStringWidth(this, &aRenderingContext
,
252 aStr
.get(), aStr
.Length());
256 case nsIPrintSettings::kJustLeft
:
257 x
+= mPD
->mExtraMargin
.left
+ mPD
->mEdgePaperMargin
.left
;
260 case nsIPrintSettings::kJustCenter
:
261 x
+= (aRect
.width
- width
) / 2;
264 case nsIPrintSettings::kJustRight
:
265 x
+= aRect
.width
- width
- mPD
->mExtraMargin
.right
- mPD
->mEdgePaperMargin
.right
;
272 // Draw a header or footer
273 // @param aRenderingContext - rendering content ot draw into
274 // @param aHeaderFooter - indicates whether it is a header or footer
275 // @param aStrLeft - string for the left header or footer; can be empty
276 // @param aStrCenter - string for the center header or footer; can be empty
277 // @param aStrRight - string for the right header or footer; can be empty
278 // @param aRect - the rect of the page
279 // @param aAscent - the ascent of the font
280 // @param aHeight - the height of the font
282 nsPageFrame::DrawHeaderFooter(nsIRenderingContext
& aRenderingContext
,
283 nsHeaderFooterEnum aHeaderFooter
,
284 const nsString
& aStrLeft
,
285 const nsString
& aStrCenter
,
286 const nsString
& aStrRight
,
292 if (!aStrLeft
.IsEmpty()) numStrs
++;
293 if (!aStrCenter
.IsEmpty()) numStrs
++;
294 if (!aStrRight
.IsEmpty()) numStrs
++;
296 if (numStrs
== 0) return;
297 nscoord strSpace
= aRect
.width
/ numStrs
;
299 if (!aStrLeft
.IsEmpty()) {
300 DrawHeaderFooter(aRenderingContext
, aHeaderFooter
,
301 nsIPrintSettings::kJustLeft
, aStrLeft
, aRect
, aAscent
,
304 if (!aStrCenter
.IsEmpty()) {
305 DrawHeaderFooter(aRenderingContext
, aHeaderFooter
,
306 nsIPrintSettings::kJustCenter
, aStrCenter
, aRect
, aAscent
,
309 if (!aStrRight
.IsEmpty()) {
310 DrawHeaderFooter(aRenderingContext
, aHeaderFooter
,
311 nsIPrintSettings::kJustRight
, aStrRight
, aRect
, aAscent
,
316 // Draw a header or footer string
317 // @param aRenderingContext - rendering content ot draw into
318 // @param aHeaderFooter - indicates whether it is a header or footer
319 // @param aJust - indicates where the string is located within the header/footer
320 // @param aStr - the string to be drawn
321 // @param aRect - the rect of the page
322 // @param aHeight - the height of the font
323 // @param aAscent - the ascent of the font
324 // @param aWidth - available width for the string
326 nsPageFrame::DrawHeaderFooter(nsIRenderingContext
& aRenderingContext
,
327 nsHeaderFooterEnum aHeaderFooter
,
329 const nsString
& aStr
,
336 nscoord contentWidth
= aWidth
- (mPD
->mEdgePaperMargin
.left
+ mPD
->mEdgePaperMargin
.right
);
338 if ((aHeaderFooter
== eHeader
&& aHeight
< mPD
->mReflowMargin
.top
) ||
339 (aHeaderFooter
== eFooter
&& aHeight
< mPD
->mReflowMargin
.bottom
)) {
341 ProcessSpecialCodes(aStr
, str
);
344 PRInt32 textWidth
= 0;
345 const PRUnichar
* text
= str
.get();
347 PRInt32 len
= (PRInt32
)str
.Length();
349 return; // bail is empty string
351 // find how much text fits, the "position" is the size of the available area
352 if (nsLayoutUtils::BinarySearchForPosition(&aRenderingContext
, text
, 0, 0, 0, len
,
353 PRInt32(contentWidth
), indx
, textWidth
)) {
355 // we can't fit in all the text
357 // But we can fit in at least 4 chars. Show all but 3 of them, then
359 // XXXbz for non-plane0 text, this may be cutting things in the
360 // middle of a codepoint! Also, we have no guarantees that the three
361 // dots will fit in the space the three chars we removed took up with
362 // these font metrics!
363 str
.Truncate(indx
-3);
364 str
.AppendLiteral("...");
366 // We can only fit 3 or fewer chars. Just show nothing
371 return; // bail if couldn't find the correct length
374 if (HasRTLChars(str
)) {
375 PresContext()->SetBidiEnabled();
378 // cacl the x and y positions of the text
379 nscoord x
= GetXPosition(aRenderingContext
, aRect
, aJust
, str
);
381 if (aHeaderFooter
== eHeader
) {
382 y
= aRect
.y
+ mPD
->mExtraMargin
.top
+ mPD
->mEdgePaperMargin
.top
;
384 y
= aRect
.YMost() - aHeight
- mPD
->mExtraMargin
.bottom
- mPD
->mEdgePaperMargin
.bottom
;
387 // set up new clip and draw the text
388 aRenderingContext
.PushState();
389 aRenderingContext
.SetColor(NS_RGB(0,0,0));
390 aRenderingContext
.SetClipRect(aRect
, nsClipCombine_kReplace
);
391 nsLayoutUtils::DrawString(this, &aRenderingContext
, str
.get(), str
.Length(), nsPoint(x
, y
+ aAscent
));
392 aRenderingContext
.PopState();
396 static void PaintPrintPreviewBackground(nsIFrame
* aFrame
, nsIRenderingContext
* aCtx
,
397 const nsRect
& aDirtyRect
, nsPoint aPt
)
399 static_cast<nsPageFrame
*>(aFrame
)->PaintPrintPreviewBackground(*aCtx
, aPt
);
402 static void PaintPageContent(nsIFrame
* aFrame
, nsIRenderingContext
* aCtx
,
403 const nsRect
& aDirtyRect
, nsPoint aPt
)
405 static_cast<nsPageFrame
*>(aFrame
)->PaintPageContent(*aCtx
, aDirtyRect
, aPt
);
408 static void PaintHeaderFooter(nsIFrame
* aFrame
, nsIRenderingContext
* aCtx
,
409 const nsRect
& aDirtyRect
, nsPoint aPt
)
411 static_cast<nsPageFrame
*>(aFrame
)->PaintHeaderFooter(*aCtx
, aPt
);
414 //------------------------------------------------------------------------------
416 nsPageFrame::BuildDisplayList(nsDisplayListBuilder
* aBuilder
,
417 const nsRect
& aDirtyRect
,
418 const nsDisplayListSet
& aLists
)
420 nsDisplayListCollection set
;
423 if (PresContext()->IsScreen()) {
424 rv
= set
.BorderBackground()->AppendNewToTop(new (aBuilder
)
425 nsDisplayGeneric(this, ::PaintPrintPreviewBackground
, "PrintPreviewBackground"));
426 NS_ENSURE_SUCCESS(rv
, rv
);
429 rv
= set
.BorderBackground()->AppendNewToTop(new (aBuilder
)
430 nsDisplayGeneric(this, ::PaintPageContent
, "PageContent"));
431 NS_ENSURE_SUCCESS(rv
, rv
);
433 if (PresContext()->IsRootPaginatedDocument()) {
434 rv
= set
.Content()->AppendNewToTop(new (aBuilder
)
435 nsDisplayGeneric(this, ::PaintHeaderFooter
, "HeaderFooter"));
436 NS_ENSURE_SUCCESS(rv
, rv
);
443 //------------------------------------------------------------------------------
445 nsPageFrame::SetPageNumInfo(PRInt32 aPageNumber
, PRInt32 aTotalPages
)
447 mPageNum
= aPageNumber
;
448 mTotNumPages
= aTotalPages
;
453 nsPageFrame::PaintPrintPreviewBackground(nsIRenderingContext
& aRenderingContext
,
456 // fill page with White
457 aRenderingContext
.SetColor(NS_RGB(255,255,255));
458 // REVIEW: this used to have rect's width and height be the
459 // mClipRect if specialClipIsSet ... but that seems completely bogus
460 // and inconsistent with the painting of the shadow below
461 nsRect
rect(aPt
, GetSize());
462 rect
.width
-= mPD
->mShadowSize
.width
;
463 rect
.height
-= mPD
->mShadowSize
.height
;
464 aRenderingContext
.FillRect(rect
);
465 // draw line around outside of page
466 aRenderingContext
.SetColor(NS_RGB(0,0,0));
467 aRenderingContext
.DrawRect(rect
);
469 if (mPD
->mShadowSize
.width
> 0 && mPD
->mShadowSize
.height
> 0) {
470 aRenderingContext
.SetColor(NS_RGB(51,51,51));
471 nsRect
r(aPt
.x
,aPt
.y
, mRect
.width
, mRect
.height
);
473 shadowRect
.x
= r
.x
+ r
.width
- mPD
->mShadowSize
.width
;
474 shadowRect
.y
= r
.y
+ mPD
->mShadowSize
.height
;
475 shadowRect
.width
= mPD
->mShadowSize
.width
;
476 shadowRect
.height
= r
.height
- mPD
->mShadowSize
.height
;
477 aRenderingContext
.FillRect(shadowRect
);
479 shadowRect
.x
= r
.x
+ mPD
->mShadowSize
.width
;
480 shadowRect
.y
= r
.y
+ r
.height
- mPD
->mShadowSize
.height
;
481 shadowRect
.width
= r
.width
- mPD
->mShadowSize
.width
;
482 shadowRect
.height
= mPD
->mShadowSize
.height
;
483 aRenderingContext
.FillRect(shadowRect
);
488 nsPageFrame::PaintHeaderFooter(nsIRenderingContext
& aRenderingContext
,
491 nsPresContext
* pc
= PresContext();
493 if (!mPD
->mPrintSettings
) {
494 if (pc
->Type() == nsPresContext::eContext_PrintPreview
|| pc
->IsDynamic())
495 mPD
->mPrintSettings
= pc
->GetPrintSettings();
496 if (!mPD
->mPrintSettings
)
500 nsRect
rect(aPt
.x
, aPt
.y
, mRect
.width
- mPD
->mShadowSize
.width
,
501 mRect
.height
- mPD
->mShadowSize
.height
);
503 aRenderingContext
.SetFont(*mPD
->mHeadFootFont
, nsnull
);
504 aRenderingContext
.SetColor(NS_RGB(0,0,0));
506 // Get the FontMetrics to determine width.height of strings
507 nsCOMPtr
<nsIFontMetrics
> fontMet
;
508 pc
->DeviceContext()->GetMetricsFor(*mPD
->mHeadFootFont
, nsnull
,
509 *getter_AddRefs(fontMet
));
511 nscoord visibleHeight
= 0;
513 fontMet
->GetHeight(visibleHeight
);
514 fontMet
->GetMaxAscent(ascent
);
517 // print document headers and footers
518 nsXPIDLString headerLeft
, headerCenter
, headerRight
;
519 mPD
->mPrintSettings
->GetHeaderStrLeft(getter_Copies(headerLeft
));
520 mPD
->mPrintSettings
->GetHeaderStrCenter(getter_Copies(headerCenter
));
521 mPD
->mPrintSettings
->GetHeaderStrRight(getter_Copies(headerRight
));
522 DrawHeaderFooter(aRenderingContext
, eHeader
,
523 headerLeft
, headerCenter
, headerRight
,
524 rect
, ascent
, visibleHeight
);
526 nsXPIDLString footerLeft
, footerCenter
, footerRight
;
527 mPD
->mPrintSettings
->GetFooterStrLeft(getter_Copies(footerLeft
));
528 mPD
->mPrintSettings
->GetFooterStrCenter(getter_Copies(footerCenter
));
529 mPD
->mPrintSettings
->GetFooterStrRight(getter_Copies(footerRight
));
530 DrawHeaderFooter(aRenderingContext
, eFooter
,
531 footerLeft
, footerCenter
, footerRight
,
532 rect
, ascent
, visibleHeight
);
535 //------------------------------------------------------------------------------
537 nsPageFrame::PaintPageContent(nsIRenderingContext
& aRenderingContext
,
538 const nsRect
& aDirtyRect
,
540 nsIFrame
* pageContentFrame
= mFrames
.FirstChild();
541 nsRect rect
= aDirtyRect
;
542 float scale
= PresContext()->GetPageScale();
543 aRenderingContext
.PushState();
544 nsPoint framePos
= aPt
+ pageContentFrame
->GetOffsetTo(this);
545 aRenderingContext
.Translate(framePos
.x
, framePos
.y
);
546 // aPt translates to coords relative to this, then margins translate to
547 // pageContentFrame's coords
549 aRenderingContext
.Scale(scale
, scale
);
550 rect
.ScaleRoundOut(1.0f
/ scale
);
551 // Make sure we don't draw where we aren't supposed to draw, especially
552 // when printing selection
553 nsRect
clipRect(nsPoint(0, 0), pageContentFrame
->GetSize());
554 // Note: this computation matches how we compute maxSize.height
555 // in nsPageFrame::Reflow
556 nscoord expectedPageContentHeight
=
557 NSToCoordCeil((GetSize().height
- mPD
->mReflowMargin
.TopBottom()) / scale
);
558 if (clipRect
.height
> expectedPageContentHeight
) {
559 // We're doing print-selection, with one long page-content frame.
560 // Clip to the appropriate page-content slice for the current page.
561 NS_ASSERTION(mPageNum
> 0, "page num should be positive");
562 // Note: The pageContentFrame's y-position has been set such that a zero
563 // y-value matches the top edge of the current page. So, to clip to the
564 // current page's content (in coordinates *relative* to the page content
565 // frame), we just negate its y-position and add the top margin.
566 clipRect
.y
= NSToCoordCeil((-pageContentFrame
->GetRect().y
+
567 mPD
->mReflowMargin
.top
) / scale
);
568 clipRect
.height
= expectedPageContentHeight
;
569 NS_ASSERTION(clipRect
.y
< pageContentFrame
->GetSize().height
,
570 "Should be clipping to region inside the page content bounds");
572 aRenderingContext
.SetClipRect(clipRect
, nsClipCombine_kIntersect
);
574 const nsStyleBorder
* border
= GetStyleBorder();
575 const nsStylePadding
* padding
= GetStylePadding();
576 nsRect backgroundRect
= nsRect(nsPoint(0, 0), pageContentFrame
->GetSize());
577 nsCSSRendering::PaintBackground(PresContext(), aRenderingContext
, this,
578 rect
, backgroundRect
, *border
, *padding
,
581 nsLayoutUtils::PaintFrame(&aRenderingContext
, pageContentFrame
,
582 nsRegion(rect
), NS_RGBA(0,0,0,0));
584 aRenderingContext
.PopState();
588 nsPageFrame::SetSharedPageData(nsSharedPageData
* aPD
)
591 // Set the shared data into the page frame before reflow
592 nsPageContentFrame
* pcf
= static_cast<nsPageContentFrame
*>(mFrames
.FirstChild());
594 pcf
->SetSharedPageData(mPD
);
600 NS_NewPageBreakFrame(nsIPresShell
* aPresShell
, nsStyleContext
* aContext
)
602 NS_PRECONDITION(aPresShell
, "null PresShell");
603 //check that we are only creating page break frames when printing
604 NS_ASSERTION(aPresShell
->GetPresContext()->IsPaginated(), "created a page break frame while not printing");
606 return new (aPresShell
) nsPageBreakFrame(aContext
);
609 nsPageBreakFrame::nsPageBreakFrame(nsStyleContext
* aContext
) :
610 nsLeafFrame(aContext
), mHaveReflowed(PR_FALSE
)
614 nsPageBreakFrame::~nsPageBreakFrame()
619 nsPageBreakFrame::GetIntrinsicWidth()
621 return nsPresContext::CSSPixelsToAppUnits(1);
625 nsPageBreakFrame::GetIntrinsicHeight()
631 nsPageBreakFrame::Reflow(nsPresContext
* aPresContext
,
632 nsHTMLReflowMetrics
& aDesiredSize
,
633 const nsHTMLReflowState
& aReflowState
,
634 nsReflowStatus
& aStatus
)
636 DO_GLOBAL_REFLOW_COUNT("nsPageBreakFrame");
637 DISPLAY_REFLOW(aPresContext
, this, aReflowState
, aDesiredSize
, aStatus
);
639 // Override reflow, since we don't want to deal with what our
640 // computed values are.
641 aDesiredSize
.width
= GetIntrinsicWidth();
642 aDesiredSize
.height
= (aReflowState
.availableHeight
== NS_UNCONSTRAINEDSIZE
?
643 0 : aReflowState
.availableHeight
);
644 // round the height down to the nearest pixel
645 aDesiredSize
.height
-=
646 aDesiredSize
.height
% nsPresContext::CSSPixelsToAppUnits(1);
648 // Note: not using NS_FRAME_FIRST_REFLOW here, since it's not clear whether
649 // DidReflow will always get called before the next Reflow() call.
650 mHaveReflowed
= PR_TRUE
;
651 aStatus
= NS_FRAME_COMPLETE
;
656 nsPageBreakFrame::GetType() const
658 return nsGkAtoms::pageBreakFrame
;