skia2/forth/SampleForth.cpp

254 lines
6.5 KiB
C++
Raw Normal View History

#include "SampleCode.h"
#include "SkColorPriv.h"
#include "SkGradientShader.h"
#include "SkView.h"
#include "SkCanvas.h"
#include "SkUtils.h"
#include "Forth.h"
class MyOutput : public ForthOutput {
public:
SkString fStr;
virtual void show(const char text[]) {
fStr.set(text);
}
};
class SkForthCtx {
public:
SkCanvas fCanvas;
SkPaint fPaint;
void init(const SkBitmap& bm) {
fCanvas.setBitmapDevice(bm);
fPaint.setAntiAlias(true);
}
};
class SkForthCtx_FW : public ForthWord {
public:
SkForthCtx_FW() : fCtx(NULL) {}
void setCtx(SkForthCtx* ctx) { fCtx = ctx; }
SkCanvas* canvas() const { return &fCtx->fCanvas; }
SkPaint* paint() const { return &fCtx->fPaint; }
private:
SkForthCtx* fCtx;
};
class setColor_FW : public SkForthCtx_FW {
public:
virtual void exec(ForthEngine* fe) {
paint()->setColor(fe->pop());
}
static SkForthCtx_FW* New() { return new setColor_FW; }
};
class setStyle_FW : public SkForthCtx_FW {
public:
virtual void exec(ForthEngine* fe) {
paint()->setStyle((SkPaint::Style)fe->pop());
}
static SkForthCtx_FW* New() { return new setStyle_FW; }
};
class setStrokeWidth_FW : public SkForthCtx_FW {
public:
virtual void exec(ForthEngine* fe) {
paint()->setStrokeWidth(fe->fpop());
}
static SkForthCtx_FW* New() { return new setStrokeWidth_FW; }
};
class translate_FW : public SkForthCtx_FW {
public:
virtual void exec(ForthEngine* fe) {
SkScalar dy = fe->fpop();
SkScalar dx = fe->fpop();
canvas()->translate(dx, dy);
}
static SkForthCtx_FW* New() { return new translate_FW; }
};
class drawColor_FW : public SkForthCtx_FW {
public:
virtual void exec(ForthEngine* fe) {
canvas()->drawColor(fe->pop());
}
static SkForthCtx_FW* New() { return new drawColor_FW; }
};
class drawRect_FW : public SkForthCtx_FW {
public:
virtual void exec(ForthEngine* fe) {
SkRect r;
r.fBottom = fe->fpop();
r.fRight = fe->fpop();
r.fTop = fe->fpop();
r.fLeft = fe->fpop();
canvas()->drawRect(r, *paint());
}
static SkForthCtx_FW* New() { return new drawRect_FW; }
};
class drawCircle_FW : public SkForthCtx_FW {
public:
virtual void exec(ForthEngine* fe) {
SkScalar radius = fe->fpop();
SkScalar y = fe->fpop();
SkScalar x = fe->fpop();
canvas()->drawCircle(x, y, radius, *paint());
}
static SkForthCtx_FW* New() { return new drawCircle_FW; }
};
class drawLine_FW : public SkForthCtx_FW {
public:
virtual void exec(ForthEngine* fe) {
SkScalar x0, y0, x1, y1;
y1 = fe->fpop();
x1 = fe->fpop();
y0 = fe->fpop();
x0 = fe->fpop();
canvas()->drawLine(x0, y0, x1, y1, *paint());
}
static SkForthCtx_FW* New() { return new drawLine_FW; }
};
static const struct {
const char* fName;
SkForthCtx_FW* (*fProc)();
} gWordRecs[] = {
{ "setColor", setColor_FW::New },
{ "setStyle", setStyle_FW::New },
{ "setStrokeWidth", setStrokeWidth_FW::New },
{ "translate", translate_FW::New },
{ "drawColor", drawColor_FW::New },
{ "drawRect", drawRect_FW::New },
{ "drawCircle", drawCircle_FW::New },
{ "drawLine", drawLine_FW::New },
};
static void load_words(ForthEnv* env, SkForthCtx* ctx) {
for (size_t i = 0; i < SK_ARRAY_COUNT(gWordRecs); i++) {
SkForthCtx_FW* word = gWordRecs[i].fProc();
word->setCtx(ctx);
env->addWord(gWordRecs[i].fName, word);
}
}
///////////////////////////////////////////////////////////////////////////////
void Forth_test_stdwords(bool verbose);
class ForthView : public SkView {
ForthEnv fEnv;
ForthWord* fOnClickWord;
SkBitmap fBM;
SkForthCtx fContext;
public:
ForthView() {
Forth_test_stdwords(false);
load_words(&fEnv, &fContext);
fBM.setConfig(SkBitmap::kARGB_8888_Config, 640, 480);
fBM.allocPixels();
fBM.eraseColor(0);
fContext.init(fBM);
fEnv.parse(": mycolor ( x. y. -- x. y. ) OVER OVER f< IF #FFFF0000 ELSE #FF0000FF THEN setColor ;");
fEnv.parse(": view.onClick ( x. y. -- ) mycolor 10. drawCircle ;");
fOnClickWord = fEnv.findWord("view.onClick");
#if 0
env.parse(
": draw1 "
"10. setStrokeWidth 1 setStyle #FF000000 setColor "
"10. 20. 200. 100. drawLine "
"0 setStyle #80FF0000 setColor "
"50. 50. 250. 150. drawRect "
";");
env.parse("#FF0000FF drawColor "
"draw1 "
"150. 120. translate "
"draw1 "
);
#endif
}
protected:
// overrides from SkEventSink
virtual bool onQuery(SkEvent* evt) {
if (SampleCode::TitleQ(*evt)) {
SampleCode::TitleR(evt, "Forth");
return true;
}
return this->INHERITED::onQuery(evt);
}
void drawBG(SkCanvas* canvas) {
canvas->drawColor(0xFFDDDDDD);
}
void test_onClick(ForthEnv* env) {
ForthWord* word = env->findWord("view.onClick");
if (word) {
const intptr_t idata[2] = { 40, 2 };
intptr_t odata[1] = { -1 };
ForthCallBlock block;
block.in_data = idata;
block.in_count = 2;
block.out_data = odata;
block.out_count = 1;
word->call(&block);
SkDebugf("after view.onClick depth %d count %d top %d\n",
block.out_depth, block.out_count, odata[0]);
} else {
SkDebugf("------ view.onClick not found\n");
}
}
virtual void onDraw(SkCanvas* canvas) {
drawBG(canvas);
canvas->drawBitmap(fBM, 0, 0, NULL);
}
virtual SkView::Click* onFindClickHandler(SkScalar x, SkScalar y) {
return fOnClickWord ? new Click(this) : NULL;
}
virtual bool onClick(Click* click) {
intptr_t idata[2] = {
f2i_bits(click->fCurr.fX), f2i_bits(click->fCurr.fY)
};
ForthCallBlock block;
block.in_data = idata;
block.in_count = 2;
block.out_count = 0;
fOnClickWord->call(&block);
this->inval(NULL);
return true;
}
private:
typedef SkView INHERITED;
};
//////////////////////////////////////////////////////////////////////////////
static SkView* MyFactory() { return new ForthView; }
static SkViewRegister reg(MyFactory);