blob: f68b6adcd4d3f193caec32020ac252f3303aeea9 [file] [log] [blame]
//*********************************************************************************
// Movie.cc
//---------------------------------------------------------------------------------
//
//---------------------------------------------------------------------------------
// Hugo Mercier <hmercier31[at]gmail.com> (c) 2008
// Pino Toscano <pino@kde.org> (c) 2008
// Carlos Garcia Campos <carlosgc@gnome.org> (c) 2010
// Albert Astals Cid <aacid@kde.org> (c) 2010
//
// This program is free software; you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation; either version 2 of the License, or
// (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program; if not, write to the Free Software
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
//*********************************************************************************
#include <math.h>
#include "Movie.h"
#include "FileSpec.h"
MovieActivationParameters::MovieActivationParameters() {
// default values
floatingWindow = gFalse;
xPosition = 0.5;
yPosition = 0.5;
rate = 1.0;
volume = 100;
showControls = gFalse;
synchronousPlay = gFalse;
repeatMode = repeatModeOnce;
start.units = 0;
duration.units = 0;
znum = 1;
zdenum = 1;
}
MovieActivationParameters::~MovieActivationParameters() {
}
void MovieActivationParameters::parseMovieActivation(Object* aDict) {
Object obj1;
if (!aDict->dictLookup("Start", &obj1)->isNull()) {
if (obj1.isInt()) {
// If it is representable as an integer (subject to the implementation limit for
// integers, as described in Appendix C), it should be specified as such.
start.units = obj1.getInt();
} else if (obj1.isString()) {
// If it is not representable as an integer, it should be specified as an 8-byte
// string representing a 64-bit twos-complement integer, most significant
// byte first.
// UNSUPPORTED
} else if (obj1.isArray()) {
Array* a = obj1.getArray();
Object tmp;
a->get(0, &tmp);
if (tmp.isInt()) {
start.units = tmp.getInt();
}
if (tmp.isString()) {
// UNSUPPORTED
}
tmp.free();
a->get(1, &tmp);
if (tmp.isInt()) {
start.units_per_second = tmp.getInt();
}
tmp.free();
}
}
obj1.free();
if (!aDict->dictLookup("Duration", &obj1)->isNull()) {
if (obj1.isInt()) {
duration.units = obj1.getInt();
} else if (obj1.isString()) {
// UNSUPPORTED
} else if (obj1.isArray()) {
Array* a = obj1.getArray();
Object tmp;
a->get(0, &tmp);
if (tmp.isInt()) {
duration.units = tmp.getInt();
}
if (tmp.isString()) {
// UNSUPPORTED
}
tmp.free();
a->get(1, &tmp);
if (tmp.isInt()) {
duration.units_per_second = tmp.getInt();
}
tmp.free();
}
}
obj1.free();
if (aDict->dictLookup("Rate", &obj1)->isNum()) {
rate = obj1.getNum();
}
obj1.free();
if (aDict->dictLookup("Volume", &obj1)->isNum()) {
// convert volume to [0 100]
volume = int((obj1.getNum() + 1.0) * 50);
}
obj1.free();
if (aDict->dictLookup("ShowControls", &obj1)->isBool()) {
showControls = obj1.getBool();
}
obj1.free();
if (aDict->dictLookup("Synchronous", &obj1)->isBool()) {
synchronousPlay = obj1.getBool();
}
obj1.free();
if (aDict->dictLookup("Mode", &obj1)->isName()) {
char* name = obj1.getName();
if (!strcmp(name, "Once")) {
repeatMode = repeatModeOnce;
} else if (!strcmp(name, "Open")) {
repeatMode = repeatModeOpen;
} else if (!strcmp(name, "Repeat")) {
repeatMode = repeatModeRepeat;
} else if (!strcmp(name,"Palindrome")) {
repeatMode = repeatModePalindrome;
}
}
obj1.free();
if (aDict->dictLookup("FWScale", &obj1)->isArray()) {
// the presence of that entry implies that the movie is to be played
// in a floating window
floatingWindow = gTrue;
Array* scale = obj1.getArray();
if (scale->getLength() >= 2) {
Object tmp;
if (scale->get(0, &tmp)->isInt()) {
znum = tmp.getInt();
}
tmp.free();
if (scale->get(1, &tmp)->isInt()) {
zdenum = tmp.getInt();
}
tmp.free();
}
}
obj1.free();
if (aDict->dictLookup("FWPosition", &obj1)->isArray()) {
Array* pos = obj1.getArray();
if (pos->getLength() >= 2) {
Object tmp;
if (pos->get(0, &tmp)->isNum()) {
xPosition = tmp.getNum();
}
tmp.free();
if (pos->get(1, &tmp)->isNum()) {
yPosition = tmp.getNum();
}
tmp.free();
}
}
obj1.free();
}
void Movie::parseMovie (Object *movieDict) {
fileName = NULL;
rotationAngle = 0;
width = -1;
height = -1;
showPoster = gFalse;
Object obj1, obj2;
if (getFileSpecNameForPlatform(movieDict->dictLookup("F", &obj1), &obj2)) {
fileName = obj2.getString()->copy();
obj2.free();
} else {
error (errSyntaxError, -1, "Invalid Movie");
ok = gFalse;
obj1.free();
return;
}
obj1.free();
if (movieDict->dictLookup("Aspect", &obj1)->isArray()) {
Array* aspect = obj1.getArray();
if (aspect->getLength() >= 2) {
Object tmp;
if( aspect->get(0, &tmp)->isNum() ) {
width = (int)floor( aspect->get(0, &tmp)->getNum() + 0.5 );
}
tmp.free();
if( aspect->get(1, &tmp)->isNum() ) {
height = (int)floor( aspect->get(1, &tmp)->getNum() + 0.5 );
}
tmp.free();
}
}
obj1.free();
if (movieDict->dictLookup("Rotate", &obj1)->isInt()) {
// round up to 90°
rotationAngle = (((obj1.getInt() + 360) % 360) % 90) * 90;
}
obj1.free();
//
// movie poster
//
if (!movieDict->dictLookupNF("Poster", &poster)->isNull()) {
if (poster.isRef() || poster.isStream()) {
showPoster = gTrue;
} else if (poster.isBool()) {
showPoster = poster.getBool();
poster.free();
} else {
poster.free();
}
}
}
Movie::~Movie() {
if (fileName)
delete fileName;
poster.free();
}
Movie::Movie(Object *movieDict) {
ok = gTrue;
if (movieDict->isDict())
parseMovie(movieDict);
else
ok = gFalse;
}
Movie::Movie(Object *movieDict, Object *aDict) {
ok = gTrue;
if (movieDict->isDict()) {
parseMovie(movieDict);
if (aDict->isDict())
MA.parseMovieActivation(aDict);
} else {
ok = gFalse;
}
}
void Movie::getFloatingWindowSize(int *widthA, int *heightA)
{
*widthA = int(width * double(MA.znum) / MA.zdenum);
*heightA = int(height * double(MA.znum) / MA.zdenum);
}
Movie* Movie::copy() {
// call default copy constructor
Movie* new_movie = new Movie(*this);
if (fileName)
new_movie->fileName = fileName->copy();
poster.copy(&new_movie->poster);
return new_movie;
}