11cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger 21cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger/* 31cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger * Copyright 2011 Google Inc. 41cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger * 51cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger * Use of this source code is governed by a BSD-style license that can be 61cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger * found in the LICENSE file. 71cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger */ 80910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project#include "SkDevice.h" 90910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project#include "SkDraw.h" 101cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger#include "SkImageFilter.h" 1187b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenberger#include "SkMetaData.h" 120910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project#include "SkRect.h" 130910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 1435e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenberger/////////////////////////////////////////////////////////////////////////////// 1535e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenberger 161cab2921ab279367f8206cdadc9259d12e603548Derek SollenbergerSkDevice::SkDevice(const SkBitmap& bitmap) : fBitmap(bitmap) { 1705b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger fOrigin.setZero(); 181cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger fMetaData = NULL; 1905b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger} 2040528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger 211cab2921ab279367f8206cdadc9259d12e603548Derek SollenbergerSkDevice::SkDevice(SkBitmap::Config config, int width, int height, bool isOpaque) { 2205b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger fOrigin.setZero(); 231cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger fMetaData = NULL; 241cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger 251cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger fBitmap.setConfig(config, width, height); 261cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger fBitmap.allocPixels(); 271cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger fBitmap.setIsOpaque(isOpaque); 281cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger if (!isOpaque) { 291cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger fBitmap.eraseColor(0); 3040528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger } 3140528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger} 320910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 3387b8e645865f9633f410c02252a0fd3feb18f09bDerek SollenbergerSkDevice::~SkDevice() { 3487b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenberger delete fMetaData; 3535e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenberger} 3635e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenberger 374f1dae40e24d57d647db01443b8bf2410514b8b5Derek SollenbergerSkDevice* SkDevice::createCompatibleDevice(SkBitmap::Config config, 381cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger int width, int height, 391cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger bool isOpaque) { 401cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger return this->onCreateCompatibleDevice(config, width, height, 411cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger isOpaque, kGeneral_Usage); 4235e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenberger} 4335e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenberger 441cab2921ab279367f8206cdadc9259d12e603548Derek SollenbergerSkDevice* SkDevice::createCompatibleDeviceForSaveLayer(SkBitmap::Config config, 451cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger int width, int height, 461cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger bool isOpaque) { 471cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger return this->onCreateCompatibleDevice(config, width, height, 481cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger isOpaque, kSaveLayer_Usage); 491cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger} 501cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger 514f1dae40e24d57d647db01443b8bf2410514b8b5Derek SollenbergerSkDevice* SkDevice::onCreateCompatibleDevice(SkBitmap::Config config, 524f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger int width, int height, 531cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger bool isOpaque, 541cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger Usage usage) { 551cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger return SkNEW_ARGS(SkDevice,(config, width, height, isOpaque)); 5687b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenberger} 5787b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenberger 5887b8e645865f9633f410c02252a0fd3feb18f09bDerek SollenbergerSkMetaData& SkDevice::getMetaData() { 5987b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenberger // metadata users are rare, so we lazily allocate it. If that changes we 6087b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenberger // can decide to just make it a field in the device (rather than a ptr) 6187b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenberger if (NULL == fMetaData) { 6287b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenberger fMetaData = new SkMetaData; 6387b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenberger } 6487b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenberger return *fMetaData; 6587b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenberger} 6687b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenberger 670910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Projectvoid SkDevice::lockPixels() { 681cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger if (fBitmap.lockPixelsAreWritable()) { 691cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger fBitmap.lockPixels(); 701cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger } 710910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project} 720910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 730910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Projectvoid SkDevice::unlockPixels() { 741cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger if (fBitmap.lockPixelsAreWritable()) { 751cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger fBitmap.unlockPixels(); 761cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger } 770910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project} 780910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 790910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Projectconst SkBitmap& SkDevice::accessBitmap(bool changePixels) { 804f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger const SkBitmap& bitmap = this->onAccessBitmap(&fBitmap); 810910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project if (changePixels) { 824f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger bitmap.notifyPixelsChanged(); 830910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project } 844f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger return bitmap; 850910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project} 860910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 871cab2921ab279367f8206cdadc9259d12e603548Derek Sollenbergervoid SkDevice::getGlobalBounds(SkIRect* bounds) const { 880910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project if (bounds) { 891cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger bounds->setXYWH(fOrigin.x(), fOrigin.y(), 901cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger fBitmap.width(), fBitmap.height()); 910910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project } 920910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project} 930910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 9435e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenbergervoid SkDevice::clear(SkColor color) { 9535e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenberger fBitmap.eraseColor(color); 960910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project} 970910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 984f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenbergerconst SkBitmap& SkDevice::onAccessBitmap(SkBitmap* bitmap) {return *bitmap;} 990910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 10035e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenbergervoid SkDevice::setMatrixClip(const SkMatrix& matrix, const SkRegion& region, 10135e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenberger const SkClipStack& clipStack) { 10235e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenberger} 1030910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 1041cab2921ab279367f8206cdadc9259d12e603548Derek Sollenbergerbool SkDevice::filterImage(SkImageFilter*, const SkBitmap& src, 1051cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger const SkMatrix& ctm, 1061cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger SkBitmap* result, SkIPoint* offset) { 1071cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger return false; 1081cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger} 1090910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 1101cab2921ab279367f8206cdadc9259d12e603548Derek Sollenbergerbool SkDevice::allowImageFilter(SkImageFilter*) { 1111cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger return true; 1121cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger} 11340528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger 1141cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger/////////////////////////////////////////////////////////////////////////////// 1151cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger 1161cab2921ab279367f8206cdadc9259d12e603548Derek Sollenbergerbool SkDevice::readPixels(SkBitmap* bitmap, int x, int y, 1171cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger SkCanvas::Config8888 config8888) { 1181cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger if (SkBitmap::kARGB_8888_Config != bitmap->config() || 1191cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger NULL != bitmap->getTexture()) { 12040528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger return false; 12140528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger } 12240528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger 1231cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger const SkBitmap& src = this->accessBitmap(false); 1241cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger 1251cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger SkIRect srcRect = SkIRect::MakeXYWH(x, y, bitmap->width(), 1261cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger bitmap->height()); 1271cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger SkIRect devbounds = SkIRect::MakeWH(src.width(), src.height()); 1281cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger if (!srcRect.intersect(devbounds)) { 12940528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger return false; 13040528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger } 13140528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger 13240528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger SkBitmap tmp; 1331cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger SkBitmap* bmp; 1341cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger if (bitmap->isNull()) { 1351cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger tmp.setConfig(SkBitmap::kARGB_8888_Config, bitmap->width(), 1361cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger bitmap->height()); 1371cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger if (!tmp.allocPixels()) { 1381cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger return false; 1391cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger } 1401cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger bmp = &tmp; 1411cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger } else { 1421cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger bmp = bitmap; 1431cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger } 1441cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger 1451cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger SkIRect subrect = srcRect; 1461cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger subrect.offset(-x, -y); 1471cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger SkBitmap bmpSubset; 1481cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger bmp->extractSubset(&bmpSubset, subrect); 1491cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger 1501cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger bool result = this->onReadPixels(bmpSubset, 1511cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger srcRect.fLeft, 1521cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger srcRect.fTop, 1531cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger config8888); 1541cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger if (result && bmp == &tmp) { 1551cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger tmp.swap(*bitmap); 15640528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger } 1571cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger return result; 1581cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger} 1591cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger 1601cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger#ifdef SK_CPU_LENDIAN 1611cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger #if 24 == SK_A32_SHIFT && 16 == SK_R32_SHIFT && \ 1621cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger 8 == SK_G32_SHIFT && 0 == SK_B32_SHIFT 1631cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger const SkCanvas::Config8888 SkDevice::kPMColorAlias = 1641cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger SkCanvas::kBGRA_Premul_Config8888; 1651cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger #elif 24 == SK_A32_SHIFT && 0 == SK_R32_SHIFT && \ 1661cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger 8 == SK_G32_SHIFT && 16 == SK_B32_SHIFT 1671cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger const SkCanvas::Config8888 SkDevice::kPMColorAlias = 1681cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger SkCanvas::kRGBA_Premul_Config8888; 1691cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger #else 1701cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger const SkCanvas::Config8888 SkDevice::kPMColorAlias = 1711cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger (SkCanvas::Config8888) -1; 1721cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger #endif 1731cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger#else 1741cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger #if 0 == SK_A32_SHIFT && 8 == SK_R32_SHIFT && \ 1751cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger 16 == SK_G32_SHIFT && 24 == SK_B32_SHIFT 1761cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger const SkCanvas::Config8888 SkDevice::kPMColorAlias = 1771cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger SkCanvas::kBGRA_Premul_Config8888; 1781cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger #elif 0 == SK_A32_SHIFT && 24 == SK_R32_SHIFT && \ 1791cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger 16 == SK_G32_SHIFT && 8 == SK_B32_SHIFT 1801cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger const SkCanvas::Config8888 SkDevice::kPMColorAlias = 1811cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger SkCanvas::kRGBA_Premul_Config8888; 1821cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger #else 1831cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger const SkCanvas::Config8888 SkDevice::kPMColorAlias = 1841cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger (SkCanvas::Config8888) -1; 1851cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger #endif 1861cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger#endif 18740528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger 1881cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger#include <SkConfig8888.h> 1891cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger 1901cab2921ab279367f8206cdadc9259d12e603548Derek Sollenbergerbool SkDevice::onReadPixels(const SkBitmap& bitmap, 1911cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger int x, int y, 1921cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger SkCanvas::Config8888 config8888) { 1931cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger SkASSERT(SkBitmap::kARGB_8888_Config == bitmap.config()); 1941cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger SkASSERT(!bitmap.isNull()); 1951cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger SkASSERT(SkIRect::MakeWH(this->width(), this->height()).contains(SkIRect::MakeXYWH(x, y, bitmap.width(), bitmap.height()))); 1961cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger 1971cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger SkIRect srcRect = SkIRect::MakeXYWH(x, y, bitmap.width(), 1981cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger bitmap.height()); 1991cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger const SkBitmap& src = this->accessBitmap(false); 2001cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger 2011cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger SkBitmap subset; 2021cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger if (!src.extractSubset(&subset, srcRect)) { 2031cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger return false; 2041cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger } 2051cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger if (SkBitmap::kARGB_8888_Config != subset.config()) { 2061cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger // It'd be preferable to do this directly to bitmap. 2074f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger subset.copyTo(&subset, SkBitmap::kARGB_8888_Config); 2081cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger } 2091cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger SkAutoLockPixels alp(bitmap); 2101cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger uint32_t* bmpPixels = reinterpret_cast<uint32_t*>(bitmap.getPixels()); 2114f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger SkCopyBitmapToConfig8888(bmpPixels, bitmap.rowBytes(), config8888, subset); 21240528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger return true; 21340528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger} 21440528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger 2151cab2921ab279367f8206cdadc9259d12e603548Derek Sollenbergervoid SkDevice::writePixels(const SkBitmap& bitmap, 2161cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger int x, int y, 2171cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger SkCanvas::Config8888 config8888) { 2181cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger if (bitmap.isNull() || bitmap.getTexture()) { 2191cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger return; 2201cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger } 2211cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger const SkBitmap* sprite = &bitmap; 2221cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger // check whether we have to handle a config8888 that doesn't match SkPMColor 2231cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger if (SkBitmap::kARGB_8888_Config == bitmap.config() && 2241cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger SkCanvas::kNative_Premul_Config8888 != config8888 && 2251cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger kPMColorAlias != config8888) { 2261cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger 2271cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger // We're going to have to convert from a config8888 to the native config 2281cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger // First we clip to the device bounds. 2291cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger SkBitmap dstBmp = this->accessBitmap(true); 2301cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger SkIRect spriteRect = SkIRect::MakeXYWH(x, y, 2311cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger bitmap.width(), bitmap.height()); 2321cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger SkIRect devRect = SkIRect::MakeWH(dstBmp.width(), dstBmp.height()); 2331cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger if (!spriteRect.intersect(devRect)) { 2341cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger return; 2351cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger } 2361cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger 2371cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger // write directly to the device if it has pixels and is SkPMColor 2381cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger bool drawSprite; 2391cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger if (SkBitmap::kARGB_8888_Config == dstBmp.config() && !dstBmp.isNull()) { 2401cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger // we can write directly to the dst when doing the conversion 2411cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger dstBmp.extractSubset(&dstBmp, spriteRect); 2421cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger drawSprite = false; 2431cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger } else { 2441cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger // we convert to a temporary bitmap and draw that as a sprite 2451cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger dstBmp.setConfig(SkBitmap::kARGB_8888_Config, 2461cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger spriteRect.width(), 2471cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger spriteRect.height()); 2481cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger if (!dstBmp.allocPixels()) { 2491cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger return; 2501cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger } 2511cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger drawSprite = true; 2521cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger } 2531cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger 2541cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger // copy pixels to dstBmp and convert from config8888 to native config. 2551cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger SkAutoLockPixels alp(bitmap); 2561cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger uint32_t* srcPixels = bitmap.getAddr32(spriteRect.fLeft - x, 2571cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger spriteRect.fTop - y); 2581cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger SkCopyConfig8888ToBitmap(dstBmp, 2591cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger srcPixels, 2601cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger bitmap.rowBytes(), 2611cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger config8888); 2621cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger 2631cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger if (drawSprite) { 2641cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger // we've clipped the sprite when we made a copy 2651cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger x = spriteRect.fLeft; 2661cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger y = spriteRect.fTop; 2671cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger sprite = &dstBmp; 2681cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger } else { 2691cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger return; 2701cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger } 2711cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger } 2721cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger 27340528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger SkPaint paint; 27440528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger paint.setXfermodeMode(SkXfermode::kSrc_Mode); 27540528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger SkCanvas canvas(this); 2761cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger canvas.drawSprite(*sprite, x, y, &paint); 27740528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger} 27840528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger 27940528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger/////////////////////////////////////////////////////////////////////////////// 28040528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger 2810910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Projectvoid SkDevice::drawPaint(const SkDraw& draw, const SkPaint& paint) { 2820910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project draw.drawPaint(paint); 2830910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project} 2840910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 2850910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Projectvoid SkDevice::drawPoints(const SkDraw& draw, SkCanvas::PointMode mode, size_t count, 2860910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project const SkPoint pts[], const SkPaint& paint) { 2870910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project draw.drawPoints(mode, count, pts, paint); 2880910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project} 2890910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 2900910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Projectvoid SkDevice::drawRect(const SkDraw& draw, const SkRect& r, 2910910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project const SkPaint& paint) { 2920910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project draw.drawRect(r, paint); 2930910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project} 2940910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 2950910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Projectvoid SkDevice::drawPath(const SkDraw& draw, const SkPath& path, 29640528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger const SkPaint& paint, const SkMatrix* prePathMatrix, 29740528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger bool pathIsMutable) { 29840528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger draw.drawPath(path, paint, prePathMatrix, pathIsMutable); 2990910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project} 3000910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 3010910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Projectvoid SkDevice::drawBitmap(const SkDraw& draw, const SkBitmap& bitmap, 30240528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger const SkIRect* srcRect, 30340528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger const SkMatrix& matrix, const SkPaint& paint) { 30440528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger SkBitmap tmp; // storage if we need a subset of bitmap 30540528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger const SkBitmap* bitmapPtr = &bitmap; 30671531ca1f484da5837be8017a0c83e5bff701587Derek Sollenberger 30740528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger if (srcRect) { 30840528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger if (!bitmap.extractSubset(&tmp, *srcRect)) { 30940528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger return; // extraction failed 31040528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger } 31140528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger bitmapPtr = &tmp; 31240528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger } 31340528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger draw.drawBitmap(*bitmapPtr, matrix, paint); 3140910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project} 3150910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 3160910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Projectvoid SkDevice::drawSprite(const SkDraw& draw, const SkBitmap& bitmap, 3170910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project int x, int y, const SkPaint& paint) { 3180910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project draw.drawSprite(bitmap, x, y, paint); 3190910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project} 3200910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 3210910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Projectvoid SkDevice::drawText(const SkDraw& draw, const void* text, size_t len, 3220910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project SkScalar x, SkScalar y, const SkPaint& paint) { 3230910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project draw.drawText((const char*)text, len, x, y, paint); 3240910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project} 3250910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 3260910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Projectvoid SkDevice::drawPosText(const SkDraw& draw, const void* text, size_t len, 3270910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project const SkScalar xpos[], SkScalar y, 3280910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project int scalarsPerPos, const SkPaint& paint) { 3290910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project draw.drawPosText((const char*)text, len, xpos, y, scalarsPerPos, paint); 3300910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project} 3310910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 3320910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Projectvoid SkDevice::drawTextOnPath(const SkDraw& draw, const void* text, 3330910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project size_t len, const SkPath& path, 3340910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project const SkMatrix* matrix, 3350910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project const SkPaint& paint) { 3360910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project draw.drawTextOnPath((const char*)text, len, path, matrix, paint); 3370910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project} 3380910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 3391cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger#ifdef SK_BUILD_FOR_ANDROID 340a2dfb00239c367c3663e8487a8213d0edad238baAndreas Borglinvoid SkDevice::drawPosTextOnPath(const SkDraw& draw, const void* text, size_t len, 341a2dfb00239c367c3663e8487a8213d0edad238baAndreas Borglin const SkPoint pos[], const SkPaint& paint, 342a2dfb00239c367c3663e8487a8213d0edad238baAndreas Borglin const SkPath& path, const SkMatrix* matrix) { 343a2dfb00239c367c3663e8487a8213d0edad238baAndreas Borglin draw.drawPosTextOnPath((const char*)text, len, pos, paint, path, matrix); 344a2dfb00239c367c3663e8487a8213d0edad238baAndreas Borglin} 34505b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger#endif 346a2dfb00239c367c3663e8487a8213d0edad238baAndreas Borglin 3470910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Projectvoid SkDevice::drawVertices(const SkDraw& draw, SkCanvas::VertexMode vmode, 3480910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project int vertexCount, 3490910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project const SkPoint verts[], const SkPoint textures[], 3500910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project const SkColor colors[], SkXfermode* xmode, 3510910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project const uint16_t indices[], int indexCount, 3520910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project const SkPaint& paint) { 3530910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project draw.drawVertices(vmode, vertexCount, verts, textures, colors, xmode, 3540910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project indices, indexCount, paint); 3550910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project} 3560910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 3570910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Projectvoid SkDevice::drawDevice(const SkDraw& draw, SkDevice* device, 3580910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project int x, int y, const SkPaint& paint) { 3591cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger const SkBitmap& src = device->accessBitmap(false); 3601cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger draw.drawSprite(src, x, y, paint); 3610910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project} 3620910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 36340528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger/////////////////////////////////////////////////////////////////////////////// 36440528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger 365137a4ca42423bbb6d683067ea544c9a48f18f06cDerek Sollenbergerbool SkDevice::filterTextFlags(const SkPaint& paint, TextFlags* flags) { 3661cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger if (!paint.isLCDRenderText() || !paint.isAntiAlias()) { 367137a4ca42423bbb6d683067ea544c9a48f18f06cDerek Sollenberger // we're cool with the paint as is 368137a4ca42423bbb6d683067ea544c9a48f18f06cDerek Sollenberger return false; 369137a4ca42423bbb6d683067ea544c9a48f18f06cDerek Sollenberger } 370137a4ca42423bbb6d683067ea544c9a48f18f06cDerek Sollenberger 371137a4ca42423bbb6d683067ea544c9a48f18f06cDerek Sollenberger if (SkBitmap::kARGB_8888_Config != fBitmap.config() || 372137a4ca42423bbb6d683067ea544c9a48f18f06cDerek Sollenberger paint.getRasterizer() || 373137a4ca42423bbb6d683067ea544c9a48f18f06cDerek Sollenberger paint.getPathEffect() || 374137a4ca42423bbb6d683067ea544c9a48f18f06cDerek Sollenberger paint.isFakeBoldText() || 3751cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger paint.getStyle() != SkPaint::kFill_Style || 3761cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger !SkXfermode::IsMode(paint.getXfermode(), SkXfermode::kSrcOver_Mode)) { 377137a4ca42423bbb6d683067ea544c9a48f18f06cDerek Sollenberger // turn off lcd 378137a4ca42423bbb6d683067ea544c9a48f18f06cDerek Sollenberger flags->fFlags = paint.getFlags() & ~SkPaint::kLCDRenderText_Flag; 379137a4ca42423bbb6d683067ea544c9a48f18f06cDerek Sollenberger flags->fHinting = paint.getHinting(); 380137a4ca42423bbb6d683067ea544c9a48f18f06cDerek Sollenberger return true; 381137a4ca42423bbb6d683067ea544c9a48f18f06cDerek Sollenberger } 382137a4ca42423bbb6d683067ea544c9a48f18f06cDerek Sollenberger // we're cool with the paint as is 383137a4ca42423bbb6d683067ea544c9a48f18f06cDerek Sollenberger return false; 384137a4ca42423bbb6d683067ea544c9a48f18f06cDerek Sollenberger} 385137a4ca42423bbb6d683067ea544c9a48f18f06cDerek Sollenberger 386