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