nsPageSequenceFrame.h (6919B)
1 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ 2 /* vim: set ts=8 sts=2 et sw=2 tw=80: */ 3 /* This Source Code Form is subject to the terms of the Mozilla Public 4 * License, v. 2.0. If a copy of the MPL was not distributed with this 5 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ 6 #ifndef nsPageSequenceFrame_h___ 7 #define nsPageSequenceFrame_h___ 8 9 #include "mozilla/UniquePtr.h" 10 #include "nsContainerFrame.h" 11 #include "nsIPrintSettings.h" 12 13 namespace mozilla { 14 15 class PresShell; 16 class PrintedSheetFrame; 17 18 namespace dom { 19 20 class HTMLCanvasElement; 21 22 } // namespace dom 23 } // namespace mozilla 24 25 //----------------------------------------------- 26 // This class is used to manage some static data about the layout 27 // characteristics of our various "Pages Per Sheet" options. 28 struct nsPagesPerSheetInfo { 29 static const nsPagesPerSheetInfo& LookupInfo(int32_t aPPS); 30 31 uint16_t mNumPages; 32 33 // This is the larger of the row-count vs. column-count for this layout 34 // (if they aren't the same). We'll aim to stack this number of pages 35 // in the sheet's longer axis. 36 uint16_t mLargerNumTracks; 37 }; 38 39 /** 40 * This class maintains various shared data that is used by printing-related 41 * frames. The nsPageSequenceFrame strongly owns an instance of this class, 42 * which lives for as long as the nsPageSequenceFrame does. 43 */ 44 class nsSharedPageData { 45 public: 46 nsString mDateTimeStr; 47 nsString mPageNumFormat; 48 nsString mPageNumAndTotalsFormat; 49 nsString mDocTitle; 50 nsString mDocURL; 51 nsFont mHeadFootFont; 52 53 // Total number of pages (populated by PrintedSheetFrame when it determines 54 // that it's reflowed the final page): 55 int32_t mRawNumPages = 0; 56 57 // If there's more than one page-range, then its components are stored here 58 // as pairs of (start,end). They're stored in the order provided (not 59 // necessarily in ascending order). 60 nsTArray<int32_t> mPageRanges; 61 62 // Margin for headers and footers; it defaults to 4/100 of an inch on UNIX 63 // and 0 elsewhere; I think it has to do with some inconsistency in page size 64 // computations 65 nsMargin mEdgePaperMargin; 66 67 nsCOMPtr<nsIPrintSettings> mPrintSettings; 68 69 // The scaling ratio we need to apply to make all pages fit horizontally. It's 70 // the minimum "ComputedWidth / OverflowWidth" ratio of all page content 71 // frames that overflowed. It's 1.0 if none overflowed horizontally. 72 float mShrinkToFitRatio = 1.0f; 73 74 // Lazy getter, to look up our pages-per-sheet info based on mPrintSettings 75 // (if it's available). The result is stored in our mPagesPerSheetInfo 76 // member-var to speed up subsequent lookups. 77 // This API is infallible; in failure cases, it just returns the info struct 78 // that corresponds to 1 page per sheet. 79 const nsPagesPerSheetInfo* PagesPerSheetInfo(); 80 81 private: 82 const nsPagesPerSheetInfo* mPagesPerSheetInfo = nullptr; 83 }; 84 85 // Page sequence frame class. Manages a series of pages, in paginated mode. 86 // (Strictly speaking, this frame's direct children are PrintedSheetFrame 87 // instances, and each of those will usually contain one nsPageFrame, depending 88 // on the "pages-per-sheet" setting and whether the print operation is 89 // restricted to a custom page range.) 90 class nsPageSequenceFrame final : public nsContainerFrame { 91 using LogicalSize = mozilla::LogicalSize; 92 93 public: 94 friend nsPageSequenceFrame* NS_NewPageSequenceFrame( 95 mozilla::PresShell* aPresShell, ComputedStyle* aStyle); 96 97 NS_DECL_QUERYFRAME 98 NS_DECL_FRAMEARENA_HELPERS(nsPageSequenceFrame) 99 100 // nsIFrame 101 void Reflow(nsPresContext* aPresContext, ReflowOutput& aReflowOutput, 102 const ReflowInput& aReflowInput, 103 nsReflowStatus& aStatus) override; 104 105 void BuildDisplayList(nsDisplayListBuilder* aBuilder, 106 const nsDisplayListSet& aLists) override; 107 108 // For Shrink To Fit 109 float GetSTFPercent() const { return mPageData->mShrinkToFitRatio; } 110 111 // Gets the final print preview scale that we're applying to the previewed 112 // sheets of paper. 113 float GetPrintPreviewScale() const; 114 115 // Async Printing 116 nsresult StartPrint(nsPresContext* aPresContext, 117 nsIPrintSettings* aPrintSettings, 118 const nsAString& aDocTitle, const nsAString& aDocURL); 119 nsresult PrePrintNextSheet(nsITimerCallback* aCallback, bool* aDone); 120 nsresult PrintNextSheet(); 121 void ResetPrintCanvasList(); 122 123 uint32_t GetCurrentSheetIdx() const { return mCurrentSheetIdx; } 124 125 int32_t GetRawNumPages() const { return mPageData->mRawNumPages; } 126 127 uint32_t GetPagesInFirstSheet() const; 128 129 nsresult DoPageEnd(); 130 131 ComputeTransformFunction GetTransformGetter() const override; 132 133 #ifdef DEBUG_FRAME_DUMP 134 nsresult GetFrameName(nsAString& aResult) const override; 135 #endif 136 137 protected: 138 nsPageSequenceFrame(ComputedStyle*, nsPresContext*); 139 virtual ~nsPageSequenceFrame(); 140 141 void SetPageNumberFormat(const char* aPropName, const char* aDefPropVal, 142 bool aPageNumOnly); 143 144 // SharedPageData Helper methods 145 void SetDateTimeStr(const nsAString& aDateTimeStr); 146 void SetPageNumberFormat(const nsAString& aFormatStr, bool aForPageNumOnly); 147 148 // Print scaling is applied in this function. 149 void PopulateReflowOutput(ReflowOutput&, const ReflowInput&); 150 151 // Helper function to compute the offset needed to center a child 152 // page-frame's margin-box inside our content-box. 153 nscoord ComputeCenteringMargin(nscoord aContainerContentBoxWidth, 154 nscoord aChildPaddingBoxWidth, 155 const nsMargin& aChildPhysicalMargin); 156 157 mozilla::PrintedSheetFrame* GetCurrentSheetFrame(); 158 159 nsSize mSize; 160 161 // These next two LogicalSize members are used when we're in print-preview to 162 // ensure that each previewed sheet will fit in the print-preview scrollport: 163 // ------- 164 165 // Each component of this LogicalSize represents the maximum length of all 166 // our print-previewed sheets in that axis, plus a little extra for the 167 // print-preview margin. Note that this LogicalSize doesn't necessarily 168 // correspond to any one particular sheet's size (especially if our sheets 169 // have different sizes), since the components are tracked independently such 170 // that we end up storing the maximum in each dimension. 171 LogicalSize mMaxSheetSize; 172 // The size of the scrollport where we're print-previewing sheets. 173 LogicalSize mScrollportSize; 174 175 // Data shared by all the nsPageFrames: 176 mozilla::UniquePtr<nsSharedPageData> mPageData; 177 178 // The zero-based index of the PrintedSheetFrame child that is being printed 179 // (or about-to-be-printed), in an async print operation. 180 // This is an index into our PrincipalChildList, effectively. 181 uint32_t mCurrentSheetIdx = 0; 182 183 nsTArray<RefPtr<mozilla::dom::HTMLCanvasElement> > mCurrentCanvasList; 184 185 bool mCalledBeginPage; 186 187 bool mCurrentCanvasListSetup; 188 }; 189 190 #endif /* nsPageSequenceFrame_h___ */