diff --git a/ReactCommon/fabric/graphics/Geometry.h b/ReactCommon/fabric/graphics/Geometry.h index 36f71e8321562f..16777b67855a8a 100644 --- a/ReactCommon/fabric/graphics/Geometry.h +++ b/ReactCommon/fabric/graphics/Geometry.h @@ -7,58 +7,16 @@ #pragma once -#include -#include -#include - -#include #include +#include +#include +#include +#include +#include namespace facebook { namespace react { -/* - * Point - */ -struct Point { - Float x{0}; - Float y{0}; - - Point &operator+=(const Point &point) { - x += point.x; - y += point.y; - return *this; - } - - Point &operator-=(const Point &point) { - x -= point.x; - y -= point.y; - return *this; - } - - Point &operator*=(const Point &point) { - x *= point.x; - y *= point.y; - return *this; - } - - friend Point operator+(Point lhs, const Point &rhs) { - return lhs += rhs; - } - - friend Point operator-(Point lhs, const Point &rhs) { - return lhs -= rhs; - } - - bool operator==(const Point &rhs) const { - return std::tie(this->x, this->y) == std::tie(rhs.x, rhs.y); - } - - bool operator!=(const Point &rhs) const { - return !(*this == rhs); - } -}; - struct Vector { Float x{0}; Float y{0}; @@ -66,251 +24,5 @@ struct Vector { Float w{0}; }; -/* - * Size - */ -struct Size { - Float width{0}; - Float height{0}; - - Size &operator+=(const Point &point) { - width += point.x; - height += point.y; - return *this; - } - - Size &operator*=(const Point &point) { - width *= point.x; - height *= point.y; - return *this; - } - - bool operator==(const Size &rhs) const { - return std::tie(this->width, this->height) == - std::tie(rhs.width, rhs.height); - } - - bool operator!=(const Size &rhs) const { - return !(*this == rhs); - } -}; - -/* - * Rect: Point and Size - */ -struct Rect { - Point origin{0, 0}; - Size size{0, 0}; - - bool operator==(const Rect &rhs) const { - return std::tie(this->origin, this->size) == std::tie(rhs.origin, rhs.size); - } - - bool operator!=(const Rect &rhs) const { - return !(*this == rhs); - } - - Float getMaxX() const { - return size.width > 0 ? origin.x + size.width : origin.x; - } - Float getMaxY() const { - return size.height > 0 ? origin.y + size.height : origin.y; - } - Float getMinX() const { - return size.width >= 0 ? origin.x : origin.x + size.width; - } - Float getMinY() const { - return size.height >= 0 ? origin.y : origin.y + size.height; - } - Float getMidX() const { - return origin.x + size.width / 2; - } - Float getMidY() const { - return origin.y + size.height / 2; - } - Point getCenter() const { - return {getMidX(), getMidY()}; - } - - void unionInPlace(const Rect &rect) { - auto x1 = std::min(getMinX(), rect.getMinX()); - auto y1 = std::min(getMinY(), rect.getMinY()); - auto x2 = std::max(getMaxX(), rect.getMaxX()); - auto y2 = std::max(getMaxY(), rect.getMaxY()); - origin = {x1, y1}; - size = {x2 - x1, y2 - y1}; - } - - bool containsPoint(Point point) { - return point.x >= origin.x && point.y >= origin.y && - point.x <= (origin.x + size.width) && - point.y <= (origin.y + size.height); - } - - static Rect - boundingRect(Point const &a, Point const &b, Point const &c, Point const &d) { - auto leftTopPoint = a; - auto rightBottomPoint = a; - - leftTopPoint.x = std::min(leftTopPoint.x, b.x); - leftTopPoint.x = std::min(leftTopPoint.x, c.x); - leftTopPoint.x = std::min(leftTopPoint.x, d.x); - - leftTopPoint.y = std::min(leftTopPoint.y, b.y); - leftTopPoint.y = std::min(leftTopPoint.y, c.y); - leftTopPoint.y = std::min(leftTopPoint.y, d.y); - - rightBottomPoint.x = std::max(rightBottomPoint.x, b.x); - rightBottomPoint.x = std::max(rightBottomPoint.x, c.x); - rightBottomPoint.x = std::max(rightBottomPoint.x, d.x); - - rightBottomPoint.y = std::max(rightBottomPoint.y, b.y); - rightBottomPoint.y = std::max(rightBottomPoint.y, c.y); - rightBottomPoint.y = std::max(rightBottomPoint.y, d.y); - - return {leftTopPoint, - {rightBottomPoint.x - leftTopPoint.x, - rightBottomPoint.y - leftTopPoint.y}}; - } -}; - -/* - * Generic data structure describes some values associated with *edges* - * of a rectangle. - */ -template -struct RectangleEdges { - T left{}; - T top{}; - T right{}; - T bottom{}; - - bool operator==(const RectangleEdges &rhs) const { - return std::tie(this->left, this->top, this->right, this->bottom) == - std::tie(rhs.left, rhs.top, rhs.right, rhs.bottom); - } - - bool operator!=(const RectangleEdges &rhs) const { - return !(*this == rhs); - } - - bool isUniform() const { - return left == top && left == right && left == bottom; - } -}; - -template -RectangleEdges operator+( - RectangleEdges const &lhs, - RectangleEdges const &rhs) { - return RectangleEdges{lhs.left + rhs.left, - lhs.top + rhs.top, - lhs.right + rhs.right, - lhs.bottom + rhs.bottom}; -} - -template -RectangleEdges operator-( - RectangleEdges const &lhs, - RectangleEdges const &rhs) { - return RectangleEdges{lhs.left - rhs.left, - lhs.top - rhs.top, - lhs.right - rhs.right, - lhs.bottom - rhs.bottom}; -} - -/* - * Generic data structure describes some values associated with *corners* - * of a rectangle. - */ -template -struct RectangleCorners { - T topLeft{}; - T topRight{}; - T bottomLeft{}; - T bottomRight{}; - - bool operator==(const RectangleCorners &rhs) const { - return std::tie( - this->topLeft, - this->topRight, - this->bottomLeft, - this->bottomRight) == - std::tie(rhs.topLeft, rhs.topRight, rhs.bottomLeft, rhs.bottomRight); - } - - bool operator!=(const RectangleCorners &rhs) const { - return !(*this == rhs); - } - - bool isUniform() const { - return topLeft == topRight && topLeft == bottomLeft && - topLeft == bottomRight; - } -}; - -/* - * EdgeInsets - */ -using EdgeInsets = RectangleEdges; - -/* - * CornerInsets - */ -using CornerInsets = RectangleCorners; - -/* - * Adjusts a rectangle by the given edge insets. - */ -inline Rect insetBy(Rect rect, EdgeInsets insets) { - return Rect{{rect.origin.x + insets.left, rect.origin.y + insets.top}, - {rect.size.width - insets.left - insets.right, - rect.size.height - insets.top - insets.bottom}}; -} - } // namespace react } // namespace facebook - -namespace std { -template <> -struct hash { - size_t operator()(const facebook::react::Point &point) const { - return folly::hash::hash_combine(0, point.x, point.y); - } -}; - -template <> -struct hash { - size_t operator()(const facebook::react::Size &size) const { - return folly::hash::hash_combine(0, size.width, size.height); - } -}; - -template <> -struct hash { - size_t operator()(const facebook::react::Rect &rect) const { - return folly::hash::hash_combine(0, rect.origin, rect.size); - } -}; - -template -struct hash> { - size_t operator()(const facebook::react::RectangleEdges &edges) const { - return folly::hash::hash_combine( - 0, edges.left, edges.right, edges.top, edges.bottom); - } -}; - -template -struct hash> { - size_t operator()(const facebook::react::RectangleCorners &corners) const { - return folly::hash::hash_combine( - 0, - corners.topLeft, - corners.bottomLeft, - corners.topRight, - corners.bottomRight); - } -}; - -} // namespace std diff --git a/ReactCommon/fabric/graphics/Point.h b/ReactCommon/fabric/graphics/Point.h new file mode 100644 index 00000000000000..a0637ac54b75e7 --- /dev/null +++ b/ReactCommon/fabric/graphics/Point.h @@ -0,0 +1,72 @@ +/* + * Copyright (c) Facebook, Inc. and its affiliates. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + */ + +#pragma once + +#include + +#include +#include + +namespace facebook { +namespace react { + +/* + * Contains a point in a two-dimensional coordinate system. + */ +struct Point { + Float x{0}; + Float y{0}; + + Point &operator+=(Point const &point) noexcept { + x += point.x; + y += point.y; + return *this; + } + + Point &operator-=(Point const &point) noexcept { + x -= point.x; + y -= point.y; + return *this; + } + + Point &operator*=(Point const &point) noexcept { + x *= point.x; + y *= point.y; + return *this; + } + + friend Point operator+(Point lhs, Point const &rhs) noexcept { + return lhs += rhs; + } + + friend Point operator-(Point lhs, Point const &rhs) noexcept { + return lhs -= rhs; + } +}; + +inline bool operator==(Point const &rhs, Point const &lhs) noexcept { + return std::tie(lhs.x, lhs.y) == std::tie(rhs.x, rhs.y); +} + +inline bool operator!=(Point const &rhs, Point const &lhs) noexcept { + return !(lhs == rhs); +} + +} // namespace react +} // namespace facebook + +namespace std { + +template <> +struct hash { + size_t operator()(facebook::react::Point const &point) const noexcept { + return folly::hash::hash_combine(0, point.x, point.y); + } +}; + +} // namespace std diff --git a/ReactCommon/fabric/graphics/Rect.h b/ReactCommon/fabric/graphics/Rect.h new file mode 100644 index 00000000000000..93b049b5c2b3c5 --- /dev/null +++ b/ReactCommon/fabric/graphics/Rect.h @@ -0,0 +1,114 @@ +/* + * Copyright (c) Facebook, Inc. and its affiliates. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + */ + +#pragma once + +#include + +#include +#include +#include +#include + +namespace facebook { +namespace react { + +/* + * Contains the location and dimensions of a rectangle. + */ +struct Rect { + Point origin{0, 0}; + Size size{0, 0}; + + bool operator==(Rect const &rhs) const noexcept { + return std::tie(this->origin, this->size) == std::tie(rhs.origin, rhs.size); + } + + bool operator!=(Rect const &rhs) const noexcept { + return !(*this == rhs); + } + + Float getMaxX() const noexcept { + return size.width > 0 ? origin.x + size.width : origin.x; + } + Float getMaxY() const noexcept { + return size.height > 0 ? origin.y + size.height : origin.y; + } + Float getMinX() const noexcept { + return size.width >= 0 ? origin.x : origin.x + size.width; + } + Float getMinY() const noexcept { + return size.height >= 0 ? origin.y : origin.y + size.height; + } + Float getMidX() const noexcept { + return origin.x + size.width / 2; + } + Float getMidY() const noexcept { + return origin.y + size.height / 2; + } + Point getCenter() const noexcept { + return {getMidX(), getMidY()}; + } + + void unionInPlace(Rect const &rect) noexcept { + auto x1 = std::min(getMinX(), rect.getMinX()); + auto y1 = std::min(getMinY(), rect.getMinY()); + auto x2 = std::max(getMaxX(), rect.getMaxX()); + auto y2 = std::max(getMaxY(), rect.getMaxY()); + origin = {x1, y1}; + size = {x2 - x1, y2 - y1}; + } + + bool containsPoint(Point point) noexcept { + return point.x >= origin.x && point.y >= origin.y && + point.x <= (origin.x + size.width) && + point.y <= (origin.y + size.height); + } + + static Rect boundingRect( + Point const &a, + Point const &b, + Point const &c, + Point const &d) noexcept { + auto leftTopPoint = a; + auto rightBottomPoint = a; + + leftTopPoint.x = std::min(leftTopPoint.x, b.x); + leftTopPoint.x = std::min(leftTopPoint.x, c.x); + leftTopPoint.x = std::min(leftTopPoint.x, d.x); + + leftTopPoint.y = std::min(leftTopPoint.y, b.y); + leftTopPoint.y = std::min(leftTopPoint.y, c.y); + leftTopPoint.y = std::min(leftTopPoint.y, d.y); + + rightBottomPoint.x = std::max(rightBottomPoint.x, b.x); + rightBottomPoint.x = std::max(rightBottomPoint.x, c.x); + rightBottomPoint.x = std::max(rightBottomPoint.x, d.x); + + rightBottomPoint.y = std::max(rightBottomPoint.y, b.y); + rightBottomPoint.y = std::max(rightBottomPoint.y, c.y); + rightBottomPoint.y = std::max(rightBottomPoint.y, d.y); + + return {leftTopPoint, + {rightBottomPoint.x - leftTopPoint.x, + rightBottomPoint.y - leftTopPoint.y}}; + } +}; + +} // namespace react +} // namespace facebook + +namespace std { + +template <> +struct hash { + size_t operator()(facebook::react::Rect const &rect) const noexcept { + return folly::hash::hash_combine(0, rect.origin, rect.size); + } +}; + +} // namespace std diff --git a/ReactCommon/fabric/graphics/RectangleCorners.h b/ReactCommon/fabric/graphics/RectangleCorners.h new file mode 100644 index 00000000000000..6d174f921423f0 --- /dev/null +++ b/ReactCommon/fabric/graphics/RectangleCorners.h @@ -0,0 +1,71 @@ +/* + * Copyright (c) Facebook, Inc. and its affiliates. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + */ + +#pragma once + +#include + +#include +#include + +namespace facebook { +namespace react { + +/* + * Generic data structure describes some values associated with *corners* + * of a rectangle. + */ +template +struct RectangleCorners { + T topLeft{}; + T topRight{}; + T bottomLeft{}; + T bottomRight{}; + + bool operator==(RectangleCorners const &rhs) const noexcept { + return std::tie( + this->topLeft, + this->topRight, + this->bottomLeft, + this->bottomRight) == + std::tie(rhs.topLeft, rhs.topRight, rhs.bottomLeft, rhs.bottomRight); + } + + bool operator!=(RectangleCorners const &rhs) const noexcept { + return !(*this == rhs); + } + + bool isUniform() const noexcept { + return topLeft == topRight && topLeft == bottomLeft && + topLeft == bottomRight; + } +}; + +/* + * CornerInsets + */ +using CornerInsets = RectangleCorners; + +} // namespace react +} // namespace facebook + +namespace std { + +template +struct hash> { + size_t operator()(facebook::react::RectangleCorners const &corners) const + noexcept { + return folly::hash::hash_combine( + 0, + corners.topLeft, + corners.bottomLeft, + corners.topRight, + corners.bottomRight); + } +}; + +} // namespace std diff --git a/ReactCommon/fabric/graphics/RectangleEdges.h b/ReactCommon/fabric/graphics/RectangleEdges.h new file mode 100644 index 00000000000000..d4db57752a5cb8 --- /dev/null +++ b/ReactCommon/fabric/graphics/RectangleEdges.h @@ -0,0 +1,92 @@ +/* + * Copyright (c) Facebook, Inc. and its affiliates. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + */ + +#pragma once + +#include + +#include +#include +#include + +namespace facebook { +namespace react { + +/* + * Generic data structure describes some values associated with *edges* + * of a rectangle. + */ +template +struct RectangleEdges { + T left{}; + T top{}; + T right{}; + T bottom{}; + + bool operator==(RectangleEdges const &rhs) const noexcept { + return std::tie(this->left, this->top, this->right, this->bottom) == + std::tie(rhs.left, rhs.top, rhs.right, rhs.bottom); + } + + bool operator!=(RectangleEdges const &rhs) const noexcept { + return !(*this == rhs); + } + + bool isUniform() const noexcept { + return left == top && left == right && left == bottom; + } +}; + +template +RectangleEdges operator+( + RectangleEdges const &lhs, + RectangleEdges const &rhs) noexcept { + return RectangleEdges{lhs.left + rhs.left, + lhs.top + rhs.top, + lhs.right + rhs.right, + lhs.bottom + rhs.bottom}; +} + +template +RectangleEdges operator-( + RectangleEdges const &lhs, + RectangleEdges const &rhs) noexcept { + return RectangleEdges{lhs.left - rhs.left, + lhs.top - rhs.top, + lhs.right - rhs.right, + lhs.bottom - rhs.bottom}; +} + +/* + * EdgeInsets + */ +using EdgeInsets = RectangleEdges; + +/* + * Adjusts a rectangle by the given edge insets. + */ +inline Rect insetBy(Rect const &rect, EdgeInsets const &insets) noexcept { + return Rect{{rect.origin.x + insets.left, rect.origin.y + insets.top}, + {rect.size.width - insets.left - insets.right, + rect.size.height - insets.top - insets.bottom}}; +} + +} // namespace react +} // namespace facebook + +namespace std { + +template +struct hash> { + size_t operator()(facebook::react::RectangleEdges const &edges) const + noexcept { + return folly::hash::hash_combine( + 0, edges.left, edges.right, edges.top, edges.bottom); + } +}; + +} // namespace std diff --git a/ReactCommon/fabric/graphics/Size.h b/ReactCommon/fabric/graphics/Size.h new file mode 100644 index 00000000000000..ad537db1771437 --- /dev/null +++ b/ReactCommon/fabric/graphics/Size.h @@ -0,0 +1,59 @@ +/* + * Copyright (c) Facebook, Inc. and its affiliates. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + */ + +#pragma once + +#include + +#include +#include +#include + +namespace facebook { +namespace react { + +/* + * Contains width and height values. + */ +struct Size { + Float width{0}; + Float height{0}; + + Size &operator+=(Point const &point) noexcept { + width += point.x; + height += point.y; + return *this; + } + + Size &operator*=(Point const &point) noexcept { + width *= point.x; + height *= point.y; + return *this; + } +}; + +inline bool operator==(Size const &rhs, Size const &lhs) noexcept { + return std::tie(lhs.width, lhs.height) == std::tie(rhs.width, rhs.height); +} + +inline bool operator!=(Size const &rhs, Size const &lhs) noexcept { + return !(lhs == rhs); +} + +} // namespace react +} // namespace facebook + +namespace std { + +template <> +struct hash { + size_t operator()(facebook::react::Size const &size) const { + return folly::hash::hash_combine(0, size.width, size.height); + } +}; + +} // namespace std