261b8e2ca1
git-svn-id: http://skia.googlecode.com/svn/trunk@1129 2bbb7eff-a529-9590-31e7-b0007b416f81
231 lines
5.7 KiB
C++
231 lines
5.7 KiB
C++
#include "SampleCode.h"
|
|
#include "SkView.h"
|
|
#include "SkCanvas.h"
|
|
#include "SkCornerPathEffect.h"
|
|
#include "SkCullPoints.h"
|
|
#include "SkGradientShader.h"
|
|
#include "SkPath.h"
|
|
#include "SkRegion.h"
|
|
#include "SkShader.h"
|
|
#include "SkUtils.h"
|
|
#include "SkRandom.h"
|
|
|
|
static void addbump(SkPath* path, const SkPoint pts[2], SkScalar bump)
|
|
{
|
|
SkVector tang;
|
|
|
|
tang.setLength(pts[1].fX - pts[0].fX, pts[1].fY - pts[0].fY, bump);
|
|
|
|
path->lineTo(SkScalarHalf(pts[0].fX + pts[1].fX) - tang.fY,
|
|
SkScalarHalf(pts[0].fY + pts[1].fY) + tang.fX);
|
|
path->lineTo(pts[1]);
|
|
}
|
|
|
|
static void subdivide(SkPath* path, SkScalar bump)
|
|
{
|
|
SkPath::Iter iter(*path, false);
|
|
SkPoint pts[4];
|
|
SkPath tmp;
|
|
|
|
for (;;)
|
|
switch (iter.next(pts)) {
|
|
case SkPath::kMove_Verb:
|
|
tmp.moveTo(pts[0]);
|
|
break;
|
|
case SkPath::kLine_Verb:
|
|
addbump(&tmp, pts, bump);
|
|
bump = -bump;
|
|
break;
|
|
case SkPath::kDone_Verb:
|
|
goto FINISH;
|
|
default:
|
|
break;
|
|
}
|
|
|
|
FINISH:
|
|
path->swap(tmp);
|
|
}
|
|
|
|
static SkIPoint* getpts(const SkPath& path, int* count)
|
|
{
|
|
SkPoint pts[4];
|
|
int n = 1;
|
|
SkIPoint* array;
|
|
|
|
{
|
|
SkPath::Iter iter(path, false);
|
|
for (;;)
|
|
switch (iter.next(pts)) {
|
|
case SkPath::kLine_Verb:
|
|
n += 1;
|
|
break;
|
|
case SkPath::kDone_Verb:
|
|
goto FINISHED;
|
|
default:
|
|
break;
|
|
}
|
|
}
|
|
|
|
FINISHED:
|
|
array = new SkIPoint[n];
|
|
n = 0;
|
|
|
|
{
|
|
SkPath::Iter iter(path, false);
|
|
for (;;)
|
|
switch (iter.next(pts)) {
|
|
case SkPath::kMove_Verb:
|
|
array[n++].set(SkScalarRound(pts[0].fX), SkScalarRound(pts[0].fY));
|
|
break;
|
|
case SkPath::kLine_Verb:
|
|
array[n++].set(SkScalarRound(pts[1].fX), SkScalarRound(pts[1].fY));
|
|
break;
|
|
case SkPath::kDone_Verb:
|
|
goto FINISHED2;
|
|
default:
|
|
break;
|
|
}
|
|
}
|
|
|
|
FINISHED2:
|
|
*count = n;
|
|
return array;
|
|
}
|
|
|
|
static SkScalar nextScalarRange(SkRandom& rand, SkScalar min, SkScalar max)
|
|
{
|
|
return min + SkScalarMul(rand.nextUScalar1(), max - min);
|
|
}
|
|
|
|
class CullView : public SkView {
|
|
public:
|
|
CullView()
|
|
{
|
|
fClip.set(0, 0, SkIntToScalar(160), SkIntToScalar(160));
|
|
|
|
SkRandom rand;
|
|
|
|
for (int i = 0; i < 50; i++) {
|
|
SkScalar x = nextScalarRange(rand, -fClip.width()*1, fClip.width()*2);
|
|
SkScalar y = nextScalarRange(rand, -fClip.height()*1, fClip.height()*2);
|
|
if (i == 0)
|
|
fPath.moveTo(x, y);
|
|
else
|
|
fPath.lineTo(x, y);
|
|
}
|
|
|
|
SkScalar bump = fClip.width()/8;
|
|
subdivide(&fPath, bump);
|
|
subdivide(&fPath, bump);
|
|
subdivide(&fPath, bump);
|
|
fPoints = getpts(fPath, &fPtCount);
|
|
}
|
|
|
|
virtual ~CullView()
|
|
{
|
|
delete[] fPoints;
|
|
}
|
|
|
|
protected:
|
|
// overrides from SkEventSink
|
|
virtual bool onQuery(SkEvent* evt)
|
|
{
|
|
if (SampleCode::TitleQ(*evt))
|
|
{
|
|
SampleCode::TitleR(evt, "Culling");
|
|
return true;
|
|
}
|
|
return this->INHERITED::onQuery(evt);
|
|
}
|
|
|
|
void drawBG(SkCanvas* canvas)
|
|
{
|
|
canvas->drawColor(0xFFDDDDDD);
|
|
|
|
#if 0
|
|
SkPaint paint;
|
|
|
|
paint.setAntiAliasOn(true);
|
|
paint.setTextSize(SkIntToScalar(20));
|
|
paint.setTypeface(SkTypeface::Create("serif", SkTypeface::kBoldItalic))->unref();
|
|
|
|
uint16_t text[20];
|
|
|
|
text[0] = 'H';
|
|
text[1] = 'i';
|
|
text[2] = ' ';
|
|
for (int i = 3; i < 20; i++)
|
|
text[i] = 0x3040 + i;
|
|
canvas->drawText16(text, 20, SkIntToScalar(20), SkIntToScalar(20), paint);
|
|
#endif
|
|
}
|
|
|
|
virtual void onDraw(SkCanvas* canvas)
|
|
{
|
|
this->drawBG(canvas);
|
|
|
|
SkAutoCanvasRestore ar(canvas, true);
|
|
|
|
canvas->translate( SkScalarHalf(this->width() - fClip.width()),
|
|
SkScalarHalf(this->height() - fClip.height()));
|
|
|
|
// canvas->scale(SK_Scalar1*3, SK_Scalar1*3, 0, 0);
|
|
|
|
SkPaint paint;
|
|
|
|
// paint.setAntiAliasOn(true);
|
|
paint.setStyle(SkPaint::kStroke_Style);
|
|
|
|
canvas->drawRect(fClip, paint);
|
|
|
|
#if 1
|
|
paint.setColor(0xFF555555);
|
|
paint.setStrokeWidth(SkIntToScalar(2));
|
|
// paint.setPathEffect(new SkCornerPathEffect(SkIntToScalar(30)))->unref();
|
|
canvas->drawPath(fPath, paint);
|
|
// paint.setPathEffect(NULL);
|
|
#endif
|
|
|
|
SkPath tmp;
|
|
SkIRect iclip;
|
|
fClip.round(&iclip);
|
|
|
|
SkCullPointsPath cpp(iclip, &tmp);
|
|
|
|
cpp.moveTo(fPoints[0].fX, fPoints[0].fY);
|
|
for (int i = 0; i < fPtCount; i++)
|
|
cpp.lineTo(fPoints[i].fX, fPoints[i].fY);
|
|
|
|
paint.setColor(SK_ColorRED);
|
|
paint.setStrokeWidth(SkIntToScalar(3));
|
|
paint.setStrokeJoin(SkPaint::kRound_Join);
|
|
canvas->drawPath(tmp, paint);
|
|
|
|
this->inval(NULL);
|
|
}
|
|
|
|
virtual SkView::Click* onFindClickHandler(SkScalar x, SkScalar y)
|
|
{
|
|
return this->INHERITED::onFindClickHandler(x, y);
|
|
}
|
|
|
|
virtual bool onClick(Click* click)
|
|
{
|
|
return this->INHERITED::onClick(click);
|
|
}
|
|
|
|
private:
|
|
SkRect fClip;
|
|
SkIPoint* fPoints;
|
|
SkPath fPath;
|
|
int fPtCount;
|
|
|
|
typedef SkView INHERITED;
|
|
};
|
|
|
|
//////////////////////////////////////////////////////////////////////////////
|
|
|
|
static SkView* MyFactory() { return new CullView; }
|
|
static SkViewRegister reg(MyFactory);
|
|
|