mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-10-08 19:04:45 +00:00
Bug 1555838 - More polyutil fixes. r=rhunt
Differential Revision: https://phabricator.services.mozilla.com/D33688 --HG-- extra : moz-landing-system : lando
This commit is contained in:
parent
d572d1339c
commit
93c478a9ca
@ -1051,16 +1051,16 @@ bool SkIsSimplePolygon(const SkPoint* polygon, int polygonSize) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// need to be able to represent all the vertices in the 16-bit indices
|
||||
if (polygonSize > std::numeric_limits<uint16_t>::max()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// If it's convex, it's simple
|
||||
if (SkIsConvexPolygon(polygon, polygonSize)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
// practically speaking, it takes too long to process large polygons
|
||||
if (polygonSize > 2048) {
|
||||
return false;
|
||||
}
|
||||
|
||||
SkTDPQueue <Vertex, Vertex::Left> vertexQueue(polygonSize);
|
||||
for (int i = 0; i < polygonSize; ++i) {
|
||||
Vertex newVertex;
|
||||
@ -1145,7 +1145,8 @@ static bool is_reflex_vertex(const SkPoint* inputPolygonVerts, int winding, SkSc
|
||||
return (side*winding*offset < 0);
|
||||
}
|
||||
|
||||
bool SkOffsetSimplePolygon(const SkPoint* inputPolygonVerts, int inputPolygonSize, SkScalar offset,
|
||||
bool SkOffsetSimplePolygon(const SkPoint* inputPolygonVerts, int inputPolygonSize,
|
||||
const SkRect& bounds, SkScalar offset,
|
||||
SkTDArray<SkPoint>* offsetPolygon, SkTDArray<int>* polygonIndices) {
|
||||
if (inputPolygonSize < 3) {
|
||||
return false;
|
||||
@ -1160,6 +1161,12 @@ bool SkOffsetSimplePolygon(const SkPoint* inputPolygonVerts, int inputPolygonSiz
|
||||
return false;
|
||||
}
|
||||
|
||||
// can't inset more than the half bounds of the polygon
|
||||
if (offset > SkTMin(SkTAbs(SK_ScalarHalf*bounds.width()),
|
||||
SkTAbs(SK_ScalarHalf*bounds.height()))) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// offsetting close to zero just returns the original poly
|
||||
if (SkScalarNearlyZero(offset)) {
|
||||
for (int i = 0; i < inputPolygonSize; ++i) {
|
||||
|
@ -13,6 +13,8 @@
|
||||
#include "SkTDArray.h"
|
||||
#include "SkPoint.h"
|
||||
|
||||
struct SkRect;
|
||||
|
||||
/**
|
||||
* Generates a polygon that is inset a constant from the boundary of a given convex polygon.
|
||||
*
|
||||
@ -33,6 +35,7 @@ bool SkInsetConvexPolygon(const SkPoint* inputPolygonVerts, int inputPolygonSize
|
||||
*
|
||||
* @param inputPolygonVerts Array of points representing the vertices of the original polygon.
|
||||
* @param inputPolygonSize Number of vertices in the original polygon.
|
||||
* @param bounds Bounding rectangle for the original polygon.
|
||||
* @param offset How far we wish to offset the polygon.
|
||||
* Positive values indicate insetting, negative values outsetting.
|
||||
* @param offsetPolgon The resulting offset polygon, if any.
|
||||
@ -40,7 +43,7 @@ bool SkInsetConvexPolygon(const SkPoint* inputPolygonVerts, int inputPolygonSize
|
||||
* @return true if an offset simple polygon exists, false otherwise.
|
||||
*/
|
||||
bool SkOffsetSimplePolygon(const SkPoint* inputPolygonVerts, int inputPolygonSize,
|
||||
SkScalar offset, SkTDArray<SkPoint>* offsetPolygon,
|
||||
const SkRect& bounds, SkScalar offset, SkTDArray<SkPoint>* offsetPolygon,
|
||||
SkTDArray<int>* polygonIndices = nullptr);
|
||||
|
||||
/**
|
||||
|
@ -25,7 +25,7 @@
|
||||
*/
|
||||
class SkBaseShadowTessellator {
|
||||
public:
|
||||
SkBaseShadowTessellator(const SkPoint3& zPlaneParams, bool transparent);
|
||||
SkBaseShadowTessellator(const SkPoint3& zPlaneParams, const SkRect& bounds, bool transparent);
|
||||
virtual ~SkBaseShadowTessellator() {}
|
||||
|
||||
sk_sp<SkVertices> releaseVertices() {
|
||||
@ -99,6 +99,7 @@ protected:
|
||||
SkTDArray<SkPoint> fClipPolygon;
|
||||
SkTDArray<SkVector> fClipVectors;
|
||||
|
||||
SkRect fPathBounds;
|
||||
SkPoint fCentroid;
|
||||
SkScalar fArea;
|
||||
SkScalar fLastArea;
|
||||
@ -155,8 +156,10 @@ static SkScalar perp_dot(const SkPoint& p0, const SkPoint& p1, const SkPoint& p2
|
||||
return v0.cross(v1);
|
||||
}
|
||||
|
||||
SkBaseShadowTessellator::SkBaseShadowTessellator(const SkPoint3& zPlaneParams, bool transparent)
|
||||
SkBaseShadowTessellator::SkBaseShadowTessellator(const SkPoint3& zPlaneParams, const SkRect& bounds,
|
||||
bool transparent)
|
||||
: fZPlaneParams(zPlaneParams)
|
||||
, fPathBounds(bounds)
|
||||
, fCentroid({0, 0})
|
||||
, fArea(0)
|
||||
, fLastArea(0)
|
||||
@ -559,8 +562,8 @@ bool SkBaseShadowTessellator::computeConcaveShadow(SkScalar inset, SkScalar outs
|
||||
SkTDArray<SkPoint> umbraPolygon;
|
||||
SkTDArray<int> umbraIndices;
|
||||
umbraIndices.setReserve(fPathPolygon.count());
|
||||
if (!SkOffsetSimplePolygon(&fPathPolygon[0], fPathPolygon.count(), inset,
|
||||
&umbraPolygon, &umbraIndices)) {
|
||||
if (!SkOffsetSimplePolygon(&fPathPolygon[0], fPathPolygon.count(), fPathBounds, inset,
|
||||
&umbraPolygon, &umbraIndices)) {
|
||||
// TODO: figure out how to handle this case
|
||||
return false;
|
||||
}
|
||||
@ -570,7 +573,7 @@ bool SkBaseShadowTessellator::computeConcaveShadow(SkScalar inset, SkScalar outs
|
||||
SkTDArray<int> penumbraIndices;
|
||||
penumbraPolygon.setReserve(umbraPolygon.count());
|
||||
penumbraIndices.setReserve(umbraPolygon.count());
|
||||
if (!SkOffsetSimplePolygon(&fPathPolygon[0], fPathPolygon.count(), -outset,
|
||||
if (!SkOffsetSimplePolygon(&fPathPolygon[0], fPathPolygon.count(), fPathBounds, -outset,
|
||||
&penumbraPolygon, &penumbraIndices)) {
|
||||
// TODO: figure out how to handle this case
|
||||
return false;
|
||||
@ -904,12 +907,14 @@ SkAmbientShadowTessellator::SkAmbientShadowTessellator(const SkPath& path,
|
||||
const SkMatrix& ctm,
|
||||
const SkPoint3& zPlaneParams,
|
||||
bool transparent)
|
||||
: INHERITED(zPlaneParams, transparent) {
|
||||
: INHERITED(zPlaneParams, path.getBounds(), transparent) {
|
||||
// Set base colors
|
||||
auto baseZ = heightFunc(path.getBounds().centerX(), path.getBounds().centerY());
|
||||
auto baseZ = heightFunc(fPathBounds.centerX(), fPathBounds.centerY());
|
||||
// umbraColor is the interior value, penumbraColor the exterior value.
|
||||
auto outset = SkDrawShadowMetrics::AmbientBlurRadius(baseZ);
|
||||
auto inset = outset * SkDrawShadowMetrics::AmbientRecipAlpha(baseZ) - outset;
|
||||
inset = SkScalarPin(inset, 0, SkTMin(path.getBounds().width(),
|
||||
path.getBounds().height()));
|
||||
|
||||
if (!this->computePathPolygon(path, ctm)) {
|
||||
return;
|
||||
@ -999,7 +1004,7 @@ SkSpotShadowTessellator::SkSpotShadowTessellator(const SkPath& path, const SkMat
|
||||
const SkPoint3& zPlaneParams,
|
||||
const SkPoint3& lightPos, SkScalar lightRadius,
|
||||
bool transparent)
|
||||
: INHERITED(zPlaneParams, transparent) {
|
||||
: INHERITED(zPlaneParams, path.getBounds(), transparent) {
|
||||
|
||||
// Compute the blur radius, scale and translation for the spot shadow.
|
||||
SkMatrix shadowTransform;
|
||||
|
Loading…
Reference in New Issue
Block a user