aboutsummaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorGravatar mtklein <mtklein@chromium.org>2015-02-17 11:13:33 -0800
committerGravatar Commit bot <commit-bot@chromium.org>2015-02-17 11:13:33 -0800
commitd603b22903bf7c023226bf52bd7c1f49a9bee1bf (patch)
treeba674388e18d20eefe6ca1bf542b81b06f852d3a
parentf87fe78bc36c94143625fc38cc848d0da86eb60d (diff)
Suggested version with 'undo'.
-rw-r--r--dm/DM.cpp18
-rw-r--r--dm/DMSrcSink.cpp54
-rw-r--r--dm/DMSrcSink.h12
3 files changed, 73 insertions, 11 deletions
diff --git a/dm/DM.cpp b/dm/DM.cpp
index 5745113096..b41a77f8ad 100644
--- a/dm/DM.cpp
+++ b/dm/DM.cpp
@@ -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*);