180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru/*
380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru * Copyright 2006 The Android Open Source Project
480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru *
580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru * Use of this source code is governed by a BSD-style license that can be
680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru * found in the LICENSE file.
780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru */
880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
1080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru#ifndef SkMask_DEFINED
1180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru#define SkMask_DEFINED
1280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
1380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru#include "SkRect.h"
1480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
1580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru/** \class SkMask
1680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    SkMask is used to describe alpha bitmaps, either 1bit, 8bit, or
1780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    the 3-channel 3D format. These are passed to SkMaskFilter objects.
1880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru*/
1980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Querustruct SkMask {
2080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    enum Format {
2180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        kBW_Format, //!< 1bit per pixel mask (e.g. monochrome)
2280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        kA8_Format, //!< 8bits per pixel mask (e.g. antialiasing)
2380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        k3D_Format, //!< 3 8bit per pixl planes: alpha, mul, add
2480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        kARGB32_Format,         //!< SkPMColor
2580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        kLCD16_Format,          //!< 565 alpha for r/g/b
2680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        kLCD32_Format           //!< 888 alpha for r/g/b
2780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    };
2880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
2980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    enum {
3080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        kCountMaskFormats = kLCD32_Format + 1
3180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    };
3280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
3380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    uint8_t*    fImage;
3480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    SkIRect     fBounds;
3580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    uint32_t    fRowBytes;
3680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    Format      fFormat;
3780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
3880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    /** Returns true if the mask is empty: i.e. it has an empty bounds.
3980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru     */
4080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    bool isEmpty() const { return fBounds.isEmpty(); }
4180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
4280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    /** Return the byte size of the mask, assuming only 1 plane.
4380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        Does not account for k3D_Format. For that, use computeTotalImageSize().
4480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        If there is an overflow of 32bits, then returns 0.
4580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    */
4680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    size_t computeImageSize() const;
4780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
4880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    /** Return the byte size of the mask, taking into account
4980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        any extra planes (e.g. k3D_Format).
5080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        If there is an overflow of 32bits, then returns 0.
5180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    */
5280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    size_t computeTotalImageSize() const;
5380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
5480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    /** Returns the address of the byte that holds the specified bit.
5580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        Asserts that the mask is kBW_Format, and that x,y are in range.
5680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        x,y are in the same coordiate space as fBounds.
5780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    */
5880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    uint8_t* getAddr1(int x, int y) const {
5980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        SkASSERT(kBW_Format == fFormat);
6080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        SkASSERT(fBounds.contains(x, y));
6180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        SkASSERT(fImage != NULL);
6280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        return fImage + ((x - fBounds.fLeft) >> 3) + (y - fBounds.fTop) * fRowBytes;
6380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    }
6480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
6580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    /** Returns the address of the specified byte.
6680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        Asserts that the mask is kA8_Format, and that x,y are in range.
6780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        x,y are in the same coordiate space as fBounds.
6880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    */
6980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    uint8_t* getAddr8(int x, int y) const {
7080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        SkASSERT(kA8_Format == fFormat);
7180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        SkASSERT(fBounds.contains(x, y));
7280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        SkASSERT(fImage != NULL);
7380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        return fImage + x - fBounds.fLeft + (y - fBounds.fTop) * fRowBytes;
7480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    }
7580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
7680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    /**
7780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru     *  Return the address of the specified 16bit mask. In the debug build,
7880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru     *  this asserts that the mask's format is kLCD16_Format, and that (x,y)
7980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru     *  are contained in the mask's fBounds.
8080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru     */
8180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    uint16_t* getAddrLCD16(int x, int y) const {
8280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        SkASSERT(kLCD16_Format == fFormat);
8380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        SkASSERT(fBounds.contains(x, y));
8480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        SkASSERT(fImage != NULL);
8580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        uint16_t* row = (uint16_t*)(fImage + (y - fBounds.fTop) * fRowBytes);
8680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        return row + (x - fBounds.fLeft);
8780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    }
8880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
8980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    /**
9080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru     *  Return the address of the specified 32bit mask. In the debug build,
9180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru     *  this asserts that the mask's format is kLCD32_Format, and that (x,y)
9280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru     *  are contained in the mask's fBounds.
9380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru     */
9480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    uint32_t* getAddrLCD32(int x, int y) const {
9580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        SkASSERT(kLCD32_Format == fFormat);
9680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        SkASSERT(fBounds.contains(x, y));
9780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        SkASSERT(fImage != NULL);
9880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        uint32_t* row = (uint32_t*)(fImage + (y - fBounds.fTop) * fRowBytes);
9980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        return row + (x - fBounds.fLeft);
10080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    }
10180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
10280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    /**
1037839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger     *  Return the address of the specified 32bit mask. In the debug build,
1047839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger     *  this asserts that the mask's format is 32bits, and that (x,y)
1057839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger     *  are contained in the mask's fBounds.
1067839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger     */
1077839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    uint32_t* getAddr32(int x, int y) const {
1087839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger        SkASSERT(kLCD32_Format == fFormat || kARGB32_Format == fFormat);
1097839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger        SkASSERT(fBounds.contains(x, y));
1107839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger        SkASSERT(fImage != NULL);
1117839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger        uint32_t* row = (uint32_t*)(fImage + (y - fBounds.fTop) * fRowBytes);
1127839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger        return row + (x - fBounds.fLeft);
1137839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    }
1147839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger
1157839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    /**
11680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru     *  Returns the address of the specified pixel, computing the pixel-size
11780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru     *  at runtime based on the mask format. This will be slightly slower than
11880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru     *  using one of the routines where the format is implied by the name
11980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru     *  e.g. getAddr8 or getAddrLCD32.
12080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru     *
12180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru     *  x,y must be contained by the mask's bounds (this is asserted in the
12280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru     *  debug build, but not checked in the release build.)
12380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru     *
12480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru     *  This should not be called with kBW_Format, as it will give unspecified
12580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru     *  results (and assert in the debug build).
12680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru     */
12780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    void* getAddr(int x, int y) const;
12880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
12980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    static uint8_t* AllocImage(size_t bytes);
13080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    static void FreeImage(void* image);
13180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
13280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    enum CreateMode {
13380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        kJustComputeBounds_CreateMode,      //!< compute bounds and return
13480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        kJustRenderImage_CreateMode,        //!< render into preallocate mask
13580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        kComputeBoundsAndRenderImage_CreateMode  //!< compute bounds, alloc image and render into it
13680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    };
13780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru};
13880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
13980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru///////////////////////////////////////////////////////////////////////////////
14080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
14180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru/**
14280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru *  \class SkAutoMaskImage
14380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru *
14480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru *  Stack class used to manage the fImage buffer in a SkMask.
14580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru *  When this object loses scope, the buffer is freed with SkMask::FreeImage().
14680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru */
14780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queruclass SkAutoMaskFreeImage {
14880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Querupublic:
14980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    SkAutoMaskFreeImage(uint8_t* maskImage) {
15080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        fImage = maskImage;
15180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    }
15280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
15380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    ~SkAutoMaskFreeImage() {
15480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        SkMask::FreeImage(fImage);
15580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    }
15680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
15780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queruprivate:
15880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    uint8_t* fImage;
15980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru};
160910f694aefb0b671dd8522a9afe9b6be645701c1Derek Sollenberger#define SkAutoMaskFreeImage(...) SK_REQUIRE_LOCAL_VAR(SkAutoMaskFreeImage)
16180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
16280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru#endif
163