blob: f0296a52c9f7cb317841d56546b3855bdbb9de27 [file]
// Copyright 2013 The Flutter Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include <algorithm>
#include "flutter/impeller/entity/geometry/circle_geometry.h"
#include "flutter/impeller/entity/geometry/line_geometry.h"
#include "impeller/core/formats.h"
#include "impeller/entity/geometry/geometry.h"
#include "impeller/geometry/scalar.h"
namespace impeller {
CircleGeometry::CircleGeometry(const Point& center, Scalar radius)
: center_(center),
radius_(radius),
stroke_width_(-1.0f),
padding_pixels_(0.0f) {
FML_DCHECK(radius >= 0);
}
CircleGeometry::~CircleGeometry() = default;
CircleGeometry::CircleGeometry(const Point& center,
Scalar radius,
Scalar stroke_width)
: center_(center),
radius_(radius),
stroke_width_(std::max(stroke_width, 0.0f)),
padding_pixels_(0.0) {
FML_DCHECK(radius >= 0);
FML_DCHECK(stroke_width >= 0);
}
// |Geometry|
Scalar CircleGeometry::ComputeAlphaCoverage(const Matrix& transform) const {
if (stroke_width_ < 0) {
return 1;
}
return Geometry::ComputeStrokeAlphaCoverage(transform, stroke_width_);
}
Point CircleGeometry::GetCenter() const {
return center_;
}
Scalar CircleGeometry::GetRadius() const {
return radius_;
}
Scalar CircleGeometry::GetStrokeWidth() const {
return stroke_width_;
}
void CircleGeometry::SetAntialiasPadding(Scalar extra_padding) {
padding_pixels_ = extra_padding;
}
Scalar CircleGeometry::GetAntialiasPadding() const {
return padding_pixels_;
}
GeometryResult CircleGeometry::GetPositionBuffer(const ContentContext& renderer,
const Entity& entity,
RenderPass& pass) const {
auto& transform = entity.GetTransform();
Scalar max_basis = transform.GetMaxBasisLengthXY();
Scalar expansion = max_basis == 0 ? 0.0 : padding_pixels_ / max_basis;
if (stroke_width_ < 0) {
auto generator = renderer.GetTessellator().FilledCircle(
transform, center_, radius_ + expansion);
return ComputePositionGeometry(renderer, generator, entity, pass);
}
Scalar half_width =
LineGeometry::ComputePixelHalfWidth(transform, stroke_width_);
auto generator = renderer.GetTessellator().StrokedCircle(
transform, center_, radius_, half_width + expansion);
return ComputePositionGeometry(renderer, generator, entity, pass);
}
std::optional<Rect> CircleGeometry::GetCoverage(const Matrix& transform) const {
Scalar max_basis = transform.GetMaxBasisLengthXY();
Scalar expansion = max_basis == 0 ? 0.0 : padding_pixels_ / max_basis;
Scalar half_width = stroke_width_ < 0 ? 0.0 : stroke_width_ * 0.5f;
Scalar outer_radius = radius_ + half_width + expansion;
return Rect::MakeCircleBounds(center_, outer_radius)
.TransformAndClipBounds(transform);
}
bool CircleGeometry::CoversArea(const Matrix& transform,
const IRect& rect) const {
return false;
}
bool CircleGeometry::IsAxisAlignedRect() const {
return false;
}
} // namespace impeller