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