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 SkMask_DEFINED
     11 #define SkMask_DEFINED
     12 
     13 #include "SkRect.h"
     14 
     15 /** \class SkMask
     16     SkMask is used to describe alpha bitmaps, either 1bit, 8bit, or
     17     the 3-channel 3D format. These are passed to SkMaskFilter objects.
     18 */
     19 struct SkMask {
     20     enum Format {
     21         kBW_Format, //!< 1bit per pixel mask (e.g. monochrome)
     22         kA8_Format, //!< 8bits per pixel mask (e.g. antialiasing)
     23         k3D_Format, //!< 3 8bit per pixl planes: alpha, mul, add
     24         kARGB32_Format,         //!< SkPMColor
     25         kLCD16_Format,          //!< 565 alpha for r/g/b
     26     };
     27 
     28     enum {
     29         kCountMaskFormats = kLCD16_Format + 1
     30     };
     31 
     32     uint8_t*    fImage;
     33     SkIRect     fBounds;
     34     uint32_t    fRowBytes;
     35     Format      fFormat;
     36 
     37     /** Returns true if the mask is empty: i.e. it has an empty bounds.
     38      */
     39     bool isEmpty() const { return fBounds.isEmpty(); }
     40 
     41     /** Return the byte size of the mask, assuming only 1 plane.
     42         Does not account for k3D_Format. For that, use computeTotalImageSize().
     43         If there is an overflow of 32bits, then returns 0.
     44     */
     45     size_t computeImageSize() const;
     46 
     47     /** Return the byte size of the mask, taking into account
     48         any extra planes (e.g. k3D_Format).
     49         If there is an overflow of 32bits, then returns 0.
     50     */
     51     size_t computeTotalImageSize() const;
     52 
     53     /** Returns the address of the byte that holds the specified bit.
     54         Asserts that the mask is kBW_Format, and that x,y are in range.
     55         x,y are in the same coordiate space as fBounds.
     56     */
     57     uint8_t* getAddr1(int x, int y) const {
     58         SkASSERT(kBW_Format == fFormat);
     59         SkASSERT(fBounds.contains(x, y));
     60         SkASSERT(fImage != NULL);
     61         return fImage + ((x - fBounds.fLeft) >> 3) + (y - fBounds.fTop) * fRowBytes;
     62     }
     63 
     64     /** Returns the address of the specified byte.
     65         Asserts that the mask is kA8_Format, and that x,y are in range.
     66         x,y are in the same coordiate space as fBounds.
     67     */
     68     uint8_t* getAddr8(int x, int y) const {
     69         SkASSERT(kA8_Format == fFormat);
     70         SkASSERT(fBounds.contains(x, y));
     71         SkASSERT(fImage != NULL);
     72         return fImage + x - fBounds.fLeft + (y - fBounds.fTop) * fRowBytes;
     73     }
     74 
     75     /**
     76      *  Return the address of the specified 16bit mask. In the debug build,
     77      *  this asserts that the mask's format is kLCD16_Format, and that (x,y)
     78      *  are contained in the mask's fBounds.
     79      */
     80     uint16_t* getAddrLCD16(int x, int y) const {
     81         SkASSERT(kLCD16_Format == fFormat);
     82         SkASSERT(fBounds.contains(x, y));
     83         SkASSERT(fImage != NULL);
     84         uint16_t* row = (uint16_t*)(fImage + (y - fBounds.fTop) * fRowBytes);
     85         return row + (x - fBounds.fLeft);
     86     }
     87 
     88     /**
     89      *  Return the address of the specified 32bit mask. In the debug build,
     90      *  this asserts that the mask's format is 32bits, and that (x,y)
     91      *  are contained in the mask's fBounds.
     92      */
     93     uint32_t* getAddr32(int x, int y) const {
     94         SkASSERT(kARGB32_Format == fFormat);
     95         SkASSERT(fBounds.contains(x, y));
     96         SkASSERT(fImage != NULL);
     97         uint32_t* row = (uint32_t*)(fImage + (y - fBounds.fTop) * fRowBytes);
     98         return row + (x - fBounds.fLeft);
     99     }
    100 
    101     /**
    102      *  Returns the address of the specified pixel, computing the pixel-size
    103      *  at runtime based on the mask format. This will be slightly slower than
    104      *  using one of the routines where the format is implied by the name
    105      *  e.g. getAddr8 or getAddr32.
    106      *
    107      *  x,y must be contained by the mask's bounds (this is asserted in the
    108      *  debug build, but not checked in the release build.)
    109      *
    110      *  This should not be called with kBW_Format, as it will give unspecified
    111      *  results (and assert in the debug build).
    112      */
    113     void* getAddr(int x, int y) const;
    114 
    115     static uint8_t* AllocImage(size_t bytes);
    116     static void FreeImage(void* image);
    117 
    118     enum CreateMode {
    119         kJustComputeBounds_CreateMode,      //!< compute bounds and return
    120         kJustRenderImage_CreateMode,        //!< render into preallocate mask
    121         kComputeBoundsAndRenderImage_CreateMode  //!< compute bounds, alloc image and render into it
    122     };
    123 };
    124 
    125 ///////////////////////////////////////////////////////////////////////////////
    126 
    127 /**
    128  *  \class SkAutoMaskImage
    129  *
    130  *  Stack class used to manage the fImage buffer in a SkMask.
    131  *  When this object loses scope, the buffer is freed with SkMask::FreeImage().
    132  */
    133 class SkAutoMaskFreeImage {
    134 public:
    135     SkAutoMaskFreeImage(uint8_t* maskImage) {
    136         fImage = maskImage;
    137     }
    138 
    139     ~SkAutoMaskFreeImage() {
    140         SkMask::FreeImage(fImage);
    141     }
    142 
    143 private:
    144     uint8_t* fImage;
    145 };
    146 #define SkAutoMaskFreeImage(...) SK_REQUIRE_LOCAL_VAR(SkAutoMaskFreeImage)
    147 
    148 #endif
    149