1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144
|
/* -*- 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 https://mozilla.org/MPL/2.0/. */
/* Rendering object for a printed or print-previewed sheet of paper */
#ifndef LAYOUT_GENERIC_PRINTEDSHEETFRAME_H_
#define LAYOUT_GENERIC_PRINTEDSHEETFRAME_H_
#include "mozilla/gfx/Point.h"
#include "nsContainerFrame.h"
#include "nsHTMLParts.h"
class nsSharedPageData;
namespace mozilla {
class PrintedSheetFrame final : public nsContainerFrame {
public:
using IntSize = mozilla::gfx::IntSize;
NS_DECL_QUERYFRAME
NS_DECL_FRAMEARENA_HELPERS(PrintedSheetFrame)
friend PrintedSheetFrame* ::NS_NewPrintedSheetFrame(
mozilla::PresShell* aPresShell, ComputedStyle* aStyle);
void SetSharedPageData(nsSharedPageData* aPD) { mPD = aPD; }
// XXX: this needs a better name, since it also updates style.
// Invokes MoveOverflowToChildList.
// This is intended for use by callers that need to be able to get our first/
// only nsPageFrame from our child list to examine its computed style just
// **prior** to us being reflowed. (If our first nsPageFrame will come from
// our prev-in-flow, we won't otherwise take ownership of it until we are
// reflowed.)
void ClaimPageFrameFromPrevInFlow();
// nsIFrame overrides
void Reflow(nsPresContext* aPresContext, ReflowOutput& aReflowOutput,
const ReflowInput& aReflowInput,
nsReflowStatus& aStatus) override;
void BuildDisplayList(nsDisplayListBuilder* aBuilder,
const nsDisplayListSet& aLists) override;
#ifdef DEBUG_FRAME_DUMP
nsresult GetFrameName(nsAString& aResult) const override;
#endif
uint32_t GetNumPages() const { return mNumPages; }
// These methods provide information about the grid that pages should be
// placed into in the case that there are multiple pages-per-sheet.
uint32_t GetGridNumCols() const { return mGridNumCols; }
nsPoint GetGridOrigin() const { return mGridOrigin; }
nscoord GetGridCellWidth() const { return mGridCellWidth; }
nscoord GetGridCellHeight() const { return mGridCellHeight; }
nsSize ComputeSheetSize(const nsPresContext* aPresContext);
/**
* When we're printing one page-per-sheet and `page-orientation` on our
* single nsPageFrame child should cause the page to rotate, then we want to
* essentially rotate the sheet. We implement that by switching the
* dimensions of this sheet (changing its orientation), sizing the
* nsPageFrame to the original dimensions, and then applying the rotation to
* the nsPageFrame child.
*
* This returns the dimensions that this frame would have without any
* dimension swap we may have done to implement `page-orientation`. If
* there is no rotation caused by `page-orientation`, then the value returned
* and mRect.Size() are identical.
*/
nsSize GetSizeForChildren() const { return mSizeForChildren; }
/**
* This method returns the dimensions of the physical page that the target
* [pseudo-]printer should create. This may be different from our own
* dimensions in the case where CSS `page-orientation` causes us to be
* rotated, but we only support that if the PrintTarget backend supports
* different page sizes/orientations. That's only the case for our Save-to-PDF
* backends (possibly other save-to-file outputs in future).
*
* The dimensions returned are expected to be passed to
* nsDeviceContext::BeginPage, which will pass them on to
* PrintTarget::BeginPage to use as the physical dimensions of the page.
*/
IntSize GetPrintTargetSizeInPoints(
const int32_t aAppUnitsPerPhysicalInch) const;
private:
// Private construtor & destructor, to avoid accidental (non-FrameArena)
// instantiation/deletion:
PrintedSheetFrame(ComputedStyle* aStyle, nsPresContext* aPresContext)
: nsContainerFrame(aStyle, aPresContext, kClassID) {}
~PrintedSheetFrame() = default;
// Helper function to populate some pages-per-sheet metrics in our
// nsSharedPageData.
// XXXjwatt: We should investigate sharing this function for the single
// page-per-sheet case (bug 1835782). The logic for that case
// (nsPageFrame::ComputePageSizeScale) is somewhat different though, since
// that case uses no sheet margins and uses the user/CSS specified margins on
// the page, with any page scaling reverted to keep the margins unchanged.
// We, on the other hand, use the unwriteable margins for the sheet, unscaled,
// and use the user/CSS margins on the pages and allow them to be scaled
// along with any pages-per-sheet scaling. (This behavior makes maximum use
// of the sheet and, by scaling the default on the pages, results in a
// a sensible amount of spacing between pages.)
void ComputePagesPerSheetGridMetrics(const nsSize& aSheetSize);
// See GetSizeForChildren.
nsSize mSizeForChildren;
// Note: this will be set before reflow, and it's strongly owned by our
// nsPageSequenceFrame, which outlives us.
nsSharedPageData* mPD = nullptr;
// The number of visible pages in this sheet.
uint32_t mNumPages = 0;
// 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 mGridNumCols = 1;
// The offset of the start of the multiple pages-per-sheet grid from the
// top-left of the sheet.
nsPoint mGridOrigin;
// The size of each cell on the sheet into which pages are to be placed.
// (The default values are arbitrary.)
nscoord mGridCellWidth = 1;
nscoord mGridCellHeight = 1;
};
} // namespace mozilla
#endif /* LAYOUT_GENERIC_PRINTEDSHEETFRAME_H_ */
|