blob: 0a9a09d8a2c203d6cd4c707f7c5ef7bd969cc81c [file] [log] [blame]
// 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) {}
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());
}
// Ensure the rounded corners' radii do not exceed the length of the
// corresponding edge of the given rect.
void Normalize(const math::RectF& rect);
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_