зеркало из https://github.com/mozilla/moz-skia.git
197 строки
5.0 KiB
C++
197 строки
5.0 KiB
C++
|
|
/*
|
|
* Copyright 2011 Google Inc.
|
|
*
|
|
* Use of this source code is governed by a BSD-style license that can be
|
|
* found in the LICENSE file.
|
|
*/
|
|
#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 SampleView {
|
|
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);
|
|
|
|
this->setBGColor(0xFFDDDDDD);
|
|
}
|
|
|
|
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);
|
|
}
|
|
|
|
virtual void onDrawContent(SkCanvas* 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);
|
|
}
|
|
|
|
private:
|
|
SkRect fClip;
|
|
SkIPoint* fPoints;
|
|
SkPath fPath;
|
|
int fPtCount;
|
|
|
|
typedef SampleView INHERITED;
|
|
};
|
|
|
|
//////////////////////////////////////////////////////////////////////////////
|
|
|
|
static SkView* MyFactory() { return new CullView; }
|
|
static SkViewRegister reg(MyFactory);
|
|
|