| OLD | NEW |
| 1 /* | 1 /* |
| 2 * Copyright 2006 The Android Open Source Project | 2 * Copyright 2006 The Android Open Source Project |
| 3 * | 3 * |
| 4 * Use of this source code is governed by a BSD-style license that can be | 4 * Use of this source code is governed by a BSD-style license that can be |
| 5 * found in the LICENSE file. | 5 * found in the LICENSE file. |
| 6 */ | 6 */ |
| 7 | 7 |
| 8 #include "SkDraw.h" | 8 #include "SkDraw.h" |
| 9 #include "SkBlitter.h" | 9 #include "SkBlitter.h" |
| 10 #include "SkCanvas.h" | 10 #include "SkCanvas.h" |
| (...skipping 768 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 779 } | 779 } |
| 780 | 780 |
| 781 static const SkPoint* rect_points(const SkRect& r) { | 781 static const SkPoint* rect_points(const SkRect& r) { |
| 782 return SkTCast<const SkPoint*>(&r); | 782 return SkTCast<const SkPoint*>(&r); |
| 783 } | 783 } |
| 784 | 784 |
| 785 static SkPoint* rect_points(SkRect& r) { | 785 static SkPoint* rect_points(SkRect& r) { |
| 786 return SkTCast<SkPoint*>(&r); | 786 return SkTCast<SkPoint*>(&r); |
| 787 } | 787 } |
| 788 | 788 |
| 789 void SkDraw::drawRect(const SkRect& rect, const SkPaint& paint) const { | 789 void SkDraw::drawRect(const SkRect& prePaintRect, const SkPaint& paint, |
| 790 const SkMatrix* paintMatrix, const SkRect* postPaintRect)
const { |
| 790 SkDEBUGCODE(this->validate();) | 791 SkDEBUGCODE(this->validate();) |
| 791 | 792 |
| 792 // nothing to draw | 793 // nothing to draw |
| 793 if (fRC->isEmpty()) { | 794 if (fRC->isEmpty()) { |
| 794 return; | 795 return; |
| 795 } | 796 } |
| 796 | 797 |
| 798 const SkMatrix* matrix; |
| 799 SkMatrix combinedMatrixStorage; |
| 800 if (paintMatrix) { |
| 801 SkASSERT(postPaintRect); |
| 802 combinedMatrixStorage.setConcat(*fMatrix, *paintMatrix); |
| 803 matrix = &combinedMatrixStorage; |
| 804 } else { |
| 805 SkASSERT(!postPaintRect); |
| 806 matrix = fMatrix; |
| 807 } |
| 808 |
| 797 SkPoint strokeSize; | 809 SkPoint strokeSize; |
| 798 RectType rtype = ComputeRectType(paint, *fMatrix, &strokeSize); | 810 RectType rtype = ComputeRectType(paint, *fMatrix, &strokeSize); |
| 799 | 811 |
| 800 if (kPath_RectType == rtype) { | 812 if (kPath_RectType == rtype) { |
| 813 SkDraw draw(*this); |
| 814 if (paintMatrix) { |
| 815 draw.fMatrix = matrix; |
| 816 } |
| 801 SkPath tmp; | 817 SkPath tmp; |
| 802 tmp.addRect(rect); | 818 tmp.addRect(prePaintRect); |
| 803 tmp.setFillType(SkPath::kWinding_FillType); | 819 tmp.setFillType(SkPath::kWinding_FillType); |
| 804 this->drawPath(tmp, paint, NULL, true); | 820 draw.drawPath(tmp, paint, NULL, true); |
| 805 return; | 821 return; |
| 806 } | 822 } |
| 807 | 823 |
| 808 const SkMatrix& matrix = *fMatrix; | 824 SkRect devRect; |
| 809 SkRect devRect; | 825 if (paintMatrix) { |
| 810 | 826 // skip the paintMatrix when transforming the rect by the CTM |
| 827 fMatrix->mapPoints(rect_points(devRect), rect_points(*postPaintRect), 2)
; |
| 828 } else { |
| 829 fMatrix->mapPoints(rect_points(devRect), rect_points(prePaintRect), 2); |
| 830 } |
| 811 // transform rect into devRect | 831 // transform rect into devRect |
| 812 matrix.mapPoints(rect_points(devRect), rect_points(rect), 2); | |
| 813 devRect.sort(); | 832 devRect.sort(); |
| 814 | 833 |
| 815 // look for the quick exit, before we build a blitter | 834 // look for the quick exit, before we build a blitter |
| 816 SkIRect ir = devRect.roundOut(); | 835 SkIRect ir = devRect.roundOut(); |
| 817 if (paint.getStyle() != SkPaint::kFill_Style) { | 836 if (paint.getStyle() != SkPaint::kFill_Style) { |
| 818 // extra space for hairlines | 837 // extra space for hairlines |
| 819 if (paint.getStrokeWidth() == 0) { | 838 if (paint.getStrokeWidth() == 0) { |
| 820 ir.outset(1, 1); | 839 ir.outset(1, 1); |
| 821 } else { | 840 } else { |
| 822 SkScalar radius = SkScalarHalf(paint.getStrokeWidth()); | 841 SkScalar radius = SkScalarHalf(paint.getStrokeWidth()); |
| 823 ir.outset(radius, radius); | 842 ir.outset(radius, radius); |
| 824 } | 843 } |
| 825 } | 844 } |
| 826 if (fRC->quickReject(ir)) { | 845 if (fRC->quickReject(ir)) { |
| 827 return; | 846 return; |
| 828 } | 847 } |
| 829 | 848 |
| 830 SkDeviceLooper looper(*fBitmap, *fRC, ir, paint.isAntiAlias()); | 849 SkDeviceLooper looper(*fBitmap, *fRC, ir, paint.isAntiAlias()); |
| 831 while (looper.next()) { | 850 while (looper.next()) { |
| 832 SkRect localDevRect; | 851 SkRect localDevRect; |
| 833 looper.mapRect(&localDevRect, devRect); | 852 looper.mapRect(&localDevRect, devRect); |
| 834 SkMatrix localMatrix; | 853 SkMatrix localMatrix; |
| 835 looper.mapMatrix(&localMatrix, matrix); | 854 looper.mapMatrix(&localMatrix, *matrix); |
| 836 | 855 |
| 837 SkAutoBlitterChoose blitterStorage(looper.getBitmap(), localMatrix, | 856 SkAutoBlitterChoose blitterStorage(looper.getBitmap(), localMatrix, pain
t); |
| 838 paint); | |
| 839 const SkRasterClip& clip = looper.getRC(); | 857 const SkRasterClip& clip = looper.getRC(); |
| 840 SkBlitter* blitter = blitterStorage.get(); | 858 SkBlitter* blitter = blitterStorage.get(); |
| 841 | 859 |
| 842 // we want to "fill" if we are kFill or kStrokeAndFill, since in the lat
ter | 860 // we want to "fill" if we are kFill or kStrokeAndFill, since in the lat
ter |
| 843 // case we are also hairline (if we've gotten to here), which devolves t
o | 861 // case we are also hairline (if we've gotten to here), which devolves t
o |
| 844 // effectively just kFill | 862 // effectively just kFill |
| 845 switch (rtype) { | 863 switch (rtype) { |
| 846 case kFill_RectType: | 864 case kFill_RectType: |
| 847 if (paint.isAntiAlias()) { | 865 if (paint.isAntiAlias()) { |
| 848 SkScan::AntiFillRect(localDevRect, clip, blitter); | 866 SkScan::AntiFillRect(localDevRect, clip, blitter); |
| (...skipping 371 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1220 return clipped_out(matrix, clip, r); | 1238 return clipped_out(matrix, clip, r); |
| 1221 } | 1239 } |
| 1222 | 1240 |
| 1223 static bool clipHandlesSprite(const SkRasterClip& clip, int x, int y, | 1241 static bool clipHandlesSprite(const SkRasterClip& clip, int x, int y, |
| 1224 const SkBitmap& bitmap) { | 1242 const SkBitmap& bitmap) { |
| 1225 return clip.isBW() || | 1243 return clip.isBW() || |
| 1226 clip.quickContains(x, y, x + bitmap.width(), y + bitmap.height()); | 1244 clip.quickContains(x, y, x + bitmap.width(), y + bitmap.height()); |
| 1227 } | 1245 } |
| 1228 | 1246 |
| 1229 void SkDraw::drawBitmap(const SkBitmap& bitmap, const SkMatrix& prematrix, | 1247 void SkDraw::drawBitmap(const SkBitmap& bitmap, const SkMatrix& prematrix, |
| 1230 const SkPaint& origPaint) const { | 1248 const SkRect* dstBounds, const SkPaint& origPaint) const
{ |
| 1231 SkDEBUGCODE(this->validate();) | 1249 SkDEBUGCODE(this->validate();) |
| 1232 | 1250 |
| 1233 // nothing to draw | 1251 // nothing to draw |
| 1234 if (fRC->isEmpty() || | 1252 if (fRC->isEmpty() || |
| 1235 bitmap.width() == 0 || bitmap.height() == 0 || | 1253 bitmap.width() == 0 || bitmap.height() == 0 || |
| 1236 bitmap.colorType() == kUnknown_SkColorType) { | 1254 bitmap.colorType() == kUnknown_SkColorType) { |
| 1237 return; | 1255 return; |
| 1238 } | 1256 } |
| 1239 | 1257 |
| 1240 SkPaint paint(origPaint); | 1258 SkPaint paint(origPaint); |
| (...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1275 | 1293 |
| 1276 // now make a temp draw on the stack, and use it | 1294 // now make a temp draw on the stack, and use it |
| 1277 // | 1295 // |
| 1278 SkDraw draw(*this); | 1296 SkDraw draw(*this); |
| 1279 draw.fMatrix = &matrix; | 1297 draw.fMatrix = &matrix; |
| 1280 | 1298 |
| 1281 if (bitmap.colorType() == kAlpha_8_SkColorType) { | 1299 if (bitmap.colorType() == kAlpha_8_SkColorType) { |
| 1282 draw.drawBitmapAsMask(bitmap, paint); | 1300 draw.drawBitmapAsMask(bitmap, paint); |
| 1283 } else { | 1301 } else { |
| 1284 SkAutoBitmapShaderInstall install(bitmap, paint); | 1302 SkAutoBitmapShaderInstall install(bitmap, paint); |
| 1285 | 1303 const SkPaint& paintWithShader = install.paintWithShader(); |
| 1286 SkRect r; | 1304 const SkRect srcBounds = SkRect::MakeIWH(bitmap.width(), bitmap.height()
); |
| 1287 r.set(0, 0, SkIntToScalar(bitmap.width()), | 1305 if (dstBounds) { |
| 1288 SkIntToScalar(bitmap.height())); | 1306 this->drawRect(srcBounds, paintWithShader, &prematrix, dstBounds); |
| 1289 // is this ok if paint has a rasterizer? | 1307 } else { |
| 1290 draw.drawRect(r, install.paintWithShader()); | 1308 draw.drawRect(srcBounds, paintWithShader); |
| 1309 } |
| 1291 } | 1310 } |
| 1292 } | 1311 } |
| 1293 | 1312 |
| 1294 void SkDraw::drawSprite(const SkBitmap& bitmap, int x, int y, | 1313 void SkDraw::drawSprite(const SkBitmap& bitmap, int x, int y, |
| 1295 const SkPaint& origPaint) const { | 1314 const SkPaint& origPaint) const { |
| 1296 SkDEBUGCODE(this->validate();) | 1315 SkDEBUGCODE(this->validate();) |
| 1297 | 1316 |
| 1298 // nothing to draw | 1317 // nothing to draw |
| 1299 if (fRC->isEmpty() || | 1318 if (fRC->isEmpty() || |
| 1300 bitmap.width() == 0 || bitmap.height() == 0 || | 1319 bitmap.width() == 0 || bitmap.height() == 0 || |
| (...skipping 1069 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2370 mask->fImage = SkMask::AllocImage(size); | 2389 mask->fImage = SkMask::AllocImage(size); |
| 2371 memset(mask->fImage, 0, mask->computeImageSize()); | 2390 memset(mask->fImage, 0, mask->computeImageSize()); |
| 2372 } | 2391 } |
| 2373 | 2392 |
| 2374 if (SkMask::kJustComputeBounds_CreateMode != mode) { | 2393 if (SkMask::kJustComputeBounds_CreateMode != mode) { |
| 2375 draw_into_mask(*mask, devPath, style); | 2394 draw_into_mask(*mask, devPath, style); |
| 2376 } | 2395 } |
| 2377 | 2396 |
| 2378 return true; | 2397 return true; |
| 2379 } | 2398 } |
| OLD | NEW |