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