SkImage.cpp revision 70e359055240d0de93da4ba71bf5833164fb394c
1f6627b78f933b77b358ac0791c520f99b0e79fcareed@google.com#include "SkImage.h"
2889b09edfeb5f461ca283dfd08ee6b23560a7859reed@google.com#include "SkImagePriv.h"
3f6627b78f933b77b358ac0791c520f99b0e79fcareed@google.com#include "SkBitmap.h"
470e359055240d0de93da4ba71bf5833164fb394cmike@reedtribe.org#include "SkCanvas.h"
5f6627b78f933b77b358ac0791c520f99b0e79fcareed@google.com
6f6627b78f933b77b358ac0791c520f99b0e79fcareed@google.com///////////////////////////////////////////////////////////////////////////////
7f6627b78f933b77b358ac0791c520f99b0e79fcareed@google.com
8f6627b78f933b77b358ac0791c520f99b0e79fcareed@google.comclass SkImage_Base : public SkImage {
9f6627b78f933b77b358ac0791c520f99b0e79fcareed@google.compublic:
10f6627b78f933b77b358ac0791c520f99b0e79fcareed@google.com    SkImage_Base(int width, int height) : INHERITED(width, height) {}
11f6627b78f933b77b358ac0791c520f99b0e79fcareed@google.com
1270e359055240d0de93da4ba71bf5833164fb394cmike@reedtribe.org    virtual void onDraw(SkCanvas*, SkScalar, SkScalar, const SkPaint*) = 0;
13f6627b78f933b77b358ac0791c520f99b0e79fcareed@google.com
14f6627b78f933b77b358ac0791c520f99b0e79fcareed@google.comprivate:
15f6627b78f933b77b358ac0791c520f99b0e79fcareed@google.com    typedef SkImage INHERITED;
16f6627b78f933b77b358ac0791c520f99b0e79fcareed@google.com};
17f6627b78f933b77b358ac0791c520f99b0e79fcareed@google.com
18f6627b78f933b77b358ac0791c520f99b0e79fcareed@google.comstatic SkImage_Base* asIB(SkImage* image) {
19f6627b78f933b77b358ac0791c520f99b0e79fcareed@google.com    return static_cast<SkImage_Base*>(image);
20f6627b78f933b77b358ac0791c520f99b0e79fcareed@google.com}
21f6627b78f933b77b358ac0791c520f99b0e79fcareed@google.com
22f6627b78f933b77b358ac0791c520f99b0e79fcareed@google.com///////////////////////////////////////////////////////////////////////////////
23f6627b78f933b77b358ac0791c520f99b0e79fcareed@google.com
24f6627b78f933b77b358ac0791c520f99b0e79fcareed@google.com
25f6627b78f933b77b358ac0791c520f99b0e79fcareed@google.comclass SkImage_Raster : public SkImage_Base {
26f6627b78f933b77b358ac0791c520f99b0e79fcareed@google.compublic:
27f6627b78f933b77b358ac0791c520f99b0e79fcareed@google.com    static bool ValidArgs(const Info& info, SkColorSpace* cs, size_t rowBytes) {
28f6627b78f933b77b358ac0791c520f99b0e79fcareed@google.com        const int maxDimension = SK_MaxS32 >> 2;
29f6627b78f933b77b358ac0791c520f99b0e79fcareed@google.com        const size_t kMaxPixelByteSize = SK_MaxS32;
30f6627b78f933b77b358ac0791c520f99b0e79fcareed@google.com
31f6627b78f933b77b358ac0791c520f99b0e79fcareed@google.com        if (info.fWidth < 0 || info.fHeight < 0) {
32f6627b78f933b77b358ac0791c520f99b0e79fcareed@google.com            return false;
33f6627b78f933b77b358ac0791c520f99b0e79fcareed@google.com        }
34f6627b78f933b77b358ac0791c520f99b0e79fcareed@google.com        if (info.fWidth > maxDimension || info.fHeight > maxDimension) {
35f6627b78f933b77b358ac0791c520f99b0e79fcareed@google.com            return false;
36f6627b78f933b77b358ac0791c520f99b0e79fcareed@google.com        }
37f6627b78f933b77b358ac0791c520f99b0e79fcareed@google.com        if ((unsigned)info.fColorType > (unsigned)kLastEnum_ColorType) {
38f6627b78f933b77b358ac0791c520f99b0e79fcareed@google.com            return false;
39f6627b78f933b77b358ac0791c520f99b0e79fcareed@google.com        }
40f6627b78f933b77b358ac0791c520f99b0e79fcareed@google.com        if ((unsigned)info.fAlphaType > (unsigned)kLastEnum_AlphaType) {
41f6627b78f933b77b358ac0791c520f99b0e79fcareed@google.com            return false;
42f6627b78f933b77b358ac0791c520f99b0e79fcareed@google.com        }
43f6627b78f933b77b358ac0791c520f99b0e79fcareed@google.com
44f6627b78f933b77b358ac0791c520f99b0e79fcareed@google.com        bool isOpaque;
45889b09edfeb5f461ca283dfd08ee6b23560a7859reed@google.com        if (SkImageInfoToBitmapConfig(info, &isOpaque) == SkBitmap::kNo_Config) {
46f6627b78f933b77b358ac0791c520f99b0e79fcareed@google.com            return false;
47f6627b78f933b77b358ac0791c520f99b0e79fcareed@google.com        }
48f6627b78f933b77b358ac0791c520f99b0e79fcareed@google.com
49f6627b78f933b77b358ac0791c520f99b0e79fcareed@google.com        // TODO: check colorspace
50f6627b78f933b77b358ac0791c520f99b0e79fcareed@google.com
51889b09edfeb5f461ca283dfd08ee6b23560a7859reed@google.com        if (rowBytes < SkImageMinRowBytes(info)) {
52f6627b78f933b77b358ac0791c520f99b0e79fcareed@google.com            return false;
53f6627b78f933b77b358ac0791c520f99b0e79fcareed@google.com        }
54f6627b78f933b77b358ac0791c520f99b0e79fcareed@google.com
55f6627b78f933b77b358ac0791c520f99b0e79fcareed@google.com        int64_t size = (int64_t)info.fHeight * rowBytes;
56f6627b78f933b77b358ac0791c520f99b0e79fcareed@google.com        if (size > kMaxPixelByteSize) {
57f6627b78f933b77b358ac0791c520f99b0e79fcareed@google.com            return false;
58f6627b78f933b77b358ac0791c520f99b0e79fcareed@google.com        }
59f6627b78f933b77b358ac0791c520f99b0e79fcareed@google.com        return true;
60f6627b78f933b77b358ac0791c520f99b0e79fcareed@google.com    }
61f6627b78f933b77b358ac0791c520f99b0e79fcareed@google.com
62f6627b78f933b77b358ac0791c520f99b0e79fcareed@google.com    static SkImage* NewEmpty();
63f6627b78f933b77b358ac0791c520f99b0e79fcareed@google.com
64f6627b78f933b77b358ac0791c520f99b0e79fcareed@google.com    SkImage_Raster(const SkImage::Info&, SkColorSpace*, SkData*, size_t rb);
65f6627b78f933b77b358ac0791c520f99b0e79fcareed@google.com    virtual ~SkImage_Raster();
66f6627b78f933b77b358ac0791c520f99b0e79fcareed@google.com
6770e359055240d0de93da4ba71bf5833164fb394cmike@reedtribe.org    virtual void onDraw(SkCanvas*, SkScalar, SkScalar, const SkPaint*) SK_OVERRIDE;
68f6627b78f933b77b358ac0791c520f99b0e79fcareed@google.com
69889b09edfeb5f461ca283dfd08ee6b23560a7859reed@google.com    // exposed for SkSurface_Raster via SkNewImageFromPixelRef
70889b09edfeb5f461ca283dfd08ee6b23560a7859reed@google.com    SkImage_Raster(const SkImage::Info&, SkPixelRef*, size_t rowBytes);
71889b09edfeb5f461ca283dfd08ee6b23560a7859reed@google.com
72f6627b78f933b77b358ac0791c520f99b0e79fcareed@google.comprivate:
73f6627b78f933b77b358ac0791c520f99b0e79fcareed@google.com    SkImage_Raster() : INHERITED(0, 0) {}
74f6627b78f933b77b358ac0791c520f99b0e79fcareed@google.com
75f6627b78f933b77b358ac0791c520f99b0e79fcareed@google.com    SkBitmap    fBitmap;
76f6627b78f933b77b358ac0791c520f99b0e79fcareed@google.com
77f6627b78f933b77b358ac0791c520f99b0e79fcareed@google.com    typedef SkImage_Base INHERITED;
78f6627b78f933b77b358ac0791c520f99b0e79fcareed@google.com};
79f6627b78f933b77b358ac0791c520f99b0e79fcareed@google.com
80889b09edfeb5f461ca283dfd08ee6b23560a7859reed@google.comSkImage* SkNewImageFromPixelRef(const SkImage::Info& info, SkPixelRef* pr,
81889b09edfeb5f461ca283dfd08ee6b23560a7859reed@google.com                                size_t rowBytes) {
82889b09edfeb5f461ca283dfd08ee6b23560a7859reed@google.com    return SkNEW_ARGS(SkImage_Raster, (info, pr, rowBytes));
83889b09edfeb5f461ca283dfd08ee6b23560a7859reed@google.com}
84889b09edfeb5f461ca283dfd08ee6b23560a7859reed@google.com
85f6627b78f933b77b358ac0791c520f99b0e79fcareed@google.com///////////////////////////////////////////////////////////////////////////////
86f6627b78f933b77b358ac0791c520f99b0e79fcareed@google.com
87f6627b78f933b77b358ac0791c520f99b0e79fcareed@google.com#include "SkData.h"
88f6627b78f933b77b358ac0791c520f99b0e79fcareed@google.com#include "SkDataPixelRef.h"
89f6627b78f933b77b358ac0791c520f99b0e79fcareed@google.com
90f6627b78f933b77b358ac0791c520f99b0e79fcareed@google.comSkImage* SkImage_Raster::NewEmpty() {
91f6627b78f933b77b358ac0791c520f99b0e79fcareed@google.com    // Returns lazily created singleton
92f6627b78f933b77b358ac0791c520f99b0e79fcareed@google.com    static SkImage* gEmpty;
93f6627b78f933b77b358ac0791c520f99b0e79fcareed@google.com    if (NULL == gEmpty) {
94f6627b78f933b77b358ac0791c520f99b0e79fcareed@google.com        gEmpty = SkNEW(SkImage_Raster);
95f6627b78f933b77b358ac0791c520f99b0e79fcareed@google.com    }
96f6627b78f933b77b358ac0791c520f99b0e79fcareed@google.com    gEmpty->ref();
97f6627b78f933b77b358ac0791c520f99b0e79fcareed@google.com    return gEmpty;
98f6627b78f933b77b358ac0791c520f99b0e79fcareed@google.com}
99f6627b78f933b77b358ac0791c520f99b0e79fcareed@google.com
100f6627b78f933b77b358ac0791c520f99b0e79fcareed@google.comSkImage_Raster::SkImage_Raster(const Info& info, SkColorSpace* cs,
101f6627b78f933b77b358ac0791c520f99b0e79fcareed@google.com                               SkData* data, size_t rowBytes)
102889b09edfeb5f461ca283dfd08ee6b23560a7859reed@google.com: INHERITED(info.fWidth, info.fHeight) {
103889b09edfeb5f461ca283dfd08ee6b23560a7859reed@google.com    bool isOpaque;
104889b09edfeb5f461ca283dfd08ee6b23560a7859reed@google.com    SkBitmap::Config config = SkImageInfoToBitmapConfig(info, &isOpaque);
105889b09edfeb5f461ca283dfd08ee6b23560a7859reed@google.com
106889b09edfeb5f461ca283dfd08ee6b23560a7859reed@google.com    fBitmap.setConfig(config, info.fWidth, info.fHeight, rowBytes);
107889b09edfeb5f461ca283dfd08ee6b23560a7859reed@google.com    fBitmap.setPixelRef(SkNEW_ARGS(SkDataPixelRef, (data)))->unref();
108889b09edfeb5f461ca283dfd08ee6b23560a7859reed@google.com    fBitmap.setIsOpaque(isOpaque);
109889b09edfeb5f461ca283dfd08ee6b23560a7859reed@google.com    fBitmap.setImmutable();
110889b09edfeb5f461ca283dfd08ee6b23560a7859reed@google.com}
111889b09edfeb5f461ca283dfd08ee6b23560a7859reed@google.com
112889b09edfeb5f461ca283dfd08ee6b23560a7859reed@google.comSkImage_Raster::SkImage_Raster(const Info& info, SkPixelRef* pr, size_t rowBytes)
113f6627b78f933b77b358ac0791c520f99b0e79fcareed@google.com        : INHERITED(info.fWidth, info.fHeight) {
114889b09edfeb5f461ca283dfd08ee6b23560a7859reed@google.com    SkASSERT(pr->isImmutable());
115889b09edfeb5f461ca283dfd08ee6b23560a7859reed@google.com
116f6627b78f933b77b358ac0791c520f99b0e79fcareed@google.com    bool isOpaque;
117889b09edfeb5f461ca283dfd08ee6b23560a7859reed@google.com    SkBitmap::Config config = SkImageInfoToBitmapConfig(info, &isOpaque);
118f6627b78f933b77b358ac0791c520f99b0e79fcareed@google.com
119f6627b78f933b77b358ac0791c520f99b0e79fcareed@google.com    fBitmap.setConfig(config, info.fWidth, info.fHeight, rowBytes);
120889b09edfeb5f461ca283dfd08ee6b23560a7859reed@google.com    fBitmap.setPixelRef(pr);
121f6627b78f933b77b358ac0791c520f99b0e79fcareed@google.com    fBitmap.setIsOpaque(isOpaque);
122889b09edfeb5f461ca283dfd08ee6b23560a7859reed@google.com    fBitmap.setImmutable();
123f6627b78f933b77b358ac0791c520f99b0e79fcareed@google.com}
124f6627b78f933b77b358ac0791c520f99b0e79fcareed@google.com
125f6627b78f933b77b358ac0791c520f99b0e79fcareed@google.comSkImage_Raster::~SkImage_Raster() {}
126f6627b78f933b77b358ac0791c520f99b0e79fcareed@google.com
12770e359055240d0de93da4ba71bf5833164fb394cmike@reedtribe.orgvoid SkImage_Raster::onDraw(SkCanvas* canvas, SkScalar x, SkScalar y, const SkPaint* paint) {
12870e359055240d0de93da4ba71bf5833164fb394cmike@reedtribe.org    canvas->drawBitmap(fBitmap, x, y, paint);
12970e359055240d0de93da4ba71bf5833164fb394cmike@reedtribe.org}
13070e359055240d0de93da4ba71bf5833164fb394cmike@reedtribe.org
13170e359055240d0de93da4ba71bf5833164fb394cmike@reedtribe.org///////////////////////////////////////////////////////////////////////////////
13270e359055240d0de93da4ba71bf5833164fb394cmike@reedtribe.org
13370e359055240d0de93da4ba71bf5833164fb394cmike@reedtribe.org#include "SkPicture.h"
13470e359055240d0de93da4ba71bf5833164fb394cmike@reedtribe.org
13570e359055240d0de93da4ba71bf5833164fb394cmike@reedtribe.orgclass SkImage_Picture : public SkImage_Base {
13670e359055240d0de93da4ba71bf5833164fb394cmike@reedtribe.orgpublic:
13770e359055240d0de93da4ba71bf5833164fb394cmike@reedtribe.org    SkImage_Picture(SkPicture*);
13870e359055240d0de93da4ba71bf5833164fb394cmike@reedtribe.org    virtual ~SkImage_Picture();
13970e359055240d0de93da4ba71bf5833164fb394cmike@reedtribe.org
14070e359055240d0de93da4ba71bf5833164fb394cmike@reedtribe.org    virtual void onDraw(SkCanvas*, SkScalar, SkScalar, const SkPaint*) SK_OVERRIDE;
14170e359055240d0de93da4ba71bf5833164fb394cmike@reedtribe.org
14270e359055240d0de93da4ba71bf5833164fb394cmike@reedtribe.orgprivate:
14370e359055240d0de93da4ba71bf5833164fb394cmike@reedtribe.org    SkPicture*  fPicture;
14470e359055240d0de93da4ba71bf5833164fb394cmike@reedtribe.org
14570e359055240d0de93da4ba71bf5833164fb394cmike@reedtribe.org    typedef SkImage_Base INHERITED;
14670e359055240d0de93da4ba71bf5833164fb394cmike@reedtribe.org};
14770e359055240d0de93da4ba71bf5833164fb394cmike@reedtribe.org
14870e359055240d0de93da4ba71bf5833164fb394cmike@reedtribe.orgSkImage_Picture::SkImage_Picture(SkPicture* pict) : INHERITED(pict->width(), pict->height()) {
14970e359055240d0de93da4ba71bf5833164fb394cmike@reedtribe.org    pict->endRecording();
15070e359055240d0de93da4ba71bf5833164fb394cmike@reedtribe.org    pict->ref();
15170e359055240d0de93da4ba71bf5833164fb394cmike@reedtribe.org    fPicture = pict;
15270e359055240d0de93da4ba71bf5833164fb394cmike@reedtribe.org}
15370e359055240d0de93da4ba71bf5833164fb394cmike@reedtribe.org
15470e359055240d0de93da4ba71bf5833164fb394cmike@reedtribe.orgSkImage_Picture::~SkImage_Picture() {
15570e359055240d0de93da4ba71bf5833164fb394cmike@reedtribe.org    fPicture->unref();
15670e359055240d0de93da4ba71bf5833164fb394cmike@reedtribe.org}
15770e359055240d0de93da4ba71bf5833164fb394cmike@reedtribe.org
15870e359055240d0de93da4ba71bf5833164fb394cmike@reedtribe.orgvoid SkImage_Picture::onDraw(SkCanvas* canvas, SkScalar x, SkScalar y,
15970e359055240d0de93da4ba71bf5833164fb394cmike@reedtribe.org                             const SkPaint* paint) {
16070e359055240d0de93da4ba71bf5833164fb394cmike@reedtribe.org    SkImagePrivDrawPicture(canvas, fPicture, x, y, paint);
16170e359055240d0de93da4ba71bf5833164fb394cmike@reedtribe.org}
16270e359055240d0de93da4ba71bf5833164fb394cmike@reedtribe.org
16370e359055240d0de93da4ba71bf5833164fb394cmike@reedtribe.orgSkImage* SkNewImageFromPicture(SkPicture* pict) {
16470e359055240d0de93da4ba71bf5833164fb394cmike@reedtribe.org    return SkNEW_ARGS(SkImage_Picture, (pict));
165f6627b78f933b77b358ac0791c520f99b0e79fcareed@google.com}
166f6627b78f933b77b358ac0791c520f99b0e79fcareed@google.com
167f6627b78f933b77b358ac0791c520f99b0e79fcareed@google.com///////////////////////////////////////////////////////////////////////////////
168f6627b78f933b77b358ac0791c520f99b0e79fcareed@google.com
169f6627b78f933b77b358ac0791c520f99b0e79fcareed@google.comSkImage* SkImage::NewRasterCopy(const SkImage::Info& info, SkColorSpace* cs,
170f6627b78f933b77b358ac0791c520f99b0e79fcareed@google.com                                const void* pixels, size_t rowBytes) {
171f6627b78f933b77b358ac0791c520f99b0e79fcareed@google.com    if (!SkImage_Raster::ValidArgs(info, cs, rowBytes)) {
172f6627b78f933b77b358ac0791c520f99b0e79fcareed@google.com        return NULL;
173f6627b78f933b77b358ac0791c520f99b0e79fcareed@google.com    }
174f6627b78f933b77b358ac0791c520f99b0e79fcareed@google.com    if (0 == info.fWidth && 0 == info.fHeight) {
175f6627b78f933b77b358ac0791c520f99b0e79fcareed@google.com        return SkImage_Raster::NewEmpty();
176f6627b78f933b77b358ac0791c520f99b0e79fcareed@google.com    }
177f6627b78f933b77b358ac0791c520f99b0e79fcareed@google.com    // check this after empty-check
178f6627b78f933b77b358ac0791c520f99b0e79fcareed@google.com    if (NULL == pixels) {
179f6627b78f933b77b358ac0791c520f99b0e79fcareed@google.com        return NULL;
180f6627b78f933b77b358ac0791c520f99b0e79fcareed@google.com    }
181f6627b78f933b77b358ac0791c520f99b0e79fcareed@google.com
182f6627b78f933b77b358ac0791c520f99b0e79fcareed@google.com    // Here we actually make a copy of the caller's pixel data
183f6627b78f933b77b358ac0791c520f99b0e79fcareed@google.com    SkAutoDataUnref data(SkData::NewWithCopy(pixels, info.fHeight * rowBytes));
184f6627b78f933b77b358ac0791c520f99b0e79fcareed@google.com    return SkNEW_ARGS(SkImage_Raster, (info, cs, data, rowBytes));
185f6627b78f933b77b358ac0791c520f99b0e79fcareed@google.com}
186f6627b78f933b77b358ac0791c520f99b0e79fcareed@google.com
187f6627b78f933b77b358ac0791c520f99b0e79fcareed@google.com
188f6627b78f933b77b358ac0791c520f99b0e79fcareed@google.comSkImage* SkImage::NewRasterData(const SkImage::Info& info, SkColorSpace* cs,
189f6627b78f933b77b358ac0791c520f99b0e79fcareed@google.com                                SkData* pixelData, size_t rowBytes) {
190f6627b78f933b77b358ac0791c520f99b0e79fcareed@google.com    if (!SkImage_Raster::ValidArgs(info, cs, rowBytes)) {
191f6627b78f933b77b358ac0791c520f99b0e79fcareed@google.com        return NULL;
192f6627b78f933b77b358ac0791c520f99b0e79fcareed@google.com    }
193f6627b78f933b77b358ac0791c520f99b0e79fcareed@google.com    if (0 == info.fWidth && 0 == info.fHeight) {
194f6627b78f933b77b358ac0791c520f99b0e79fcareed@google.com        return SkImage_Raster::NewEmpty();
195f6627b78f933b77b358ac0791c520f99b0e79fcareed@google.com    }
196f6627b78f933b77b358ac0791c520f99b0e79fcareed@google.com    // check this after empty-check
197f6627b78f933b77b358ac0791c520f99b0e79fcareed@google.com    if (NULL == pixelData) {
198f6627b78f933b77b358ac0791c520f99b0e79fcareed@google.com        return NULL;
199f6627b78f933b77b358ac0791c520f99b0e79fcareed@google.com    }
200f6627b78f933b77b358ac0791c520f99b0e79fcareed@google.com
201f6627b78f933b77b358ac0791c520f99b0e79fcareed@google.com    // did they give us enough data?
202f6627b78f933b77b358ac0791c520f99b0e79fcareed@google.com    size_t size = info.fHeight * rowBytes;
203f6627b78f933b77b358ac0791c520f99b0e79fcareed@google.com    if (pixelData->size() < size) {
204f6627b78f933b77b358ac0791c520f99b0e79fcareed@google.com        return NULL;
205f6627b78f933b77b358ac0791c520f99b0e79fcareed@google.com    }
206f6627b78f933b77b358ac0791c520f99b0e79fcareed@google.com
207f6627b78f933b77b358ac0791c520f99b0e79fcareed@google.com    SkAutoDataUnref data(pixelData);
208f6627b78f933b77b358ac0791c520f99b0e79fcareed@google.com    return SkNEW_ARGS(SkImage_Raster, (info, cs, data, rowBytes));
209f6627b78f933b77b358ac0791c520f99b0e79fcareed@google.com}
210f6627b78f933b77b358ac0791c520f99b0e79fcareed@google.com
211f6627b78f933b77b358ac0791c520f99b0e79fcareed@google.com///////////////////////////////////////////////////////////////////////////////
212f6627b78f933b77b358ac0791c520f99b0e79fcareed@google.com
213f6627b78f933b77b358ac0791c520f99b0e79fcareed@google.com#include "SkCanvas.h"
214f6627b78f933b77b358ac0791c520f99b0e79fcareed@google.com
215f6627b78f933b77b358ac0791c520f99b0e79fcareed@google.comuint32_t SkImage::NextUniqueID() {
216f6627b78f933b77b358ac0791c520f99b0e79fcareed@google.com    static int32_t gUniqueID;
217f6627b78f933b77b358ac0791c520f99b0e79fcareed@google.com
218f6627b78f933b77b358ac0791c520f99b0e79fcareed@google.com    // never return 0;
219f6627b78f933b77b358ac0791c520f99b0e79fcareed@google.com    uint32_t id;
220f6627b78f933b77b358ac0791c520f99b0e79fcareed@google.com    do {
221f6627b78f933b77b358ac0791c520f99b0e79fcareed@google.com        id = sk_atomic_inc(&gUniqueID) + 1;
222f6627b78f933b77b358ac0791c520f99b0e79fcareed@google.com    } while (0 == id);
223f6627b78f933b77b358ac0791c520f99b0e79fcareed@google.com    return id;
224f6627b78f933b77b358ac0791c520f99b0e79fcareed@google.com}
225f6627b78f933b77b358ac0791c520f99b0e79fcareed@google.com
226f6627b78f933b77b358ac0791c520f99b0e79fcareed@google.comvoid SkImage::draw(SkCanvas* canvas, SkScalar x, SkScalar y,
227f6627b78f933b77b358ac0791c520f99b0e79fcareed@google.com                   const SkPaint* paint) {
22870e359055240d0de93da4ba71bf5833164fb394cmike@reedtribe.org    asIB(this)->onDraw(canvas, x, y, paint);
229f6627b78f933b77b358ac0791c520f99b0e79fcareed@google.com}
230f6627b78f933b77b358ac0791c520f99b0e79fcareed@google.com
231