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