1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/gfx/skia/trunk/include/core/SkMask.h Wed Dec 31 06:09:35 2014 +0100 1.3 @@ -0,0 +1,162 @@ 1.4 + 1.5 +/* 1.6 + * Copyright 2006 The Android Open Source Project 1.7 + * 1.8 + * Use of this source code is governed by a BSD-style license that can be 1.9 + * found in the LICENSE file. 1.10 + */ 1.11 + 1.12 + 1.13 +#ifndef SkMask_DEFINED 1.14 +#define SkMask_DEFINED 1.15 + 1.16 +#include "SkRect.h" 1.17 + 1.18 +/** \class SkMask 1.19 + SkMask is used to describe alpha bitmaps, either 1bit, 8bit, or 1.20 + the 3-channel 3D format. These are passed to SkMaskFilter objects. 1.21 +*/ 1.22 +struct SkMask { 1.23 + enum Format { 1.24 + kBW_Format, //!< 1bit per pixel mask (e.g. monochrome) 1.25 + kA8_Format, //!< 8bits per pixel mask (e.g. antialiasing) 1.26 + k3D_Format, //!< 3 8bit per pixl planes: alpha, mul, add 1.27 + kARGB32_Format, //!< SkPMColor 1.28 + kLCD16_Format, //!< 565 alpha for r/g/b 1.29 + kLCD32_Format //!< 888 alpha for r/g/b 1.30 + }; 1.31 + 1.32 + enum { 1.33 + kCountMaskFormats = kLCD32_Format + 1 1.34 + }; 1.35 + 1.36 + uint8_t* fImage; 1.37 + SkIRect fBounds; 1.38 + uint32_t fRowBytes; 1.39 + Format fFormat; 1.40 + 1.41 + /** Returns true if the mask is empty: i.e. it has an empty bounds. 1.42 + */ 1.43 + bool isEmpty() const { return fBounds.isEmpty(); } 1.44 + 1.45 + /** Return the byte size of the mask, assuming only 1 plane. 1.46 + Does not account for k3D_Format. For that, use computeTotalImageSize(). 1.47 + If there is an overflow of 32bits, then returns 0. 1.48 + */ 1.49 + size_t computeImageSize() const; 1.50 + 1.51 + /** Return the byte size of the mask, taking into account 1.52 + any extra planes (e.g. k3D_Format). 1.53 + If there is an overflow of 32bits, then returns 0. 1.54 + */ 1.55 + size_t computeTotalImageSize() const; 1.56 + 1.57 + /** Returns the address of the byte that holds the specified bit. 1.58 + Asserts that the mask is kBW_Format, and that x,y are in range. 1.59 + x,y are in the same coordiate space as fBounds. 1.60 + */ 1.61 + uint8_t* getAddr1(int x, int y) const { 1.62 + SkASSERT(kBW_Format == fFormat); 1.63 + SkASSERT(fBounds.contains(x, y)); 1.64 + SkASSERT(fImage != NULL); 1.65 + return fImage + ((x - fBounds.fLeft) >> 3) + (y - fBounds.fTop) * fRowBytes; 1.66 + } 1.67 + 1.68 + /** Returns the address of the specified byte. 1.69 + Asserts that the mask is kA8_Format, and that x,y are in range. 1.70 + x,y are in the same coordiate space as fBounds. 1.71 + */ 1.72 + uint8_t* getAddr8(int x, int y) const { 1.73 + SkASSERT(kA8_Format == fFormat); 1.74 + SkASSERT(fBounds.contains(x, y)); 1.75 + SkASSERT(fImage != NULL); 1.76 + return fImage + x - fBounds.fLeft + (y - fBounds.fTop) * fRowBytes; 1.77 + } 1.78 + 1.79 + /** 1.80 + * Return the address of the specified 16bit mask. In the debug build, 1.81 + * this asserts that the mask's format is kLCD16_Format, and that (x,y) 1.82 + * are contained in the mask's fBounds. 1.83 + */ 1.84 + uint16_t* getAddrLCD16(int x, int y) const { 1.85 + SkASSERT(kLCD16_Format == fFormat); 1.86 + SkASSERT(fBounds.contains(x, y)); 1.87 + SkASSERT(fImage != NULL); 1.88 + uint16_t* row = (uint16_t*)(fImage + (y - fBounds.fTop) * fRowBytes); 1.89 + return row + (x - fBounds.fLeft); 1.90 + } 1.91 + 1.92 + /** 1.93 + * Return the address of the specified 32bit mask. In the debug build, 1.94 + * this asserts that the mask's format is kLCD32_Format, and that (x,y) 1.95 + * are contained in the mask's fBounds. 1.96 + */ 1.97 + uint32_t* getAddrLCD32(int x, int y) const { 1.98 + SkASSERT(kLCD32_Format == fFormat); 1.99 + SkASSERT(fBounds.contains(x, y)); 1.100 + SkASSERT(fImage != NULL); 1.101 + uint32_t* row = (uint32_t*)(fImage + (y - fBounds.fTop) * fRowBytes); 1.102 + return row + (x - fBounds.fLeft); 1.103 + } 1.104 + 1.105 + /** 1.106 + * Return the address of the specified 32bit mask. In the debug build, 1.107 + * this asserts that the mask's format is 32bits, and that (x,y) 1.108 + * are contained in the mask's fBounds. 1.109 + */ 1.110 + uint32_t* getAddr32(int x, int y) const { 1.111 + SkASSERT(kLCD32_Format == fFormat || kARGB32_Format == fFormat); 1.112 + SkASSERT(fBounds.contains(x, y)); 1.113 + SkASSERT(fImage != NULL); 1.114 + uint32_t* row = (uint32_t*)(fImage + (y - fBounds.fTop) * fRowBytes); 1.115 + return row + (x - fBounds.fLeft); 1.116 + } 1.117 + 1.118 + /** 1.119 + * Returns the address of the specified pixel, computing the pixel-size 1.120 + * at runtime based on the mask format. This will be slightly slower than 1.121 + * using one of the routines where the format is implied by the name 1.122 + * e.g. getAddr8 or getAddrLCD32. 1.123 + * 1.124 + * x,y must be contained by the mask's bounds (this is asserted in the 1.125 + * debug build, but not checked in the release build.) 1.126 + * 1.127 + * This should not be called with kBW_Format, as it will give unspecified 1.128 + * results (and assert in the debug build). 1.129 + */ 1.130 + void* getAddr(int x, int y) const; 1.131 + 1.132 + static uint8_t* AllocImage(size_t bytes); 1.133 + static void FreeImage(void* image); 1.134 + 1.135 + enum CreateMode { 1.136 + kJustComputeBounds_CreateMode, //!< compute bounds and return 1.137 + kJustRenderImage_CreateMode, //!< render into preallocate mask 1.138 + kComputeBoundsAndRenderImage_CreateMode //!< compute bounds, alloc image and render into it 1.139 + }; 1.140 +}; 1.141 + 1.142 +/////////////////////////////////////////////////////////////////////////////// 1.143 + 1.144 +/** 1.145 + * \class SkAutoMaskImage 1.146 + * 1.147 + * Stack class used to manage the fImage buffer in a SkMask. 1.148 + * When this object loses scope, the buffer is freed with SkMask::FreeImage(). 1.149 + */ 1.150 +class SkAutoMaskFreeImage { 1.151 +public: 1.152 + SkAutoMaskFreeImage(uint8_t* maskImage) { 1.153 + fImage = maskImage; 1.154 + } 1.155 + 1.156 + ~SkAutoMaskFreeImage() { 1.157 + SkMask::FreeImage(fImage); 1.158 + } 1.159 + 1.160 +private: 1.161 + uint8_t* fImage; 1.162 +}; 1.163 +#define SkAutoMaskFreeImage(...) SK_REQUIRE_LOCAL_VAR(SkAutoMaskFreeImage) 1.164 + 1.165 +#endif