diff --git a/gm/gm.h b/gm/gm.h index d75a1c17c8..bec29bfa5f 100644 --- a/gm/gm.h +++ b/gm/gm.h @@ -45,7 +45,15 @@ namespace skiagm { uint32_t getFlags() const { return this->onGetFlags(); } - + + // TODO(vandebo) Instead of exposing this, we should run all the GMs + // with and without an initial transform. + // Most GMs will return the identity matrix, but some PDFs tests + // require setting the initial transform. + SkMatrix getInitialTransform() const { + return this->onGetInitialTransform(); + } + SkColor getBGColor() const { return fBGColor; } void setBGColor(SkColor); @@ -65,7 +73,8 @@ namespace skiagm { virtual SkISize onISize() = 0; virtual SkString onShortName() = 0; virtual uint32_t onGetFlags() const { return 0; } - + virtual SkMatrix onGetInitialTransform() const { return SkMatrix::I(); } + private: SkString fShortName; SkColor fBGColor; diff --git a/gm/gmmain.cpp b/gm/gmmain.cpp index 61095e173f..1e63bb6d77 100644 --- a/gm/gmmain.cpp +++ b/gm/gmmain.cpp @@ -264,7 +264,10 @@ static void installFilter(SkCanvas* canvas) { } } -static void invokeGM(GM* gm, SkCanvas* canvas) { +static void invokeGM(GM* gm, SkCanvas* canvas, bool isPDF = false) { + if (!isPDF) { + canvas->setMatrix(gm->getInitialTransform()); + } installFilter(canvas); gm->draw(canvas); canvas->setDrawFilter(NULL); @@ -323,14 +326,26 @@ static void generate_image_from_picture(GM* gm, const ConfigData& gRec, static void generate_pdf(GM* gm, SkDynamicMemoryWStream& pdf) { #ifdef SK_SUPPORT_PDF - SkISize size = gm->getISize(); - SkMatrix identity; - identity.reset(); - SkPDFDevice* dev = new SkPDFDevice(size, size, identity); + SkMatrix initialTransform = gm->getInitialTransform(); + SkISize pageSize = gm->getISize(); + SkPDFDevice* dev = NULL; + if (initialTransform.isIdentity()) { + dev = new SkPDFDevice(pageSize, pageSize, initialTransform); + } else { + SkRect content = SkRect::MakeWH(SkIntToScalar(pageSize.width()), + SkIntToScalar(pageSize.height())); + initialTransform.mapRect(&content); + content.intersect(0, 0, SkIntToScalar(pageSize.width()), + SkIntToScalar(pageSize.height())); + SkISize contentSize = + SkISize::Make(SkScalarRoundToInt(content.width()), + SkScalarRoundToInt(content.height())); + dev = new SkPDFDevice(pageSize, contentSize, initialTransform); + } SkAutoUnref aur(dev); SkCanvas c(dev); - invokeGM(gm, &c); + invokeGM(gm, &c, true); SkPDFDocument doc; doc.appendPage(dev); diff --git a/gm/shaderbounds.cpp b/gm/shaderbounds.cpp new file mode 100644 index 0000000000..d301f6c162 --- /dev/null +++ b/gm/shaderbounds.cpp @@ -0,0 +1,105 @@ +/* + * Copyright 2012 Google Inc. + * + * Use of this source code is governed by a BSD-style license that can be + * found in the LICENSE file. + */ +#include "gm.h" +#include "SkGradientShader.h" + +namespace skiagm { + +static SkShader* MakeLinear(SkScalar width, SkScalar height, bool alternate) { + SkPoint pts[2] = { {0, 0}, {width, height}}; + SkColor colors[2] = {SK_ColorRED, SK_ColorGREEN}; + if (alternate) { + pts[1].fY = 0; + colors[0] = SK_ColorBLUE; + colors[1] = SK_ColorYELLOW; + } + return SkGradientShader::CreateLinear(pts, colors, NULL, 2, + SkShader::kClamp_TileMode, NULL); +} + +/////////////////////////////////////////////////////////////////////////////// + +class ShaderBoundsGM : public GM { +public: + typedef SkShader* (*ShaderGenFunc)(SkScalar width, SkScalar height, + bool alternate); + ShaderBoundsGM(ShaderGenFunc maker, const SkString& name) + : fShaderMaker(maker), + fName(name) { + } + +protected: + SkString onShortName() { + return fName; + } + + virtual SkISize onISize() { return make_isize(320, 240); } + + virtual SkMatrix onGetInitialTransform() const SK_OVERRIDE { + SkMatrix result; + SkScalar scale = SkFloatToScalar(0.8f); + result.setScale(scale, scale); + result.postTranslate(7, 23); + return result; + } + + virtual void onDraw(SkCanvas* canvas) { + // The PDF device has already clipped to the content area, but we + // do it again here so that the raster and pdf results are consistent. + canvas->clipRect(SkRect::MakeWH(320, 240)); + + SkMatrix canvasScale; + SkScalar scale = SkFloatToScalar(0.7f); + canvasScale.setScale(scale, scale); + canvas->concat(canvasScale); + + // Background shader. + SkPaint paint; + paint.setShader(MakeShader(559, 387, false))->unref(); + SkRect r = SkRect::MakeXYWH(SkIntToScalar(-12), SkIntToScalar(-41), + SkIntToScalar(571), SkIntToScalar(428)); + canvas->drawRect(r, paint); + + // Constrained shader. + paint.setShader(MakeShader(101, 151, true))->unref(); + r = SkRect::MakeXYWH(SkIntToScalar(43), SkIntToScalar(71), + SkIntToScalar(101), SkIntToScalar(151)); + canvas->clipRect(r); + canvas->drawRect(r, paint); + } + + SkShader* MakeShader(int width, int height, bool background) { + SkScalar scale = SkFloatToScalar(0.5f); + if (background) { + scale = SkFloatToScalar(0.6f); + } + SkScalar shaderWidth = SkIntToScalar(width)/scale; + SkScalar shaderHeight = SkIntToScalar(height)/scale; + SkShader* shader = fShaderMaker(shaderWidth, shaderHeight, background); + SkMatrix shaderScale; + shaderScale.setScale(scale, scale); + shader->setLocalMatrix(shaderScale); + return shader; + } + +private: + typedef GM INHERITED; + + ShaderGenFunc fShaderMaker; + SkString fName; + + SkShader* MakeShader(bool background); +}; + +/////////////////////////////////////////////////////////////////////////////// + +static GM* MyFactory(void*) { + return new ShaderBoundsGM(MakeLinear, SkString("shaderbounds_linear")); +} +static GMRegistry reg(MyFactory); + +} diff --git a/gyp/gmslides.gypi b/gyp/gmslides.gypi index ec223fb07b..5beac2b787 100644 --- a/gyp/gmslides.gypi +++ b/gyp/gmslides.gypi @@ -37,6 +37,7 @@ '../gm/points.cpp', '../gm/poly2poly.cpp', '../gm/quadpaths.cpp', + '../gm/shaderbounds.cpp', '../gm/shadertext.cpp', '../gm/shadows.cpp', '../gm/shapes.cpp',