Back to index

lightning-sunbird  0.9+nobinonly
nsPageContentFrame.cpp
Go to the documentation of this file.
00001 /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
00002 /* ***** BEGIN LICENSE BLOCK *****
00003  * Version: MPL 1.1/GPL 2.0/LGPL 2.1
00004  *
00005  * The contents of this file are subject to the Mozilla Public License Version
00006  * 1.1 (the "License"); you may not use this file except in compliance with
00007  * the License. You may obtain a copy of the License at
00008  * http://www.mozilla.org/MPL/
00009  *
00010  * Software distributed under the License is distributed on an "AS IS" basis,
00011  * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
00012  * for the specific language governing rights and limitations under the
00013  * License.
00014  *
00015  * The Original Code is mozilla.org code.
00016  *
00017  * The Initial Developer of the Original Code is
00018  * Netscape Communications Corporation.
00019  * Portions created by the Initial Developer are Copyright (C) 1998
00020  * the Initial Developer. All Rights Reserved.
00021  *
00022  * Contributor(s):
00023  *
00024  * Alternatively, the contents of this file may be used under the terms of
00025  * either of the GNU General Public License Version 2 or later (the "GPL"),
00026  * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
00027  * in which case the provisions of the GPL or the LGPL are applicable instead
00028  * of those above. If you wish to allow use of your version of this file only
00029  * under the terms of either the GPL or the LGPL, and not to allow others to
00030  * use your version of this file under the terms of the MPL, indicate your
00031  * decision by deleting the provisions above and replace them with the notice
00032  * and other provisions required by the GPL or the LGPL. If you do not delete
00033  * the provisions above, a recipient may use your version of this file under
00034  * the terms of any one of the MPL, the GPL or the LGPL.
00035  *
00036  * ***** END LICENSE BLOCK ***** */
00037 #include "nsPageContentFrame.h"
00038 #include "nsHTMLParts.h"
00039 #include "nsIContent.h"
00040 #include "nsPresContext.h"
00041 #include "nsIRenderingContext.h"
00042 #include "nsHTMLAtoms.h"
00043 #include "nsLayoutAtoms.h"
00044 #include "nsIPresShell.h"
00045 #include "nsIDeviceContext.h"
00046 #include "nsReadableUtils.h"
00047 #include "nsSimplePageSequence.h"
00048 
00049 #include "nsIView.h"
00050 
00051 #if defined(DEBUG_rods) || defined(DEBUG_dcone)
00052 //#define DEBUG_PRINTING
00053 #endif
00054 
00055 
00056 nsresult
00057 NS_NewPageContentFrame(nsIPresShell* aPresShell, nsIFrame** aNewFrame)
00058 {
00059   NS_PRECONDITION(aNewFrame, "null OUT ptr");
00060 
00061   nsPageContentFrame* it = new (aPresShell) nsPageContentFrame;
00062   if (nsnull == it) {
00063     return NS_ERROR_OUT_OF_MEMORY;
00064   }
00065   *aNewFrame = it;
00066   return NS_OK;
00067 }
00068 
00069 nsPageContentFrame::nsPageContentFrame() :
00070   mClipRect(-1, -1, -1, -1)
00071 {
00072 }
00073 
00074 NS_IMETHODIMP nsPageContentFrame::Reflow(nsPresContext*   aPresContext,
00075                                   nsHTMLReflowMetrics&     aDesiredSize,
00076                                   const nsHTMLReflowState& aReflowState,
00077                                   nsReflowStatus&          aStatus)
00078 {
00079   DO_GLOBAL_REFLOW_COUNT("nsPageContentFrame", aReflowState.reason);
00080   DISPLAY_REFLOW(aPresContext, this, aReflowState, aDesiredSize, aStatus);
00081   aStatus = NS_FRAME_COMPLETE;  // initialize out parameter
00082 
00083   if (eReflowReason_Incremental != aReflowState.reason) {
00084     // Resize our frame allowing it only to be as big as we are
00085     // XXX Pay attention to the page's border and padding...
00086     if (mFrames.NotEmpty()) {
00087       nsIFrame* frame = mFrames.FirstChild();
00088       nsSize  maxSize(aReflowState.availableWidth, aReflowState.availableHeight);
00089       nsHTMLReflowState kidReflowState(aPresContext, aReflowState, frame, maxSize);
00090 
00091       mPD->mPageContentSize  = aReflowState.availableWidth;
00092 
00093       // Reflow the page content area to get the child's desired size
00094       ReflowChild(frame, aPresContext, aDesiredSize, kidReflowState, 0, 0, 0, aStatus);
00095 
00096       // The document element's background should cover the entire canvas, so
00097       // take into account the combined area and any space taken up by
00098       // absolutely positioned elements
00099       nsMargin padding(0,0,0,0);
00100 
00101       // XXXbz this screws up percentage padding (sets padding to zero
00102       // in the percentage padding case)
00103       kidReflowState.mStylePadding->GetPadding(padding);
00104 
00105       // First check the combined area
00106       if (NS_FRAME_OUTSIDE_CHILDREN & frame->GetStateBits()) {
00107         // The background covers the content area and padding area, so check
00108         // for children sticking outside the child frame's padding edge
00109         if (aDesiredSize.mOverflowArea.XMost() > aDesiredSize.width) {
00110           mPD->mPageContentXMost =
00111             aDesiredSize.mOverflowArea.XMost() +
00112             kidReflowState.mStyleBorder->GetBorderWidth(NS_SIDE_RIGHT) +
00113             padding.right;
00114         }
00115       }
00116 
00117       // Place and size the child
00118       FinishReflowChild(frame, aPresContext, &kidReflowState, aDesiredSize, 0, 0, 0);
00119 
00120       NS_ASSERTION(!NS_FRAME_IS_COMPLETE(aStatus) ||
00121                    !frame->GetNextInFlow(), "bad child flow list");
00122 
00123 #ifdef DEBUG_PRINTING
00124       nsRect r = frame->GetRect();
00125       printf("PCF: Area Frame %p Bounds: %5d,%5d,%5d,%5d\n", frame, r.x, r.y, r.width, r.height);
00126       nsIView* view = frame->GetView();
00127       if (view) {
00128         r = view->GetBounds();
00129         printf("PCF: Area Frame View Bounds: %5d,%5d,%5d,%5d\n", r.x, r.y, r.width, r.height);
00130       } else {
00131         printf("PCF: Area Frame View Bounds: NO VIEW\n");
00132       }
00133 #endif
00134     }
00135     // Reflow our fixed frames 
00136     mFixedContainer.Reflow(this, aPresContext, aReflowState, aReflowState.availableWidth, 
00137                            aReflowState.availableHeight);
00138 
00139     // Return our desired size
00140     aDesiredSize.width = aReflowState.availableWidth;
00141     if (aReflowState.availableHeight != NS_UNCONSTRAINEDSIZE) {
00142       aDesiredSize.height = aReflowState.availableHeight;
00143     }
00144   }
00145 
00146   NS_FRAME_SET_TRUNCATION(aStatus, aReflowState, aDesiredSize);
00147   return NS_OK;
00148 }
00149 
00150 nsIAtom*
00151 nsPageContentFrame::GetType() const
00152 {
00153   return nsLayoutAtoms::pageContentFrame; 
00154 }
00155 
00156 #ifdef DEBUG
00157 NS_IMETHODIMP
00158 nsPageContentFrame::GetFrameName(nsAString& aResult) const
00159 {
00160   return MakeFrameName(NS_LITERAL_STRING("PageContent"), aResult);
00161 }
00162 #endif
00163 
00164 /* virtual */ PRBool
00165 nsPageContentFrame::IsContainingBlock() const
00166 {
00167   return PR_TRUE;
00168 }
00169 
00170 
00171 //------------------------------------------------------------------------------
00172 NS_IMETHODIMP
00173 nsPageContentFrame::Paint(nsPresContext*      aPresContext,
00174                    nsIRenderingContext& aRenderingContext,
00175                    const nsRect&        aDirtyRect,
00176                    nsFramePaintLayer    aWhichLayer,
00177                    PRUint32             aFlags)
00178 {
00179   aRenderingContext.PushState();
00180 
00181   nsRect rect;
00182   if (mClipRect.width != -1 || mClipRect.height != -1) {
00183     rect = mClipRect;
00184   } else {
00185     rect = mRect;
00186     rect.x = 0;
00187     rect.y = 0;
00188   }
00189 
00190   aRenderingContext.SetClipRect(rect, nsClipCombine_kReplace);
00191 
00192   nsresult rv = nsContainerFrame::Paint(aPresContext, aRenderingContext, aDirtyRect, aWhichLayer);
00193 
00194 #if defined(DEBUG_rods) || defined(DEBUG_dcone)
00195   if (NS_FRAME_PAINT_LAYER_BACKGROUND == aWhichLayer) {
00196     nsRect r = mRect;
00197     r.x = 0;
00198     r.y = 0;
00199     aRenderingContext.SetColor(NS_RGB(0, 0, 0));
00200     aRenderingContext.DrawRect(r);
00201   }
00202 #endif
00203 
00204   aRenderingContext.PopState();
00205 
00206   return rv;
00207 }
00208 
00209 
00210