1 // Copyright 2016 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 #ifndef THIRD_PARTY_BLINK_RENDERER_CORE_LAYOUT_GEOMETRY_PHYSICAL_OFFSET_H_
6 #define THIRD_PARTY_BLINK_RENDERER_CORE_LAYOUT_GEOMETRY_PHYSICAL_OFFSET_H_
7
8 #include "third_party/blink/renderer/core/core_export.h"
9 #include "third_party/blink/renderer/platform/geometry/layout_point.h"
10 #include "third_party/blink/renderer/platform/geometry/layout_size.h"
11 #include "third_party/blink/renderer/platform/geometry/layout_unit.h"
12 #include "third_party/blink/renderer/platform/text/text_direction.h"
13 #include "third_party/blink/renderer/platform/text/writing_mode.h"
14
15 namespace blink {
16
17 class LayoutPoint;
18 class LayoutSize;
19 struct LogicalOffset;
20 struct PhysicalSize;
21
22 // PhysicalOffset is the position of a rect (typically a fragment) relative to
23 // its parent rect in the physical coordinate system.
24 // For more information about physical and logical coordinate systems, see:
25 // https://chromium.googlesource.com/chromium/src/+/master/third_party/blink/renderer/core/layout/README.md#coordinate-spaces
26 struct CORE_EXPORT PhysicalOffset {
27 constexpr PhysicalOffset() = default;
PhysicalOffsetPhysicalOffset28 constexpr PhysicalOffset(LayoutUnit left, LayoutUnit top)
29 : left(left), top(top) {}
30
31 // For testing only. It's defined in core/testing/core_unit_test_helpers.h.
32 inline PhysicalOffset(int left, int top);
33
34 LayoutUnit left;
35 LayoutUnit top;
36
37 // Converts a physical offset to a logical offset. See:
38 // https://drafts.csswg.org/css-writing-modes-3/#logical-to-physical
39 // @param outer_size the size of the rect (typically a fragment).
40 // @param inner_size the size of the inner rect (typically a child fragment).
41 LogicalOffset ConvertToLogical(WritingMode,
42 TextDirection,
43 PhysicalSize outer_size,
44 PhysicalSize inner_size) const;
45
IsZeroPhysicalOffset46 constexpr bool IsZero() const { return !left && !top; }
HasFractionPhysicalOffset47 constexpr bool HasFraction() const {
48 return left.HasFraction() || top.HasFraction();
49 }
50
ClampNegativeToZeroPhysicalOffset51 void ClampNegativeToZero() {
52 left = std::max(left, LayoutUnit());
53 top = std::max(top, LayoutUnit());
54 }
55
56 PhysicalOffset operator+(const PhysicalOffset& other) const {
57 return PhysicalOffset{this->left + other.left, this->top + other.top};
58 }
59 PhysicalOffset& operator+=(const PhysicalOffset& other) {
60 *this = *this + other;
61 return *this;
62 }
63
64 PhysicalOffset operator-() const {
65 return PhysicalOffset{-this->left, -this->top};
66 }
67 PhysicalOffset operator-(const PhysicalOffset& other) const {
68 return PhysicalOffset{this->left - other.left, this->top - other.top};
69 }
70 PhysicalOffset& operator-=(const PhysicalOffset& other) {
71 *this = *this - other;
72 return *this;
73 }
74
75 constexpr bool operator==(const PhysicalOffset& other) const {
76 return other.left == left && other.top == top;
77 }
78
79 constexpr bool operator!=(const PhysicalOffset& other) const {
80 return !(*this == other);
81 }
82
83 // Conversions from/to existing code. New code prefers type safety for
84 // logical/physical distinctions.
PhysicalOffsetPhysicalOffset85 constexpr explicit PhysicalOffset(const LayoutPoint& point)
86 : left(point.X()), top(point.Y()) {}
PhysicalOffsetPhysicalOffset87 constexpr explicit PhysicalOffset(const LayoutSize& size)
88 : left(size.Width()), top(size.Height()) {}
89
90 // Conversions from/to existing code. New code prefers type safety for
91 // logical/physical distinctions.
ToLayoutPointPhysicalOffset92 constexpr LayoutPoint ToLayoutPoint() const { return {left, top}; }
ToLayoutSizePhysicalOffset93 constexpr LayoutSize ToLayoutSize() const { return {left, top}; }
94
PhysicalOffsetPhysicalOffset95 explicit PhysicalOffset(const IntPoint& point)
96 : left(point.X()), top(point.Y()) {}
PhysicalOffsetPhysicalOffset97 explicit PhysicalOffset(const IntSize& size)
98 : left(size.Width()), top(size.Height()) {}
PhysicalOffsetPhysicalOffset99 explicit PhysicalOffset(const gfx::Point& point)
100 : left(point.x()), top(point.y()) {}
101
FromFloatPointFloorPhysicalOffset102 static PhysicalOffset FromFloatPointFloor(const FloatPoint& point) {
103 return {LayoutUnit::FromFloatFloor(point.X()),
104 LayoutUnit::FromFloatFloor(point.Y())};
105 }
FromFloatPointRoundPhysicalOffset106 static PhysicalOffset FromFloatPointRound(const FloatPoint& point) {
107 return {LayoutUnit::FromFloatRound(point.X()),
108 LayoutUnit::FromFloatRound(point.Y())};
109 }
FromFloatSizeFloorPhysicalOffset110 static PhysicalOffset FromFloatSizeFloor(const FloatSize& size) {
111 return {LayoutUnit::FromFloatFloor(size.Width()),
112 LayoutUnit::FromFloatFloor(size.Height())};
113 }
FromFloatSizeRoundPhysicalOffset114 static PhysicalOffset FromFloatSizeRound(const FloatSize& size) {
115 return {LayoutUnit::FromFloatRound(size.Width()),
116 LayoutUnit::FromFloatRound(size.Height())};
117 }
118
FloatPointPhysicalOffset119 constexpr explicit operator FloatPoint() const { return {left, top}; }
FloatSizePhysicalOffset120 constexpr explicit operator FloatSize() const { return {left, top}; }
121
122 String ToString() const;
123 };
124
125 // TODO(crbug.com/962299): These functions should upgraded to force correct
126 // pixel snapping in a type-safe way.
RoundedIntPoint(const PhysicalOffset & o)127 inline IntPoint RoundedIntPoint(const PhysicalOffset& o) {
128 return {o.left.Round(), o.top.Round()};
129 }
FlooredIntPoint(const PhysicalOffset & o)130 inline IntPoint FlooredIntPoint(const PhysicalOffset& o) {
131 return {o.left.Floor(), o.top.Floor()};
132 }
CeiledIntPoint(const PhysicalOffset & o)133 inline IntPoint CeiledIntPoint(const PhysicalOffset& o) {
134 return {o.left.Ceil(), o.top.Ceil()};
135 }
136
137 // TODO(wangxianzhu): For temporary conversion from LayoutPoint/LayoutSize to
138 // PhysicalOffset, where the input will be changed to PhysicalOffset soon, to
139 // avoid redundant PhysicalOffset() which can't be discovered by the compiler.
PhysicalOffsetToBeNoop(const LayoutPoint & p)140 inline PhysicalOffset PhysicalOffsetToBeNoop(const LayoutPoint& p) {
141 return PhysicalOffset(p);
142 }
PhysicalOffsetToBeNoop(const LayoutSize & s)143 inline PhysicalOffset PhysicalOffsetToBeNoop(const LayoutSize& s) {
144 return PhysicalOffset(s);
145 }
146
147 CORE_EXPORT std::ostream& operator<<(std::ostream&, const PhysicalOffset&);
148
149 } // namespace blink
150
151 #endif // THIRD_PARTY_BLINK_RENDERER_CORE_LAYOUT_GEOMETRY_PHYSICAL_OFFSET_H_
152