diff options
author | robertphillips@google.com <robertphillips@google.com@2bbb7eff-a529-9590-31e7-b0007b416f81> | 2013-03-28 12:25:25 +0000 |
---|---|---|
committer | robertphillips@google.com <robertphillips@google.com@2bbb7eff-a529-9590-31e7-b0007b416f81> | 2013-03-28 12:25:25 +0000 |
commit | c3410b8cbbf63ac7968262c25c996bdbaab20588 (patch) | |
tree | 1d2ddece2b48c76e31fb3d766aa4670093dc614f | |
parent | 6dcc338ab4b02b526cd407e77767261d92acff12 (diff) |
New filter targeted at desk_googlespreadsheet overdraw issues
https://codereview.chromium.org/12918029/
git-svn-id: http://skia.googlecode.com/svn/trunk@8424 2bbb7eff-a529-9590-31e7-b0007b416f81
-rw-r--r-- | debugger/SkDrawCommand.h | 5 | ||||
-rw-r--r-- | tools/filtermain.cpp | 188 |
2 files changed, 193 insertions, 0 deletions
diff --git a/debugger/SkDrawCommand.h b/debugger/SkDrawCommand.h index 65e1f0df01..02a4afed5d 100644 --- a/debugger/SkDrawCommand.h +++ b/debugger/SkDrawCommand.h @@ -200,6 +200,8 @@ public: virtual void execute(SkCanvas* canvas) SK_OVERRIDE; virtual const SkBitmap* getBitmap() const SK_OVERRIDE; + const SkBitmap& bitmap() const { return fBitmap; } + // The non-const 'paint' method allows modification of this object's // SkPaint. For this reason the ctor and setPaint method make a local copy. // The 'fPaintPtr' member acts a signal that the local SkPaint is valid @@ -212,6 +214,9 @@ public: const SkRect* srcRect() const { return fSrc.isEmpty() ? NULL : &fSrc; } const SkRect& dstRect() const { return fDst; } + void setSrcRect(const SkRect& src) { fSrc = src; } + void setDstRect(const SkRect& dst) { fDst = dst; } + private: SkBitmap fBitmap; SkRect fSrc; diff --git a/tools/filtermain.cpp b/tools/filtermain.cpp index 14eafdc412..aa7afa0f9e 100644 --- a/tools/filtermain.cpp +++ b/tools/filtermain.cpp @@ -320,6 +320,193 @@ static void apply_6(SkTDArray<SkDrawCommand*>& commands, int curCommand) { s->setVisible(false); } +// Check for: +// SAVE +// CLIP_RECT +// SAVE_LAYER +// SAVE +// CLIP_RECT +// SAVE_LAYER +// SAVE +// CLIP_RECT +// DRAWBITMAPRECTTORECT +// RESTORE +// RESTORE +// RESTORE +// RESTORE +// RESTORE +// where: +// all the clipRect's are BW, nested, intersections +// the drawBitmapRectToRect is a 1-1 copy from src to dest +// the last (smallest) clip rect is a subset of the drawBitmapRectToRect's dest rect +// all the saveLayer's paints can be rolled into the drawBitmapRectToRect's paint +// This pattern is used by Google spreadsheet when drawing the toolbar buttons +static bool check_7(const SkTDArray<SkDrawCommand*>& commands, int curCommand) { + if (SAVE != commands[curCommand]->getType() || + commands.count() <= curCommand+13 || + CLIP_RECT != commands[curCommand+1]->getType() || + SAVE_LAYER != commands[curCommand+2]->getType() || + SAVE != commands[curCommand+3]->getType() || + CLIP_RECT != commands[curCommand+4]->getType() || + SAVE_LAYER != commands[curCommand+5]->getType() || + SAVE != commands[curCommand+6]->getType() || + CLIP_RECT != commands[curCommand+7]->getType() || + DRAW_BITMAP_RECT_TO_RECT != commands[curCommand+8]->getType() || + RESTORE != commands[curCommand+9]->getType() || + RESTORE != commands[curCommand+10]->getType() || + RESTORE != commands[curCommand+11]->getType() || + RESTORE != commands[curCommand+12]->getType() || + RESTORE != commands[curCommand+13]->getType()) + return false; + + ClipRect* clip0 = (ClipRect*) commands[curCommand+1]; + SaveLayer* saveLayer0 = (SaveLayer*) commands[curCommand+2]; + ClipRect* clip1 = (ClipRect*) commands[curCommand+4]; + SaveLayer* saveLayer1 = (SaveLayer*) commands[curCommand+5]; + ClipRect* clip2 = (ClipRect*) commands[curCommand+7]; + DrawBitmapRect* dbmr = (DrawBitmapRect*) commands[curCommand+8]; + + if (clip0->doAA() || clip1->doAA() || clip2->doAA()) { + return false; + } + + if (SkRegion::kIntersect_Op != clip0->op() || + SkRegion::kIntersect_Op != clip1->op() || + SkRegion::kIntersect_Op != clip2->op()) { + return false; + } + + if (!clip0->rect().contains(clip1->rect()) || + !clip1->rect().contains(clip2->rect())) { + return false; + } + + // The src->dest mapping needs to be 1-to-1 + if (NULL == dbmr->srcRect()) { + if (dbmr->bitmap().width() != dbmr->dstRect().width() || + dbmr->bitmap().height() != dbmr->dstRect().height()) { + return false; + } + } else { + if (dbmr->srcRect()->width() != dbmr->dstRect().width() || + dbmr->srcRect()->height() != dbmr->dstRect().height()) { + return false; + } + } + + if (!dbmr->dstRect().contains(clip2->rect())) { + return false; + } + + const SkPaint* saveLayerPaint0 = saveLayer0->paint(); + const SkPaint* saveLayerPaint1 = saveLayer1->paint(); + + if ((NULL != saveLayerPaint0 && !is_simple(*saveLayerPaint0)) || + (NULL != saveLayerPaint1 && !is_simple(*saveLayerPaint1))) { + return false; + } + + SkPaint* dbmrPaint = dbmr->paint(); + + if (NULL == dbmrPaint) { + return true; + } + + if (NULL != saveLayerPaint0) { + SkColor layerColor0 = saveLayerPaint0->getColor() | 0xFF000000; // force opaque + if (dbmrPaint->getColor() != layerColor0) { + return false; + } + } + + if (NULL != saveLayerPaint1) { + SkColor layerColor1 = saveLayerPaint1->getColor() | 0xFF000000; // force opaque + if (dbmrPaint->getColor() != layerColor1) { + return false; + } + } + + return true; +} + +// Reduce to a single drawBitmapRectToRect call by folding the clipRect's into +// the src and dst Rects and the saveLayer paints into the drawBitmapRectToRect's +// paint. +static void apply_7(SkTDArray<SkDrawCommand*>& commands, int curCommand) { + Save* save0 = (Save*) commands[curCommand]; + ClipRect* clip0 = (ClipRect*) commands[curCommand+1]; + SaveLayer* saveLayer0 = (SaveLayer*) commands[curCommand+2]; + Save* save1 = (Save*) commands[curCommand+3]; + ClipRect* clip1 = (ClipRect*) commands[curCommand+4]; + SaveLayer* saveLayer1 = (SaveLayer*) commands[curCommand+5]; + Save* save2 = (Save*) commands[curCommand+6]; + ClipRect* clip2 = (ClipRect*) commands[curCommand+7]; + DrawBitmapRect* dbmr = (DrawBitmapRect*) commands[curCommand+8]; + Restore* restore0 = (Restore*) commands[curCommand+9]; + Restore* restore1 = (Restore*) commands[curCommand+10]; + Restore* restore2 = (Restore*) commands[curCommand+11]; + Restore* restore3 = (Restore*) commands[curCommand+12]; + Restore* restore4 = (Restore*) commands[curCommand+13]; + + SkScalar newSrcLeft = dbmr->srcRect()->fLeft + clip2->rect().fLeft - dbmr->dstRect().fLeft; + SkScalar newSrcTop = dbmr->srcRect()->fTop + clip2->rect().fTop - dbmr->dstRect().fTop; + + SkRect newSrc = SkRect::MakeXYWH(newSrcLeft, newSrcTop, + clip2->rect().width(), clip2->rect().height()); + + dbmr->setSrcRect(newSrc); + dbmr->setDstRect(clip2->rect()); + + SkColor color = 0xFF000000; + int a0, a1; + + const SkPaint* saveLayerPaint0 = saveLayer0->paint(); + if (NULL != saveLayerPaint0) { + color = saveLayerPaint0->getColor(); + a0 = SkColorGetA(color); + } else { + a0 = 0xFF; + } + + const SkPaint* saveLayerPaint1 = saveLayer1->paint(); + if (NULL != saveLayerPaint1) { + color = saveLayerPaint1->getColor(); + a1 = SkColorGetA(color); + } else { + a1 = 0xFF; + } + + int newA = (a0 * a1) / 255; + SkASSERT(newA <= 0xFF); + + SkPaint* dbmrPaint = dbmr->paint(); + + if (NULL != dbmrPaint) { + SkColor newColor = SkColorSetA(dbmrPaint->getColor(), newA); + dbmrPaint->setColor(newColor); + } else { + SkColor newColor = SkColorSetA(color, newA); + + SkPaint newPaint; + newPaint.setColor(newColor); + dbmr->setPaint(newPaint); + } + + // remove everything except the drawbitmaprect + save0->setVisible(false); + clip0->setVisible(false); + saveLayer0->setVisible(false); + save1->setVisible(false); + clip1->setVisible(false); + saveLayer1->setVisible(false); + save2->setVisible(false); + clip2->setVisible(false); + restore0->setVisible(false); + restore1->setVisible(false); + restore2->setVisible(false); + restore3->setVisible(false); + restore4->setVisible(false); +} typedef bool (*PFCheck)(const SkTDArray<SkDrawCommand*>& commands, int curCommand); typedef void (*PFApply)(SkTDArray<SkDrawCommand*>& commands, int curCommand); @@ -336,6 +523,7 @@ struct OptTableEntry { { check_4, apply_4, 0 }, { check_5, apply_5, 0 }, { check_6, apply_6, 0 }, + { check_7, apply_7, 0 }, }; static int filter_picture(const SkString& inFile, const SkString& outFile) { |