11c028bd395dc52ca12b99f85f0c297d15a288c2dreed@google.com/* 21c028bd395dc52ca12b99f85f0c297d15a288c2dreed@google.com * Copyright 2013 Google Inc. 31c028bd395dc52ca12b99f85f0c297d15a288c2dreed@google.com * 41c028bd395dc52ca12b99f85f0c297d15a288c2dreed@google.com * Use of this source code is governed by a BSD-style license that can be 51c028bd395dc52ca12b99f85f0c297d15a288c2dreed@google.com * found in the LICENSE file. 61c028bd395dc52ca12b99f85f0c297d15a288c2dreed@google.com */ 71c028bd395dc52ca12b99f85f0c297d15a288c2dreed@google.com 81c028bd395dc52ca12b99f85f0c297d15a288c2dreed@google.com#ifndef SkDeviceLooper_DEFINED 91c028bd395dc52ca12b99f85f0c297d15a288c2dreed@google.com#define SkDeviceLooper_DEFINED 101c028bd395dc52ca12b99f85f0c297d15a288c2dreed@google.com 111c028bd395dc52ca12b99f85f0c297d15a288c2dreed@google.com#include "SkBitmap.h" 121c028bd395dc52ca12b99f85f0c297d15a288c2dreed@google.com#include "SkMatrix.h" 131c028bd395dc52ca12b99f85f0c297d15a288c2dreed@google.com#include "SkRasterClip.h" 141c028bd395dc52ca12b99f85f0c297d15a288c2dreed@google.com 151c028bd395dc52ca12b99f85f0c297d15a288c2dreed@google.com/** 161c028bd395dc52ca12b99f85f0c297d15a288c2dreed@google.com * Helper class to manage "tiling" a large coordinate space into managable 171c028bd395dc52ca12b99f85f0c297d15a288c2dreed@google.com * chunks, where managable means areas that are <= some max critical coordinate 181c028bd395dc52ca12b99f85f0c297d15a288c2dreed@google.com * size. 191c028bd395dc52ca12b99f85f0c297d15a288c2dreed@google.com * 201c028bd395dc52ca12b99f85f0c297d15a288c2dreed@google.com * The constructor takes an antialiasing bool, which affects what this maximum 211c028bd395dc52ca12b99f85f0c297d15a288c2dreed@google.com * allowable size is: If we're drawing BW, then we need coordinates to stay 221c028bd395dc52ca12b99f85f0c297d15a288c2dreed@google.com * safely within fixed-point range (we use +- 16K, to give ourselves room to 231c028bd395dc52ca12b99f85f0c297d15a288c2dreed@google.com * add/subtract two fixed values and still be in range. If we're drawing AA, 241c028bd395dc52ca12b99f85f0c297d15a288c2dreed@google.com * then we reduce that size by the amount that the supersampler scan converter 251c028bd395dc52ca12b99f85f0c297d15a288c2dreed@google.com * needs (at the moment, that is 4X, so the "safe" range is +- 4K). 261c028bd395dc52ca12b99f85f0c297d15a288c2dreed@google.com * 271c028bd395dc52ca12b99f85f0c297d15a288c2dreed@google.com * For performance reasons, the class first checks to see if any help is needed 281c028bd395dc52ca12b99f85f0c297d15a288c2dreed@google.com * at all, and if not (i.e. the specified bounds and base bitmap area already 291c028bd395dc52ca12b99f85f0c297d15a288c2dreed@google.com * in the safe-zone, then the class does nothing (effectively). 301c028bd395dc52ca12b99f85f0c297d15a288c2dreed@google.com */ 311c028bd395dc52ca12b99f85f0c297d15a288c2dreed@google.comclass SkDeviceLooper { 321c028bd395dc52ca12b99f85f0c297d15a288c2dreed@google.compublic: 331c028bd395dc52ca12b99f85f0c297d15a288c2dreed@google.com SkDeviceLooper(const SkBitmap& base, const SkRasterClip&, 341c028bd395dc52ca12b99f85f0c297d15a288c2dreed@google.com const SkIRect& bounds, bool aa); 351c028bd395dc52ca12b99f85f0c297d15a288c2dreed@google.com ~SkDeviceLooper(); 361c028bd395dc52ca12b99f85f0c297d15a288c2dreed@google.com 371c028bd395dc52ca12b99f85f0c297d15a288c2dreed@google.com const SkBitmap& getBitmap() const { 381c028bd395dc52ca12b99f85f0c297d15a288c2dreed@google.com SkASSERT(kDone_State != fState); 391c028bd395dc52ca12b99f85f0c297d15a288c2dreed@google.com SkASSERT(fCurrBitmap); 401c028bd395dc52ca12b99f85f0c297d15a288c2dreed@google.com return *fCurrBitmap; 411c028bd395dc52ca12b99f85f0c297d15a288c2dreed@google.com } 421c028bd395dc52ca12b99f85f0c297d15a288c2dreed@google.com 431c028bd395dc52ca12b99f85f0c297d15a288c2dreed@google.com const SkRasterClip& getRC() const { 441c028bd395dc52ca12b99f85f0c297d15a288c2dreed@google.com SkASSERT(kDone_State != fState); 451c028bd395dc52ca12b99f85f0c297d15a288c2dreed@google.com SkASSERT(fCurrRC); 461c028bd395dc52ca12b99f85f0c297d15a288c2dreed@google.com return *fCurrRC; 471c028bd395dc52ca12b99f85f0c297d15a288c2dreed@google.com } 481c028bd395dc52ca12b99f85f0c297d15a288c2dreed@google.com 491c028bd395dc52ca12b99f85f0c297d15a288c2dreed@google.com void mapRect(SkRect* dst, const SkRect& src) const; 501c028bd395dc52ca12b99f85f0c297d15a288c2dreed@google.com void mapMatrix(SkMatrix* dst, const SkMatrix& src) const; 511c028bd395dc52ca12b99f85f0c297d15a288c2dreed@google.com 521c028bd395dc52ca12b99f85f0c297d15a288c2dreed@google.com /** 531c028bd395dc52ca12b99f85f0c297d15a288c2dreed@google.com * Call next to setup the looper to return a valid coordinate chunk. 546b00a1ec2ad525cae559d6b6e2157786686b2953skia.committer@gmail.com * Each time this returns true, it is safe to call mapRect() and 551c028bd395dc52ca12b99f85f0c297d15a288c2dreed@google.com * mapMatrix(), to convert from "global" coordinate values to ones that 561c028bd395dc52ca12b99f85f0c297d15a288c2dreed@google.com * are local to this chunk. 571c028bd395dc52ca12b99f85f0c297d15a288c2dreed@google.com * 581c028bd395dc52ca12b99f85f0c297d15a288c2dreed@google.com * When next() returns false, the list of chunks is done, and mapRect() 591c028bd395dc52ca12b99f85f0c297d15a288c2dreed@google.com * and mapMatrix() should no longer be called. 601c028bd395dc52ca12b99f85f0c297d15a288c2dreed@google.com */ 611c028bd395dc52ca12b99f85f0c297d15a288c2dreed@google.com bool next(); 621c028bd395dc52ca12b99f85f0c297d15a288c2dreed@google.com 631c028bd395dc52ca12b99f85f0c297d15a288c2dreed@google.comprivate: 641c028bd395dc52ca12b99f85f0c297d15a288c2dreed@google.com const SkBitmap& fBaseBitmap; 651c028bd395dc52ca12b99f85f0c297d15a288c2dreed@google.com const SkRasterClip& fBaseRC; 661c028bd395dc52ca12b99f85f0c297d15a288c2dreed@google.com 671c028bd395dc52ca12b99f85f0c297d15a288c2dreed@google.com enum State { 681c028bd395dc52ca12b99f85f0c297d15a288c2dreed@google.com kDone_State, // iteration is complete, getters will assert 691c028bd395dc52ca12b99f85f0c297d15a288c2dreed@google.com kSimple_State, // no translate/clip mods needed 701c028bd395dc52ca12b99f85f0c297d15a288c2dreed@google.com kComplex_State 711c028bd395dc52ca12b99f85f0c297d15a288c2dreed@google.com }; 721c028bd395dc52ca12b99f85f0c297d15a288c2dreed@google.com 731c028bd395dc52ca12b99f85f0c297d15a288c2dreed@google.com // storage for our tiled versions. Perhaps could use SkTLazy 741c028bd395dc52ca12b99f85f0c297d15a288c2dreed@google.com SkBitmap fSubsetBitmap; 751c028bd395dc52ca12b99f85f0c297d15a288c2dreed@google.com SkRasterClip fSubsetRC; 761c028bd395dc52ca12b99f85f0c297d15a288c2dreed@google.com 771c028bd395dc52ca12b99f85f0c297d15a288c2dreed@google.com const SkBitmap* fCurrBitmap; 781c028bd395dc52ca12b99f85f0c297d15a288c2dreed@google.com const SkRasterClip* fCurrRC; 791c028bd395dc52ca12b99f85f0c297d15a288c2dreed@google.com SkIRect fClippedBounds; 801c028bd395dc52ca12b99f85f0c297d15a288c2dreed@google.com SkIPoint fCurrOffset; 811c028bd395dc52ca12b99f85f0c297d15a288c2dreed@google.com int fDelta; 821c028bd395dc52ca12b99f85f0c297d15a288c2dreed@google.com State fState; 831c028bd395dc52ca12b99f85f0c297d15a288c2dreed@google.com 841c028bd395dc52ca12b99f85f0c297d15a288c2dreed@google.com enum Delta { 851c028bd395dc52ca12b99f85f0c297d15a288c2dreed@google.com kBW_Delta = 1 << 14, // 16K, gives room to spare for fixedpoint 861c028bd395dc52ca12b99f85f0c297d15a288c2dreed@google.com kAA_Delta = kBW_Delta >> 2 // supersample 4x 871c028bd395dc52ca12b99f85f0c297d15a288c2dreed@google.com }; 881c028bd395dc52ca12b99f85f0c297d15a288c2dreed@google.com 891c028bd395dc52ca12b99f85f0c297d15a288c2dreed@google.com bool fitsInDelta(const SkIRect& r) const { 901c028bd395dc52ca12b99f85f0c297d15a288c2dreed@google.com return r.right() < fDelta && r.bottom() < fDelta; 911c028bd395dc52ca12b99f85f0c297d15a288c2dreed@google.com } 926b00a1ec2ad525cae559d6b6e2157786686b2953skia.committer@gmail.com 931c028bd395dc52ca12b99f85f0c297d15a288c2dreed@google.com bool computeCurrBitmapAndClip(); 941c028bd395dc52ca12b99f85f0c297d15a288c2dreed@google.com}; 951c028bd395dc52ca12b99f85f0c297d15a288c2dreed@google.com 961c028bd395dc52ca12b99f85f0c297d15a288c2dreed@google.com#endif 97