| // Copyright 2014 Google Inc. All Rights Reserved. |
| // |
| // Licensed under the Apache License, Version 2.0 (the "License"); |
| // you may not use this file except in compliance with the License. |
| // You may obtain a copy of the License at |
| // |
| // http://www.apache.org/licenses/LICENSE-2.0 |
| // |
| // Unless required by applicable law or agreed to in writing, software |
| // distributed under the License is distributed on an "AS IS" BASIS, |
| // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| // See the License for the specific language governing permissions and |
| // limitations under the License. |
| |
| #ifndef COBALT_RENDER_TREE_ROUNDED_CORNERS_H_ |
| #define COBALT_RENDER_TREE_ROUNDED_CORNERS_H_ |
| |
| #include <algorithm> |
| |
| #include "cobalt/math/insets_f.h" |
| #include "cobalt/math/rect_f.h" |
| |
| namespace cobalt { |
| namespace render_tree { |
| |
| // RoundedCorner represents one of the corners of an rectangle. It contains the |
| // lengths of the semi-major axis and the semi-minor axis of an ellipse. |
| struct RoundedCorner { |
| RoundedCorner() : horizontal(0.0f), vertical(0.0f) {} |
| |
| RoundedCorner(float horizontal, float vertical) |
| : horizontal(horizontal), vertical(vertical) {} |
| |
| // If either length is zero, the corner is square, not rounded. |
| bool IsSquare() const { return horizontal == 0.0f || vertical == 0.0f; } |
| |
| RoundedCorner Inset(float x, float y) const { |
| return RoundedCorner(std::max(0.0f, horizontal - x), |
| std::max(0.0f, vertical - y)); |
| } |
| |
| bool operator==(const RoundedCorner& other) const { |
| return horizontal == other.horizontal && vertical == other.vertical; |
| } |
| bool operator>=(const RoundedCorner& other) const { |
| return horizontal >= other.horizontal && vertical >= other.vertical; |
| } |
| |
| // |horizontal| and |vertial| represent the horizontal radius and vertical |
| // radius of a corner. |
| float horizontal; |
| float vertical; |
| }; |
| |
| // RoundedCorners represents 4 rounded corners of an rectangle. Top left, top |
| // right, bottom right and bottom left. |
| struct RoundedCorners { |
| explicit RoundedCorners(const RoundedCorner& corner) |
| : top_left(corner), |
| top_right(corner), |
| bottom_right(corner), |
| bottom_left(corner) {} |
| |
| RoundedCorners(float horizontal, float vertical) |
| : top_left(horizontal, vertical), |
| top_right(horizontal, vertical), |
| bottom_right(horizontal, vertical), |
| bottom_left(horizontal, vertical) {} |
| |
| RoundedCorners(const RoundedCorners& radiuses) |
| : top_left(radiuses.top_left), |
| top_right(radiuses.top_right), |
| bottom_right(radiuses.bottom_right), |
| bottom_left(radiuses.bottom_left) {} |
| |
| RoundedCorners(const RoundedCorner& top_left, const RoundedCorner& top_right, |
| const RoundedCorner& bottom_right, |
| const RoundedCorner& bottom_left) |
| : top_left(top_left), |
| top_right(top_right), |
| bottom_right(bottom_right), |
| bottom_left(bottom_left) {} |
| |
| bool operator==(const RoundedCorners& other) const { |
| return top_left == other.top_left && top_right == other.top_right && |
| bottom_right == other.bottom_right && |
| bottom_left == other.bottom_left; |
| } |
| |
| RoundedCorners Inset(float left, float top, float right, float bottom) const { |
| return RoundedCorners( |
| top_left.Inset(left, top), top_right.Inset(right, top), |
| bottom_right.Inset(right, bottom), bottom_left.Inset(left, bottom)); |
| } |
| |
| RoundedCorners Inset(const math::InsetsF& insets) const { |
| return Inset(insets.left(), insets.top(), insets.right(), insets.bottom()); |
| } |
| |
| RoundedCorners Scale(float sx, float sy) const; |
| |
| // Ensure the rounded corners' radii do not exceed the length of the |
| // corresponding edge of the given rect. |
| RoundedCorners Normalize(const math::RectF& rect) const; |
| bool IsNormalized(const math::RectF& rect) const; |
| |
| bool AreSquares() const { |
| return top_left.IsSquare() && top_right.IsSquare() && |
| bottom_right.IsSquare() && bottom_left.IsSquare(); |
| } |
| |
| // Returns true if all corners have the same value as the input. |
| bool AllCornersEqual(const RoundedCorner& rhs) const { |
| return top_left == rhs && top_right == rhs && bottom_right == rhs && |
| bottom_left == rhs; |
| } |
| |
| // Returns true if all corners' radii are greater than or equal to the |
| // corresponding radii of the input. |
| bool AllCornersGE(const RoundedCorner& rhs) const { |
| return top_left >= rhs && top_right >= rhs && bottom_right >= rhs && |
| bottom_left >= rhs; |
| } |
| |
| RoundedCorner top_left; |
| RoundedCorner top_right; |
| RoundedCorner bottom_right; |
| RoundedCorner bottom_left; |
| }; |
| |
| } // namespace render_tree |
| } // namespace cobalt |
| |
| #endif // COBALT_RENDER_TREE_ROUNDED_CORNERS_H_ |