~ubuntu-branches/debian/experimental/gpac/experimental

« back to all changes in this revision

Viewing changes to src/scene_manager/swf_svg.c

  • Committer: Package Import Robot
  • Author(s): Reinhard Tartler
  • Date: 2014-02-22 18:15:00 UTC
  • mfrom: (1.2.2) (3.1.6 sid)
  • Revision ID: package-import@ubuntu.com-20140222181500-b4phupo05gjpmopa
Tags: 0.5.0+svn5104~dfsg1-1
* New  upstream version 0.5.0+svn5104~dfsg1:
  - src/utils/sha1.c is relicensed under LGPLv2.1, Closes: #730759
* Don't install modules in multi-arch directories, Closes: #730497
* Add libusb-1.0.0-dev headers because libfreenect requires this
* Fix install rule
* Follow upstream soname bump
  - Drop the symbols file for now until it has been revised thourougly
* Let binaries produce the correct svn revision
* Refresh patches
* Patch and build against libav10, Closes: #739321
* Bump standards version, no changes necessary

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
/*
2
 
 *          GPAC - Multimedia Framework C SDK
3
 
 *
4
 
 *          Authors: Cyril Concolato
5
 
 *          Copyright (c) Telecom ParisTech 2000-2012
6
 
 *                  All rights reserved
7
 
 *
8
 
 *  This file is part of GPAC / Scene Management sub-project
9
 
 *
10
 
 *  GPAC is free software; you can redistribute it and/or modify
11
 
 *  it under the terms of the GNU Lesser General Public License as published by
12
 
 *  the Free Software Foundation; either version 2, or (at your option)
13
 
 *  any later version.
14
 
 *   
15
 
 *  GPAC is distributed in the hope that it will be useful,
16
 
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
17
 
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18
 
 *  GNU Lesser General Public License for more details.
19
 
 *   
20
 
 *  You should have received a copy of the GNU Lesser General Public
21
 
 *  License along with this library; see the file COPYING.  If not, write to
22
 
 *  the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. 
23
 
 *
24
 
 */
25
 
#include <gpac/utf.h>
26
 
#include <gpac/xml.h>
27
 
#include <gpac/internal/swf_dev.h>
28
 
#include <gpac/internal/scenegraph_dev.h>
29
 
 
30
 
#ifndef GPAC_DISABLE_VRML
31
 
 
32
 
#ifndef GPAC_DISABLE_SWF_IMPORT
33
 
 
34
 
#define SWF_TEXT_SCALE              (1/1024.0f)
35
 
 
36
 
typedef struct
37
 
{
38
 
    u32 btn_id;
39
 
    u32 sprite_up_id;
40
 
} s2sBtnRec;
41
 
 
42
 
static void swf_svg_print_color(SWFReader *read, u32 ARGB)
43
 
{
44
 
    SFColor val;
45
 
    val.red = INT2FIX((ARGB>>16)&0xFF) / 255*100;
46
 
    val.green = INT2FIX((ARGB>>8)&0xFF) / 255*100;
47
 
    val.blue = INT2FIX((ARGB)&0xFF) / 255*100;
48
 
    fprintf(read->svg_output, "rgb(%f%%,%f%%,%f%%)", FIX2FLT(val.red), FIX2FLT(val.green), FIX2FLT(val.blue));
49
 
}
50
 
 
51
 
static void swf_svg_print_alpha(SWFReader *read, u32 ARGB)
52
 
{
53
 
    Fixed alpha;
54
 
    alpha = INT2FIX((ARGB>>24)&0xFF)/255;
55
 
    fprintf(read->svg_output, "%f", FIX2FLT(alpha));
56
 
}
57
 
 
58
 
static void swg_svg_print_shape_record_to_fill_stroke(SWFReader *read, SWFShapeRec *srec, Bool is_fill)
59
 
{
60
 
        /*get regular appearance reuse*/
61
 
        if (is_fill) {
62
 
                switch (srec->type) {
63
 
                /*solid/alpha fill*/
64
 
                case 0x00:
65
 
            fprintf(read->svg_output, "fill=\"");
66
 
            swf_svg_print_color(read, srec->solid_col);
67
 
            fprintf(read->svg_output, "\" ");
68
 
            fprintf(read->svg_output, "fill-opacity=\"");
69
 
            swf_svg_print_alpha(read, srec->solid_col);
70
 
            fprintf(read->svg_output, "\" ");
71
 
                        break;
72
 
                case 0x10:
73
 
                case 0x12:
74
 
                        //if (read->flags & GF_SM_SWF_NO_GRADIENT) {
75
 
                        //      u32 col = srec->grad_col[srec->nbGrad/2];
76
 
                        //      col |= 0xFF000000;
77
 
                        //      n->appearance = s2b_get_appearance(read, (GF_Node *) n, col, 0, 0);
78
 
                        //} else {
79
 
                        //      n->appearance = s2b_get_gradient(read, (GF_Node *) n, shape, srec);
80
 
                        //}
81
 
                        //break;
82
 
                case 0x40:
83
 
                case 0x41:
84
 
                case 0x42:
85
 
                case 0x43:
86
 
                        //n->appearance = s2b_get_bitmap(read, (GF_Node *) n, shape, srec);
87
 
                        //break;
88
 
                default:
89
 
                        swf_report(read, GF_NOT_SUPPORTED, "fill_style %x not supported", srec->type);
90
 
                        break;
91
 
                }
92
 
        } else {
93
 
        fprintf(read->svg_output, "fill=\"none\" ");
94
 
        fprintf(read->svg_output, "stroke=\"");
95
 
        swf_svg_print_color(read, srec->solid_col);
96
 
        fprintf(read->svg_output, "\" ");
97
 
        fprintf(read->svg_output, "stroke-opacity=\"");
98
 
        swf_svg_print_alpha(read, srec->solid_col);
99
 
        fprintf(read->svg_output, "\" ");
100
 
        fprintf(read->svg_output, "stroke-width=\"%f\" ", FIX2FLT(srec->width));
101
 
        }
102
 
}
103
 
 
104
 
static void swf_svg_print_shape_record_to_path_d(SWFReader *read, SWFShapeRec *srec) 
105
 
{
106
 
    u32     pt_idx;
107
 
    u32     i;
108
 
 
109
 
    pt_idx = 0;
110
 
    for (i=0; i<srec->path->nbType; i++) {
111
 
        switch (srec->path->types[i]) {
112
 
        /*moveTo*/
113
 
        case 0:
114
 
            fprintf(read->svg_output, "M%f,%f", FIX2FLT(srec->path->pts[pt_idx].x), FIX2FLT(srec->path->pts[pt_idx].y));
115
 
            pt_idx++;
116
 
            break;
117
 
        /*lineTo*/
118
 
        case 1:
119
 
            fprintf(read->svg_output, "L%f,%f", FIX2FLT(srec->path->pts[pt_idx].x), FIX2FLT(srec->path->pts[pt_idx].y));
120
 
            pt_idx++;
121
 
            break;
122
 
        /*curveTo*/
123
 
        case 2:
124
 
            fprintf(read->svg_output, "Q%f,%f", FIX2FLT(srec->path->pts[pt_idx].x), FIX2FLT(srec->path->pts[pt_idx].y));
125
 
            pt_idx++;
126
 
            fprintf(read->svg_output, ",%f,%f", FIX2FLT(srec->path->pts[pt_idx].x), FIX2FLT(srec->path->pts[pt_idx].y));
127
 
            pt_idx++;
128
 
            break;
129
 
        }
130
 
    }
131
 
}
132
 
 
133
 
static void swf_svg_print_matrix(SWFReader *read, GF_Matrix2D *mat)
134
 
{
135
 
    if (!gf_mx2d_is_identity(*mat))
136
 
    {
137
 
        GF_Point2D  scale;
138
 
        GF_Point2D  translate;
139
 
        Fixed       rotate;
140
 
        if( gf_mx2d_decompose(mat, &scale, &rotate, &translate)) 
141
 
        {
142
 
            fprintf(read->svg_output, "transform=\"");
143
 
            if (translate.x != 0 || translate.y != 0)
144
 
            {
145
 
                fprintf(read->svg_output, "translate(%f, %f) ", translate.x, translate.y);
146
 
            }
147
 
            if (rotate != 0)
148
 
            {
149
 
                fprintf(read->svg_output, "rotate(%f) ", rotate);
150
 
            }
151
 
            if (scale.x != FIX_ONE || scale.y != FIX_ONE)
152
 
            {
153
 
                fprintf(read->svg_output, "scale(%f, %f) ", scale.x, scale.y);
154
 
            }
155
 
            fprintf(read->svg_output, "\" ");
156
 
        } 
157
 
        else 
158
 
        {
159
 
            fprintf(read->svg_output, "transform=\"matrix(%f,%f,%f,%f,%f,%f)\" ", mat->m[0], mat->m[3], mat->m[1], mat->m[4], mat->m[2], mat->m[5]);
160
 
        }
161
 
    }
162
 
}
163
 
 
164
 
/*translates Flash to SVG shapes*/
165
 
static GF_Err swf_svg_define_shape(SWFReader *read, SWFShape *shape, SWFFont *parent_font, Bool last_sub_shape)
166
 
{
167
 
    u32 i;
168
 
    SWFShapeRec *srec;
169
 
 
170
 
    if (parent_font && (read->flags & GF_SM_SWF_NO_FONT)) 
171
 
    {
172
 
        return GF_OK;
173
 
    }
174
 
 
175
 
    if (!read->cur_shape) 
176
 
    {
177
 
        fprintf(read->svg_output, "<defs>\n");
178
 
        if (!parent_font)
179
 
        {
180
 
            fprintf(read->svg_output, "<g id=\"S%d\" >\n", shape->ID);
181
 
        }
182
 
        else
183
 
        {
184
 
            char    szGlyphId[256];
185
 
            sprintf(szGlyphId, "Font%d_Glyph%d", parent_font->fontID, gf_list_count(parent_font->glyphs));
186
 
            fprintf(read->svg_output, "<g id=\"%s\" >\n", szGlyphId);
187
 
            gf_list_add(parent_font->glyphs, szGlyphId);
188
 
        }
189
 
    }
190
 
    read->cur_shape = (GF_Node *)"shape";
191
 
 
192
 
    i=0;
193
 
    while ((srec = (SWFShapeRec*)gf_list_enum(shape->fill_left, &i))) {
194
 
        fprintf(read->svg_output, "<path d=\"");
195
 
        swf_svg_print_shape_record_to_path_d(read, srec);
196
 
        fprintf(read->svg_output, "\" ");
197
 
        swg_svg_print_shape_record_to_fill_stroke(read, srec, 1);
198
 
        fprintf(read->svg_output, "/>\n");
199
 
    }
200
 
    i=0;
201
 
    while ((srec = (SWFShapeRec*)gf_list_enum(shape->lines, &i))) {
202
 
        fprintf(read->svg_output, "<path d=\"");
203
 
        swf_svg_print_shape_record_to_path_d(read, srec);
204
 
        fprintf(read->svg_output, "\" ");
205
 
        swg_svg_print_shape_record_to_fill_stroke(read, srec, 0);
206
 
        fprintf(read->svg_output, "/>\n");
207
 
    }
208
 
 
209
 
    if (last_sub_shape) 
210
 
    {
211
 
        read->cur_shape = NULL;
212
 
        fprintf(read->svg_output, "</g>\n");
213
 
        fprintf(read->svg_output, "</defs>\n");
214
 
    }
215
 
    return GF_OK;
216
 
}
217
 
 
218
 
