1/*
2 * << Haru Free PDF Library >> -- hpdf_u3d.c
3 *
4 * URL: http://libharu.org
5 *
6 * Copyright (c) 1999-2006 Takeshi Kanno <takeshi_kanno@est.hi-ho.ne.jp>
7 * Copyright (c) 2007-2009 Antony Dovgal <tony@daylessday.org>
8 *
9 * Permission to use, copy, modify, distribute and sell this software
10 * and its documentation for any purpose is hereby granted without fee,
11 * provided that the above copyright notice appear in all copies and
12 * that both that copyright notice and this permission notice appear
13 * in supporting documentation.
14 * It is provided "as is" without express or implied warranty.
15 *
16 */
17#include "hpdf_conf.h"
18#include "hpdf_utils.h"
19#include "hpdf.h"
20
21#include <string.h>
22
23#ifndef M_PI
24/* Not defined in MSVC6 */
25#define M_PI 3.14159265358979323846
26#endif
27
28HPDF_U3D
29HPDF_U3D_LoadU3D (HPDF_MMgr mmgr,
30 HPDF_Stream u3d_data,
31 HPDF_Xref xref);
32
33static const char u3d[] = "U3D";
34static const char prc[] = "PRC";
35
36static HPDF_STATUS Get3DStreamType (HPDF_Stream stream, const char **type)
37{
38 HPDF_BYTE tag[4];
39 HPDF_UINT len;
40
41 HPDF_PTRACE ((" HPDF_U3D_Get3DStreamType\n"));
42
43 len = 4;
44 if (HPDF_Stream_Read (stream, tag, &len) != HPDF_OK) {
45 return HPDF_Error_GetCode (stream->error);
46 }
47
48 if (HPDF_Stream_Seek (stream, 0, HPDF_SEEK_SET) != HPDF_OK) {
49 return HPDF_Error_GetCode (stream->error);
50 }
51
52 if (HPDF_MemCmp(tag, (HPDF_BYTE *)u3d, 4/* yes, \0 is required */) == 0) {
53 *type = u3d;
54 return HPDF_OK;
55 }
56
57 if (HPDF_MemCmp(tag, (HPDF_BYTE *)prc, 3) == 0) {
58 *type = prc;
59 return HPDF_OK;
60 }
61
62 return HPDF_INVALID_U3D_DATA;
63}
64
65
66HPDF_U3D
67HPDF_U3D_LoadU3DFromMem ( HPDF_MMgr mmgr,
68 const HPDF_BYTE *buf,
69 HPDF_UINT size,
70 HPDF_Xref xref )
71{
72 HPDF_Dict image;
73 HPDF_STATUS ret = HPDF_OK;
74
75 HPDF_PTRACE ((" HPDF_U3D_LoadU3DFromMem\n"));
76
77 image = HPDF_DictStream_New (mmgr, xref);
78 if (!image) {
79 return NULL;
80 }
81
82 image->header.obj_class |= HPDF_OSUBCLASS_XOBJECT;
83 ret = HPDF_Dict_AddName (image, "Type", "XObject");
84 if (ret != HPDF_OK) {
85 HPDF_Dict_Free(image);
86 return NULL;
87 }
88
89 ret = HPDF_Dict_AddName (image, "Subtype", "Image");
90 if (ret != HPDF_OK) {
91 HPDF_Dict_Free(image);
92 return NULL;
93 }
94
95 if (HPDF_Stream_Write (image->stream, buf, size) != HPDF_OK) {
96 HPDF_Dict_Free(image);
97 return NULL;
98 }
99
100 return image;
101}
102
103
104HPDF_EXPORT(HPDF_Image)
105HPDF_LoadU3DFromFile (HPDF_Doc pdf,
106 const char *filename)
107{
108 HPDF_Stream imagedata;
109 HPDF_Image image;
110
111 HPDF_PTRACE ((" HPDF_LoadU3DFromFile\n"));
112
113 if (!HPDF_HasDoc (pdf)) {
114 return NULL;
115 }
116
117 /* create file stream */
118 imagedata = HPDF_FileReader_New (pdf->mmgr, filename);
119
120 if (HPDF_Stream_Validate (imagedata)) {
121 image = HPDF_U3D_LoadU3D (pdf->mmgr, imagedata, pdf->xref);
122 } else {
123 image = NULL;
124 }
125
126 /* destroy file stream */
127 HPDF_Stream_Free (imagedata);
128
129 if (!image) {
130 HPDF_CheckError (&pdf->error);
131 }
132 return image;
133}
134
135HPDF_EXPORT(HPDF_Image)
136HPDF_LoadU3DFromMem (HPDF_Doc pdf,
137 const HPDF_BYTE *buffer,
138 HPDF_UINT size)
139{
140 HPDF_Stream imagedata;
141 HPDF_Image image;
142
143 HPDF_PTRACE ((" HPDF_LoadU3DFromMem\n"));
144
145 if (!HPDF_HasDoc (pdf)) {
146 return NULL;
147 }
148
149 /* create file stream */
150 imagedata = HPDF_MemStream_New (pdf->mmgr, size);
151
152 if (!HPDF_Stream_Validate (imagedata)) {
153 HPDF_RaiseError (&pdf->error, HPDF_INVALID_STREAM, 0);
154 return NULL;
155 }
156
157 if (HPDF_Stream_Write (imagedata, buffer, size) != HPDF_OK) {
158 HPDF_Stream_Free (imagedata);
159 return NULL;
160 }
161
162 if (HPDF_Stream_Validate (imagedata)) {
163 image = HPDF_U3D_LoadU3D (pdf->mmgr, imagedata, pdf->xref);
164 } else {
165 image = NULL;
166 }
167
168 /* destroy file stream */
169 HPDF_Stream_Free (imagedata);
170
171 if (!image) {
172 HPDF_CheckError (&pdf->error);
173 }
174 return image;
175}
176
177HPDF_U3D
178HPDF_U3D_LoadU3D (HPDF_MMgr mmgr,
179 HPDF_Stream u3d_data,
180 HPDF_Xref xref)
181{
182 HPDF_Dict u3d;
183 const char *type;
184
185 HPDF_PTRACE ((" HPDF_U3D_LoadU3D\n"));
186
187 u3d = HPDF_DictStream_New (mmgr, xref);
188 if (!u3d) {
189 return NULL;
190 }
191
192 u3d->header.obj_class |= HPDF_OSUBCLASS_XOBJECT;
193
194 /* add required elements */
195 u3d->filter = HPDF_STREAM_FILTER_NONE;
196
197 if (HPDF_Dict_AddName (u3d, "Type", "3D") != HPDF_OK) {
198 HPDF_Dict_Free(u3d);
199 return NULL;
200 }
201
202 if (Get3DStreamType (u3d_data, &type) != HPDF_OK) {
203 HPDF_Dict_Free(u3d);
204 return NULL;
205 }
206
207 if (HPDF_Dict_AddName (u3d, "Subtype", type) != HPDF_OK) {
208 HPDF_Dict_Free(u3d);
209 return NULL;
210 }
211
212 for (;;) {
213 HPDF_BYTE buf[HPDF_STREAM_BUF_SIZ];
214 HPDF_UINT len = HPDF_STREAM_BUF_SIZ;
215 HPDF_STATUS ret = HPDF_Stream_Read (u3d_data, buf, &len);
216
217 if (ret != HPDF_OK) {
218 if (ret == HPDF_STREAM_EOF) {
219 if (len > 0) {
220 ret = HPDF_Stream_Write (u3d->stream, buf, len);
221 if (ret != HPDF_OK) {
222 HPDF_Dict_Free(u3d);
223 return NULL;
224 }
225 }
226 break;
227 } else {
228 HPDF_Dict_Free(u3d);
229 return NULL;
230 }
231 }
232
233 if (HPDF_Stream_Write (u3d->stream, buf, len) != HPDF_OK) {
234 HPDF_Dict_Free(u3d);
235 return NULL;
236 }
237 }
238
239 return u3d;
240}
241
242HPDF_EXPORT(HPDF_Dict) HPDF_Create3DView(HPDF_MMgr mmgr, const char *name)
243{
244 HPDF_STATUS ret = HPDF_OK;
245 HPDF_Dict view;
246
247 HPDF_PTRACE ((" HPDF_Create3DView\n"));
248
249 if (name == NULL || name[0] == '\0') {
250 return NULL;
251 }
252
253 view = HPDF_Dict_New (mmgr);
254 if (!view) {
255 return NULL;
256 }
257
258 ret = HPDF_Dict_AddName (view, "TYPE", "3DView");
259 if (ret != HPDF_OK) {
260 HPDF_Dict_Free (view);
261 return NULL;
262 }
263
264 ret = HPDF_Dict_Add (view, "XN", HPDF_String_New (mmgr, name, NULL));
265 if (ret != HPDF_OK) {
266 HPDF_Dict_Free (view);
267 return NULL;
268 }
269
270 ret = HPDF_Dict_Add (view, "IN", HPDF_String_New (mmgr, name, NULL));
271 if (ret != HPDF_OK) {
272 HPDF_Dict_Free (view);
273 return NULL;
274 }
275
276 return view;
277}
278
279HPDF_EXPORT(HPDF_STATUS) HPDF_U3D_Add3DView(HPDF_U3D u3d, HPDF_Dict view)
280{
281 HPDF_Array views = NULL;
282 HPDF_STATUS ret = HPDF_OK;
283
284 HPDF_PTRACE ((" HPDF_Add3DView\n"));
285
286 if (u3d == NULL || view == NULL) {
287 return HPDF_INVALID_U3D_DATA;
288 }
289
290 views = (HPDF_Array)HPDF_Dict_GetItem (u3d, "VA", HPDF_OCLASS_ARRAY);
291 if (views == NULL) {
292 views = HPDF_Array_New (u3d->mmgr);
293 if (!views) {
294 return HPDF_Error_GetCode (u3d->error);
295 }
296
297 ret = HPDF_Dict_Add (u3d, "VA", views);
298 if (ret == HPDF_OK) {
299 ret = HPDF_Dict_AddNumber (u3d, "DV", 0);
300 } else {
301 HPDF_Array_Free (views);
302 return ret;
303 }
304 }
305
306 if (ret == HPDF_OK) {
307 ret = HPDF_Array_Add( views, view);
308 }
309
310 return ret;
311}
312
313
314HPDF_EXPORT(HPDF_STATUS) HPDF_U3D_AddOnInstanciate(HPDF_U3D u3d, HPDF_JavaScript javascript)
315{
316 HPDF_STATUS ret = HPDF_OK;
317
318 HPDF_PTRACE ((" HPDF_U3D_AddOnInstanciate\n"));
319
320 if (u3d == NULL || javascript == NULL) {
321 return HPDF_INVALID_U3D_DATA;
322 }
323
324 ret = HPDF_Dict_Add(u3d, "OnInstantiate", javascript);
325
326 return ret;
327}
328
329
330HPDF_EXPORT(HPDF_STATUS) HPDF_U3D_SetDefault3DView(HPDF_U3D u3d, const char *name)
331{
332 HPDF_STATUS ret = HPDF_OK;
333
334 HPDF_PTRACE ((" HPDF_U3D_SetDefault3DView\n"));
335
336 if (u3d == NULL || name == NULL || name[0] == '\0') {
337 return HPDF_INVALID_U3D_DATA;
338 }
339
340 ret = HPDF_Dict_Add (u3d, "DV", HPDF_String_New (u3d->mmgr, name, NULL));
341 return ret;
342}
343
344HPDF_EXPORT(HPDF_STATUS) HPDF_3DView_AddNode(HPDF_Dict view, const char *name, HPDF_REAL opacity, HPDF_BOOL visible)
345{
346 HPDF_Array nodes = NULL;
347 HPDF_Dict node;
348 HPDF_STATUS ret = HPDF_OK;
349
350 HPDF_PTRACE ((" HPDF_3DView_AddNode\n"));
351
352 if (view == NULL || opacity < 0 || opacity > 1 || name == NULL || name[0] == '\0') {
353 return HPDF_INVALID_U3D_DATA;
354 }
355
356 nodes = (HPDF_Array)HPDF_Dict_GetItem (view, "NA", HPDF_OCLASS_ARRAY);
357 if (nodes == NULL) {
358 nodes = HPDF_Array_New (view->mmgr);
359 if (!nodes) {
360 return HPDF_Error_GetCode (view->error);
361 }
362
363 ret = HPDF_Dict_Add (view, "NA", nodes);
364 if (ret != HPDF_OK) {
365 HPDF_Array_Free (nodes);
366 return ret;
367 }
368 }
369
370 node = HPDF_Dict_New (view->mmgr);
371 if (!node) {
372 HPDF_Array_Free (nodes);
373 return HPDF_Error_GetCode (view->error);
374 }
375
376 ret = HPDF_Dict_AddName (node, "Type", "3DNode");
377 if (ret != HPDF_OK) {
378 HPDF_Array_Free (nodes);
379 HPDF_Dict_Free (node);
380 return ret;
381 }
382
383 ret = HPDF_Dict_Add (node, "N", HPDF_String_New (view->mmgr, name, NULL));
384 if (ret != HPDF_OK) {
385 HPDF_Array_Free (nodes);
386 HPDF_Dict_Free (node);
387 return ret;
388 }
389
390 ret = HPDF_Dict_AddReal (node, "O", opacity);
391 if (ret != HPDF_OK) {
392 HPDF_Array_Free (nodes);
393 HPDF_Dict_Free (node);
394 return ret;
395 }
396
397 ret = HPDF_Dict_AddBoolean (node, "V", visible);
398 if (ret != HPDF_OK) {
399 HPDF_Dict_Free (node);
400 HPDF_Array_Free (nodes);
401 return ret;
402 }
403
404 ret = HPDF_Array_Add(nodes, node);
405 if (ret != HPDF_OK) {
406 HPDF_Dict_Free (node);
407 HPDF_Array_Free (nodes);
408 return ret;
409 }
410 return ret;
411}
412
413HPDF_EXPORT(HPDF_STATUS) HPDF_3DView_SetLighting(HPDF_Dict view, const char *scheme)
414{
415 HPDF_STATUS ret = HPDF_OK;
416 HPDF_Dict lighting;
417 int i;
418 static const char * const schemes[] =
419 { "Artwork", "None", "White", "Day", "Night", "Hard", "Primary", "Blue", "Red", "Cube", "CAD", "Headlamp" };
420
421 HPDF_PTRACE ((" HPDF_3DView_SetLighting\n"));
422
423 if (view == NULL || scheme == NULL || scheme[0] == '\0') {
424 return HPDF_INVALID_U3D_DATA;
425 }
426
427 for (i = 0; i < 12; i++) {
428 if (!strcmp(scheme, schemes[i])) {
429 break;
430 }
431 }
432
433 if (i == 12) {
434 return HPDF_INVALID_U3D_DATA;
435 }
436
437 lighting = HPDF_Dict_New (view->mmgr);
438 if (!lighting) {
439 return HPDF_Error_GetCode (view->error);
440 }
441
442 ret = HPDF_Dict_AddName (lighting, "Type", "3DLightingScheme");
443 if (ret != HPDF_OK) {
444 HPDF_Dict_Free (lighting);
445 return ret;
446 }
447
448 ret = HPDF_Dict_AddName (lighting, "Subtype", scheme);
449 if (ret != HPDF_OK) {
450 HPDF_Dict_Free (lighting);
451 return ret;
452 }
453
454 ret = HPDF_Dict_Add (view, "LS", lighting);
455 if (ret != HPDF_OK) {
456 HPDF_Dict_Free (lighting);
457 return ret;
458 }
459 return ret;
460}
461
462HPDF_EXPORT(HPDF_STATUS) HPDF_3DView_SetBackgroundColor(HPDF_Dict view, HPDF_REAL r, HPDF_REAL g, HPDF_REAL b)
463{
464 HPDF_Array color;
465 HPDF_STATUS ret = HPDF_OK;
466 HPDF_Dict background;
467
468 HPDF_PTRACE ((" HPDF_3DView_SetBackgroundColor\n"));
469
470 if (view == NULL || r < 0 || r > 1 || g < 0 || g > 1 || b < 0 || b > 1) {
471 return HPDF_INVALID_U3D_DATA;
472 }
473
474 background = HPDF_Dict_New (view->mmgr);
475 if (!background) {
476 return HPDF_Error_GetCode (view->error);
477 }
478
479 color = HPDF_Array_New (view->mmgr);
480 if (!color) {
481 HPDF_Dict_Free (background);
482 return HPDF_Error_GetCode (view->error);
483 }
484
485 ret = HPDF_Array_AddReal (color, r);
486 if (ret != HPDF_OK) {
487 HPDF_Array_Free (color);
488 HPDF_Dict_Free (background);
489 return ret;
490 }
491
492 ret = HPDF_Array_AddReal (color, g);
493 if (ret != HPDF_OK) {
494 HPDF_Array_Free (color);
495 HPDF_Dict_Free (background);
496 return ret;
497 }
498
499 ret = HPDF_Array_AddReal (color, b);
500 if (ret != HPDF_OK) {
501 HPDF_Array_Free (color);
502 HPDF_Dict_Free (background);
503 return ret;
504 }
505
506
507 ret = HPDF_Dict_AddName (background, "Type", "3DBG");
508 if (ret != HPDF_OK) {
509 HPDF_Array_Free (color);
510 HPDF_Dict_Free (background);
511 return ret;
512 }
513
514 ret = HPDF_Dict_Add (background, "C", color);
515 if (ret != HPDF_OK) {
516 HPDF_Array_Free (color);
517 HPDF_Dict_Free (background);
518 return ret;
519 }
520
521 ret = HPDF_Dict_Add (view, "BG", background);
522 if (ret != HPDF_OK) {
523 HPDF_Array_Free (color);
524 HPDF_Dict_Free (background);
525 return ret;
526 }
527 return ret;
528}
529
530HPDF_EXPORT(HPDF_STATUS) HPDF_3DView_SetPerspectiveProjection(HPDF_Dict view, HPDF_REAL fov)
531{
532 HPDF_STATUS ret = HPDF_OK;
533 HPDF_Dict projection;
534
535 HPDF_PTRACE ((" HPDF_3DView_SetPerspectiveProjection\n"));
536
537 if (view == NULL || fov < 0 || fov > 180) {
538 return HPDF_INVALID_U3D_DATA;
539 }
540
541 projection = HPDF_Dict_New (view->mmgr);
542 if (!projection) {
543 return HPDF_Error_GetCode (view->error);
544 }
545
546 ret = HPDF_Dict_AddName (projection, "Subtype", "P");
547 if (ret != HPDF_OK) {
548 HPDF_Dict_Free (projection);
549 return ret;
550 }
551
552 ret = HPDF_Dict_AddName (projection, "PS", "Min");
553 if (ret != HPDF_OK) {
554 HPDF_Dict_Free (projection);
555 return ret;
556 }
557
558 ret = HPDF_Dict_AddReal (projection, "FOV", fov);
559 if (ret != HPDF_OK) {
560 HPDF_Dict_Free (projection);
561 return ret;
562 }
563
564 ret = HPDF_Dict_Add (view, "P", projection);
565 if (ret != HPDF_OK) {
566 HPDF_Dict_Free (projection);
567 return ret;
568 }
569 return ret;
570}
571
572HPDF_EXPORT(HPDF_STATUS) HPDF_3DView_SetOrthogonalProjection(HPDF_Dict view, HPDF_REAL mag)
573{
574 HPDF_STATUS ret = HPDF_OK;
575 HPDF_Dict projection;
576
577 HPDF_PTRACE ((" HPDF_3DView_SetOrthogonalProjection\n"));
578
579 if (view == NULL || mag <= 0) {
580 return HPDF_INVALID_U3D_DATA;
581 }
582
583 projection = HPDF_Dict_New (view->mmgr);
584 if (!projection) {
585 return HPDF_Error_GetCode (view->error);
586 }
587
588 ret = HPDF_Dict_AddName (projection, "Subtype", "O");
589 if (ret != HPDF_OK) {
590 HPDF_Dict_Free (projection);
591 return ret;
592 }
593
594 ret = HPDF_Dict_AddReal (projection, "OS", mag);
595 if (ret != HPDF_OK) {
596 HPDF_Dict_Free (projection);
597 return ret;
598 }
599
600 ret = HPDF_Dict_Add (view, "P", projection);
601 if (ret != HPDF_OK) {
602 HPDF_Dict_Free (projection);
603 return ret;
604 }
605 return ret;
606}
607
608#define normalize(x, y, z) \
609{ \
610 HPDF_REAL modulo; \
611 modulo = (float)sqrt((float)(x*x) + (float)(y*y) + (float)(z*z)); \
612 if (modulo != 0.0) \
613 { \
614 x = x/modulo; \
615 y = y/modulo; \
616 z = z/modulo; \
617 } \
618}
619
620/* building the transformation matrix*/
621/* #1,#2,#3 centre of orbit coordinates (coo)*/
622/* #4,#5,#6 centre of orbit to camera direction vector (c2c)*/
623/* #7 orbital radius (roo)*/
624/* #8 camera roll (roll)*/
625
626HPDF_EXPORT(HPDF_STATUS) HPDF_3DView_SetCamera(HPDF_Dict view, HPDF_REAL coox, HPDF_REAL cooy, HPDF_REAL cooz, HPDF_REAL c2cx, HPDF_REAL c2cy, HPDF_REAL c2cz, HPDF_REAL roo, HPDF_REAL roll)
627{
628 HPDF_REAL viewx, viewy, viewz;
629 HPDF_REAL leftx, lefty, leftz;
630 HPDF_REAL upx, upy, upz;
631 HPDF_REAL transx, transy, transz;
632
633 HPDF_Array matrix;
634 HPDF_STATUS ret = HPDF_OK;
635
636 HPDF_PTRACE ((" HPDF_3DView_SetCamera\n"));
637
638 if (view == NULL) {
639 return HPDF_INVALID_U3D_DATA;
640 }
641
642 /* view vector (opposite to c2c) */
643 viewx = -c2cx;
644 viewy = -c2cy;
645 viewz = -c2cz;
646
647 /* c2c = (0, -1, 0) by default */
648 if (viewx == 0.0 && viewy == 0.0 && viewz == 0.0) {
649 viewy = 1.0;
650 }
651 /* normalize view vector */
652 normalize(viewx, viewy, viewz);
653
654 /* rotation matrix */
655
656 /* top and bottom views */
657 leftx = -1.0f;
658 lefty = 0.0f;
659 leftz = 0.0f;
660
661 /* up-vector */
662 if (viewz < 0.0) /* top view*/
663 {
664 upx = 0.0f;
665 upy = 1.0f;
666 upz = 0.0f;
667 }
668 else /* bottom view*/
669 {
670 upx = 0.0f;
671 upy =-1.0f;
672 upz = 0.0f;
673 }
674
675 if ( fabs(viewx) + fabs(viewy) != 0.0f) /* other views than top and bottom*/
676 {
677 /* up-vector = up_world - (up_world dot view) view*/
678 upx = -viewz*viewx;
679 upy = -viewz*viewy;
680 upz = -viewz*viewz + 1.0f;
681 /* normalize up-vector*/
682 normalize(upx, upy, upz);
683 /* left vector = up x view*/
684 leftx = viewz*upy - viewy*upz;
685 lefty = viewx*upz - viewz*upx;
686 leftz = viewy*upx - viewx*upy;
687 /* normalize left vector*/
688 normalize(leftx, lefty, leftz);
689 }
690 /* apply camera roll*/
691 {
692 HPDF_REAL leftxprime, leftyprime, leftzprime;
693 HPDF_REAL upxprime, upyprime, upzprime;
694 HPDF_REAL sinroll, cosroll;
695
696 sinroll = (HPDF_REAL)sin((roll/180.0f)*M_PI);
697 cosroll = (HPDF_REAL)cos((roll/180.0f)*M_PI);
698 leftxprime = leftx*cosroll + upx*sinroll;
699 leftyprime = lefty*cosroll + upy*sinroll;
700 leftzprime = leftz*cosroll + upz*sinroll;
701 upxprime = upx*cosroll + leftx*sinroll;
702 upyprime = upy*cosroll + lefty*sinroll;
703 upzprime = upz*cosroll + leftz*sinroll;
704 leftx = leftxprime;
705 lefty = leftyprime;
706 leftz = leftzprime;
707 upx = upxprime;
708 upy = upyprime;
709 upz = upzprime;
710 }
711
712 /* translation vector*/
713 roo = (HPDF_REAL)fabs(roo);
714 if (roo == 0.0) {
715 roo = (HPDF_REAL)0.000000000000000001;
716 }
717 transx = coox - roo*viewx;
718 transy = cooy - roo*viewy;
719 transz = cooz - roo*viewz;
720
721 /* transformation matrix*/
722 matrix = HPDF_Array_New (view->mmgr);
723 if (!matrix) {
724 return HPDF_Error_GetCode (view->error);
725 }
726
727 ret = HPDF_Array_AddReal (matrix, leftx);
728 if (ret != HPDF_OK) goto failed;
729
730 ret = HPDF_Array_AddReal (matrix, lefty);
731 if (ret != HPDF_OK) goto failed;
732
733 ret = HPDF_Array_AddReal (matrix, leftz);
734 if (ret != HPDF_OK) goto failed;
735
736 ret = HPDF_Array_AddReal (matrix, upx);
737 if (ret != HPDF_OK) goto failed;
738
739 ret = HPDF_Array_AddReal (matrix, upy);
740 if (ret != HPDF_OK) goto failed;
741
742 ret = HPDF_Array_AddReal (matrix, upz);
743 if (ret != HPDF_OK) goto failed;
744
745 ret = HPDF_Array_AddReal (matrix, viewx);
746 if (ret != HPDF_OK) goto failed;
747
748 ret = HPDF_Array_AddReal (matrix, viewy);
749 if (ret != HPDF_OK) goto failed;
750
751 ret = HPDF_Array_AddReal (matrix, viewz);
752 if (ret != HPDF_OK) goto failed;
753
754 ret = HPDF_Array_AddReal (matrix, transx);
755 if (ret != HPDF_OK) goto failed;
756
757 ret = HPDF_Array_AddReal (matrix, transy);
758 if (ret != HPDF_OK) goto failed;
759
760 ret = HPDF_Array_AddReal (matrix, transz);
761 if (ret != HPDF_OK) goto failed;
762
763 ret = HPDF_Dict_AddName (view, "MS", "M");
764 if (ret != HPDF_OK) goto failed;
765
766 ret = HPDF_Dict_Add (view, "C2W", matrix);
767 if (ret != HPDF_OK) goto failed;
768
769 ret = HPDF_Dict_AddNumber (view, "CO", (HPDF_INT32)roo);
770
771failed:
772 if (ret != HPDF_OK) {
773 HPDF_Array_Free (matrix);
774 return ret;
775 }
776 return ret;
777}
778
779HPDF_Dict HPDF_3DView_New( HPDF_MMgr mmgr, HPDF_Xref xref, HPDF_U3D u3d, const char *name)
780{
781 HPDF_STATUS ret = HPDF_OK;
782 HPDF_Dict view;
783
784 HPDF_PTRACE ((" HPDF_3DView_New\n"));
785
786 if (name == NULL || name[0] == '\0') {
787 return NULL;
788 }
789
790 view = HPDF_Dict_New (mmgr);
791 if (!view) {
792 return NULL;
793 }
794
795 if (HPDF_Xref_Add (xref, view) != HPDF_OK)
796 return NULL;
797
798 ret = HPDF_Dict_AddName (view, "TYPE", "3DView");
799 if (ret != HPDF_OK) {
800 HPDF_Dict_Free (view);
801 return NULL;
802 }
803
804 ret = HPDF_Dict_Add (view, "XN", HPDF_String_New (mmgr, name, NULL));
805 if (ret != HPDF_OK) {
806 HPDF_Dict_Free (view);
807 return NULL;
808 }
809
810 ret = HPDF_Dict_Add (view, "IN", HPDF_String_New (mmgr, name, NULL));
811 if (ret != HPDF_OK) {
812 HPDF_Dict_Free (view);
813 return NULL;
814 }
815
816 ret = HPDF_U3D_Add3DView( u3d, view);
817 if (ret != HPDF_OK) {
818 HPDF_Dict_Free (view);
819 return NULL;
820 }
821
822 return view;
823}
824
825
826HPDF_EXPORT(HPDF_STATUS)
827HPDF_3DView_Add3DC3DMeasure(HPDF_Dict view,
828 HPDF_3DMeasure measure)
829{
830
831 HPDF_STATUS ret = HPDF_OK;
832 HPDF_Array array;
833 void* a;
834
835 a = HPDF_Dict_GetItem (view, "MA", HPDF_OCLASS_ARRAY);
836
837 if ( a )
838 {
839 array = (HPDF_Array)a;
840 }
841 else
842 {
843 array = HPDF_Array_New (view->mmgr);
844 if (!array)
845 return 0;
846
847 if (HPDF_Dict_Add (view, "MA", array) != HPDF_OK)
848 return 0;
849 }
850
851 ret = HPDF_Array_Add(array, measure);
852
853 return ret;
854}
855
856
857HPDF_EXPORT(HPDF_JavaScript) HPDF_CreateJavaScript( HPDF_Doc pdf, const char *code )
858{
859 HPDF_JavaScript javaScript;
860 int len ;
861
862 HPDF_PTRACE ((" HPDF_CreateJavaScript\n"));
863
864 javaScript = (HPDF_JavaScript) HPDF_DictStream_New(pdf->mmgr, pdf->xref);
865 if (!javaScript) {
866 return NULL;
867 }
868
869 len = (HPDF_UINT)strlen(code);
870 if (HPDF_Stream_Write (javaScript->stream, (HPDF_BYTE *)code, len) != HPDF_OK) {
871 HPDF_Dict_Free(javaScript);
872 return NULL;
873 }
874
875 return javaScript;
876}
877
878
879#undef normalize
880
881