SkBitmapDevice.cpp revision 76033be81b82c44fd5d4fdf2672eb22e505da1f0
153238bc96051d1774b7f72d3ebfd35a7dd4c04dfrobertphillips@google.com/*
253238bc96051d1774b7f72d3ebfd35a7dd4c04dfrobertphillips@google.com * Copyright 2013 Google Inc.
353238bc96051d1774b7f72d3ebfd35a7dd4c04dfrobertphillips@google.com *
453238bc96051d1774b7f72d3ebfd35a7dd4c04dfrobertphillips@google.com * Use of this source code is governed by a BSD-style license that can be
553238bc96051d1774b7f72d3ebfd35a7dd4c04dfrobertphillips@google.com * found in the LICENSE file.
653238bc96051d1774b7f72d3ebfd35a7dd4c04dfrobertphillips@google.com */
753238bc96051d1774b7f72d3ebfd35a7dd4c04dfrobertphillips@google.com
853238bc96051d1774b7f72d3ebfd35a7dd4c04dfrobertphillips@google.com#include "SkBitmapDevice.h"
953238bc96051d1774b7f72d3ebfd35a7dd4c04dfrobertphillips@google.com#include "SkConfig8888.h"
10b2db898573e3cdcc8234eebf51961bfc4977ebbcreed#include "SkDeviceProperties.h"
1153238bc96051d1774b7f72d3ebfd35a7dd4c04dfrobertphillips@google.com#include "SkDraw.h"
1253238bc96051d1774b7f72d3ebfd35a7dd4c04dfrobertphillips@google.com#include "SkRasterClip.h"
1353238bc96051d1774b7f72d3ebfd35a7dd4c04dfrobertphillips@google.com#include "SkShader.h"
1476f10a3bd936af7dbe2b5873d5a7eedd73cdc5dareed@google.com#include "SkSurface.h"
1553238bc96051d1774b7f72d3ebfd35a7dd4c04dfrobertphillips@google.com
164469938e92d779dff05e745559e67907bbf21e78reed@google.com#define CHECK_FOR_ANNOTATION(paint) \
174469938e92d779dff05e745559e67907bbf21e78reed@google.com    do { if (paint.getAnnotation()) { return; } } while (0)
1853238bc96051d1774b7f72d3ebfd35a7dd4c04dfrobertphillips@google.com
1915a140599942f70e47380e3f700a825c7cece3b4commit-bot@chromium.orgstatic bool valid_for_bitmap_device(const SkImageInfo& info,
2015a140599942f70e47380e3f700a825c7cece3b4commit-bot@chromium.org                                    SkAlphaType* newAlphaType) {
2115a140599942f70e47380e3f700a825c7cece3b4commit-bot@chromium.org    if (info.width() < 0 || info.height() < 0) {
2215a140599942f70e47380e3f700a825c7cece3b4commit-bot@chromium.org        return false;
2315a140599942f70e47380e3f700a825c7cece3b4commit-bot@chromium.org    }
2415a140599942f70e47380e3f700a825c7cece3b4commit-bot@chromium.org
2515a140599942f70e47380e3f700a825c7cece3b4commit-bot@chromium.org    // TODO: can we stop supporting kUnknown in SkBitmkapDevice?
2615a140599942f70e47380e3f700a825c7cece3b4commit-bot@chromium.org    if (kUnknown_SkColorType == info.colorType()) {
2715a140599942f70e47380e3f700a825c7cece3b4commit-bot@chromium.org        if (newAlphaType) {
2844977485bdac75c055c3fa638f118874ccd2d22freed            *newAlphaType = kUnknown_SkAlphaType;
2915a140599942f70e47380e3f700a825c7cece3b4commit-bot@chromium.org        }
3015a140599942f70e47380e3f700a825c7cece3b4commit-bot@chromium.org        return true;
3115a140599942f70e47380e3f700a825c7cece3b4commit-bot@chromium.org    }
32969588f0c9030d5a4942085a4b5a5ea7e8d2bc25skia.committer@gmail.com
3315a140599942f70e47380e3f700a825c7cece3b4commit-bot@chromium.org    switch (info.alphaType()) {
3415a140599942f70e47380e3f700a825c7cece3b4commit-bot@chromium.org        case kPremul_SkAlphaType:
3515a140599942f70e47380e3f700a825c7cece3b4commit-bot@chromium.org        case kOpaque_SkAlphaType:
3615a140599942f70e47380e3f700a825c7cece3b4commit-bot@chromium.org            break;
3715a140599942f70e47380e3f700a825c7cece3b4commit-bot@chromium.org        default:
3815a140599942f70e47380e3f700a825c7cece3b4commit-bot@chromium.org            return false;
3915a140599942f70e47380e3f700a825c7cece3b4commit-bot@chromium.org    }
4015a140599942f70e47380e3f700a825c7cece3b4commit-bot@chromium.org
4115a140599942f70e47380e3f700a825c7cece3b4commit-bot@chromium.org    SkAlphaType canonicalAlphaType = info.alphaType();
4215a140599942f70e47380e3f700a825c7cece3b4commit-bot@chromium.org
4315a140599942f70e47380e3f700a825c7cece3b4commit-bot@chromium.org    switch (info.colorType()) {
4415a140599942f70e47380e3f700a825c7cece3b4commit-bot@chromium.org        case kAlpha_8_SkColorType:
4515a140599942f70e47380e3f700a825c7cece3b4commit-bot@chromium.org            break;
4615a140599942f70e47380e3f700a825c7cece3b4commit-bot@chromium.org        case kRGB_565_SkColorType:
4715a140599942f70e47380e3f700a825c7cece3b4commit-bot@chromium.org            canonicalAlphaType = kOpaque_SkAlphaType;
4815a140599942f70e47380e3f700a825c7cece3b4commit-bot@chromium.org            break;
4928fcae2ec77eb16a79e155f8d788b20457f1c951commit-bot@chromium.org        case kN32_SkColorType:
5015a140599942f70e47380e3f700a825c7cece3b4commit-bot@chromium.org            break;
5115a140599942f70e47380e3f700a825c7cece3b4commit-bot@chromium.org        default:
5215a140599942f70e47380e3f700a825c7cece3b4commit-bot@chromium.org            return false;
5315a140599942f70e47380e3f700a825c7cece3b4commit-bot@chromium.org    }
5415a140599942f70e47380e3f700a825c7cece3b4commit-bot@chromium.org
5515a140599942f70e47380e3f700a825c7cece3b4commit-bot@chromium.org    if (newAlphaType) {
5615a140599942f70e47380e3f700a825c7cece3b4commit-bot@chromium.org        *newAlphaType = canonicalAlphaType;
5715a140599942f70e47380e3f700a825c7cece3b4commit-bot@chromium.org    }
5815a140599942f70e47380e3f700a825c7cece3b4commit-bot@chromium.org    return true;
5915a140599942f70e47380e3f700a825c7cece3b4commit-bot@chromium.org}
6015a140599942f70e47380e3f700a825c7cece3b4commit-bot@chromium.org
6115a140599942f70e47380e3f700a825c7cece3b4commit-bot@chromium.orgSkBitmapDevice::SkBitmapDevice(const SkBitmap& bitmap) : fBitmap(bitmap) {
6215a140599942f70e47380e3f700a825c7cece3b4commit-bot@chromium.org    SkASSERT(valid_for_bitmap_device(bitmap.info(), NULL));
6353238bc96051d1774b7f72d3ebfd35a7dd4c04dfrobertphillips@google.com}
6453238bc96051d1774b7f72d3ebfd35a7dd4c04dfrobertphillips@google.com
6553238bc96051d1774b7f72d3ebfd35a7dd4c04dfrobertphillips@google.comSkBitmapDevice::SkBitmapDevice(const SkBitmap& bitmap, const SkDeviceProperties& deviceProperties)
6653238bc96051d1774b7f72d3ebfd35a7dd4c04dfrobertphillips@google.com    : SkBaseDevice(deviceProperties)
6715a140599942f70e47380e3f700a825c7cece3b4commit-bot@chromium.org    , fBitmap(bitmap)
6815a140599942f70e47380e3f700a825c7cece3b4commit-bot@chromium.org{
6915a140599942f70e47380e3f700a825c7cece3b4commit-bot@chromium.org    SkASSERT(valid_for_bitmap_device(bitmap.info(), NULL));
7053238bc96051d1774b7f72d3ebfd35a7dd4c04dfrobertphillips@google.com}
7153238bc96051d1774b7f72d3ebfd35a7dd4c04dfrobertphillips@google.com
7215a140599942f70e47380e3f700a825c7cece3b4commit-bot@chromium.orgSkBitmapDevice* SkBitmapDevice::Create(const SkImageInfo& origInfo,
7315a140599942f70e47380e3f700a825c7cece3b4commit-bot@chromium.org                                       const SkDeviceProperties* props) {
74e5ea500d4714a7d84de2bf913e81be3b65d2de68reed    SkAlphaType newAT = origInfo.alphaType();
75e5ea500d4714a7d84de2bf913e81be3b65d2de68reed    if (!valid_for_bitmap_device(origInfo, &newAT)) {
7615a140599942f70e47380e3f700a825c7cece3b4commit-bot@chromium.org        return NULL;
7715a140599942f70e47380e3f700a825c7cece3b4commit-bot@chromium.org    }
7815a140599942f70e47380e3f700a825c7cece3b4commit-bot@chromium.org
79e5ea500d4714a7d84de2bf913e81be3b65d2de68reed    const SkImageInfo info = origInfo.makeAlphaType(newAT);
8015a140599942f70e47380e3f700a825c7cece3b4commit-bot@chromium.org    SkBitmap bitmap;
8115a140599942f70e47380e3f700a825c7cece3b4commit-bot@chromium.org
8215a140599942f70e47380e3f700a825c7cece3b4commit-bot@chromium.org    if (kUnknown_SkColorType == info.colorType()) {
83a3264e53ee3f3c5d6a2c813df7e44b5b96d207f2commit-bot@chromium.org        if (!bitmap.setInfo(info)) {
8415a140599942f70e47380e3f700a825c7cece3b4commit-bot@chromium.org            return NULL;
8515a140599942f70e47380e3f700a825c7cece3b4commit-bot@chromium.org        }
8615a140599942f70e47380e3f700a825c7cece3b4commit-bot@chromium.org    } else {
87848250415eddc54075f7eb8795e8db79e749c6abreed        if (!bitmap.tryAllocPixels(info)) {
8815a140599942f70e47380e3f700a825c7cece3b4commit-bot@chromium.org            return NULL;
8915a140599942f70e47380e3f700a825c7cece3b4commit-bot@chromium.org        }
9015a140599942f70e47380e3f700a825c7cece3b4commit-bot@chromium.org        if (!bitmap.info().isOpaque()) {
9115a140599942f70e47380e3f700a825c7cece3b4commit-bot@chromium.org            bitmap.eraseColor(SK_ColorTRANSPARENT);
9215a140599942f70e47380e3f700a825c7cece3b4commit-bot@chromium.org        }
9315a140599942f70e47380e3f700a825c7cece3b4commit-bot@chromium.org    }
9453238bc96051d1774b7f72d3ebfd35a7dd4c04dfrobertphillips@google.com
95b2db898573e3cdcc8234eebf51961bfc4977ebbcreed    if (props) {
96b2db898573e3cdcc8234eebf51961bfc4977ebbcreed        return SkNEW_ARGS(SkBitmapDevice, (bitmap, *props));
9715a140599942f70e47380e3f700a825c7cece3b4commit-bot@chromium.org    } else {
9815a140599942f70e47380e3f700a825c7cece3b4commit-bot@chromium.org        return SkNEW_ARGS(SkBitmapDevice, (bitmap));
9915a140599942f70e47380e3f700a825c7cece3b4commit-bot@chromium.org    }
10053238bc96051d1774b7f72d3ebfd35a7dd4c04dfrobertphillips@google.com}
10153238bc96051d1774b7f72d3ebfd35a7dd4c04dfrobertphillips@google.com
102c3bd8af6d5722e854feca70c40d92f4954c5b67bcommit-bot@chromium.orgSkImageInfo SkBitmapDevice::imageInfo() const {
103c3bd8af6d5722e854feca70c40d92f4954c5b67bcommit-bot@chromium.org    return fBitmap.info();
104c3bd8af6d5722e854feca70c40d92f4954c5b67bcommit-bot@chromium.org}
105c3bd8af6d5722e854feca70c40d92f4954c5b67bcommit-bot@chromium.org
10653238bc96051d1774b7f72d3ebfd35a7dd4c04dfrobertphillips@google.comvoid SkBitmapDevice::replaceBitmapBackendForRasterSurface(const SkBitmap& bm) {
10753238bc96051d1774b7f72d3ebfd35a7dd4c04dfrobertphillips@google.com    SkASSERT(bm.width() == fBitmap.width());
10853238bc96051d1774b7f72d3ebfd35a7dd4c04dfrobertphillips@google.com    SkASSERT(bm.height() == fBitmap.height());
10953238bc96051d1774b7f72d3ebfd35a7dd4c04dfrobertphillips@google.com    fBitmap = bm;   // intent is to use bm's pixelRef (and rowbytes/config)
11053238bc96051d1774b7f72d3ebfd35a7dd4c04dfrobertphillips@google.com    fBitmap.lockPixels();
11153238bc96051d1774b7f72d3ebfd35a7dd4c04dfrobertphillips@google.com}
11253238bc96051d1774b7f72d3ebfd35a7dd4c04dfrobertphillips@google.com
11376033be81b82c44fd5d4fdf2672eb22e505da1f0reedSkBaseDevice* SkBitmapDevice::onCreateDevice(const CreateInfo& cinfo, const SkPaint*) {
114b2db898573e3cdcc8234eebf51961bfc4977ebbcreed    SkDeviceProperties leaky(cinfo.fPixelGeometry);
115b2db898573e3cdcc8234eebf51961bfc4977ebbcreed    return SkBitmapDevice::Create(cinfo.fInfo, &leaky);
11653238bc96051d1774b7f72d3ebfd35a7dd4c04dfrobertphillips@google.com}
11753238bc96051d1774b7f72d3ebfd35a7dd4c04dfrobertphillips@google.com
11853238bc96051d1774b7f72d3ebfd35a7dd4c04dfrobertphillips@google.comvoid SkBitmapDevice::lockPixels() {
11953238bc96051d1774b7f72d3ebfd35a7dd4c04dfrobertphillips@google.com    if (fBitmap.lockPixelsAreWritable()) {
12053238bc96051d1774b7f72d3ebfd35a7dd4c04dfrobertphillips@google.com        fBitmap.lockPixels();
12153238bc96051d1774b7f72d3ebfd35a7dd4c04dfrobertphillips@google.com    }
12253238bc96051d1774b7f72d3ebfd35a7dd4c04dfrobertphillips@google.com}
12353238bc96051d1774b7f72d3ebfd35a7dd4c04dfrobertphillips@google.com
12453238bc96051d1774b7f72d3ebfd35a7dd4c04dfrobertphillips@google.comvoid SkBitmapDevice::unlockPixels() {
12553238bc96051d1774b7f72d3ebfd35a7dd4c04dfrobertphillips@google.com    if (fBitmap.lockPixelsAreWritable()) {
12653238bc96051d1774b7f72d3ebfd35a7dd4c04dfrobertphillips@google.com        fBitmap.unlockPixels();
12753238bc96051d1774b7f72d3ebfd35a7dd4c04dfrobertphillips@google.com    }
12853238bc96051d1774b7f72d3ebfd35a7dd4c04dfrobertphillips@google.com}
12953238bc96051d1774b7f72d3ebfd35a7dd4c04dfrobertphillips@google.com
13053238bc96051d1774b7f72d3ebfd35a7dd4c04dfrobertphillips@google.comconst SkBitmap& SkBitmapDevice::onAccessBitmap() {
13153238bc96051d1774b7f72d3ebfd35a7dd4c04dfrobertphillips@google.com    return fBitmap;
13253238bc96051d1774b7f72d3ebfd35a7dd4c04dfrobertphillips@google.com}
13353238bc96051d1774b7f72d3ebfd35a7dd4c04dfrobertphillips@google.com
1349c135db83d198e7d8200027c7d2cf60f38517ee3reed@google.comvoid* SkBitmapDevice::onAccessPixels(SkImageInfo* info, size_t* rowBytes) {
1359c135db83d198e7d8200027c7d2cf60f38517ee3reed@google.com    if (fBitmap.getPixels()) {
1369c135db83d198e7d8200027c7d2cf60f38517ee3reed@google.com        *info = fBitmap.info();
1379c135db83d198e7d8200027c7d2cf60f38517ee3reed@google.com        *rowBytes = fBitmap.rowBytes();
1389c135db83d198e7d8200027c7d2cf60f38517ee3reed@google.com        return fBitmap.getPixels();
1399c135db83d198e7d8200027c7d2cf60f38517ee3reed@google.com    }
1409c135db83d198e7d8200027c7d2cf60f38517ee3reed@google.com    return NULL;
1419c135db83d198e7d8200027c7d2cf60f38517ee3reed@google.com}
1429c135db83d198e7d8200027c7d2cf60f38517ee3reed@google.com
143231f6b81c22001cac4ea87ea412c4d6fd10ffb8acommit-bot@chromium.org#include "SkConfig8888.h"
1440e9770515cab45decb56a5926d1741b71854fb4cpiotaixr#include "SkPixelRef.h"
1457111d463cee893a479280c7af41757e709e33ef5reed@google.com
1464cd9e2169e35cd67ee7358acea6541245e1d1744commit-bot@chromium.orgbool SkBitmapDevice::onWritePixels(const SkImageInfo& srcInfo, const void* srcPixels,
1474cd9e2169e35cd67ee7358acea6541245e1d1744commit-bot@chromium.org                                   size_t srcRowBytes, int x, int y) {
1480d30c51c6cf45b3a08a3000b6d348c16bdec7f05reed@google.com    // since we don't stop creating un-pixeled devices yet, check for no pixels here
1490d30c51c6cf45b3a08a3000b6d348c16bdec7f05reed@google.com    if (NULL == fBitmap.getPixels()) {
1500d30c51c6cf45b3a08a3000b6d348c16bdec7f05reed@google.com        return false;
1510d30c51c6cf45b3a08a3000b6d348c16bdec7f05reed@google.com    }
1520d30c51c6cf45b3a08a3000b6d348c16bdec7f05reed@google.com
153e5ea500d4714a7d84de2bf913e81be3b65d2de68reed    const SkImageInfo dstInfo = fBitmap.info().makeWH(srcInfo.width(), srcInfo.height());
1544cd9e2169e35cd67ee7358acea6541245e1d1744commit-bot@chromium.org
1554cd9e2169e35cd67ee7358acea6541245e1d1744commit-bot@chromium.org    void* dstPixels = fBitmap.getAddr(x, y);
1564cd9e2169e35cd67ee7358acea6541245e1d1744commit-bot@chromium.org    size_t dstRowBytes = fBitmap.rowBytes();
1574cd9e2169e35cd67ee7358acea6541245e1d1744commit-bot@chromium.org
158b184f7f52b2a94e95aee326a3ca37110d2e43336reed    if (SkPixelInfo::CopyPixels(dstInfo, dstPixels, dstRowBytes, srcInfo, srcPixels, srcRowBytes)) {
1594cd9e2169e35cd67ee7358acea6541245e1d1744commit-bot@chromium.org        fBitmap.notifyPixelsChanged();
1604cd9e2169e35cd67ee7358acea6541245e1d1744commit-bot@chromium.org        return true;
1614cd9e2169e35cd67ee7358acea6541245e1d1744commit-bot@chromium.org    }
1624cd9e2169e35cd67ee7358acea6541245e1d1744commit-bot@chromium.org    return false;
1634cd9e2169e35cd67ee7358acea6541245e1d1744commit-bot@chromium.org}
16453238bc96051d1774b7f72d3ebfd35a7dd4c04dfrobertphillips@google.com
165a713f9c6f6a06d216d53e268b9c691941053dabfcommit-bot@chromium.orgbool SkBitmapDevice::onReadPixels(const SkImageInfo& dstInfo, void* dstPixels, size_t dstRowBytes,
166a713f9c6f6a06d216d53e268b9c691941053dabfcommit-bot@chromium.org                                  int x, int y) {
167b184f7f52b2a94e95aee326a3ca37110d2e43336reed    return fBitmap.readPixels(dstInfo, dstPixels, dstRowBytes, x, y);
168a713f9c6f6a06d216d53e268b9c691941053dabfcommit-bot@chromium.org}
169a713f9c6f6a06d216d53e268b9c691941053dabfcommit-bot@chromium.org
17053238bc96051d1774b7f72d3ebfd35a7dd4c04dfrobertphillips@google.com///////////////////////////////////////////////////////////////////////////////
17153238bc96051d1774b7f72d3ebfd35a7dd4c04dfrobertphillips@google.com
17253238bc96051d1774b7f72d3ebfd35a7dd4c04dfrobertphillips@google.comvoid SkBitmapDevice::drawPaint(const SkDraw& draw, const SkPaint& paint) {
17353238bc96051d1774b7f72d3ebfd35a7dd4c04dfrobertphillips@google.com    draw.drawPaint(paint);
17453238bc96051d1774b7f72d3ebfd35a7dd4c04dfrobertphillips@google.com}
17553238bc96051d1774b7f72d3ebfd35a7dd4c04dfrobertphillips@google.com
17653238bc96051d1774b7f72d3ebfd35a7dd4c04dfrobertphillips@google.comvoid SkBitmapDevice::drawPoints(const SkDraw& draw, SkCanvas::PointMode mode, size_t count,
17753238bc96051d1774b7f72d3ebfd35a7dd4c04dfrobertphillips@google.com                                const SkPoint pts[], const SkPaint& paint) {
1784469938e92d779dff05e745559e67907bbf21e78reed@google.com    CHECK_FOR_ANNOTATION(paint);
17953238bc96051d1774b7f72d3ebfd35a7dd4c04dfrobertphillips@google.com    draw.drawPoints(mode, count, pts, paint);
18053238bc96051d1774b7f72d3ebfd35a7dd4c04dfrobertphillips@google.com}
18153238bc96051d1774b7f72d3ebfd35a7dd4c04dfrobertphillips@google.com
18253238bc96051d1774b7f72d3ebfd35a7dd4c04dfrobertphillips@google.comvoid SkBitmapDevice::drawRect(const SkDraw& draw, const SkRect& r, const SkPaint& paint) {
1834469938e92d779dff05e745559e67907bbf21e78reed@google.com    CHECK_FOR_ANNOTATION(paint);
18453238bc96051d1774b7f72d3ebfd35a7dd4c04dfrobertphillips@google.com    draw.drawRect(r, paint);
18553238bc96051d1774b7f72d3ebfd35a7dd4c04dfrobertphillips@google.com}
18653238bc96051d1774b7f72d3ebfd35a7dd4c04dfrobertphillips@google.com
18753238bc96051d1774b7f72d3ebfd35a7dd4c04dfrobertphillips@google.comvoid SkBitmapDevice::drawOval(const SkDraw& draw, const SkRect& oval, const SkPaint& paint) {
1884469938e92d779dff05e745559e67907bbf21e78reed@google.com    CHECK_FOR_ANNOTATION(paint);
18953238bc96051d1774b7f72d3ebfd35a7dd4c04dfrobertphillips@google.com
19053238bc96051d1774b7f72d3ebfd35a7dd4c04dfrobertphillips@google.com    SkPath path;
19153238bc96051d1774b7f72d3ebfd35a7dd4c04dfrobertphillips@google.com    path.addOval(oval);
19253238bc96051d1774b7f72d3ebfd35a7dd4c04dfrobertphillips@google.com    // call the VIRTUAL version, so any subclasses who do handle drawPath aren't
19353238bc96051d1774b7f72d3ebfd35a7dd4c04dfrobertphillips@google.com    // required to override drawOval.
19453238bc96051d1774b7f72d3ebfd35a7dd4c04dfrobertphillips@google.com    this->drawPath(draw, path, paint, NULL, true);
19553238bc96051d1774b7f72d3ebfd35a7dd4c04dfrobertphillips@google.com}
19653238bc96051d1774b7f72d3ebfd35a7dd4c04dfrobertphillips@google.com
19753238bc96051d1774b7f72d3ebfd35a7dd4c04dfrobertphillips@google.comvoid SkBitmapDevice::drawRRect(const SkDraw& draw, const SkRRect& rrect, const SkPaint& paint) {
1984469938e92d779dff05e745559e67907bbf21e78reed@google.com    CHECK_FOR_ANNOTATION(paint);
19953238bc96051d1774b7f72d3ebfd35a7dd4c04dfrobertphillips@google.com
20050a7600d05d427c64f77d39c8c18d2bf6cabd25brobertphillips@google.com#ifdef SK_IGNORE_BLURRED_RRECT_OPT
20150a7600d05d427c64f77d39c8c18d2bf6cabd25brobertphillips@google.com    SkPath  path;
20250a7600d05d427c64f77d39c8c18d2bf6cabd25brobertphillips@google.com
20350a7600d05d427c64f77d39c8c18d2bf6cabd25brobertphillips@google.com    path.addRRect(rrect);
20450a7600d05d427c64f77d39c8c18d2bf6cabd25brobertphillips@google.com    // call the VIRTUAL version, so any subclasses who do handle drawPath aren't
20550a7600d05d427c64f77d39c8c18d2bf6cabd25brobertphillips@google.com    // required to override drawRRect.
20650a7600d05d427c64f77d39c8c18d2bf6cabd25brobertphillips@google.com    this->drawPath(draw, path, paint, NULL, true);
20750a7600d05d427c64f77d39c8c18d2bf6cabd25brobertphillips@google.com#else
208a8e33a92e27ca1523601226cad83c79a7e00c93bscroggo@google.com    draw.drawRRect(rrect, paint);
20950a7600d05d427c64f77d39c8c18d2bf6cabd25brobertphillips@google.com#endif
21053238bc96051d1774b7f72d3ebfd35a7dd4c04dfrobertphillips@google.com}
21153238bc96051d1774b7f72d3ebfd35a7dd4c04dfrobertphillips@google.com
21253238bc96051d1774b7f72d3ebfd35a7dd4c04dfrobertphillips@google.comvoid SkBitmapDevice::drawPath(const SkDraw& draw, const SkPath& path,
21353238bc96051d1774b7f72d3ebfd35a7dd4c04dfrobertphillips@google.com                              const SkPaint& paint, const SkMatrix* prePathMatrix,
21453238bc96051d1774b7f72d3ebfd35a7dd4c04dfrobertphillips@google.com                              bool pathIsMutable) {
2154469938e92d779dff05e745559e67907bbf21e78reed@google.com    CHECK_FOR_ANNOTATION(paint);
21653238bc96051d1774b7f72d3ebfd35a7dd4c04dfrobertphillips@google.com    draw.drawPath(path, paint, prePathMatrix, pathIsMutable);
21753238bc96051d1774b7f72d3ebfd35a7dd4c04dfrobertphillips@google.com}
21853238bc96051d1774b7f72d3ebfd35a7dd4c04dfrobertphillips@google.com
21953238bc96051d1774b7f72d3ebfd35a7dd4c04dfrobertphillips@google.comvoid SkBitmapDevice::drawBitmap(const SkDraw& draw, const SkBitmap& bitmap,
22053238bc96051d1774b7f72d3ebfd35a7dd4c04dfrobertphillips@google.com                                const SkMatrix& matrix, const SkPaint& paint) {
2210393912de72bc3d8b3640c122c53470dd0da1e6dreed    draw.drawBitmap(bitmap, matrix, NULL, paint);
22253238bc96051d1774b7f72d3ebfd35a7dd4c04dfrobertphillips@google.com}
22353238bc96051d1774b7f72d3ebfd35a7dd4c04dfrobertphillips@google.com
22453238bc96051d1774b7f72d3ebfd35a7dd4c04dfrobertphillips@google.comvoid SkBitmapDevice::drawBitmapRect(const SkDraw& draw, const SkBitmap& bitmap,
22553238bc96051d1774b7f72d3ebfd35a7dd4c04dfrobertphillips@google.com                                    const SkRect* src, const SkRect& dst,
22653238bc96051d1774b7f72d3ebfd35a7dd4c04dfrobertphillips@google.com                                    const SkPaint& paint,
22753238bc96051d1774b7f72d3ebfd35a7dd4c04dfrobertphillips@google.com                                    SkCanvas::DrawBitmapRectFlags flags) {
22853238bc96051d1774b7f72d3ebfd35a7dd4c04dfrobertphillips@google.com    SkMatrix    matrix;
22953238bc96051d1774b7f72d3ebfd35a7dd4c04dfrobertphillips@google.com    SkRect      bitmapBounds, tmpSrc, tmpDst;
23053238bc96051d1774b7f72d3ebfd35a7dd4c04dfrobertphillips@google.com    SkBitmap    tmpBitmap;
23153238bc96051d1774b7f72d3ebfd35a7dd4c04dfrobertphillips@google.com
23253238bc96051d1774b7f72d3ebfd35a7dd4c04dfrobertphillips@google.com    bitmapBounds.isetWH(bitmap.width(), bitmap.height());
23353238bc96051d1774b7f72d3ebfd35a7dd4c04dfrobertphillips@google.com
23453238bc96051d1774b7f72d3ebfd35a7dd4c04dfrobertphillips@google.com    // Compute matrix from the two rectangles
23553238bc96051d1774b7f72d3ebfd35a7dd4c04dfrobertphillips@google.com    if (src) {
23653238bc96051d1774b7f72d3ebfd35a7dd4c04dfrobertphillips@google.com        tmpSrc = *src;
23753238bc96051d1774b7f72d3ebfd35a7dd4c04dfrobertphillips@google.com    } else {
23853238bc96051d1774b7f72d3ebfd35a7dd4c04dfrobertphillips@google.com        tmpSrc = bitmapBounds;
23953238bc96051d1774b7f72d3ebfd35a7dd4c04dfrobertphillips@google.com    }
24053238bc96051d1774b7f72d3ebfd35a7dd4c04dfrobertphillips@google.com    matrix.setRectToRect(tmpSrc, dst, SkMatrix::kFill_ScaleToFit);
24153238bc96051d1774b7f72d3ebfd35a7dd4c04dfrobertphillips@google.com
24253238bc96051d1774b7f72d3ebfd35a7dd4c04dfrobertphillips@google.com    const SkRect* dstPtr = &dst;
24353238bc96051d1774b7f72d3ebfd35a7dd4c04dfrobertphillips@google.com    const SkBitmap* bitmapPtr = &bitmap;
24453238bc96051d1774b7f72d3ebfd35a7dd4c04dfrobertphillips@google.com
24553238bc96051d1774b7f72d3ebfd35a7dd4c04dfrobertphillips@google.com    // clip the tmpSrc to the bounds of the bitmap, and recompute dstRect if
24653238bc96051d1774b7f72d3ebfd35a7dd4c04dfrobertphillips@google.com    // needed (if the src was clipped). No check needed if src==null.
24753238bc96051d1774b7f72d3ebfd35a7dd4c04dfrobertphillips@google.com    if (src) {
24853238bc96051d1774b7f72d3ebfd35a7dd4c04dfrobertphillips@google.com        if (!bitmapBounds.contains(*src)) {
24953238bc96051d1774b7f72d3ebfd35a7dd4c04dfrobertphillips@google.com            if (!tmpSrc.intersect(bitmapBounds)) {
25053238bc96051d1774b7f72d3ebfd35a7dd4c04dfrobertphillips@google.com                return; // nothing to draw
25153238bc96051d1774b7f72d3ebfd35a7dd4c04dfrobertphillips@google.com            }
25253238bc96051d1774b7f72d3ebfd35a7dd4c04dfrobertphillips@google.com            // recompute dst, based on the smaller tmpSrc
25353238bc96051d1774b7f72d3ebfd35a7dd4c04dfrobertphillips@google.com            matrix.mapRect(&tmpDst, tmpSrc);
25453238bc96051d1774b7f72d3ebfd35a7dd4c04dfrobertphillips@google.com            dstPtr = &tmpDst;
25553238bc96051d1774b7f72d3ebfd35a7dd4c04dfrobertphillips@google.com        }
25653238bc96051d1774b7f72d3ebfd35a7dd4c04dfrobertphillips@google.com
25753238bc96051d1774b7f72d3ebfd35a7dd4c04dfrobertphillips@google.com        // since we may need to clamp to the borders of the src rect within
25853238bc96051d1774b7f72d3ebfd35a7dd4c04dfrobertphillips@google.com        // the bitmap, we extract a subset.
259b07a94f1cba3976596ae1a7f23d8c2043ba353f3reed        const SkIRect srcIR = tmpSrc.roundOut();
2600e9770515cab45decb56a5926d1741b71854fb4cpiotaixr        if(bitmap.pixelRef()->getTexture()) {
2610e9770515cab45decb56a5926d1741b71854fb4cpiotaixr            // Accelerated source canvas, don't use extractSubset but readPixels to get the subset.
2620e9770515cab45decb56a5926d1741b71854fb4cpiotaixr            // This way, the pixels are copied in CPU memory instead of GPU memory.
2630e9770515cab45decb56a5926d1741b71854fb4cpiotaixr            bitmap.pixelRef()->readPixels(&tmpBitmap, &srcIR);
2640e9770515cab45decb56a5926d1741b71854fb4cpiotaixr        } else {
2650e9770515cab45decb56a5926d1741b71854fb4cpiotaixr            if (!bitmap.extractSubset(&tmpBitmap, srcIR)) {
2660e9770515cab45decb56a5926d1741b71854fb4cpiotaixr                return;
2670e9770515cab45decb56a5926d1741b71854fb4cpiotaixr            }
26853238bc96051d1774b7f72d3ebfd35a7dd4c04dfrobertphillips@google.com        }
26953238bc96051d1774b7f72d3ebfd35a7dd4c04dfrobertphillips@google.com        bitmapPtr = &tmpBitmap;
27053238bc96051d1774b7f72d3ebfd35a7dd4c04dfrobertphillips@google.com
27153238bc96051d1774b7f72d3ebfd35a7dd4c04dfrobertphillips@google.com        // Since we did an extract, we need to adjust the matrix accordingly
27253238bc96051d1774b7f72d3ebfd35a7dd4c04dfrobertphillips@google.com        SkScalar dx = 0, dy = 0;
27353238bc96051d1774b7f72d3ebfd35a7dd4c04dfrobertphillips@google.com        if (srcIR.fLeft > 0) {
27453238bc96051d1774b7f72d3ebfd35a7dd4c04dfrobertphillips@google.com            dx = SkIntToScalar(srcIR.fLeft);
27553238bc96051d1774b7f72d3ebfd35a7dd4c04dfrobertphillips@google.com        }
27653238bc96051d1774b7f72d3ebfd35a7dd4c04dfrobertphillips@google.com        if (srcIR.fTop > 0) {
27753238bc96051d1774b7f72d3ebfd35a7dd4c04dfrobertphillips@google.com            dy = SkIntToScalar(srcIR.fTop);
27853238bc96051d1774b7f72d3ebfd35a7dd4c04dfrobertphillips@google.com        }
27953238bc96051d1774b7f72d3ebfd35a7dd4c04dfrobertphillips@google.com        if (dx || dy) {
28053238bc96051d1774b7f72d3ebfd35a7dd4c04dfrobertphillips@google.com            matrix.preTranslate(dx, dy);
28153238bc96051d1774b7f72d3ebfd35a7dd4c04dfrobertphillips@google.com        }
28253238bc96051d1774b7f72d3ebfd35a7dd4c04dfrobertphillips@google.com
28353238bc96051d1774b7f72d3ebfd35a7dd4c04dfrobertphillips@google.com        SkRect extractedBitmapBounds;
28453238bc96051d1774b7f72d3ebfd35a7dd4c04dfrobertphillips@google.com        extractedBitmapBounds.isetWH(bitmapPtr->width(), bitmapPtr->height());
28553238bc96051d1774b7f72d3ebfd35a7dd4c04dfrobertphillips@google.com        if (extractedBitmapBounds == tmpSrc) {
28653238bc96051d1774b7f72d3ebfd35a7dd4c04dfrobertphillips@google.com            // no fractional part in src, we can just call drawBitmap
28753238bc96051d1774b7f72d3ebfd35a7dd4c04dfrobertphillips@google.com            goto USE_DRAWBITMAP;
28853238bc96051d1774b7f72d3ebfd35a7dd4c04dfrobertphillips@google.com        }
28953238bc96051d1774b7f72d3ebfd35a7dd4c04dfrobertphillips@google.com    } else {
29053238bc96051d1774b7f72d3ebfd35a7dd4c04dfrobertphillips@google.com        USE_DRAWBITMAP:
29153238bc96051d1774b7f72d3ebfd35a7dd4c04dfrobertphillips@google.com        // We can go faster by just calling drawBitmap, which will concat the
29253238bc96051d1774b7f72d3ebfd35a7dd4c04dfrobertphillips@google.com        // matrix with the CTM, and try to call drawSprite if it can. If not,
29353238bc96051d1774b7f72d3ebfd35a7dd4c04dfrobertphillips@google.com        // it will make a shader and call drawRect, as we do below.
2940393912de72bc3d8b3640c122c53470dd0da1e6dreed        draw.drawBitmap(*bitmapPtr, matrix, dstPtr, paint);
29553238bc96051d1774b7f72d3ebfd35a7dd4c04dfrobertphillips@google.com        return;
29653238bc96051d1774b7f72d3ebfd35a7dd4c04dfrobertphillips@google.com    }
29753238bc96051d1774b7f72d3ebfd35a7dd4c04dfrobertphillips@google.com
29853238bc96051d1774b7f72d3ebfd35a7dd4c04dfrobertphillips@google.com    // construct a shader, so we can call drawRect with the dst
29953238bc96051d1774b7f72d3ebfd35a7dd4c04dfrobertphillips@google.com    SkShader* s = SkShader::CreateBitmapShader(*bitmapPtr,
30053238bc96051d1774b7f72d3ebfd35a7dd4c04dfrobertphillips@google.com                                               SkShader::kClamp_TileMode,
3019c9005a347e9996f357bd79591bd34f74f8bbc66commit-bot@chromium.org                                               SkShader::kClamp_TileMode,
3029c9005a347e9996f357bd79591bd34f74f8bbc66commit-bot@chromium.org                                               &matrix);
30353238bc96051d1774b7f72d3ebfd35a7dd4c04dfrobertphillips@google.com    if (NULL == s) {
30453238bc96051d1774b7f72d3ebfd35a7dd4c04dfrobertphillips@google.com        return;
30553238bc96051d1774b7f72d3ebfd35a7dd4c04dfrobertphillips@google.com    }
30653238bc96051d1774b7f72d3ebfd35a7dd4c04dfrobertphillips@google.com
30753238bc96051d1774b7f72d3ebfd35a7dd4c04dfrobertphillips@google.com    SkPaint paintWithShader(paint);
30853238bc96051d1774b7f72d3ebfd35a7dd4c04dfrobertphillips@google.com    paintWithShader.setStyle(SkPaint::kFill_Style);
30953238bc96051d1774b7f72d3ebfd35a7dd4c04dfrobertphillips@google.com    paintWithShader.setShader(s)->unref();
31053238bc96051d1774b7f72d3ebfd35a7dd4c04dfrobertphillips@google.com
31153238bc96051d1774b7f72d3ebfd35a7dd4c04dfrobertphillips@google.com    // Call ourself, in case the subclass wanted to share this setup code
31253238bc96051d1774b7f72d3ebfd35a7dd4c04dfrobertphillips@google.com    // but handle the drawRect code themselves.
31353238bc96051d1774b7f72d3ebfd35a7dd4c04dfrobertphillips@google.com    this->drawRect(draw, *dstPtr, paintWithShader);
31453238bc96051d1774b7f72d3ebfd35a7dd4c04dfrobertphillips@google.com}
31553238bc96051d1774b7f72d3ebfd35a7dd4c04dfrobertphillips@google.com
31653238bc96051d1774b7f72d3ebfd35a7dd4c04dfrobertphillips@google.comvoid SkBitmapDevice::drawSprite(const SkDraw& draw, const SkBitmap& bitmap,
31753238bc96051d1774b7f72d3ebfd35a7dd4c04dfrobertphillips@google.com                                int x, int y, const SkPaint& paint) {
31853238bc96051d1774b7f72d3ebfd35a7dd4c04dfrobertphillips@google.com    draw.drawSprite(bitmap, x, y, paint);
31953238bc96051d1774b7f72d3ebfd35a7dd4c04dfrobertphillips@google.com}
32053238bc96051d1774b7f72d3ebfd35a7dd4c04dfrobertphillips@google.com
32153238bc96051d1774b7f72d3ebfd35a7dd4c04dfrobertphillips@google.comvoid SkBitmapDevice::drawText(const SkDraw& draw, const void* text, size_t len,
32253238bc96051d1774b7f72d3ebfd35a7dd4c04dfrobertphillips@google.com                              SkScalar x, SkScalar y, const SkPaint& paint) {
32353238bc96051d1774b7f72d3ebfd35a7dd4c04dfrobertphillips@google.com    draw.drawText((const char*)text, len, x, y, paint);
32453238bc96051d1774b7f72d3ebfd35a7dd4c04dfrobertphillips@google.com}
32553238bc96051d1774b7f72d3ebfd35a7dd4c04dfrobertphillips@google.com
32653238bc96051d1774b7f72d3ebfd35a7dd4c04dfrobertphillips@google.comvoid SkBitmapDevice::drawPosText(const SkDraw& draw, const void* text, size_t len,
32705c4a4322e7d4f3417b7df33825bab8603d52051fmalita                                 const SkScalar xpos[], int scalarsPerPos,
32805c4a4322e7d4f3417b7df33825bab8603d52051fmalita                                 const SkPoint& offset, const SkPaint& paint) {
32905c4a4322e7d4f3417b7df33825bab8603d52051fmalita    draw.drawPosText((const char*)text, len, xpos, scalarsPerPos, offset, paint);
33053238bc96051d1774b7f72d3ebfd35a7dd4c04dfrobertphillips@google.com}
33153238bc96051d1774b7f72d3ebfd35a7dd4c04dfrobertphillips@google.com
33253238bc96051d1774b7f72d3ebfd35a7dd4c04dfrobertphillips@google.comvoid SkBitmapDevice::drawVertices(const SkDraw& draw, SkCanvas::VertexMode vmode,
33353238bc96051d1774b7f72d3ebfd35a7dd4c04dfrobertphillips@google.com                                  int vertexCount,
33453238bc96051d1774b7f72d3ebfd35a7dd4c04dfrobertphillips@google.com                                  const SkPoint verts[], const SkPoint textures[],
33553238bc96051d1774b7f72d3ebfd35a7dd4c04dfrobertphillips@google.com                                  const SkColor colors[], SkXfermode* xmode,
33653238bc96051d1774b7f72d3ebfd35a7dd4c04dfrobertphillips@google.com                                  const uint16_t indices[], int indexCount,
33753238bc96051d1774b7f72d3ebfd35a7dd4c04dfrobertphillips@google.com                                  const SkPaint& paint) {
33853238bc96051d1774b7f72d3ebfd35a7dd4c04dfrobertphillips@google.com    draw.drawVertices(vmode, vertexCount, verts, textures, colors, xmode,
33953238bc96051d1774b7f72d3ebfd35a7dd4c04dfrobertphillips@google.com                      indices, indexCount, paint);
34053238bc96051d1774b7f72d3ebfd35a7dd4c04dfrobertphillips@google.com}
34153238bc96051d1774b7f72d3ebfd35a7dd4c04dfrobertphillips@google.com
34253238bc96051d1774b7f72d3ebfd35a7dd4c04dfrobertphillips@google.comvoid SkBitmapDevice::drawDevice(const SkDraw& draw, SkBaseDevice* device,
34353238bc96051d1774b7f72d3ebfd35a7dd4c04dfrobertphillips@google.com                                int x, int y, const SkPaint& paint) {
34453238bc96051d1774b7f72d3ebfd35a7dd4c04dfrobertphillips@google.com    const SkBitmap& src = device->accessBitmap(false);
34553238bc96051d1774b7f72d3ebfd35a7dd4c04dfrobertphillips@google.com    draw.drawSprite(src, x, y, paint);
34653238bc96051d1774b7f72d3ebfd35a7dd4c04dfrobertphillips@google.com}
34753238bc96051d1774b7f72d3ebfd35a7dd4c04dfrobertphillips@google.com
3484a8126e7f81384526629b1e21bf89b632ea13cd9reedSkSurface* SkBitmapDevice::newSurface(const SkImageInfo& info, const SkSurfaceProps& props) {
3494a8126e7f81384526629b1e21bf89b632ea13cd9reed    return SkSurface::NewRaster(info, &props);
35076f10a3bd936af7dbe2b5873d5a7eedd73cdc5dareed@google.com}
35176f10a3bd936af7dbe2b5873d5a7eedd73cdc5dareed@google.com
352c3bd8af6d5722e854feca70c40d92f4954c5b67bcommit-bot@chromium.orgconst void* SkBitmapDevice::peekPixels(SkImageInfo* info, size_t* rowBytes) {
353466f5f3e44e703ca58b43ac1c4ac3bfa0e1ff024commit-bot@chromium.org    const SkImageInfo bmInfo = fBitmap.info();
354466f5f3e44e703ca58b43ac1c4ac3bfa0e1ff024commit-bot@chromium.org    if (fBitmap.getPixels() && (kUnknown_SkColorType != bmInfo.colorType())) {
355466f5f3e44e703ca58b43ac1c4ac3bfa0e1ff024commit-bot@chromium.org        if (info) {
356466f5f3e44e703ca58b43ac1c4ac3bfa0e1ff024commit-bot@chromium.org            *info = bmInfo;
357466f5f3e44e703ca58b43ac1c4ac3bfa0e1ff024commit-bot@chromium.org        }
358c3bd8af6d5722e854feca70c40d92f4954c5b67bcommit-bot@chromium.org        if (rowBytes) {
359c3bd8af6d5722e854feca70c40d92f4954c5b67bcommit-bot@chromium.org            *rowBytes = fBitmap.rowBytes();
360c3bd8af6d5722e854feca70c40d92f4954c5b67bcommit-bot@chromium.org        }
361c3bd8af6d5722e854feca70c40d92f4954c5b67bcommit-bot@chromium.org        return fBitmap.getPixels();
362c3bd8af6d5722e854feca70c40d92f4954c5b67bcommit-bot@chromium.org    }
363c3bd8af6d5722e854feca70c40d92f4954c5b67bcommit-bot@chromium.org    return NULL;
364c3bd8af6d5722e854feca70c40d92f4954c5b67bcommit-bot@chromium.org}
365c3bd8af6d5722e854feca70c40d92f4954c5b67bcommit-bot@chromium.org
366be129b26f13d575fd6b396c6ae759838ecc9bd1asenorblancoSkImageFilter::Cache* SkBitmapDevice::getImageFilterCache() {
367be129b26f13d575fd6b396c6ae759838ecc9bd1asenorblanco    SkImageFilter::Cache* cache = SkImageFilter::Cache::Get();
36855b6d8be997a447ef9ce0f029697677a940bfc24senorblanco    cache->ref();
36955b6d8be997a447ef9ce0f029697677a940bfc24senorblanco    return cache;
37055b6d8be997a447ef9ce0f029697677a940bfc24senorblanco}
37155b6d8be997a447ef9ce0f029697677a940bfc24senorblanco
37253238bc96051d1774b7f72d3ebfd35a7dd4c04dfrobertphillips@google.com///////////////////////////////////////////////////////////////////////////////
37353238bc96051d1774b7f72d3ebfd35a7dd4c04dfrobertphillips@google.com
374b2db898573e3cdcc8234eebf51961bfc4977ebbcreedbool SkBitmapDevice::onShouldDisableLCD(const SkPaint& paint) const {
375cba73780bbd12fd254229517aec04fcbf0b64b52commit-bot@chromium.org    if (kN32_SkColorType != fBitmap.colorType() ||
37653238bc96051d1774b7f72d3ebfd35a7dd4c04dfrobertphillips@google.com        paint.getRasterizer() ||
37753238bc96051d1774b7f72d3ebfd35a7dd4c04dfrobertphillips@google.com        paint.getPathEffect() ||
37853238bc96051d1774b7f72d3ebfd35a7dd4c04dfrobertphillips@google.com        paint.isFakeBoldText() ||
37953238bc96051d1774b7f72d3ebfd35a7dd4c04dfrobertphillips@google.com        paint.getStyle() != SkPaint::kFill_Style ||
380b2db898573e3cdcc8234eebf51961bfc4977ebbcreed        !SkXfermode::IsMode(paint.getXfermode(), SkXfermode::kSrcOver_Mode))
381b2db898573e3cdcc8234eebf51961bfc4977ebbcreed    {
38253238bc96051d1774b7f72d3ebfd35a7dd4c04dfrobertphillips@google.com        return true;
38353238bc96051d1774b7f72d3ebfd35a7dd4c04dfrobertphillips@google.com    }
38453238bc96051d1774b7f72d3ebfd35a7dd4c04dfrobertphillips@google.com    return false;
38553238bc96051d1774b7f72d3ebfd35a7dd4c04dfrobertphillips@google.com}
386