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 "SkDisplayMovie.h"
11 #include "SkAnimateMaker.h"
12 #include "SkCanvas.h"
13 #include "SkPaint.h"
14 
15 #if SK_USE_CONDENSED_INFO == 0
16 
17 const SkMemberInfo SkDisplayMovie::fInfo[] = {
18     SK_MEMBER(src, String)
19 };
20 
21 #endif
22 
23 DEFINE_GET_MEMBER(SkDisplayMovie);
24 
SkDisplayMovie()25 SkDisplayMovie::SkDisplayMovie() : fDecodedSuccessfully(false), fLoaded(false), fMovieBuilt(false) {
26     fMovie.fMaker->fInMovie = true;
27 }
28 
~SkDisplayMovie()29 SkDisplayMovie::~SkDisplayMovie() {
30 }
31 
buildMovie()32 void SkDisplayMovie::buildMovie() {
33     if (fMovieBuilt)
34         return;
35     SkAnimateMaker* movieMaker = fMovie.fMaker;
36     SkAnimateMaker* parentMaker = movieMaker->fParentMaker;
37     if (src.size() == 0 || parentMaker == nullptr)
38         return;
39     movieMaker->fPrefix.set(parentMaker->fPrefix);
40     fDecodedSuccessfully = fMovie.fMaker->decodeURI(src.c_str());
41     if (fDecodedSuccessfully == false) {
42 
43         if (movieMaker->getErrorCode() != SkXMLParserError::kNoError || movieMaker->getNativeCode() != -1) {
44             movieMaker->setInnerError(parentMaker, src);
45             parentMaker->setErrorCode(SkDisplayXMLParserError::kInMovie);
46         } else {
47             parentMaker->setErrorNoun(src);
48             parentMaker->setErrorCode(SkDisplayXMLParserError::kMovieNameUnknownOrMissing);
49         }
50     }
51     fMovieBuilt = true;
52 }
53 
deepCopy(SkAnimateMaker * maker)54 SkDisplayable* SkDisplayMovie::deepCopy(SkAnimateMaker* maker) {
55     SkDisplayMovie* copy = (SkDisplayMovie*) INHERITED::deepCopy(maker);
56     copy->fMovie.fMaker->fParentMaker = fMovie.fMaker->fParentMaker;
57     copy->fMovie.fMaker->fHostEventSinkID = fMovie.fMaker->fHostEventSinkID;
58     copy->fMovieBuilt = false;
59     *fMovie.fMaker->fParentMaker->fMovies.append() = copy;
60     return copy;
61 }
62 
dirty()63 void SkDisplayMovie::dirty() {
64     buildMovie();
65 }
66 
doEvent(SkDisplayEvent::Kind kind,SkEventState * state)67 bool SkDisplayMovie::doEvent(SkDisplayEvent::Kind kind, SkEventState* state) {
68     if (fLoaded == false)
69         return false;
70     fMovie.fMaker->fEnableTime = fMovie.fMaker->fParentMaker->fEnableTime;
71     return fMovie.fMaker->fEvents.doEvent(*fMovie.fMaker, kind, state);
72 }
73 
draw(SkAnimateMaker & maker)74 bool SkDisplayMovie::draw(SkAnimateMaker& maker) {
75     if (fDecodedSuccessfully == false)
76         return false;
77     if (fLoaded == false)
78         enable(maker);
79     maker.fCanvas->save();
80     SkPaint local = SkPaint(*maker.fPaint);
81     bool result = fMovie.draw(maker.fCanvas, &local,
82         maker.fDisplayList.getTime()) != SkAnimator::kNotDifferent;
83     maker.fDisplayList.fInvalBounds.join(fMovie.fMaker->fDisplayList.fInvalBounds);
84     maker.fCanvas->restore();
85     return result;
86 }
87 
88 #ifdef SK_DUMP_ENABLED
dump(SkAnimateMaker * maker)89 void SkDisplayMovie::dump(SkAnimateMaker* maker) {
90     dumpBase(maker);
91     SkDebugf("src=\"%s\"/>\n",  src.c_str());
92     SkAnimateMaker* movieMaker = fMovie.fMaker;
93     SkDisplayList::fIndent += 4;
94     movieMaker->fDisplayList.dumpInner(movieMaker);
95     SkDisplayList::fIndent -= 4;
96     dumpEnd(maker);
97 }
98 
dumpEvents()99 void SkDisplayMovie::dumpEvents() {
100     fMovie.fMaker->fEvents.dump(*fMovie.fMaker);
101 }
102 #endif
103 
enable(SkAnimateMaker &)104 bool SkDisplayMovie::enable(SkAnimateMaker&) {
105     if (fDecodedSuccessfully == false)
106         return false;
107     SkAnimateMaker* movieMaker = fMovie.fMaker;
108     movieMaker->fEvents.doEvent(*movieMaker, SkDisplayEvent::kOnload, nullptr);
109     movieMaker->fEvents.removeEvent(SkDisplayEvent::kOnload, nullptr);
110     fLoaded = true;
111     movieMaker->fLoaded = true;
112     return false;
113 }
114 
hasEnable() const115 bool SkDisplayMovie::hasEnable() const {
116     return true;
117 }
118 
onEndElement(SkAnimateMaker & maker)119 void SkDisplayMovie::onEndElement(SkAnimateMaker& maker) {
120 #if defined SK_DEBUG && defined SK_DEBUG_ANIMATION_TIMING
121     fMovie.fMaker->fDebugTimeBase = maker.fDebugTimeBase;
122 #endif
123     fMovie.fMaker->fPrefix.set(maker.fPrefix);
124     fMovie.fMaker->fHostEventSinkID = maker.fHostEventSinkID;
125     fMovie.fMaker->fParentMaker = &maker;
126     buildMovie();
127     *maker.fMovies.append() = this;
128 }
129