| Index: src/core/SkDraw.cpp
|
| diff --git a/src/core/SkDraw.cpp b/src/core/SkDraw.cpp
|
| index 0069087a92dc82da50f82e85c57fe14727197cf0..ac696808112fa5af4bbc08da717b3de9d3b6dd25 100644
|
| --- a/src/core/SkDraw.cpp
|
| +++ b/src/core/SkDraw.cpp
|
| @@ -44,18 +44,20 @@
|
| SkAutoBlitterChoose() {
|
| fBlitter = NULL;
|
| }
|
| - SkAutoBlitterChoose(const SkPixmap& dst, const SkMatrix& matrix,
|
| + SkAutoBlitterChoose(const SkBitmap& device, const SkMatrix& matrix,
|
| const SkPaint& paint, bool drawCoverage = false) {
|
| - fBlitter = SkBlitter::Choose(dst, matrix, paint, &fAllocator, drawCoverage);
|
| - }
|
| -
|
| + fBlitter = SkBlitter::Choose(device, matrix, paint, &fAllocator,
|
| + drawCoverage);
|
| + }
|
| +
|
| SkBlitter* operator->() { return fBlitter; }
|
| SkBlitter* get() const { return fBlitter; }
|
|
|
| - void choose(const SkPixmap& dst, const SkMatrix& matrix,
|
| + void choose(const SkBitmap& device, const SkMatrix& matrix,
|
| const SkPaint& paint, bool drawCoverage = false) {
|
| SkASSERT(!fBlitter);
|
| - fBlitter = SkBlitter::Choose(dst, matrix, paint, &fAllocator, drawCoverage);
|
| + fBlitter = SkBlitter::Choose(device, matrix, paint, &fAllocator,
|
| + drawCoverage);
|
| }
|
|
|
| private:
|
| @@ -150,7 +152,8 @@
|
| memset(pixels, data, bytes);
|
| }
|
|
|
| -static BitmapXferProc ChooseBitmapXferProc(const SkPixmap& dst, const SkPaint& paint,
|
| +static BitmapXferProc ChooseBitmapXferProc(const SkBitmap& bitmap,
|
| + const SkPaint& paint,
|
| uint32_t* data) {
|
| // todo: we can apply colorfilter up front if no shader, so we wouldn't
|
| // need to abort this fastpath
|
| @@ -187,7 +190,7 @@
|
| should I worry about dithering for the lower depths?
|
| */
|
| SkPMColor pmc = SkPreMultiplyColor(color);
|
| - switch (dst.colorType()) {
|
| + switch (bitmap.colorType()) {
|
| case kN32_SkColorType:
|
| if (data) {
|
| *data = pmc;
|
| @@ -217,10 +220,10 @@
|
| return NULL;
|
| }
|
|
|
| -static void CallBitmapXferProc(const SkPixmap& dst, const SkIRect& rect, BitmapXferProc proc,
|
| - uint32_t procData) {
|
| +static void CallBitmapXferProc(const SkBitmap& bitmap, const SkIRect& rect,
|
| + BitmapXferProc proc, uint32_t procData) {
|
| int shiftPerPixel;
|
| - switch (dst.colorType()) {
|
| + switch (bitmap.colorType()) {
|
| case kN32_SkColorType:
|
| shiftPerPixel = 2;
|
| break;
|
| @@ -235,9 +238,9 @@
|
| return;
|
| }
|
|
|
| - uint8_t* pixels = (uint8_t*)dst.writable_addr();
|
| + uint8_t* pixels = (uint8_t*)bitmap.getPixels();
|
| SkASSERT(pixels);
|
| - const size_t rowBytes = dst.rowBytes();
|
| + const size_t rowBytes = bitmap.rowBytes();
|
| const int widthBytes = rect.width() << shiftPerPixel;
|
|
|
| // skip down to the first scanline and X position
|
| @@ -256,7 +259,7 @@
|
| }
|
|
|
| SkIRect devRect;
|
| - devRect.set(0, 0, fDst.width(), fDst.height());
|
| + devRect.set(0, 0, fBitmap->width(), fBitmap->height());
|
|
|
| if (fRC->isBW()) {
|
| /* If we don't have a shader (i.e. we're just a solid color) we may
|
| @@ -266,7 +269,7 @@
|
| in the clip, we don't have to worry about antialiasing.
|
| */
|
| uint32_t procData = 0; // to avoid the warning
|
| - BitmapXferProc proc = ChooseBitmapXferProc(fDst, paint, &procData);
|
| + BitmapXferProc proc = ChooseBitmapXferProc(*fBitmap, paint, &procData);
|
| if (proc) {
|
| if (D_Dst_BitmapXferProc == proc) { // nothing to do
|
| return;
|
| @@ -274,7 +277,7 @@
|
|
|
| SkRegion::Iterator iter(fRC->bwRgn());
|
| while (!iter.done()) {
|
| - CallBitmapXferProc(fDst, iter.rect(), proc, procData);
|
| + CallBitmapXferProc(*fBitmap, iter.rect(), proc, procData);
|
| iter.next();
|
| }
|
| return;
|
| @@ -282,7 +285,7 @@
|
| }
|
|
|
| // normal case: use a blitter
|
| - SkAutoBlitterChoose blitter(fDst, *fMatrix, paint);
|
| + SkAutoBlitterChoose blitter(*fBitmap, *fMatrix, paint);
|
| SkScan::FillIRect(devRect, *fRC, blitter.get());
|
| }
|
|
|
| @@ -328,11 +331,11 @@
|
| SkASSERT(rec.fRC->isRect());
|
| const SkIRect& r = rec.fRC->getBounds();
|
| uint32_t value;
|
| - const SkPixmap* dst = blitter->justAnOpaqueColor(&value);
|
| - SkASSERT(dst);
|
| -
|
| - uint16_t* addr = dst->writable_addr16(0, 0);
|
| - size_t rb = dst->rowBytes();
|
| + const SkBitmap* bitmap = blitter->justAnOpaqueColor(&value);
|
| + SkASSERT(bitmap);
|
| +
|
| + uint16_t* addr = bitmap->getAddr16(0, 0);
|
| + size_t rb = bitmap->rowBytes();
|
|
|
| for (int i = 0; i < count; i++) {
|
| int x = SkScalarFloorToInt(devPts[i].fX);
|
| @@ -349,11 +352,11 @@
|
| SkASSERT(rec.fRC->isRect());
|
| const SkIRect& r = rec.fRC->getBounds();
|
| uint32_t value;
|
| - const SkPixmap* dst = blitter->justAnOpaqueColor(&value);
|
| - SkASSERT(dst);
|
| -
|
| - SkPMColor* addr = dst->writable_addr32(0, 0);
|
| - size_t rb = dst->rowBytes();
|
| + const SkBitmap* bitmap = blitter->justAnOpaqueColor(&value);
|
| + SkASSERT(bitmap);
|
| +
|
| + SkPMColor* addr = bitmap->getAddr32(0, 0);
|
| + size_t rb = bitmap->rowBytes();
|
|
|
| for (int i = 0; i < count; i++) {
|
| int x = SkScalarFloorToInt(devPts[i].fX);
|
| @@ -509,7 +512,7 @@
|
| if (fRadius <= SK_FixedHalf) { // small radii and hairline
|
| if (SkCanvas::kPoints_PointMode == fMode && fClip->isRect()) {
|
| uint32_t value;
|
| - const SkPixmap* bm = blitter->justAnOpaqueColor(&value);
|
| + const SkBitmap* bm = blitter->justAnOpaqueColor(&value);
|
| if (bm && kRGB_565_SkColorType == bm->colorType()) {
|
| proc = bw_pt_rect_16_hair_proc;
|
| } else if (bm && kN32_SkColorType == bm->colorType()) {
|
| @@ -556,7 +559,7 @@
|
|
|
| PtProcRec rec;
|
| if (!forceUseDevice && rec.init(mode, paint, fMatrix, fRC)) {
|
| - SkAutoBlitterChoose blitter(fDst, *fMatrix, paint);
|
| + SkAutoBlitterChoose blitter(*fBitmap, *fMatrix, paint);
|
|
|
| SkPoint devPts[MAX_DEV_PTS];
|
| const SkMatrix* matrix = fMatrix;
|
| @@ -850,14 +853,14 @@
|
| return;
|
| }
|
|
|
| - SkDeviceLooper looper(fDst, *fRC, ir, paint.isAntiAlias());
|
| + SkDeviceLooper looper(*fBitmap, *fRC, ir, paint.isAntiAlias());
|
| while (looper.next()) {
|
| SkRect localDevRect;
|
| looper.mapRect(&localDevRect, devRect);
|
| SkMatrix localMatrix;
|
| looper.mapMatrix(&localMatrix, *matrix);
|
|
|
| - SkAutoBlitterChoose blitterStorage(looper.getPixmap(), localMatrix, paint);
|
| + SkAutoBlitterChoose blitterStorage(looper.getBitmap(), localMatrix, paint);
|
| const SkRasterClip& clip = looper.getRC();
|
| SkBlitter* blitter = blitterStorage.get();
|
|
|
| @@ -908,7 +911,7 @@
|
| }
|
| SkAutoMaskFreeImage ami(dstM.fImage);
|
|
|
| - SkAutoBlitterChoose blitterChooser(fDst, *fMatrix, paint);
|
| + SkAutoBlitterChoose blitterChooser(*fBitmap, *fMatrix, paint);
|
| SkBlitter* blitter = blitterChooser.get();
|
|
|
| SkAAClipBlitterWrapper wrapper;
|
| @@ -986,7 +989,7 @@
|
| // Transform the rrect into device space.
|
| SkRRect devRRect;
|
| if (rrect.transform(*fMatrix, &devRRect)) {
|
| - SkAutoBlitterChoose blitter(fDst, *fMatrix, paint);
|
| + SkAutoBlitterChoose blitter(*fBitmap, *fMatrix, paint);
|
| if (paint.getMaskFilter()->filterRRect(devRRect, *fMatrix, *fRC, blitter.get(),
|
| SkPaint::kFill_Style)) {
|
| return; // filterRRect() called the blitter, so we're done
|
| @@ -1105,7 +1108,7 @@
|
| SkBlitter* blitter = NULL;
|
| SkAutoBlitterChoose blitterStorage;
|
| if (NULL == customBlitter) {
|
| - blitterStorage.choose(fDst, *fMatrix, *paint, drawCoverage);
|
| + blitterStorage.choose(*fBitmap, *fMatrix, *paint, drawCoverage);
|
| blitter = blitterStorage.get();
|
| } else {
|
| blitter = customBlitter;
|
| @@ -1179,7 +1182,7 @@
|
| // clipped to the actual device
|
| {
|
| SkIRect devBounds;
|
| - devBounds.set(0, 0, fDst.width(), fDst.height());
|
| + devBounds.set(0, 0, fBitmap->width(), fBitmap->height());
|
| // need intersect(l, t, r, b) on irect
|
| if (!mask.fBounds.intersect(devBounds)) {
|
| return;
|
| @@ -1277,9 +1280,13 @@
|
| int ix = SkScalarRoundToInt(matrix.getTranslateX());
|
| int iy = SkScalarRoundToInt(matrix.getTranslateY());
|
| if (clipHandlesSprite(*fRC, ix, iy, pmap)) {
|
| + SkPixmap dstPM;
|
| + if (!fBitmap->peekPixels(&dstPM)) {
|
| + return;
|
| + }
|
| SkTBlitterAllocator allocator;
|
| // blitter will be owned by the allocator.
|
| - SkBlitter* blitter = SkBlitter::ChooseSprite(fDst, paint, pmap, ix, iy, &allocator);
|
| + SkBlitter* blitter = SkBlitter::ChooseSprite(dstPM, paint, pmap, ix, iy, &allocator);
|
| if (blitter) {
|
| SkScan::FillIRect(SkIRect::MakeXYWH(ix, iy, pmap.width(), pmap.height()),
|
| *fRC, blitter);
|
| @@ -1334,9 +1341,13 @@
|
| const SkPixmap& pmap = unlocker.pixmap();
|
|
|
| if (NULL == paint.getColorFilter() && clipHandlesSprite(*fRC, x, y, pmap)) {
|
| + SkPixmap dstPM;
|
| + if (!fBitmap->peekPixels(&dstPM)) {
|
| + return;
|
| + }
|
| SkTBlitterAllocator allocator;
|
| // blitter will be owned by the allocator.
|
| - SkBlitter* blitter = SkBlitter::ChooseSprite(fDst, paint, pmap, x, y, &allocator);
|
| + SkBlitter* blitter = SkBlitter::ChooseSprite(dstPM, paint, pmap, x, y, &allocator);
|
| if (blitter) {
|
| SkScan::FillIRect(bounds, *fRC, blitter);
|
| return;
|
| @@ -1635,7 +1646,7 @@
|
| SkAutoBlitterChoose blitterChooser;
|
| SkBlitter* blitter = NULL;
|
| if (needsRasterTextBlit(*this)) {
|
| - blitterChooser.choose(fDst, *fMatrix, paint);
|
| + blitterChooser.choose(*fBitmap, *fMatrix, paint);
|
| blitter = blitterChooser.get();
|
| if (fRC->isAA()) {
|
| aaBlitter.init(blitter, &fRC->aaRgn());
|
| @@ -1754,7 +1765,7 @@
|
| SkAutoBlitterChoose blitterChooser;
|
| SkBlitter* blitter = NULL;
|
| if (needsRasterTextBlit(*this)) {
|
| - blitterChooser.choose(fDst, *fMatrix, paint);
|
| + blitterChooser.choose(*fBitmap, *fMatrix, paint);
|
| blitter = blitterChooser.get();
|
| if (fRC->isAA()) {
|
| wrapper.init(*fRC, blitter);
|
| @@ -2084,7 +2095,7 @@
|
| }
|
| }
|
|
|
| - SkAutoBlitterChoose blitter(fDst, *fMatrix, p);
|
| + SkAutoBlitterChoose blitter(*fBitmap, *fMatrix, p);
|
| // Abort early if we failed to create a shader context.
|
| if (blitter->isNullBlitter()) {
|
| return;
|
| @@ -2155,6 +2166,7 @@
|
| #ifdef SK_DEBUG
|
|
|
| void SkDraw::validate() const {
|
| + SkASSERT(fBitmap != NULL);
|
| SkASSERT(fMatrix != NULL);
|
| SkASSERT(fClip != NULL);
|
| SkASSERT(fRC != NULL);
|
| @@ -2162,7 +2174,7 @@
|
| const SkIRect& cr = fRC->getBounds();
|
| SkIRect br;
|
|
|
| - br.set(0, 0, fDst.width(), fDst.height());
|
| + br.set(0, 0, fBitmap->width(), fBitmap->height());
|
| SkASSERT(cr.isEmpty() || br.contains(cr));
|
| }
|
|
|
| @@ -2218,20 +2230,22 @@
|
| return true;
|
| }
|
|
|
| -static void draw_into_mask(const SkMask& mask, const SkPath& devPath, SkPaint::Style style) {
|
| - SkDraw draw;
|
| - if (!draw.fDst.reset(mask)) {
|
| - return;
|
| - }
|
| -
|
| +static void draw_into_mask(const SkMask& mask, const SkPath& devPath,
|
| + SkPaint::Style style) {
|
| + SkBitmap bm;
|
| + SkDraw draw;
|
| SkRasterClip clip;
|
| SkMatrix matrix;
|
| SkPaint paint;
|
|
|
| + bm.installPixels(SkImageInfo::MakeA8(mask.fBounds.width(), mask.fBounds.height()),
|
| + mask.fImage, mask.fRowBytes);
|
| +
|
| clip.setRect(SkIRect::MakeWH(mask.fBounds.width(), mask.fBounds.height()));
|
| matrix.setTranslate(-SkIntToScalar(mask.fBounds.fLeft),
|
| -SkIntToScalar(mask.fBounds.fTop));
|
|
|
| + draw.fBitmap = &bm;
|
| draw.fRC = &clip;
|
| draw.fClip = &clip.bwRgn();
|
| draw.fMatrix = &matrix;
|
|
|