1
2/*
3 * Copyright 2006 The Android Open Source Project
4 *
5 * Use of this source code is governed by a BSD-style license that can be
6 * found in the LICENSE file.
7 */
8
9
10#include "SkDrawBitmap.h"
11#include "SkAnimateMaker.h"
12#include "SkCanvas.h"
13#include "SkImageDecoder.h"
14#include "SkPaint.h"
15#include "SkStream.h"
16
17#if SK_USE_CONDENSED_INFO == 0
18
19const SkMemberInfo SkBaseBitmap::fInfo[] = {
20    SK_MEMBER(x, Float),
21    SK_MEMBER(y, Float)
22};
23
24#endif
25
26DEFINE_GET_MEMBER(SkBaseBitmap);
27
28SkBaseBitmap::SkBaseBitmap() : x(0), y(0) {
29}
30
31SkBaseBitmap::~SkBaseBitmap() {
32}
33
34bool SkBaseBitmap::draw(SkAnimateMaker& maker) {
35    SkBoundableAuto boundable(this, maker);
36    maker.fCanvas->drawBitmap(fBitmap, x, y, maker.fPaint);
37    return false;
38}
39
40enum SkDrawBitmap_Properties {
41    SK_PROPERTY(erase)
42};
43
44#if SK_USE_CONDENSED_INFO == 0
45
46const SkMemberInfo SkDrawBitmap::fInfo[] = {
47    SK_MEMBER_INHERITED,
48    SK_MEMBER_PROPERTY(erase, ARGB),
49    SK_MEMBER(format, BitmapFormat),
50    SK_MEMBER(height, Int),
51    SK_MEMBER(rowBytes, Int),
52    SK_MEMBER(width, Int),
53};
54
55#endif
56
57DEFINE_GET_MEMBER(SkDrawBitmap);
58
59SkDrawBitmap::SkDrawBitmap() : format((SkColorType) -1), height(-1),
60    rowBytes(0),    width(-1), fColor(0), fColorSet(false) {
61}
62
63SkDrawBitmap::~SkDrawBitmap() {
64}
65
66#ifdef SK_DUMP_ENABLED
67void SkDrawBitmap::dump(SkAnimateMaker* maker) {
68    dumpBase(maker);
69    dumpAttrs(maker);
70    if (fColorSet)
71        SkDebugf("erase=\"argb(%d,%d,%d,%d)\" ", SkColorGetA(fColor)/255, SkColorGetR(fColor),
72            SkColorGetG(fColor), SkColorGetB(fColor));
73    if (rowBytes > 0)
74        SkDebugf("rowBytes=\"%d\" ", rowBytes);
75    const char* formatName;
76    switch (format) {
77        case 0: formatName = "none"; break;
78        case 1: formatName = "A8"; break;
79        case 2: formatName = "Index8"; break;
80        case 3: formatName = "RGB16"; break;
81        case 4: formatName = "RGB32"; break;
82    }
83    SkDebugf("format=\"%s\" />\n", formatName);
84}
85#endif
86
87void SkDrawBitmap::onEndElement(SkAnimateMaker&) {
88    SkASSERT(width != -1);
89    SkASSERT(height != -1);
90    SkASSERT(rowBytes >= 0);
91    SkColorType colorType = SkColorType(format);
92    fBitmap.allocPixels(SkImageInfo::Make(width, height, colorType, kPremul_SkAlphaType),
93                        rowBytes);
94    if (fColorSet)
95        fBitmap.eraseColor(fColor);
96}
97
98bool SkDrawBitmap::setProperty(int index, SkScriptValue& value)
99{
100    switch (index) {
101        case SK_PROPERTY(erase):
102            SkASSERT(value.fType == SkType_ARGB);
103            fColor = value.fOperand.fS32;
104            fColorSet = true;
105            break;
106        default:
107            SkASSERT(0);
108            return false;
109    }
110    return true;
111}
112
113
114enum SkImageBaseBitmap_Properties {
115    SK_PROPERTY(height),
116    SK_PROPERTY(width)
117};
118
119#if SK_USE_CONDENSED_INFO == 0
120
121const SkMemberInfo SkImageBaseBitmap::fInfo[] = {
122    SK_MEMBER_INHERITED,
123    SK_MEMBER(base64, Base64),
124    SK_MEMBER_PROPERTY(height, Int),
125    SK_MEMBER(src, String),
126    SK_MEMBER_PROPERTY(width, Int)
127};
128
129#endif
130
131DEFINE_GET_MEMBER(SkImageBaseBitmap);
132
133SkImageBaseBitmap::SkImageBaseBitmap() : fDirty(true), fUriBase(NULL) {
134    base64.fData = NULL;
135    base64.fLength = 0;
136}
137
138SkImageBaseBitmap::~SkImageBaseBitmap() {
139    delete[] base64.fData;
140}
141
142SkDisplayable* SkImageBaseBitmap::deepCopy(SkAnimateMaker* maker) {
143    SkDisplayable* copy = INHERITED::deepCopy(maker);
144    ((SkImageBaseBitmap*) copy)->fUriBase = ((SkImageBaseBitmap*) this)->fUriBase;
145    return copy;
146}
147
148void SkImageBaseBitmap::dirty() {
149    fDirty = true;
150}
151
152bool SkImageBaseBitmap::draw(SkAnimateMaker& maker) {
153    if (fDirty)
154        resolve();
155    return INHERITED::draw(maker);
156}
157
158bool SkImageBaseBitmap::getProperty(int index, SkScriptValue* value) const {
159    if (fDirty)
160        resolve();
161    switch (index) {
162        case SK_PROPERTY(height):
163            value->fOperand.fS32 = fBitmap.height();
164            break;
165        case SK_PROPERTY(width):
166            value->fOperand.fS32 = fBitmap.width();
167            break;
168    default:
169        SkASSERT(0);
170        return false;
171    }
172    value->fType = SkType_Int;
173    return true;
174}
175
176void SkImageBaseBitmap::onEndElement(SkAnimateMaker& maker) {
177    fUriBase = maker.fPrefix.c_str();
178}
179
180void SkImageBaseBitmap::resolve() {
181    fDirty = false;
182    if (base64.fData) {
183        fBitmap.reset();
184        SkImageDecoder::DecodeMemory(base64.fData, base64.fLength, &fBitmap);
185    } else if (src.size()) {
186        if (fLast.equals(src))
187            return;
188        fLast.set(src);
189        fBitmap.reset();
190
191        //SkStream* stream = SkStream::GetURIStream(fUriBase, src.c_str());
192        SkAutoTUnref<SkStreamAsset> stream(SkStream::NewFromFile(src.c_str()));
193        if (stream.get()) {
194            SkImageDecoder::DecodeStream(stream, &fBitmap);
195        }
196    }
197}
198