diff options
Diffstat (limited to 'gm')
-rw-r--r-- | gm/Android.mk | 9 | ||||
-rw-r--r-- | gm/blurs.cpp | 92 | ||||
-rw-r--r-- | gm/gm_files.mk | 4 | ||||
-rw-r--r-- | gm/gmmain.cpp | 190 | ||||
-rw-r--r-- | gm/gradients.cpp | 21 | ||||
-rw-r--r-- | gm/points.cpp | 67 | ||||
-rw-r--r-- | gm/poly2poly.cpp | 108 | ||||
-rw-r--r-- | gm/shadertext.cpp | 198 | ||||
-rw-r--r-- | gm/shapes.cpp | 33 | ||||
-rw-r--r-- | gm/xfermodes.cpp | 70 |
10 files changed, 696 insertions, 96 deletions
diff --git a/gm/Android.mk b/gm/Android.mk index 6ce1dae..6861e16 100644 --- a/gm/Android.mk +++ b/gm/Android.mk @@ -4,7 +4,7 @@ include $(CLEAR_VARS) LOCAL_SRC_FILES := \ filltypes.cpp \ - gradients.cpp \ + gradients.cpp \ tilemodes.cpp \ bitmapfilters.cpp \ xfermodes.cpp \ @@ -12,7 +12,8 @@ LOCAL_SRC_FILES := \ # additional optional class for this tool LOCAL_SRC_FILES += \ - ../src/utils/SkUnitMappers.cpp + ../src/utils/SkUnitMappers.cpp \ + ../src/utils/SkEGLContext_none.cpp LOCAL_SHARED_LIBRARIES := libcutils libskia LOCAL_C_INCLUDES := \ @@ -20,7 +21,9 @@ LOCAL_C_INCLUDES := \ external/skia/include/core \ external/skia/include/images \ external/skia/include/utils \ - external/skia/include/effects + external/skia/include/effects \ + external/skia/gpu/include \ + external/skia/include/gpu #LOCAL_CFLAGS := diff --git a/gm/blurs.cpp b/gm/blurs.cpp new file mode 100644 index 0000000..8250d76 --- /dev/null +++ b/gm/blurs.cpp @@ -0,0 +1,92 @@ +#include "gm.h" +#include "SkBlurMaskFilter.h" + +namespace skiagm { + +class BlursGM : public GM { +public: + BlursGM() {} + +protected: + virtual SkString onShortName() { + return SkString("blurs"); + } + + virtual SkISize onISize() { + return make_isize(700, 500); + } + + void drawBG(SkCanvas* canvas) { + canvas->drawColor(0xFFDDDDDD); + } + + virtual void onDraw(SkCanvas* canvas) { + drawBG(canvas); + + SkBlurMaskFilter::BlurStyle NONE = SkBlurMaskFilter::BlurStyle(-999); + static const struct { + SkBlurMaskFilter::BlurStyle fStyle; + int fCx, fCy; + } gRecs[] = { + { NONE, 0, 0 }, + { SkBlurMaskFilter::kInner_BlurStyle, -1, 0 }, + { SkBlurMaskFilter::kNormal_BlurStyle, 0, 1 }, + { SkBlurMaskFilter::kSolid_BlurStyle, 0, -1 }, + { SkBlurMaskFilter::kOuter_BlurStyle, 1, 0 }, + }; + + SkPaint paint; + paint.setAntiAlias(true); + paint.setTextSize(25); + canvas->translate(-40, 0); + + SkBlurMaskFilter::BlurFlags flags = SkBlurMaskFilter::kNone_BlurFlag; + for (int j = 0; j < 2; j++) { + canvas->save(); + paint.setColor(SK_ColorBLUE); + for (size_t i = 0; i < SK_ARRAY_COUNT(gRecs); i++) { + if (gRecs[i].fStyle != NONE) { + SkMaskFilter* mf = SkBlurMaskFilter::Create(20, + gRecs[i].fStyle, + flags); + paint.setMaskFilter(mf)->unref(); + } else { + paint.setMaskFilter(NULL); + } + canvas->drawCircle(200 + gRecs[i].fCx*100, + 200 + gRecs[i].fCy*100, 50, paint); + } + // draw text + { + SkMaskFilter* mf = SkBlurMaskFilter::Create(4, + SkBlurMaskFilter::kNormal_BlurStyle, + flags); + paint.setMaskFilter(mf)->unref(); + SkScalar x = SkIntToScalar(70); + SkScalar y = SkIntToScalar(400); + paint.setColor(SK_ColorBLACK); + canvas->drawText("Hamburgefons Style", 18, x, y, paint); + canvas->drawText("Hamburgefons Style", 18, x, y + SkIntToScalar(50), paint); + paint.setMaskFilter(NULL); + paint.setColor(SK_ColorWHITE); + x -= SkIntToScalar(2); + y -= SkIntToScalar(2); + canvas->drawText("Hamburgefons Style", 18, x, y, paint); + } + canvas->restore(); +// flags = SkBlurMaskFilter::kHighQuality_BlurFlag; + canvas->translate(350, 0); + } + } + +private: + typedef GM INHERITED; +}; + +////////////////////////////////////////////////////////////////////////////// + +static GM* MyFactory(void*) { return new BlursGM; } +static GMRegistry reg(MyFactory); + +} + diff --git a/gm/gm_files.mk b/gm/gm_files.mk index 50eb311..2f7769e 100644 --- a/gm/gm_files.mk +++ b/gm/gm_files.mk @@ -1,8 +1,12 @@ SOURCE := \ bitmapfilters.cpp \ + blurs.cpp \ filltypes.cpp \ gradients.cpp \ + points.cpp \ + poly2poly.cpp \ shapes.cpp \ tilemodes.cpp \ xfermodes.cpp \ + shadertext.cpp \ gmmain.cpp diff --git a/gm/gmmain.cpp b/gm/gmmain.cpp index 59f6c64..357a54e 100644 --- a/gm/gmmain.cpp +++ b/gm/gmmain.cpp @@ -3,6 +3,19 @@ #include "SkGraphics.h" #include "SkImageDecoder.h" #include "SkImageEncoder.h" +#include "SkStream.h" +#include "SkRefCnt.h" + +#include "GrContext.h" +#include "SkGpuCanvas.h" +#include "SkGpuDevice.h" +#include "SkEGLContext.h" +#include "SkDevice.h" + +#ifdef SK_SUPPORT_PDF + #include "SkPDFDevice.h" + #include "SkPDFDocument.h" +#endif using namespace skiagm; @@ -14,7 +27,7 @@ public: Iter() { fReg = GMRegistry::Head(); } - + GM* next() { if (fReg) { GMRegistry::Factory fact = fReg->factory(); @@ -23,7 +36,7 @@ public: } return NULL; } - + static int Count() { const GMRegistry* reg = GMRegistry::Head(); int count = 0; @@ -33,7 +46,7 @@ public: } return count; } - + private: const GMRegistry* fReg; }; @@ -44,12 +57,12 @@ static SkString make_name(const char shortName[], const char configName[]) { return name; } -static SkString make_filename(const char path[], const SkString& name) { +static SkString make_filename(const char path[], const SkString& name, const char suffix[]) { SkString filename(path); if (filename.size() && filename[filename.size() - 1] != '/') { filename.append("/"); } - filename.appendf("%s.png", name.c_str()); + filename.appendf("%s.%s", name.c_str(), suffix); return filename; } @@ -74,8 +87,34 @@ static bool write_bitmap(const SkString& path, const SkBitmap& bitmap) { SkImageEncoder::kPNG_Type, 100); } -static void compare(const SkBitmap& target, const SkBitmap& base, - const SkString& name) { +static inline SkPMColor compute_diff_pmcolor(SkPMColor c0, SkPMColor c1) { + int dr = SkGetPackedR32(c0) - SkGetPackedR32(c1); + int dg = SkGetPackedG32(c0) - SkGetPackedG32(c1); + int db = SkGetPackedB32(c0) - SkGetPackedB32(c1); + return SkPackARGB32(0xFF, SkAbs32(dr), SkAbs32(dg), SkAbs32(db)); +} + +static void compute_diff(const SkBitmap& target, const SkBitmap& base, + SkBitmap* diff) { + SkAutoLockPixels alp(*diff); + + const int w = target.width(); + const int h = target.height(); + for (int y = 0; y < h; y++) { + for (int x = 0; x < w; x++) { + SkPMColor c0 = *base.getAddr32(x, y); + SkPMColor c1 = *target.getAddr32(x, y); + SkPMColor d = 0; + if (c0 != c1) { + d = compute_diff_pmcolor(c0, c1); + } + *diff->getAddr32(x, y) = d; + } + } +} + +static bool compare(const SkBitmap& target, const SkBitmap& base, + const SkString& name, SkBitmap* diff) { SkBitmap copy; const SkBitmap* bm = ⌖ if (target.config() != SkBitmap::kARGB_8888_Config) { @@ -90,7 +129,7 @@ static void compare(const SkBitmap& target, const SkBitmap& base, if (w != base.width() || h != base.height()) { SkDebugf("---- dimensions mismatch for %s base [%d %d] current [%d %d]\n", name.c_str(), base.width(), base.height(), w, h); - return; + return false; } SkAutoLockPixels bmLock(*bm); @@ -103,27 +142,52 @@ static void compare(const SkBitmap& target, const SkBitmap& base, if (c0 != c1) { SkDebugf("----- pixel mismatch for %s at [%d %d] base 0x%08X current 0x%08X\n", name.c_str(), x, y, c0, c1); - return; + + if (diff) { + diff->setConfig(SkBitmap::kARGB_8888_Config, w, h); + diff->allocPixels(); + compute_diff(*bm, base, diff); + } + return false; } } } + + // they're equal + return true; +} + +static bool write_pdf(const SkString& path, const SkDynamicMemoryWStream& pdf) { + SkFILEWStream stream(path.c_str()); + return stream.write(pdf.getStream(), pdf.getOffset()); } +enum Backend { + kRaster_Backend, + kGPU_Backend, + kPDF_Backend, +}; + static const struct { SkBitmap::Config fConfig; - bool fUsePicture; + Backend fBackend; const char* fName; } gRec[] = { - { SkBitmap::kARGB_8888_Config, false, "8888" }, - { SkBitmap::kARGB_4444_Config, false, "4444" }, - { SkBitmap::kRGB_565_Config, false, "565" }, + { SkBitmap::kARGB_8888_Config, kRaster_Backend, "8888" }, + { SkBitmap::kARGB_4444_Config, kRaster_Backend, "4444" }, + { SkBitmap::kRGB_565_Config, kRaster_Backend, "565" }, + { SkBitmap::kARGB_8888_Config, kGPU_Backend, "gpu" }, +#ifdef SK_SUPPORT_PDF + { SkBitmap::kARGB_8888_Config, kPDF_Backend, "pdf" }, +#endif }; int main (int argc, char * const argv[]) { SkAutoGraphics ag; - + const char* writePath = NULL; // if non-null, where we write the originals const char* readPath = NULL; // if non-null, were we read from to compare + const char* diffPath = NULL; // if non-null, where we write our diffs (from compare) char* const* stop = argv + argc; for (++argv; argv < stop; ++argv) { @@ -137,42 +201,106 @@ int main (int argc, char * const argv[]) { if (argv < stop && **argv) { readPath = *argv; } - } + } else if (strcmp(*argv, "-d") == 0) { + argv++; + if (argv < stop && **argv) { + diffPath = *argv; + } + } + } + + // setup a GL context for drawing offscreen + GrContext* context = NULL; + SkEGLContext eglContext; + if (eglContext.init(1024, 1024)) { + context = GrContext::CreateGLShaderContext(); } - + Iter iter; GM* gm; - + + if (readPath) { + fprintf(stderr, "reading from %s\n", readPath); + } else if (writePath) { + fprintf(stderr, "writing to %s\n", writePath); + } + while ((gm = iter.next()) != NULL) { SkISize size = gm->getISize(); - SkDebugf("creating... %s [%d %d]\n", gm->shortName(), + SkDebugf("drawing... %s [%d %d]\n", gm->shortName(), size.width(), size.height()); SkBitmap bitmap; + SkDynamicMemoryWStream pdf; 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); + if (gRec[i].fBackend == kRaster_Backend || + gRec[i].fBackend == kGPU_Backend) { + bitmap.setConfig(gRec[i].fConfig, size.width(), size.height()); + bitmap.allocPixels(); + bitmap.eraseColor(0); + SkCanvas canvas(bitmap); + + if (gRec[i].fBackend == kRaster_Backend) { + gm->draw(&canvas); + } else { // GPU + if (NULL == context) { + continue; + } + SkGpuCanvas gc(context, + SkGpuDevice::Current3DApiRenderTarget()); + gc.setDevice(gc.createDevice(bitmap.config(), + bitmap.width(), + bitmap.height(), + bitmap.isOpaque(), + false))->unref(); + gm->draw(&gc); + gc.readPixels(&bitmap); // overwrite our previous allocation + } + } + // TODO: Figure out a way to compare PDFs. + if (gRec[i].fBackend == kPDF_Backend && writePath) { +#ifdef SK_SUPPORT_PDF + SkISize size = gm->getISize(); + SkPDFDevice* dev = new SkPDFDevice(size.width(), size.height()); + SkAutoUnref aur(dev); + + SkCanvas c(dev); + gm->draw(&c); - gm->draw(&canvas); - + SkPDFDocument doc; + doc.appendPage(dev); + doc.emitPDF(&pdf); +#endif + } SkString name = make_name(gm->shortName(), gRec[i].fName); if (writePath) { - SkString path = make_filename(writePath, name); - bool success = write_bitmap(path, bitmap); - if (!success) { - fprintf(stderr, "FAILED to write %s\n", path.c_str()); + SkString path; + bool success; + if (gRec[i].fBackend != kPDF_Backend) { + path = make_filename(writePath, name, "png"); + success = write_bitmap(path, bitmap); + } else { + path = make_filename(writePath, name, "pdf"); + success = write_pdf(path, pdf); } - } else if (readPath) { - SkString path = make_filename(readPath, name); + if (!success) + fprintf(stderr, "FAILED to write %s\n", path.c_str()); + // TODO: Figure out a way to compare PDFs. + } else if (readPath && gRec[i].fBackend != kPDF_Backend) { + SkString path = make_filename(readPath, name, "png"); SkBitmap orig; bool success = SkImageDecoder::DecodeFile(path.c_str(), &orig, SkBitmap::kARGB_8888_Config, SkImageDecoder::kDecodePixels_Mode, NULL); if (success) { - compare(bitmap, orig, name); + SkBitmap diffBitmap; + success = compare(bitmap, orig, name, diffPath ? &diffBitmap : NULL); + if (!success && diffPath) { + SkString diffName = make_filename(diffPath, name, ".diff.png"); + fprintf(stderr, "Writing %s\n", diffName.c_str()); + write_bitmap(diffName, diffBitmap); + } } else { fprintf(stderr, "FAILED to read %s\n", path.c_str()); } diff --git a/gm/gradients.cpp b/gm/gradients.cpp index aed4e0b..26eee9d 100644 --- a/gm/gradients.cpp +++ b/gm/gradients.cpp @@ -31,7 +31,7 @@ static SkShader* MakeLinear(const SkPoint pts[2], const GradData& data, return SkGradientShader::CreateLinear(pts, data.fColors, data.fPos, data.fCount, tm, mapper); } - + static SkShader* MakeRadial(const SkPoint pts[2], const GradData& data, SkShader::TileMode tm, SkUnitMapper* mapper) { SkPoint center; @@ -50,10 +50,23 @@ static SkShader* MakeSweep(const SkPoint pts[2], const GradData& data, data.fPos, data.fCount, mapper); } +static SkShader* Make2Radial(const SkPoint pts[2], const GradData& data, + SkShader::TileMode tm, SkUnitMapper* mapper) { + SkPoint center0, center1; + center0.set(SkScalarAve(pts[0].fX, pts[1].fX), + SkScalarAve(pts[0].fY, pts[1].fY)); + center1.set(SkScalarInterp(pts[0].fX, pts[1].fX, SkIntToScalar(3)/5), + SkScalarInterp(pts[0].fY, pts[1].fY, SkIntToScalar(1)/4)); + return SkGradientShader::CreateTwoPointRadial( + center1, (pts[1].fX - pts[0].fX) / 7, + center0, (pts[1].fX - pts[0].fX) / 2, + data.fColors, data.fPos, data.fCount, tm, mapper); +} + typedef SkShader* (*GradMaker)(const SkPoint pts[2], const GradData& data, - SkShader::TileMode tm, SkUnitMapper* mapper); + SkShader::TileMode tm, SkUnitMapper* mapper); static const GradMaker gGradMakers[] = { - MakeLinear, MakeRadial, MakeSweep + MakeLinear, MakeRadial, MakeSweep, Make2Radial }; /////////////////////////////////////////////////////////////////////////////// @@ -67,7 +80,7 @@ protected: return SkString("gradients"); } - SkISize onISize() { return make_isize(640, 380); } + SkISize onISize() { return make_isize(640, 510); } void drawBG(SkCanvas* canvas) { canvas->drawColor(0xFFDDDDDD); diff --git a/gm/points.cpp b/gm/points.cpp new file mode 100644 index 0000000..48d8fec --- /dev/null +++ b/gm/points.cpp @@ -0,0 +1,67 @@ +#include "gm.h" +#include "SkRandom.h" + +namespace skiagm { + +class PointsGM : public GM { +public: + PointsGM() {} + +protected: + virtual SkString onShortName() { + return SkString("points"); + } + + virtual SkISize onISize() { + return make_isize(640, 490); + } + + void drawBG(SkCanvas* canvas) { + canvas->drawColor(SK_ColorWHITE); + } + + static void fill_pts(SkPoint pts[], size_t n, SkRandom* rand) { + for (size_t i = 0; i < n; i++) + pts[i].set(rand->nextUScalar1() * 640, rand->nextUScalar1() * 480); + } + + virtual void onDraw(SkCanvas* canvas) { + this->drawBG(canvas); + + canvas->translate(SK_Scalar1, SK_Scalar1); + + SkRandom rand; + SkPaint p0, p1, p2, p3; + const size_t n = 99; + + p0.setColor(SK_ColorRED); + p1.setColor(SK_ColorGREEN); + p2.setColor(SK_ColorBLUE); + p3.setColor(SK_ColorWHITE); + + p0.setStrokeWidth(SkIntToScalar(4)); + p2.setStrokeCap(SkPaint::kRound_Cap); + p2.setStrokeWidth(SkIntToScalar(6)); + + SkPoint* pts = new SkPoint[n]; + fill_pts(pts, n, &rand); + + canvas->drawPoints(SkCanvas::kPolygon_PointMode, n, pts, p0); + canvas->drawPoints(SkCanvas::kLines_PointMode, n, pts, p1); + canvas->drawPoints(SkCanvas::kPoints_PointMode, n, pts, p2); + canvas->drawPoints(SkCanvas::kPoints_PointMode, n, pts, p3); + + delete[] pts; + } + +private: + typedef GM INHERITED; +}; + +////////////////////////////////////////////////////////////////////////////// + +static GM* MyFactory(void*) { return new PointsGM; } +static GMRegistry reg(MyFactory); + +} + diff --git a/gm/poly2poly.cpp b/gm/poly2poly.cpp new file mode 100644 index 0000000..193ede7 --- /dev/null +++ b/gm/poly2poly.cpp @@ -0,0 +1,108 @@ +#include "gm.h" + +namespace skiagm { + +class Poly2PolyGM : public GM { +public: + Poly2PolyGM() {} + +protected: + virtual SkString onShortName() { + return SkString("poly2poly"); + } + + virtual SkISize onISize() { + return make_isize(835, 840); + } + + void drawBG(SkCanvas* canvas) { + canvas->drawColor(SK_ColorWHITE); + } + + static void doDraw(SkCanvas* canvas, SkPaint* paint, const int isrc[], + const int idst[], int count) { + SkMatrix matrix; + SkPoint src[4], dst[4]; + + for (int i = 0; i < count; i++) { + src[i].set(SkIntToScalar(isrc[2*i+0]), SkIntToScalar(isrc[2*i+1])); + dst[i].set(SkIntToScalar(idst[2*i+0]), SkIntToScalar(idst[2*i+1])); + } + + canvas->save(); + matrix.setPolyToPoly(src, dst, count); + canvas->concat(matrix); + + paint->setColor(SK_ColorGRAY); + paint->setStyle(SkPaint::kStroke_Style); + const SkScalar D = SkIntToScalar(64); + canvas->drawRectCoords(0, 0, D, D, *paint); + canvas->drawLine(0, 0, D, D, *paint); + canvas->drawLine(0, D, D, 0, *paint); + + SkPaint::FontMetrics fm; + paint->getFontMetrics(&fm); + paint->setColor(SK_ColorRED); + paint->setStyle(SkPaint::kFill_Style); + SkScalar x = D/2; + float y = D/2 - (fm.fAscent + fm.fDescent)/2; + SkString str; + str.appendS32(count); + canvas->drawText(str.c_str(), str.size(), x, y, *paint); + + canvas->restore(); + } + + virtual void onDraw(SkCanvas* canvas) { + this->drawBG(canvas); + + SkPaint paint; + paint.setAntiAlias(true); + paint.setStrokeWidth(SkIntToScalar(4)); + paint.setTextSize(SkIntToScalar(40)); + paint.setTextAlign(SkPaint::kCenter_Align); + + canvas->save(); + canvas->translate(SkIntToScalar(10), SkIntToScalar(10)); + // translate (1 point) + const int src1[] = { 0, 0 }; + const int dst1[] = { 5, 5 }; + doDraw(canvas, &paint, src1, dst1, 1); + canvas->restore(); + + canvas->save(); + canvas->translate(SkIntToScalar(160), SkIntToScalar(10)); + // rotate/uniform-scale (2 points) + const int src2[] = { 32, 32, 64, 32 }; + const int dst2[] = { 32, 32, 64, 48 }; + doDraw(canvas, &paint, src2, dst2, 2); + canvas->restore(); + + canvas->save(); + canvas->translate(SkIntToScalar(10), SkIntToScalar(110)); + // rotate/skew (3 points) + const int src3[] = { 0, 0, 64, 0, 0, 64 }; + const int dst3[] = { 0, 0, 96, 0, 24, 64 }; + doDraw(canvas, &paint, src3, dst3, 3); + canvas->restore(); + + canvas->save(); + canvas->translate(SkIntToScalar(160), SkIntToScalar(110)); + // perspective (4 points) + const int src4[] = { 0, 0, 64, 0, 64, 64, 0, 64 }; + const int dst4[] = { 0, 0, 96, 0, 64, 96, 0, 64 }; + doDraw(canvas, &paint, src4, dst4, 4); + canvas->restore(); + } + +private: + typedef GM INHERITED; +}; + +////////////////////////////////////////////////////////////////////////////// + +static GM* MyFactory(void*) { return new Poly2PolyGM; } +static GMRegistry reg(MyFactory); + +} + diff --git a/gm/shadertext.cpp b/gm/shadertext.cpp new file mode 100644 index 0000000..1cf562c --- /dev/null +++ b/gm/shadertext.cpp @@ -0,0 +1,198 @@ +#include "gm.h" +#include "SkCanvas.h" +#include "SkGradientShader.h" +#include "SkUnitMappers.h" + +namespace skiagm { + +static void makebm(SkBitmap* bm, SkBitmap::Config config, int w, int h) { + bm->setConfig(config, w, h); + bm->allocPixels(); + bm->eraseColor(0); + + SkCanvas canvas(*bm); + SkScalar s = w < h ? w : h; + SkPoint pts[] = { { 0, 0 }, { s, s } }; + SkColor colors[] = { SK_ColorRED, SK_ColorGREEN, SK_ColorBLUE }; + SkScalar pos[] = { 0, SK_Scalar1/2, SK_Scalar1 }; + SkPaint paint; + + SkUnitMapper* um = NULL; + + um = new SkCosineMapper; + + SkAutoUnref au(um); + + paint.setDither(true); + paint.setShader(SkGradientShader::CreateLinear(pts, colors, pos, + SK_ARRAY_COUNT(colors), SkShader::kClamp_TileMode, um))->unref(); + canvas.drawPaint(paint); +} + +SkShader* MakeBitmapShader(SkShader::TileMode tx, SkShader::TileMode ty, + int w, int h) { + static SkBitmap bmp; + if (bmp.isNull()) { + makebm(&bmp, SkBitmap::kARGB_8888_Config, w/2, h/4); + } + return SkShader::CreateBitmapShader(bmp, tx, ty); +} + +/////////////////////////////////////////////////////////////////////////////// + +struct GradData { + int fCount; + const SkColor* fColors; + const SkScalar* fPos; +}; + +static const SkColor gColors[] = { + SK_ColorRED, SK_ColorGREEN, SK_ColorBLUE, SK_ColorWHITE, SK_ColorBLACK +}; + +static const GradData gGradData[] = { + { 2, gColors, NULL }, + { 5, gColors, NULL }, +}; + +static SkShader* MakeLinear(const SkPoint pts[2], const GradData& data, + SkShader::TileMode tm, SkUnitMapper* mapper) { + return SkGradientShader::CreateLinear(pts, data.fColors, data.fPos, + data.fCount, tm, mapper); +} + +static SkShader* MakeRadial(const SkPoint pts[2], const GradData& data, + SkShader::TileMode tm, SkUnitMapper* mapper) { + SkPoint center; + center.set(SkScalarAve(pts[0].fX, pts[1].fX), + SkScalarAve(pts[0].fY, pts[1].fY)); + return SkGradientShader::CreateRadial(center, center.fX, data.fColors, + data.fPos, data.fCount, tm, mapper); +} + +static SkShader* MakeSweep(const SkPoint pts[2], const GradData& data, + SkShader::TileMode tm, SkUnitMapper* mapper) { + SkPoint center; + center.set(SkScalarAve(pts[0].fX, pts[1].fX), + SkScalarAve(pts[0].fY, pts[1].fY)); + return SkGradientShader::CreateSweep(center.fX, center.fY, data.fColors, + data.fPos, data.fCount, mapper); +} + +static SkShader* Make2Radial(const SkPoint pts[2], const GradData& data, + SkShader::TileMode tm, SkUnitMapper* mapper) { + SkPoint center0, center1; + center0.set(SkScalarAve(pts[0].fX, pts[1].fX), + SkScalarAve(pts[0].fY, pts[1].fY)); + center1.set(SkScalarInterp(pts[0].fX, pts[1].fX, SkIntToScalar(3)/5), + SkScalarInterp(pts[0].fY, pts[1].fY, SkIntToScalar(1)/4)); + return SkGradientShader::CreateTwoPointRadial( + center1, (pts[1].fX - pts[0].fX) / 7, + center0, (pts[1].fX - pts[0].fX) / 2, + data.fColors, data.fPos, data.fCount, tm, mapper); +} + +typedef SkShader* (*GradMaker)(const SkPoint pts[2], const GradData& data, + SkShader::TileMode tm, SkUnitMapper* mapper); +static const GradMaker gGradMakers[] = { + MakeLinear, MakeRadial, MakeSweep, Make2Radial +}; + +/////////////////////////////////////////////////////////////////////////////// + +class ShaderTextGM : public GM { +public: + ShaderTextGM() {} + +protected: + + SkString onShortName() { + return SkString("shadertext"); + } + + SkISize onISize() { return make_isize(950, 500); } + + void drawBG(SkCanvas* canvas) { + canvas->drawColor(0xFFDDDDDD); + } + + virtual void onDraw(SkCanvas* canvas) { + this->drawBG(canvas); + + const char text[] = "Shaded Text"; + const int textLen = SK_ARRAY_COUNT(text) - 1; + static int pointSize = SkIntToScalar(48); + + int w = pointSize * textLen; + int h = pointSize; + + SkPoint pts[2] = { + { 0, 0 }, + { SkIntToScalar(w), SkIntToScalar(h) } + }; + SkScalar textBase = SkIntToScalar(h/2); + + SkShader::TileMode tileModes[] = { + SkShader::kClamp_TileMode, + SkShader::kRepeat_TileMode, + SkShader::kMirror_TileMode + }; + + static const int gradCount = SK_ARRAY_COUNT(gGradData) * + SK_ARRAY_COUNT(gGradMakers); + static const int bmpCount = SK_ARRAY_COUNT(tileModes) * + SK_ARRAY_COUNT(tileModes); + SkShader* shaders[gradCount + bmpCount]; + + int shdIdx = 0; + for (size_t d = 0; d < SK_ARRAY_COUNT(gGradData); ++d) { + for (size_t m = 0; m < SK_ARRAY_COUNT(gGradMakers); ++m) { + shaders[shdIdx++] = gGradMakers[m](pts, + gGradData[d], + SkShader::kClamp_TileMode, + NULL); + } + } + for (size_t tx = 0; tx < SK_ARRAY_COUNT(tileModes); ++tx) { + for (size_t ty = 0; ty < SK_ARRAY_COUNT(tileModes); ++ty) { + shaders[shdIdx++] = MakeBitmapShader(tileModes[tx], + tileModes[ty], + w/8, h); + } + } + + SkPaint paint; + paint.setDither(true); + paint.setAntiAlias(true); + paint.setTextSize(SkIntToScalar(pointSize)); + + canvas->save(); + canvas->translate(SkIntToScalar(20), SkIntToScalar(10)); + + static const int testsPerCol = 8; + static const int rowHeight = 60; + static const int colWidth = 300; + canvas->save(); + for (size_t s = 0; s < SK_ARRAY_COUNT(shaders); s++) { + canvas->save(); + canvas->translate(SkIntToScalar((s / testsPerCol) * colWidth), + SkIntToScalar((s % testsPerCol) * rowHeight)); + paint.setShader(shaders[s])->ref(); + canvas->drawText(text, textLen, 0, textBase, paint); + canvas->restore(); + } + canvas->restore(); + } + +private: + typedef GM INHERITED; +}; + +/////////////////////////////////////////////////////////////////////////////// + +static GM* MyFactory(void*) { return new ShaderTextGM; } +static GMRegistry reg(MyFactory); + +} + + diff --git a/gm/shapes.cpp b/gm/shapes.cpp index b3d4863..324ce7e 100644 --- a/gm/shapes.cpp +++ b/gm/shapes.cpp @@ -53,40 +53,40 @@ public: fGroup.appendShape(make_shape1(), m)->unref(); m.postTranslate(0, SkIntToScalar(120)); fGroup.appendShape(make_shape2(), m)->unref(); - + for (size_t i = 0; i < SK_ARRAY_COUNT(fMatrixRefs); i++) { SkSafeRef(fMatrixRefs[i] = fGroup.getShapeMatrixRef(i)); } } - + virtual ~ShapesGM() { for (size_t i = 0; i < SK_ARRAY_COUNT(fMatrixRefs); i++) { SkSafeUnref(fMatrixRefs[i]); } } - + protected: virtual SkString onShortName() { return SkString("shapes"); } - + virtual SkISize onISize() { return make_isize(380, 480); } - + void drawBG(SkCanvas* canvas) { canvas->drawColor(0xFFDDDDDD); } - + virtual void onDraw(SkCanvas* canvas) { this->drawBG(canvas); - + SkMatrix saveM = *fMatrixRefs[3]; SkScalar c = SkIntToScalar(50); fMatrixRefs[3]->preRotate(SkIntToScalar(30), c, c); - + SkMatrix matrix; - + SkGroupShape* gs = new SkGroupShape; SkAutoUnref aur(gs); gs->appendShape(&fGroup); @@ -96,24 +96,25 @@ protected: matrix.setTranslate(SkIntToScalar(240), 0); matrix.preScale(SK_Scalar1*2, SK_Scalar1*2); gs->appendShape(&fGroup, matrix); - -#if 0 + +#if 0 canvas->drawShape(gs); #else - SkPicture pict; - SkCanvas* cv = pict.beginRecording(1000, 1000); + SkPicture* pict = new SkPicture; + SkCanvas* cv = pict->beginRecording(1000, 1000); cv->scale(SK_ScalarHalf, SK_ScalarHalf); cv->drawShape(gs); cv->translate(SkIntToScalar(680), SkIntToScalar(480)); cv->scale(-SK_Scalar1, SK_Scalar1); cv->drawShape(gs); - pict.endRecording(); - canvas->drawPicture(pict); + pict->endRecording(); + canvas->drawPicture(*pict); + pict->unref(); #endif *fMatrixRefs[3] = saveM; } - + private: typedef GM INHERITED; }; diff --git a/gm/xfermodes.cpp b/gm/xfermodes.cpp index 5a43f4a..d417bfa 100644 --- a/gm/xfermodes.cpp +++ b/gm/xfermodes.cpp @@ -34,27 +34,23 @@ static void make_bitmaps(int w, int h, SkBitmap* src, SkBitmap* dst) { 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) { + void draw_mode(SkCanvas* canvas, SkXfermode* mode, int alpha, + SkScalar x, SkScalar y) { SkPaint p; - canvas->drawBitmap(fSrcB, 0, 0, &p); + canvas->drawBitmap(fSrcB, x, y, &p); p.setAlpha(alpha); p.setXfermode(mode); - canvas->drawBitmap(fDstB, 0, 0, &p); + canvas->drawBitmap(fDstB, x, y, &p); } public: - XfermodesGM() { - const int W = 64; - const int H = 64; - - fBitmap.setConfig(SkBitmap::kARGB_8888_Config, W, H); - fBitmap.allocPixels(); - + const static int W = 64; + const static int H = 64; + XfermodesGM() { fBG.setConfig(SkBitmap::kARGB_4444_Config, 2, 2, 4); fBG.setPixels(gBG); fBG.setIsOpaque(true); @@ -68,29 +64,20 @@ protected: } virtual SkISize onISize() { - return make_isize(790, 480); + return make_isize(790, 640); } 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) { + canvas->translate(SkIntToScalar(10), SkIntToScalar(20)); + this->drawBG(canvas); const struct { - SkXfermode::Mode fMode; + SkXfermode::Mode fMode; const char* fLabel; } gModes[] = { { SkXfermode::kClear_Mode, "Clear" }, @@ -120,11 +107,8 @@ protected: { SkXfermode::kExclusion_Mode, "Exclusion" }, }; - canvas->translate(SkIntToScalar(10), SkIntToScalar(20)); - - SkCanvas c(fBitmap); - const SkScalar w = SkIntToScalar(fBitmap.width()); - const SkScalar h = SkIntToScalar(fBitmap.height()); + const SkScalar w = SkIntToScalar(W); + const SkScalar h = SkIntToScalar(H); SkShader* s = SkShader::CreateBitmapShader(fBG, SkShader::kRepeat_TileMode, SkShader::kRepeat_TileMode); @@ -135,7 +119,7 @@ protected: SkPaint labelP; labelP.setAntiAlias(true); labelP.setTextAlign(SkPaint::kCenter_Align); - + const int W = 5; SkScalar x0 = 0; @@ -143,27 +127,29 @@ protected: SkScalar x = x0, y = 0; for (size_t i = 0; i < SK_ARRAY_COUNT(gModes); i++) { SkXfermode* mode = SkXfermode::Create(gModes[i].fMode); - - fBitmap.eraseColor(0); - draw_mode(&c, mode, twice ? 0x88 : 0xFF); - SkSafeUnref(mode); - - SkPaint p; + SkAutoUnref aur(mode); 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); + + SkPaint 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); + canvas->saveLayer(&r, NULL, SkCanvas::kARGB_ClipLayer_SaveFlag); + // canvas->save(); + draw_mode(canvas, mode, twice ? 0x88 : 0xFF, r.fLeft, r.fTop); + canvas->restore(); + r.inset(-SK_ScalarHalf, -SK_ScalarHalf); + p.setStyle(SkPaint::kStroke_Style); + p.setShader(NULL); + canvas->drawRect(r, p); + +#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 % W) == W - 1) { x = x0; |