249 lines
6.3 KiB
C++
249 lines
6.3 KiB
C++
|
#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);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
///////////////////////////////////////////////////////////////////////////////
|
||
|
|
||
|
class ForthView : public SkView {
|
||
|
ForthEnv fEnv;
|
||
|
ForthWord* fOnClickWord;
|
||
|
|
||
|
SkBitmap fBM;
|
||
|
SkForthCtx fContext;
|
||
|
public:
|
||
|
ForthView() {
|
||
|
load_words(&fEnv, &fContext);
|
||
|
|
||
|
fBM.setConfig(SkBitmap::kARGB_8888_Config, 640, 480);
|
||
|
fBM.allocPixels();
|
||
|
fBM.eraseColor(0);
|
||
|
fContext.init(fBM);
|
||
|
|
||
|
fEnv.parse(": view.onClick ( x y -- ) 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);
|
||
|
|