1fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 2fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot/* 3fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot * Copyright 2011 The Android Open Source Project 4fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot * 5fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot * Use of this source code is governed by a BSD-style license that can be 6fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot * found in the LICENSE file. 7fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot */ 8fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 9fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 10fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot#ifndef SkDrawLooper_DEFINED 11fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot#define SkDrawLooper_DEFINED 12fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 13fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot#include "SkBlurTypes.h" 14fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot#include "SkFlattenable.h" 15fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot#include "SkPoint.h" 16fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot#include "SkColor.h" 17fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 18fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robotclass SkArenaAlloc; 19fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robotclass SkCanvas; 20fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robotclass SkColorSpaceXformer; 21fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robotclass SkPaint; 22fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robotstruct SkRect; 23fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robotclass SkString; 24fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 25fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot/** \class SkDrawLooper 26fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot Subclasses of SkDrawLooper can be attached to a SkPaint. Where they are, 27fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot and something is drawn to a canvas with that paint, the looper subclass will 28fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot be called, allowing it to modify the canvas and/or paint for that draw call. 29fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot More than that, via the next() method, the looper can modify the draw to be 30fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot invoked multiple times (hence the name loop-er), allow it to perform effects 31fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot like shadows or frame/fills, that require more than one pass. 32fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot*/ 33fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robotclass SK_API SkDrawLooper : public SkFlattenable { 34fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robotpublic: 35fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot /** 36fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot * Holds state during a draw. Users call next() until it returns false. 37fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot * 38fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot * Subclasses of SkDrawLooper should create a subclass of this object to 39fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot * hold state specific to their subclass. 40fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot */ 41fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot class SK_API Context : ::SkNoncopyable { 42fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot public: 43fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot Context() {} 44fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot virtual ~Context() {} 45fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 46fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot /** 47fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot * Called in a loop on objects returned by SkDrawLooper::createContext(). 48fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot * Each time true is returned, the object is drawn (possibly with a modified 49fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot * canvas and/or paint). When false is finally returned, drawing for the object 50fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot * stops. 51fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot * 52fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot * On each call, the paint will be in its original state, but the 53fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot * canvas will be as it was following the previous call to next() or 54fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot * createContext(). 55fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot * 56fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot * The implementation must ensure that, when next() finally returns 57fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot * false, the canvas has been restored to the state it was 58fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot * initially, before createContext() was first called. 59fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot */ 60fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot virtual bool next(SkCanvas* canvas, SkPaint* paint) = 0; 61fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot }; 62fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 63fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot /** 64fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot * Called right before something is being drawn. Returns a Context 65fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot * whose next() method should be called until it returns false. 66fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot */ 67fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot virtual Context* makeContext(SkCanvas*, SkArenaAlloc*) const = 0; 68fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 69fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot /** 70fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot * The fast bounds functions are used to enable the paint to be culled early 71fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot * in the drawing pipeline. If a subclass can support this feature it must 72fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot * return true for the canComputeFastBounds() function. If that function 73fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot * returns false then computeFastBounds behavior is undefined otherwise it 74fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot * is expected to have the following behavior. Given the parent paint and 75fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot * the parent's bounding rect the subclass must fill in and return the 76fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot * storage rect, where the storage rect is with the union of the src rect 77fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot * and the looper's bounding rect. 78fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot */ 79fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot bool canComputeFastBounds(const SkPaint& paint) const; 80fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot void computeFastBounds(const SkPaint& paint, const SkRect& src, SkRect* dst) const; 81fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 82fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot struct BlurShadowRec { 83fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot SkScalar fSigma; 84fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot SkVector fOffset; 85fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot SkColor fColor; 86fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot SkBlurStyle fStyle; 87fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot SkBlurQuality fQuality; 88fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot }; 89fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot /** 90fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot * If this looper can be interpreted as having two layers, such that 91fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot * 1. The first layer (bottom most) just has a blur and translate 92fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot * 2. The second layer has no modifications to either paint or canvas 93fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot * 3. No other layers. 94fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot * then return true, and if not null, fill out the BlurShadowRec). 95fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot * 96fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot * If any of the above are not met, return false and ignore the BlurShadowRec parameter. 97fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot */ 98fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot virtual bool asABlurShadow(BlurShadowRec*) const; 99fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 100fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot SK_TO_STRING_PUREVIRT() 101fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot SK_DEFINE_FLATTENABLE_TYPE(SkDrawLooper) 102fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 103fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robotprotected: 104fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot sk_sp<SkDrawLooper> makeColorSpace(SkColorSpaceXformer* xformer) const { 105fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot return this->onMakeColorSpace(xformer); 106fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot } 107fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot virtual sk_sp<SkDrawLooper> onMakeColorSpace(SkColorSpaceXformer*) const = 0; 108fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 109fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot SkDrawLooper() {} 110fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 111fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robotprivate: 112fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot friend class SkColorSpaceXformer; 113fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 114fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot typedef SkFlattenable INHERITED; 115fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot}; 116fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 117fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot#endif 118