| Index: tools/filtermain.cpp
|
| ===================================================================
|
| --- tools/filtermain.cpp (revision 8402)
|
| +++ tools/filtermain.cpp (working copy)
|
| @@ -320,7 +320,194 @@
|
| 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 @@
|
| { 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) {
|
|
|