Home | History | Annotate | Download | only in core
      1 /*
      2  * Copyright 2006 The Android Open Source Project
      3  *
      4  * Use of this source code is governed by a BSD-style license that can be
      5  * found in the LICENSE file.
      6  */
      7 
      8 #ifndef SkFlattenable_DEFINED
      9 #define SkFlattenable_DEFINED
     10 
     11 #include "SkRefCnt.h"
     12 
     13 class SkReadBuffer;
     14 class SkWriteBuffer;
     15 
     16 class SkPrivateEffectInitializer;
     17 
     18 /*
     19  *  Flattening is straight-forward:
     20  *      1. call getFactory() so we have a function-ptr to recreate the subclass
     21  *      2. call flatten(buffer) to write out enough data for the factory to read
     22  *
     23  *  Unflattening is easy for the caller: new_instance = factory(buffer)
     24  *
     25  *  The complexity of supporting this is as follows.
     26  *
     27  *  If your subclass wants to control unflattening, use this macro in your declaration:
     28  *      SK_DECLARE_PUBLIC_FLATTENABLE_DESERIALIZATION_PROCS
     29  *  This will provide a getFactory(), and require that the subclass implements CreateProc.
     30  *
     31  *  For older buffers (before the DEEPFLATTENING change, the macros below declare
     32  *  a thin factory DeepCreateProc. It checks the version of the buffer, and if it is pre-deep,
     33  *  then it calls through to a (usually protected) constructor, passing the buffer.
     34  *  If the buffer is newer, then it directly calls the "real" factory: CreateProc.
     35  */
     36 
     37 #define SK_DECLARE_FLATTENABLE_REGISTRAR_GROUP() static void InitializeFlattenables();
     38 
     39 #define SK_DEFINE_FLATTENABLE_REGISTRAR_GROUP_START(flattenable) \
     40     void flattenable::InitializeFlattenables() {
     41 
     42 #define SK_DEFINE_FLATTENABLE_REGISTRAR_GROUP_END \
     43     }
     44 
     45 #define SK_DEFINE_FLATTENABLE_REGISTRAR_ENTRY(flattenable) \
     46     SkFlattenable::Register(#flattenable, flattenable::CreateProc, \
     47                             flattenable::GetFlattenableType());
     48 
     49 #define SK_DECLARE_PUBLIC_FLATTENABLE_DESERIALIZATION_PROCS(flattenable)    \
     50     private:                                                                \
     51     static SkFlattenable* CreateProc(SkReadBuffer&);                        \
     52     friend class SkFlattenable::PrivateInitializer;                         \
     53     public:                                                                 \
     54     Factory getFactory() const override { return CreateProc; }
     55 
     56 /** For SkFlattenable derived objects with a valid type
     57     This macro should only be used in base class objects in core
     58   */
     59 #define SK_DEFINE_FLATTENABLE_TYPE(flattenable) \
     60     static Type GetFlattenableType() { \
     61         return k##flattenable##_Type; \
     62     }
     63 
     64 /** \class SkFlattenable
     65 
     66  SkFlattenable is the base class for objects that need to be flattened
     67  into a data stream for either transport or as part of the key to the
     68  font cache.
     69  */
     70 class SK_API SkFlattenable : public SkRefCnt {
     71 public:
     72     enum Type {
     73         kSkColorFilter_Type,
     74         kSkDrawLooper_Type,
     75         kSkImageFilter_Type,
     76         kSkMaskFilter_Type,
     77         kSkPathEffect_Type,
     78         kSkPixelRef_Type,
     79         kSkRasterizer_Type,
     80         kSkShader_Type,
     81         kSkUnused_Type,     // used to be SkUnitMapper
     82         kSkXfermode_Type,
     83     };
     84 
     85     typedef SkFlattenable* (*Factory)(SkReadBuffer&);
     86 
     87     SkFlattenable() {}
     88 
     89     /** Implement this to return a factory function pointer that can be called
     90      to recreate your class given a buffer (previously written to by your
     91      override of flatten().
     92      */
     93     virtual Factory getFactory() const = 0;
     94 
     95     /** Returns the name of the object's class
     96       */
     97     const char* getTypeName() const { return FactoryToName(getFactory()); }
     98 
     99     static Factory NameToFactory(const char name[]);
    100     static const char* FactoryToName(Factory);
    101     static bool NameToType(const char name[], Type* type);
    102 
    103     static void Register(const char name[], Factory, Type);
    104 
    105     /**
    106      *  Override this if your subclass needs to record data that it will need to recreate itself
    107      *  from its CreateProc (returned by getFactory()).
    108      */
    109     virtual void flatten(SkWriteBuffer&) const {}
    110 
    111 protected:
    112     class PrivateInitializer {
    113     public:
    114         static void InitCore();
    115         static void InitEffects();
    116     };
    117 
    118 private:
    119     static void InitializeFlattenablesIfNeeded();
    120 
    121     friend class SkGraphics;
    122 
    123     typedef SkRefCnt INHERITED;
    124 };
    125 
    126 #endif
    127