summaryrefslogtreecommitdiffstats
path: root/dom/base/nsViewportInfo.h
blob: 5401e4bd877e63926f1ae8d3c45ca7ffc80cb706 (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
/* 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 nsViewportInfo_h___
#define nsViewportInfo_h___

#include <algorithm>
#include <stdint.h>
#include "mozilla/Attributes.h"
#include "mozilla/StaticPrefs_apz.h"
#include "Units.h"

namespace mozilla::dom {
enum class ViewportFitType : uint8_t {
  Auto,
  Contain,
  Cover,
};
}  // namespace mozilla::dom

/**
 * Default values for the nsViewportInfo class.
 */
static const mozilla::CSSIntSize kViewportMinSize(200, 40);
static const mozilla::CSSIntSize kViewportMaxSize(10000, 10000);

inline mozilla::LayoutDeviceToScreenScale ViewportMinScale() {
  return mozilla::LayoutDeviceToScreenScale(
      std::max(mozilla::StaticPrefs::apz_min_zoom(), 0.1f));
}

inline mozilla::LayoutDeviceToScreenScale ViewportMaxScale() {
  return mozilla::LayoutDeviceToScreenScale(
      std::min(mozilla::StaticPrefs::apz_max_zoom(), 100.0f));
}

/**
 * Information retrieved from the <meta name="viewport"> tag. See
 * Document::GetViewportInfo for more information on this functionality.
 */
class MOZ_STACK_CLASS nsViewportInfo {
 public:
  enum class AutoSizeFlag {
    AutoSize,
    FixedSize,
  };
  enum class AutoScaleFlag {
    AutoScale,
    FixedScale,
  };
  enum class ZoomFlag {
    AllowZoom,
    DisallowZoom,
  };
  enum class ZoomBehaviour {
    Mobile,
    Desktop,  // disallows zooming out past default zoom
  };
  nsViewportInfo(const mozilla::ScreenIntSize& aDisplaySize,
                 const mozilla::CSSToScreenScale& aDefaultZoom,
                 ZoomFlag aZoomFlag, ZoomBehaviour aBehaviour,
                 AutoScaleFlag aAutoScaleFlag = AutoScaleFlag::FixedScale)
      : mDefaultZoom(aDefaultZoom),
        mViewportFit(mozilla::dom::ViewportFitType::Auto),
        mDefaultZoomValid(aAutoScaleFlag != AutoScaleFlag::AutoScale),
        mAutoSize(true),
        mAllowZoom(aZoomFlag == ZoomFlag::AllowZoom) {
    mSize = mozilla::ScreenSize(aDisplaySize) / mDefaultZoom;
    mozilla::CSSToLayoutDeviceScale pixelRatio(1.0f);
    if (aBehaviour == ZoomBehaviour::Desktop) {
      mMinZoom = aDefaultZoom;
    } else {
      mMinZoom = pixelRatio * ViewportMinScale();
    }
    mMaxZoom = pixelRatio * ViewportMaxScale();
    ConstrainViewportValues();
  }

  nsViewportInfo(const mozilla::CSSToScreenScale& aDefaultZoom,
                 const mozilla::CSSToScreenScale& aMinZoom,
                 const mozilla::CSSToScreenScale& aMaxZoom,
                 const mozilla::CSSSize& aSize, AutoSizeFlag aAutoSizeFlag,
                 AutoScaleFlag aAutoScaleFlag, ZoomFlag aZoomFlag,
                 mozilla::dom::ViewportFitType aViewportFit)
      : mDefaultZoom(aDefaultZoom),
        mMinZoom(aMinZoom),
        mMaxZoom(aMaxZoom),
        mSize(aSize),
        mViewportFit(aViewportFit),
        mDefaultZoomValid(aAutoScaleFlag != AutoScaleFlag::AutoScale),
        mAutoSize(aAutoSizeFlag == AutoSizeFlag::AutoSize),
        mAllowZoom(aZoomFlag == ZoomFlag::AllowZoom) {
    ConstrainViewportValues();
  }

  bool IsDefaultZoomValid() const { return mDefaultZoomValid; }
  mozilla::CSSToScreenScale GetDefaultZoom() const { return mDefaultZoom; }
  mozilla::CSSToScreenScale GetMinZoom() const { return mMinZoom; }
  mozilla::CSSToScreenScale GetMaxZoom() const { return mMaxZoom; }

  mozilla::CSSSize GetSize() const { return mSize; }

  bool IsAutoSizeEnabled() const { return mAutoSize; }
  bool IsZoomAllowed() const { return mAllowZoom; }

  mozilla::dom::ViewportFitType GetViewportFit() const { return mViewportFit; }

  static constexpr float kAuto = -1.0f;
  static constexpr float kExtendToZoom = -2.0f;
  static constexpr float kDeviceSize =
      -3.0f;  // for device-width or device-height

  // MIN/MAX computations where one of the arguments is auto resolve to the
  // other argument. For instance, MIN(0.25, auto) = 0.25, and
  // MAX(5, auto) = 5.
  // https://drafts.csswg.org/css-device-adapt/#constraining-defs
  static const float& Max(const float& aA, const float& aB);
  static const float& Min(const float& aA, const float& aB);

 private:
  /**
   * Constrain the viewport calculations from the
   * Document::GetViewportInfo() function in order to always return
   * sane minimum/maximum values.
   */
  void ConstrainViewportValues();

  // Default zoom indicates the level at which the display is 'zoomed in'
  // initially for the user, upon loading of the page.
  mozilla::CSSToScreenScale mDefaultZoom;

  // The minimum zoom level permitted by the page.
  mozilla::CSSToScreenScale mMinZoom;

  // The maximum zoom level permitted by the page.
  mozilla::CSSToScreenScale mMaxZoom;

  // The size of the viewport, specified by the <meta name="viewport"> tag.
  mozilla::CSSSize mSize;

  // The value of the viewport-fit.
  mozilla::dom::ViewportFitType mViewportFit;

  // If the default zoom was specified and was between the min and max
  // zoom values.
  // FIXME: Bug 1504362 - Unify this and mDefaultZoom into
  // Maybe<CSSToScreenScale>.
  bool mDefaultZoomValid;

  // Whether or not we should automatically size the viewport to the device's
  // width. This is true if the document has been optimized for mobile, and
  // the width property of a specified <meta name="viewport"> tag is either
  // not specified, or is set to the special value 'device-width'.
  bool mAutoSize;

  // Whether or not the user can zoom in and out on the page. Default is true.
  bool mAllowZoom;
};

#endif