static GF_Err swf_svg_define_text(SWFReader *read, SWFText *text)
219
 
{
220
 
    Bool            use_text;
221
 
    u32             i;
222
 
    u32             j;
223
 
    SWFGlyphRec     *gr;
224
 
    SWFFont         *ft;
225
 
 
226
 
    use_text = (read->flags & GF_SM_SWF_NO_FONT) ? 1 : 0;
227
 
 
228
 
    fprintf(read->svg_output, "<defs>\n");
229
 
    fprintf(read->svg_output, "<g id=\"S%d\" ", text->ID);
230
 
    swf_svg_print_matrix(read, &text->mat);
231
 
    fprintf(read->svg_output, ">\n");
232
 
 
233
 
    i=0;
234
 
    while ((gr = (SWFGlyphRec*)gf_list_enum(text->text, &i))) 
235
 
    {
236
 
        ft = NULL;
237
 
        if (use_text) {
238
 
            ft = swf_find_font(read, gr->fontID);
239
 
            if (!ft->glyph_codes) {
240
 
                use_text = 0;
241
 
                swf_report(read, GF_BAD_PARAM, "Font glyphs are not defined, cannot reference extern font - Forcing glyph embedding");
242
 
            }
243
 
        }
244
 
        if (use_text) {
245
 
            /*restore back the font height in pixels (it's currently in SWF glyph design units)*/
246
 
            fprintf(read->svg_output, "<text ");
247
 
            fprintf(read->svg_output, "x=\"%f \" ", FIX2FLT(gr->orig_x));
248
 
            fprintf(read->svg_output, "y=\"%f \" ", FIX2FLT(gr->orig_y));
249
 
            fprintf(read->svg_output, "font-size=\"%d\" ", (u32)(gr->fontSize * SWF_TWIP_SCALE));
250
 
            if (ft->fontName)
251
 
            {
252
 
                fprintf(read->svg_output, "font-family=\"%s\" ", ft->fontName);
253
 
            }
254
 
            if (ft->is_italic) 
255
 
            {
256
 
                fprintf(read->svg_output, "font-style=\"italic\" ");
257
 
            }
258
 
            if (ft->is_bold) 
259
 
            {
260
 
                fprintf(read->svg_output, "font-weight=\"bold\" ");
261
 
            }
262
 
            fprintf(read->svg_output, ">");
263
 
            /*convert to UTF-8*/
264
 
            {
265
 
                u16     *str_w;
266
 
                u16     *widestr;
267
 
                char    *str;
268
 
 
269
 
                str_w = (u16*)gf_malloc(sizeof(u16) * (gr->nbGlyphs+1));
270
 
                for (j=0; j<gr->nbGlyphs; j++) 
271
 
                {
272
 
                    str_w[j] = ft->glyph_codes[gr->indexes[j]];
273
 
                }
274
 
                str_w[j] = 0;
275
 
                str = (char*)gf_malloc(sizeof(char) * (gr->nbGlyphs+2));
276
 
                widestr = str_w;
277
 
                j = gf_utf8_wcstombs(str, sizeof(u8) * (gr->nbGlyphs+1), (const unsigned short **) &widestr);
278
 
                if (j != (u32) -1) {
279
 
                    str[j] = 0;
280
 
                    fprintf(read->svg_output, "%s", str);
281
 
                }
282
 
            }
283
 
            fprintf(read->svg_output, "</text>\n");
284
 
        }
285
 
        else
286
 
        {
287
 
            /*convert glyphs*/
288
 
            Fixed       dx;
289
 
            fprintf(read->svg_output, "<g tranform=\"scale(1,-1) ");
290
 
            fprintf(read->svg_output, "translate(%f, %f)\" >\n", FIX2FLT(gr->orig_x), FIX2FLT(gr->orig_y));
291
 
 
292
 
            dx = 0;
293
 
            for (j=0; j<gr->nbGlyphs; j++) 
294
 
            {
295
 
                fprintf(read->svg_output, "<use xlink:href=\"#Font%d_Glyph%d\" transform=\"translate(%f)\" />\n", gr->fontID, gr->indexes[j], FLT2FIX(gf_divfix(dx, FLT2FIX(gr->fontSize * SWF_TEXT_SCALE))));
296
 
                dx += gr->dx[j];
297
 
            }
298
 
            fprintf(read->svg_output, "</g>\n");
299
 
        }
300
 
    }
301
 
    fprintf(read->svg_output, "</g>\n");
302
 
    fprintf(read->svg_output, "</defs>\n");
303
 
    return GF_OK;
304
 
}
305
 
 
306
 
static GF_Err swf_svg_define_edit_text(SWFReader *read, SWFEditText *text)
307
 
{
308
 
    //char styles[1024];
309
 
    //char *ptr;
310
 
    //Bool use_layout;
311
 
    //M_Layout *layout = NULL;
312
 
    //M_Shape *txt;
313
 
    //M_Text *t;
314
 
    //M_FontStyle *f;
315
 
    //M_Transform2D *tr;
316
 
 
317
 
    //tr = (M_Transform2D *) s2s_new_node(read, TAG_MPEG4_Transform2D);
318
 
    //tr->scale.y = -FIX_ONE;
319
 
 
320
 
    //use_layout = 0;
321
 
    //if (text->align==3) use_layout = 1;
322
 
    //else if (text->multiline) use_layout = 1;
323
 
 
324
 
    //if (use_layout) {
325
 
    //  layout = (M_Layout *) s2s_new_node(read, TAG_MPEG4_Layout);
326
 
    //  tr->translation.x = read->width/2;
327
 
    //  tr->translation.y = read->height/2;
328
 
    //}
329
 
 
330
 
    //t = (M_Text *) s2s_new_node(read, TAG_MPEG4_Text);
331
 
    //f = (M_FontStyle *) s2s_new_node(read, TAG_MPEG4_FontStyle);
332
 
    //t->fontStyle = (GF_Node *) f;
333
 
    //gf_node_register(t->fontStyle, (GF_Node *) t);
334
 
 
335
 
    ///*restore back the font height in pixels (it's currently in SWF glyph design units)*/
336
 
    //f->size = text->font_height;
337
 
    //f->spacing = text->font_height + text->leading;
338
 
 
339
 
    //gf_sg_vrml_mf_reset(&f->justify, GF_SG_VRML_MFSTRING);
340
 
    //gf_sg_vrml_mf_append(&f->justify, GF_SG_VRML_MFSTRING, (void**)&ptr);
341
 
    //switch (text->align) {
342
 
    //case 0:
343
 
    //  ((SFString*)ptr)->buffer = gf_strdup("BEGIN"); 
344
 
    //  break;
345
 
    //case 1:
346
 
    //  ((SFString*)ptr)->buffer = gf_strdup("END"); 
347
 
    //  break;
348
 
    //case 3:
349
 
    //  ((SFString*)ptr)->buffer = gf_strdup("JUSTIFY"); 
350
 
    //  break;
351
 
    //default:
352
 
    //  ((SFString*)ptr)->buffer = gf_strdup("MIDDLE"); 
353
 
    //  break;
354
 
    //}
355
 
 
356
 
    //strcpy(styles, "");
357
 
    //if (!text->read_only) strcat(styles, "EDITABLE");
358
 
    //if (text->password) strcat(styles, "PASSWORD");
359
 
    //
360
 
    //if (f->style.buffer) gf_free(f->style.buffer);
361
 
    //f->style.buffer = gf_strdup(styles);
362
 
 
363
 
    //if (text->init_value) {
364
 
    //  gf_sg_vrml_mf_reset(&t->string, GF_SG_VRML_MFSTRING);
365
 
    //  gf_sg_vrml_mf_append(&t->string, GF_SG_VRML_MFSTRING, (void**)&ptr);
366
 
 
367
 
    //  if (text->html) {
368
 
    //      GF_SAXParser *xml;
369
 
    //      SWFFlatText flat;
370
 
    //      flat.final = 0;
371
 
    //      flat.len = 0;
372
 
    //      xml = gf_xml_sax_new(swf_nstart, swf_nend, swf_ntext, &flat);
373
 
    //      gf_xml_sax_init(xml, NULL);
374
 
    //      gf_xml_sax_parse(xml, text->init_value);
375
 
    //      gf_xml_sax_del(xml);
376
 
 
377
 
    //      if (flat.final) {
378
 
    //          ((SFString*)ptr)->buffer = gf_strdup(flat.final);
379
 
    //          gf_free(flat.final);
380
 
    //      }
381
 
    //  } else {
382
 
    //      ((SFString*)ptr)->buffer = gf_strdup(text->init_value);
383
 
    //  }
384
 
    //}
385
 
 
386
 
 
387
 
    //txt = (M_Shape *) s2s_new_node(read, TAG_MPEG4_Shape);
388
 
    //txt->appearance = s2s_get_appearance(read, (GF_Node *) txt, text->color, 0, 0);               
389
 
    //txt->geometry = (GF_Node *) t;
390
 
    //gf_node_register(txt->geometry, (GF_Node *) txt);
391
 
 
392
 
    //if (layout) {     
393
 
    //  gf_sg_vrml_mf_reset(&layout->justify, GF_SG_VRML_MFSTRING);
394
 
    //  gf_sg_vrml_mf_append(&layout->justify, GF_SG_VRML_MFSTRING, NULL);
395
 
    //  switch (text->align) {
396
 
    //  case 0:
397
 
    //      layout->justify.vals[0] = gf_strdup("BEGIN"); 
398
 
    //      break;
399
 
    //  case 1:
400
 
    //      layout->justify.vals[0] = gf_strdup("END"); 
401
 
    //      break;
402
 
    //  case 3:
403
 
    //      layout->justify.vals[0] = gf_strdup("JUSTIFY"); 
404
 
    //      break;
405
 
    //  default:
406
 
    //      layout->justify.vals[0] = gf_strdup("MIDDLE"); 
407
 
    //      break;
408
 
    //  }
409
 
    //  if (text->multiline || text->word_wrap) layout->wrap = 1;
410
 
 
411
 
    //  gf_node_insert_child((GF_Node *) layout, (GF_Node *)txt, -1);
412
 
    //  gf_node_register((GF_Node *) txt, (GF_Node *) layout);
413
 
 
414
 
    //  gf_node_insert_child((GF_Node *) tr, (GF_Node *)layout, -1);
415
 
    //  gf_node_register((GF_Node *) layout, (GF_Node *) tr);
416
 
    //} else {
417
 
    //  gf_node_insert_child((GF_Node *) tr, (GF_Node *)txt, -1);
418
 
    //  gf_node_register((GF_Node *) txt, (GF_Node *) tr);
419
 
    //} 
420
 
    //if (tr) {
421
 
    //  char szDEF[1024];
422
 
    //  u32 ID;
423
 
    //  sprintf(szDEF, "Text%d", text->ID);
424
 
    //  read->load->ctx->max_node_id++;
425
 
    //  ID = read->load->ctx->max_node_id;
426
 
    //  gf_node_set_id((GF_Node*)tr, ID, szDEF);
427
 
    //  s2s_insert_symbol(read, (GF_Node*)tr);
428
 
    //}
429
 
    return GF_OK;
430
 
}
431
 
 
432
 
