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 |