aboutsummaryrefslogtreecommitdiffstats
path: root/gm
diff options
context:
space:
mode:
Diffstat (limited to 'gm')
-rw-r--r--gm/Android.mk9
-rw-r--r--gm/blurs.cpp92
-rw-r--r--gm/gm_files.mk4
-rw-r--r--gm/gmmain.cpp190
-rw-r--r--gm/gradients.cpp21
-rw-r--r--gm/points.cpp67
-rw-r--r--gm/poly2poly.cpp108
-rw-r--r--gm/shadertext.cpp198
-rw-r--r--gm/shapes.cpp33
-rw-r--r--gm/xfermodes.cpp70
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 = &target;
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;