SkDevice.cpp revision f2b98d67dcb6fcb3120feede9c72016fc7b3ead8
1#include "SkDevice.h"
2#include "SkDraw.h"
3#include "SkRect.h"
4
5SkDeviceFactory::~SkDeviceFactory() {}
6
7SkDevice::SkDevice(SkCanvas* canvas) : fCanvas(canvas) {}
8
9SkDevice::SkDevice(SkCanvas* canvas, const SkBitmap& bitmap, bool isForLayer)
10        : fCanvas(canvas), fBitmap(bitmap) {
11    // auto-allocate if we're for offscreen drawing
12    if (isForLayer) {
13        if (NULL == fBitmap.getPixels() && NULL == fBitmap.pixelRef()) {
14            fBitmap.allocPixels();
15            if (!fBitmap.isOpaque()) {
16                fBitmap.eraseColor(0);
17            }
18        }
19    }
20}
21
22void SkDevice::lockPixels() {
23    fBitmap.lockPixels();
24}
25
26void SkDevice::unlockPixels() {
27    fBitmap.unlockPixels();
28}
29
30const SkBitmap& SkDevice::accessBitmap(bool changePixels) {
31    this->onAccessBitmap(&fBitmap);
32    if (changePixels) {
33        fBitmap.notifyPixelsChanged();
34    }
35    return fBitmap;
36}
37
38void SkDevice::getBounds(SkIRect* bounds) const {
39    if (bounds) {
40        bounds->set(0, 0, fBitmap.width(), fBitmap.height());
41    }
42}
43
44bool SkDevice::intersects(const SkIRect& r, SkIRect* sect) const {
45    SkIRect bounds;
46
47    this->getBounds(&bounds);
48    return sect ? sect->intersect(r, bounds) : SkIRect::Intersects(r, bounds);
49}
50
51void SkDevice::eraseColor(SkColor eraseColor) {
52    fBitmap.eraseColor(eraseColor);
53}
54
55void SkDevice::onAccessBitmap(SkBitmap* bitmap) {}
56
57void SkDevice::setMatrixClip(const SkMatrix&, const SkRegion&) {}
58
59///////////////////////////////////////////////////////////////////////////////
60
61bool SkDevice::readPixels(const SkIRect& srcRect, SkBitmap* bitmap) {
62    const SkBitmap& src = this->accessBitmap(false);
63
64    SkIRect bounds;
65    bounds.set(0, 0, src.width(), src.height());
66    if (!bounds.intersect(srcRect)) {
67        return false;
68    }
69
70    SkBitmap subset;
71    if (!src.extractSubset(&subset, bounds)) {
72        return false;
73    }
74
75    SkBitmap tmp;
76    if (!subset.copyTo(&tmp, SkBitmap::kARGB_8888_Config)) {
77        return false;
78    }
79
80    tmp.swap(*bitmap);
81    return true;
82}
83
84void SkDevice::writePixels(const SkBitmap& bitmap, int x, int y) {
85    SkPaint paint;
86    paint.setXfermodeMode(SkXfermode::kSrc_Mode);
87
88    SkCanvas canvas(this);
89    canvas.drawSprite(bitmap, x, y, &paint);
90}
91
92///////////////////////////////////////////////////////////////////////////////
93
94void SkDevice::drawPaint(const SkDraw& draw, const SkPaint& paint) {
95    draw.drawPaint(paint);
96}
97
98void SkDevice::drawPoints(const SkDraw& draw, SkCanvas::PointMode mode, size_t count,
99                              const SkPoint pts[], const SkPaint& paint) {
100    draw.drawPoints(mode, count, pts, paint);
101}
102
103void SkDevice::drawRect(const SkDraw& draw, const SkRect& r,
104                            const SkPaint& paint) {
105    draw.drawRect(r, paint);
106}
107
108void SkDevice::drawPath(const SkDraw& draw, const SkPath& path,
109                        const SkPaint& paint, const SkMatrix* prePathMatrix,
110                        bool pathIsMutable) {
111    draw.drawPath(path, paint, prePathMatrix, pathIsMutable);
112}
113
114void SkDevice::drawBitmap(const SkDraw& draw, const SkBitmap& bitmap,
115                          const SkIRect* srcRect,
116                          const SkMatrix& matrix, const SkPaint& paint) {
117    SkBitmap        tmp;    // storage if we need a subset of bitmap
118    const SkBitmap* bitmapPtr = &bitmap;
119
120    if (srcRect) {
121        if (!bitmap.extractSubset(&tmp, *srcRect)) {
122            return;     // extraction failed
123        }
124        bitmapPtr = &tmp;
125    }
126    draw.drawBitmap(*bitmapPtr, matrix, paint);
127}
128
129void SkDevice::drawSprite(const SkDraw& draw, const SkBitmap& bitmap,
130                              int x, int y, const SkPaint& paint) {
131    draw.drawSprite(bitmap, x, y, paint);
132}
133
134void SkDevice::drawText(const SkDraw& draw, const void* text, size_t len,
135                            SkScalar x, SkScalar y, const SkPaint& paint) {
136    draw.drawText((const char*)text, len, x, y, paint);
137}
138
139void SkDevice::drawPosText(const SkDraw& draw, const void* text, size_t len,
140                               const SkScalar xpos[], SkScalar y,
141                               int scalarsPerPos, const SkPaint& paint) {
142    draw.drawPosText((const char*)text, len, xpos, y, scalarsPerPos, paint);
143}
144
145void SkDevice::drawTextOnPath(const SkDraw& draw, const void* text,
146                                  size_t len, const SkPath& path,
147                                  const SkMatrix* matrix,
148                                  const SkPaint& paint) {
149    draw.drawTextOnPath((const char*)text, len, path, matrix, paint);
150}
151
152void SkDevice::drawVertices(const SkDraw& draw, SkCanvas::VertexMode vmode,
153                                int vertexCount,
154                                const SkPoint verts[], const SkPoint textures[],
155                                const SkColor colors[], SkXfermode* xmode,
156                                const uint16_t indices[], int indexCount,
157                                const SkPaint& paint) {
158    draw.drawVertices(vmode, vertexCount, verts, textures, colors, xmode,
159                      indices, indexCount, paint);
160}
161
162void SkDevice::drawDevice(const SkDraw& draw, SkDevice* device,
163                              int x, int y, const SkPaint& paint) {
164    draw.drawSprite(device->accessBitmap(false), x, y, paint);
165}
166
167///////////////////////////////////////////////////////////////////////////////
168
169SkDevice* SkRasterDeviceFactory::newDevice(SkCanvas* canvas,
170                                           SkBitmap::Config config, int width,
171                                           int height, bool isOpaque,
172                                           bool isForLayer) {
173    SkBitmap bitmap;
174    bitmap.setConfig(config, width, height);
175    bitmap.setIsOpaque(isOpaque);
176
177    return SkNEW_ARGS(SkDevice, (canvas, bitmap, isForLayer));
178}
179