#if 0
433
 
/*called upon end of sprite or clip*/
434
 
static void swf_svg_end_of_clip(SWFReader *read)
435
 
{
436
 
    //char szDEF[1024];
437
 
    //u32 i;
438
 
    //GF_AUContext *au;
439
 
    //GF_Command *com;
440
 
    //GF_CommandField *f;
441
 
    //GF_Node *empty;
442
 
    //
443
 
    //return;
444
 
 
445
 
    //empty = gf_sg_find_node_by_name(read->load->scene_graph, "Shape0");
446
 
 
447
 
    //au = gf_list_get(read->bifs_es->AUs, 0);
448
 
    //for (i=0; i<read->max_depth; i++) {
449
 
    //  /*and write command*/
450
 
    //  com = gf_sg_command_new(read->load->scene_graph, GF_SG_INDEXED_REPLACE);
451
 
    //  sprintf(szDEF, "CLIP%d_DL", read->current_sprite_id);
452
 
    //  com->node = gf_sg_find_node_by_name(read->load->scene_graph, szDEF);
453
 
 
454
 
    //  gf_node_register(com->node, NULL);
455
 
    //  f = gf_sg_command_field_new(com);
456
 
    //  f->field_ptr = &f->new_node;
457
 
    //  f->fieldType = GF_SG_VRML_SFNODE;
458
 
    //  f->pos = i;
459
 
    //  f->fieldIndex = 2;  /*children index*/
460
 
    //  f->new_node = empty;
461
 
    //  gf_node_register(f->new_node, com->node);
462
 
 
463
 
    //  gf_list_insert(au->commands, com, i);
464
 
    //}
465
 
}
466
 
#endif
467
 
 
468
 
static Bool swf_svg_allocate_depth(SWFReader *read, u32 depth)
469
 
{
470
 
    //char szDEF[100];
471
 
    //GF_Node *disp, *empty;
472
 
    //if (read->max_depth > depth) return 1;
473
 
 
474
 
    //sprintf(szDEF, "CLIP%d_DL", read->current_sprite_id);
475
 
    //disp = gf_sg_find_node_by_name(read->load->scene_graph, szDEF);
476
 
 
477
 
    //empty = gf_sg_find_node_by_name(read->load->scene_graph, "Shape0");
478
 
    //while (read->max_depth<=depth) {
479
 
    //  gf_node_insert_child(disp, empty, -1);
480
 
    //  gf_node_register(empty, disp);
481
 
    //  read->max_depth++;
482
 
    //}
483
 
    return 0;
484
 
}
485
 
 
486
 
static GF_Err swf_svg_define_sprite(SWFReader *read, u32 nb_frames)
487
 
{
488
 
    //GF_Err e;
489
 
    //GF_ObjectDescriptor *od;
490
 
    //GF_ESD *esd;
491
 
    //u32 ID;
492
 
    //GF_Node *n, *par;
493
 
    //GF_FieldInfo info;
494
 
    //char szDEF[100];
495
 
    //GF_StreamContext *prev_sc;
496
 
    //GF_AUContext *prev_au;
497
 
 
498
 
    ///*init OD*/
499
 
    //e = swf_init_od(read, 0);
500
 
    //if (e) return e;
501
 
 
502
 
    ///*create animationStream object*/
503
 
    //od = (GF_ObjectDescriptor *) gf_odf_desc_new(GF_ODF_OD_TAG);
504
 
    //if (!od) return GF_OUT_OF_MEM;
505
 
 
506
 
    //od->objectDescriptorID = swf_get_od_id(read);
507
 
    //esd = (GF_ESD *) gf_odf_desc_esd_new(0);
508
 
    //if (!esd) return GF_OUT_OF_MEM;
509
 
    //esd->ESID = swf_get_es_id(read);
510
 
    ///*sprite runs on its own timeline*/
511
 
    //esd->OCRESID = esd->ESID;
512
 
    ///*always depends on main scene*/
513
 
    //esd->dependsOnESID = 1;
514
 
    //esd->decoderConfig->streamType = GF_STREAM_SCENE;
515
 
    //esd->decoderConfig->objectTypeIndication = 1;
516
 
    //esd->slConfig->timestampResolution = read->bifs_es->timeScale;
517
 
    //gf_odf_desc_del((GF_Descriptor *) esd->decoderConfig->decoderSpecificInfo);
518
 
    //esd->decoderConfig->decoderSpecificInfo = NULL;
519
 
    //gf_list_add(od->ESDescriptors, esd);
520
 
 
521
 
    ///*by default insert OD at begining*/
522
 
    //e = swf_insert_od(read, 0, od);
523
 
    //if (e) {
524
 
    //  gf_odf_desc_del((GF_Descriptor *) od);
525
 
    //  return e;
526
 
    //}
527
 
 
528
 
    ///*create AS for sprite - all AS are created in initial scene replace*/
529
 
    //n = s2s_new_node(read, TAG_MPEG4_AnimationStream);
530
 
    //gf_node_insert_child(read->root, n, 0);
531
 
    //gf_node_register(n, read->root);
532
 
    ///*assign URL*/
533
 
    //gf_node_get_field_by_name(n, "url", &info);
534
 
    //gf_sg_vrml_mf_alloc(info.far_ptr, info.fieldType, 1);
535
 
    //((MFURL*)info.far_ptr)->vals[0].OD_ID = od->objectDescriptorID;
536
 
    //((M_AnimationStream *)n)->startTime = 0;
537
 
 
538
 
    //n = s2s_new_node(read, TAG_MPEG4_MediaControl);
539
 
    //sprintf(szDEF, "CLIP%d_CTRL", read->current_sprite_id);
540
 
    //read->load->ctx->max_node_id++;
541
 
    //ID = read->load->ctx->max_node_id;
542
 
    //gf_node_set_id(n, ID, szDEF);
543
 
 
544
 
    //gf_node_insert_child(read->root, n, 0);
545
 
    //gf_node_register(n, read->root);
546
 
    ///*assign URL*/
547
 
    //gf_node_get_field_by_name(n, "url", &info);
548
 
    //gf_sg_vrml_mf_alloc(info.far_ptr, info.fieldType, 1);
549
 
    //((MFURL*)info.far_ptr)->vals[0].OD_ID = od->objectDescriptorID;
550
 
    ///*inactive by default (until inserted)*/
551
 
    //((M_MediaControl *)n)->mediaSpeed = 0;
552
 
    //((M_MediaControl *)n)->loop = 1;
553
 
 
554
 
    ///*create sprite grouping node*/
555
 
    //n = s2s_new_node(read, TAG_MPEG4_Group);
556
 
    //sprintf(szDEF, "CLIP%d_DL", read->current_sprite_id);
557
 
 
558
 
    //read->load->ctx->max_node_id++;
559
 
    //ID = read->load->ctx->max_node_id;
560
 
    //gf_node_set_id(n, ID, szDEF);
561
 
    //par = gf_sg_find_node_by_name(read->load->scene_graph, "DICTIONARY");
562
 
    //assert(par);
563
 
    //gf_node_list_add_child(&((M_Switch *)par)->choice, n);
564
 
    //gf_node_register(n, par);
565
 
    //par = gf_sg_find_node_by_name(read->load->scene_graph, "Shape0");
566
 
    //gf_node_insert_child(n, par, -1);
567
 
    //gf_node_register(par, n);
568
 
 
569
 
    ///*store BIFS context*/
570
 
    //prev_sc = read->bifs_es;
571
 
    //prev_au = read->bifs_au;
572
 
    ///*create new BIFS stream*/
573
 
    //read->bifs_es = gf_sm_stream_new(read->load->ctx, esd->ESID, GF_STREAM_SCENE, 1);
574
 
    //read->bifs_es->timeScale = prev_sc->timeScale;
575
 
    //read->bifs_es->imp_exp_time = prev_sc->imp_exp_time + prev_au->timing;
576
 
 
577
 
    ///*create first AU*/
578
 
    //read->bifs_au = gf_sm_stream_au_new(read->bifs_es, 0, 0, 1);
579
 
 
580
 
    //e = swf_parse_sprite(read);
581
 
    //if (e) return e;
582
 
 
583
 
    //swf_svg_end_of_clip(read);
584
 
 
585
 
    ///*restore BIFS context*/
586
 
    //read->bifs_es = prev_sc;
587
 
    //read->bifs_au = prev_au;
588
 
 
589
 
    return GF_OK;
590
 
}
591
 
 
592
 
static GF_Err swf_svg_setup_sound(SWFReader *read, SWFSound *snd, Bool soundstream_first_block)
593
 
