diff options
-rw-r--r-- | Makefile | 13 | ||||
-rw-r--r-- | gm/gm.h | 11 | ||||
-rw-r--r-- | gm/gmmain.cpp | 30 | ||||
-rw-r--r-- | gm/xfermodes.cpp | 172 |
4 files changed, 219 insertions, 7 deletions
@@ -131,6 +131,18 @@ skimage: $(SKIMAGE_OBJS) out/libskia.a ############################################################################## +GM_SRCS := gmmain.cpp xfermodes.cpp +GM_SRCS := $(addprefix gm/, $(GM_SRCS)) + +GM_OBJS := $(GM_SRCS:.cpp=.o) +GM_OBJS := $(addprefix out/, $(GM_OBJS)) + +gm: $(GM_OBJS) out/libskia.a + @echo "linking gm..." + $(HIDE)g++ $(GM_OBJS) out/libskia.a -o out/gm/gm $(LINKER_OPTS) + +############################################################################## + .PHONY: clean clean: $(HIDE)rm -rf out @@ -140,6 +152,7 @@ help: @echo "Targets:" @echo " <default>: out/libskia.a" @echo " bench: out/bench/bench" + @echo " gm: out/gm/gm" @echo " skimage: out/tools/skimage" @echo " tests: out/tests/tests" @echo " clean: removes entire out/ directory" @@ -1,11 +1,20 @@ #ifndef skiagm_DEFINED #define skiagm_DEFINED +#include "SkCanvas.h" +#include "SkPaint.h" #include "SkRefCnt.h" +#include "SkSize.h" #include "SkString.h" #include "SkTRegistry.h" namespace skiagm { + + static SkISize make_isize(int w, int h) { + SkISize sz; + sz.set(w, h); + return sz; + } class GM { public: @@ -13,9 +22,11 @@ namespace skiagm { virtual ~GM(); void draw(SkCanvas*); + SkISize getISize() { return this->onISize(); } protected: virtual void onDraw(SkCanvas*) {} + virtual SkISize onISize() { return make_isize(0, 0); } }; typedef SkTRegistry<GM*, void*> GMRegistry; diff --git a/gm/gmmain.cpp b/gm/gmmain.cpp index 22341882ac..24178817e7 100644 --- a/gm/gmmain.cpp +++ b/gm/gmmain.cpp @@ -9,20 +9,20 @@ template GMRegistry* GMRegistry::gHead; class Iter { public: Iter() { - fReg = TestRegistry::Head(); + fReg = GMRegistry::Head(); } - Test* next() { + GM* next() { if (fReg) { - TestRegistry::Factory fact = fReg->factory(); + GMRegistry::Factory fact = fReg->factory(); fReg = fReg->next(); - return fact(); + return fact(0); } return NULL; } static int Count() { - const TestRegistry* reg = TestRegistry::Head(); + const GMRegistry* reg = GMRegistry::Head(); int count = 0; while (reg) { count += 1; @@ -64,23 +64,39 @@ int main (int argc, char * const argv[]) { while ((gm = iter.next()) != NULL) { SkISize size = gm->getISize(); + SkDebugf("---- gm %p [%d %d]\n", gm, size.width(), size.height()); SkBitmap bitmap; - for (size_t i = 0; i < SK_ARRAY_COUNT(gConfigs); i++) { + for (size_t i = 0; i < SK_ARRAY_COUNT(gRec); i++) { bitmap.setConfig(gRec[i].fConfig, size.width(), size.height()); bitmap.allocPixels(); bitmap.eraseColor(0); SkCanvas canvas(bitmap); + SkDebugf("------- drawing to %s config\n", gRec[i].fName); gm->draw(&canvas); - +#if 0 if (gRec[i].fUsePicture) { SkPicture picture; gm->draw(picture.beginRecording(size.width(), size.height(), 0)); canvas.drawPicture(picture); } else { } +#endif } SkDELETE(gm); } return 0; } + +/////////////////////////////////////////////////////////////////////////////// + +using namespace skiagm; + +GM::GM() {} +GM::~GM() {} + +void GM::draw(SkCanvas* canvas) { + this->onDraw(canvas); +} + + diff --git a/gm/xfermodes.cpp b/gm/xfermodes.cpp new file mode 100644 index 0000000000..18b0bbbf43 --- /dev/null +++ b/gm/xfermodes.cpp @@ -0,0 +1,172 @@ +#include "gm.h" +#include "SkBitmap.h" +#include "SkShader.h" +#include "SkXfermode.h" + +namespace skiagm { + +static void make_bitmaps(int w, int h, SkBitmap* src, SkBitmap* dst) { + src->setConfig(SkBitmap::kARGB_8888_Config, w, h); + src->allocPixels(); + src->eraseColor(0); + + SkCanvas c(*src); + SkPaint p; + SkRect r; + SkScalar ww = SkIntToScalar(w); + SkScalar hh = SkIntToScalar(h); + + p.setAntiAlias(true); + p.setColor(0xFFFFCC44); + r.set(0, 0, ww*3/4, hh*3/4); + c.drawOval(r, p); + + dst->setConfig(SkBitmap::kARGB_8888_Config, w, h); + dst->allocPixels(); + dst->eraseColor(0); + c.setBitmapDevice(*dst); + + p.setColor(0xFF66AAFF); + r.set(ww/3, hh/3, ww*19/20, hh*19/20); + c.drawRect(r, p); +} + +static uint16_t gBG[] = { 0xFFFF, 0xCCCF, 0xCCCF, 0xFFFF }; + +class XfermodesGM : public GM { + SkBitmap fBitmap; + SkBitmap fBG; + SkBitmap fSrcB, fDstB; + + void draw_mode(SkCanvas* canvas, SkXfermode* mode, int alpha) { + SkPaint p; + + canvas->drawBitmap(fSrcB, 0, 0, &p); + p.setAlpha(alpha); + p.setXfermode(mode); + canvas->drawBitmap(fDstB, 0, 0, &p); + } + +public: + XfermodesGM() { + const int W = 64; + const int H = 64; + + fBitmap.setConfig(SkBitmap::kARGB_8888_Config, W, H); + fBitmap.allocPixels(); + + fBG.setConfig(SkBitmap::kARGB_4444_Config, 2, 2, 4); + fBG.setPixels(gBG); + fBG.setIsOpaque(true); + + make_bitmaps(W, H, &fSrcB, &fDstB); + } + +protected: + SkISize onISize() { return make_isize(400, 250); } + + void drawBG(SkCanvas* canvas) { + canvas->drawColor(SK_ColorWHITE); + return; + SkShader* s = SkShader::CreateBitmapShader(fBG, + SkShader::kRepeat_TileMode, + SkShader::kRepeat_TileMode); + SkPaint p; + SkMatrix m; + + p.setShader(s)->unref(); + m.setScale(SkIntToScalar(8), SkIntToScalar(8)); + s->setLocalMatrix(m); + canvas->drawPaint(p); + } + + virtual void onDraw(SkCanvas* canvas) { + this->drawBG(canvas); + + const struct { + SkPorterDuff::Mode fMode; + const char* fLabel; + } gModes[] = { + { SkPorterDuff::kClear_Mode, "Clear" }, + { SkPorterDuff::kSrc_Mode, "Src" }, + { SkPorterDuff::kDst_Mode, "Dst" }, + { SkPorterDuff::kSrcOver_Mode, "SrcOver" }, + { SkPorterDuff::kDstOver_Mode, "DstOver" }, + { SkPorterDuff::kSrcIn_Mode, "SrcIn" }, + { SkPorterDuff::kDstIn_Mode, "DstIn" }, + { SkPorterDuff::kSrcOut_Mode, "SrcOut" }, + { SkPorterDuff::kDstOut_Mode, "DstOut" }, + { SkPorterDuff::kSrcATop_Mode, "SrcATop" }, + { SkPorterDuff::kDstATop_Mode, "DstATop" }, + { SkPorterDuff::kXor_Mode, "Xor" }, + { SkPorterDuff::kDarken_Mode, "Darken" }, + { SkPorterDuff::kLighten_Mode, "Lighten" }, + { SkPorterDuff::kMultiply_Mode, "Multiply" }, + { SkPorterDuff::kScreen_Mode, "Screen" } + }; + + canvas->translate(SkIntToScalar(10), SkIntToScalar(20)); + + SkCanvas c(fBitmap); + const SkScalar w = SkIntToScalar(fBitmap.width()); + const SkScalar h = SkIntToScalar(fBitmap.height()); + SkShader* s = SkShader::CreateBitmapShader(fBG, + SkShader::kRepeat_TileMode, + SkShader::kRepeat_TileMode); + SkMatrix m; + m.setScale(SkIntToScalar(6), SkIntToScalar(6)); + s->setLocalMatrix(m); + + SkPaint labelP; + labelP.setAntiAlias(true); + labelP.setTextAlign(SkPaint::kCenter_Align); + + SkScalar x0 = 0; + for (int twice = 0; twice < 2; twice++) { + SkScalar x = x0, y = 0; + for (size_t i = 0; i < SK_ARRAY_COUNT(gModes); i++) { + SkXfermode* mode = SkPorterDuff::CreateXfermode(gModes[i].fMode); + + fBitmap.eraseColor(0); + draw_mode(&c, mode, twice ? 0x88 : 0xFF); + mode->safeUnref(); + + SkPaint p; + SkRect r; + r.set(x, y, x+w, y+h); + r.inset(-SK_ScalarHalf, -SK_ScalarHalf); + p.setStyle(SkPaint::kStroke_Style); + canvas->drawRect(r, p); + p.setStyle(SkPaint::kFill_Style); + p.setShader(s); + r.inset(SK_ScalarHalf, SK_ScalarHalf); + canvas->drawRect(r, p); + + canvas->drawBitmap(fBitmap, x, y, NULL); + +#if 1 + canvas->drawText(gModes[i].fLabel, strlen(gModes[i].fLabel), + x + w/2, y - labelP.getTextSize()/2, labelP); +#endif + x += w + SkIntToScalar(10); + if ((i & 3) == 3) { + x = x0; + y += h + SkIntToScalar(30); + } + } + x0 += SkIntToScalar(330); + } + s->unref(); + } + +private: + typedef GM INHERITED; +}; + +////////////////////////////////////////////////////////////////////////////// + +static GM* MyFactory(void*) { return new XfermodesGM; } +static GMRegistry reg(MyFactory); + +} + |