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