forked from mirrors/gecko-dev
		
	Actually, there's not so much we can improve right now, in the sense that: * We need the ::-moz-page-content pseudo-element to be able to set `display` on the page, since that's a style rule rather than a @page rule. We could get away without it. * Keeping the current code-path (slightly cleaned up) is less code, for now at least. We can have a separate code-path or what not that actually performs the @page rule selector-matching and what not if needed when we get to named pages or other page selectors. Selectors like :first should be pretty trivial to implement, actually. We make some paged mode anon boxes non-inheriting anon boxes. This allows us to share the styles and is generally nicer. They don't need to inherit from anywhere. We could remove the origin handling and don't look at UA rules or what not, but it seems pretty harmless to do that. We also fix the name of the pseudo-elements to match the capitalization. Differential Revision: https://phabricator.services.mozilla.com/D104772
		
			
				
	
	
		
			211 lines
		
	
	
	
		
			7.8 KiB
		
	
	
	
		
			C++
		
	
	
	
	
	
			
		
		
	
	
			211 lines
		
	
	
	
		
			7.8 KiB
		
	
	
	
		
			C++
		
	
	
	
	
	
/* -*- 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;
 | 
						|
 | 
						|
  // The mPagesPerSheet{...} members are only used if
 | 
						|
  // PagesPerSheetInfo()->mNumPages > 1.  They're initialized with reasonable
 | 
						|
  // defaults here (which correspond to what we do for the regular
 | 
						|
  // 1-page-per-sheet scenario, though we don't actually use these members in
 | 
						|
  // that case).  If we're in >1 pages-per-sheet scenario, then these members
 | 
						|
  // will be assigned "real" values during the reflow of the first
 | 
						|
  // PrintedSheetFrame.
 | 
						|
  float mPagesPerSheetScale = 1.0f;
 | 
						|
  // Number of "columns" in our pages-per-sheet layout. For example: if we're
 | 
						|
  // printing with 6 pages-per-sheet, then this could be either 3 or 2,
 | 
						|
  // depending on whether we're printing portrait-oriented pages onto a
 | 
						|
  // landscape-oriented sheet (3 cols) vs. if we're printing landscape-oriented
 | 
						|
  // pages onto a portrait-oriented sheet (2 cols).
 | 
						|
  uint32_t mPagesPerSheetNumCols = 1;
 | 
						|
  nsPoint mPagesPerSheetGridOrigin;
 | 
						|
 | 
						|
  // 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();
 | 
						|
 | 
						|
  // We must allow Print Preview UI to have a background, no matter what the
 | 
						|
  // user's settings
 | 
						|
  bool HonorPrintBackgroundSettings() const override { return false; }
 | 
						|
 | 
						|
  bool HasTransformGetter() const override { return true; }
 | 
						|
 | 
						|
#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___ */
 |