1ec3ed6a5ebf6f2c406d7bcf94b6bc34fcaeb976eepoger@google.com 28a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com/* 3ec3ed6a5ebf6f2c406d7bcf94b6bc34fcaeb976eepoger@google.com * Copyright 2006 The Android Open Source Project 48a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com * 5ec3ed6a5ebf6f2c406d7bcf94b6bc34fcaeb976eepoger@google.com * Use of this source code is governed by a BSD-style license that can be 6ec3ed6a5ebf6f2c406d7bcf94b6bc34fcaeb976eepoger@google.com * found in the LICENSE file. 78a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com */ 88a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 9ec3ed6a5ebf6f2c406d7bcf94b6bc34fcaeb976eepoger@google.com 108a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#ifndef SkMask_DEFINED 118a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#define SkMask_DEFINED 128a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 138a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#include "SkRect.h" 148a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 158a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com/** \class SkMask 168a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkMask is used to describe alpha bitmaps, either 1bit, 8bit, or 178a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com the 3-channel 3D format. These are passed to SkMaskFilter objects. 188a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com*/ 198a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comstruct SkMask { 208a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com enum Format { 218a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com kBW_Format, //!< 1bit per pixel mask (e.g. monochrome) 228a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com kA8_Format, //!< 8bits per pixel mask (e.g. antialiasing) 238a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com k3D_Format, //!< 3 8bit per pixl planes: alpha, mul, add 24f2b98d67dcb6fcb3120feede9c72016fc7b3ead8reed@android.com kARGB32_Format, //!< SkPMColor 251eeaf0ba2381f84ffd889f56303cbe0d1886bb21caryclark@google.com kLCD16_Format, //!< 565 alpha for r/g/b 261eeaf0ba2381f84ffd889f56303cbe0d1886bb21caryclark@google.com kLCD32_Format //!< 888 alpha for r/g/b 278a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com }; 28309485b7b51f4cae4c0361ab4da00fe9cc89515cagl@chromium.org 298a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com enum { 30effc5016f040945a53ab0ea47f9ea02404c17805reed@google.com kCountMaskFormats = kLCD32_Format + 1 318a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com }; 328a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 338a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com uint8_t* fImage; 348a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkIRect fBounds; 3549f0ff25a046d6001dc2d095b6fa3c30f0f46b6areed@android.com uint32_t fRowBytes; 3649f0ff25a046d6001dc2d095b6fa3c30f0f46b6areed@android.com Format fFormat; 378a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 38543ed9352c7dfd93071c08b14930cca2e82a08d4reed@android.com /** Returns true if the mask is empty: i.e. it has an empty bounds. 39543ed9352c7dfd93071c08b14930cca2e82a08d4reed@android.com */ 40543ed9352c7dfd93071c08b14930cca2e82a08d4reed@android.com bool isEmpty() const { return fBounds.isEmpty(); } 41543ed9352c7dfd93071c08b14930cca2e82a08d4reed@android.com 428a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com /** Return the byte size of the mask, assuming only 1 plane. 43543ed9352c7dfd93071c08b14930cca2e82a08d4reed@android.com Does not account for k3D_Format. For that, use computeTotalImageSize(). 44543ed9352c7dfd93071c08b14930cca2e82a08d4reed@android.com If there is an overflow of 32bits, then returns 0. 458a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com */ 468a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com size_t computeImageSize() const; 4749f0ff25a046d6001dc2d095b6fa3c30f0f46b6areed@android.com 488a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com /** Return the byte size of the mask, taking into account 498a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com any extra planes (e.g. k3D_Format). 50543ed9352c7dfd93071c08b14930cca2e82a08d4reed@android.com If there is an overflow of 32bits, then returns 0. 518a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com */ 528a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com size_t computeTotalImageSize() const; 538a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 548a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com /** Returns the address of the byte that holds the specified bit. 558a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com Asserts that the mask is kBW_Format, and that x,y are in range. 568a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com x,y are in the same coordiate space as fBounds. 578a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com */ 5849f0ff25a046d6001dc2d095b6fa3c30f0f46b6areed@android.com uint8_t* getAddr1(int x, int y) const { 59edb606cb999887d54629f361bcbf57c5fede1bb0reed@google.com SkASSERT(kBW_Format == fFormat); 608a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkASSERT(fBounds.contains(x, y)); 618a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkASSERT(fImage != NULL); 628a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com return fImage + ((x - fBounds.fLeft) >> 3) + (y - fBounds.fTop) * fRowBytes; 638a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 6449f0ff25a046d6001dc2d095b6fa3c30f0f46b6areed@android.com 658a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com /** Returns the address of the specified byte. 668a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com Asserts that the mask is kA8_Format, and that x,y are in range. 678a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com x,y are in the same coordiate space as fBounds. 688a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com */ 697989186dab6bc2f1c1927daf91bddd32b7fd8d0creed@google.com uint8_t* getAddr8(int x, int y) const { 70edb606cb999887d54629f361bcbf57c5fede1bb0reed@google.com SkASSERT(kA8_Format == fFormat); 718a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkASSERT(fBounds.contains(x, y)); 728a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkASSERT(fImage != NULL); 738a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com return fImage + x - fBounds.fLeft + (y - fBounds.fTop) * fRowBytes; 748a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 758a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 76f88d6765a594cf9fb0825b74779f74394a7ccc7areed@google.com /** 77f88d6765a594cf9fb0825b74779f74394a7ccc7areed@google.com * Return the address of the specified 16bit mask. In the debug build, 78f88d6765a594cf9fb0825b74779f74394a7ccc7areed@google.com * this asserts that the mask's format is kLCD16_Format, and that (x,y) 79f88d6765a594cf9fb0825b74779f74394a7ccc7areed@google.com * are contained in the mask's fBounds. 80f88d6765a594cf9fb0825b74779f74394a7ccc7areed@google.com */ 81f88d6765a594cf9fb0825b74779f74394a7ccc7areed@google.com uint16_t* getAddrLCD16(int x, int y) const { 82f88d6765a594cf9fb0825b74779f74394a7ccc7areed@google.com SkASSERT(kLCD16_Format == fFormat); 83f88d6765a594cf9fb0825b74779f74394a7ccc7areed@google.com SkASSERT(fBounds.contains(x, y)); 84f88d6765a594cf9fb0825b74779f74394a7ccc7areed@google.com SkASSERT(fImage != NULL); 85f88d6765a594cf9fb0825b74779f74394a7ccc7areed@google.com uint16_t* row = (uint16_t*)(fImage + (y - fBounds.fTop) * fRowBytes); 86f88d6765a594cf9fb0825b74779f74394a7ccc7areed@google.com return row + (x - fBounds.fLeft); 87f88d6765a594cf9fb0825b74779f74394a7ccc7areed@google.com } 88f88d6765a594cf9fb0825b74779f74394a7ccc7areed@google.com 891eeaf0ba2381f84ffd889f56303cbe0d1886bb21caryclark@google.com /** 901eeaf0ba2381f84ffd889f56303cbe0d1886bb21caryclark@google.com * Return the address of the specified 32bit mask. In the debug build, 911eeaf0ba2381f84ffd889f56303cbe0d1886bb21caryclark@google.com * this asserts that the mask's format is kLCD32_Format, and that (x,y) 921eeaf0ba2381f84ffd889f56303cbe0d1886bb21caryclark@google.com * are contained in the mask's fBounds. 931eeaf0ba2381f84ffd889f56303cbe0d1886bb21caryclark@google.com */ 941eeaf0ba2381f84ffd889f56303cbe0d1886bb21caryclark@google.com uint32_t* getAddrLCD32(int x, int y) const { 951eeaf0ba2381f84ffd889f56303cbe0d1886bb21caryclark@google.com SkASSERT(kLCD32_Format == fFormat); 961eeaf0ba2381f84ffd889f56303cbe0d1886bb21caryclark@google.com SkASSERT(fBounds.contains(x, y)); 971eeaf0ba2381f84ffd889f56303cbe0d1886bb21caryclark@google.com SkASSERT(fImage != NULL); 981eeaf0ba2381f84ffd889f56303cbe0d1886bb21caryclark@google.com uint32_t* row = (uint32_t*)(fImage + (y - fBounds.fTop) * fRowBytes); 991eeaf0ba2381f84ffd889f56303cbe0d1886bb21caryclark@google.com return row + (x - fBounds.fLeft); 1001eeaf0ba2381f84ffd889f56303cbe0d1886bb21caryclark@google.com } 1012fd42c471c77f54ace35c13975651e17d5b2e8c6skia.committer@gmail.com 1025bdfb331ac650cf464baa96a49e2473ee10a515creed@google.com /** 1035bdfb331ac650cf464baa96a49e2473ee10a515creed@google.com * Return the address of the specified 32bit mask. In the debug build, 1045bdfb331ac650cf464baa96a49e2473ee10a515creed@google.com * this asserts that the mask's format is 32bits, and that (x,y) 1055bdfb331ac650cf464baa96a49e2473ee10a515creed@google.com * are contained in the mask's fBounds. 1065bdfb331ac650cf464baa96a49e2473ee10a515creed@google.com */ 1075bdfb331ac650cf464baa96a49e2473ee10a515creed@google.com uint32_t* getAddr32(int x, int y) const { 1085bdfb331ac650cf464baa96a49e2473ee10a515creed@google.com SkASSERT(kLCD32_Format == fFormat || kARGB32_Format == fFormat); 1095bdfb331ac650cf464baa96a49e2473ee10a515creed@google.com SkASSERT(fBounds.contains(x, y)); 1105bdfb331ac650cf464baa96a49e2473ee10a515creed@google.com SkASSERT(fImage != NULL); 1115bdfb331ac650cf464baa96a49e2473ee10a515creed@google.com uint32_t* row = (uint32_t*)(fImage + (y - fBounds.fTop) * fRowBytes); 1125bdfb331ac650cf464baa96a49e2473ee10a515creed@google.com return row + (x - fBounds.fLeft); 1135bdfb331ac650cf464baa96a49e2473ee10a515creed@google.com } 1142fd42c471c77f54ace35c13975651e17d5b2e8c6skia.committer@gmail.com 115f52e55543e8e34a9fc9dd6f6f2d0e14e25d97ba5reed@google.com /** 116f52e55543e8e34a9fc9dd6f6f2d0e14e25d97ba5reed@google.com * Returns the address of the specified pixel, computing the pixel-size 117f52e55543e8e34a9fc9dd6f6f2d0e14e25d97ba5reed@google.com * at runtime based on the mask format. This will be slightly slower than 118f52e55543e8e34a9fc9dd6f6f2d0e14e25d97ba5reed@google.com * using one of the routines where the format is implied by the name 119f52e55543e8e34a9fc9dd6f6f2d0e14e25d97ba5reed@google.com * e.g. getAddr8 or getAddrLCD32. 120f52e55543e8e34a9fc9dd6f6f2d0e14e25d97ba5reed@google.com * 121f52e55543e8e34a9fc9dd6f6f2d0e14e25d97ba5reed@google.com * x,y must be contained by the mask's bounds (this is asserted in the 122f52e55543e8e34a9fc9dd6f6f2d0e14e25d97ba5reed@google.com * debug build, but not checked in the release build.) 123f52e55543e8e34a9fc9dd6f6f2d0e14e25d97ba5reed@google.com * 124f52e55543e8e34a9fc9dd6f6f2d0e14e25d97ba5reed@google.com * This should not be called with kBW_Format, as it will give unspecified 125f52e55543e8e34a9fc9dd6f6f2d0e14e25d97ba5reed@google.com * results (and assert in the debug build). 126f52e55543e8e34a9fc9dd6f6f2d0e14e25d97ba5reed@google.com */ 127f52e55543e8e34a9fc9dd6f6f2d0e14e25d97ba5reed@google.com void* getAddr(int x, int y) const; 128f52e55543e8e34a9fc9dd6f6f2d0e14e25d97ba5reed@google.com 1298a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com static uint8_t* AllocImage(size_t bytes); 1308a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com static void FreeImage(void* image); 131f88d6765a594cf9fb0825b74779f74394a7ccc7areed@google.com 1328a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com enum CreateMode { 1338a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com kJustComputeBounds_CreateMode, //!< compute bounds and return 1348a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com kJustRenderImage_CreateMode, //!< render into preallocate mask 1358a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com kComputeBoundsAndRenderImage_CreateMode //!< compute bounds, alloc image and render into it 1368a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com }; 1378a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com}; 1388a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 13986b49d2ef316989a5b0b5bd533eda43438d988e3reed@google.com/////////////////////////////////////////////////////////////////////////////// 14086b49d2ef316989a5b0b5bd533eda43438d988e3reed@google.com 14186b49d2ef316989a5b0b5bd533eda43438d988e3reed@google.com/** 14286b49d2ef316989a5b0b5bd533eda43438d988e3reed@google.com * \class SkAutoMaskImage 14386b49d2ef316989a5b0b5bd533eda43438d988e3reed@google.com * 14486b49d2ef316989a5b0b5bd533eda43438d988e3reed@google.com * Stack class used to manage the fImage buffer in a SkMask. 14586b49d2ef316989a5b0b5bd533eda43438d988e3reed@google.com * When this object loses scope, the buffer is freed with SkMask::FreeImage(). 14686b49d2ef316989a5b0b5bd533eda43438d988e3reed@google.com */ 14786b49d2ef316989a5b0b5bd533eda43438d988e3reed@google.comclass SkAutoMaskFreeImage { 14886b49d2ef316989a5b0b5bd533eda43438d988e3reed@google.compublic: 14986b49d2ef316989a5b0b5bd533eda43438d988e3reed@google.com SkAutoMaskFreeImage(uint8_t* maskImage) { 15086b49d2ef316989a5b0b5bd533eda43438d988e3reed@google.com fImage = maskImage; 15186b49d2ef316989a5b0b5bd533eda43438d988e3reed@google.com } 152fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.com 15386b49d2ef316989a5b0b5bd533eda43438d988e3reed@google.com ~SkAutoMaskFreeImage() { 15486b49d2ef316989a5b0b5bd533eda43438d988e3reed@google.com SkMask::FreeImage(fImage); 15586b49d2ef316989a5b0b5bd533eda43438d988e3reed@google.com } 15686b49d2ef316989a5b0b5bd533eda43438d988e3reed@google.com 15786b49d2ef316989a5b0b5bd533eda43438d988e3reed@google.comprivate: 15886b49d2ef316989a5b0b5bd533eda43438d988e3reed@google.com uint8_t* fImage; 15986b49d2ef316989a5b0b5bd533eda43438d988e3reed@google.com}; 160e61a86cfa00ea393ecc4a71fca94e1d476a37ecccommit-bot@chromium.org#define SkAutoMaskFreeImage(...) SK_REQUIRE_LOCAL_VAR(SkAutoMaskFreeImage) 16186b49d2ef316989a5b0b5bd533eda43438d988e3reed@google.com 1628a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#endif 163