{
594
 
//  GF_Err e;
595
 
//  GF_ObjectDescriptor *od;
596
 
//  GF_ESD *esd;
597
 
//  GF_MuxInfo *mux;
598
 
//  GF_Node *n, *par;
599
 
//  GF_FieldInfo info;
600
 
//  u32 ID;
601
 
//  char szDEF[100];
602
 
//
603
 
//  /*soundstream header, only declare the associated MediaControl node for later actions*/
604
 
//  if (!snd->ID && !soundstream_first_block) {
605
 
//      n = s2s_new_node(read, TAG_MPEG4_MediaControl);
606
 
//      sprintf(szDEF, "CLIP%d_SND", read->current_sprite_id);
607
 
//      read->load->ctx->max_node_id++;
608
 
//      ID = read->load->ctx->max_node_id;
609
 
//      gf_node_set_id(n, ID, szDEF);
610
 
//
611
 
//      gf_node_insert_child(read->root, n, 0);
612
 
//      gf_node_register(n, read->root);
613
 
//      return GF_OK;
614
 
//  }
615
 
//
616
 
//  e = swf_init_od(read, 0);
617
 
//  if (e) return e;
618
 
//
619
 
//  /*create audio object*/
620
 
//  od = (GF_ObjectDescriptor *) gf_odf_desc_new(GF_ODF_OD_TAG);
621
 
//  if (!od) return GF_OUT_OF_MEM;
622
 
//  od->objectDescriptorID = swf_get_od_id(read);
623
 
//  esd = (GF_ESD *) gf_odf_desc_new(GF_ODF_ESD_TAG);
624
 
//  if (!esd) return GF_OUT_OF_MEM;
625
 
//  esd->ESID = swf_get_es_id(read);
626
 
//  if (snd->ID) {
627
 
//      /*sound runs on its own timeline*/
628
 
//      esd->OCRESID = esd->ESID;
629
 
//  } else {
630
 
//      /*soundstream runs on movie/sprite timeline*/
631
 
//      esd->OCRESID = read->bifs_es->ESID;
632
 
//      esd->OCRESID = esd->ESID;
633
 
//  }
634
 
//  gf_list_add(od->ESDescriptors, esd);
635
 
//
636
 
//  /*setup mux info*/
637
 
//  mux = (GF_MuxInfo*)gf_odf_desc_new(GF_ODF_MUXINFO_TAG);
638
 
//  mux->file_name = gf_strdup(snd->szFileName);
639
 
////    mux->startTime = snd->frame_delay_ms;
640
 
//  mux->startTime = 0;
641
 
//  /*MP3 in, destroy file once done*/
642
 
//  if (snd->format==2) mux->delete_file = 1;
643
 
//  gf_list_add(esd->extensionDescriptors, mux);
644
 
//
645
 
//
646
 
//  /*by default insert OD at begining*/
647
 
//  e = swf_insert_od(read, 0, od);
648
 
//  if (e) {
649
 
//      gf_odf_desc_del((GF_Descriptor *) od);
650
 
//      return e;
651
 
//  }
652
 
//  /*create sound & audio clip*/
653
 
//  n = s2s_new_node(read, TAG_MPEG4_Sound2D);
654
 
//  gf_node_insert_child(read->root, n, 0);
655
 
//  gf_node_register(n, read->root);
656
 
//  par = n;
657
 
//  n = s2s_new_node(read, TAG_MPEG4_AudioClip);
658
 
//  ((M_Sound2D *)par)->source = n;
659
 
//  gf_node_register(n, par);
660
 
//  /*assign URL*/
661
 
//  gf_node_get_field_by_name(n, "url", &info);
662
 
//  gf_sg_vrml_mf_alloc(info.far_ptr, info.fieldType, 1);
663
 
//  ((MFURL *)info.far_ptr)->vals[0].OD_ID = od->objectDescriptorID;
664
 
//
665
 
//  ((M_AudioClip*)n)->startTime = -1.0;
666
 
//
667
 
//  /*regular sound: set an ID to do play/stop*/
668
 
//  if (snd->ID) {
669
 
//      sprintf(szDEF, "Sound%d", snd->ID);
670
 
//      read->load->ctx->max_node_id++;
671
 
//      ID = read->load->ctx->max_node_id;
672
 
//      gf_node_set_id(n, ID, szDEF);
673
 
//  }
674
 
//  /*soundStream - add a MediaControl*/
675
 
//  else {
676
 
//      /*if sprite always have the media active but controled by its mediaControl*/
677
 
//      if (read->current_sprite_id) {
678
 
//          ((M_AudioClip*)n)->startTime = 0;
679
 
//      } 
680
 
//      /*otherwise start the media at the first soundstream block*/
681
 
//      else {
682
 
//          ((M_AudioClip*)n)->startTime = snd->frame_delay_ms/1000.0;
683
 
//          ((M_AudioClip*)n)->startTime = 0;
684
 
//      }
685
 
//
686
 
//      sprintf(szDEF, "CLIP%d_SND", read->current_sprite_id);
687
 
//      n = gf_sg_find_node_by_name(read->load->scene_graph, szDEF);
688
 
//
689
 
//      /*assign URL*/
690
 
//      gf_node_get_field_by_name(n, "url", &info);
691
 
//      gf_sg_vrml_mf_alloc(info.far_ptr, info.fieldType, 1);
692
 
//      ((MFURL*)info.far_ptr)->vals[0].OD_ID = od->objectDescriptorID;
693
 
//      ((M_MediaControl *)n)->loop = 0;
694
 
//
695
 
//      /*inactive by default (until inserted)*/
696
 
//      if (read->current_sprite_id) {
697
 
//          ((M_MediaControl *)n)->mediaSpeed = 0;
698
 
//      } else {
699
 
//          ((M_MediaControl *)n)->mediaSpeed = FIX_ONE;
700
 
//      }
701
 
//  }
702
 
    return GF_OK;
703
 
}
704
 
 
705
 
static GF_Err swf_svg_setup_image(SWFReader *read, u32 ID, char *fileName)
706
 
{
707
 
 
708
 
    //GF_Err e;
709
 
    //GF_ObjectDescriptor *od;
710
 
    //GF_ESD *esd;
711
 
    //GF_MuxInfo *mux;
712
 
    //GF_Node *n, *par;
713
 
    //GF_FieldInfo info;
714
 
    //char szDEF[100];
715
 
    //
716
 
    //e = swf_init_od(read, 0);
717
 
    //if (e) return e;
718
 
 
719
 
    ///*create visual object*/
720
 
    //od = (GF_ObjectDescriptor *) gf_odf_desc_new(GF_ODF_OD_TAG);
721
 
    //if (!od) return GF_OUT_OF_MEM;
722
 
    //od->objectDescriptorID = swf_get_od_id(read);
723
 
    //esd = (GF_ESD *) gf_odf_desc_new(GF_ODF_ESD_TAG);
724
 
    //if (!esd) return GF_OUT_OF_MEM;
725
 
    //esd->ESID = swf_get_es_id(read);
726
 
    //esd->OCRESID = esd->ESID;
727
 
    //gf_list_add(od->ESDescriptors, esd);
728
 
 
729
 
    ///*setup mux info*/
730
 
    //mux = (GF_MuxInfo*)gf_odf_desc_new(GF_ODF_MUXINFO_TAG);
731
 
 
732
 
    //mux->file_name = gf_strdup(fileName);
733
 
    ///*destroy file once done*/
734
 
    ////mux->delete_file = 1;
735
 
    //gf_list_add(esd->extensionDescriptors, mux);
736
 
 
737
 
 
738
 
    ///*by default insert OD at begining*/
739
 
    //e = swf_insert_od(read, 0, od);
740
 
    //if (e) {
741
 
    //  gf_odf_desc_del((GF_Descriptor *) od);
742
 
    //  return e;
743
 
    //}
744
 
    ///*create appearance clip*/
745
 
    //par = s2s_new_node(read, TAG_MPEG4_Shape);
746
 
    //s2s_insert_symbol(read, par);
747
 
    //n = s2s_new_node(read, TAG_MPEG4_Appearance);
748
 
    //((M_Shape *)par)->appearance = n;
749
 
    //gf_node_register(n, par);
750
 
 
751
 
    //par = n;
752
 
    //n = s2s_new_node(read, TAG_MPEG4_ImageTexture);
753
 
    //((M_Appearance *)par)->texture = n;
754
 
    //gf_node_register(n, par);
755
 
 
756
 
    //sprintf(szDEF, "Bitmap%d", ID);
757
 
    //read->load->ctx->max_node_id++;
758
 
    //ID = read->load->ctx->max_node_id;
759
 
    //gf_node_set_id(n, ID, szDEF);
760
 
 
761
 
    ///*assign URL*/
762
 
    //gf_node_get_field_by_name(n, "url", &info);
763
 
    //gf_sg_vrml_mf_alloc(info.far_ptr, info.fieldType, 1);
764
 
    //((MFURL *)info.far_ptr)->vals[0].OD_ID = od->objectDescriptorID;
765
 
 
766
 
    return GF_OK;
767
 
}
768
 
 
769
 
static GF_Err swf_svg_set_backcol(SWFReader *read, u32 xrgb)
770
 
{
771
 
    //SFColor rgb;
772
 
    //GF_Node *bck = gf_sg_find_node_by_name(read->load->scene_graph, "BACKGROUND");
773
 
 
774
 
    //rgb.red = INT2FIX((xrgb>>16) & 0xFF) / 255;
775
 
    //rgb.green = INT2FIX((xrgb>>8) & 0xFF) / 255;
776
 
    //rgb.blue = INT2FIX((xrgb) & 0xFF) / 255;
777
 
    //s2s_set_field(read, read->bifs_au->commands, bck, "backColor", -1, GF_SG_VRML_SFCOLOR, &rgb, 0);
778
 
    return GF_OK;
779
 
}
780
 
 
781
 
static GF_Err swf_svg_start_sound(SWFReader *read, SWFSound *snd, Bool stop)
782
 
{
783
 
    //GF_Node *sound2D;
784
 
    //SFTime t = 0;
785
 
    //char szDEF[100];
786
 
 
787
 
    //sprintf(szDEF, "Sound%d", snd->ID);
788
 
    //sound2D = gf_sg_find_node_by_name(read->load->scene_graph, szDEF);
789
 
    ///*check flags*/
790
 
    //if (sound2D)
791
 
    //  s2s_set_field(read, read->bifs_au->commands, sound2D, stop ? "stopTime" : "startTime", -1, GF_SG_VRML_SFTIME, &t, 0);
792
 
 
793
 
    return GF_OK;
794
 
}
795
 
 
796
 
static GF_Err swf_svg_place_obj(SWFReader *read, u32 depth, u32 ID, u32 prev_id, u32 type, GF_Matrix2D *mat, GF_ColorMatrix *cmat, GF_Matrix2D *prev_mat, GF_ColorMatrix *prev_cmat)
797
 
{
798
 
    //fprintf(read->svg_output, "<use xlink:href=\"#S%d\" z-index=\"%d\" ", ID, depth);
799
 
    //if (mat) {
800
 
    //    swf_svg_print_matrix(read, mat);
801
 
    //}
802
 
    //fprintf(read->svg_output, "/>\n");
803
 
 
804
 
    //GF_Command *com;
805
 
    //GF_CommandField *f;
806
 
    //GF_Node *obj, *par;
807
 
    //char szDEF[100];
808
 
    //Bool is_sprite;
809
 
 
810
 
    //obj = s2s_get_node(read, ID);
811
 
    //is_sprite = 0;
812
 
    //if (!obj) {
813
 
    //  sprintf(szDEF, "CLIP%d_DL", ID);
814
 
    //  obj = gf_sg_find_node_by_name(read->load->scene_graph, szDEF);
815
 
    //  if (obj) is_sprite = 1;
816
 
    //}
817
 
    //if (!obj) return GF_BAD_PARAM;
818
 
 
819
 
    ///*then add cmat/mat and node*/
820
 
    //par = s2s_wrap_node(read, obj, mat, cmat);
821
 
 
822
 
    ///*and write command*/
823
 
    //com = gf_sg_command_new(read->load->scene_graph, GF_SG_INDEXED_REPLACE);
824
 
    //sprintf(szDEF, "CLIP%d_DL", read->current_sprite_id);
825
 
    //com->node = gf_sg_find_node_by_name(read->load->scene_graph, szDEF);
826
 
    //gf_node_register(com->node, NULL);
827
 
    //f = gf_sg_command_field_new(com);
828
 
    //f->field_ptr = &f->new_node;
829
 
    //f->fieldType = GF_SG_VRML_SFNODE;
830
 
    //f->pos = depth;
831
 
    //f->fieldIndex = 2;    /*children index*/
832
 
    //f->new_node = par;
833
 
    //gf_node_register(f->new_node, com->node);
834
 
    //gf_list_add(read->bifs_au->commands, com);
835
 
 
836
 
    //if (ID==prev_id) return GF_OK;
837
 
 
838
 
    //strcpy(szDEF, gf_node_get_name(obj));
839
 
    ///*when inserting a button, trigger a pause*/
840
 
    //if (!strnicmp(szDEF, "Button", 6)) {
841
 
    //  u32 i, count;
842
 
    //  s2s_control_sprite(read, read->bifs_au->commands, read->current_sprite_id, 1, 0, 0, 1);
843
 
 
844
 
    //  count = gf_list_count(read->buttons);
845
 
    //  for (i=0; i<count; i++) {
846
 
    //      s2sBtnRec *btnrec = gf_list_get(read->buttons, i);
847
 
    //      if (btnrec->btn_id==ID) {
848
 
    //          s2s_control_sprite(read, read->bifs_au->commands, btnrec->sprite_up_id, 0, 0, 0, 1);
849
 
    //      }
850
 
    //  }
851
 
    //}
852
 
    ///*starts anim*/
853
 
    //else if (is_sprite) {
854
 
    //  s2s_control_sprite(read, read->bifs_au->commands, ID, 0, 1, 0, 0);
855
 
    //  if (prev_id) {
856
 
    //      s2s_control_sprite(read, read->bifs_au->commands, prev_id, 1, 0, 0, 0);
857
 
    //  }
858
 
    //}
859
 
    return GF_OK;
860
 
}
861
 
 
862
 
