SkLayerDrawLooper.h revision 842292f10fc08bc8701114f7eec00944b6ea26d2
19682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall/* 29682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall * Copyright 2011 Google Inc. 39682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall * 49682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall * Use of this source code is governed by a BSD-style license that can be 59682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall * found in the LICENSE file. 69682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall */ 79682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 89682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall#ifndef SkLayerDrawLooper_DEFINED 99682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall#define SkLayerDrawLooper_DEFINED 109682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 119682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall#include "SkDrawLooper.h" 129682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall#include "SkPaint.h" 139682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall#include "SkPoint.h" 149682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall#include "SkXfermode.h" 159682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 169682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hallclass SK_API SkLayerDrawLooper : public SkDrawLooper { 179682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hallpublic: 189682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall SK_DECLARE_INST_COUNT(SkLayerDrawLooper) 199682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 209682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall SkLayerDrawLooper(); 219682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall virtual ~SkLayerDrawLooper(); 229682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 239682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall /** 249682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall * Bits specifies which aspects of the layer's paint should replace the 259682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall * corresponding aspects on the draw's paint. 269682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall * kEntirePaint_Bits means use the layer's paint completely. 279682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall * 0 means ignore the layer's paint... except for fColorMode, which is 289682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall * always applied. 299682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall */ 309682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall enum Bits { 319682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall kStyle_Bit = 1 << 0, //!< use this layer's Style/stroke settings 329682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall kTextSkewX_Bit = 1 << 1, //!< use this layer's textskewx 339682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall kPathEffect_Bit = 1 << 2, //!< use this layer's patheffect 349682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall kMaskFilter_Bit = 1 << 3, //!< use this layer's maskfilter 359682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall kShader_Bit = 1 << 4, //!< use this layer's shader 369682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall kColorFilter_Bit = 1 << 5, //!< use this layer's colorfilter 379682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall kXfermode_Bit = 1 << 6, //!< use this layer's xfermode 389682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 399682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall /** 409682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall * Use the layer's paint entirely, with these exceptions: 419682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall * - We never override the draw's paint's text_encoding, since that is 429682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall * used to interpret the text/len parameters in draw[Pos]Text. 439682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall * - Color is always computed using the LayerInfo's fColorMode. 449682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall */ 459682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall kEntirePaint_Bits = -1 469682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 479682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall }; 489682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall typedef int32_t BitFlags; 499682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 509682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall /** 519682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall * Info for how to apply the layer's paint and offset. 529682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall * 539682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall * fColorMode controls how we compute the final color for the layer: 549682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall * The layer's paint's color is treated as the SRC 559682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall * The draw's paint's color is treated as the DST 569682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall * final-color = Mode(layers-color, draws-color); 579682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall * Any SkXfermode::Mode will work. Two common choices are: 589682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall * kSrc_Mode: to use the layer's color, ignoring the draw's 599682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall * kDst_Mode: to just keep the draw's color, ignoring the layer's 609682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall */ 619682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall struct SK_API LayerInfo { 629682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall BitFlags fPaintBits; 639682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall SkXfermode::Mode fColorMode; 649682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall SkVector fOffset; 659682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall bool fPostTranslate; //!< applies to fOffset 669682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 679682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall /** 689682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall * Initial the LayerInfo. Defaults to settings that will draw the 699682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall * layer with no changes: e.g. 709682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall * fPaintBits == 0 719682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall * fColorMode == kDst_Mode 729682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall * fOffset == (0, 0) 739682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall */ 749682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall LayerInfo(); 759682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall }; 769682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 779682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall /** 789682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall * Call for each layer you want to add (from top to bottom). 799682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall * This returns a paint you can modify, but that ptr is only valid until 809682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall * the next call made to addLayer(). 819682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall */ 829682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall SkPaint* addLayer(const LayerInfo&); 839682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 849682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall /** 859682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall * This layer will draw with the original paint, at the specified offset 869682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall */ 879682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall void addLayer(SkScalar dx, SkScalar dy); 889682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 899682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall /** 909682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall * This layer will with the original paint and no offset. 919682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall */ 929682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall void addLayer() { this->addLayer(0, 0); } 939682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 949682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall /// Similar to addLayer, but adds a layer to the top. 959682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall SkPaint* addLayerOnTop(const LayerInfo&); 969682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 979682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall // overrides from SkDrawLooper 989682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall virtual void init(SkCanvas*); 999682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall virtual bool next(SkCanvas*, SkPaint* paint); 1009682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 1019682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall SK_DEVELOPER_TO_STRING() 1029682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 1039682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall /// Implements Flattenable. 1049682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall virtual Factory getFactory() const SK_OVERRIDE { return CreateProc; } 1059682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall static SkFlattenable* CreateProc(SkReadBuffer& buffer); 1069682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 1079682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hallprotected: 1089682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall virtual void flatten(SkWriteBuffer&) const SK_OVERRIDE; 1099682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 1109682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hallprivate: 1119682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall struct Rec { 1129682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall Rec* fNext; 1139682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall SkPaint fPaint; 1149682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall LayerInfo fInfo; 1159682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall }; 1169682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall Rec* fRecs; 1179682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall Rec* fTopRec; 1189682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall int fCount; 1199682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 1209682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall // state-machine during the init/next cycle 1219682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall Rec* fCurrRec; 1229682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 1239682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall static void ApplyInfo(SkPaint* dst, const SkPaint& src, const LayerInfo&); 1249682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 1259682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall class MyRegistrar : public SkFlattenable::Registrar { 1269682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall public: 1279682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall MyRegistrar(); 1289682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall }; 1299682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 1309682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall typedef SkDrawLooper INHERITED; 1319682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 1329682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hallpublic: 1339682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall class SK_API Builder { 1349682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall public: 1359682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall Builder(); 1369682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall ~Builder(); 1379682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 1389682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall /** 1399682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall * Call for each layer you want to add (from top to bottom). 1409682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall * This returns a paint you can modify, but that ptr is only valid until 1419682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall * the next call made to addLayer(). 1429682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall */ 1439682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall SkPaint* addLayer(const LayerInfo&); 1449682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 1459682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall /** 1469682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall * This layer will draw with the original paint, at the specified offset 1479682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall */ 1489682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall void addLayer(SkScalar dx, SkScalar dy); 1499682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 1509682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall /** 1519682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall * This layer will with the original paint and no offset. 1529682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall */ 1539682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall void addLayer() { this->addLayer(0, 0); } 1549682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 1559682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall /// Similar to addLayer, but adds a layer to the top. 1569682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall SkPaint* addLayerOnTop(const LayerInfo&); 1579682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 1589682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall /** 1599682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall * Pass list of layers on to newly built looper and return it. This will 1609682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall * also reset the builder, so it can be used to build another looper. 1619682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall */ 1629682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall SkLayerDrawLooper* detachLooper(); 1639682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 1649682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall private: 1659682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall Rec* fRecs; 1669682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall Rec* fTopRec; 1679682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall int fCount; 1689682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall }; 1699682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall}; 1709682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 1719682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall#endif 1729682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall