diff options
Diffstat (limited to '')
-rw-r--r-- | layout/generic/nsPageSequenceFrame.h | 191 |
1 files changed, 191 insertions, 0 deletions
diff --git a/layout/generic/nsPageSequenceFrame.h b/layout/generic/nsPageSequenceFrame.h new file mode 100644 index 0000000000..06293192b0 --- /dev/null +++ b/layout/generic/nsPageSequenceFrame.h @@ -0,0 +1,191 @@ +/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* vim: set ts=8 sts=2 et sw=2 tw=80: */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ +#ifndef nsPageSequenceFrame_h___ +#define nsPageSequenceFrame_h___ + +#include "mozilla/Attributes.h" +#include "mozilla/UniquePtr.h" +#include "nsContainerFrame.h" +#include "nsIPrintSettings.h" + +namespace mozilla { + +class PresShell; +class PrintedSheetFrame; + +namespace dom { + +class HTMLCanvasElement; + +} // namespace dom +} // namespace mozilla + +//----------------------------------------------- +// This class is used to manage some static data about the layout +// characteristics of our various "Pages Per Sheet" options. +struct nsPagesPerSheetInfo { + static const nsPagesPerSheetInfo& LookupInfo(int32_t aPPS); + + uint16_t mNumPages; + + // This is the larger of the row-count vs. column-count for this layout + // (if they aren't the same). We'll aim to stack this number of pages + // in the sheet's longer axis. + uint16_t mLargerNumTracks; +}; + +/** + * This class maintains various shared data that is used by printing-related + * frames. The nsPageSequenceFrame strongly owns an instance of this class, + * which lives for as long as the nsPageSequenceFrame does. + */ +class nsSharedPageData { + public: + nsString mDateTimeStr; + nsString mPageNumFormat; + nsString mPageNumAndTotalsFormat; + nsString mDocTitle; + nsString mDocURL; + nsFont mHeadFootFont; + + // Total number of pages (populated by PrintedSheetFrame when it determines + // that it's reflowed the final page): + int32_t mRawNumPages = 0; + + // If there's more than one page-range, then its components are stored here + // as pairs of (start,end). They're stored in the order provided (not + // necessarily in ascending order). + nsTArray<int32_t> mPageRanges; + + // Margin for headers and footers; it defaults to 4/100 of an inch on UNIX + // and 0 elsewhere; I think it has to do with some inconsistency in page size + // computations + nsMargin mEdgePaperMargin; + + nsCOMPtr<nsIPrintSettings> mPrintSettings; + + // The scaling ratio we need to apply to make all pages fit horizontally. It's + // the minimum "ComputedWidth / OverflowWidth" ratio of all page content + // frames that overflowed. It's 1.0 if none overflowed horizontally. + float mShrinkToFitRatio = 1.0f; + + // Lazy getter, to look up our pages-per-sheet info based on mPrintSettings + // (if it's available). The result is stored in our mPagesPerSheetInfo + // member-var to speed up subsequent lookups. + // This API is infallible; in failure cases, it just returns the info struct + // that corresponds to 1 page per sheet. + const nsPagesPerSheetInfo* PagesPerSheetInfo(); + + private: + const nsPagesPerSheetInfo* mPagesPerSheetInfo = nullptr; +}; + +// Page sequence frame class. Manages a series of pages, in paginated mode. +// (Strictly speaking, this frame's direct children are PrintedSheetFrame +// instances, and each of those will usually contain one nsPageFrame, depending +// on the "pages-per-sheet" setting and whether the print operation is +// restricted to a custom page range.) +class nsPageSequenceFrame final : public nsContainerFrame { + using LogicalSize = mozilla::LogicalSize; + + public: + friend nsPageSequenceFrame* NS_NewPageSequenceFrame( + mozilla::PresShell* aPresShell, ComputedStyle* aStyle); + + NS_DECL_QUERYFRAME + NS_DECL_FRAMEARENA_HELPERS(nsPageSequenceFrame) + + // nsIFrame + void Reflow(nsPresContext* aPresContext, ReflowOutput& aReflowOutput, + const ReflowInput& aReflowInput, + nsReflowStatus& aStatus) override; + + void BuildDisplayList(nsDisplayListBuilder* aBuilder, + const nsDisplayListSet& aLists) override; + + // For Shrink To Fit + float GetSTFPercent() const { return mPageData->mShrinkToFitRatio; } + + // Gets the final print preview scale that we're applying to the previewed + // sheets of paper. + float GetPrintPreviewScale() const; + + // Async Printing + nsresult StartPrint(nsPresContext* aPresContext, + nsIPrintSettings* aPrintSettings, + const nsAString& aDocTitle, const nsAString& aDocURL); + nsresult PrePrintNextSheet(nsITimerCallback* aCallback, bool* aDone); + nsresult PrintNextSheet(); + void ResetPrintCanvasList(); + + uint32_t GetCurrentSheetIdx() const { return mCurrentSheetIdx; } + + int32_t GetRawNumPages() const { return mPageData->mRawNumPages; } + + uint32_t GetPagesInFirstSheet() const; + + nsresult DoPageEnd(); + + ComputeTransformFunction GetTransformGetter() const override; + +#ifdef DEBUG_FRAME_DUMP + nsresult GetFrameName(nsAString& aResult) const override; +#endif + + protected: + nsPageSequenceFrame(ComputedStyle*, nsPresContext*); + virtual ~nsPageSequenceFrame(); + + void SetPageNumberFormat(const char* aPropName, const char* aDefPropVal, + bool aPageNumOnly); + + // SharedPageData Helper methods + void SetDateTimeStr(const nsAString& aDateTimeStr); + void SetPageNumberFormat(const nsAString& aFormatStr, bool aForPageNumOnly); + + // Print scaling is applied in this function. + void PopulateReflowOutput(ReflowOutput&, const ReflowInput&); + + // Helper function to compute the offset needed to center a child + // page-frame's margin-box inside our content-box. + nscoord ComputeCenteringMargin(nscoord aContainerContentBoxWidth, + nscoord aChildPaddingBoxWidth, + const nsMargin& aChildPhysicalMargin); + + mozilla::PrintedSheetFrame* GetCurrentSheetFrame(); + + nsSize mSize; + + // These next two LogicalSize members are used when we're in print-preview to + // ensure that each previewed sheet will fit in the print-preview scrollport: + // ------- + + // Each component of this LogicalSize represents the maximum length of all + // our print-previewed sheets in that axis, plus a little extra for the + // print-preview margin. Note that this LogicalSize doesn't necessarily + // correspond to any one particular sheet's size (especially if our sheets + // have different sizes), since the components are tracked independently such + // that we end up storing the maximum in each dimension. + LogicalSize mMaxSheetSize; + // The size of the scrollport where we're print-previewing sheets. + LogicalSize mScrollportSize; + + // Data shared by all the nsPageFrames: + mozilla::UniquePtr<nsSharedPageData> mPageData; + + // The zero-based index of the PrintedSheetFrame child that is being printed + // (or about-to-be-printed), in an async print operation. + // This is an index into our PrincipalChildList, effectively. + uint32_t mCurrentSheetIdx = 0; + + nsTArray<RefPtr<mozilla::dom::HTMLCanvasElement> > mCurrentCanvasList; + + bool mCalledBeginPage; + + bool mCurrentCanvasListSetup; +}; + +#endif /* nsPageSequenceFrame_h___ */ |