1 //*********************************************************************************
3 //---------------------------------------------------------------------------------
5 //---------------------------------------------------------------------------------
6 // Hugo Mercier <hmercier31[at]gmail.com> (c) 2008
7 // Pino Toscano <pino@kde.org> (c) 2008
8 // Carlos Garcia Campos <carlosgc@gnome.org> (c) 2010
9 // Tobias Koenig <tobias.koenig@kdab.com> (c) 2012
11 // This program is free software; you can redistribute it and/or modify
12 // it under the terms of the GNU General Public License as published by
13 // the Free Software Foundation; either version 2 of the License, or
14 // (at your option) any later version.
16 // This program is distributed in the hope that it will be useful,
17 // but WITHOUT ANY WARRANTY; without even the implied warranty of
18 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 // GNU General Public License for more details.
21 // You should have received a copy of the GNU General Public License
22 // along with this program; if not, write to the Free Software
23 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
24 //*********************************************************************************
27 #include "Rendition.h"
30 MediaWindowParameters::MediaWindowParameters() {
32 type
= windowEmbedded
;
35 relativeTo
= windowRelativeToDocument
;
39 hasCloseButton
= gTrue
;
43 MediaWindowParameters::~MediaWindowParameters() {
46 void MediaWindowParameters::parseFWParams(Object
* obj
) {
49 if (obj
->dictLookup("D", &tmp
)->isArray()) {
50 Array
* dim
= tmp
.getArray();
52 if (dim
->getLength() >= 2) {
54 if (dim
->get(0, &dd
)->isInt()) {
58 if (dim
->get(1, &dd
)->isInt()) {
66 if (obj
->dictLookup("RT", &tmp
)->isInt()) {
69 case 0: relativeTo
= windowRelativeToDocument
; break;
70 case 1: relativeTo
= windowRelativeToApplication
; break;
71 case 2: relativeTo
= windowRelativeToDesktop
; break;
76 if (obj
->dictLookup("P",&tmp
)->isInt()) {
84 case 1: // Upper Center
88 case 2: // Upper Right
92 case 3: // Center Left
100 case 5: // Center Right
104 case 6: // Lower Left
108 case 7: // Lower Center
112 case 8: // Lower Right
120 if (obj
->dictLookup("T", &tmp
)->isBool()) {
121 hasTitleBar
= tmp
.getBool();
124 if (obj
->dictLookup("UC", &tmp
)->isBool()) {
125 hasCloseButton
= tmp
.getBool();
128 if (obj
->dictLookup("R", &tmp
)->isInt()) {
129 isResizeable
= (tmp
.getInt() != 0);
135 MediaParameters::MediaParameters() {
136 // instanciate to default values
139 fittingPolicy
= fittingUndefined
;
143 showControls
= gFalse
;
147 MediaParameters::~MediaParameters() {
150 void MediaParameters::parseMediaPlayParameters(Object
* obj
) {
154 if (obj
->dictLookup("V", &tmp
)->isInt()) {
155 volume
= tmp
.getInt();
159 if (obj
->dictLookup("C", &tmp
)->isBool()) {
160 showControls
= tmp
.getBool();
164 if (obj
->dictLookup("F", &tmp
)->isInt()) {
165 int t
= tmp
.getInt();
168 case 0: fittingPolicy
= fittingMeet
; break;
169 case 1: fittingPolicy
= fittingSlice
; break;
170 case 2: fittingPolicy
= fittingFill
; break;
171 case 3: fittingPolicy
= fittingScroll
; break;
172 case 4: fittingPolicy
= fittingHidden
; break;
173 case 5: fittingPolicy
= fittingUndefined
; break;
179 // duration's default value is set to 0, which means : intrinsinc media duration
180 if (obj
->dictLookup("D", &tmp
)->isDict()) {
181 Object oname
, ddict
, tmp2
;
182 if (tmp
.dictLookup("S", &oname
)->isName()) {
183 char* name
= oname
.getName();
184 if (!strcmp(name
, "F"))
185 duration
= -1; // infinity
186 else if (!strcmp(name
, "T")) {
187 if (tmp
.dictLookup("T", &ddict
)->isDict()) {
188 if (ddict
.dictLookup("V", &tmp2
)->isNum()) {
189 duration
= Gulong(tmp2
.getNum());
201 if (obj
->dictLookup("A", &tmp
)->isBool()) {
202 autoPlay
= tmp
.getBool();
206 if (obj
->dictLookup("RC", &tmp
)->isNum()) {
207 repeatCount
= tmp
.getNum();
213 void MediaParameters::parseMediaScreenParameters(Object
* obj
) {
216 if (obj
->dictLookup("W", &tmp
)->isInt()) {
217 int t
= tmp
.getInt();
220 case 0: windowParams
.type
= MediaWindowParameters::windowFloating
; break;
221 case 1: windowParams
.type
= MediaWindowParameters::windowFullscreen
; break;
222 case 2: windowParams
.type
= MediaWindowParameters::windowHidden
; break;
223 case 3: windowParams
.type
= MediaWindowParameters::windowEmbedded
; break;
229 if (obj
->dictLookup("B", &tmp
)->isArray()) {
230 Array
* color
= tmp
.getArray();
234 color
->get(0, &component
);
235 bgColor
.r
= component
.getNum();
238 color
->get(1, &component
);
239 bgColor
.g
= component
.getNum();
242 color
->get(2, &component
);
243 bgColor
.b
= component
.getNum();
250 if (obj
->dictLookup("O", &tmp
)->isNum()) {
251 opacity
= tmp
.getNum();
255 if (windowParams
.type
== MediaWindowParameters::windowFloating
) {
257 if (obj
->dictLookup("F",&winDict
)->isDict()) {
258 windowParams
.parseFWParams(&winDict
);
264 MediaRendition::~MediaRendition() {
270 if (embeddedStream
&& (!embeddedStream
->decRef())) {
271 delete embeddedStream
;
275 MediaRendition::MediaRendition(Object
* obj
) {
277 GBool hasClip
= gFalse
;
283 embeddedStream
= NULL
;
286 // Parse media clip data
288 if (obj
->dictLookup("C", &tmp2
)->isDict()) { // media clip
290 if (tmp2
.dictLookup("S", &tmp
)->isName()) {
291 if (!strcmp(tmp
.getName(), "MCD")) { // media clip data
293 if (tmp2
.dictLookup("D", &obj1
)->isDict()) {
294 if (obj1
.dictLookup("F", &obj2
)->isString()) {
295 fileName
= obj2
.getString()->copy();
298 if (obj1
.dictLookup("EF", &obj2
)->isDict()) {
300 if (obj2
.dictLookup("F", &embedded
)->isStream()) {
302 embeddedStream
= embedded
.getStream();
304 embeddedStream
->incRef();
310 // TODO: D might be a form XObject too
312 error (errSyntaxError
, -1, "Invalid Media Clip Data");
317 // FIXME: ignore CT if D is a form XObject
318 if (tmp2
.dictLookup("CT", &obj1
)->isString()) {
319 contentType
= obj1
.getString()->copy();
322 } else if (!strcmp(tmp
.getName(), "MCS")) { // media clip data
326 error (errSyntaxError
, -1, "Invalid Media Clip");
337 // parse Media Play Parameters
338 if (obj
->dictLookup("P", &tmp2
)->isDict()) { // media play parameters
340 if (tmp2
.dictLookup("MH", ¶ms
)->isDict()) {
341 MH
.parseMediaPlayParameters(¶ms
);
344 if (tmp2
.dictLookup("BE", ¶ms
)->isDict()) {
345 BE
.parseMediaPlayParameters(¶ms
);
348 } else if (!hasClip
) {
349 error (errSyntaxError
, -1, "Invalid Media Rendition");
355 // parse Media Screen Parameters
356 if (obj
->dictLookup("SP", &tmp2
)->isDict()) { // media screen parameters
358 if (tmp2
.dictLookup("MH", ¶ms
)->isDict()) {
359 MH
.parseMediaScreenParameters(¶ms
);
362 if (tmp2
.dictLookup("BE", ¶ms
)->isDict()) {
363 BE
.parseMediaScreenParameters(¶ms
);
370 void MediaRendition::outputToFile(FILE* fp
) {
374 embeddedStream
->reset();
377 int c
= embeddedStream
->getChar();
381 fwrite(&c
, 1, 1, fp
);
386 MediaRendition
*MediaRendition::copy() {
387 // call default copy constructor
388 MediaRendition
* new_media
= new MediaRendition(*this);
391 new_media
->contentType
= contentType
->copy();
393 new_media
->fileName
= fileName
->copy();
395 if (new_media
->embeddedStream
)
396 new_media
->embeddedStream
->incRef();
401 // TODO: SelectorRendition