static GF_Err swf_svg_remove_obj(SWFReader *read, u32 depth, u32 ID)
863
 
{
864
 
    return GF_OK;
865
 
}
866
 
 
867
 
static GF_Err swf_svg_show_frame(SWFReader *read)
868
 
{
869
 
    u32     i;
870
 
    u32     len;
871
 
    GF_List *sdl = gf_list_new(); // sorted display list
872
 
 
873
 
    /* sorting the display list */
874
 
    while (gf_list_count(read->display_list))
875
 
    {
876
 
        Bool        inserted = 0;
877
 
        DispShape   *s;
878
 
 
879
 
        s = (DispShape *)gf_list_get(read->display_list, 0);
880
 
        gf_list_rem(read->display_list, 0);
881
 
        
882
 
        for (i = 0; i < gf_list_count(sdl); i++)
883
 
        {
884
 
            DispShape *s2 = (DispShape *)gf_list_get(sdl, i);
885
 
            if (s->depth < s2->depth) 
886
 
            {
887
 
                gf_list_insert(sdl, s, i);
888
 
                inserted = 1;
889
 
                break;
890
 
            }
891
 
        }
892
 
        if (!inserted)
893
 
        {
894
 
            gf_list_add(sdl, s);
895
 
        }
896
 
    }
897
 
    gf_list_del(read->display_list);
898
 
    read->display_list = sdl;
899
 
 
900
 
    /* dumping the display list */
901
 
    len = gf_list_count(read->display_list);
902
 
    for (i=0; i<len; i++)
903
 
    {
904
 
        DispShape   *s;
905
 
        s = (DispShape *)gf_list_get(read->display_list, i);
906
 
        fprintf(read->svg_output, "<use xlink:href=\"#S%d\" z-index=\"%d\" ", s->char_id, s->depth);
907
 
        swf_svg_print_matrix(read, &s->mat);
908
 
        fprintf(read->svg_output, "/>\n");
909
 
    }
910
 
    fprintf(read->svg_output, "</g>\n");
911
 
 
912
 
    fprintf(read->svg_output, "<g id=\"frame%d\" display=\"none\">\n",read->current_frame+1);
913
 
    fprintf(read->svg_output, "<animate attributeName=\"display\" to=\"inline\" begin=\"%f\" end=\"%f\" fill=\"%s\" restart=\"never\"/>\n", 
914
 
        1.0*(read->current_frame+1)/read->frame_rate, 1.0*(read->current_frame+2)/read->frame_rate,
915
 
        (((read->current_frame+1) <= (read->frame_count-1)) ? "remove" : "freeze"));
916
 
    return GF_OK;
917
 
}
918
 
 
919
 
static void swf_svg_finalize(SWFReader *read)
920
 
{
921
 
    //u32 i, count;
922
 
 
923
 
    //swf_svg_end_of_clip(read);    
924
 
 
925
 
    //while (gf_list_count(read->buttons)) {
926
 
    //  s2sBtnRec *btnrec = gf_list_get(read->buttons, 0);
927
 
    //  gf_list_rem(read->buttons, 0);
928
 
    //  gf_free(btnrec);
929
 
    //}
930
 
 
931
 
    //count = gf_list_count(read->fonts);
932
 
    //for (i=0;i<count; i++) {
933
 
    //  SWFFont *ft = (SWFFont *)gf_list_get(read->fonts, i);
934
 
    //  while (gf_list_count(ft->glyphs)) {
935
 
    //      GF_Node *gl = (GF_Node *)gf_list_get(ft->glyphs, 0);
936
 
    //      gf_list_rem(ft->glyphs, 0);
937
 
    //      gf_node_unregister(gl, NULL);
938
 
    //  }
939
 
    //}
940
 
    fprintf(read->svg_output, "</g>\n");
941
 
    fprintf(read->svg_output, "</svg>\n");
942
 
    fclose(read->svg_output);
943
 
}
944
 
 
945
 
static GF_Err swf_svg_define_button(SWFReader *read, SWF_Button *btn)
946
 
{
947
 
    //char szName[1024];
948
 
    //M_Switch *button;
949
 
    //SWF_ButtonRecord *br;
950
 
    //GF_Node *btn_root, *n, *btn_ts;
951
 
    //u32 i, ID, pos;
952
 
 
953
 
    //if (!btn) {
954
 
    //  read->btn = NULL;
955
 
    //  read->btn_over = read->btn_not_over = read->btn_active = read->btn_not_active = NULL;
956
 
    //  return GF_OK;
957
 
    //}
958
 
 
959
 
    //read->btn = btn;
960
 
 
961
 
    //btn_root = s2s_new_node(read, TAG_MPEG4_Transform2D);
962
 
    //sprintf(szName, "Button%d", btn->ID);
963
 
    //read->load->ctx->max_node_id++;
964
 
    //ID = read->load->ctx->max_node_id;
965
 
    //gf_node_set_id((GF_Node *)btn_root, ID, szName);
966
 
 
967
 
    //n = s2s_button_add_child(read, btn_root, TAG_MPEG4_ColorTransform, NULL, -1);
968
 
    //((M_ColorTransform*)n)->maa = ((M_ColorTransform*)n)->mab = ((M_ColorTransform*)n)->mar = ((M_ColorTransform*)n)->mag = ((M_ColorTransform*)n)->ta = 0; 
969
 
 
970
 
    ///*locate hit buttons and add them to the color transform*/
971
 
    //for (i=0; i<btn->count; i++) {
972
 
    //  GF_Node *character;
973
 
    //  br = &btn->buttons[i];
974
 
    //  if (!br->hitTest) continue;
975
 
    //  character = s2s_get_node(read, br->character_id);
976
 
    //  if (!character) {
977
 
    //      sprintf(szName, "CLIP%d_DL", br->character_id);
978
 
    //      character = gf_sg_find_node_by_name(read->load->scene_graph, szName);
979
 
    //  }
980
 
    //  if (character) {
981
 
    //      gf_node_list_add_child(&((GF_ParentNode*)n)->children, character);
982
 
    //      gf_node_register(character, (GF_Node *)n);
983
 
    //  }
984
 
    //}
985
 
    ///*add touch sensor to the color transform*/
986
 
    //sprintf(szName, "BTN%d_TS", read->btn->ID);
987
 
    //btn_ts = s2s_button_add_child(read, n, TAG_MPEG4_TouchSensor, szName, -1);
988
 
 
989
 
    //s2s_insert_symbol(read, (GF_Node *)btn_root);
990
 
 
991
 
    ///*isActive handler*/
992
 
    //sprintf(szName, "BTN%d_CA", read->btn->ID);
993
 
    //n = s2s_button_add_child(read, btn_root, TAG_MPEG4_Conditional, szName, -1);
994
 
    //read->btn_active = ((M_Conditional*)n)->buffer.commandList;
995
 
    //s2s_button_add_route(read, btn_ts, 4, n, 0);
996
 
 
997
 
    ///*!isActive handler*/
998
 
    //sprintf(szName, "BTN%d_CNA", read->btn->ID);
999
 
    //n = s2s_button_add_child(read, btn_root, TAG_MPEG4_Conditional, szName, -1);
1000
 
    //read->btn_not_active = ((M_Conditional*)n)->buffer.commandList;
1001
 
    //s2s_button_add_route(read, btn_ts, 4, n, 1);
1002
 
 
1003
 
    ///*isOver handler*/
1004
 
    //sprintf(szName, "BTN%d_CO", read->btn->ID);
1005
 
    //n = s2s_button_add_child(read, btn_root, TAG_MPEG4_Conditional, szName, -1);
1006
 
    //read->btn_over = ((M_Conditional*)n)->buffer.commandList;
1007
 
    //s2s_button_add_route(read, btn_ts, 5, n, 0);
1008
 
 
1009
 
    ///*!isOver handler*/
1010
 
    //sprintf(szName, "BTN%d_CNO", read->btn->ID);
1011
 
    //n = s2s_button_add_child(read, btn_root, TAG_MPEG4_Conditional, szName, -1);
1012
 
    //read->btn_not_over = ((M_Conditional*)n)->buffer.commandList;
1013
 
    //s2s_button_add_route(read, btn_ts, 5, n, 1);
1014
 
 
1015
 
    ///*by default show first character*/
1016
 
    //pos = 0;
1017
 
    //for (i=0; i<btn->count; i++) {
1018
 
    //  GF_Node *sprite_ctrl = NULL;
1019
 
    //  GF_Node *character;
1020
 
    //  br = &btn->buttons[i];
1021
 
    //  if (!br->up && !br->down && !br->over) continue;
1022
 
 
1023
 
    //  character = s2s_get_node(read, br->character_id);
1024
 
 
1025
 
    //  if (!character) {
1026
 
    //      sprintf(szName, "CLIP%d_DL", br->character_id);
1027
 
    //      character = gf_sg_find_node_by_name(read->load->scene_graph, szName);
1028
 
    //      if (character) {
1029
 
    //          sprintf(szName, "CLIP%d_CTRL", br->character_id);
1030
 
    //          sprite_ctrl = gf_sg_find_node_by_name(read->load->scene_graph, szName);
1031
 
    //      }
1032
 
    //  }
1033
 
    //  if (character) {
1034
 
    //      SFInt32 choice = 0;
1035
 
    //      GF_Node *n = s2s_wrap_node(read, character, &br->mx, &br->cmx);
1036
 
 
1037
 
    //      sprintf(szName, "BTN%d_R%d", btn->ID, i+1);
1038
 
    //      button = (M_Switch *) s2s_button_add_child(read, btn_root, TAG_MPEG4_Switch, szName, pos);
1039
 
    //      pos++;
1040
 
 
1041
 
    //      gf_node_list_add_child(&button->choice, n);
1042
 
    //      gf_node_register(n, (GF_Node *)button);
1043
 
    //      /*initial state*/
1044
 
    //      if (br->up) {
1045
 
    //          button->whichChoice = 0;
1046
 
    //          /*register this button for sprite start upon place_obj*/
1047
 
    //          if (sprite_ctrl) {
1048
 
    //              s2sBtnRec *btnrec;
1049
 
    //              if (!read->buttons) read->buttons = gf_list_new();
1050
 
    //              btnrec = gf_malloc(sizeof(s2sBtnRec));
1051
 
    //              btnrec->btn_id = btn->ID;
1052
 
    //              btnrec->sprite_up_id = br->character_id;
1053
 
    //              gf_list_add(read->buttons, btnrec);
1054
 
    //          }
1055
 
 
1056
 
    //      } else {
1057
 
    //          button->whichChoice = -1;
1058
 
    //      }
1059
 
 
1060
 
    //      choice = br->up ? 0 : -1;
1061
 
    //      s2s_set_field(read, read->btn_not_over, (GF_Node *)button, "whichChoice", -1, GF_SG_VRML_SFINT32, &choice, 0);
1062
 
    //      /*start or stop sprite if button is up or not*/
1063
 
    //      if (sprite_ctrl) {
1064
 
    //          s2s_control_sprite(read, read->btn_not_over, br->character_id, choice, 1, 0, 0);
1065
 
    //      }
1066
 
 
1067
 
    //      choice = br->down ? 0 : -1;
1068
 
    //      s2s_set_field(read, read->btn_active, (GF_Node *)button, "whichChoice", -1, GF_SG_VRML_SFINT32, &choice, 0);
1069
 
    //      if (sprite_ctrl && !br->over) {
1070
 
    //          s2s_control_sprite(read, read->btn_active, br->character_id, choice, 1, 0, 0);
1071
 
    //      }
1072
 
 
1073
 
    //      choice = br->over ? 0 : -1;
1074
 
    //      s2s_set_field(read, read->btn_not_active, (GF_Node *)button, "whichChoice", -1, GF_SG_VRML_SFINT32, &choice, 0);
1075
 
    //      s2s_set_field(read, read->btn_over, (GF_Node *)button, "whichChoice", -1, GF_SG_VRML_SFINT32, &choice, 0);
1076
 
    //      if (sprite_ctrl) {
1077
 
    //          s2s_control_sprite(read, read->btn_over, br->character_id, choice, 1, 0, 0);
1078
 
    //          if (!br->down)
1079
 
    //              s2s_control_sprite(read, read->btn_not_active, br->character_id, choice, 1, 0, 0);
1080
 
    //      }
1081
 
    //  }
1082
 
    //}
1083
 
 
1084
 
    return GF_OK;
1085
 
}
1086
 
 
1087
 
