Home | History | Annotate | Download | only in core
      1 
      2 /*
      3  * Copyright 2006 The Android Open Source Project
      4  *
      5  * Use of this source code is governed by a BSD-style license that can be
      6  * found in the LICENSE file.
      7  */
      8 
      9 
     10 #ifndef SkFlattenable_DEFINED
     11 #define SkFlattenable_DEFINED
     12 
     13 #include "SkRefCnt.h"
     14 #include "SkBitmap.h"
     15 #include "SkReader32.h"
     16 #include "SkTDArray.h"
     17 #include "SkWriter32.h"
     18 
     19 class SkFlattenableReadBuffer;
     20 class SkFlattenableWriteBuffer;
     21 class SkString;
     22 
     23 #if SK_ALLOW_STATIC_GLOBAL_INITIALIZERS
     24 
     25 #define SK_DECLARE_FLATTENABLE_REGISTRAR()
     26 
     27 #define SK_DEFINE_FLATTENABLE_REGISTRAR(flattenable) \
     28     static SkFlattenable::Registrar g##flattenable##Reg(#flattenable, \
     29                                                       flattenable::CreateProc);
     30 
     31 #define SK_DEFINE_FLATTENABLE_REGISTRAR_GROUP_START(flattenable)
     32 #define SK_DEFINE_FLATTENABLE_REGISTRAR_ENTRY(flattenable) \
     33     static SkFlattenable::Registrar g##flattenable##Reg(#flattenable, \
     34                                                       flattenable::CreateProc);
     35 #define SK_DEFINE_FLATTENABLE_REGISTRAR_GROUP_END
     36 
     37 #else
     38 
     39 #define SK_DECLARE_FLATTENABLE_REGISTRAR() static void Init();
     40 
     41 #define SK_DEFINE_FLATTENABLE_REGISTRAR(flattenable) \
     42     void flattenable::Init() { \
     43         SkFlattenable::Registrar(#flattenable, CreateProc); \
     44     }
     45 
     46 #define SK_DEFINE_FLATTENABLE_REGISTRAR_GROUP_START(flattenable) \
     47     void flattenable::Init() {
     48 
     49 #define SK_DEFINE_FLATTENABLE_REGISTRAR_ENTRY(flattenable) \
     50         SkFlattenable::Registrar(#flattenable, flattenable::CreateProc);
     51 
     52 #define SK_DEFINE_FLATTENABLE_REGISTRAR_GROUP_END \
     53     }
     54 
     55 #endif
     56 
     57 /** \class SkFlattenable
     58 
     59  SkFlattenable is the base class for objects that need to be flattened
     60  into a data stream for either transport or as part of the key to the
     61  font cache.
     62  */
     63 class SK_API SkFlattenable : public SkRefCnt {
     64 public:
     65     typedef SkFlattenable* (*Factory)(SkFlattenableReadBuffer&);
     66 
     67     SkFlattenable() {}
     68 
     69     /** Implement this to return a factory function pointer that can be called
     70      to recreate your class given a buffer (previously written to by your
     71      override of flatten().
     72      */
     73     virtual Factory getFactory() = 0;
     74     /** Override this to write data specific to your subclass into the buffer,
     75      being sure to call your super-class' version first. This data will later
     76      be passed to your Factory function, returned by getFactory().
     77      */
     78     virtual void flatten(SkFlattenableWriteBuffer&);
     79 
     80     /** Set the string to describe the sublass and return true. If this is not
     81         overridden, ignore the string param and return false.
     82      */
     83     virtual bool toDumpString(SkString*) const;
     84 
     85     static Factory NameToFactory(const char name[]);
     86     static const char* FactoryToName(Factory);
     87     static void Register(const char name[], Factory);
     88 
     89     class Registrar {
     90     public:
     91         Registrar(const char name[], Factory factory) {
     92             SkFlattenable::Register(name, factory);
     93         }
     94     };
     95 
     96 protected:
     97     SkFlattenable(SkFlattenableReadBuffer&) {}
     98 
     99 private:
    100 #if !SK_ALLOW_STATIC_GLOBAL_INITIALIZERS
    101     static void InitializeFlattenables();
    102 #endif
    103 
    104     friend class SkGraphics;
    105 };
    106 
    107 // helpers for matrix and region
    108 
    109 class SkMatrix;
    110 extern void SkReadMatrix(SkReader32*, SkMatrix*);
    111 extern void SkWriteMatrix(SkWriter32*, const SkMatrix&);
    112 
    113 class SkRegion;
    114 extern void SkReadRegion(SkReader32*, SkRegion*);
    115 extern void SkWriteRegion(SkWriter32*, const SkRegion&);
    116 
    117 ///////////////////////////////////////////////////////////////////////////////
    118 ///////////////////////////////////////////////////////////////////////////////
    119 
    120 class SkTypeface;
    121 
    122 class SkFlattenableReadBuffer : public SkReader32 {
    123 public:
    124     SkFlattenableReadBuffer();
    125     explicit SkFlattenableReadBuffer(const void* data);
    126     SkFlattenableReadBuffer(const void* data, size_t size);
    127 
    128     void setRefCntArray(SkRefCnt* array[], int count) {
    129         fRCArray = array;
    130         fRCCount = count;
    131     }
    132 
    133     void setTypefaceArray(SkTypeface* array[], int count) {
    134         fTFArray = array;
    135         fTFCount = count;
    136     }
    137 
    138     /**
    139      *  Call this with a pre-loaded array of Factories, in the same order as
    140      *  were created/written by the writer. SkPicture uses this.
    141      */
    142     void setFactoryPlayback(SkFlattenable::Factory array[], int count) {
    143         fFactoryTDArray = NULL;
    144         fFactoryArray = array;
    145         fFactoryCount = count;
    146     }
    147 
    148     /**
    149      *  Call this with an initially empty array, so the reader can cache each
    150      *  factory it sees by name. Used by the pipe code in conjunction with
    151      *  the writer's kInlineFactoryNames_Flag.
    152      */
    153     void setFactoryArray(SkTDArray<SkFlattenable::Factory>* array) {
    154         fFactoryTDArray = array;
    155         fFactoryArray = NULL;
    156         fFactoryCount = 0;
    157     }
    158 
    159     SkTypeface* readTypeface();
    160     SkRefCnt* readRefCnt();
    161     void* readFunctionPtr();
    162     SkFlattenable* readFlattenable();
    163 
    164     void setPictureVersion(uint32_t version) { fPictureVersion = version; }
    165     uint32_t getPictureVersion() { return fPictureVersion; }
    166 
    167 private:
    168     SkRefCnt** fRCArray;
    169     int        fRCCount;
    170 
    171     SkTypeface** fTFArray;
    172     int        fTFCount;
    173 
    174     SkTDArray<SkFlattenable::Factory>* fFactoryTDArray;
    175     SkFlattenable::Factory* fFactoryArray;
    176     int                     fFactoryCount;
    177 
    178     uint32_t fPictureVersion;
    179 
    180     typedef SkReader32 INHERITED;
    181 };
    182 
    183 ///////////////////////////////////////////////////////////////////////////////
    184 
    185 #include "SkPtrRecorder.h"
    186 
    187 /**
    188  *  Subclass of SkTPtrSet specialed to call ref() and unref() when the
    189  *  base class's incPtr() and decPtr() are called. This makes it a valid owner
    190  *  of each ptr, which is released when the set is reset or destroyed.
    191  */
    192 class SkRefCntSet : public SkTPtrSet<SkRefCnt*> {
    193 public:
    194     virtual ~SkRefCntSet();
    195 
    196 protected:
    197     // overrides
    198     virtual void incPtr(void*);
    199     virtual void decPtr(void*);
    200 };
    201 
    202 class SkFactorySet : public SkTPtrSet<SkFlattenable::Factory> {};
    203 
    204 class SkFlattenableWriteBuffer : public SkWriter32 {
    205 public:
    206     SkFlattenableWriteBuffer(size_t minSize);
    207     virtual ~SkFlattenableWriteBuffer();
    208 
    209     void writeTypeface(SkTypeface*);
    210     void writeRefCnt(SkRefCnt*);
    211     void writeFunctionPtr(void*);
    212     void writeFlattenable(SkFlattenable* flattenable);
    213 
    214     SkRefCntSet* getTypefaceRecorder() const { return fTFSet; }
    215     SkRefCntSet* setTypefaceRecorder(SkRefCntSet*);
    216 
    217     SkRefCntSet* getRefCntRecorder() const { return fRCSet; }
    218     SkRefCntSet* setRefCntRecorder(SkRefCntSet*);
    219 
    220     SkFactorySet* getFactoryRecorder() const { return fFactorySet; }
    221     SkFactorySet* setFactoryRecorder(SkFactorySet*);
    222 
    223     enum Flags {
    224         kCrossProcess_Flag       = 0x01,
    225         /**
    226          *  Instructs the writer to inline Factory names as there are seen the
    227          *  first time (after that we store an index). The pipe code uses this.
    228          */
    229         kInlineFactoryNames_Flag = 0x02,
    230     };
    231     Flags getFlags() const { return (Flags)fFlags; }
    232     void setFlags(Flags flags) { fFlags = flags; }
    233 
    234     bool isCrossProcess() const {
    235         return SkToBool(fFlags & kCrossProcess_Flag);
    236     }
    237     bool inlineFactoryNames() const {
    238         return SkToBool(fFlags & kInlineFactoryNames_Flag);
    239     }
    240 
    241     bool persistBitmapPixels() const {
    242         return (fFlags & kCrossProcess_Flag) != 0;
    243     }
    244 
    245     bool persistTypeface() const { return (fFlags & kCrossProcess_Flag) != 0; }
    246 
    247 private:
    248     uint32_t        fFlags;
    249     SkRefCntSet*    fTFSet;
    250     SkRefCntSet*    fRCSet;
    251     SkFactorySet*   fFactorySet;
    252 
    253     typedef SkWriter32 INHERITED;
    254 };
    255 
    256 #endif
    257 
    258