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 
19 const SkMemberInfo SkBaseBitmap::fInfo[] = {
20     SK_MEMBER(x, Float),
21     SK_MEMBER(y, Float)
22 };
23 
24 #endif
25 
26 DEFINE_GET_MEMBER(SkBaseBitmap);
27 
SkBaseBitmap()28 SkBaseBitmap::SkBaseBitmap() : x(0), y(0) {
29 }
30 
~SkBaseBitmap()31 SkBaseBitmap::~SkBaseBitmap() {
32 }
33 
draw(SkAnimateMaker & maker)34 bool SkBaseBitmap::draw(SkAnimateMaker& maker) {
35     SkBoundableAuto boundable(this, maker);
36     maker.fCanvas->drawBitmap(fBitmap, x, y, maker.fPaint);
37     return false;
38 }
39 
40 enum SkDrawBitmap_Properties {
41     SK_PROPERTY(erase)
42 };
43 
44 #if SK_USE_CONDENSED_INFO == 0
45 
46 const 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 
57 DEFINE_GET_MEMBER(SkDrawBitmap);
58 
SkDrawBitmap()59 SkDrawBitmap::SkDrawBitmap() : format((SkColorType) -1), height(-1),
60     rowBytes(0),    width(-1), fColor(0), fColorSet(false) {
61 }
62 
~SkDrawBitmap()63 SkDrawBitmap::~SkDrawBitmap() {
64 }
65 
66 #ifdef SK_DUMP_ENABLED
dump(SkAnimateMaker * maker)67 void 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 
onEndElement(SkAnimateMaker &)87 void 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 
setProperty(int index,SkScriptValue & value)98 bool 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 
114 enum SkImageBaseBitmap_Properties {
115     SK_PROPERTY(height),
116     SK_PROPERTY(width)
117 };
118 
119 #if SK_USE_CONDENSED_INFO == 0
120 
121 const 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 
131 DEFINE_GET_MEMBER(SkImageBaseBitmap);
132 
SkImageBaseBitmap()133 SkImageBaseBitmap::SkImageBaseBitmap() : fDirty(true), fUriBase(NULL) {
134     base64.fData = NULL;
135     base64.fLength = 0;
136 }
137 
~SkImageBaseBitmap()138 SkImageBaseBitmap::~SkImageBaseBitmap() {
139     delete[] base64.fData;
140 }
141 
deepCopy(SkAnimateMaker * maker)142 SkDisplayable* SkImageBaseBitmap::deepCopy(SkAnimateMaker* maker) {
143     SkDisplayable* copy = INHERITED::deepCopy(maker);
144     ((SkImageBaseBitmap*) copy)->fUriBase = ((SkImageBaseBitmap*) this)->fUriBase;
145     return copy;
146 }
147 
dirty()148 void SkImageBaseBitmap::dirty() {
149     fDirty = true;
150 }
151 
draw(SkAnimateMaker & maker)152 bool SkImageBaseBitmap::draw(SkAnimateMaker& maker) {
153     if (fDirty)
154         resolve();
155     return INHERITED::draw(maker);
156 }
157 
getProperty(int index,SkScriptValue * value) const158 bool 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 
onEndElement(SkAnimateMaker & maker)176 void SkImageBaseBitmap::onEndElement(SkAnimateMaker& maker) {
177     fUriBase = maker.fPrefix.c_str();
178 }
179 
resolve()180 void 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         SkAutoTDelete<SkStreamAsset> stream(SkStream::NewFromFile(src.c_str()));
193         if (stream.get()) {
194             SkImageDecoder::DecodeStream(stream, &fBitmap);
195         }
196     }
197 }
198