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 |