LCOV - app.info - layout/generic/nsSimplePageSequence.cpp

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