Bool swf_svg_action(SWFReader *read, SWFAction *act)
1088
 
{
1089
 
//  GF_List *dst;
1090
 
//  MFURL url;
1091
 
//  SFURL sfurl;
1092
 
//  Bool bval;
1093
 
//  GF_Node *n;
1094
 
//  Double time;
1095
 
//
1096
 
//  dst = read->bifs_au->commands;
1097
 
//  if (read->btn) {
1098
 
//      if (act->button_mask & GF_SWF_COND_OVERUP_TO_OVERDOWN) dst = read->btn_active;
1099
 
//      else if (act->button_mask & GF_SWF_COND_IDLE_TO_OVERUP) dst = read->btn_over;
1100
 
//      else if (act->button_mask & GF_SWF_COND_OVERUP_TO_IDLE) dst = read->btn_not_over;
1101
 
//      else dst = read->btn_not_active;
1102
 
//  }
1103
 
//
1104
 
//  switch (act->type) {
1105
 
//  case GF_SWF_AS3_WAIT_FOR_FRAME:
1106
 
//      /*while correct, this is not optimal, we set the wait-frame upon GOTO frame*/
1107
 
////        read->wait_frame = act->frame_number;
1108
 
//      break;
1109
 
//  case GF_SWF_AS3_GOTO_FRAME:
1110
 
//      if (act->frame_number>read->current_frame)
1111
 
//          read->wait_frame = act->frame_number;
1112
 
//
1113
 
//      time = act->frame_number ? act->frame_number +1: 0;
1114
 
//      time /= read->frame_rate;
1115
 
//      s2s_control_sprite(read, dst, read->current_sprite_id, 0, 1, time, 0);
1116
 
//      break;
1117
 
//  case GF_SWF_AS3_GET_URL:
1118
 
//      n = gf_sg_find_node_by_name(read->load->scene_graph, "MOVIE_URL");
1119
 
//      sfurl.OD_ID = 0; sfurl.url = act->url;
1120
 
//      url.count = 1; url.vals = &sfurl;
1121
 
//      s2s_set_field(read, dst, n, "url", -1, GF_SG_VRML_MFURL, &url, 0);
1122
 
//      s2s_set_field(read, dst, n, "parameter", -1, GF_SG_VRML_MFSTRING, &url, 0);
1123
 
//      bval = 1;
1124
 
//      s2s_set_field(read, dst, n, "activate", -1, GF_SG_VRML_SFBOOL, &bval, 0);
1125
 
//      break;
1126
 
//  case GF_SWF_AS3_PLAY:
1127
 
//      s2s_control_sprite(read, dst, read->current_sprite_id, 0, 1, -1, 0);
1128
 
//      break;
1129
 
//  case GF_SWF_AS3_STOP:
1130
 
//      s2s_control_sprite(read, dst, read->current_sprite_id, 1, 0, 0, 0);
1131
 
//      break;
1132
 
//  default:
1133
 
//      return 0;
1134
 
//  }
1135
 
//
1136
 
    return 1;
1137
 
}
1138
 
 
1139
 
GF_Err swf_to_svg_init(SWFReader *read)
1140
 
{
1141
 
    char szFileName[GF_MAX_PATH];
1142
 
    sprintf(szFileName, "%s.svg", read->load->fileName);
1143
 
    /*init callbacks*/
1144
 
    read->svg_output = gf_f64_open(szFileName, "wt");
1145
 
    fprintf(read->svg_output, "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n");
1146
 
    fprintf(read->svg_output, "<svg xmlns=\"http://www.w3.org/2000/svg\" ");
1147
 
    fprintf(read->svg_output, "xmlns:xlink=\"http://www.w3.org/1999/xlink\" ");
1148
 
    fprintf(read->svg_output, "width=\"100%%\" ");
1149
 
    fprintf(read->svg_output, "height=\"100%%\" ");
1150
 
    fprintf(read->svg_output, "viewBox=\"0 0 %d %d\" ", FIX2INT(read->width), FIX2INT(read->height));
1151
 
    fprintf(read->svg_output, "viewport-fill=\"rgb(255,255,255)\" ");
1152
 
    fprintf(read->svg_output, ">\n");
1153
 
    fprintf(read->svg_output, "<g id=\"frame%d\" display=\"none\">\n",read->current_frame);
1154
 
    fprintf(read->svg_output, "<animate attributeName=\"display\" to=\"inline\" begin=\"%f\" end=\"%f\" fill=\"remove\" restart=\"never\"/>\n",
1155
 
        1.0*(read->current_frame)/read->frame_rate, 1.0*(read->current_frame+1)/read->frame_rate);
1156
 
    read->show_frame = swf_svg_show_frame;
1157
 
    read->allocate_depth = swf_svg_allocate_depth;
1158
 
    read->place_obj = swf_svg_place_obj;
1159
 
    read->remove_obj = swf_svg_remove_obj;
1160
 
    read->define_shape = swf_svg_define_shape;
1161
 
    read->define_sprite = swf_svg_define_sprite;
1162
 
    read->set_backcol = swf_svg_set_backcol;
1163
 
    read->define_button = swf_svg_define_button;
1164
 
    read->define_text = swf_svg_define_text;
1165
 
    read->define_edit_text = swf_svg_define_edit_text;
1166
 
    read->setup_sound = swf_svg_setup_sound;
1167
 
    read->start_sound = swf_svg_start_sound;
1168
 
    read->setup_image = swf_svg_setup_image;
1169
 
    read->action = swf_svg_action;
1170
 
    read->finalize = swf_svg_finalize;
1171
 
    return GF_OK;
1172
 
}
1173
 
 
1174
 
#endif /*GPAC_DISABLE_SWF_IMPORT*/
1175
 
 
1176
 
#else
1177
 
GF_Err swf_to_svg_init(SWFReader *read)
1178
 
{
1179
 
    return GF_NOT_SUPPORTED;
1180
 
}
1181
 
 
1182
 
#endif /*GPAC_DISABLE_VRML*/
 
1
/*
 
2
 *          GPAC - Multimedia Framework C SDK
 
3
 *
 
4
 *          Authors: Cyril Concolato
 
5
 *          Copyright (c) Telecom ParisTech 2000-2012
 
6
 *                  All rights reserved
 
7
 *
 
8
 *  This file is part of GPAC / Scene Management sub-project
 
9
 *
 
10
 *  GPAC is free software; you can redistribute it and/or modify
 
11
 *  it under the terms of the GNU Lesser General Public License as published by
 
12
 *  the Free Software Foundation; either version 2, or (at your option)
 
13
 *  any later version.
 
14
 *   
 
15
 *  GPAC is distributed in the hope that it will be useful,
 
16
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 
17
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 
18
 *  GNU Lesser General Public License for more details.
 
19
 *   
 
20
 *  You should have received a copy of the GNU Lesser General Public
 
21
 *  License along with this library; see the file COPYING.  If not, write to
 
22
 *  the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. 
 
23
 *
 
24
 */
 
25
#include <gpac/utf.h>
 
26
#include <gpac/xml.h>
 
27
#include <gpac/internal/swf_dev.h>
 
28
#include <gpac/internal/scenegraph_dev.h>
 
29
#include <gpac/internal/isomedia_dev.h>
 
30
#include <gpac/internal/media_dev.h>
 
31
#include <gpac/constants.h>
 
32
 
 
33
#ifndef GPAC_DISABLE_VRML
 
34
 
 
35
#ifndef GPAC_DISABLE_SWF_IMPORT
 
36
 
 
37
#define SWF_TEXT_SCALE              (1/1024.0f)
 
38
 
 
39
typedef struct _swf_svg_sample
 
40
{
 
41
    u64 start;
 
42
    u64 end;
 
43
    char *data;
 
44
} GF_SWF_SVG_Sample;
 
45
 
 
46
static void swf_svg_print(SWFReader *read, const char *format, ...) {
 
47
        char line[2000];
 
48
        u32 line_length;
 
49
        u32 new_size;
 
50
        va_list args;
 
51
 
 
52
        /* print the line */
 
53
        va_start(args, format);
 
54
        vsprintf(line, format, args);
 
55
        va_end(args);
 
56
        /* add the line to the buffer */
 
57
        line_length = (u32)strlen(line);
 
58
        new_size = read->svg_data_size+line_length;
 
59
        read->svg_data = (char *)gf_realloc(read->svg_data, new_size+1);
 
60
        if (read->print_frame_header) {
 
61
                /* write at the beginning of the buffer */
 
62
                memmove(read->svg_data+read->frame_header_offset+line_length, read->svg_data+read->frame_header_offset, (read->svg_data_size-read->frame_header_offset)+1);
 
63
                memcpy(read->svg_data+read->frame_header_offset, line, line_length);
 
64
                read->frame_header_offset += line_length;
 
65
        } else {
 
66
                strcpy(read->svg_data+read->svg_data_size, line);
 
67
        }
 
68
        read->svg_data_size = new_size;
 
69
}
 
70
 
 
71
static void swf_svg_print_color(SWFReader *read, u32 ARGB)
 
72
{
 
73
    SFColor val;
 
74
    val.red = INT2FIX((ARGB>>16)&0xFF) / 255*100;
 
75
    val.green = INT2FIX((ARGB>>8)&0xFF) / 255*100;
 
76
    val.blue = INT2FIX((ARGB)&0xFF) / 255*100;
 
77
    swf_svg_print(read, "rgb(%g%%,%g%%,%g%%)", FIX2FLT(val.red), FIX2FLT(val.green), FIX2FLT(val.blue));
 
78
}
 
