beta-0.89.2
[luatex.git] / source / libs / poppler / poppler-src / poppler / Rendition.cc
blobc040bf2b4a8d31be92a621ce62497d70177fec3e
1 //*********************************************************************************
2 // Rendition.cc
3 //---------------------------------------------------------------------------------
4 //
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 //*********************************************************************************
26 #include <math.h>
27 #include "Rendition.h"
28 #include "FileSpec.h"
30 MediaWindowParameters::MediaWindowParameters() {
31 // default values
32 type = windowEmbedded;
33 width = -1;
34 height = -1;
35 relativeTo = windowRelativeToDocument;
36 XPosition = 0.5;
37 YPosition = 0.5;
38 hasTitleBar = gTrue;
39 hasCloseButton = gTrue;
40 isResizeable = gTrue;
43 MediaWindowParameters::~MediaWindowParameters() {
46 void MediaWindowParameters::parseFWParams(Object* obj) {
47 Object tmp;
49 if (obj->dictLookup("D", &tmp)->isArray()) {
50 Array * dim = tmp.getArray();
52 if (dim->getLength() >= 2) {
53 Object dd;
54 if (dim->get(0, &dd)->isInt()) {
55 width = dd.getInt();
57 dd.free();
58 if (dim->get(1, &dd)->isInt()) {
59 height = dd.getInt();
61 dd.free();
64 tmp.free();
66 if (obj->dictLookup("RT", &tmp)->isInt()) {
67 int t = tmp.getInt();
68 switch(t) {
69 case 0: relativeTo = windowRelativeToDocument; break;
70 case 1: relativeTo = windowRelativeToApplication; break;
71 case 2: relativeTo = windowRelativeToDesktop; break;
74 tmp.free();
76 if (obj->dictLookup("P",&tmp)->isInt()) {
77 int t = tmp.getInt();
79 switch(t) {
80 case 0: // Upper left
81 XPosition = 0.0;
82 YPosition = 0.0;
83 break;
84 case 1: // Upper Center
85 XPosition = 0.5;
86 YPosition = 0.0;
87 break;
88 case 2: // Upper Right
89 XPosition = 1.0;
90 YPosition = 0.0;
91 break;
92 case 3: // Center Left
93 XPosition = 0.0;
94 YPosition = 0.5;
95 break;
96 case 4: // Center
97 XPosition = 0.5;
98 YPosition = 0.5;
99 break;
100 case 5: // Center Right
101 XPosition = 1.0;
102 YPosition = 0.5;
103 break;
104 case 6: // Lower Left
105 XPosition = 0.0;
106 YPosition = 1.0;
107 break;
108 case 7: // Lower Center
109 XPosition = 0.5;
110 YPosition = 1.0;
111 break;
112 case 8: // Lower Right
113 XPosition = 1.0;
114 YPosition = 1.0;
115 break;
118 tmp.free();
120 if (obj->dictLookup("T", &tmp)->isBool()) {
121 hasTitleBar = tmp.getBool();
123 tmp.free();
124 if (obj->dictLookup("UC", &tmp)->isBool()) {
125 hasCloseButton = tmp.getBool();
127 tmp.free();
128 if (obj->dictLookup("R", &tmp)->isInt()) {
129 isResizeable = (tmp.getInt() != 0);
131 tmp.free();
135 MediaParameters::MediaParameters() {
136 // instanciate to default values
138 volume = 100;
139 fittingPolicy = fittingUndefined;
140 autoPlay = gTrue;
141 repeatCount = 1.0;
142 opacity = 1.0;
143 showControls = gFalse;
144 duration = 0;
147 MediaParameters::~MediaParameters() {
150 void MediaParameters::parseMediaPlayParameters(Object* obj) {
152 Object tmp;
154 if (obj->dictLookup("V", &tmp)->isInt()) {
155 volume = tmp.getInt();
157 tmp.free();
159 if (obj->dictLookup("C", &tmp)->isBool()) {
160 showControls = tmp.getBool();
162 tmp.free();
164 if (obj->dictLookup("F", &tmp)->isInt()) {
165 int t = tmp.getInt();
167 switch(t) {
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;
176 tmp.free();
178 // duration parsing
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());
191 tmp2.free();
193 ddict.free();
196 oname.free();
198 tmp.free();
201 if (obj->dictLookup("A", &tmp)->isBool()) {
202 autoPlay = tmp.getBool();
204 tmp.free();
206 if (obj->dictLookup("RC", &tmp)->isNum()) {
207 repeatCount = tmp.getNum();
209 tmp.free();
213 void MediaParameters::parseMediaScreenParameters(Object* obj) {
214 Object tmp;
216 if (obj->dictLookup("W", &tmp)->isInt()) {
217 int t = tmp.getInt();
219 switch(t) {
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;
226 tmp.free();
228 // background color
229 if (obj->dictLookup("B", &tmp)->isArray()) {
230 Array* color = tmp.getArray();
232 Object component;
234 color->get(0, &component);
235 bgColor.r = component.getNum();
236 component.free();
238 color->get(1, &component);
239 bgColor.g = component.getNum();
240 component.free();
242 color->get(2, &component);
243 bgColor.b = component.getNum();
244 component.free();
246 tmp.free();
249 // opacity
250 if (obj->dictLookup("O", &tmp)->isNum()) {
251 opacity = tmp.getNum();
253 tmp.free();
255 if (windowParams.type == MediaWindowParameters::windowFloating) {
256 Object winDict;
257 if (obj->dictLookup("F",&winDict)->isDict()) {
258 windowParams.parseFWParams(&winDict);
260 winDict.free();
264 MediaRendition::~MediaRendition() {
265 if (fileName)
266 delete fileName;
267 if (contentType)
268 delete contentType;
270 if (embeddedStream && (!embeddedStream->decRef())) {
271 delete embeddedStream;
275 MediaRendition::MediaRendition(Object* obj) {
276 Object tmp, tmp2;
277 GBool hasClip = gFalse;
279 ok = gTrue;
280 fileName = NULL;
281 contentType = NULL;
282 isEmbedded = gFalse;
283 embeddedStream = NULL;
286 // Parse media clip data
288 if (obj->dictLookup("C", &tmp2)->isDict()) { // media clip
289 hasClip = gTrue;
290 if (tmp2.dictLookup("S", &tmp)->isName()) {
291 if (!strcmp(tmp.getName(), "MCD")) { // media clip data
292 Object obj1, obj2;
293 if (tmp2.dictLookup("D", &obj1)->isDict()) {
294 if (obj1.dictLookup("F", &obj2)->isString()) {
295 fileName = obj2.getString()->copy();
297 obj2.free();
298 if (obj1.dictLookup("EF", &obj2)->isDict()) {
299 Object embedded;
300 if (obj2.dictLookup("F", &embedded)->isStream()) {
301 isEmbedded = gTrue;
302 embeddedStream = embedded.getStream();
303 // "copy" stream
304 embeddedStream->incRef();
306 embedded.free();
308 obj2.free();
310 // TODO: D might be a form XObject too
311 } else {
312 error (errSyntaxError, -1, "Invalid Media Clip Data");
313 ok = gFalse;
315 obj1.free();
317 // FIXME: ignore CT if D is a form XObject
318 if (tmp2.dictLookup("CT", &obj1)->isString()) {
319 contentType = obj1.getString()->copy();
321 obj1.free();
322 } else if (!strcmp(tmp.getName(), "MCS")) { // media clip data
323 // TODO
325 } else {
326 error (errSyntaxError, -1, "Invalid Media Clip");
327 ok = gFalse;
329 tmp.free();
331 tmp2.free();
333 if (!ok)
334 return;
337 // parse Media Play Parameters
338 if (obj->dictLookup("P", &tmp2)->isDict()) { // media play parameters
339 Object params;
340 if (tmp2.dictLookup("MH", &params)->isDict()) {
341 MH.parseMediaPlayParameters(&params);
343 params.free();
344 if (tmp2.dictLookup("BE", &params)->isDict()) {
345 BE.parseMediaPlayParameters(&params);
347 params.free();
348 } else if (!hasClip) {
349 error (errSyntaxError, -1, "Invalid Media Rendition");
350 ok = gFalse;
352 tmp2.free();
355 // parse Media Screen Parameters
356 if (obj->dictLookup("SP", &tmp2)->isDict()) { // media screen parameters
357 Object params;
358 if (tmp2.dictLookup("MH", &params)->isDict()) {
359 MH.parseMediaScreenParameters(&params);
361 params.free();
362 if (tmp2.dictLookup("BE", &params)->isDict()) {
363 BE.parseMediaScreenParameters(&params);
365 params.free();
367 tmp2.free();
370 void MediaRendition::outputToFile(FILE* fp) {
371 if (!isEmbedded)
372 return;
374 embeddedStream->reset();
376 while (1) {
377 int c = embeddedStream->getChar();
378 if (c == EOF)
379 break;
381 fwrite(&c, 1, 1, fp);
386 MediaRendition *MediaRendition::copy() {
387 // call default copy constructor
388 MediaRendition* new_media = new MediaRendition(*this);
390 if (contentType)
391 new_media->contentType = contentType->copy();
392 if (fileName)
393 new_media->fileName = fileName->copy();
395 if (new_media->embeddedStream)
396 new_media->embeddedStream->incRef();
398 return new_media;
401 // TODO: SelectorRendition