OSDN Git Service

binding with libharu.
[putex/putex.git] / src / texsourc / lib / libhpdf / src / hpdf_u3d.c
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
28 HPDF_U3D
29 HPDF_U3D_LoadU3D  (HPDF_MMgr        mmgr,
30                                    HPDF_Stream      u3d_data,
31                                    HPDF_Xref        xref);
32
33 static const char u3d[] = "U3D";
34 static const char prc[] = "PRC";
35
36 static 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
66 HPDF_U3D
67 HPDF_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
104 HPDF_EXPORT(HPDF_Image)
105 HPDF_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
135 HPDF_U3D
136 HPDF_U3D_LoadU3D   (HPDF_MMgr        mmgr,
137                                         HPDF_Stream      u3d_data,
138                                         HPDF_Xref        xref)
139 {
140         HPDF_Dict u3d;
141         const char *type;
142
143         HPDF_PTRACE ((" HPDF_U3D_LoadU3D\n"));
144
145         u3d = HPDF_DictStream_New (mmgr, xref);
146         if (!u3d) {
147                 return NULL;
148         }
149
150         u3d->header.obj_class |= HPDF_OSUBCLASS_XOBJECT;
151
152         /* add required elements */
153         u3d->filter = HPDF_STREAM_FILTER_NONE;
154
155         if (HPDF_Dict_AddName (u3d, "Type", "3D") != HPDF_OK) {
156                 HPDF_Dict_Free(u3d);
157                 return NULL;
158         }
159
160         if (Get3DStreamType (u3d_data, &type) != HPDF_OK) {
161                 HPDF_Dict_Free(u3d);
162                 return NULL;
163         }
164
165         if (HPDF_Dict_AddName (u3d, "Subtype", type) != HPDF_OK) {
166                 HPDF_Dict_Free(u3d);
167                 return NULL;
168         }
169
170         for (;;) {
171                 HPDF_BYTE buf[HPDF_STREAM_BUF_SIZ];
172                 HPDF_UINT len = HPDF_STREAM_BUF_SIZ;
173                 HPDF_STATUS ret = HPDF_Stream_Read (u3d_data, buf, &len);
174
175                 if (ret != HPDF_OK) {
176                         if (ret == HPDF_STREAM_EOF) {
177                                 if (len > 0) {
178                                         ret = HPDF_Stream_Write (u3d->stream, buf, len);
179                                         if (ret != HPDF_OK) {
180                                                 HPDF_Dict_Free(u3d);
181                                                 return NULL;
182                                         }
183                                 }
184                                 break;
185                         } else {
186                                 HPDF_Dict_Free(u3d);
187                                 return NULL;
188                         }
189                 }
190
191                 if (HPDF_Stream_Write (u3d->stream, buf, len) != HPDF_OK) {
192                         HPDF_Dict_Free(u3d);
193                         return NULL;
194                 }
195         }
196
197         return u3d;
198 }
199
200 HPDF_EXPORT(HPDF_Dict) HPDF_Create3DView(HPDF_MMgr mmgr, const char *name)
201 {
202         HPDF_STATUS ret = HPDF_OK;
203         HPDF_Dict view;
204
205         HPDF_PTRACE ((" HPDF_Create3DView\n"));
206
207         if (name == NULL || name[0] == '\0') { 
208                 return NULL;
209         }
210
211         view = HPDF_Dict_New (mmgr);
212         if (!view) {
213                 return NULL;
214         }
215
216         ret = HPDF_Dict_AddName (view, "TYPE", "3DView");
217         if (ret != HPDF_OK) {
218                 HPDF_Dict_Free (view);
219                 return NULL;
220         }
221         
222         ret = HPDF_Dict_Add (view, "XN", HPDF_String_New (mmgr, name, NULL));
223         if (ret != HPDF_OK) {
224                 HPDF_Dict_Free (view);
225                 return NULL;
226         }
227
228         ret = HPDF_Dict_Add (view, "IN", HPDF_String_New (mmgr, name, NULL));
229         if (ret != HPDF_OK) {
230                 HPDF_Dict_Free (view);
231                 return NULL;
232         }
233
234         return view;
235 }
236
237 HPDF_EXPORT(HPDF_STATUS) HPDF_U3D_Add3DView(HPDF_U3D u3d, HPDF_Dict view)
238 {
239         HPDF_Array views = NULL;
240         HPDF_STATUS ret = HPDF_OK;
241
242         HPDF_PTRACE ((" HPDF_Add3DView\n"));
243
244         if (u3d == NULL || view == NULL) {
245                 return HPDF_INVALID_U3D_DATA;
246         }
247
248         views = (HPDF_Array)HPDF_Dict_GetItem (u3d, "VA", HPDF_OCLASS_ARRAY);
249         if (views == NULL) {
250                 views = HPDF_Array_New (u3d->mmgr);
251                 if (!views) {
252                         return HPDF_Error_GetCode (u3d->error);
253                 }
254
255                 ret = HPDF_Dict_Add (u3d, "VA", views);
256                 if (ret == HPDF_OK) {
257                         ret = HPDF_Dict_AddNumber (u3d, "DV", 0);
258                 } else {
259                         HPDF_Array_Free (views);
260                         return ret;
261                 }
262         }
263
264         if (ret == HPDF_OK) {
265                 ret = HPDF_Array_Add( views, view);
266         }
267
268         return ret;
269 }
270
271
272 HPDF_EXPORT(HPDF_STATUS) HPDF_U3D_AddOnInstanciate(HPDF_U3D u3d, HPDF_JavaScript javascript)
273 {
274         HPDF_STATUS ret = HPDF_OK;
275
276         HPDF_PTRACE ((" HPDF_U3D_AddOnInstanciate\n"));
277
278         if (u3d == NULL || javascript == NULL) {
279                 return HPDF_INVALID_U3D_DATA;
280         }
281
282         ret = HPDF_Dict_Add(u3d, "OnInstantiate", javascript);
283
284         return ret;
285 }
286
287
288 HPDF_EXPORT(HPDF_STATUS) HPDF_U3D_SetDefault3DView(HPDF_U3D u3d, const char *name)
289 {
290         HPDF_STATUS ret = HPDF_OK;
291
292         HPDF_PTRACE ((" HPDF_U3D_SetDefault3DView\n"));
293
294         if (u3d == NULL || name == NULL || name[0] == '\0') {
295                 return HPDF_INVALID_U3D_DATA;
296         }
297
298         ret = HPDF_Dict_Add (u3d, "DV", HPDF_String_New (u3d->mmgr, name, NULL));
299         return ret;
300 }
301
302 HPDF_EXPORT(HPDF_STATUS) HPDF_3DView_AddNode(HPDF_Dict view, const char *name, HPDF_REAL opacity, HPDF_BOOL visible)
303 {
304         HPDF_Array nodes = NULL;
305         HPDF_Dict  node; 
306         HPDF_STATUS ret = HPDF_OK;
307
308         HPDF_PTRACE ((" HPDF_3DView_AddNode\n"));
309
310         if (view == NULL || opacity < 0 || opacity > 1 || name == NULL || name[0] == '\0') {
311                 return HPDF_INVALID_U3D_DATA;
312         }
313
314         nodes = (HPDF_Array)HPDF_Dict_GetItem (view, "NA", HPDF_OCLASS_ARRAY);
315         if (nodes == NULL) {
316                 nodes = HPDF_Array_New (view->mmgr);
317                 if (!nodes) {
318                         return HPDF_Error_GetCode (view->error);
319                 }
320
321                 ret = HPDF_Dict_Add (view, "NA", nodes);
322                 if (ret != HPDF_OK) {
323                         HPDF_Array_Free (nodes);
324                         return ret;
325                 }
326         }
327
328         node = HPDF_Dict_New (view->mmgr);
329         if (!node) {
330                 HPDF_Array_Free (nodes);
331                 return HPDF_Error_GetCode (view->error);
332         }
333
334         ret = HPDF_Dict_AddName (node, "Type", "3DNode");
335         if (ret != HPDF_OK) {
336                 HPDF_Array_Free (nodes);
337                 HPDF_Dict_Free (node);
338                 return ret;
339         }
340
341         ret = HPDF_Dict_Add (node, "N", HPDF_String_New (view->mmgr, name, NULL));
342         if (ret != HPDF_OK) {
343                 HPDF_Array_Free (nodes);
344                 HPDF_Dict_Free (node);
345                 return ret;
346         }
347
348         ret = HPDF_Dict_AddReal (node, "O", opacity);
349         if (ret != HPDF_OK) {
350                 HPDF_Array_Free (nodes);
351                 HPDF_Dict_Free (node);
352                 return ret;
353         }
354
355         ret = HPDF_Dict_AddBoolean (node, "V", visible);
356         if (ret != HPDF_OK) {
357                 HPDF_Dict_Free (node);
358                 HPDF_Array_Free (nodes);
359                 return ret;
360         }
361
362         ret = HPDF_Array_Add(nodes, node);
363         if (ret != HPDF_OK) {
364                 HPDF_Dict_Free (node);
365                 HPDF_Array_Free (nodes);
366                 return ret;
367         }
368         return ret;
369 }
370
371 HPDF_EXPORT(HPDF_STATUS) HPDF_3DView_SetLighting(HPDF_Dict view, const char *scheme)
372 {
373         HPDF_STATUS ret = HPDF_OK;
374         HPDF_Dict lighting;
375         int i;
376         static const char * const schemes[] =
377         { "Artwork", "None", "White", "Day", "Night", "Hard", "Primary", "Blue", "Red", "Cube", "CAD", "Headlamp" };
378
379         HPDF_PTRACE ((" HPDF_3DView_SetLighting\n"));
380
381         if (view == NULL || scheme == NULL || scheme[0] == '\0') {
382                 return HPDF_INVALID_U3D_DATA;
383         }
384
385         for (i = 0; i < 12; i++) {
386                 if (!strcmp(scheme, schemes[i])) {
387                         break;
388                 }
389         }
390
391         if (i == 12) {
392                 return HPDF_INVALID_U3D_DATA;
393         }
394
395         lighting = HPDF_Dict_New (view->mmgr);
396         if (!lighting) {
397                 return HPDF_Error_GetCode (view->error);
398         }
399
400         ret = HPDF_Dict_AddName (lighting, "Type", "3DLightingScheme");
401         if (ret != HPDF_OK) {
402                 HPDF_Dict_Free (lighting);
403                 return ret;
404         }
405
406         ret = HPDF_Dict_AddName (lighting, "Subtype", scheme);
407         if (ret != HPDF_OK) {
408                 HPDF_Dict_Free (lighting);
409                 return ret;
410         }
411
412         ret = HPDF_Dict_Add (view, "LS", lighting);
413         if (ret != HPDF_OK) {
414                 HPDF_Dict_Free (lighting);
415                 return ret;
416         }
417         return ret;
418 }
419
420 HPDF_EXPORT(HPDF_STATUS) HPDF_3DView_SetBackgroundColor(HPDF_Dict view, HPDF_REAL r, HPDF_REAL g, HPDF_REAL b)
421 {
422         HPDF_Array  color; 
423         HPDF_STATUS ret = HPDF_OK;
424         HPDF_Dict background;
425
426         HPDF_PTRACE ((" HPDF_3DView_SetBackgroundColor\n"));
427
428         if (view == NULL || r < 0 || r > 1 || g < 0 || g > 1 || b < 0 || b > 1) {
429                 return HPDF_INVALID_U3D_DATA;
430         }
431
432         background = HPDF_Dict_New (view->mmgr);
433         if (!background) {
434                 return HPDF_Error_GetCode (view->error);
435         }
436
437         color = HPDF_Array_New (view->mmgr);
438         if (!color) {
439                 HPDF_Dict_Free (background);
440                 return HPDF_Error_GetCode (view->error);
441         }
442
443         ret = HPDF_Array_AddReal (color, r);
444         if (ret != HPDF_OK) {
445                 HPDF_Array_Free (color);
446                 HPDF_Dict_Free (background);
447                 return ret;
448         }
449
450         ret = HPDF_Array_AddReal (color, g);
451         if (ret != HPDF_OK) {
452                 HPDF_Array_Free (color);
453                 HPDF_Dict_Free (background);
454                 return ret;
455         }
456
457         ret = HPDF_Array_AddReal (color, b);
458         if (ret != HPDF_OK) {
459                 HPDF_Array_Free (color);
460                 HPDF_Dict_Free (background);
461                 return ret;
462         }
463
464
465         ret = HPDF_Dict_AddName (background, "Type", "3DBG");
466         if (ret != HPDF_OK) {
467                 HPDF_Array_Free (color);
468                 HPDF_Dict_Free (background);
469                 return ret;
470         }
471
472         ret = HPDF_Dict_Add (background, "C", color);
473         if (ret != HPDF_OK) {
474                 HPDF_Array_Free (color);
475                 HPDF_Dict_Free (background);
476                 return ret;
477         }
478
479         ret = HPDF_Dict_Add (view, "BG", background);
480         if (ret != HPDF_OK) {
481                 HPDF_Array_Free (color);
482                 HPDF_Dict_Free (background);
483                 return ret;
484         }
485         return ret;
486 }
487
488 HPDF_EXPORT(HPDF_STATUS) HPDF_3DView_SetPerspectiveProjection(HPDF_Dict view, HPDF_REAL fov)
489 {
490         HPDF_STATUS ret = HPDF_OK;
491         HPDF_Dict projection;
492
493         HPDF_PTRACE ((" HPDF_3DView_SetPerspectiveProjection\n"));
494
495         if (view == NULL || fov < 0 || fov > 180) {
496                 return HPDF_INVALID_U3D_DATA;
497         }
498
499         projection = HPDF_Dict_New (view->mmgr);
500         if (!projection) {
501                 return HPDF_Error_GetCode (view->error);
502         }
503
504         ret = HPDF_Dict_AddName (projection, "Subtype", "P");
505         if (ret != HPDF_OK) {
506                 HPDF_Dict_Free (projection);
507                 return ret;
508         }
509
510         ret = HPDF_Dict_AddName (projection, "PS", "Min");
511         if (ret != HPDF_OK) {
512                 HPDF_Dict_Free (projection);
513                 return ret;
514         }
515
516         ret = HPDF_Dict_AddReal (projection, "FOV", fov);
517         if (ret != HPDF_OK) {
518                 HPDF_Dict_Free (projection);
519                 return ret;
520         }
521
522         ret = HPDF_Dict_Add (view, "P", projection);
523         if (ret != HPDF_OK) {
524                 HPDF_Dict_Free (projection);
525                 return ret;
526         }
527         return ret;
528 }
529
530 HPDF_EXPORT(HPDF_STATUS) HPDF_3DView_SetOrthogonalProjection(HPDF_Dict view, HPDF_REAL mag)
531 {
532         HPDF_STATUS ret = HPDF_OK;
533         HPDF_Dict projection;
534
535         HPDF_PTRACE ((" HPDF_3DView_SetOrthogonalProjection\n"));
536
537         if (view == NULL || mag <= 0) {
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", "O");
547         if (ret != HPDF_OK) {
548                 HPDF_Dict_Free (projection);
549                 return ret;
550         }
551
552         ret = HPDF_Dict_AddReal (projection, "OS", mag);
553         if (ret != HPDF_OK) {
554                 HPDF_Dict_Free (projection);
555                 return ret;
556         }
557
558         ret = HPDF_Dict_Add (view, "P", projection);
559         if (ret != HPDF_OK) {
560                 HPDF_Dict_Free (projection);
561                 return ret;
562         }
563         return ret;
564 }
565
566 #define normalize(x, y, z)              \
567 {                                       \
568         HPDF_REAL modulo;                       \
569         modulo = (float)sqrt((float)(x*x) + (float)(y*y) + (float)(z*z));       \
570         if (modulo != 0.0)                      \
571         {                                       \
572                 x = x/modulo;                   \
573                 y = y/modulo;                   \
574                 z = z/modulo;                   \
575         }                                       \
576 }
577
578 /* building the transformation matrix*/
579 /* #1,#2,#3 centre of orbit coordinates (coo)*/
580 /* #4,#5,#6 centre of orbit to camera direction vector (c2c)*/
581 /* #7 orbital radius (roo)*/
582 /* #8 camera roll (roll)*/
583
584 HPDF_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)
585 {
586         HPDF_REAL viewx, viewy, viewz;
587         HPDF_REAL leftx, lefty, leftz;
588         HPDF_REAL upx, upy, upz;
589         HPDF_REAL transx, transy, transz;
590
591         HPDF_Array  matrix; 
592         HPDF_STATUS ret = HPDF_OK;
593
594         HPDF_PTRACE ((" HPDF_3DView_SetCamera\n"));
595
596         if (view == NULL) {
597                 return HPDF_INVALID_U3D_DATA;
598         }
599
600         /* view vector (opposite to c2c) */
601         viewx = -c2cx;
602         viewy = -c2cy;
603         viewz = -c2cz;
604         
605         /* c2c = (0, -1, 0) by default */
606         if (viewx == 0.0 && viewy == 0.0 && viewz == 0.0) {
607                 viewy = 1.0;
608         }
609         /* normalize view vector */
610         normalize(viewx, viewy, viewz);
611
612         /* rotation matrix */
613
614         /* top and bottom views */
615         leftx = -1.0f;
616         lefty =  0.0f;
617         leftz =  0.0f;
618
619         /* up-vector */
620         if (viewz < 0.0) /* top view*/
621         {
622                 upx = 0.0f;
623                 upy = 1.0f;
624                 upz = 0.0f;
625         }
626         else /* bottom view*/
627         {
628                 upx = 0.0f;
629                 upy =-1.0f;
630                 upz = 0.0f;
631         }
632         
633         if ( fabs(viewx) + fabs(viewy) != 0.0f) /* other views than top and bottom*/
634         {
635                 /* up-vector = up_world - (up_world dot view) view*/
636                 upx = -viewz*viewx;
637                 upy = -viewz*viewy;
638                 upz = -viewz*viewz + 1.0f;
639                 /* normalize up-vector*/
640                 normalize(upx, upy, upz);
641                 /* left vector = up x view*/
642                 leftx = viewz*upy - viewy*upz;
643                 lefty = viewx*upz - viewz*upx;
644                 leftz = viewy*upx - viewx*upy;
645                 /* normalize left vector*/
646                 normalize(leftx, lefty, leftz);
647         }
648         /* apply camera roll*/
649         {
650                 HPDF_REAL leftxprime, leftyprime, leftzprime;
651                 HPDF_REAL upxprime, upyprime, upzprime;
652                 HPDF_REAL sinroll, cosroll;
653
654                 sinroll =  (HPDF_REAL)sin((roll/180.0f)*M_PI);
655                 cosroll =  (HPDF_REAL)cos((roll/180.0f)*M_PI);
656                 leftxprime = leftx*cosroll + upx*sinroll;
657                 leftyprime = lefty*cosroll + upy*sinroll;
658                 leftzprime = leftz*cosroll + upz*sinroll;
659                 upxprime = upx*cosroll + leftx*sinroll;
660                 upyprime = upy*cosroll + lefty*sinroll;
661                 upzprime = upz*cosroll + leftz*sinroll;
662                 leftx = leftxprime;
663                 lefty = leftyprime;
664                 leftz = leftzprime;
665                 upx = upxprime;
666                 upy = upyprime;
667                 upz = upzprime;
668         }
669         
670         /* translation vector*/
671         roo = (HPDF_REAL)fabs(roo);
672         if (roo == 0.0) {
673                 roo = (HPDF_REAL)0.000000000000000001;
674         }
675         transx = coox - roo*viewx;
676         transy = cooy - roo*viewy;
677         transz = cooz - roo*viewz;
678
679         /* transformation matrix*/
680         matrix = HPDF_Array_New (view->mmgr);
681         if (!matrix) {
682                 return HPDF_Error_GetCode (view->error);
683         }
684
685         ret = HPDF_Array_AddReal (matrix, leftx);
686         if (ret != HPDF_OK) goto failed;
687
688         ret = HPDF_Array_AddReal (matrix, lefty);
689         if (ret != HPDF_OK) goto failed;
690
691         ret = HPDF_Array_AddReal (matrix, leftz);
692         if (ret != HPDF_OK) goto failed;
693
694         ret = HPDF_Array_AddReal (matrix, upx);
695         if (ret != HPDF_OK) goto failed;
696
697         ret = HPDF_Array_AddReal (matrix, upy);
698         if (ret != HPDF_OK) goto failed;
699
700         ret = HPDF_Array_AddReal (matrix, upz);
701         if (ret != HPDF_OK) goto failed;
702
703         ret = HPDF_Array_AddReal (matrix, viewx);
704         if (ret != HPDF_OK) goto failed;
705
706         ret = HPDF_Array_AddReal (matrix, viewy);
707         if (ret != HPDF_OK) goto failed;
708
709         ret = HPDF_Array_AddReal (matrix, viewz);
710         if (ret != HPDF_OK) goto failed;
711
712         ret = HPDF_Array_AddReal (matrix, transx);
713         if (ret != HPDF_OK) goto failed;
714
715         ret = HPDF_Array_AddReal (matrix, transy);
716         if (ret != HPDF_OK) goto failed;
717
718         ret = HPDF_Array_AddReal (matrix, transz);
719         if (ret != HPDF_OK) goto failed;
720
721         ret = HPDF_Dict_AddName (view, "MS", "M");
722         if (ret != HPDF_OK) goto failed;
723
724         ret = HPDF_Dict_Add (view, "C2W", matrix);
725         if (ret != HPDF_OK) goto failed;
726
727         ret = HPDF_Dict_AddNumber (view, "CO", (HPDF_INT32)roo);
728
729 failed:
730         if (ret != HPDF_OK) {
731                 HPDF_Array_Free (matrix);
732                 return ret;
733         }
734         return ret;
735 }
736
737 HPDF_Dict HPDF_3DView_New( HPDF_MMgr  mmgr, HPDF_Xref  xref, HPDF_U3D u3d, const char *name)
738 {
739         HPDF_STATUS ret = HPDF_OK;
740         HPDF_Dict view;
741
742         HPDF_PTRACE ((" HPDF_3DView_New\n"));
743
744         if (name == NULL || name[0] == '\0') { 
745                 return NULL;
746         }
747
748         view = HPDF_Dict_New (mmgr);
749         if (!view) {
750                 return NULL;
751         }
752
753         if (HPDF_Xref_Add (xref, view) != HPDF_OK)
754         return NULL;
755
756         ret = HPDF_Dict_AddName (view, "TYPE", "3DView");
757         if (ret != HPDF_OK) {
758                 HPDF_Dict_Free (view);
759                 return NULL;
760         }
761         
762         ret = HPDF_Dict_Add (view, "XN", HPDF_String_New (mmgr, name, NULL));
763         if (ret != HPDF_OK) {
764                 HPDF_Dict_Free (view);
765                 return NULL;
766         }
767
768         ret = HPDF_Dict_Add (view, "IN", HPDF_String_New (mmgr, name, NULL));
769         if (ret != HPDF_OK) {
770                 HPDF_Dict_Free (view);
771                 return NULL;
772         }
773
774         ret = HPDF_U3D_Add3DView( u3d, view);
775         if (ret != HPDF_OK) {
776                 HPDF_Dict_Free (view);
777                 return NULL;
778         }
779
780         return view;
781 }
782
783
784 HPDF_EXPORT(HPDF_STATUS)
785 HPDF_3DView_Add3DC3DMeasure(HPDF_Dict       view,
786                                                         HPDF_3DMeasure measure)
787 {
788
789         HPDF_STATUS ret = HPDF_OK;
790         HPDF_Array array;
791         void* a;
792
793         a = HPDF_Dict_GetItem (view, "MA", HPDF_OCLASS_ARRAY);
794
795         if ( a )
796         {
797                 array = (HPDF_Array)a;
798         }
799         else
800         {
801                 array = HPDF_Array_New (view->mmgr);
802                 if (!array)
803                         return 0;
804
805                 if (HPDF_Dict_Add (view, "MA", array) != HPDF_OK)
806                         return 0;
807         }
808
809         ret = HPDF_Array_Add(array, measure);
810
811         return ret;
812 }
813
814
815 HPDF_EXPORT(HPDF_JavaScript) HPDF_CreateJavaScript( HPDF_Doc pdf, const char *code )
816 {
817         HPDF_JavaScript javaScript;
818         int len ;
819
820         HPDF_PTRACE ((" HPDF_CreateJavaScript\n"));
821
822         javaScript = (HPDF_JavaScript) HPDF_DictStream_New(pdf->mmgr, pdf->xref);
823         if (!javaScript) {
824                 return NULL;
825         }
826
827         len = (HPDF_UINT)strlen(code);
828         if (HPDF_Stream_Write (javaScript->stream, (HPDF_BYTE *)code, len) != HPDF_OK) {
829                 HPDF_Dict_Free(javaScript);
830                 return NULL;
831         }
832
833         return javaScript;
834 }
835
836
837 #undef normalize
838