LCOV - code coverage report
Current view: directory - layout/generic - nsSimplePageSequence.cpp (source / functions) Found Hit Coverage
Test: app.info Lines: 333 2 0.6 %
Date: 2012-06-02 Functions: 30 2 6.7 %

       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
       4                 :  *
       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/
       9                 :  *
      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
      13                 :  * License.
      14                 :  *
      15                 :  * The Original Code is mozilla.org code.
      16                 :  *
      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.
      21                 :  *
      22                 :  * Contributor(s):
      23                 :  *
      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.
      35                 :  *
      36                 :  * ***** END LICENSE BLOCK ***** */
      37                 : #include "nsCOMPtr.h" 
      38                 : #include "nsReadableUtils.h"
      39                 : #include "nsSimplePageSequence.h"
      40                 : #include "nsPresContext.h"
      41                 : #include "gfxContext.h"
      42                 : #include "nsRenderingContext.h"
      43                 : #include "nsGkAtoms.h"
      44                 : #include "nsIPresShell.h"
      45                 : #include "nsIPrintSettings.h"
      46                 : #include "nsPageFrame.h"
      47                 : #include "nsStyleConsts.h"
      48                 : #include "nsRegion.h"
      49                 : #include "nsCSSFrameConstructor.h"
      50                 : #include "nsContentUtils.h"
      51                 : #include "nsDisplayList.h"
      52                 : #include "mozilla/Preferences.h"
      53                 : 
      54                 : // DateTime Includes
      55                 : #include "nsDateTimeFormatCID.h"
      56                 : 
      57                 : #define OFFSET_NOT_SET -1
      58                 : 
      59                 : // Print Options
      60                 : #include "nsIPrintOptions.h"
      61                 : #include "nsGfxCIID.h"
      62                 : #include "nsIServiceManager.h"
      63                 : 
      64                 : using namespace mozilla;
      65                 : 
      66                 : static const char sPrintOptionsContractID[] = "@mozilla.org/gfx/printsettings-service;1";
      67                 : 
      68                 : //
      69                 : 
      70                 : #include "prlog.h"
      71                 : #ifdef PR_LOGGING 
      72            1464 : PRLogModuleInfo * kLayoutPrintingLogMod = PR_NewLogModule("printing-layout");
      73                 : #define PR_PL(_p1)  PR_LOG(kLayoutPrintingLogMod, PR_LOG_DEBUG, _p1)
      74                 : #else
      75                 : #define PR_PL(_p1)
      76                 : #endif
      77                 : 
      78                 : // This object a shared by all the nsPageFrames 
      79                 : // parented to a SimplePageSequenceFrame
      80               0 : nsSharedPageData::nsSharedPageData() :
      81                 :   mDateTimeStr(nsnull),
      82                 :   mHeadFootFont(nsnull),
      83                 :   mPageNumFormat(nsnull),
      84                 :   mPageNumAndTotalsFormat(nsnull),
      85                 :   mDocTitle(nsnull),
      86                 :   mDocURL(nsnull),
      87                 :   mReflowSize(0,0),
      88                 :   mReflowMargin(0,0,0,0),
      89                 :   mExtraMargin(0,0,0,0),
      90                 :   mEdgePaperMargin(0,0,0,0),
      91                 :   mPageContentXMost(0),
      92               0 :   mPageContentSize(0)
      93                 : {
      94               0 : }
      95                 : 
      96               0 : nsSharedPageData::~nsSharedPageData()
      97                 : {
      98               0 :   nsMemory::Free(mDateTimeStr);
      99               0 :   delete mHeadFootFont;
     100               0 :   nsMemory::Free(mPageNumFormat);
     101               0 :   nsMemory::Free(mPageNumAndTotalsFormat);
     102               0 :   if (mDocTitle) nsMemory::Free(mDocTitle);
     103               0 :   if (mDocURL) nsMemory::Free(mDocURL);
     104               0 : }
     105                 : 
     106                 : nsIFrame*
     107               0 : NS_NewSimplePageSequenceFrame(nsIPresShell* aPresShell, nsStyleContext* aContext)
     108                 : {
     109               0 :   return new (aPresShell) nsSimplePageSequenceFrame(aContext);
     110                 : }
     111                 : 
     112               0 : NS_IMPL_FRAMEARENA_HELPERS(nsSimplePageSequenceFrame)
     113                 : 
     114               0 : nsSimplePageSequenceFrame::nsSimplePageSequenceFrame(nsStyleContext* aContext) :
     115                 :   nsContainerFrame(aContext),
     116                 :   mTotalPages(-1),
     117                 :   mSelectionHeight(-1),
     118               0 :   mYSelOffset(0)
     119                 : {
     120               0 :   nscoord halfInch = PresContext()->CSSTwipsToAppUnits(NS_INCHES_TO_TWIPS(0.5));
     121               0 :   mMargin.SizeTo(halfInch, halfInch, halfInch, halfInch);
     122                 : 
     123                 :   // XXX Unsafe to assume successful allocation
     124               0 :   mPageData = new nsSharedPageData();
     125                 :   mPageData->mHeadFootFont =
     126                 :     new nsFont(*PresContext()->GetDefaultFont(kGenericFont_serif,
     127               0 :                                               aContext->GetStyleFont()->mLanguage));
     128               0 :   mPageData->mHeadFootFont->size = nsPresContext::CSSPointsToAppUnits(10);
     129                 : 
     130                 :   nsresult rv;
     131               0 :   mPageData->mPrintOptions = do_GetService(sPrintOptionsContractID, &rv);
     132                 : 
     133                 :   // Doing this here so we only have to go get these formats once
     134               0 :   SetPageNumberFormat("pagenumber",  "%1$d", true);
     135               0 :   SetPageNumberFormat("pageofpages", "%1$d of %2$d", false);
     136               0 : }
     137                 : 
     138               0 : nsSimplePageSequenceFrame::~nsSimplePageSequenceFrame()
     139                 : {
     140               0 :   delete mPageData;
     141               0 : }
     142                 : 
     143               0 : NS_QUERYFRAME_HEAD(nsSimplePageSequenceFrame)
     144               0 :   NS_QUERYFRAME_ENTRY(nsIPageSequenceFrame)
     145               0 : NS_QUERYFRAME_TAIL_INHERITING(nsContainerFrame)
     146                 : 
     147                 : //----------------------------------------------------------------------
     148                 : 
     149                 : void
     150               0 : nsSimplePageSequenceFrame::SetDesiredSize(nsHTMLReflowMetrics& aDesiredSize,
     151                 :                                           const nsHTMLReflowState& aReflowState,
     152                 :                                           nscoord aWidth,
     153                 :                                           nscoord aHeight)
     154                 : {
     155                 :     // Aim to fill the whole size of the document, not only so we
     156                 :     // can act as a background in print preview but also handle overflow
     157                 :     // in child page frames correctly.
     158                 :     // Use availableWidth so we don't cause a needless horizontal scrollbar.
     159                 :     aDesiredSize.width = NS_MAX(aReflowState.availableWidth,
     160               0 :                                 nscoord(aWidth * PresContext()->GetPrintPreviewScale()));
     161               0 :     aDesiredSize.height = NS_MAX(aReflowState.ComputedHeight(),
     162               0 :                                  nscoord(aHeight * PresContext()->GetPrintPreviewScale()));
     163               0 : }
     164                 : 
     165                 : NS_IMETHODIMP
     166               0 : nsSimplePageSequenceFrame::Reflow(nsPresContext*          aPresContext,
     167                 :                                   nsHTMLReflowMetrics&     aDesiredSize,
     168                 :                                   const nsHTMLReflowState& aReflowState,
     169                 :                                   nsReflowStatus&          aStatus)
     170                 : {
     171               0 :   NS_PRECONDITION(aPresContext->IsRootPaginatedDocument(),
     172                 :                   "A Page Sequence is only for real pages");
     173               0 :   DO_GLOBAL_REFLOW_COUNT("nsSimplePageSequenceFrame");
     174               0 :   DISPLAY_REFLOW(aPresContext, this, aReflowState, aDesiredSize, aStatus);
     175               0 :   NS_FRAME_TRACE_REFLOW_IN("nsSimplePageSequenceFrame::Reflow");
     176                 : 
     177               0 :   aStatus = NS_FRAME_COMPLETE;  // we're always complete
     178                 : 
     179                 :   // Don't do incremental reflow until we've taught tables how to do
     180                 :   // it right in paginated mode.
     181               0 :   if (!(GetStateBits() & NS_FRAME_FIRST_REFLOW)) {
     182                 :     // Return our desired size
     183               0 :     SetDesiredSize(aDesiredSize, aReflowState, mSize.width, mSize.height);
     184               0 :     aDesiredSize.SetOverflowAreasToDesiredBounds();
     185               0 :     FinishAndStoreOverflow(&aDesiredSize);
     186               0 :     return NS_OK;
     187                 :   }
     188                 : 
     189                 :   // See if we can get a Print Settings from the Context
     190               0 :   if (!mPageData->mPrintSettings &&
     191               0 :       aPresContext->Medium() == nsGkAtoms::print) {
     192               0 :       mPageData->mPrintSettings = aPresContext->GetPrintSettings();
     193                 :   }
     194                 : 
     195                 :   // now get out margins & edges
     196               0 :   if (mPageData->mPrintSettings) {
     197               0 :     nsIntMargin unwriteableTwips;
     198               0 :     mPageData->mPrintSettings->GetUnwriteableMarginInTwips(unwriteableTwips);
     199               0 :     NS_ASSERTION(unwriteableTwips.left  >= 0 && unwriteableTwips.top >= 0 &&
     200                 :                  unwriteableTwips.right >= 0 && unwriteableTwips.bottom >= 0,
     201                 :                  "Unwriteable twips should be non-negative");
     202                 : 
     203               0 :     nsIntMargin marginTwips;
     204               0 :     mPageData->mPrintSettings->GetMarginInTwips(marginTwips);
     205               0 :     mMargin = aPresContext->CSSTwipsToAppUnits(marginTwips + unwriteableTwips);
     206                 : 
     207                 :     PRInt16 printType;
     208               0 :     mPageData->mPrintSettings->GetPrintRange(&printType);
     209               0 :     mPrintRangeType = printType;
     210                 : 
     211               0 :     nsIntMargin edgeTwips;
     212               0 :     mPageData->mPrintSettings->GetEdgeInTwips(edgeTwips);
     213                 : 
     214                 :     // sanity check the values. three inches are sometimes needed
     215               0 :     PRInt32 inchInTwips = NS_INCHES_TO_INT_TWIPS(3.0);
     216               0 :     edgeTwips.top    = clamped(edgeTwips.top,    0, inchInTwips);
     217               0 :     edgeTwips.bottom = clamped(edgeTwips.bottom, 0, inchInTwips);
     218               0 :     edgeTwips.left   = clamped(edgeTwips.left,   0, inchInTwips);
     219               0 :     edgeTwips.right  = clamped(edgeTwips.right,  0, inchInTwips);
     220                 : 
     221                 :     mPageData->mEdgePaperMargin =
     222               0 :       aPresContext->CSSTwipsToAppUnits(edgeTwips + unwriteableTwips);
     223                 :   }
     224                 : 
     225                 :   // *** Special Override ***
     226                 :   // If this is a sub-sdoc (meaning it doesn't take the whole page)
     227                 :   // and if this Document is in the upper left hand corner
     228                 :   // we need to suppress the top margin or it will reflow too small
     229                 : 
     230               0 :   nsSize pageSize = aPresContext->GetPageSize();
     231                 : 
     232               0 :   mPageData->mReflowSize = pageSize;
     233                 :   // If we're printing a selection, we need to reflow with
     234                 :   // unconstrained height, to make sure we'll get to the selection
     235                 :   // even if it's beyond the first page of content.
     236               0 :   if (nsIPrintSettings::kRangeSelection == mPrintRangeType) {
     237               0 :     mPageData->mReflowSize.height = NS_UNCONSTRAINEDSIZE;
     238                 :   }
     239               0 :   mPageData->mReflowMargin = mMargin;
     240                 : 
     241                 :   // Compute the size of each page and the x coordinate that each page will
     242                 :   // be placed at
     243               0 :   nscoord extraThreshold = NS_MAX(pageSize.width, pageSize.height)/10;
     244               0 :   PRInt32 gapInTwips = Preferences::GetInt("print.print_extra_margin");
     245               0 :   gapInTwips = NS_MAX(0, gapInTwips);
     246                 : 
     247               0 :   nscoord extraGap = aPresContext->CSSTwipsToAppUnits(gapInTwips);
     248               0 :   extraGap = NS_MIN(extraGap, extraThreshold); // clamp to 1/10 of the largest dim of the page
     249                 : 
     250               0 :   nsMargin extraMargin(0,0,0,0);
     251               0 :   if (aPresContext->IsScreen()) {
     252               0 :     extraMargin.SizeTo(extraGap, extraGap, extraGap, extraGap);
     253                 :   }
     254                 : 
     255               0 :   mPageData->mExtraMargin = extraMargin;
     256                 : 
     257                 :   // We use the CSS "margin" property on the -moz-page pseudoelement
     258                 :   // to determine the space between each page in print preview.
     259                 :   // Keep a running y-offset for each page.
     260               0 :   nscoord y = 0;
     261               0 :   nscoord maxXMost = 0;
     262                 : 
     263               0 :   nsSize availSize(pageSize.width + extraMargin.LeftRight(),
     264               0 :                    pageSize.height + extraMargin.TopBottom());
     265                 : 
     266                 :   // Tile the pages vertically
     267               0 :   nsHTMLReflowMetrics kidSize;
     268               0 :   for (nsIFrame* kidFrame = mFrames.FirstChild(); nsnull != kidFrame; ) {
     269                 :     // Set the shared data into the page frame before reflow
     270               0 :     nsPageFrame * pf = static_cast<nsPageFrame*>(kidFrame);
     271               0 :     pf->SetSharedPageData(mPageData);
     272                 : 
     273                 :     // Reflow the page
     274                 :     nsHTMLReflowState kidReflowState(aPresContext, aReflowState, kidFrame,
     275               0 :                                      availSize);
     276                 :     nsReflowStatus  status;
     277                 : 
     278               0 :     kidReflowState.SetComputedWidth(kidReflowState.availableWidth);
     279                 :     //kidReflowState.SetComputedHeight(kidReflowState.availableHeight);
     280               0 :     PR_PL(("AV W: %d   H: %d\n", kidReflowState.availableWidth, kidReflowState.availableHeight));
     281                 : 
     282               0 :     nsMargin pageCSSMargin = kidReflowState.mComputedMargin;
     283               0 :     y += pageCSSMargin.top;
     284               0 :     const nscoord x = pageCSSMargin.left;
     285                 : 
     286                 :     // Place and size the page. If the page is narrower than our
     287                 :     // max width then center it horizontally
     288               0 :     ReflowChild(kidFrame, aPresContext, kidSize, kidReflowState, x, y, 0, status);
     289                 : 
     290               0 :     FinishReflowChild(kidFrame, aPresContext, nsnull, kidSize, x, y, 0);
     291               0 :     y += kidSize.height;
     292               0 :     y += pageCSSMargin.bottom;
     293                 : 
     294               0 :     maxXMost = NS_MAX(maxXMost, x + kidSize.width + pageCSSMargin.right);
     295                 : 
     296                 :     // Is the page complete?
     297               0 :     nsIFrame* kidNextInFlow = kidFrame->GetNextInFlow();
     298                 : 
     299               0 :     if (NS_FRAME_IS_FULLY_COMPLETE(status)) {
     300               0 :       NS_ASSERTION(!kidNextInFlow, "bad child flow list");
     301               0 :     } else if (!kidNextInFlow) {
     302                 :       // The page isn't complete and it doesn't have a next-in-flow, so
     303                 :       // create a continuing page.
     304                 :       nsIFrame* continuingPage;
     305                 :       nsresult rv = aPresContext->PresShell()->FrameConstructor()->
     306               0 :         CreateContinuingFrame(aPresContext, kidFrame, this, &continuingPage);
     307               0 :       if (NS_FAILED(rv)) {
     308                 :         break;
     309                 :       }
     310                 : 
     311                 :       // Add it to our child list
     312               0 :       mFrames.InsertFrame(nsnull, kidFrame, continuingPage);
     313                 :     }
     314                 : 
     315                 :     // Get the next page
     316               0 :     kidFrame = kidFrame->GetNextSibling();
     317                 :   }
     318                 : 
     319                 :   // Get Total Page Count
     320                 :   nsIFrame* page;
     321               0 :   PRInt32 pageTot = 0;
     322               0 :   for (page = mFrames.FirstChild(); page; page = page->GetNextSibling()) {
     323               0 :     pageTot++;
     324                 :   }
     325                 : 
     326                 :   // Set Page Number Info
     327               0 :   PRInt32 pageNum = 1;
     328               0 :   for (page = mFrames.FirstChild(); page; page = page->GetNextSibling()) {
     329               0 :     nsPageFrame * pf = static_cast<nsPageFrame*>(page);
     330               0 :     if (pf != nsnull) {
     331               0 :       pf->SetPageNumInfo(pageNum, pageTot);
     332                 :     }
     333               0 :     pageNum++;
     334                 :   }
     335                 : 
     336                 :   // Create current Date/Time String
     337               0 :   if (!mDateFormatter)
     338               0 :     mDateFormatter = do_CreateInstance(NS_DATETIMEFORMAT_CONTRACTID);
     339                 : 
     340               0 :   NS_ENSURE_TRUE(mDateFormatter, NS_ERROR_FAILURE);
     341                 : 
     342               0 :   nsAutoString formattedDateString;
     343                 :   time_t ltime;
     344               0 :   time( &ltime );
     345               0 :   if (NS_SUCCEEDED(mDateFormatter->FormatTime(nsnull /* nsILocale* locale */,
     346                 :                                               kDateFormatShort,
     347                 :                                               kTimeFormatNoSeconds,
     348                 :                                               ltime,
     349                 :                                               formattedDateString))) {
     350               0 :     PRUnichar * uStr = ToNewUnicode(formattedDateString);
     351               0 :     SetDateTimeStr(uStr); // memory will be freed
     352                 :   }
     353                 : 
     354                 :   // Return our desired size
     355                 :   // Adjust the reflow size by PrintPreviewScale so the scrollbars end up the
     356                 :   // correct size
     357               0 :   SetDesiredSize(aDesiredSize, aReflowState, maxXMost, y);
     358                 : 
     359               0 :   aDesiredSize.SetOverflowAreasToDesiredBounds();
     360               0 :   FinishAndStoreOverflow(&aDesiredSize);
     361                 : 
     362                 :   // cache the size so we can set the desired size 
     363                 :   // for the other reflows that happen
     364               0 :   mSize.width  = maxXMost;
     365               0 :   mSize.height = y;
     366                 : 
     367               0 :   NS_FRAME_TRACE_REFLOW_OUT("nsSimplePageSequeceFrame::Reflow", aStatus);
     368               0 :   NS_FRAME_SET_TRUNCATION(aStatus, aReflowState, aDesiredSize);
     369               0 :   return NS_OK;
     370                 : }
     371                 : 
     372                 : //----------------------------------------------------------------------
     373                 : 
     374                 : #ifdef DEBUG
     375                 : NS_IMETHODIMP
     376               0 : nsSimplePageSequenceFrame::GetFrameName(nsAString& aResult) const
     377                 : {
     378               0 :   return MakeFrameName(NS_LITERAL_STRING("SimplePageSequence"), aResult);
     379                 : }
     380                 : #endif
     381                 : 
     382                 : //====================================================================
     383                 : //== Asynch Printing
     384                 : //====================================================================
     385                 : NS_IMETHODIMP
     386               0 : nsSimplePageSequenceFrame::GetCurrentPageNum(PRInt32* aPageNum)
     387                 : {
     388               0 :   NS_ENSURE_ARG_POINTER(aPageNum);
     389                 : 
     390               0 :   *aPageNum = mPageNum;
     391               0 :   return NS_OK;
     392                 : }
     393                 : 
     394                 : NS_IMETHODIMP
     395               0 : nsSimplePageSequenceFrame::GetNumPages(PRInt32* aNumPages)
     396                 : {
     397               0 :   NS_ENSURE_ARG_POINTER(aNumPages);
     398                 : 
     399               0 :   *aNumPages = mTotalPages;
     400               0 :   return NS_OK;
     401                 : }
     402                 : 
     403                 : NS_IMETHODIMP
     404               0 : nsSimplePageSequenceFrame::IsDoingPrintRange(bool* aDoing)
     405                 : {
     406               0 :   NS_ENSURE_ARG_POINTER(aDoing);
     407                 : 
     408               0 :   *aDoing = mDoingPageRange;
     409               0 :   return NS_OK;
     410                 : }
     411                 : 
     412                 : NS_IMETHODIMP
     413               0 : nsSimplePageSequenceFrame::GetPrintRange(PRInt32* aFromPage, PRInt32* aToPage)
     414                 : {
     415               0 :   NS_ENSURE_ARG_POINTER(aFromPage);
     416               0 :   NS_ENSURE_ARG_POINTER(aToPage);
     417                 : 
     418               0 :   *aFromPage = mFromPageNum;
     419               0 :   *aToPage   = mToPageNum;
     420               0 :   return NS_OK;
     421                 : }
     422                 : 
     423                 : // Helper Function
     424                 : void 
     425               0 : nsSimplePageSequenceFrame::SetPageNumberFormat(const char* aPropName, const char* aDefPropVal, bool aPageNumOnly)
     426                 : {
     427                 :   // Doing this here so we only have to go get these formats once
     428               0 :   nsXPIDLString pageNumberFormat;
     429                 :   // Now go get the Localized Page Formating String
     430                 :   nsresult rv =
     431                 :     nsContentUtils::GetLocalizedString(nsContentUtils::ePRINTING_PROPERTIES,
     432               0 :                                        aPropName, pageNumberFormat);
     433               0 :   if (NS_FAILED(rv)) { // back stop formatting
     434               0 :     pageNumberFormat.AssignASCII(aDefPropVal);
     435                 :   }
     436                 : 
     437                 :   // Sets the format into a static data member which will own the memory and free it
     438               0 :   PRUnichar* uStr = ToNewUnicode(pageNumberFormat);
     439               0 :   if (uStr != nsnull) {
     440               0 :     SetPageNumberFormat(uStr, aPageNumOnly); // nsPageFrame will own the memory
     441                 :   }
     442                 : 
     443               0 : }
     444                 : 
     445                 : NS_IMETHODIMP
     446               0 : nsSimplePageSequenceFrame::StartPrint(nsPresContext*   aPresContext,
     447                 :                                       nsIPrintSettings* aPrintSettings,
     448                 :                                       PRUnichar*        aDocTitle,
     449                 :                                       PRUnichar*        aDocURL)
     450                 : {
     451               0 :   NS_ENSURE_ARG_POINTER(aPresContext);
     452               0 :   NS_ENSURE_ARG_POINTER(aPrintSettings);
     453                 : 
     454               0 :   if (!mPageData->mPrintSettings) {
     455               0 :     mPageData->mPrintSettings = aPrintSettings;
     456                 :   }
     457                 : 
     458                 :   // Only set them if they are not null
     459               0 :   if (aDocTitle) mPageData->mDocTitle = aDocTitle;
     460               0 :   if (aDocURL) mPageData->mDocURL   = aDocURL;
     461                 : 
     462               0 :   aPrintSettings->GetStartPageRange(&mFromPageNum);
     463               0 :   aPrintSettings->GetEndPageRange(&mToPageNum);
     464               0 :   aPrintSettings->GetPageRanges(mPageRanges);
     465                 : 
     466                 :   mDoingPageRange = nsIPrintSettings::kRangeSpecifiedPageRange == mPrintRangeType ||
     467               0 :                     nsIPrintSettings::kRangeSelection == mPrintRangeType;
     468                 : 
     469                 :   // If printing a range of pages make sure at least the starting page
     470                 :   // number is valid
     471               0 :   PRInt32 totalPages = mFrames.GetLength();
     472                 : 
     473               0 :   if (mDoingPageRange) {
     474               0 :     if (mFromPageNum > totalPages) {
     475               0 :       return NS_ERROR_INVALID_ARG;
     476                 :     }
     477                 :   }
     478                 : 
     479                 :   // Begin printing of the document
     480               0 :   nsresult rv = NS_OK;
     481                 : 
     482                 :   // Determine if we are rendering only the selection
     483               0 :   aPresContext->SetIsRenderingOnlySelection(nsIPrintSettings::kRangeSelection == mPrintRangeType);
     484                 : 
     485                 : 
     486               0 :   if (mDoingPageRange) {
     487                 :     // XXX because of the hack for making the selection all print on one page
     488                 :     // we must make sure that the page is sized correctly before printing.
     489               0 :     nscoord height = aPresContext->GetPageSize().height;
     490                 : 
     491               0 :     PRInt32 pageNum = 1;
     492               0 :     nscoord y = 0;//mMargin.top;
     493                 : 
     494               0 :     for (nsIFrame* page = mFrames.FirstChild(); page;
     495                 :          page = page->GetNextSibling()) {
     496               0 :       if (pageNum >= mFromPageNum && pageNum <= mToPageNum) {
     497               0 :         nsRect rect = page->GetRect();
     498               0 :         rect.y = y;
     499               0 :         rect.height = height;
     500               0 :         page->SetRect(rect);
     501               0 :         y += rect.height + mMargin.top + mMargin.bottom;
     502                 :       }
     503               0 :       pageNum++;
     504                 :     }
     505                 : 
     506                 :     // adjust total number of pages
     507               0 :     if (nsIPrintSettings::kRangeSelection != mPrintRangeType) {
     508               0 :       totalPages = pageNum - 1;
     509                 :     }
     510                 :   }
     511                 : 
     512               0 :   mPageNum          = 1;
     513               0 :   mCurrentPageFrame = mFrames.FirstChild();
     514                 : 
     515               0 :   if (mTotalPages == -1) {
     516               0 :     mTotalPages = totalPages;
     517                 :   }
     518                 : 
     519               0 :   return rv;
     520                 : }
     521                 : 
     522                 : NS_IMETHODIMP
     523               0 : nsSimplePageSequenceFrame::PrintNextPage()
     524                 : {
     525                 :   // Print each specified page
     526                 :   // pageNum keeps track of the current page and what pages are printing
     527                 :   //
     528                 :   // printedPageNum keeps track of the current page number to be printed
     529                 :   // Note: When print al the pages or a page range the printed page shows the
     530                 :   // actual page number, when printing selection it prints the page number starting
     531                 :   // with the first page of the selection. For example if the user has a 
     532                 :   // selection that starts on page 2 and ends on page 3, the page numbers when
     533                 :   // print are 1 and then two (which is different than printing a page range, where
     534                 :   // the page numbers would have been 2 and then 3)
     535                 : 
     536               0 :   if (mCurrentPageFrame == nsnull) {
     537               0 :     return NS_ERROR_FAILURE;
     538                 :   }
     539                 : 
     540                 :   bool printEvenPages, printOddPages;
     541               0 :   mPageData->mPrintSettings->GetPrintOptions(nsIPrintSettings::kPrintEvenPages, &printEvenPages);
     542               0 :   mPageData->mPrintSettings->GetPrintOptions(nsIPrintSettings::kPrintOddPages, &printOddPages);
     543                 : 
     544                 :   // Begin printing of the document
     545               0 :   nsDeviceContext *dc = PresContext()->DeviceContext();
     546                 : 
     547               0 :   nsresult rv = NS_OK;
     548                 : 
     549                 :   // See whether we should print this page
     550               0 :   mPrintThisPage = true;
     551                 : 
     552                 :   // If printing a range of pages check whether the page number is in the
     553                 :   // range of pages to print
     554               0 :   if (mDoingPageRange) {
     555               0 :     if (mPageNum < mFromPageNum) {
     556               0 :       mPrintThisPage = false;
     557               0 :     } else if (mPageNum > mToPageNum) {
     558               0 :       mPageNum++;
     559               0 :       mCurrentPageFrame = nsnull;
     560               0 :       return NS_OK;
     561                 :     } else {
     562               0 :       PRInt32 length = mPageRanges.Length();
     563                 :     
     564                 :       // Page ranges are pairs (start, end)
     565               0 :       if (length && (length % 2 == 0)) {
     566               0 :         mPrintThisPage = false;
     567                 :       
     568                 :         PRInt32 i;
     569               0 :         for (i = 0; i < length; i += 2) {          
     570               0 :           if (mPageRanges[i] <= mPageNum && mPageNum <= mPageRanges[i+1]) {
     571               0 :             mPrintThisPage = true;
     572               0 :             break;
     573                 :           }
     574                 :         }
     575                 :       }
     576                 :     }
     577                 :   }
     578                 : 
     579                 :   // Check for printing of odd and even pages
     580               0 :   if (mPageNum & 0x1) {
     581               0 :     if (!printOddPages) {
     582               0 :       mPrintThisPage = false;  // don't print odd numbered page
     583                 :     }
     584                 :   } else {
     585               0 :     if (!printEvenPages) {
     586               0 :       mPrintThisPage = false;  // don't print even numbered page
     587                 :     }
     588                 :   }
     589                 :   
     590               0 :   if (nsIPrintSettings::kRangeSelection == mPrintRangeType) {
     591               0 :     mPrintThisPage = true;
     592                 :   }
     593                 : 
     594               0 :   if (mPrintThisPage) {
     595                 :     // XXX This is temporary fix for printing more than one page of a selection
     596                 :     // This does a poor man's "dump" pagination (see Bug 89353)
     597                 :     // It has laid out as one long page and now we are just moving or view up/down 
     598                 :     // one page at a time and printing the contents of what is exposed by the rect.
     599                 :     // currently this does not work for IFrames
     600                 :     // I will soon improve this to work with IFrames 
     601               0 :     bool    continuePrinting = true;
     602                 :     nscoord width, height;
     603               0 :     width = PresContext()->GetPageSize().width;
     604               0 :     height = PresContext()->GetPageSize().height;
     605               0 :     height -= mMargin.top + mMargin.bottom;
     606               0 :     width  -= mMargin.left + mMargin.right;
     607               0 :     nscoord selectionY = height;
     608               0 :     nsIFrame* conFrame = mCurrentPageFrame->GetFirstPrincipalChild();
     609               0 :     if (mSelectionHeight >= 0) {
     610               0 :       conFrame->SetPosition(conFrame->GetPosition() + nsPoint(0, -mYSelOffset));
     611               0 :       nsContainerFrame::PositionChildViews(conFrame);
     612                 :     }
     613                 : 
     614                 :     // cast the frame to be a page frame
     615               0 :     nsPageFrame * pf = static_cast<nsPageFrame*>(mCurrentPageFrame);
     616               0 :     pf->SetPageNumInfo(mPageNum, mTotalPages);
     617               0 :     pf->SetSharedPageData(mPageData);
     618                 : 
     619               0 :     PRInt32 printedPageNum = 1;
     620               0 :     while (continuePrinting) {
     621               0 :       if (PresContext()->IsRootPaginatedDocument()) {
     622               0 :         PR_PL(("\n"));
     623               0 :         PR_PL(("***************** BeginPage *****************\n"));
     624               0 :         rv = dc->BeginPage();
     625               0 :         NS_ENSURE_SUCCESS(rv, rv);
     626                 :       }
     627                 : 
     628               0 :       PR_PL(("SeqFr::PrintNextPage -> %p PageNo: %d", pf, mPageNum));
     629                 : 
     630               0 :       nsRefPtr<nsRenderingContext> renderingContext;
     631               0 :       dc->CreateRenderingContext(*getter_AddRefs(renderingContext));
     632               0 :       NS_ENSURE_TRUE(renderingContext, NS_ERROR_OUT_OF_MEMORY);
     633                 : 
     634                 :       nsRect drawingRect(nsPoint(0, 0),
     635               0 :                          mCurrentPageFrame->GetSize());
     636               0 :       nsRegion drawingRegion(drawingRect);
     637                 :       nsLayoutUtils::PaintFrame(renderingContext, mCurrentPageFrame,
     638                 :                                 drawingRegion, NS_RGBA(0,0,0,0),
     639               0 :                                 nsLayoutUtils::PAINT_SYNC_DECODE_IMAGES);
     640                 : 
     641               0 :       if (mSelectionHeight >= 0 && selectionY < mSelectionHeight) {
     642               0 :         selectionY += height;
     643               0 :         printedPageNum++;
     644               0 :         pf->SetPageNumInfo(printedPageNum, mTotalPages);
     645               0 :         conFrame->SetPosition(conFrame->GetPosition() + nsPoint(0, -height));
     646               0 :         nsContainerFrame::PositionChildViews(conFrame);
     647                 : 
     648               0 :         PR_PL(("***************** End Page (PrintNextPage) *****************\n"));
     649               0 :         rv = dc->EndPage();
     650               0 :         NS_ENSURE_SUCCESS(rv, rv);
     651                 :       } else {
     652               0 :         continuePrinting = false;
     653                 :       }
     654                 :     }
     655                 :   }
     656               0 :   return rv;
     657                 : }
     658                 : 
     659                 : NS_IMETHODIMP
     660               0 : nsSimplePageSequenceFrame::DoPageEnd()
     661                 : {
     662               0 :   nsresult rv = NS_OK;
     663               0 :   if (PresContext()->IsRootPaginatedDocument() && mPrintThisPage) {
     664               0 :     PR_PL(("***************** End Page (DoPageEnd) *****************\n"));
     665               0 :     rv = PresContext()->DeviceContext()->EndPage();
     666               0 :     NS_ENSURE_SUCCESS(rv, rv);
     667                 :   }
     668                 : 
     669               0 :   mPageNum++;
     670                 : 
     671               0 :   if (mCurrentPageFrame) {
     672               0 :     mCurrentPageFrame = mCurrentPageFrame->GetNextSibling();
     673                 :   }
     674                 :   
     675               0 :   return rv;
     676                 : }
     677                 : 
     678               0 : static void PaintPageSequence(nsIFrame* aFrame, nsRenderingContext* aCtx,
     679                 :                              const nsRect& aDirtyRect, nsPoint aPt)
     680                 : {
     681               0 :   static_cast<nsSimplePageSequenceFrame*>(aFrame)->PaintPageSequence(*aCtx, aDirtyRect, aPt);
     682               0 : }
     683                 : 
     684                 : //------------------------------------------------------------------------------
     685                 : void
     686               0 : nsSimplePageSequenceFrame::PaintPageSequence(nsRenderingContext& aRenderingContext,
     687                 :                                              const nsRect&        aDirtyRect,
     688                 :                                              nsPoint              aPt) {
     689               0 :   nsRect rect = aDirtyRect;
     690               0 :   float scale = PresContext()->GetPrintPreviewScale();
     691               0 :   aRenderingContext.PushState();
     692               0 :   nsPoint framePos = aPt;
     693               0 :   aRenderingContext.Translate(framePos);
     694               0 :   rect -= framePos;
     695               0 :   aRenderingContext.Scale(scale, scale);
     696               0 :   rect.ScaleRoundOut(1.0f / scale);
     697                 : 
     698                 :   // Now the rect and the rendering coordinates are are relative to this frame.
     699                 :   // Loop over the pages and paint them.
     700               0 :   nsIFrame* child = GetFirstPrincipalChild();
     701               0 :   while (child) {
     702               0 :     nsPoint pt = child->GetPosition();
     703                 :     // The rendering context has to be translated before each call to PaintFrame
     704               0 :     aRenderingContext.PushState();
     705               0 :     aRenderingContext.Translate(pt);
     706                 :     nsLayoutUtils::PaintFrame(&aRenderingContext, child,
     707               0 :                               nsRegion(rect - pt), NS_RGBA(0,0,0,0),
     708               0 :                               nsLayoutUtils::PAINT_SYNC_DECODE_IMAGES);
     709               0 :     aRenderingContext.PopState();
     710               0 :     child = child->GetNextSibling();
     711                 :   }
     712                 : 
     713               0 :   aRenderingContext.PopState();
     714               0 : }
     715                 : 
     716                 : NS_IMETHODIMP
     717               0 : nsSimplePageSequenceFrame::BuildDisplayList(nsDisplayListBuilder*   aBuilder,
     718                 :                                             const nsRect&           aDirtyRect,
     719                 :                                             const nsDisplayListSet& aLists)
     720                 : {
     721               0 :   nsresult rv = DisplayBorderBackgroundOutline(aBuilder, aLists);
     722               0 :   NS_ENSURE_SUCCESS(rv, rv);
     723                 : 
     724                 :   rv = aLists.Content()->AppendNewToTop(new (aBuilder)
     725                 :         nsDisplayGeneric(aBuilder, this, ::PaintPageSequence, "PageSequence",
     726               0 :                          nsDisplayItem::TYPE_PAGE_SEQUENCE));
     727               0 :   NS_ENSURE_SUCCESS(rv, rv);
     728                 : 
     729               0 :   return NS_OK;
     730                 : }
     731                 : 
     732                 : nsIAtom*
     733               0 : nsSimplePageSequenceFrame::GetType() const
     734                 : {
     735               0 :   return nsGkAtoms::sequenceFrame; 
     736                 : }
     737                 : 
     738                 : //------------------------------------------------------------------------------
     739                 : void
     740               0 : nsSimplePageSequenceFrame::SetPageNumberFormat(PRUnichar * aFormatStr, bool aForPageNumOnly)
     741                 : { 
     742               0 :   NS_ASSERTION(aFormatStr != nsnull, "Format string cannot be null!");
     743               0 :   NS_ASSERTION(mPageData != nsnull, "mPageData string cannot be null!");
     744                 : 
     745               0 :   if (aForPageNumOnly) {
     746               0 :     if (mPageData->mPageNumFormat != nsnull) {
     747               0 :       nsMemory::Free(mPageData->mPageNumFormat);
     748                 :     }
     749               0 :     mPageData->mPageNumFormat = aFormatStr;
     750                 :   } else {
     751               0 :     if (mPageData->mPageNumAndTotalsFormat != nsnull) {
     752               0 :       nsMemory::Free(mPageData->mPageNumAndTotalsFormat);
     753                 :     }
     754               0 :     mPageData->mPageNumAndTotalsFormat = aFormatStr;
     755                 :   }
     756               0 : }
     757                 : 
     758                 : //------------------------------------------------------------------------------
     759                 : void
     760               0 : nsSimplePageSequenceFrame::SetDateTimeStr(PRUnichar * aDateTimeStr)
     761                 : { 
     762               0 :   NS_ASSERTION(aDateTimeStr != nsnull, "DateTime string cannot be null!");
     763               0 :   NS_ASSERTION(mPageData != nsnull, "mPageData string cannot be null!");
     764                 : 
     765               0 :   if (mPageData->mDateTimeStr != nsnull) {
     766               0 :     nsMemory::Free(mPageData->mDateTimeStr);
     767                 :   }
     768               0 :   mPageData->mDateTimeStr = aDateTimeStr;
     769               0 : }
     770                 : 
     771                 : //------------------------------------------------------------------------------
     772                 : // For Shrink To Fit
     773                 : //
     774                 : // Return the percentage that the page needs to shrink to 
     775                 : //
     776                 : NS_IMETHODIMP
     777               0 : nsSimplePageSequenceFrame::GetSTFPercent(float& aSTFPercent)
     778                 : {
     779               0 :   NS_ENSURE_TRUE(mPageData, NS_ERROR_UNEXPECTED);
     780               0 :   aSTFPercent = 1.0f;
     781               0 :   if (mPageData && (mPageData->mPageContentXMost > mPageData->mPageContentSize)) {
     782               0 :     aSTFPercent = float(mPageData->mPageContentSize) / float(mPageData->mPageContentXMost);
     783                 :   }
     784               0 :   return NS_OK;
     785            4392 : }

Generated by: LCOV version 1.7