OLD | NEW |
1 /* | 1 /* |
2 * Copyright 2008 The Android Open Source Project | 2 * Copyright 2008 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 | 8 |
9 #include "SkCanvas.h" | 9 #include "SkCanvas.h" |
10 #include "SkCanvasPriv.h" | 10 #include "SkCanvasPriv.h" |
(...skipping 65 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
76 */ | 76 */ |
77 struct DeviceCM { | 77 struct DeviceCM { |
78 DeviceCM* fNext; | 78 DeviceCM* fNext; |
79 SkBaseDevice* fDevice; | 79 SkBaseDevice* fDevice; |
80 SkRasterClip fClip; | 80 SkRasterClip fClip; |
81 const SkMatrix* fMatrix; | 81 const SkMatrix* fMatrix; |
82 SkPaint* fPaint; // may be null (in the future) | 82 SkPaint* fPaint; // may be null (in the future) |
83 | 83 |
84 DeviceCM(SkBaseDevice* device, int x, int y, const SkPaint* paint, SkCanvas*
canvas) | 84 DeviceCM(SkBaseDevice* device, int x, int y, const SkPaint* paint, SkCanvas*
canvas) |
85 : fNext(NULL) { | 85 : fNext(NULL) { |
86 if (NULL != device) { | 86 if (device) { |
87 device->ref(); | 87 device->ref(); |
88 device->onAttachToCanvas(canvas); | 88 device->onAttachToCanvas(canvas); |
89 } | 89 } |
90 fDevice = device; | 90 fDevice = device; |
91 fPaint = paint ? SkNEW_ARGS(SkPaint, (*paint)) : NULL; | 91 fPaint = paint ? SkNEW_ARGS(SkPaint, (*paint)) : NULL; |
92 } | 92 } |
93 | 93 |
94 ~DeviceCM() { | 94 ~DeviceCM() { |
95 if (NULL != fDevice) { | 95 if (fDevice) { |
96 fDevice->onDetachFromCanvas(); | 96 fDevice->onDetachFromCanvas(); |
97 fDevice->unref(); | 97 fDevice->unref(); |
98 } | 98 } |
99 SkDELETE(fPaint); | 99 SkDELETE(fPaint); |
100 } | 100 } |
101 | 101 |
102 void updateMC(const SkMatrix& totalMatrix, const SkRasterClip& totalClip, | 102 void updateMC(const SkMatrix& totalMatrix, const SkRasterClip& totalClip, |
103 const SkClipStack& clipStack, SkRasterClip* updateClip) { | 103 const SkClipStack& clipStack, SkRasterClip* updateClip) { |
104 int x = fDevice->getOrigin().x(); | 104 int x = fDevice->getOrigin().x(); |
105 int y = fDevice->getOrigin().y(); | 105 int y = fDevice->getOrigin().y(); |
(...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
158 DeviceCM* fLayer; | 158 DeviceCM* fLayer; |
159 /* If there are any layers in the stack, this points to the top-most | 159 /* If there are any layers in the stack, this points to the top-most |
160 one that is at or below this level in the stack (so we know what | 160 one that is at or below this level in the stack (so we know what |
161 bitmap/device to draw into from this level. This value is NOT | 161 bitmap/device to draw into from this level. This value is NOT |
162 reference counted, since the real owner is either our fLayer field, | 162 reference counted, since the real owner is either our fLayer field, |
163 or a previous one in a lower level.) | 163 or a previous one in a lower level.) |
164 */ | 164 */ |
165 DeviceCM* fTopLayer; | 165 DeviceCM* fTopLayer; |
166 | 166 |
167 MCRec(const MCRec* prev) { | 167 MCRec(const MCRec* prev) { |
168 if (NULL != prev) { | 168 if (prev) { |
169 fMatrix = prev->fMatrix; | 169 fMatrix = prev->fMatrix; |
170 fRasterClip = prev->fRasterClip; | 170 fRasterClip = prev->fRasterClip; |
171 | 171 |
172 fFilter = prev->fFilter; | 172 fFilter = prev->fFilter; |
173 SkSafeRef(fFilter); | 173 SkSafeRef(fFilter); |
174 | 174 |
175 fTopLayer = prev->fTopLayer; | 175 fTopLayer = prev->fTopLayer; |
176 } else { // no prev | 176 } else { // no prev |
177 fMatrix.reset(); | 177 fMatrix.reset(); |
178 fFilter = NULL; | 178 fFilter = NULL; |
(...skipping 583 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
762 if (!this->getClipDeviceBounds(&clipBounds)) { | 762 if (!this->getClipDeviceBounds(&clipBounds)) { |
763 return false; | 763 return false; |
764 } | 764 } |
765 | 765 |
766 if (imageFilter) { | 766 if (imageFilter) { |
767 imageFilter->filterBounds(clipBounds, fMCRec->fMatrix, &clipBounds); | 767 imageFilter->filterBounds(clipBounds, fMCRec->fMatrix, &clipBounds); |
768 // Filters may grow the bounds beyond the device bounds. | 768 // Filters may grow the bounds beyond the device bounds. |
769 op = SkRegion::kReplace_Op; | 769 op = SkRegion::kReplace_Op; |
770 } | 770 } |
771 SkIRect ir; | 771 SkIRect ir; |
772 if (NULL != bounds) { | 772 if (bounds) { |
773 SkRect r; | 773 SkRect r; |
774 | 774 |
775 this->getTotalMatrix().mapRect(&r, *bounds); | 775 this->getTotalMatrix().mapRect(&r, *bounds); |
776 r.roundOut(&ir); | 776 r.roundOut(&ir); |
777 // early exit if the layer's bounds are clipped out | 777 // early exit if the layer's bounds are clipped out |
778 if (!ir.intersect(clipBounds)) { | 778 if (!ir.intersect(clipBounds)) { |
779 if (bounds_affects_clip(flags)) { | 779 if (bounds_affects_clip(flags)) { |
780 fMCRec->fRasterClip.setEmpty(); | 780 fMCRec->fRasterClip.setEmpty(); |
781 } | 781 } |
782 return false; | 782 return false; |
(...skipping 133 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
916 | 916 |
917 // now do the normal restore() | 917 // now do the normal restore() |
918 fMCRec->~MCRec(); // balanced in save() | 918 fMCRec->~MCRec(); // balanced in save() |
919 fMCStack.pop_back(); | 919 fMCStack.pop_back(); |
920 fMCRec = (MCRec*)fMCStack.back(); | 920 fMCRec = (MCRec*)fMCStack.back(); |
921 | 921 |
922 /* Time to draw the layer's offscreen. We can't call the public drawSprite, | 922 /* Time to draw the layer's offscreen. We can't call the public drawSprite, |
923 since if we're being recorded, we don't want to record this (the | 923 since if we're being recorded, we don't want to record this (the |
924 recorder will have already recorded the restore). | 924 recorder will have already recorded the restore). |
925 */ | 925 */ |
926 if (NULL != layer) { | 926 if (layer) { |
927 if (layer->fNext) { | 927 if (layer->fNext) { |
928 const SkIPoint& origin = layer->fDevice->getOrigin(); | 928 const SkIPoint& origin = layer->fDevice->getOrigin(); |
929 this->internalDrawDevice(layer->fDevice, origin.x(), origin.y(), | 929 this->internalDrawDevice(layer->fDevice, origin.x(), origin.y(), |
930 layer->fPaint); | 930 layer->fPaint); |
931 // reset this, since internalDrawDevice will have set it to true | 931 // reset this, since internalDrawDevice will have set it to true |
932 fDeviceCMDirty = true; | 932 fDeviceCMDirty = true; |
933 | 933 |
934 SkASSERT(fSaveLayerCount > 0); | 934 SkASSERT(fSaveLayerCount > 0); |
935 fSaveLayerCount -= 1; | 935 fSaveLayerCount -= 1; |
936 } | 936 } |
(...skipping 703 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1640 | 1640 |
1641 SkMatrix inverse; | 1641 SkMatrix inverse; |
1642 // if we can't invert the CTM, we can't return local clip bounds | 1642 // if we can't invert the CTM, we can't return local clip bounds |
1643 if (!fMCRec->fMatrix.invert(&inverse)) { | 1643 if (!fMCRec->fMatrix.invert(&inverse)) { |
1644 if (bounds) { | 1644 if (bounds) { |
1645 bounds->setEmpty(); | 1645 bounds->setEmpty(); |
1646 } | 1646 } |
1647 return false; | 1647 return false; |
1648 } | 1648 } |
1649 | 1649 |
1650 if (NULL != bounds) { | 1650 if (bounds) { |
1651 SkRect r; | 1651 SkRect r; |
1652 // adjust it outwards in case we are antialiasing | 1652 // adjust it outwards in case we are antialiasing |
1653 const int inset = 1; | 1653 const int inset = 1; |
1654 | 1654 |
1655 r.iset(ibounds.fLeft - inset, ibounds.fTop - inset, | 1655 r.iset(ibounds.fLeft - inset, ibounds.fTop - inset, |
1656 ibounds.fRight + inset, ibounds.fBottom + inset); | 1656 ibounds.fRight + inset, ibounds.fBottom + inset); |
1657 inverse.mapRect(bounds, r); | 1657 inverse.mapRect(bounds, r); |
1658 } | 1658 } |
1659 return true; | 1659 return true; |
1660 } | 1660 } |
1661 | 1661 |
1662 bool SkCanvas::getClipDeviceBounds(SkIRect* bounds) const { | 1662 bool SkCanvas::getClipDeviceBounds(SkIRect* bounds) const { |
1663 const SkRasterClip& clip = fMCRec->fRasterClip; | 1663 const SkRasterClip& clip = fMCRec->fRasterClip; |
1664 if (clip.isEmpty()) { | 1664 if (clip.isEmpty()) { |
1665 if (bounds) { | 1665 if (bounds) { |
1666 bounds->setEmpty(); | 1666 bounds->setEmpty(); |
1667 } | 1667 } |
1668 return false; | 1668 return false; |
1669 } | 1669 } |
1670 | 1670 |
1671 if (NULL != bounds) { | 1671 if (bounds) { |
1672 *bounds = clip.getBounds(); | 1672 *bounds = clip.getBounds(); |
1673 } | 1673 } |
1674 return true; | 1674 return true; |
1675 } | 1675 } |
1676 | 1676 |
1677 const SkMatrix& SkCanvas::getTotalMatrix() const { | 1677 const SkMatrix& SkCanvas::getTotalMatrix() const { |
1678 return fMCRec->fMatrix; | 1678 return fMCRec->fMatrix; |
1679 } | 1679 } |
1680 | 1680 |
1681 const SkRegion& SkCanvas::internal_private_getTotalClip() const { | 1681 const SkRegion& SkCanvas::internal_private_getTotalClip() const { |
1682 return fMCRec->fRasterClip.forceGetBW(); | 1682 return fMCRec->fRasterClip.forceGetBW(); |
1683 } | 1683 } |
1684 | 1684 |
1685 GrRenderTarget* SkCanvas::internal_private_accessTopLayerRenderTarget() { | 1685 GrRenderTarget* SkCanvas::internal_private_accessTopLayerRenderTarget() { |
1686 SkBaseDevice* dev = this->getTopDevice(); | 1686 SkBaseDevice* dev = this->getTopDevice(); |
1687 return dev ? dev->accessRenderTarget() : NULL; | 1687 return dev ? dev->accessRenderTarget() : NULL; |
1688 } | 1688 } |
1689 | 1689 |
1690 SkBaseDevice* SkCanvas::createLayerDevice(const SkImageInfo& info) { | 1690 SkBaseDevice* SkCanvas::createLayerDevice(const SkImageInfo& info) { |
1691 SkBaseDevice* device = this->getTopDevice(); | 1691 SkBaseDevice* device = this->getTopDevice(); |
1692 return device ? device->createCompatibleDeviceForSaveLayer(info) : NULL; | 1692 return device ? device->createCompatibleDeviceForSaveLayer(info) : NULL; |
1693 } | 1693 } |
1694 | 1694 |
1695 GrContext* SkCanvas::getGrContext() { | 1695 GrContext* SkCanvas::getGrContext() { |
1696 #if SK_SUPPORT_GPU | 1696 #if SK_SUPPORT_GPU |
1697 SkBaseDevice* device = this->getTopDevice(); | 1697 SkBaseDevice* device = this->getTopDevice(); |
1698 if (NULL != device) { | 1698 if (device) { |
1699 GrRenderTarget* renderTarget = device->accessRenderTarget(); | 1699 GrRenderTarget* renderTarget = device->accessRenderTarget(); |
1700 if (NULL != renderTarget) { | 1700 if (renderTarget) { |
1701 return renderTarget->getContext(); | 1701 return renderTarget->getContext(); |
1702 } | 1702 } |
1703 } | 1703 } |
1704 #endif | 1704 #endif |
1705 | 1705 |
1706 return NULL; | 1706 return NULL; |
1707 | 1707 |
1708 } | 1708 } |
1709 | 1709 |
1710 void SkCanvas::drawDRRect(const SkRRect& outer, const SkRRect& inner, | 1710 void SkCanvas::drawDRRect(const SkRRect& outer, const SkRRect& inner, |
(...skipping 22 matching lines...) Expand all Loading... |
1733 | 1733 |
1734 void SkCanvas::clear(SkColor color) { | 1734 void SkCanvas::clear(SkColor color) { |
1735 SkDrawIter iter(this); | 1735 SkDrawIter iter(this); |
1736 this->predrawNotify(); | 1736 this->predrawNotify(); |
1737 while (iter.next()) { | 1737 while (iter.next()) { |
1738 iter.fDevice->clear(color); | 1738 iter.fDevice->clear(color); |
1739 } | 1739 } |
1740 } | 1740 } |
1741 | 1741 |
1742 void SkCanvas::onDiscard() { | 1742 void SkCanvas::onDiscard() { |
1743 if (NULL != fSurfaceBase) { | 1743 if (fSurfaceBase) { |
1744 fSurfaceBase->aboutToDraw(SkSurface::kDiscard_ContentChangeMode); | 1744 fSurfaceBase->aboutToDraw(SkSurface::kDiscard_ContentChangeMode); |
1745 } | 1745 } |
1746 } | 1746 } |
1747 | 1747 |
1748 void SkCanvas::drawPaint(const SkPaint& paint) { | 1748 void SkCanvas::drawPaint(const SkPaint& paint) { |
1749 this->internalDrawPaint(paint); | 1749 this->internalDrawPaint(paint); |
1750 } | 1750 } |
1751 | 1751 |
1752 void SkCanvas::internalDrawPaint(const SkPaint& paint) { | 1752 void SkCanvas::internalDrawPaint(const SkPaint& paint) { |
1753 LOOPER_BEGIN(paint, SkDrawFilter::kPaint_Type, NULL) | 1753 LOOPER_BEGIN(paint, SkDrawFilter::kPaint_Type, NULL) |
(...skipping 483 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2237 void SkCanvas::drawPosTextH(const void* text, size_t byteLength, const SkScalar
xpos[], | 2237 void SkCanvas::drawPosTextH(const void* text, size_t byteLength, const SkScalar
xpos[], |
2238 SkScalar constY, const SkPaint& paint) { | 2238 SkScalar constY, const SkPaint& paint) { |
2239 this->onDrawPosTextH(text, byteLength, xpos, constY, paint); | 2239 this->onDrawPosTextH(text, byteLength, xpos, constY, paint); |
2240 } | 2240 } |
2241 void SkCanvas::drawTextOnPath(const void* text, size_t byteLength, const SkPath&
path, | 2241 void SkCanvas::drawTextOnPath(const void* text, size_t byteLength, const SkPath&
path, |
2242 const SkMatrix* matrix, const SkPaint& paint) { | 2242 const SkMatrix* matrix, const SkPaint& paint) { |
2243 this->onDrawTextOnPath(text, byteLength, path, matrix, paint); | 2243 this->onDrawTextOnPath(text, byteLength, path, matrix, paint); |
2244 } | 2244 } |
2245 void SkCanvas::drawTextBlob(const SkTextBlob* blob, SkScalar x, SkScalar y, | 2245 void SkCanvas::drawTextBlob(const SkTextBlob* blob, SkScalar x, SkScalar y, |
2246 const SkPaint& paint) { | 2246 const SkPaint& paint) { |
2247 if (NULL != blob) { | 2247 if (blob) { |
2248 this->onDrawTextBlob(blob, x, y, paint); | 2248 this->onDrawTextBlob(blob, x, y, paint); |
2249 } | 2249 } |
2250 } | 2250 } |
2251 | 2251 |
2252 void SkCanvas::drawVertices(VertexMode vmode, int vertexCount, | 2252 void SkCanvas::drawVertices(VertexMode vmode, int vertexCount, |
2253 const SkPoint verts[], const SkPoint texs[], | 2253 const SkPoint verts[], const SkPoint texs[], |
2254 const SkColor colors[], SkXfermode* xmode, | 2254 const SkColor colors[], SkXfermode* xmode, |
2255 const uint16_t indices[], int indexCount, | 2255 const uint16_t indices[], int indexCount, |
2256 const SkPaint& paint) { | 2256 const SkPaint& paint) { |
2257 LOOPER_BEGIN(paint, SkDrawFilter::kPath_Type, NULL) | 2257 LOOPER_BEGIN(paint, SkDrawFilter::kPath_Type, NULL) |
(...skipping 147 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2405 SkScalar vOffset, const SkPaint& paint) { | 2405 SkScalar vOffset, const SkPaint& paint) { |
2406 SkMatrix matrix; | 2406 SkMatrix matrix; |
2407 | 2407 |
2408 matrix.setTranslate(hOffset, vOffset); | 2408 matrix.setTranslate(hOffset, vOffset); |
2409 this->drawTextOnPath(text, byteLength, path, &matrix, paint); | 2409 this->drawTextOnPath(text, byteLength, path, &matrix, paint); |
2410 } | 2410 } |
2411 | 2411 |
2412 /////////////////////////////////////////////////////////////////////////////// | 2412 /////////////////////////////////////////////////////////////////////////////// |
2413 void SkCanvas::EXPERIMENTAL_optimize(const SkPicture* picture) { | 2413 void SkCanvas::EXPERIMENTAL_optimize(const SkPicture* picture) { |
2414 SkBaseDevice* device = this->getDevice(); | 2414 SkBaseDevice* device = this->getDevice(); |
2415 if (NULL != device) { | 2415 if (device) { |
2416 device->EXPERIMENTAL_optimize(picture); | 2416 device->EXPERIMENTAL_optimize(picture); |
2417 } | 2417 } |
2418 } | 2418 } |
2419 | 2419 |
2420 void SkCanvas::drawPicture(const SkPicture* picture) { | 2420 void SkCanvas::drawPicture(const SkPicture* picture) { |
2421 if (NULL != picture) { | 2421 if (picture) { |
2422 this->onDrawPicture(picture, NULL, NULL); | 2422 this->onDrawPicture(picture, NULL, NULL); |
2423 } | 2423 } |
2424 } | 2424 } |
2425 | 2425 |
2426 void SkCanvas::drawPicture(const SkPicture* picture, const SkMatrix* matrix, con
st SkPaint* paint) { | 2426 void SkCanvas::drawPicture(const SkPicture* picture, const SkMatrix* matrix, con
st SkPaint* paint) { |
2427 if (NULL != picture) { | 2427 if (picture) { |
2428 if (matrix && matrix->isIdentity()) { | 2428 if (matrix && matrix->isIdentity()) { |
2429 matrix = NULL; | 2429 matrix = NULL; |
2430 } | 2430 } |
2431 this->onDrawPicture(picture, matrix, paint); | 2431 this->onDrawPicture(picture, matrix, paint); |
2432 } | 2432 } |
2433 } | 2433 } |
2434 | 2434 |
2435 void SkCanvas::onDrawPicture(const SkPicture* picture, const SkMatrix* matrix, | 2435 void SkCanvas::onDrawPicture(const SkPicture* picture, const SkMatrix* matrix, |
2436 const SkPaint* paint) { | 2436 const SkPaint* paint) { |
2437 SkBaseDevice* device = this->getTopDevice(); | 2437 SkBaseDevice* device = this->getTopDevice(); |
2438 if (NULL != device) { | 2438 if (device) { |
2439 // Canvas has to first give the device the opportunity to render | 2439 // Canvas has to first give the device the opportunity to render |
2440 // the picture itself. | 2440 // the picture itself. |
2441 if (device->EXPERIMENTAL_drawPicture(this, picture, matrix, paint)) { | 2441 if (device->EXPERIMENTAL_drawPicture(this, picture, matrix, paint)) { |
2442 return; // the device has rendered the entire picture | 2442 return; // the device has rendered the entire picture |
2443 } | 2443 } |
2444 } | 2444 } |
2445 | 2445 |
2446 SkAutoCanvasMatrixPaint acmp(this, matrix, paint, picture->cullRect()); | 2446 SkAutoCanvasMatrixPaint acmp(this, matrix, paint, picture->cullRect()); |
2447 | 2447 |
2448 picture->playback(this); | 2448 picture->playback(this); |
(...skipping 95 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2544 return SkNEW_ARGS(SkCanvas, (bitmap)); | 2544 return SkNEW_ARGS(SkCanvas, (bitmap)); |
2545 } | 2545 } |
2546 | 2546 |
2547 /////////////////////////////////////////////////////////////////////////////// | 2547 /////////////////////////////////////////////////////////////////////////////// |
2548 | 2548 |
2549 SkAutoCanvasMatrixPaint::SkAutoCanvasMatrixPaint(SkCanvas* canvas, const SkMatri
x* matrix, | 2549 SkAutoCanvasMatrixPaint::SkAutoCanvasMatrixPaint(SkCanvas* canvas, const SkMatri
x* matrix, |
2550 const SkPaint* paint, const SkR
ect& bounds) | 2550 const SkPaint* paint, const SkR
ect& bounds) |
2551 : fCanvas(canvas) | 2551 : fCanvas(canvas) |
2552 , fSaveCount(canvas->getSaveCount()) | 2552 , fSaveCount(canvas->getSaveCount()) |
2553 { | 2553 { |
2554 if (NULL != paint) { | 2554 if (paint) { |
2555 SkRect newBounds = bounds; | 2555 SkRect newBounds = bounds; |
2556 if (matrix) { | 2556 if (matrix) { |
2557 matrix->mapRect(&newBounds); | 2557 matrix->mapRect(&newBounds); |
2558 } | 2558 } |
2559 canvas->saveLayer(&newBounds, paint); | 2559 canvas->saveLayer(&newBounds, paint); |
2560 } else if (NULL != matrix) { | 2560 } else if (matrix) { |
2561 canvas->save(); | 2561 canvas->save(); |
2562 } | 2562 } |
2563 | 2563 |
2564 if (NULL != matrix) { | 2564 if (matrix) { |
2565 canvas->concat(*matrix); | 2565 canvas->concat(*matrix); |
2566 } | 2566 } |
2567 } | 2567 } |
2568 | 2568 |
2569 SkAutoCanvasMatrixPaint::~SkAutoCanvasMatrixPaint() { | 2569 SkAutoCanvasMatrixPaint::~SkAutoCanvasMatrixPaint() { |
2570 fCanvas->restoreToCount(fSaveCount); | 2570 fCanvas->restoreToCount(fSaveCount); |
2571 } | 2571 } |
OLD | NEW |