79
 
 
80
static void swf_svg_print_alpha(SWFReader *read, u32 ARGB)
 
81
{
 
82
    Fixed alpha;
 
83
    alpha = INT2FIX((ARGB>>24)&0xFF)/255;
 
84
    swf_svg_print(read, "%g", FIX2FLT(alpha));
 
85
}
 
86
 
 
87
static void swg_svg_print_shape_record_to_fill_stroke(SWFReader *read, SWFShapeRec *srec, Bool is_fill)
 
88
{
 
89
        /*get regular appearance reuse*/
 
90
        if (is_fill) {
 
91
                switch (srec->type) {
 
92
                /*solid/alpha fill*/
 
93
                case 0x00:
 
94
            swf_svg_print(read, "fill=\"");
 
95
            swf_svg_print_color(read, srec->solid_col);
 
96
            swf_svg_print(read, "\" ");
 
97
            swf_svg_print(read, "fill-opacity=\"");
 
98
            swf_svg_print_alpha(read, srec->solid_col);
 
99
            swf_svg_print(read, "\" ");
 
100
                        break;
 
101
                case 0x10:
 
102
                case 0x12:
 
103
                        //if (read->flags & GF_SM_SWF_NO_GRADIENT) {
 
104
                        //      u32 col = srec->grad_col[srec->nbGrad/2];
 
105
                        //      col |= 0xFF000000;
 
106
                        //      n->appearance = s2b_get_appearance(read, (GF_Node *) n, col, 0, 0);
 
107
                        //} else {
 
108
                        //      n->appearance = s2b_get_gradient(read, (GF_Node *) n, shape, srec);
 
109
                        //}
 
110
                        //break;
 
111
                case 0x40:
 
112
                case 0x41:
 
113
                case 0x42:
 
114
                case 0x43:
 
115
                        //n->appearance = s2b_get_bitmap(read, (GF_Node *) n, shape, srec);
 
116
                        //break;
 
117
                default:
 
118
                        swf_report(read, GF_NOT_SUPPORTED, "fill_style %x not supported", srec->type);
 
119
                        break;
 
120
                }
 
121
        } else {
 
122
        swf_svg_print(read, "fill=\"none\" ");
 
123
        swf_svg_print(read, "stroke=\"");
 
124
        swf_svg_print_color(read, srec->solid_col);
 
125
        swf_svg_print(read, "\" ");
 
126
        swf_svg_print(read, "stroke-opacity=\"");
 
127
        swf_svg_print_alpha(read, srec->solid_col);
 
128
        swf_svg_print(read, "\" ");
 
129
        swf_svg_print(read, "stroke-width=\"%g\" ", FIX2FLT(srec->width));
 
130
        }
 
131
}
 
132
 
 
133
static void swf_svg_print_shape_record_to_path_d(SWFReader *read, SWFShapeRec *srec) 
 
134
{
 
135
    u32     pt_idx;
 
136
    u32     i;
 
137
 
 
138
    pt_idx = 0;
 
139
    for (i=0; i<srec->path->nbType; i++) {
 
140
        switch (srec->path->types[i]) {
 
141
        /*moveTo*/
 
142
        case 0:
 
143
            swf_svg_print(read, "M%g,%g", FIX2FLT(srec->path->pts[pt_idx].x), FIX2FLT(srec->path->pts[pt_idx].y));
 
144
            pt_idx++;
 
145
            break;
 
146
        /*lineTo*/
 
147
        case 1:
 
148
            swf_svg_print(read, "L%g,%g", FIX2FLT(srec->path->pts[pt_idx].x), FIX2FLT(srec->path->pts[pt_idx].y));
 
149
            pt_idx++;
 
150
            break;
 
151
        /*curveTo*/
 
152
        case 2:
 
153
            swf_svg_print(read, "Q%g,%g", FIX2FLT(srec->path->pts[pt_idx].x), FIX2FLT(srec->path->pts[pt_idx].y));
 
154
            pt_idx++;
 
155
            swf_svg_print(read, ",%g,%g", FIX2FLT(srec->path->pts[pt_idx].x), FIX2FLT(srec->path->pts[pt_idx].y));
 
156
            pt_idx++;
 
157
            break;
 
158
        }
 
159
    }
 
160
}
 
161
 
 
162
static void swf_svg_print_matrix(SWFReader *read, GF_Matrix2D *mat)
 
163
{
 
164
    if (!gf_mx2d_is_identity(*mat))
 
165
    {
 
166
        GF_Point2D  scale;
 
167
        GF_Point2D  translate;
 
168
        Fixed       rotate;
 
169
        if( gf_mx2d_decompose(mat, &scale, &rotate, &translate)) 
 
170
        {
 
171
            swf_svg_print(read, "transform=\"");
 
172
            if (translate.x != 0 || translate.y != 0)
 
173
            {
 
174
                swf_svg_print(read, "translate(%g, %g) ", FIX2FLT(translate.x), FIX2FLT(translate.y));
 
175
            }
 
176
            if (rotate != 0)
 
177
            {
 
178
                swf_svg_print(read, "rotate(%g) ", FIX2FLT(rotate));
 
179
            }
 
180
            if (scale.x != FIX_ONE || scale.y != FIX_ONE)
 
181
            {
 
182
                swf_svg_print(read, "scale(%g, %g) ", FIX2FLT(scale.x), FIX2FLT(scale.y));
 
183
            }
 
184
            swf_svg_print(read, "\" ");
 
185
        } 
 
186
        else 
 
187
        {
 
188
            swf_svg_print(read, "transform=\"matrix(%g,%g,%g,%g,%g,%g)\" ", FIX2FLT(mat->m[0]), FIX2FLT(mat->m[3]), FIX2FLT(mat->m[1]), FIX2FLT(mat->m[4]), FIX2FLT(mat->m[2]), FIX2FLT(mat->m[5]) );
 
189
        }
 
190
    }
 
191
}
 
192
 
 
193
/*translates Flash to SVG shapes*/
 
194
static GF_Err swf_svg_define_shape(SWFReader *read, SWFShape *shape, SWFFont *parent_font, Bool last_sub_shape)
 
195
{
 
196
    u32 i;
 
197
    SWFShapeRec *srec;
 
198
 
 
199
    if (parent_font && (read->flags & GF_SM_SWF_NO_FONT)) 
 
200
    {
 
201
        return GF_OK;
 
202
    }
 
203
 
 
204
    if (!read->svg_shape_started) 
 
205
    {
 
206
        swf_svg_print(read, "<defs>\n");
 
207
        if (!parent_font)
 
208
        {
 
209
            swf_svg_print(read, "<g id=\"S%d\" >\n", shape->ID);
 
210
        }
 
211
        else
 
212
        {
 
213
            char    szGlyphId[256];
 
214
            sprintf(szGlyphId, "Font%d_Glyph%d", parent_font->fontID, gf_list_count(parent_font->glyphs));
 
215
            swf_svg_print(read, "<g id=\"%s\" >\n", szGlyphId);
 
216
            gf_list_add(parent_font->glyphs, szGlyphId);
 
217
        }
 
218
    }
 
219
        read->empty_frame = GF_FALSE;
 
220
    read->svg_shape_started = GF_TRUE;
 
221
 
 
222
    i=0;
 
223
    while ((srec = (SWFShapeRec*)gf_list_enum(shape->fill_left, &i))) {
 
224
        swf_svg_print(read, "<path d=\"");
 
225
        swf_svg_print_shape_record_to_path_d(read, srec);
 
226
        swf_svg_print(read, "\" ");
 
227
        swg_svg_print_shape_record_to_fill_stroke(read, srec, 1);
 
228
        swf_svg_print(read, "/>\n");
 
229
    }
 
230
    i=0;
 
231
    while ((srec = (SWFShapeRec*)gf_list_enum(shape->lines, &i))) {
 
232
        swf_svg_print(read, "<path d=\"");
 
233
        swf_svg_print_shape_record_to_path_d(read, srec);
 
234
        swf_svg_print(read, "\" ");
 
235
        swg_svg_print_shape_record_to_fill_stroke(read, srec, 0);
 
236
        swf_svg_print(read, "/>\n");
 
237
    }
 
238
 
 
239
    if (last_sub_shape) 
 
240
    {
 
241
        read->svg_shape_started = GF_FALSE;
 
242
        swf_svg_print(read, "</g>\n");
 
243
        swf_svg_print(read, "</defs>\n");
 
244
    }
 
245
    return GF_OK;
 
246
}
 
247
 
 
248
static GF_Err swf_svg_define_text(SWFReader *read, SWFText *text)
 
249
{
 
250
    Bool            use_text;
 
251
    u32             i;
 
252
    u32             j;
 
253
    SWFGlyphRec     *gr;
 
254
    SWFFont         *ft;
 
255
 
 
256
    use_text = (read->flags & GF_SM_SWF_NO_FONT) ? 1 : 0;
 
257
 
 
258
    swf_svg_print(read, "<defs>\n");
 
259
    swf_svg_print(read, "<g id=\"S%d\" ", text->ID);
 
260
    swf_svg_print_matrix(read, &text->mat);
 
261
    swf_svg_print(read, ">\n");
 
262
 
 
263
    i=0;
 
264
    while ((gr = (SWFGlyphRec*)gf_list_enum(text->text, &i))) 
 
265
    {
 
266
        ft = NULL;
 
267
        if (use_text) {
 
268
            ft = swf_find_font(read, gr->fontID);
 
269
            if (!ft->glyph_codes) {
 
270
                use_text = 0;
 
271
                swf_report(read, GF_BAD_PARAM, "Font glyphs are not defined, cannot reference extern font - Forcing glyph embedding");
 
272
            }
 
273
        }
 
274
        if (use_text) {
 
275
            /*restore back the font height in pixels (it's currently in SWF glyph design units)*/
 
276
            swf_svg_print(read, "<text ");
 
277
            swf_svg_print(read, "x=\"%g \" ", FIX2FLT(gr->orig_x));
 
278
            swf_svg_print(read, "y=\"%g \" ", FIX2FLT(gr->orig_y));
 
279
            swf_svg_print(read, "font-size=\"%d\" ", (u32)(gr->fontSize * SWF_TWIP_SCALE));
 
280
            if (ft->fontName)
 
281
            {
 
282
                swf_svg_print(read, "font-family=\"%s\" ", ft->fontName);
 
283
            }
 
284
            if (ft->is_italic) 
 
285
            {
 
286
                swf_svg_print(read, "font-style=\"italic\" ");
 
287
            }
 
288
            if (ft->is_bold) 
 
289
            {
 
290
                swf_svg_print(read, "font-weight=\"bold\" ");
 
291
            }
 
292
            swf_svg_print(read, ">");
 
293
            /*convert to UTF-8*/
 
294
            {
 
295
                                size_t _len;
 
296
                u16     *str_w;
 
297
                u16     *widestr;
 
298
                char    *str;
 
299
 
 
300
                str_w = (u16*)gf_malloc(sizeof(u16) * (gr->nbGlyphs+1));
 
301
                for (j=0; j<gr->nbGlyphs; j++) 
 
302
                {
 
303
                    str_w[j] = ft->glyph_codes[gr->indexes[j]];
 
304
                }
 
305
                str_w[j] = 0;
 
306
                str = (char*)gf_malloc(sizeof(char) * (gr->nbGlyphs+2));
 
307
                widestr = str_w;
 
308
                _len = gf_utf8_wcstombs(str, sizeof(u8) * (gr->nbGlyphs+1), (const unsigned short **) &widestr);
 
309
                if (_len != (size_t) -1) {
 
310
                    str[(u32) _len] = 0;
 
311
                    swf_svg_print(read, "%s", str);
 
312
                }
 
313
            }
 
314
            swf_svg_print(read, "</text>\n");
 
315
        }
 
316
        else
 
317
        {
 
318
            /*convert glyphs*/
 
319
            Fixed       dx;
 
320
            swf_svg_print(read, "<g tranform=\"scale(1,-1) ");
 
321
            swf_svg_print(read, "translate(%g, %g)\" >\n", FIX2FLT(gr->orig_x), FIX2FLT(gr->orig_y));
 
322
 
 
323
            dx = 0;
 
324
            for (j=0; j<gr->nbGlyphs; j++) 
 
325
            {
 
326
                swf_svg_print(read, "<use xlink:href=\"#Font%d_Glyph%d\" transform=\"translate(%g)\" />\n", gr->fontID, gr->indexes[j], FIX2FLT(gf_divfix(dx, FLT2FIX(gr->fontSize * SWF_TEXT_SCALE))));
 
327
                dx += gr->dx[j];
 
328
            }
 
329
            swf_svg_print(read, "</g>\n");
 
330
        }
 
331
    }
 
332
        read->empty_frame = GF_FALSE;
 
333
    swf_svg_print(read, "</g>\n");
 
334
    swf_svg_print(read, "</defs>\n");
 
335
    return GF_OK;
 
336
}
 
