diff options
author | mtklein <mtklein@chromium.org> | 2015-02-17 11:13:33 -0800 |
---|---|---|
committer | Commit bot <commit-bot@chromium.org> | 2015-02-17 11:13:33 -0800 |
commit | d603b22903bf7c023226bf52bd7c1f49a9bee1bf (patch) | |
tree | ba674388e18d20eefe6ca1bf542b81b06f852d3a | |
parent | f87fe78bc36c94143625fc38cc848d0da86eb60d (diff) |
Suggested version with 'undo'.
BUG=skia:
Review URL: https://codereview.chromium.org/931483002
-rw-r--r-- | dm/DM.cpp | 18 | ||||
-rw-r--r-- | dm/DMSrcSink.cpp | 54 | ||||
-rw-r--r-- | dm/DMSrcSink.h | 12 |
3 files changed, 73 insertions, 11 deletions
@@ -21,8 +21,9 @@ DEFINE_bool(nameByHash, false, "If true, write to FLAGS_writePath[0]/<hash>.png instead of " "to FLAGS_writePath[0]/<config>/<sourceType>/<name>.png"); DEFINE_bool2(pathOpsExtended, x, false, "Run extended pathOps tests."); -DEFINE_string(matrix, "1 0 0 0 1 0 0 0 1", - "Matrix to apply when using 'matrix' in config."); +DEFINE_string(matrix, "1 0 0 1", + "2x2 scale+skew matrix to apply or upright when using " + "'matrix' or 'upright' in config."); DEFINE_bool(gpu_threading, false, "Allow GPU work to run on multiple threads?"); DEFINE_string(blacklist, "", @@ -242,12 +243,15 @@ static Sink* create_via(const char* tag, Sink* wrapped) { VIA("tiles", ViaTiles, 256, 256, NULL, wrapped); VIA("tiles_rt", ViaTiles, 256, 256, new SkRTreeFactory, wrapped); - if (FLAGS_matrix.count() == 9) { + if (FLAGS_matrix.count() == 4) { SkMatrix m; - for (int i = 0; i < 9; i++) { - m[i] = (SkScalar)atof(FLAGS_matrix[i]); - } - VIA("matrix", ViaMatrix, m, wrapped); + m.reset(); + m.setScaleX((SkScalar)atof(FLAGS_matrix[0])); + m.setSkewX ((SkScalar)atof(FLAGS_matrix[1])); + m.setSkewY ((SkScalar)atof(FLAGS_matrix[2])); + m.setScaleY((SkScalar)atof(FLAGS_matrix[3])); + VIA("matrix", ViaMatrix, m, wrapped); + VIA("upright", ViaUpright, m, wrapped); } #undef VIA return NULL; diff --git a/dm/DMSrcSink.cpp b/dm/DMSrcSink.cpp index 4e3668f15e..b44f1d7818 100644 --- a/dm/DMSrcSink.cpp +++ b/dm/DMSrcSink.cpp @@ -271,25 +271,71 @@ Error RasterSink::draw(const Src& src, SkBitmap* dst, SkWStream*, SkString*) con /*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/ +static SkISize auto_compute_translate(SkMatrix* matrix, int srcW, int srcH) { + SkRect bounds = SkRect::MakeIWH(srcW, srcH); + matrix->mapRect(&bounds); + matrix->postTranslate(-bounds.x(), -bounds.y()); + return SkISize::Make(SkScalarRoundToInt(bounds.width()), SkScalarRoundToInt(bounds.height())); +} + ViaMatrix::ViaMatrix(SkMatrix matrix, Sink* sink) : fMatrix(matrix), fSink(sink) {} Error ViaMatrix::draw(const Src& src, SkBitmap* bitmap, SkWStream* stream, SkString* log) const { // We turn our arguments into a Src, then draw that Src into our Sink to fill bitmap or stream. struct ProxySrc : public Src { - const Src& fSrc; - SkMatrix fMatrix; - ProxySrc(const Src& src, SkMatrix matrix) : fSrc(src), fMatrix(matrix) {} + const Src& fSrc; + SkMatrix fMatrix; + SkISize fSize; + + ProxySrc(const Src& src, SkMatrix matrix) : fSrc(src), fMatrix(matrix) { + fSize = auto_compute_translate(&fMatrix, src.size().width(), src.size().height()); + } Error draw(SkCanvas* canvas) const SK_OVERRIDE { canvas->concat(fMatrix); return fSrc.draw(canvas); } - SkISize size() const SK_OVERRIDE { return fSrc.size(); } + SkISize size() const SK_OVERRIDE { return fSize; } Name name() const SK_OVERRIDE { sk_throw(); return ""; } // No one should be calling this. } proxy(src, fMatrix); return fSink->draw(proxy, bitmap, stream, log); } +// Undoes any flip or 90 degree rotate without changing the scale of the bitmap. +// This should be pixel-preserving. +ViaUpright::ViaUpright(SkMatrix matrix, Sink* sink) : fMatrix(matrix), fSink(sink) {} + +Error ViaUpright::draw(const Src& src, SkBitmap* bitmap, SkWStream* stream, SkString* log) const { + Error err = fSink->draw(src, bitmap, stream, log); + if (!err.isEmpty()) { + return err; + } + + SkMatrix inverse; + if (!fMatrix.rectStaysRect() || !fMatrix.invert(&inverse)) { + return "Cannot upright --matrix."; + } + SkMatrix upright = SkMatrix::I(); + upright.setScaleX(SkScalarSignAsScalar(inverse.getScaleX())); + upright.setScaleY(SkScalarSignAsScalar(inverse.getScaleY())); + upright.setSkewX(SkScalarSignAsScalar(inverse.getSkewX())); + upright.setSkewY(SkScalarSignAsScalar(inverse.getSkewY())); + + SkBitmap uprighted; + SkISize size = auto_compute_translate(&upright, bitmap->width(), bitmap->height()); + uprighted.allocPixels(bitmap->info().makeWH(size.width(), size.height())); + + SkCanvas canvas(uprighted); + canvas.concat(upright); + SkPaint paint; + paint.setXfermodeMode(SkXfermode::kSrc_Mode); + canvas.drawBitmap(*bitmap, 0, 0, &paint); + + *bitmap = uprighted; + bitmap->lockPixels(); + return ""; +} + /*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/ ViaPipe::ViaPipe(Sink* sink) : fSink(sink) {} diff --git a/dm/DMSrcSink.h b/dm/DMSrcSink.h index 4c15c92cb6..abf3ef8a2f 100644 --- a/dm/DMSrcSink.h +++ b/dm/DMSrcSink.h @@ -163,6 +163,18 @@ private: SkAutoTDelete<Sink> fSink; }; +class ViaUpright : public Sink { +public: + ViaUpright(SkMatrix, Sink*); + + Error draw(const Src&, SkBitmap*, SkWStream*, SkString*) const SK_OVERRIDE; + int enclave() const SK_OVERRIDE { return fSink->enclave(); } + const char* fileExtension() const SK_OVERRIDE { return fSink->fileExtension(); } +private: + SkMatrix fMatrix; + SkAutoTDelete<Sink> fSink; +}; + class ViaPipe : public Sink { public: explicit ViaPipe(Sink*); |