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