337
 
 
338
static GF_Err swf_svg_define_edit_text(SWFReader *read, SWFEditText *text)
 
339
{
 
340
    return GF_OK;
 
341
}
 
342
 
 
343
#if 0
 
344
/*called upon end of sprite or clip*/
 
345
static void swf_svg_end_of_clip(SWFReader *read)
 
346
{
 
347
}
 
348
#endif
 
349
 
 
350
static Bool swf_svg_allocate_depth(SWFReader *read, u32 depth)
 
351
{
 
352
    return GF_FALSE;
 
353
}
 
354
 
 
355
static GF_Err swf_svg_define_sprite(SWFReader *read, u32 nb_frames)
 
356
{
 
357
    return GF_OK;
 
358
}
 
359
 
 
360
static GF_Err swf_svg_setup_sound(SWFReader *read, SWFSound *snd, Bool soundstream_first_block)
 
361
{
 
362
    return GF_OK;
 
363
}
 
364
 
 
365
static GF_Err swf_svg_setup_image(SWFReader *read, u32 ID, char *fileName)
 
366
{
 
367
    swf_svg_print(read, "<defs>\n");
 
368
    swf_svg_print(read, "<image id=\"S%d\" xlink:href=\"\"/>", ID, fileName);
 
369
    swf_svg_print(read, "</defs>\n");
 
370
    return GF_OK;
 
371
}
 
372
 
 
373
static GF_Err swf_svg_set_backcol(SWFReader *read, u32 xrgb)
 
374
{
 
375
 
 
376
    //rgb.red = INT2FIX((xrgb>>16) & 0xFF) / 255;
 
377
    //rgb.green = INT2FIX((xrgb>>8) & 0xFF) / 255;
 
378
    //rgb.blue = INT2FIX((xrgb) & 0xFF) / 255;
 
379
    return GF_OK;
 
380
}
 
381
 
 
382
static GF_Err swf_svg_start_sound(SWFReader *read, SWFSound *snd, Bool stop)
 
383
{
 
384
    return GF_OK;
 
385
}
 
386
 
 
387
static GF_Err swf_svg_place_obj(SWFReader *read, u32 depth, u32 ID, u32 prev_id, u32 type, GF_Matrix2D *mat, GF_ColorMatrix *cmat, GF_Matrix2D *prev_mat, GF_ColorMatrix *prev_cmat)
 
388
{
 
389
        read->empty_frame = GF_FALSE;
 
390
    return GF_OK;
 
391
}
 
392
 
 
393
static GF_Err swf_svg_remove_obj(SWFReader *read, u32 depth, u32 ID)
 
394
{
 
395
        read->empty_frame = GF_FALSE;
 
396
    return GF_OK;
 
397
}
 
398
 
 
399
static GF_Err swf_svg_show_frame(SWFReader *read)
 
400
{
 
401
    u32     i;
 
402
    u32     len;
 
403
    GF_List *sdl = gf_list_new(); // sorted display list
 
404
 
 
405
    /* sorting the display list because SVG/CSS z-index is not well supported */
 
406
    while (gf_list_count(read->display_list))
 
407
    {
 
408
        Bool        inserted = GF_FALSE;
 
409
        DispShape   *s;
 
410
 
 
411
        s = (DispShape *)gf_list_get(read->display_list, 0);
 
412
        gf_list_rem(read->display_list, 0);
 
413
        
 
414
        for (i = 0; i < gf_list_count(sdl); i++)
 
415
        {
 
416
            DispShape *s2 = (DispShape *)gf_list_get(sdl, i);
 
417
            if (s->depth < s2->depth) 
 
418
            {
 
419
                gf_list_insert(sdl, s, i);
 
420
                inserted = GF_TRUE;
 
421
                break;
 
422
            }
 
423
        }
 
424
        if (!inserted)
 
425
        {
 
426
            gf_list_add(sdl, s);
 
427
        }
 
428
    }
 
429
    gf_list_del(read->display_list);
 
430
    read->display_list = sdl;
 
431
 
 
432
    /* dumping the display list */
 
433
    len = gf_list_count(read->display_list);
 
434
    for (i=0; i<len; i++)
 
435
    {
 
436
        DispShape   *s;
 
437
        s = (DispShape *)gf_list_get(read->display_list, i);
 
438
        swf_svg_print(read, "<use xlink:href=\"#S%d\" ", s->char_id);
 
439
        //swf_svg_print(read, "z-index=\"%d\" ", s->depth);
 
440
        swf_svg_print_matrix(read, &s->mat);
 
441
        swf_svg_print(read, "/>\n");
 
442
                read->empty_frame = GF_FALSE;
 
443
    }
 
444
        if (!read->empty_frame) {
 
445
                read->print_frame_header = GF_TRUE;
 
446
                read->frame_header_offset = 0;
 
447
                swf_svg_print(read, "<g display=\"none\">\n");
 
448
                swf_svg_print(read, "<animate id=\"frame%d_anim\" attributeName=\"display\" to=\"inline\" ", read->current_frame);
 
449
                swf_svg_print(read, "begin=\"%g\" ", 1.0*(read->current_frame)/read->frame_rate);
 
450
                if (read->current_frame+1 < read->frame_count) {
 
451
                        swf_svg_print(read, "end=\"frame%d_anim.begin\" fill=\"remove\" ", (read->current_frame+1));
 
452
                } else {
 
453
                        swf_svg_print(read, "fill=\"freeze\" ");
 
454
                }
 
455
                swf_svg_print(read, "/>\n");
 
456
                read->print_frame_header = GF_FALSE;
 
457
 
 
458
                swf_svg_print(read, "</g>\n");
 
459
        }
 
460
        read->add_sample(read->user, read->svg_data, read->svg_data_size, read->current_frame*1000/read->frame_rate, (read->current_frame == 0));
 
461
        gf_free(read->svg_data);
 
462
        read->svg_data = NULL;
 
463
        read->svg_data_size = 0;
 
464
 
 
465
        read->empty_frame = GF_TRUE;
 
466
    return GF_OK;
 
467
}
 
468
 
 
469
static void swf_svg_finalize(SWFReader *read)
 
470
{
 
471
}
 
472
 
 
473
static GF_Err swf_svg_define_button(SWFReader *read, SWF_Button *btn)
 
474
{
 
475
    return GF_OK;
 
476
}
 
477
 
 
478
Bool swf_svg_action(SWFReader *read, SWFAction *act)
 
479
{
 
480
    return GF_TRUE;
 
481
}
 
482
 
 
483
GF_Err swf_to_svg_init(SWFReader *read, u32 swf_flags, Float swf_flatten_angle)
 
484
{
 
485
        if (!read->user) return GF_BAD_PARAM;
 
486
 
 
487
    /*init callbacks*/
 
488
    read->show_frame = swf_svg_show_frame;
 
489
    read->allocate_depth = swf_svg_allocate_depth;
 
490
    read->place_obj = swf_svg_place_obj;
 
491
    read->remove_obj = swf_svg_remove_obj;
 
492
    read->define_shape = swf_svg_define_shape;
 
493
    read->define_sprite = swf_svg_define_sprite;
 
494
    read->set_backcol = swf_svg_set_backcol;
 
495
    read->define_button = swf_svg_define_button;
 
496
    read->define_text = swf_svg_define_text;
 
497
    read->define_edit_text = swf_svg_define_edit_text;
 
498
    read->setup_sound = swf_svg_setup_sound;
 
499
    read->start_sound = swf_svg_start_sound;
 
500
    read->setup_image = swf_svg_setup_image;
 
501
    read->action = swf_svg_action;
 
502
    read->finalize = swf_svg_finalize;
 
503
 
 
504
        read->flags = swf_flags;
 
505
        read->flat_limit = FLT2FIX(swf_flatten_angle);
 
506
 
 
507
        read->print_stream_header = GF_TRUE;
 
508
        swf_svg_print(read, "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n");
 
509
        swf_svg_print(read, "<svg xmlns=\"http://www.w3.org/2000/svg\" ");
 
510
        swf_svg_print(read, "xmlns:xlink=\"http://www.w3.org/1999/xlink\" ");
 
511
        swf_svg_print(read, "width=\"100%%\" ");
 
512
        swf_svg_print(read, "height=\"100%%\" ");
 
513
        swf_svg_print(read, "viewBox=\"0 0 %d %d\" ", FIX2INT(read->width), FIX2INT(read->height));
 
514
        swf_svg_print(read, "viewport-fill=\"rgb(255,255,255)\" ");
 
515
        swf_svg_print(read, ">\n");
 
516
        read->print_stream_header = GF_FALSE;
 
517
 
 
518
        /* update sample description */
 
519
        read->add_header(read->user, read->svg_data, read->svg_data_size);
 
520
        gf_free(read->svg_data);
 
521
        read->svg_data = NULL;
 
522
        read->svg_data_size = 0;
 
523
 
 
524
        return GF_OK;
 
525
}
 
526
 
 
527
#endif /*GPAC_DISABLE_SWF_IMPORT*/
 
528
 
 
529
#else
 
530
GF_Err swf_to_svg_init(SWFReader *read, u32 swf_flags, Float swf_flatten_angle)
 
531
{
 
532
    return GF_NOT_SUPPORTED;
 
533
}
 
534
 
 
535
#endif /*GPAC_DISABLE_VRML*/