1/* 2 * Copyright 2021 Google LLC 3 * 4 * Use of this source code is governed by a BSD-style license that can be 5 * found in the LICENSE file. 6 */ 7 8#include "experimental/graphite/src/geom/Shape.h" 9 10#include "src/core/SkPathPriv.h" 11#include "src/core/SkRRectPriv.h" 12#include "src/utils/SkPolyUtils.h" 13 14namespace skgpu { 15 16Shape& Shape::operator=(const Shape& shape) { 17 switch (shape.type()) { 18 case Type::kEmpty: this->reset(); break; 19 case Type::kLine: this->setLine(shape.p0(), shape.p1()); break; 20 case Type::kRect: this->setRect(shape.rect()); break; 21 case Type::kRRect: this->setRRect(shape.rrect()); break; 22 case Type::kPath: this->setPath(shape.path()); break; 23 } 24 25 fInverted = shape.fInverted; 26 return *this; 27} 28 29bool Shape::conservativeContains(const Rect& rect) const { 30 switch (fType) { 31 case Type::kEmpty: return false; 32 case Type::kLine: return false; 33 case Type::kRect: return fRect.contains(rect); 34 case Type::kRRect: return fRRect.contains(rect.asSkRect()); 35 case Type::kPath: return fPath.conservativelyContainsRect(rect.asSkRect()); 36 } 37 SkUNREACHABLE; 38} 39 40bool Shape::conservativeContains(float2 point) const { 41 switch (fType) { 42 case Type::kEmpty: return false; 43 case Type::kLine: return false; 44 case Type::kRect: return fRect.contains(Rect::Point(point)); 45 case Type::kRRect: return SkRRectPriv::ContainsPoint(fRRect, {point.x(), point.y()}); 46 case Type::kPath: return fPath.contains(point.x(), point.y()); 47 } 48 SkUNREACHABLE; 49} 50 51bool Shape::closed() const { 52 switch (fType) { 53 case Type::kEmpty: return true; 54 case Type::kLine: return false; 55 case Type::kRect: return true; 56 case Type::kRRect: return true; 57 case Type::kPath: return SkPathPriv::IsClosedSingleContour(fPath); 58 } 59 SkUNREACHABLE; 60} 61 62bool Shape::convex(bool simpleFill) const { 63 if (this->isPath()) { 64 // SkPath.isConvex() really means "is this path convex were it to be closed". 65 return (simpleFill || fPath.isLastContourClosed()) && fPath.isConvex(); 66 } else { 67 // Every other shape type is convex by construction. 68 return true; 69 } 70} 71 72Rect Shape::bounds() const { 73 switch (fType) { 74 case Type::kEmpty: return Rect(0, 0, 0, 0); 75 case Type::kLine: return fRect.makeSorted(); // sorting corners computes bbox of segment 76 case Type::kRect: return fRect; // assuming it's sorted 77 case Type::kRRect: return fRRect.getBounds(); 78 case Type::kPath: return fPath.getBounds(); 79 } 80 SkUNREACHABLE; 81} 82 83SkPath Shape::asPath() const { 84 if (fType == Type::kPath) { 85 return fPath; 86 } 87 88 SkPathBuilder builder(this->fillType()); 89 switch (fType) { 90 case Type::kEmpty: /* do nothing */ break; 91 case Type::kLine: builder.moveTo(fRect.left(), fRect.top()) 92 .lineTo(fRect.right(), fRect.bot()); break; 93 case Type::kRect: builder.addRect(fRect.asSkRect()); break; 94 case Type::kRRect: builder.addRRect(fRRect); break; 95 case Type::kPath: SkUNREACHABLE; 96 } 97 return builder.detach(); 98} 99 100} // namespace skgpu 101