summaryrefslogtreecommitdiffstats
path: root/layout/generic/nsPageFrame.h
blob: ede3cb96f47d17e653fce8be7467699d587024b9 (plain)
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
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
/* -*- 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 nsPageFrame_h___
#define nsPageFrame_h___

#include "mozilla/Attributes.h"
#include "nsContainerFrame.h"
#include "nsLeafFrame.h"

class nsFontMetrics;
class nsPageContentFrame;
class nsSharedPageData;

namespace mozilla {
class PresShell;
}  // namespace mozilla

// Page frame class. Represents an individual page, in paginated mode.
class nsPageFrame final : public nsContainerFrame {
 public:
  NS_DECL_QUERYFRAME
  NS_DECL_FRAMEARENA_HELPERS(nsPageFrame)

  friend nsPageFrame* NS_NewPageFrame(mozilla::PresShell* aPresShell,
                                      ComputedStyle* aStyle);

  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

  //////////////////
  // For Printing
  //////////////////

  // Determine this page's page-number, based on its previous continuation
  // (whose page number is presumed to already be known).
  void DeterminePageNum();
  int32_t GetPageNum() const { return mPageNum; }

  void SetSharedPageData(nsSharedPageData* aPD);
  nsSharedPageData* GetSharedPageData() const { return mPD; }

  void PaintHeaderFooter(gfxContext& aRenderingContext, nsPoint aPt,
                         bool aSubpixelAA);

  const nsMargin& GetUsedPageContentMargin() const {
    return mPageContentMargin;
  }

  uint32_t IndexOnSheet() const { return mIndexOnSheet; }
  void SetIndexOnSheet(uint32_t aIndexOnSheet) {
    mIndexOnSheet = aIndexOnSheet;
  }

  ComputeTransformFunction GetTransformGetter() const override;

  nsPageContentFrame* PageContentFrame() const;

  nsSize ComputePageSize() const;

  // Computes the scaling factor to fit the page to the sheet in the single
  // page-per-sheet case. (The multiple pages-per-sheet case is currently
  // different - see the comment for
  // PrintedSheetFrame::ComputePagesPerSheetGridMetrics and code in
  // ComputePagesPerSheetAndPageSizeTransform.) The page and sheet dimensions
  // may be different due to a CSS page-size that gives the page a size that is
  // too large to fit on the sheet that we are printing to.
  float ComputeSinglePPSPageSizeScale(const nsSize aContentPageSize) const;

  // Returns the rotation from CSS `page-orientation` property, if set, and if
  // it applies. Note: the single page-per-sheet case is special since in that
  // case we effectively rotate the sheet (as opposed to rotating pages in
  // their pages-per-sheet grid cell). In this case we return zero if the
  // output medium does not support changing the dimensions (orientation) of
  // the sheet (i.e. only print preview and save-to-PDF are supported).
  double GetPageOrientationRotation(nsSharedPageData* aPD) const;

 protected:
  explicit nsPageFrame(ComputedStyle* aStyle, nsPresContext* aPresContext);
  virtual ~nsPageFrame();

  typedef enum { eHeader, eFooter } nsHeaderFooterEnum;

  nscoord GetXPosition(gfxContext& aRenderingContext,
                       nsFontMetrics& aFontMetrics, const nsRect& aRect,
                       int32_t aJust, const nsString& aStr);

  nsReflowStatus ReflowPageContent(nsPresContext*,
                                   const ReflowInput& aPageReflowInput);

  void DrawHeaderFooter(gfxContext& aRenderingContext,
                        nsFontMetrics& aFontMetrics,
                        nsHeaderFooterEnum aHeaderFooter, int32_t aJust,
                        const nsString& sStr, const nsRect& aRect,
                        nscoord aHeight, nscoord aAscent, nscoord aWidth);

  void DrawHeaderFooter(gfxContext& aRenderingContext,
                        nsFontMetrics& aFontMetrics,
                        nsHeaderFooterEnum aHeaderFooter,
                        const nsString& aStrLeft, const nsString& aStrRight,
                        const nsString& aStrCenter, const nsRect& aRect,
                        nscoord aAscent, nscoord aHeight);

  void ProcessSpecialCodes(const nsString& aStr, nsString& aNewStr);

  static constexpr int32_t kPageNumUnset = -1;
  // 1-based page-num
  int32_t mPageNum = kPageNumUnset;

  // 0-based index on the sheet that we belong to. Unused/meaningless if this
  // page has frame state bit NS_PAGE_SKIPPED_BY_CUSTOM_RANGE.
  uint32_t mIndexOnSheet = 0;

  // Note: this will be set before reflow, and it's strongly owned by our
  // nsPageSequenceFrame, which outlives us.
  nsSharedPageData* mPD = nullptr;

  // Computed page content margins.
  //
  // This is the amount of space from the edges of the content to the edges,
  // measured in the content coordinate space. This is as opposed to the
  // coordinate space of the physical paper. This might be different due to
  // a CSS page-size that is too large to fit on the paper, causing content to
  // be scaled to fit.
  //
  // These margins take into account:
  //    * CSS-defined margins (content units)
  //    * User-supplied margins (physical units)
  //    * Unwriteable-supplied margins (physical units)
  //
  // When computing these margins, all physical units have the inverse of the
  // scaling factor caused by CSS page-size downscaling applied. This ensures
  // that even if the content will be downscaled, it will respect the (now
  // upscaled) physical unwriteable margins required by the printer.
  // For user-supplied margins, it isn't immediately obvious to the user what
  // the intended page-size of the document is, so we consider these margins to
  // be in the physical space of the paper.
  nsMargin mPageContentMargin;
};

class nsPageBreakFrame final : public nsLeafFrame {
  NS_DECL_FRAMEARENA_HELPERS(nsPageBreakFrame)

  explicit nsPageBreakFrame(ComputedStyle* aStyle, nsPresContext* aPresContext);
  ~nsPageBreakFrame();

  void Reflow(nsPresContext* aPresContext, ReflowOutput& aReflowOutput,
              const ReflowInput& aReflowInput,
              nsReflowStatus& aStatus) override;

#ifdef DEBUG_FRAME_DUMP
  nsresult GetFrameName(nsAString& aResult) const override;
#endif

 protected:
  nscoord GetIntrinsicISize() override;
  nscoord GetIntrinsicBSize() override;

  friend nsIFrame* NS_NewPageBreakFrame(mozilla::PresShell* aPresShell,
                                        ComputedStyle* aStyle);
};

#endif /* nsPageFrame_h___ */