Home | History | Annotate | Download | only in core
      1 /*
      2  * Copyright (C) 2010 The Android Open Source Project
      3  *
      4  * Licensed under the Apache License, Version 2.0 (the "License");
      5  * you may not use this file except in compliance with the License.
      6  * You may obtain a copy of the License at
      7  *
      8  *      http://www.apache.org/licenses/LICENSE-2.0
      9  *
     10  * Unless required by applicable law or agreed to in writing, software
     11  * distributed under the License is distributed on an "AS IS" BASIS,
     12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     13  * See the License for the specific language governing permissions and
     14  * limitations under the License.
     15  */
     16 
     17 #ifndef SkDevice_DEFINED
     18 #define SkDevice_DEFINED
     19 
     20 #include "SkRefCnt.h"
     21 #include "SkBitmap.h"
     22 #include "SkCanvas.h"
     23 #include "SkColor.h"
     24 
     25 class SkClipStack;
     26 class SkDevice;
     27 class SkDraw;
     28 struct SkIRect;
     29 class SkMatrix;
     30 class SkMetaData;
     31 class SkRegion;
     32 
     33 /** \class SkDeviceFactory
     34 
     35     Devices that extend SkDevice should also provide a SkDeviceFactory class
     36     to pass into SkCanvas.  Doing so will eliminate the need to extend
     37     SkCanvas as well.
     38 */
     39 class SK_API SkDeviceFactory : public SkRefCnt {
     40 public:
     41     SkDeviceFactory();
     42     virtual ~SkDeviceFactory();
     43     virtual SkDevice* newDevice(SkCanvas*, SkBitmap::Config, int width,
     44                                 int height, bool isOpaque, bool isLayer) = 0;
     45 };
     46 
     47 class SkRasterDeviceFactory : public SkDeviceFactory {
     48 public:
     49     virtual SkDevice* newDevice(SkCanvas*, SkBitmap::Config, int width,
     50                                 int height, bool isOpaque, bool isLayer);
     51 };
     52 
     53 class SK_API SkDevice : public SkRefCnt {
     54 public:
     55     SkDevice(SkCanvas*);
     56     /** Construct a new device, extracting the width/height/config/isOpaque values from
     57         the bitmap. If transferPixelOwnership is true, and the bitmap claims to own its
     58         own pixels (getOwnsPixels() == true), then transfer this responsibility to the
     59         device, and call setOwnsPixels(false) on the bitmap.
     60 
     61         Subclasses may override the destructor, which is virtual, even though this class
     62         doesn't have one. SkRefCnt does.
     63 
     64         @param bitmap   A copy of this bitmap is made and stored in the device
     65     */
     66     SkDevice(SkCanvas*, const SkBitmap& bitmap, bool forOffscreen);
     67     virtual ~SkDevice();
     68 
     69     /**
     70      *  Return the factory that will create this subclass of SkDevice.
     71      *  The returned factory is cached by the device, and so its reference count
     72      *  is not changed by this call.
     73      */
     74     SkDeviceFactory* getDeviceFactory();
     75 
     76     enum Capabilities {
     77         kGL_Capability     = 0x1,  //!< mask indicating GL support
     78         kVector_Capability = 0x2,  //!< mask indicating a vector representation
     79         kAll_Capabilities  = 0x3
     80     };
     81     virtual uint32_t getDeviceCapabilities() { return 0; }
     82 
     83     /** Return the width of the device (in pixels).
     84     */
     85     virtual int width() const { return fBitmap.width(); }
     86     /** Return the height of the device (in pixels).
     87     */
     88     virtual int height() const { return fBitmap.height(); }
     89 
     90     /**
     91      *  Return the device's origin: its offset in device coordinates from
     92      *  the default origin in its canvas' matrix/clip
     93      */
     94     const SkIPoint& getOrigin() const { return fOrigin; }
     95 
     96     /** Return the bitmap config of the device's pixels
     97     */
     98     SkBitmap::Config config() const { return fBitmap.getConfig(); }
     99     /** Returns true if the device's bitmap's config treats every pixels as
    100         implicitly opaque.
    101     */
    102     bool isOpaque() const { return fBitmap.isOpaque(); }
    103 
    104     /** Return the bounds of the device
    105     */
    106     void getBounds(SkIRect* bounds) const;
    107 
    108     /** Return true if the specified rectangle intersects the bounds of the
    109         device. If sect is not NULL and there is an intersection, sect returns
    110         the intersection.
    111     */
    112     bool intersects(const SkIRect& r, SkIRect* sect = NULL) const;
    113 
    114     /** Return the bitmap associated with this device. Call this each time you need
    115         to access the bitmap, as it notifies the subclass to perform any flushing
    116         etc. before you examine the pixels.
    117         @param changePixels set to true if the caller plans to change the pixels
    118         @return the device's bitmap
    119     */
    120     const SkBitmap& accessBitmap(bool changePixels);
    121 
    122     /** Clears the entire device to the specified color (including alpha).
    123      *  Ignores the clip.
    124      */
    125     virtual void clear(SkColor color);
    126 
    127     /**
    128      * Deprecated name for clear.
    129      */
    130     void eraseColor(SkColor eraseColor) { this->clear(eraseColor); }
    131 
    132     /** Called when this device is installed into a Canvas. Balanaced by a call
    133         to unlockPixels() when the device is removed from a Canvas.
    134     */
    135     virtual void lockPixels();
    136     virtual void unlockPixels();
    137 
    138     /** Return the device's associated texture, or NULL. If returned, it may be
    139         drawn into another device
    140      */
    141     virtual SkGpuTexture* accessTexture() { return NULL; }
    142 
    143     /**
    144      *  Called with the correct matrix and clip before this device is drawn
    145      *  to using those settings. If your subclass overrides this, be sure to
    146      *  call through to the base class as well.
    147      *
    148      *  The clipstack is another view of the clip. It records the actual
    149      *  geometry that went into building the region. It is present for devices
    150      *  that want to parse it, but is not required: the region is a complete
    151      *  picture of the current clip. (i.e. if you regionize all of the geometry
    152      *  in the clipstack, you will arrive at an equivalent region to the one
    153      *  passed in).
    154     */
    155     virtual void setMatrixClip(const SkMatrix&, const SkRegion&,
    156                                const SkClipStack&);
    157 
    158     /** Called when this device gains focus (i.e becomes the current device
    159         for drawing).
    160     */
    161     virtual void gainFocus(SkCanvas*, const SkMatrix&, const SkRegion&,
    162                            const SkClipStack&) {}
    163 
    164     /** Causes any deferred drawing to the device to be completed.
    165      */
    166     virtual void flush() {}
    167 
    168     /**
    169      *  Copy the pixels from the device into bitmap. Returns true on success.
    170      *  If false is returned, then the bitmap parameter is left unchanged.
    171      *  The bitmap parameter is treated as output-only, and will be completely
    172      *  overwritten (if the method returns true).
    173      */
    174     virtual bool readPixels(const SkIRect& srcRect, SkBitmap* bitmap);
    175 
    176     /**
    177      *  Similar to draw sprite, this method will copy the pixels in bitmap onto
    178      *  the device, with the top/left corner specified by (x, y). The pixel
    179      *  values in the device are completely replaced: there is no blending.
    180      */
    181     virtual void writePixels(const SkBitmap& bitmap, int x, int y);
    182 
    183     /** These are called inside the per-device-layer loop for each draw call.
    184      When these are called, we have already applied any saveLayer operations,
    185      and are handling any looping from the paint, and any effects from the
    186      DrawFilter.
    187      */
    188     virtual void drawPaint(const SkDraw&, const SkPaint& paint);
    189     virtual void drawPoints(const SkDraw&, SkCanvas::PointMode mode, size_t count,
    190                             const SkPoint[], const SkPaint& paint);
    191     virtual void drawRect(const SkDraw&, const SkRect& r,
    192                           const SkPaint& paint);
    193     /**
    194      *  If pathIsMutable, then the implementation is allowed to cast path to a
    195      *  non-const pointer and modify it in place (as an optimization). Canvas
    196      *  may do this to implement helpers such as drawOval, by placing a temp
    197      *  path on the stack to hold the representation of the oval.
    198      *
    199      *  If prePathMatrix is not null, it should logically be applied before any
    200      *  stroking or other effects. If there are no effects on the paint that
    201      *  affect the geometry/rasterization, then the pre matrix can just be
    202      *  pre-concated with the current matrix.
    203      */
    204     virtual void drawPath(const SkDraw&, const SkPath& path,
    205                           const SkPaint& paint,
    206                           const SkMatrix* prePathMatrix = NULL,
    207                           bool pathIsMutable = false);
    208     virtual void drawBitmap(const SkDraw&, const SkBitmap& bitmap,
    209                             const SkIRect* srcRectOrNull,
    210                             const SkMatrix& matrix, const SkPaint& paint);
    211     virtual void drawSprite(const SkDraw&, const SkBitmap& bitmap,
    212                             int x, int y, const SkPaint& paint);
    213     virtual void drawText(const SkDraw&, const void* text, size_t len,
    214                           SkScalar x, SkScalar y, const SkPaint& paint);
    215     virtual void drawPosText(const SkDraw&, const void* text, size_t len,
    216                              const SkScalar pos[], SkScalar constY,
    217                              int scalarsPerPos, const SkPaint& paint);
    218     virtual void drawTextOnPath(const SkDraw&, const void* text, size_t len,
    219                                 const SkPath& path, const SkMatrix* matrix,
    220                                 const SkPaint& paint);
    221 #ifdef ANDROID
    222     virtual void drawPosTextOnPath(const SkDraw& draw, const void* text, size_t len,
    223                                    const SkPoint pos[], const SkPaint& paint,
    224                                    const SkPath& path, const SkMatrix* matrix);
    225 #endif
    226     virtual void drawVertices(const SkDraw&, SkCanvas::VertexMode, int vertexCount,
    227                               const SkPoint verts[], const SkPoint texs[],
    228                               const SkColor colors[], SkXfermode* xmode,
    229                               const uint16_t indices[], int indexCount,
    230                               const SkPaint& paint);
    231     virtual void drawDevice(const SkDraw&, SkDevice*, int x, int y,
    232                             const SkPaint&);
    233 
    234     ///////////////////////////////////////////////////////////////////////////
    235 
    236     SkMetaData& getMetaData();
    237 
    238     struct TextFlags {
    239         uint32_t            fFlags;     // SkPaint::getFlags()
    240         SkPaint::Hinting    fHinting;
    241     };
    242 
    243     /**
    244      *  Device may filter the text flags for drawing text here. If it wants to
    245      *  make a change to the specified values, it should write them into the
    246      *  textflags parameter (output) and return true. If the paint is fine as
    247      *  is, then ignore the textflags parameter and return false.
    248      *
    249      *  The baseclass SkDevice filters based on its depth and blitters.
    250      */
    251     virtual bool filterTextFlags(const SkPaint& paint, TextFlags*);
    252 
    253 protected:
    254     /**
    255      *  subclasses must override this to return a new (or ref'd) instance of
    256      *  a device factory that will create this subclass of device. This value
    257      *  is cached, so it should get called at most once for a given instance.
    258      */
    259     virtual SkDeviceFactory* onNewDeviceFactory();
    260 
    261     /** Update as needed the pixel value in the bitmap, so that the caller can access
    262         the pixels directly. Note: only the pixels field should be altered. The config/width/height/rowbytes
    263         must remain unchanged.
    264     */
    265     virtual void onAccessBitmap(SkBitmap*);
    266 
    267     SkPixelRef* getPixelRef() const { return fBitmap.pixelRef(); }
    268     // just for subclasses, to assign a custom pixelref
    269     SkPixelRef* setPixelRef(SkPixelRef* pr, size_t offset) {
    270         fBitmap.setPixelRef(pr, offset);
    271         return pr;
    272     }
    273 
    274 private:
    275     friend class SkCanvas;
    276     // just called by SkCanvas when built as a layer
    277     void setOrigin(int x, int y) { fOrigin.set(x, y); }
    278 
    279     SkCanvas*   fCanvas;
    280     SkBitmap    fBitmap;
    281     SkIPoint    fOrigin;
    282     SkMetaData* fMetaData;
    283 
    284     SkDeviceFactory* fCachedDeviceFactory;
    285 };
    286 
    287 #endif
    288