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