• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 #include "SkDevice.h"
2 #include "SkDraw.h"
3 #include "SkMetaData.h"
4 #include "SkRect.h"
5 
6 //#define TRACE_FACTORY_LIFETIME
7 
8 #ifdef TRACE_FACTORY_LIFETIME
9     static int gFactoryCounter;
10 #endif
11 
SkDeviceFactory()12 SkDeviceFactory::SkDeviceFactory() {
13 #ifdef TRACE_FACTORY_LIFETIME
14     SkDebugf("+++ factory index %d\n", gFactoryCounter);
15     ++gFactoryCounter;
16 #endif
17 }
18 
~SkDeviceFactory()19 SkDeviceFactory::~SkDeviceFactory() {
20 #ifdef TRACE_FACTORY_LIFETIME
21     --gFactoryCounter;
22     SkDebugf("--- factory index %d\n", gFactoryCounter);
23 #endif
24 }
25 
26 ///////////////////////////////////////////////////////////////////////////////
27 
SkDevice(SkCanvas * canvas)28 SkDevice::SkDevice(SkCanvas* canvas) : fCanvas(canvas), fMetaData(NULL) {
29     fOrigin.setZero();
30     fCachedDeviceFactory = NULL;
31 }
32 
SkDevice(SkCanvas * canvas,const SkBitmap & bitmap,bool isForLayer)33 SkDevice::SkDevice(SkCanvas* canvas, const SkBitmap& bitmap, bool isForLayer)
34         : fCanvas(canvas), fBitmap(bitmap), fMetaData(NULL) {
35     fOrigin.setZero();
36     // auto-allocate if we're for offscreen drawing
37     if (isForLayer) {
38         if (NULL == fBitmap.getPixels() && NULL == fBitmap.pixelRef()) {
39             fBitmap.allocPixels();
40             if (!fBitmap.isOpaque()) {
41                 fBitmap.eraseColor(0);
42             }
43         }
44     }
45     fCachedDeviceFactory = NULL;
46 }
47 
~SkDevice()48 SkDevice::~SkDevice() {
49     delete fMetaData;
50     SkSafeUnref(fCachedDeviceFactory);
51 }
52 
onNewDeviceFactory()53 SkDeviceFactory* SkDevice::onNewDeviceFactory() {
54     return SkNEW(SkRasterDeviceFactory);
55 }
56 
getDeviceFactory()57 SkDeviceFactory* SkDevice::getDeviceFactory() {
58     if (NULL == fCachedDeviceFactory) {
59         fCachedDeviceFactory = this->onNewDeviceFactory();
60     }
61     return fCachedDeviceFactory;
62 }
63 
getMetaData()64 SkMetaData& SkDevice::getMetaData() {
65     // metadata users are rare, so we lazily allocate it. If that changes we
66     // can decide to just make it a field in the device (rather than a ptr)
67     if (NULL == fMetaData) {
68         fMetaData = new SkMetaData;
69     }
70     return *fMetaData;
71 }
72 
lockPixels()73 void SkDevice::lockPixels() {
74     fBitmap.lockPixels();
75 }
76 
unlockPixels()77 void SkDevice::unlockPixels() {
78     fBitmap.unlockPixels();
79 }
80 
accessBitmap(bool changePixels)81 const SkBitmap& SkDevice::accessBitmap(bool changePixels) {
82     this->onAccessBitmap(&fBitmap);
83     if (changePixels) {
84         fBitmap.notifyPixelsChanged();
85     }
86     return fBitmap;
87 }
88 
getBounds(SkIRect * bounds) const89 void SkDevice::getBounds(SkIRect* bounds) const {
90     if (bounds) {
91         bounds->set(0, 0, fBitmap.width(), fBitmap.height());
92     }
93 }
94 
intersects(const SkIRect & r,SkIRect * sect) const95 bool SkDevice::intersects(const SkIRect& r, SkIRect* sect) const {
96     SkIRect bounds;
97 
98     this->getBounds(&bounds);
99     return sect ? sect->intersect(r, bounds) : SkIRect::Intersects(r, bounds);
100 }
101 
clear(SkColor color)102 void SkDevice::clear(SkColor color) {
103     fBitmap.eraseColor(color);
104 }
105 
onAccessBitmap(SkBitmap * bitmap)106 void SkDevice::onAccessBitmap(SkBitmap* bitmap) {}
107 
setMatrixClip(const SkMatrix & matrix,const SkRegion & region,const SkClipStack & clipStack)108 void SkDevice::setMatrixClip(const SkMatrix& matrix, const SkRegion& region,
109                              const SkClipStack& clipStack) {
110 }
111 
112 ///////////////////////////////////////////////////////////////////////////////
113 
readPixels(const SkIRect & srcRect,SkBitmap * bitmap)114 bool SkDevice::readPixels(const SkIRect& srcRect, SkBitmap* bitmap) {
115     const SkBitmap& src = this->accessBitmap(false);
116 
117     SkIRect bounds;
118     bounds.set(0, 0, src.width(), src.height());
119     if (!bounds.intersect(srcRect)) {
120         return false;
121     }
122 
123     SkBitmap subset;
124     if (!src.extractSubset(&subset, bounds)) {
125         return false;
126     }
127 
128     SkBitmap tmp;
129     if (!subset.copyTo(&tmp, SkBitmap::kARGB_8888_Config)) {
130         return false;
131     }
132 
133     tmp.swap(*bitmap);
134     return true;
135 }
136 
writePixels(const SkBitmap & bitmap,int x,int y)137 void SkDevice::writePixels(const SkBitmap& bitmap, int x, int y) {
138     SkPaint paint;
139     paint.setXfermodeMode(SkXfermode::kSrc_Mode);
140 
141     SkCanvas canvas(this);
142     canvas.drawSprite(bitmap, x, y, &paint);
143 }
144 
145 ///////////////////////////////////////////////////////////////////////////////
146 
drawPaint(const SkDraw & draw,const SkPaint & paint)147 void SkDevice::drawPaint(const SkDraw& draw, const SkPaint& paint) {
148     draw.drawPaint(paint);
149 }
150 
drawPoints(const SkDraw & draw,SkCanvas::PointMode mode,size_t count,const SkPoint pts[],const SkPaint & paint)151 void SkDevice::drawPoints(const SkDraw& draw, SkCanvas::PointMode mode, size_t count,
152                               const SkPoint pts[], const SkPaint& paint) {
153     draw.drawPoints(mode, count, pts, paint);
154 }
155 
drawRect(const SkDraw & draw,const SkRect & r,const SkPaint & paint)156 void SkDevice::drawRect(const SkDraw& draw, const SkRect& r,
157                             const SkPaint& paint) {
158     draw.drawRect(r, paint);
159 }
160 
drawPath(const SkDraw & draw,const SkPath & path,const SkPaint & paint,const SkMatrix * prePathMatrix,bool pathIsMutable)161 void SkDevice::drawPath(const SkDraw& draw, const SkPath& path,
162                         const SkPaint& paint, const SkMatrix* prePathMatrix,
163                         bool pathIsMutable) {
164     draw.drawPath(path, paint, prePathMatrix, pathIsMutable);
165 }
166 
drawBitmap(const SkDraw & draw,const SkBitmap & bitmap,const SkIRect * srcRect,const SkMatrix & matrix,const SkPaint & paint)167 void SkDevice::drawBitmap(const SkDraw& draw, const SkBitmap& bitmap,
168                           const SkIRect* srcRect,
169                           const SkMatrix& matrix, const SkPaint& paint) {
170     SkBitmap        tmp;    // storage if we need a subset of bitmap
171     const SkBitmap* bitmapPtr = &bitmap;
172 
173     if (srcRect) {
174         if (!bitmap.extractSubset(&tmp, *srcRect)) {
175             return;     // extraction failed
176         }
177         bitmapPtr = &tmp;
178     }
179     draw.drawBitmap(*bitmapPtr, matrix, paint);
180 }
181 
drawSprite(const SkDraw & draw,const SkBitmap & bitmap,int x,int y,const SkPaint & paint)182 void SkDevice::drawSprite(const SkDraw& draw, const SkBitmap& bitmap,
183                               int x, int y, const SkPaint& paint) {
184     draw.drawSprite(bitmap, x, y, paint);
185 }
186 
drawText(const SkDraw & draw,const void * text,size_t len,SkScalar x,SkScalar y,const SkPaint & paint)187 void SkDevice::drawText(const SkDraw& draw, const void* text, size_t len,
188                             SkScalar x, SkScalar y, const SkPaint& paint) {
189     draw.drawText((const char*)text, len, x, y, paint);
190 }
191 
drawPosText(const SkDraw & draw,const void * text,size_t len,const SkScalar xpos[],SkScalar y,int scalarsPerPos,const SkPaint & paint)192 void SkDevice::drawPosText(const SkDraw& draw, const void* text, size_t len,
193                                const SkScalar xpos[], SkScalar y,
194                                int scalarsPerPos, const SkPaint& paint) {
195     draw.drawPosText((const char*)text, len, xpos, y, scalarsPerPos, paint);
196 }
197 
drawTextOnPath(const SkDraw & draw,const void * text,size_t len,const SkPath & path,const SkMatrix * matrix,const SkPaint & paint)198 void SkDevice::drawTextOnPath(const SkDraw& draw, const void* text,
199                                   size_t len, const SkPath& path,
200                                   const SkMatrix* matrix,
201                                   const SkPaint& paint) {
202     draw.drawTextOnPath((const char*)text, len, path, matrix, paint);
203 }
204 
205 #ifdef ANDROID
drawPosTextOnPath(const SkDraw & draw,const void * text,size_t len,const SkPoint pos[],const SkPaint & paint,const SkPath & path,const SkMatrix * matrix)206 void SkDevice::drawPosTextOnPath(const SkDraw& draw, const void* text, size_t len,
207                                      const SkPoint pos[], const SkPaint& paint,
208                                      const SkPath& path, const SkMatrix* matrix) {
209     draw.drawPosTextOnPath((const char*)text, len, pos, paint, path, matrix);
210 }
211 #endif
212 
drawVertices(const SkDraw & draw,SkCanvas::VertexMode vmode,int vertexCount,const SkPoint verts[],const SkPoint textures[],const SkColor colors[],SkXfermode * xmode,const uint16_t indices[],int indexCount,const SkPaint & paint)213 void SkDevice::drawVertices(const SkDraw& draw, SkCanvas::VertexMode vmode,
214                                 int vertexCount,
215                                 const SkPoint verts[], const SkPoint textures[],
216                                 const SkColor colors[], SkXfermode* xmode,
217                                 const uint16_t indices[], int indexCount,
218                                 const SkPaint& paint) {
219     draw.drawVertices(vmode, vertexCount, verts, textures, colors, xmode,
220                       indices, indexCount, paint);
221 }
222 
drawDevice(const SkDraw & draw,SkDevice * device,int x,int y,const SkPaint & paint)223 void SkDevice::drawDevice(const SkDraw& draw, SkDevice* device,
224                               int x, int y, const SkPaint& paint) {
225     draw.drawSprite(device->accessBitmap(false), x, y, paint);
226 }
227 
228 ///////////////////////////////////////////////////////////////////////////////
229 
filterTextFlags(const SkPaint & paint,TextFlags * flags)230 bool SkDevice::filterTextFlags(const SkPaint& paint, TextFlags* flags) {
231     if (!paint.isLCDRenderText()) {
232         // we're cool with the paint as is
233         return false;
234     }
235 
236     if (SkBitmap::kARGB_8888_Config != fBitmap.config() ||
237         paint.getShader() ||
238         paint.getXfermode() || // unless its srcover
239         paint.getMaskFilter() ||
240         paint.getRasterizer() ||
241         paint.getColorFilter() ||
242         paint.getPathEffect() ||
243         paint.isFakeBoldText() ||
244         paint.getStyle() != SkPaint::kFill_Style) {
245         // turn off lcd
246         flags->fFlags = paint.getFlags() & ~SkPaint::kLCDRenderText_Flag;
247         flags->fHinting = paint.getHinting();
248         return true;
249     }
250     // we're cool with the paint as is
251     return false;
252 }
253 
254 ///////////////////////////////////////////////////////////////////////////////
255 
newDevice(SkCanvas * canvas,SkBitmap::Config config,int width,int height,bool isOpaque,bool isForLayer)256 SkDevice* SkRasterDeviceFactory::newDevice(SkCanvas* canvas,
257                                            SkBitmap::Config config, int width,
258                                            int height, bool isOpaque,
259                                            bool isForLayer) {
260     SkBitmap bitmap;
261     bitmap.setConfig(config, width, height);
262     bitmap.setIsOpaque(isOpaque);
263 
264     return SkNEW_ARGS(SkDevice, (canvas, bitmap, isForLayer));
265 }
266