| 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 "SkBounder.h" | |
| 11 #include "SkCanvas.h" | 10 #include "SkCanvas.h" |
| 12 #include "SkColorPriv.h" | 11 #include "SkColorPriv.h" |
| 13 #include "SkDevice.h" | 12 #include "SkDevice.h" |
| 14 #include "SkDeviceLooper.h" | 13 #include "SkDeviceLooper.h" |
| 15 #include "SkFixed.h" | 14 #include "SkFixed.h" |
| 16 #include "SkMaskFilter.h" | 15 #include "SkMaskFilter.h" |
| 17 #include "SkPaint.h" | 16 #include "SkPaint.h" |
| 18 #include "SkPathEffect.h" | 17 #include "SkPathEffect.h" |
| 19 #include "SkRasterClip.h" | 18 #include "SkRasterClip.h" |
| 20 #include "SkRasterizer.h" | 19 #include "SkRasterizer.h" |
| (...skipping 231 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 252 | 251 |
| 253 void SkDraw::drawPaint(const SkPaint& paint) const { | 252 void SkDraw::drawPaint(const SkPaint& paint) const { |
| 254 SkDEBUGCODE(this->validate();) | 253 SkDEBUGCODE(this->validate();) |
| 255 | 254 |
| 256 if (fRC->isEmpty()) { | 255 if (fRC->isEmpty()) { |
| 257 return; | 256 return; |
| 258 } | 257 } |
| 259 | 258 |
| 260 SkIRect devRect; | 259 SkIRect devRect; |
| 261 devRect.set(0, 0, fBitmap->width(), fBitmap->height()); | 260 devRect.set(0, 0, fBitmap->width(), fBitmap->height()); |
| 262 if (fBounder && !fBounder->doIRect(devRect)) { | |
| 263 return; | |
| 264 } | |
| 265 | 261 |
| 266 if (fRC->isBW()) { | 262 if (fRC->isBW()) { |
| 267 /* If we don't have a shader (i.e. we're just a solid color) we may | 263 /* If we don't have a shader (i.e. we're just a solid color) we may |
| 268 be faster to operate directly on the device bitmap, rather than invo
king | 264 be faster to operate directly on the device bitmap, rather than invo
king |
| 269 a blitter. Esp. true for xfermodes, which require a colorshader to b
e | 265 a blitter. Esp. true for xfermodes, which require a colorshader to b
e |
| 270 present, which is just redundant work. Since we're drawing everywher
e | 266 present, which is just redundant work. Since we're drawing everywher
e |
| 271 in the clip, we don't have to worry about antialiasing. | 267 in the clip, we don't have to worry about antialiasing. |
| 272 */ | 268 */ |
| 273 uint32_t procData = 0; // to avoid the warning | 269 uint32_t procData = 0; // to avoid the warning |
| 274 BitmapXferProc proc = ChooseBitmapXferProc(*fBitmap, paint, &procData); | 270 BitmapXferProc proc = ChooseBitmapXferProc(*fBitmap, paint, &procData); |
| (...skipping 253 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 528 }; | 524 }; |
| 529 proc = gBWProcs[fMode]; | 525 proc = gBWProcs[fMode]; |
| 530 } | 526 } |
| 531 } else { | 527 } else { |
| 532 proc = bw_square_proc; | 528 proc = bw_square_proc; |
| 533 } | 529 } |
| 534 } | 530 } |
| 535 return proc; | 531 return proc; |
| 536 } | 532 } |
| 537 | 533 |
| 538 static bool bounder_points(SkBounder* bounder, SkCanvas::PointMode mode, | |
| 539 size_t count, const SkPoint pts[], | |
| 540 const SkPaint& paint, const SkMatrix& matrix) { | |
| 541 SkIRect ibounds; | |
| 542 SkRect bounds; | |
| 543 SkScalar inset = paint.getStrokeWidth(); | |
| 544 | |
| 545 bounds.set(pts, SkToInt(count)); | |
| 546 bounds.inset(-inset, -inset); | |
| 547 matrix.mapRect(&bounds); | |
| 548 | |
| 549 bounds.roundOut(&ibounds); | |
| 550 return bounder->doIRect(ibounds); | |
| 551 } | |
| 552 | |
| 553 // each of these costs 8-bytes of stack space, so don't make it too large | 534 // each of these costs 8-bytes of stack space, so don't make it too large |
| 554 // must be even for lines/polygon to work | 535 // must be even for lines/polygon to work |
| 555 #define MAX_DEV_PTS 32 | 536 #define MAX_DEV_PTS 32 |
| 556 | 537 |
| 557 void SkDraw::drawPoints(SkCanvas::PointMode mode, size_t count, | 538 void SkDraw::drawPoints(SkCanvas::PointMode mode, size_t count, |
| 558 const SkPoint pts[], const SkPaint& paint, | 539 const SkPoint pts[], const SkPaint& paint, |
| 559 bool forceUseDevice) const { | 540 bool forceUseDevice) const { |
| 560 // if we're in lines mode, force count to be even | 541 // if we're in lines mode, force count to be even |
| 561 if (SkCanvas::kLines_PointMode == mode) { | 542 if (SkCanvas::kLines_PointMode == mode) { |
| 562 count &= ~(size_t)1; | 543 count &= ~(size_t)1; |
| 563 } | 544 } |
| 564 | 545 |
| 565 if ((long)count <= 0) { | 546 if ((long)count <= 0) { |
| 566 return; | 547 return; |
| 567 } | 548 } |
| 568 | 549 |
| 569 SkASSERT(pts != NULL); | 550 SkASSERT(pts != NULL); |
| 570 SkDEBUGCODE(this->validate();) | 551 SkDEBUGCODE(this->validate();) |
| 571 | 552 |
| 572 // nothing to draw | 553 // nothing to draw |
| 573 if (fRC->isEmpty()) { | 554 if (fRC->isEmpty()) { |
| 574 return; | 555 return; |
| 575 } | 556 } |
| 576 | 557 |
| 577 if (fBounder) { | |
| 578 if (!bounder_points(fBounder, mode, count, pts, paint, *fMatrix)) { | |
| 579 return; | |
| 580 } | |
| 581 | |
| 582 // clear the bounder and call this again, so we don't invoke the bounder | |
| 583 // later if we happen to call ourselves for drawRect, drawPath, etc. | |
| 584 SkDraw noBounder(*this); | |
| 585 noBounder.fBounder = NULL; | |
| 586 noBounder.drawPoints(mode, count, pts, paint, forceUseDevice); | |
| 587 return; | |
| 588 } | |
| 589 | |
| 590 PtProcRec rec; | 558 PtProcRec rec; |
| 591 if (!forceUseDevice && rec.init(mode, paint, fMatrix, fRC)) { | 559 if (!forceUseDevice && rec.init(mode, paint, fMatrix, fRC)) { |
| 592 SkAutoBlitterChoose blitter(*fBitmap, *fMatrix, paint); | 560 SkAutoBlitterChoose blitter(*fBitmap, *fMatrix, paint); |
| 593 | 561 |
| 594 SkPoint devPts[MAX_DEV_PTS]; | 562 SkPoint devPts[MAX_DEV_PTS]; |
| 595 const SkMatrix* matrix = fMatrix; | 563 const SkMatrix* matrix = fMatrix; |
| 596 SkBlitter* bltr = blitter.get(); | 564 SkBlitter* bltr = blitter.get(); |
| 597 PtProcRec::Proc proc = rec.chooseProc(&bltr); | 565 PtProcRec::Proc proc = rec.chooseProc(&bltr); |
| 598 // we have to back up subsequent passes if we're in polygon mode | 566 // we have to back up subsequent passes if we're in polygon mode |
| 599 const size_t backup = (SkCanvas::kPolygon_PointMode == mode); | 567 const size_t backup = (SkCanvas::kPolygon_PointMode == mode); |
| (...skipping 235 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 835 return; | 803 return; |
| 836 } | 804 } |
| 837 | 805 |
| 838 const SkMatrix& matrix = *fMatrix; | 806 const SkMatrix& matrix = *fMatrix; |
| 839 SkRect devRect; | 807 SkRect devRect; |
| 840 | 808 |
| 841 // transform rect into devRect | 809 // transform rect into devRect |
| 842 matrix.mapPoints(rect_points(devRect), rect_points(rect), 2); | 810 matrix.mapPoints(rect_points(devRect), rect_points(rect), 2); |
| 843 devRect.sort(); | 811 devRect.sort(); |
| 844 | 812 |
| 845 if (fBounder && !fBounder->doRect(devRect, paint)) { | |
| 846 return; | |
| 847 } | |
| 848 | |
| 849 // look for the quick exit, before we build a blitter | 813 // look for the quick exit, before we build a blitter |
| 850 SkIRect ir; | 814 SkIRect ir; |
| 851 devRect.roundOut(&ir); | 815 devRect.roundOut(&ir); |
| 852 if (paint.getStyle() != SkPaint::kFill_Style) { | 816 if (paint.getStyle() != SkPaint::kFill_Style) { |
| 853 // extra space for hairlines | 817 // extra space for hairlines |
| 854 ir.inset(-1, -1); | 818 ir.inset(-1, -1); |
| 855 } | 819 } |
| 856 if (fRC->quickReject(ir)) { | 820 if (fRC->quickReject(ir)) { |
| 857 return; | 821 return; |
| 858 } | 822 } |
| (...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 909 | 873 |
| 910 SkMask dstM; | 874 SkMask dstM; |
| 911 if (paint.getMaskFilter() && | 875 if (paint.getMaskFilter() && |
| 912 paint.getMaskFilter()->filterMask(&dstM, srcM, *fMatrix, NULL)) { | 876 paint.getMaskFilter()->filterMask(&dstM, srcM, *fMatrix, NULL)) { |
| 913 mask = &dstM; | 877 mask = &dstM; |
| 914 } else { | 878 } else { |
| 915 dstM.fImage = NULL; | 879 dstM.fImage = NULL; |
| 916 } | 880 } |
| 917 SkAutoMaskFreeImage ami(dstM.fImage); | 881 SkAutoMaskFreeImage ami(dstM.fImage); |
| 918 | 882 |
| 919 if (fBounder && !fBounder->doIRect(mask->fBounds)) { | |
| 920 return; | |
| 921 } | |
| 922 | |
| 923 SkAutoBlitterChoose blitterChooser(*fBitmap, *fMatrix, paint); | 883 SkAutoBlitterChoose blitterChooser(*fBitmap, *fMatrix, paint); |
| 924 SkBlitter* blitter = blitterChooser.get(); | 884 SkBlitter* blitter = blitterChooser.get(); |
| 925 | 885 |
| 926 SkAAClipBlitterWrapper wrapper; | 886 SkAAClipBlitterWrapper wrapper; |
| 927 const SkRegion* clipRgn; | 887 const SkRegion* clipRgn; |
| 928 | 888 |
| 929 if (fRC->isBW()) { | 889 if (fRC->isBW()) { |
| 930 clipRgn = &fRC->bwRgn(); | 890 clipRgn = &fRC->bwRgn(); |
| 931 } else { | 891 } else { |
| 932 wrapper.init(*fRC, blitter); | 892 wrapper.init(*fRC, blitter); |
| (...skipping 75 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1008 if (paint.getRasterizer()) { | 968 if (paint.getRasterizer()) { |
| 1009 goto DRAW_PATH; | 969 goto DRAW_PATH; |
| 1010 } | 970 } |
| 1011 } | 971 } |
| 1012 | 972 |
| 1013 if (paint.getMaskFilter()) { | 973 if (paint.getMaskFilter()) { |
| 1014 // Transform the rrect into device space. | 974 // Transform the rrect into device space. |
| 1015 SkRRect devRRect; | 975 SkRRect devRRect; |
| 1016 if (rrect.transform(*fMatrix, &devRRect)) { | 976 if (rrect.transform(*fMatrix, &devRRect)) { |
| 1017 SkAutoBlitterChoose blitter(*fBitmap, *fMatrix, paint); | 977 SkAutoBlitterChoose blitter(*fBitmap, *fMatrix, paint); |
| 1018 if (paint.getMaskFilter()->filterRRect(devRRect, *fMatrix, *fRC, | 978 if (paint.getMaskFilter()->filterRRect(devRRect, *fMatrix, *fRC, bli
tter.get(), |
| 1019 fBounder, blitter.get(), | |
| 1020 SkPaint::kFill_Style)) { | 979 SkPaint::kFill_Style)) { |
| 1021 return; // filterRRect() called the blitter, so we're done | 980 return; // filterRRect() called the blitter, so we're done |
| 1022 } | 981 } |
| 1023 } | 982 } |
| 1024 } | 983 } |
| 1025 | 984 |
| 1026 DRAW_PATH: | 985 DRAW_PATH: |
| 1027 // Now fall back to the default case of using a path. | 986 // Now fall back to the default case of using a path. |
| 1028 SkPath path; | 987 SkPath path; |
| 1029 path.addRRect(rrect); | 988 path.addRRect(rrect); |
| (...skipping 86 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1116 SkPath* devPathPtr = pathIsMutable ? pathPtr : &tmpPath; | 1075 SkPath* devPathPtr = pathIsMutable ? pathPtr : &tmpPath; |
| 1117 | 1076 |
| 1118 // transform the path into device space | 1077 // transform the path into device space |
| 1119 pathPtr->transform(*matrix, devPathPtr); | 1078 pathPtr->transform(*matrix, devPathPtr); |
| 1120 | 1079 |
| 1121 SkAutoBlitterChoose blitter(*fBitmap, *fMatrix, *paint, drawCoverage); | 1080 SkAutoBlitterChoose blitter(*fBitmap, *fMatrix, *paint, drawCoverage); |
| 1122 | 1081 |
| 1123 if (paint->getMaskFilter()) { | 1082 if (paint->getMaskFilter()) { |
| 1124 SkPaint::Style style = doFill ? SkPaint::kFill_Style : | 1083 SkPaint::Style style = doFill ? SkPaint::kFill_Style : |
| 1125 SkPaint::kStroke_Style; | 1084 SkPaint::kStroke_Style; |
| 1126 if (paint->getMaskFilter()->filterPath(*devPathPtr, *fMatrix, *fRC, | 1085 if (paint->getMaskFilter()->filterPath(*devPathPtr, *fMatrix, *fRC, blit
ter.get(), style)) { |
| 1127 fBounder, blitter.get(), | |
| 1128 style)) { | |
| 1129 return; // filterPath() called the blitter, so we're done | 1086 return; // filterPath() called the blitter, so we're done |
| 1130 } | 1087 } |
| 1131 } | 1088 } |
| 1132 | 1089 |
| 1133 if (fBounder && !fBounder->doPath(*devPathPtr, *paint, doFill)) { | |
| 1134 return; | |
| 1135 } | |
| 1136 | |
| 1137 void (*proc)(const SkPath&, const SkRasterClip&, SkBlitter*); | 1090 void (*proc)(const SkPath&, const SkRasterClip&, SkBlitter*); |
| 1138 if (doFill) { | 1091 if (doFill) { |
| 1139 if (paint->isAntiAlias()) { | 1092 if (paint->isAntiAlias()) { |
| 1140 proc = SkScan::AntiFillPath; | 1093 proc = SkScan::AntiFillPath; |
| 1141 } else { | 1094 } else { |
| 1142 proc = SkScan::FillPath; | 1095 proc = SkScan::FillPath; |
| 1143 } | 1096 } |
| 1144 } else { // hairline | 1097 } else { // hairline |
| 1145 if (paint->isAntiAlias()) { | 1098 if (paint->isAntiAlias()) { |
| 1146 proc = SkScan::AntiHairPath; | 1099 proc = SkScan::AntiHairPath; |
| (...skipping 129 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1276 SkPaint paint(origPaint); | 1229 SkPaint paint(origPaint); |
| 1277 paint.setStyle(SkPaint::kFill_Style); | 1230 paint.setStyle(SkPaint::kFill_Style); |
| 1278 | 1231 |
| 1279 SkMatrix matrix; | 1232 SkMatrix matrix; |
| 1280 matrix.setConcat(*fMatrix, prematrix); | 1233 matrix.setConcat(*fMatrix, prematrix); |
| 1281 | 1234 |
| 1282 if (clipped_out(matrix, *fRC, bitmap.width(), bitmap.height())) { | 1235 if (clipped_out(matrix, *fRC, bitmap.width(), bitmap.height())) { |
| 1283 return; | 1236 return; |
| 1284 } | 1237 } |
| 1285 | 1238 |
| 1286 if (fBounder && just_translate(matrix, bitmap)) { | 1239 if (bitmap.colorType() != kAlpha_8_SkColorType && just_translate(matrix, bit
map)) { |
| 1287 SkIRect ir; | |
| 1288 int32_t ix = SkScalarRoundToInt(matrix.getTranslateX()); | |
| 1289 int32_t iy = SkScalarRoundToInt(matrix.getTranslateY()); | |
| 1290 ir.set(ix, iy, ix + bitmap.width(), iy + bitmap.height()); | |
| 1291 if (!fBounder->doIRect(ir)) { | |
| 1292 return; | |
| 1293 } | |
| 1294 } | |
| 1295 | |
| 1296 if (bitmap.colorType() != kAlpha_8_SkColorType && | |
| 1297 just_translate(matrix, bitmap)) { | |
| 1298 // | 1240 // |
| 1299 // It is safe to call lock pixels now, since we know the matrix is | 1241 // It is safe to call lock pixels now, since we know the matrix is |
| 1300 // (more or less) identity. | 1242 // (more or less) identity. |
| 1301 // | 1243 // |
| 1302 SkAutoLockPixels alp(bitmap); | 1244 SkAutoLockPixels alp(bitmap); |
| 1303 if (!bitmap.readyToDraw()) { | 1245 if (!bitmap.readyToDraw()) { |
| 1304 return; | 1246 return; |
| 1305 } | 1247 } |
| 1306 int ix = SkScalarRoundToInt(matrix.getTranslateX()); | 1248 int ix = SkScalarRoundToInt(matrix.getTranslateX()); |
| 1307 int iy = SkScalarRoundToInt(matrix.getTranslateY()); | 1249 int iy = SkScalarRoundToInt(matrix.getTranslateY()); |
| (...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1359 SkPaint paint(origPaint); | 1301 SkPaint paint(origPaint); |
| 1360 paint.setStyle(SkPaint::kFill_Style); | 1302 paint.setStyle(SkPaint::kFill_Style); |
| 1361 | 1303 |
| 1362 if (NULL == paint.getColorFilter() && clipHandlesSprite(*fRC, x, y, bitmap))
{ | 1304 if (NULL == paint.getColorFilter() && clipHandlesSprite(*fRC, x, y, bitmap))
{ |
| 1363 SkTBlitterAllocator allocator; | 1305 SkTBlitterAllocator allocator; |
| 1364 // blitter will be owned by the allocator. | 1306 // blitter will be owned by the allocator. |
| 1365 SkBlitter* blitter = SkBlitter::ChooseSprite(*fBitmap, paint, bitmap, | 1307 SkBlitter* blitter = SkBlitter::ChooseSprite(*fBitmap, paint, bitmap, |
| 1366 x, y, &allocator); | 1308 x, y, &allocator); |
| 1367 | 1309 |
| 1368 if (blitter) { | 1310 if (blitter) { |
| 1369 if (fBounder && !fBounder->doIRect(bounds)) { | |
| 1370 return; | |
| 1371 } | |
| 1372 | |
| 1373 SkScan::FillIRect(bounds, *fRC, blitter); | 1311 SkScan::FillIRect(bounds, *fRC, blitter); |
| 1374 return; | 1312 return; |
| 1375 } | 1313 } |
| 1376 } | 1314 } |
| 1377 | 1315 |
| 1378 SkMatrix matrix; | 1316 SkMatrix matrix; |
| 1379 SkRect r; | 1317 SkRect r; |
| 1380 | 1318 |
| 1381 // get a scalar version of our rect | 1319 // get a scalar version of our rect |
| 1382 r.set(bounds); | 1320 r.set(bounds); |
| (...skipping 82 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1465 } | 1403 } |
| 1466 | 1404 |
| 1467 // disable warning : local variable used without having been initialized | 1405 // disable warning : local variable used without having been initialized |
| 1468 #if defined _WIN32 && _MSC_VER >= 1300 | 1406 #if defined _WIN32 && _MSC_VER >= 1300 |
| 1469 #pragma warning ( push ) | 1407 #pragma warning ( push ) |
| 1470 #pragma warning ( disable : 4701 ) | 1408 #pragma warning ( disable : 4701 ) |
| 1471 #endif | 1409 #endif |
| 1472 | 1410 |
| 1473 ////////////////////////////////////////////////////////////////////////////// | 1411 ////////////////////////////////////////////////////////////////////////////// |
| 1474 | 1412 |
| 1475 static void D1G_NoBounder_RectClip(const SkDraw1Glyph& state, | 1413 static void D1G_RectClip(const SkDraw1Glyph& state, SkFixed fx, SkFixed fy, cons
t SkGlyph& glyph) { |
| 1476 SkFixed fx, SkFixed fy, | |
| 1477 const SkGlyph& glyph) { | |
| 1478 int left = SkFixedFloorToInt(fx); | 1414 int left = SkFixedFloorToInt(fx); |
| 1479 int top = SkFixedFloorToInt(fy); | 1415 int top = SkFixedFloorToInt(fy); |
| 1480 SkASSERT(glyph.fWidth > 0 && glyph.fHeight > 0); | 1416 SkASSERT(glyph.fWidth > 0 && glyph.fHeight > 0); |
| 1481 SkASSERT(NULL == state.fBounder); | |
| 1482 SkASSERT((NULL == state.fClip && state.fAAClip) || | 1417 SkASSERT((NULL == state.fClip && state.fAAClip) || |
| 1483 (state.fClip && NULL == state.fAAClip && state.fClip->isRect())); | 1418 (state.fClip && NULL == state.fAAClip && state.fClip->isRect())); |
| 1484 | 1419 |
| 1485 left += glyph.fLeft; | 1420 left += glyph.fLeft; |
| 1486 top += glyph.fTop; | 1421 top += glyph.fTop; |
| 1487 | 1422 |
| 1488 int right = left + glyph.fWidth; | 1423 int right = left + glyph.fWidth; |
| 1489 int bottom = top + glyph.fHeight; | 1424 int bottom = top + glyph.fHeight; |
| 1490 | 1425 |
| 1491 SkMask mask; | 1426 SkMask mask; |
| (...skipping 17 matching lines...) Expand all Loading... |
| 1509 return; // can't rasterize glyph | 1444 return; // can't rasterize glyph |
| 1510 } | 1445 } |
| 1511 } | 1446 } |
| 1512 | 1447 |
| 1513 mask.fRowBytes = glyph.rowBytes(); | 1448 mask.fRowBytes = glyph.rowBytes(); |
| 1514 mask.fFormat = static_cast<SkMask::Format>(glyph.fMaskFormat); | 1449 mask.fFormat = static_cast<SkMask::Format>(glyph.fMaskFormat); |
| 1515 mask.fImage = aa; | 1450 mask.fImage = aa; |
| 1516 state.blitMask(mask, *bounds); | 1451 state.blitMask(mask, *bounds); |
| 1517 } | 1452 } |
| 1518 | 1453 |
| 1519 static void D1G_NoBounder_RgnClip(const SkDraw1Glyph& state, | 1454 static void D1G_RgnClip(const SkDraw1Glyph& state, SkFixed fx, SkFixed fy, const
SkGlyph& glyph) { |
| 1520 SkFixed fx, SkFixed fy, | |
| 1521 const SkGlyph& glyph) { | |
| 1522 int left = SkFixedFloorToInt(fx); | 1455 int left = SkFixedFloorToInt(fx); |
| 1523 int top = SkFixedFloorToInt(fy); | 1456 int top = SkFixedFloorToInt(fy); |
| 1524 SkASSERT(glyph.fWidth > 0 && glyph.fHeight > 0); | 1457 SkASSERT(glyph.fWidth > 0 && glyph.fHeight > 0); |
| 1525 SkASSERT(!state.fClip->isRect()); | 1458 SkASSERT(!state.fClip->isRect()); |
| 1526 SkASSERT(NULL == state.fBounder); | |
| 1527 | 1459 |
| 1528 SkMask mask; | 1460 SkMask mask; |
| 1529 | 1461 |
| 1530 left += glyph.fLeft; | 1462 left += glyph.fLeft; |
| 1531 top += glyph.fTop; | 1463 top += glyph.fTop; |
| 1532 | 1464 |
| 1533 mask.fBounds.set(left, top, left + glyph.fWidth, top + glyph.fHeight); | 1465 mask.fBounds.set(left, top, left + glyph.fWidth, top + glyph.fHeight); |
| 1534 SkRegion::Cliperator clipper(*state.fClip, mask.fBounds); | 1466 SkRegion::Cliperator clipper(*state.fClip, mask.fBounds); |
| 1535 | 1467 |
| 1536 if (!clipper.done()) { | 1468 if (!clipper.done()) { |
| 1537 const SkIRect& cr = clipper.rect(); | 1469 const SkIRect& cr = clipper.rect(); |
| 1538 const uint8_t* aa = (const uint8_t*)glyph.fImage; | 1470 const uint8_t* aa = (const uint8_t*)glyph.fImage; |
| 1539 if (NULL == aa) { | 1471 if (NULL == aa) { |
| 1540 aa = (uint8_t*)state.fCache->findImage(glyph); | 1472 aa = (uint8_t*)state.fCache->findImage(glyph); |
| 1541 if (NULL == aa) { | 1473 if (NULL == aa) { |
| 1542 return; | 1474 return; |
| 1543 } | 1475 } |
| 1544 } | 1476 } |
| 1545 | 1477 |
| 1546 mask.fRowBytes = glyph.rowBytes(); | 1478 mask.fRowBytes = glyph.rowBytes(); |
| 1547 mask.fFormat = static_cast<SkMask::Format>(glyph.fMaskFormat); | 1479 mask.fFormat = static_cast<SkMask::Format>(glyph.fMaskFormat); |
| 1548 mask.fImage = (uint8_t*)aa; | 1480 mask.fImage = (uint8_t*)aa; |
| 1549 do { | 1481 do { |
| 1550 state.blitMask(mask, cr); | 1482 state.blitMask(mask, cr); |
| 1551 clipper.next(); | 1483 clipper.next(); |
| 1552 } while (!clipper.done()); | 1484 } while (!clipper.done()); |
| 1553 } | 1485 } |
| 1554 } | 1486 } |
| 1555 | 1487 |
| 1556 static void D1G_Bounder(const SkDraw1Glyph& state, | |
| 1557 SkFixed fx, SkFixed fy, | |
| 1558 const SkGlyph& glyph) { | |
| 1559 int left = SkFixedFloorToInt(fx); | |
| 1560 int top = SkFixedFloorToInt(fy); | |
| 1561 SkASSERT(glyph.fWidth > 0 && glyph.fHeight > 0); | |
| 1562 | |
| 1563 SkMask mask; | |
| 1564 | |
| 1565 left += glyph.fLeft; | |
| 1566 top += glyph.fTop; | |
| 1567 | |
| 1568 mask.fBounds.set(left, top, left + glyph.fWidth, top + glyph.fHeight); | |
| 1569 SkRegion::Cliperator clipper(*state.fClip, mask.fBounds); | |
| 1570 | |
| 1571 if (!clipper.done()) { | |
| 1572 const SkIRect& cr = clipper.rect(); | |
| 1573 const uint8_t* aa = (const uint8_t*)glyph.fImage; | |
| 1574 if (NULL == aa) { | |
| 1575 aa = (uint8_t*)state.fCache->findImage(glyph); | |
| 1576 if (NULL == aa) { | |
| 1577 return; | |
| 1578 } | |
| 1579 } | |
| 1580 | |
| 1581 // we need to pass the origin, which we approximate with our | |
| 1582 // (unadjusted) left,top coordinates (the caller called fixedfloor) | |
| 1583 if (state.fBounder->doIRectGlyph(cr, | |
| 1584 left - glyph.fLeft, | |
| 1585 top - glyph.fTop, glyph)) { | |
| 1586 mask.fRowBytes = glyph.rowBytes(); | |
| 1587 mask.fFormat = static_cast<SkMask::Format>(glyph.fMaskFormat); | |
| 1588 mask.fImage = (uint8_t*)aa; | |
| 1589 do { | |
| 1590 state.blitMask(mask, cr); | |
| 1591 clipper.next(); | |
| 1592 } while (!clipper.done()); | |
| 1593 } | |
| 1594 } | |
| 1595 } | |
| 1596 | |
| 1597 static void D1G_Bounder_AAClip(const SkDraw1Glyph& state, | |
| 1598 SkFixed fx, SkFixed fy, | |
| 1599 const SkGlyph& glyph) { | |
| 1600 int left = SkFixedFloorToInt(fx); | |
| 1601 int top = SkFixedFloorToInt(fy); | |
| 1602 SkIRect bounds; | |
| 1603 bounds.set(left, top, left + glyph.fWidth, top + glyph.fHeight); | |
| 1604 | |
| 1605 if (state.fBounder->doIRectGlyph(bounds, left, top, glyph)) { | |
| 1606 D1G_NoBounder_RectClip(state, fx, fy, glyph); | |
| 1607 } | |
| 1608 } | |
| 1609 | |
| 1610 static bool hasCustomD1GProc(const SkDraw& draw) { | 1488 static bool hasCustomD1GProc(const SkDraw& draw) { |
| 1611 return draw.fProcs && draw.fProcs->fD1GProc; | 1489 return draw.fProcs && draw.fProcs->fD1GProc; |
| 1612 } | 1490 } |
| 1613 | 1491 |
| 1614 static bool needsRasterTextBlit(const SkDraw& draw) { | 1492 static bool needsRasterTextBlit(const SkDraw& draw) { |
| 1615 return !hasCustomD1GProc(draw); | 1493 return !hasCustomD1GProc(draw); |
| 1616 } | 1494 } |
| 1617 | 1495 |
| 1618 SkDraw1Glyph::Proc SkDraw1Glyph::init(const SkDraw* draw, SkBlitter* blitter, | 1496 SkDraw1Glyph::Proc SkDraw1Glyph::init(const SkDraw* draw, SkBlitter* blitter, Sk
GlyphCache* cache, |
| 1619 SkGlyphCache* cache, const SkPaint& pnt) { | 1497 const SkPaint& pnt) { |
| 1620 fDraw = draw; | 1498 fDraw = draw; |
| 1621 fBounder = draw->fBounder; | |
| 1622 fBlitter = blitter; | 1499 fBlitter = blitter; |
| 1623 fCache = cache; | 1500 fCache = cache; |
| 1624 fPaint = &pnt; | 1501 fPaint = &pnt; |
| 1625 | 1502 |
| 1626 if (cache->isSubpixel()) { | 1503 if (cache->isSubpixel()) { |
| 1627 fHalfSampleX = fHalfSampleY = (SK_FixedHalf >> SkGlyph::kSubBits); | 1504 fHalfSampleX = fHalfSampleY = (SK_FixedHalf >> SkGlyph::kSubBits); |
| 1628 } else { | 1505 } else { |
| 1629 fHalfSampleX = fHalfSampleY = SK_FixedHalf; | 1506 fHalfSampleX = fHalfSampleY = SK_FixedHalf; |
| 1630 } | 1507 } |
| 1631 | 1508 |
| 1632 if (hasCustomD1GProc(*draw)) { | 1509 if (hasCustomD1GProc(*draw)) { |
| 1633 // todo: fix this assumption about clips w/ custom | 1510 // todo: fix this assumption about clips w/ custom |
| 1634 fClip = draw->fClip; | 1511 fClip = draw->fClip; |
| 1635 fClipBounds = fClip->getBounds(); | 1512 fClipBounds = fClip->getBounds(); |
| 1636 return draw->fProcs->fD1GProc; | 1513 return draw->fProcs->fD1GProc; |
| 1637 } | 1514 } |
| 1638 | 1515 |
| 1639 if (draw->fRC->isBW()) { | 1516 if (draw->fRC->isBW()) { |
| 1640 fAAClip = NULL; | 1517 fAAClip = NULL; |
| 1641 fClip = &draw->fRC->bwRgn(); | 1518 fClip = &draw->fRC->bwRgn(); |
| 1642 fClipBounds = fClip->getBounds(); | 1519 fClipBounds = fClip->getBounds(); |
| 1643 if (NULL == fBounder) { | 1520 if (fClip->isRect()) { |
| 1644 if (fClip->isRect()) { | 1521 return D1G_RectClip; |
| 1645 return D1G_NoBounder_RectClip; | |
| 1646 } else { | |
| 1647 return D1G_NoBounder_RgnClip; | |
| 1648 } | |
| 1649 } else { | 1522 } else { |
| 1650 return D1G_Bounder; | 1523 return D1G_RgnClip; |
| 1651 } | 1524 } |
| 1652 } else { // aaclip | 1525 } else { // aaclip |
| 1653 fAAClip = &draw->fRC->aaRgn(); | 1526 fAAClip = &draw->fRC->aaRgn(); |
| 1654 fClip = NULL; | 1527 fClip = NULL; |
| 1655 fClipBounds = fAAClip->getBounds(); | 1528 fClipBounds = fAAClip->getBounds(); |
| 1656 if (NULL == fBounder) { | 1529 return D1G_RectClip; |
| 1657 return D1G_NoBounder_RectClip; | |
| 1658 } else { | |
| 1659 return D1G_Bounder_AAClip; | |
| 1660 } | |
| 1661 } | 1530 } |
| 1662 } | 1531 } |
| 1663 | 1532 |
| 1664 void SkDraw1Glyph::blitMaskAsSprite(const SkMask& mask) const { | 1533 void SkDraw1Glyph::blitMaskAsSprite(const SkMask& mask) const { |
| 1665 SkASSERT(SkMask::kARGB32_Format == mask.fFormat); | 1534 SkASSERT(SkMask::kARGB32_Format == mask.fFormat); |
| 1666 | 1535 |
| 1667 SkBitmap bm; | 1536 SkBitmap bm; |
| 1668 bm.installPixels(SkImageInfo::MakeN32Premul(mask.fBounds.width(), mask.fBoun
ds.height()), | 1537 bm.installPixels(SkImageInfo::MakeN32Premul(mask.fBounds.width(), mask.fBoun
ds.height()), |
| 1669 (SkPMColor*)mask.fImage, mask.fRowBytes); | 1538 (SkPMColor*)mask.fImage, mask.fRowBytes); |
| 1670 | 1539 |
| (...skipping 699 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2370 // abort early if there is nothing to draw | 2239 // abort early if there is nothing to draw |
| 2371 if (count < 3 || (indices && indexCount < 3) || fRC->isEmpty()) { | 2240 if (count < 3 || (indices && indexCount < 3) || fRC->isEmpty()) { |
| 2372 return; | 2241 return; |
| 2373 } | 2242 } |
| 2374 | 2243 |
| 2375 // transform out vertices into device coordinates | 2244 // transform out vertices into device coordinates |
| 2376 SkAutoSTMalloc<16, SkPoint> storage(count); | 2245 SkAutoSTMalloc<16, SkPoint> storage(count); |
| 2377 SkPoint* devVerts = storage.get(); | 2246 SkPoint* devVerts = storage.get(); |
| 2378 fMatrix->mapPoints(devVerts, vertices, count); | 2247 fMatrix->mapPoints(devVerts, vertices, count); |
| 2379 | 2248 |
| 2380 if (fBounder) { | |
| 2381 SkRect bounds; | |
| 2382 bounds.set(devVerts, count); | |
| 2383 if (!fBounder->doRect(bounds, paint)) { | |
| 2384 return; | |
| 2385 } | |
| 2386 } | |
| 2387 | |
| 2388 /* | 2249 /* |
| 2389 We can draw the vertices in 1 of 4 ways: | 2250 We can draw the vertices in 1 of 4 ways: |
| 2390 | 2251 |
| 2391 - solid color (no shader/texture[], no colors[]) | 2252 - solid color (no shader/texture[], no colors[]) |
| 2392 - just colors (no shader/texture[], has colors[]) | 2253 - just colors (no shader/texture[], has colors[]) |
| 2393 - just texture (has shader/texture[], no colors[]) | 2254 - just texture (has shader/texture[], no colors[]) |
| 2394 - colors * texture (has shader/texture[], has colors[]) | 2255 - colors * texture (has shader/texture[], has colors[]) |
| 2395 | 2256 |
| 2396 Thus for texture drawing, we need both texture[] and a shader. | 2257 Thus for texture drawing, we need both texture[] and a shader. |
| 2397 */ | 2258 */ |
| (...skipping 111 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2509 | 2370 |
| 2510 const SkIRect& cr = fRC->getBounds(); | 2371 const SkIRect& cr = fRC->getBounds(); |
| 2511 SkIRect br; | 2372 SkIRect br; |
| 2512 | 2373 |
| 2513 br.set(0, 0, fBitmap->width(), fBitmap->height()); | 2374 br.set(0, 0, fBitmap->width(), fBitmap->height()); |
| 2514 SkASSERT(cr.isEmpty() || br.contains(cr)); | 2375 SkASSERT(cr.isEmpty() || br.contains(cr)); |
| 2515 } | 2376 } |
| 2516 | 2377 |
| 2517 #endif | 2378 #endif |
| 2518 | 2379 |
| 2519 /////////////////////////////////////////////////////////////////////////////// | |
| 2520 | |
| 2521 SkBounder::SkBounder() { | |
| 2522 // initialize up front. This gets reset by SkCanvas before each draw call. | |
| 2523 fClip = &SkRegion::GetEmptyRegion(); | |
| 2524 } | |
| 2525 | |
| 2526 bool SkBounder::doIRect(const SkIRect& r) { | |
| 2527 SkIRect rr; | |
| 2528 return rr.intersect(fClip->getBounds(), r) && this->onIRect(rr); | |
| 2529 } | |
| 2530 | |
| 2531 // TODO: change the prototype to take fixed, and update the callers | |
| 2532 bool SkBounder::doIRectGlyph(const SkIRect& r, int x, int y, | |
| 2533 const SkGlyph& glyph) { | |
| 2534 SkIRect rr; | |
| 2535 if (!rr.intersect(fClip->getBounds(), r)) { | |
| 2536 return false; | |
| 2537 } | |
| 2538 GlyphRec rec; | |
| 2539 rec.fLSB.set(SkIntToFixed(x), SkIntToFixed(y)); | |
| 2540 rec.fRSB.set(rec.fLSB.fX + glyph.fAdvanceX, | |
| 2541 rec.fLSB.fY + glyph.fAdvanceY); | |
| 2542 rec.fGlyphID = glyph.getGlyphID(); | |
| 2543 rec.fFlags = 0; | |
| 2544 return this->onIRectGlyph(rr, rec); | |
| 2545 } | |
| 2546 | |
| 2547 bool SkBounder::doHairline(const SkPoint& pt0, const SkPoint& pt1, | |
| 2548 const SkPaint& paint) { | |
| 2549 SkIRect r; | |
| 2550 SkScalar v0, v1; | |
| 2551 | |
| 2552 v0 = pt0.fX; | |
| 2553 v1 = pt1.fX; | |
| 2554 if (v0 > v1) { | |
| 2555 SkTSwap<SkScalar>(v0, v1); | |
| 2556 } | |
| 2557 r.fLeft = SkScalarFloorToInt(v0); | |
| 2558 r.fRight = SkScalarCeilToInt(v1); | |
| 2559 | |
| 2560 v0 = pt0.fY; | |
| 2561 v1 = pt1.fY; | |
| 2562 if (v0 > v1) { | |
| 2563 SkTSwap<SkScalar>(v0, v1); | |
| 2564 } | |
| 2565 r.fTop = SkScalarFloorToInt(v0); | |
| 2566 r.fBottom = SkScalarCeilToInt(v1); | |
| 2567 | |
| 2568 if (paint.isAntiAlias()) { | |
| 2569 r.inset(-1, -1); | |
| 2570 } | |
| 2571 return this->doIRect(r); | |
| 2572 } | |
| 2573 | |
| 2574 bool SkBounder::doRect(const SkRect& rect, const SkPaint& paint) { | |
| 2575 SkIRect r; | |
| 2576 | |
| 2577 if (paint.getStyle() == SkPaint::kFill_Style) { | |
| 2578 rect.round(&r); | |
| 2579 } else { | |
| 2580 int rad = -1; | |
| 2581 rect.roundOut(&r); | |
| 2582 if (paint.isAntiAlias()) { | |
| 2583 rad = -2; | |
| 2584 } | |
| 2585 r.inset(rad, rad); | |
| 2586 } | |
| 2587 return this->doIRect(r); | |
| 2588 } | |
| 2589 | |
| 2590 bool SkBounder::doPath(const SkPath& path, const SkPaint& paint, bool doFill) { | |
| 2591 SkIRect r; | |
| 2592 const SkRect& bounds = path.getBounds(); | |
| 2593 | |
| 2594 if (doFill) { | |
| 2595 bounds.round(&r); | |
| 2596 } else { // hairline | |
| 2597 bounds.roundOut(&r); | |
| 2598 } | |
| 2599 | |
| 2600 if (paint.isAntiAlias()) { | |
| 2601 r.inset(-1, -1); | |
| 2602 } | |
| 2603 return this->doIRect(r); | |
| 2604 } | |
| 2605 | |
| 2606 void SkBounder::commit() { | |
| 2607 // override in subclass | |
| 2608 } | |
| 2609 | |
| 2610 ////////////////////////////////////////////////////////////////////////////////
//////////////// | 2380 ////////////////////////////////////////////////////////////////////////////////
//////////////// |
| 2611 | 2381 |
| 2612 #include "SkPath.h" | 2382 #include "SkPath.h" |
| 2613 #include "SkDraw.h" | 2383 #include "SkDraw.h" |
| 2614 #include "SkRegion.h" | 2384 #include "SkRegion.h" |
| 2615 #include "SkBlitter.h" | 2385 #include "SkBlitter.h" |
| 2616 | 2386 |
| 2617 static bool compute_bounds(const SkPath& devPath, const SkIRect* clipBounds, | 2387 static bool compute_bounds(const SkPath& devPath, const SkIRect* clipBounds, |
| 2618 const SkMaskFilter* filter, const SkMatrix* filterMatrix, | 2388 const SkMaskFilter* filter, const SkMatrix* filterMatrix, |
| 2619 SkIRect* bounds) { | 2389 SkIRect* bounds) { |
| (...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2675 mask.fImage, mask.fRowBytes); | 2445 mask.fImage, mask.fRowBytes); |
| 2676 | 2446 |
| 2677 clip.setRect(SkIRect::MakeWH(mask.fBounds.width(), mask.fBounds.height())); | 2447 clip.setRect(SkIRect::MakeWH(mask.fBounds.width(), mask.fBounds.height())); |
| 2678 matrix.setTranslate(-SkIntToScalar(mask.fBounds.fLeft), | 2448 matrix.setTranslate(-SkIntToScalar(mask.fBounds.fLeft), |
| 2679 -SkIntToScalar(mask.fBounds.fTop)); | 2449 -SkIntToScalar(mask.fBounds.fTop)); |
| 2680 | 2450 |
| 2681 draw.fBitmap = &bm; | 2451 draw.fBitmap = &bm; |
| 2682 draw.fRC = &clip; | 2452 draw.fRC = &clip; |
| 2683 draw.fClip = &clip.bwRgn(); | 2453 draw.fClip = &clip.bwRgn(); |
| 2684 draw.fMatrix = &matrix; | 2454 draw.fMatrix = &matrix; |
| 2685 draw.fBounder = NULL; | |
| 2686 paint.setAntiAlias(true); | 2455 paint.setAntiAlias(true); |
| 2687 paint.setStyle(style); | 2456 paint.setStyle(style); |
| 2688 draw.drawPath(devPath, paint); | 2457 draw.drawPath(devPath, paint); |
| 2689 } | 2458 } |
| 2690 | 2459 |
| 2691 bool SkDraw::DrawToMask(const SkPath& devPath, const SkIRect* clipBounds, | 2460 bool SkDraw::DrawToMask(const SkPath& devPath, const SkIRect* clipBounds, |
| 2692 const SkMaskFilter* filter, const SkMatrix* filterMatrix
, | 2461 const SkMaskFilter* filter, const SkMatrix* filterMatrix
, |
| 2693 SkMask* mask, SkMask::CreateMode mode, | 2462 SkMask* mask, SkMask::CreateMode mode, |
| 2694 SkPaint::Style style) { | 2463 SkPaint::Style style) { |
| 2695 if (SkMask::kJustRenderImage_CreateMode != mode) { | 2464 if (SkMask::kJustRenderImage_CreateMode != mode) { |
| (...skipping 12 matching lines...) Expand all Loading... |
| 2708 mask->fImage = SkMask::AllocImage(size); | 2477 mask->fImage = SkMask::AllocImage(size); |
| 2709 memset(mask->fImage, 0, mask->computeImageSize()); | 2478 memset(mask->fImage, 0, mask->computeImageSize()); |
| 2710 } | 2479 } |
| 2711 | 2480 |
| 2712 if (SkMask::kJustComputeBounds_CreateMode != mode) { | 2481 if (SkMask::kJustComputeBounds_CreateMode != mode) { |
| 2713 draw_into_mask(*mask, devPath, style); | 2482 draw_into_mask(*mask, devPath, style); |
| 2714 } | 2483 } |
| 2715 | 2484 |
| 2716 return true; | 2485 return true; |
| 2717 } | 2486 } |
| OLD | NEW |