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