| /* | |
| * Copyright 2021 Google LLC | |
| * | |
| * Use of this source code is governed by a BSD-style license that can be | |
| * found in the LICENSE file. | |
| */ | |
| #include "src/gpu/graphite/geom/Shape.h" | |
| #include "src/core/SkPathPriv.h" | |
| #include "src/core/SkRRectPriv.h" | |
| #include "src/utils/SkPolyUtils.h" | |
| namespace skgpu::graphite { | |
| Shape& Shape::operator=(const Shape& shape) { | |
| switch (shape.type()) { | |
| case Type::kEmpty: this->reset(); break; | |
| case Type::kLine: this->setLine(shape.p0(), shape.p1()); break; | |
| case Type::kRect: this->setRect(shape.rect()); break; | |
| case Type::kRRect: this->setRRect(shape.rrect()); break; | |
| case Type::kPath: this->setPath(shape.path()); break; | |
| } | |
| fInverted = shape.fInverted; | |
| return *this; | |
| } | |
| bool Shape::conservativeContains(const Rect& rect) const { | |
| switch (fType) { | |
| case Type::kEmpty: return false; | |
| case Type::kLine: return false; | |
| case Type::kRect: return fRect.contains(rect); | |
| case Type::kRRect: return fRRect.contains(rect.asSkRect()); | |
| case Type::kPath: return fPath.conservativelyContainsRect(rect.asSkRect()); | |
| } | |
| SkUNREACHABLE; | |
| } | |
| bool Shape::conservativeContains(skvx::float2 point) const { | |
| switch (fType) { | |
| case Type::kEmpty: return false; | |
| case Type::kLine: return false; | |
| case Type::kRect: return fRect.contains(Rect::Point(point)); | |
| case Type::kRRect: return SkRRectPriv::ContainsPoint(fRRect, {point.x(), point.y()}); | |
| case Type::kPath: return fPath.contains(point.x(), point.y()); | |
| } | |
| SkUNREACHABLE; | |
| } | |
| bool Shape::convex(bool simpleFill) const { | |
| if (this->isPath()) { | |
| // SkPath.isConvex() really means "is this path convex were it to be closed". | |
| return (simpleFill || fPath.isLastContourClosed()) && fPath.isConvex(); | |
| } else { | |
| // Every other shape type is convex by construction. | |
| return true; | |
| } | |
| } | |
| Rect Shape::bounds() const { | |
| switch (fType) { | |
| case Type::kEmpty: return Rect(0, 0, 0, 0); | |
| case Type::kLine: return fRect.makeSorted(); // sorting corners computes bbox of segment | |
| case Type::kRect: return fRect; // assuming it's sorted | |
| case Type::kRRect: return fRRect.getBounds(); | |
| case Type::kPath: return fPath.getBounds(); | |
| } | |
| SkUNREACHABLE; | |
| } | |
| SkPath Shape::asPath() const { | |
| if (fType == Type::kPath) { | |
| return fPath; | |
| } | |
| SkPathBuilder builder(this->fillType()); | |
| switch (fType) { | |
| case Type::kEmpty: /* do nothing */ break; | |
| case Type::kLine: builder.moveTo(fRect.left(), fRect.top()) | |
| .lineTo(fRect.right(), fRect.bot()); break; | |
| case Type::kRect: builder.addRect(fRect.asSkRect()); break; | |
| case Type::kRRect: builder.addRRect(fRRect); break; | |
| case Type::kPath: SkUNREACHABLE; | |
| } | |
| return builder.detach(); | |
| } | |
| } // namespace skgpu::graphite |