GM (and fix) for drawArc capping issue
https://codereview.chromium.org/18271003/ git-svn-id: http://skia.googlecode.com/svn/trunk@9928 2bbb7eff-a529-9590-31e7-b0007b416f81
This commit is contained in:
parent
387db0a2e5
commit
e1b75b4096
83
gm/arcofzorro.cpp
Normal file
83
gm/arcofzorro.cpp
Normal file
@ -0,0 +1,83 @@
|
||||
/*
|
||||
* Copyright 2013 Google Inc.
|
||||
*
|
||||
* Use of this source code is governed by a BSD-style license that can be
|
||||
* found in the LICENSE file.
|
||||
*/
|
||||
|
||||
#include "gm.h"
|
||||
#include "SkRandom.h"
|
||||
|
||||
namespace skiagm {
|
||||
|
||||
// This GM draws a lot of arcs in a 'Z' shape. It particularly exercises
|
||||
// the 'drawArc' code near a singularly of its processing (i.e., near the
|
||||
// edge of one of its underlying quads).
|
||||
class ArcOfZorroGM : public GM {
|
||||
public:
|
||||
ArcOfZorroGM() {
|
||||
this->setBGColor(0xFFCCCCCC);
|
||||
}
|
||||
|
||||
protected:
|
||||
virtual SkString onShortName() SK_OVERRIDE {
|
||||
return SkString("arcofzorro");
|
||||
}
|
||||
|
||||
virtual SkISize onISize() SK_OVERRIDE {
|
||||
return make_isize(1000, 1000);
|
||||
}
|
||||
|
||||
virtual void onDraw(SkCanvas* canvas) SK_OVERRIDE {
|
||||
SkMWCRandom rand;
|
||||
|
||||
SkRect rect = SkRect::MakeXYWH(10, 10, 200, 200);
|
||||
|
||||
SkPaint p;
|
||||
|
||||
p.setStyle(SkPaint::kStroke_Style);
|
||||
p.setStrokeWidth(35);
|
||||
int xOffset = 0, yOffset = 0;
|
||||
int direction = 0;
|
||||
|
||||
for (float arc = 134.0f; arc < 136.0f; arc += 0.01f) {
|
||||
SkColor color = rand.nextU();
|
||||
color |= 0xff000000;
|
||||
p.setColor(color);
|
||||
|
||||
canvas->save();
|
||||
canvas->translate(SkIntToScalar(xOffset), SkIntToScalar(yOffset));
|
||||
canvas->drawArc(rect, 0, arc, false, p);
|
||||
canvas->restore();
|
||||
|
||||
switch (direction) {
|
||||
case 0:
|
||||
xOffset += 10;
|
||||
if (xOffset >= 700) {
|
||||
direction = 1;
|
||||
}
|
||||
break;
|
||||
case 1:
|
||||
xOffset -= 10;
|
||||
yOffset += 10;
|
||||
if (xOffset < 50) {
|
||||
direction = 2;
|
||||
}
|
||||
break;
|
||||
case 2:
|
||||
xOffset += 10;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private:
|
||||
typedef GM INHERITED;
|
||||
};
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
DEF_GM( return SkNEW(ArcOfZorroGM); )
|
||||
|
||||
}
|
@ -4,6 +4,7 @@
|
||||
'../gm/aaclip.cpp',
|
||||
'../gm/aarectmodes.cpp',
|
||||
'../gm/alphagradients.cpp',
|
||||
'../gm/arcofzorro.cpp',
|
||||
'../gm/arithmode.cpp',
|
||||
'../gm/bicubicfilter.cpp',
|
||||
'../gm/bigmatrix.cpp',
|
||||
|
@ -1205,11 +1205,13 @@ static SkScalar quad_solve(SkScalar a, SkScalar b, SkScalar c, SkScalar d)
|
||||
return count == 1 ? roots[0] : 0;
|
||||
}
|
||||
|
||||
/* given a quad-curve and a point (x,y), chop the quad at that point and return
|
||||
the new quad's offCurve point. Should only return false if the computed pos
|
||||
is the start of the curve (i.e. root == 0)
|
||||
/* given a quad-curve and a point (x,y), chop the quad at that point and place
|
||||
the new off-curve point and endpoint into 'dest'. The new end point is used
|
||||
(rather than (x,y)) to compensate for numerical inaccuracies.
|
||||
Should only return false if the computed pos is the start of the curve
|
||||
(i.e. root == 0)
|
||||
*/
|
||||
static bool quad_pt2OffCurve(const SkPoint quad[3], SkScalar x, SkScalar y, SkPoint* offCurve)
|
||||
static bool truncate_last_curve(const SkPoint quad[3], SkScalar x, SkScalar y, SkPoint* dest)
|
||||
{
|
||||
const SkScalar* base;
|
||||
SkScalar value;
|
||||
@ -1230,7 +1232,8 @@ static bool quad_pt2OffCurve(const SkPoint quad[3], SkScalar x, SkScalar y, SkPo
|
||||
{
|
||||
SkPoint tmp[5];
|
||||
SkChopQuadAt(quad, tmp, t);
|
||||
*offCurve = tmp[1];
|
||||
dest[0] = tmp[1];
|
||||
dest[1] = tmp[2];
|
||||
return true;
|
||||
} else {
|
||||
/* t == 0 means either the value triggered a root outside of [0, 1)
|
||||
@ -1247,7 +1250,8 @@ static bool quad_pt2OffCurve(const SkPoint quad[3], SkScalar x, SkScalar y, SkPo
|
||||
if ((base[0] < base[4] && value > base[2]) ||
|
||||
(base[0] > base[4] && value < base[2])) // should root have been 1
|
||||
{
|
||||
*offCurve = quad[1];
|
||||
dest[0] = quad[1];
|
||||
dest[1].set(x, y);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
@ -1360,9 +1364,8 @@ int SkBuildQuadArc(const SkVector& uStart, const SkVector& uStop,
|
||||
memcpy(quadPoints, gQuadCirclePts, (wholeCount + 1) * sizeof(SkPoint));
|
||||
|
||||
const SkPoint* arc = &gQuadCirclePts[wholeCount];
|
||||
if (quad_pt2OffCurve(arc, x, y, &quadPoints[wholeCount + 1]))
|
||||
if (truncate_last_curve(arc, x, y, &quadPoints[wholeCount + 1]))
|
||||
{
|
||||
quadPoints[wholeCount + 2].set(x, y);
|
||||
wholeCount += 2;
|
||||
}
|
||||
pointCount = wholeCount + 1;
|
||||
|
Loading…
Reference in New Issue
Block a user