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
17const SkMemberInfo SkDisplayMovie::fInfo[] = {
18    SK_MEMBER(src, String)
19};
20
21#endif
22
23DEFINE_GET_MEMBER(SkDisplayMovie);
24
25SkDisplayMovie::SkDisplayMovie() : fDecodedSuccessfully(false), fLoaded(false), fMovieBuilt(false) {
26    fMovie.fMaker->fInMovie = true;
27}
28
29SkDisplayMovie::~SkDisplayMovie() {
30}
31
32void SkDisplayMovie::buildMovie() {
33    if (fMovieBuilt)
34        return;
35    SkAnimateMaker* movieMaker = fMovie.fMaker;
36    SkAnimateMaker* parentMaker = movieMaker->fParentMaker;
37    if (src.size() == 0 || parentMaker == NULL)
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
54SkDisplayable* 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
63void SkDisplayMovie::dirty() {
64    buildMovie();
65}
66
67bool 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
74bool 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
89void 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
99void SkDisplayMovie::dumpEvents() {
100    fMovie.fMaker->fEvents.dump(*fMovie.fMaker);
101}
102#endif
103
104bool SkDisplayMovie::enable(SkAnimateMaker&) {
105    if (fDecodedSuccessfully == false)
106        return false;
107    SkAnimateMaker* movieMaker = fMovie.fMaker;
108    movieMaker->fEvents.doEvent(*movieMaker, SkDisplayEvent::kOnload, NULL);
109    movieMaker->fEvents.removeEvent(SkDisplayEvent::kOnload, NULL);
110    fLoaded = true;
111    movieMaker->fLoaded = true;
112    return false;
113}
114
115bool SkDisplayMovie::hasEnable() const {
116    return true;
117}
118
119void 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