| // Copyright 2016 The Chromium Authors |
| // Use of this source code is governed by a BSD-style license that can be |
| // found in the LICENSE file. |
| |
| #ifndef THIRD_PARTY_BLINK_RENDERER_PLATFORM_GEOMETRY_PHYSICAL_OFFSET_H_ |
| #define THIRD_PARTY_BLINK_RENDERER_PLATFORM_GEOMETRY_PHYSICAL_OFFSET_H_ |
| |
| #include "third_party/blink/renderer/platform/geometry/layout_unit.h" |
| #include "third_party/blink/renderer/platform/platform_export.h" |
| #include "ui/gfx/geometry/point.h" |
| #include "ui/gfx/geometry/point_f.h" |
| #include "ui/gfx/geometry/vector2d.h" |
| #include "ui/gfx/geometry/vector2d_f.h" |
| |
| namespace blink { |
| |
| // PhysicalOffset is the position of a rect (typically a fragment) relative to |
| // its parent rect in the physical coordinate system. |
| // For more information about physical and logical coordinate systems, see: |
| // https://chromium.googlesource.com/chromium/src/+/main/third_party/blink/renderer/core/layout/README.md#coordinate-spaces |
| template <typename ValueType> |
| struct PLATFORM_EXPORT PhysicalFixedOffset { |
| constexpr PhysicalFixedOffset() = default; |
| constexpr PhysicalFixedOffset(ValueType left, ValueType top) |
| : left(left), top(top) {} |
| |
| // This is deleted to avoid unwanted lossy conversion from float or double to |
| // LayoutUnit or int. Use explicit LayoutUnit constructor for each parameter, |
| // or use FromPointF*() instead. |
| PhysicalFixedOffset(double, double) = delete; |
| |
| // For testing only. It's defined in core/testing/core_unit_test_helper.h. |
| // 'constexpr' is to let compiler detect usage from production code. |
| constexpr PhysicalFixedOffset(int left, int top); |
| |
| ValueType left; |
| ValueType top; |
| |
| constexpr bool IsZero() const { return !left && !top; } |
| constexpr bool HasFraction() const { |
| return left.HasFraction() || top.HasFraction(); |
| } |
| |
| void ClampNegativeToZero() { |
| left = std::max(left, ValueType()); |
| top = std::max(top, ValueType()); |
| } |
| |
| constexpr bool operator==(const PhysicalFixedOffset& other) const = default; |
| |
| PhysicalFixedOffset operator+(const PhysicalFixedOffset& other) const { |
| return PhysicalFixedOffset{this->left + other.left, this->top + other.top}; |
| } |
| PhysicalFixedOffset& operator+=(const PhysicalFixedOffset& other) { |
| *this = *this + other; |
| return *this; |
| } |
| |
| PhysicalFixedOffset operator-() const { |
| return PhysicalFixedOffset{-this->left, -this->top}; |
| } |
| PhysicalFixedOffset operator-(const PhysicalFixedOffset& other) const { |
| return PhysicalFixedOffset{this->left - other.left, this->top - other.top}; |
| } |
| PhysicalFixedOffset& operator-=(const PhysicalFixedOffset& other) { |
| *this = *this - other; |
| return *this; |
| } |
| |
| explicit PhysicalFixedOffset(const gfx::Point& point) |
| : left(point.x()), top(point.y()) {} |
| explicit PhysicalFixedOffset(const gfx::Vector2d& vector) |
| : left(vector.x()), top(vector.y()) {} |
| |
| static PhysicalFixedOffset FromPointFFloor(const gfx::PointF& point) { |
| return {ValueType::FromFloatFloor(point.x()), |
| ValueType::FromFloatFloor(point.y())}; |
| } |
| static PhysicalFixedOffset FromPointFRound(const gfx::PointF& point) { |
| return {ValueType::FromFloatRound(point.x()), |
| ValueType::FromFloatRound(point.y())}; |
| } |
| static PhysicalFixedOffset FromVector2dFFloor(const gfx::Vector2dF& vector) { |
| return {ValueType::FromFloatFloor(vector.x()), |
| ValueType::FromFloatFloor(vector.y())}; |
| } |
| static PhysicalFixedOffset FromVector2dFRound(const gfx::Vector2dF& vector) { |
| return {ValueType::FromFloatRound(vector.x()), |
| ValueType::FromFloatRound(vector.y())}; |
| } |
| |
| void Scale(float s) { |
| left *= s; |
| top *= s; |
| } |
| |
| constexpr explicit operator gfx::PointF() const { return {left, top}; } |
| constexpr explicit operator gfx::Vector2dF() const { return {left, top}; } |
| |
| String ToString() const; |
| }; |
| |
| using PhysicalOffset = PhysicalFixedOffset<LayoutUnit>; |
| |
| // TODO(crbug.com/41458361): These functions should upgraded to force correct |
| // pixel snapping in a type-safe way. |
| template <typename ValueType> |
| inline gfx::Point ToRoundedPoint(const PhysicalFixedOffset<ValueType>& o) { |
| return {o.left.Round(), o.top.Round()}; |
| } |
| template <typename ValueType> |
| inline gfx::Point ToFlooredPoint(const PhysicalFixedOffset<ValueType>& o) { |
| return {o.left.Floor(), o.top.Floor()}; |
| } |
| template <typename ValueType> |
| inline gfx::Point ToCeiledPoint(const PhysicalFixedOffset<ValueType>& o) { |
| return {o.left.Ceil(), o.top.Ceil()}; |
| } |
| |
| template <typename ValueType> |
| inline gfx::Vector2d ToRoundedVector2d( |
| const PhysicalFixedOffset<ValueType>& o) { |
| return {o.left.Round(), o.top.Round()}; |
| } |
| template <typename ValueType> |
| inline gfx::Vector2d ToFlooredVector2d( |
| const PhysicalFixedOffset<ValueType>& o) { |
| return {o.left.Floor(), o.top.Floor()}; |
| } |
| template <typename ValueType> |
| inline gfx::Vector2d ToCeiledVector2d(const PhysicalFixedOffset<ValueType>& o) { |
| return {o.left.Ceil(), o.top.Ceil()}; |
| } |
| |
| template <typename ValueType> |
| PLATFORM_EXPORT std::ostream& operator<<(std::ostream&, |
| const PhysicalFixedOffset<ValueType>&); |
| |
| } // namespace blink |
| |
| #endif // THIRD_PARTY_BLINK_RENDERER_PLATFORM_GEOMETRY_PHYSICAL_OFFSET_H_ |