2
* GPAC - Multimedia Framework C SDK
4
* Authors: Cyril Concolato
5
* Copyright (c) Telecom ParisTech 2000-2012
8
* This file is part of GPAC / Scene Management sub-project
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)
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.
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.
27
#include <gpac/internal/swf_dev.h>
28
#include <gpac/internal/scenegraph_dev.h>
30
#ifndef GPAC_DISABLE_VRML
32
#ifndef GPAC_DISABLE_SWF_IMPORT
34
#define SWF_TEXT_SCALE (1/1024.0f)
42
static void swf_svg_print_color(SWFReader *read, u32 ARGB)
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));
51
static void swf_svg_print_alpha(SWFReader *read, u32 ARGB)
54
alpha = INT2FIX((ARGB>>24)&0xFF)/255;
55
fprintf(read->svg_output, "%f", FIX2FLT(alpha));
58
static void swg_svg_print_shape_record_to_fill_stroke(SWFReader *read, SWFShapeRec *srec, Bool is_fill)
60
/*get regular appearance reuse*/
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, "\" ");
74
//if (read->flags & GF_SM_SWF_NO_GRADIENT) {
75
// u32 col = srec->grad_col[srec->nbGrad/2];
77
// n->appearance = s2b_get_appearance(read, (GF_Node *) n, col, 0, 0);
79
// n->appearance = s2b_get_gradient(read, (GF_Node *) n, shape, srec);
86
//n->appearance = s2b_get_bitmap(read, (GF_Node *) n, shape, srec);
89
swf_report(read, GF_NOT_SUPPORTED, "fill_style %x not supported", srec->type);
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));
104
static void swf_svg_print_shape_record_to_path_d(SWFReader *read, SWFShapeRec *srec)
110
for (i=0; i<srec->path->nbType; i++) {
111
switch (srec->path->types[i]) {
114
fprintf(read->svg_output, "M%f,%f", FIX2FLT(srec->path->pts[pt_idx].x), FIX2FLT(srec->path->pts[pt_idx].y));
119
fprintf(read->svg_output, "L%f,%f", FIX2FLT(srec->path->pts[pt_idx].x), FIX2FLT(srec->path->pts[pt_idx].y));
124
fprintf(read->svg_output, "Q%f,%f", FIX2FLT(srec->path->pts[pt_idx].x), FIX2FLT(srec->path->pts[pt_idx].y));
126
fprintf(read->svg_output, ",%f,%f", FIX2FLT(srec->path->pts[pt_idx].x), FIX2FLT(srec->path->pts[pt_idx].y));
133
static void swf_svg_print_matrix(SWFReader *read, GF_Matrix2D *mat)
135
if (!gf_mx2d_is_identity(*mat))
138
GF_Point2D translate;
140
if( gf_mx2d_decompose(mat, &scale, &rotate, &translate))
142
fprintf(read->svg_output, "transform=\"");
143
if (translate.x != 0 || translate.y != 0)
145
fprintf(read->svg_output, "translate(%f, %f) ", translate.x, translate.y);
149
fprintf(read->svg_output, "rotate(%f) ", rotate);
151
if (scale.x != FIX_ONE || scale.y != FIX_ONE)
153
fprintf(read->svg_output, "scale(%f, %f) ", scale.x, scale.y);
155
fprintf(read->svg_output, "\" ");
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]);
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)
170
if (parent_font && (read->flags & GF_SM_SWF_NO_FONT))
175
if (!read->cur_shape)
177
fprintf(read->svg_output, "<defs>\n");
180
fprintf(read->svg_output, "<g id=\"S%d\" >\n", shape->ID);
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);
190
read->cur_shape = (GF_Node *)"shape";
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");
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");
211
read->cur_shape = NULL;
212
fprintf(read->svg_output, "</g>\n");
213
fprintf(read->svg_output, "</defs>\n");
218
static GF_Err swf_svg_define_text(SWFReader *read, SWFText *text)
226
use_text = (read->flags & GF_SM_SWF_NO_FONT) ? 1 : 0;
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");
234
while ((gr = (SWFGlyphRec*)gf_list_enum(text->text, &i)))
238
ft = swf_find_font(read, gr->fontID);
239
if (!ft->glyph_codes) {
241
swf_report(read, GF_BAD_PARAM, "Font glyphs are not defined, cannot reference extern font - Forcing glyph embedding");
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));
252
fprintf(read->svg_output, "font-family=\"%s\" ", ft->fontName);
256
fprintf(read->svg_output, "font-style=\"italic\" ");
260
fprintf(read->svg_output, "font-weight=\"bold\" ");
262
fprintf(read->svg_output, ">");
269
str_w = (u16*)gf_malloc(sizeof(u16) * (gr->nbGlyphs+1));
270
for (j=0; j<gr->nbGlyphs; j++)
272
str_w[j] = ft->glyph_codes[gr->indexes[j]];
275
str = (char*)gf_malloc(sizeof(char) * (gr->nbGlyphs+2));
277
j = gf_utf8_wcstombs(str, sizeof(u8) * (gr->nbGlyphs+1), (const unsigned short **) &widestr);
280
fprintf(read->svg_output, "%s", str);
283
fprintf(read->svg_output, "</text>\n");
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));
293
for (j=0; j<gr->nbGlyphs; j++)
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))));
298
fprintf(read->svg_output, "</g>\n");
301
fprintf(read->svg_output, "</g>\n");
302
fprintf(read->svg_output, "</defs>\n");
306
static GF_Err swf_svg_define_edit_text(SWFReader *read, SWFEditText *text)
311
//M_Layout *layout = NULL;
317
//tr = (M_Transform2D *) s2s_new_node(read, TAG_MPEG4_Transform2D);
318
//tr->scale.y = -FIX_ONE;
321
//if (text->align==3) use_layout = 1;
322
//else if (text->multiline) use_layout = 1;
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;
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);
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;
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) {
343
// ((SFString*)ptr)->buffer = gf_strdup("BEGIN");
346
// ((SFString*)ptr)->buffer = gf_strdup("END");
349
// ((SFString*)ptr)->buffer = gf_strdup("JUSTIFY");
352
// ((SFString*)ptr)->buffer = gf_strdup("MIDDLE");
356
//strcpy(styles, "");
357
//if (!text->read_only) strcat(styles, "EDITABLE");
358
//if (text->password) strcat(styles, "PASSWORD");
360
//if (f->style.buffer) gf_free(f->style.buffer);
361
//f->style.buffer = gf_strdup(styles);
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);
368
// GF_SAXParser *xml;
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);
378
// ((SFString*)ptr)->buffer = gf_strdup(flat.final);
379
// gf_free(flat.final);
382
// ((SFString*)ptr)->buffer = gf_strdup(text->init_value);
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);
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) {
397
// layout->justify.vals[0] = gf_strdup("BEGIN");
400
// layout->justify.vals[0] = gf_strdup("END");
403
// layout->justify.vals[0] = gf_strdup("JUSTIFY");
406
// layout->justify.vals[0] = gf_strdup("MIDDLE");
409
// if (text->multiline || text->word_wrap) layout->wrap = 1;
411
// gf_node_insert_child((GF_Node *) layout, (GF_Node *)txt, -1);
412
// gf_node_register((GF_Node *) txt, (GF_Node *) layout);
414
// gf_node_insert_child((GF_Node *) tr, (GF_Node *)layout, -1);
415
// gf_node_register((GF_Node *) layout, (GF_Node *) tr);
417
// gf_node_insert_child((GF_Node *) tr, (GF_Node *)txt, -1);
418
// gf_node_register((GF_Node *) txt, (GF_Node *) tr);
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);
433
/*called upon end of sprite or clip*/
434
static void swf_svg_end_of_clip(SWFReader *read)
440
//GF_CommandField *f;
445
//empty = gf_sg_find_node_by_name(read->load->scene_graph, "Shape0");
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);
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;
459
// f->fieldIndex = 2; /*children index*/
460
// f->new_node = empty;
461
// gf_node_register(f->new_node, com->node);
463
// gf_list_insert(au->commands, com, i);
468
static Bool swf_svg_allocate_depth(SWFReader *read, u32 depth)
471
//GF_Node *disp, *empty;
472
//if (read->max_depth > depth) return 1;
474
//sprintf(szDEF, "CLIP%d_DL", read->current_sprite_id);
475
//disp = gf_sg_find_node_by_name(read->load->scene_graph, szDEF);
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++;
486
static GF_Err swf_svg_define_sprite(SWFReader *read, u32 nb_frames)
489
//GF_ObjectDescriptor *od;
495
//GF_StreamContext *prev_sc;
496
//GF_AUContext *prev_au;
499
//e = swf_init_od(read, 0);
502
///*create animationStream object*/
503
//od = (GF_ObjectDescriptor *) gf_odf_desc_new(GF_ODF_OD_TAG);
504
//if (!od) return GF_OUT_OF_MEM;
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);
521
///*by default insert OD at begining*/
522
//e = swf_insert_od(read, 0, od);
524
// gf_odf_desc_del((GF_Descriptor *) od);
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);
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;
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);
544
//gf_node_insert_child(read->root, n, 0);
545
//gf_node_register(n, read->root);
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;
554
///*create sprite grouping node*/
555
//n = s2s_new_node(read, TAG_MPEG4_Group);
556
//sprintf(szDEF, "CLIP%d_DL", read->current_sprite_id);
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");
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);
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;
577
///*create first AU*/
578
//read->bifs_au = gf_sm_stream_au_new(read->bifs_es, 0, 0, 1);
580
//e = swf_parse_sprite(read);
583
//swf_svg_end_of_clip(read);
585
///*restore BIFS context*/
586
//read->bifs_es = prev_sc;
587
//read->bifs_au = prev_au;
592
static GF_Err swf_svg_setup_sound(SWFReader *read, SWFSound *snd, Bool soundstream_first_block)
595
// GF_ObjectDescriptor *od;
599
// GF_FieldInfo info;
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);
611
// gf_node_insert_child(read->root, n, 0);
612
// gf_node_register(n, read->root);
616
// e = swf_init_od(read, 0);
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);
627
// /*sound runs on its own timeline*/
628
// esd->OCRESID = esd->ESID;
630
// /*soundstream runs on movie/sprite timeline*/
631
// esd->OCRESID = read->bifs_es->ESID;
632
// esd->OCRESID = esd->ESID;
634
// gf_list_add(od->ESDescriptors, esd);
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);
646
// /*by default insert OD at begining*/
647
// e = swf_insert_od(read, 0, od);
649
// gf_odf_desc_del((GF_Descriptor *) od);
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);
657
// n = s2s_new_node(read, TAG_MPEG4_AudioClip);
658
// ((M_Sound2D *)par)->source = n;
659
// gf_node_register(n, par);
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;
665
// ((M_AudioClip*)n)->startTime = -1.0;
667
// /*regular sound: set an ID to do play/stop*/
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);
674
// /*soundStream - add a MediaControl*/
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;
680
// /*otherwise start the media at the first soundstream block*/
682
// ((M_AudioClip*)n)->startTime = snd->frame_delay_ms/1000.0;
683
// ((M_AudioClip*)n)->startTime = 0;
686
// sprintf(szDEF, "CLIP%d_SND", read->current_sprite_id);
687
// n = gf_sg_find_node_by_name(read->load->scene_graph, szDEF);
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;
695
// /*inactive by default (until inserted)*/
696
// if (read->current_sprite_id) {
697
// ((M_MediaControl *)n)->mediaSpeed = 0;
699
// ((M_MediaControl *)n)->mediaSpeed = FIX_ONE;
705
static GF_Err swf_svg_setup_image(SWFReader *read, u32 ID, char *fileName)
709
//GF_ObjectDescriptor *od;
716
//e = swf_init_od(read, 0);
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);
730
//mux = (GF_MuxInfo*)gf_odf_desc_new(GF_ODF_MUXINFO_TAG);
732
//mux->file_name = gf_strdup(fileName);
733
///*destroy file once done*/
734
////mux->delete_file = 1;
735
//gf_list_add(esd->extensionDescriptors, mux);
738
///*by default insert OD at begining*/
739
//e = swf_insert_od(read, 0, od);
741
// gf_odf_desc_del((GF_Descriptor *) od);
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);
752
//n = s2s_new_node(read, TAG_MPEG4_ImageTexture);
753
//((M_Appearance *)par)->texture = n;
754
//gf_node_register(n, par);
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);
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;
769
static GF_Err swf_svg_set_backcol(SWFReader *read, u32 xrgb)
772
//GF_Node *bck = gf_sg_find_node_by_name(read->load->scene_graph, "BACKGROUND");
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);
781
static GF_Err swf_svg_start_sound(SWFReader *read, SWFSound *snd, Bool stop)
787
//sprintf(szDEF, "Sound%d", snd->ID);
788
//sound2D = gf_sg_find_node_by_name(read->load->scene_graph, szDEF);
791
// s2s_set_field(read, read->bifs_au->commands, sound2D, stop ? "stopTime" : "startTime", -1, GF_SG_VRML_SFTIME, &t, 0);
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)
798
//fprintf(read->svg_output, "<use xlink:href=\"#S%d\" z-index=\"%d\" ", ID, depth);
800
// swf_svg_print_matrix(read, mat);
802
//fprintf(read->svg_output, "/>\n");
805
//GF_CommandField *f;
806
//GF_Node *obj, *par;
810
//obj = s2s_get_node(read, ID);
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;
817
//if (!obj) return GF_BAD_PARAM;
819
///*then add cmat/mat and node*/
820
//par = s2s_wrap_node(read, obj, mat, cmat);
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;
831
//f->fieldIndex = 2; /*children index*/
833
//gf_node_register(f->new_node, com->node);
834
//gf_list_add(read->bifs_au->commands, com);
836
//if (ID==prev_id) return GF_OK;
838
//strcpy(szDEF, gf_node_get_name(obj));
839
///*when inserting a button, trigger a pause*/
840
//if (!strnicmp(szDEF, "Button", 6)) {
842
// s2s_control_sprite(read, read->bifs_au->commands, read->current_sprite_id, 1, 0, 0, 1);
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);
853
//else if (is_sprite) {
854
// s2s_control_sprite(read, read->bifs_au->commands, ID, 0, 1, 0, 0);
856
// s2s_control_sprite(read, read->bifs_au->commands, prev_id, 1, 0, 0, 0);
862
static GF_Err swf_svg_remove_obj(SWFReader *read, u32 depth, u32 ID)
867
static GF_Err swf_svg_show_frame(SWFReader *read)
871
GF_List *sdl = gf_list_new(); // sorted display list
873
/* sorting the display list */
874
while (gf_list_count(read->display_list))
879
s = (DispShape *)gf_list_get(read->display_list, 0);
880
gf_list_rem(read->display_list, 0);
882
for (i = 0; i < gf_list_count(sdl); i++)
884
DispShape *s2 = (DispShape *)gf_list_get(sdl, i);
885
if (s->depth < s2->depth)
887
gf_list_insert(sdl, s, i);
897
gf_list_del(read->display_list);
898
read->display_list = sdl;
900
/* dumping the display list */
901
len = gf_list_count(read->display_list);
902
for (i=0; i<len; i++)
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");
910
fprintf(read->svg_output, "</g>\n");
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"));
919
static void swf_svg_finalize(SWFReader *read)
923
//swf_svg_end_of_clip(read);
925
//while (gf_list_count(read->buttons)) {
926
// s2sBtnRec *btnrec = gf_list_get(read->buttons, 0);
927
// gf_list_rem(read->buttons, 0);
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);
940
fprintf(read->svg_output, "</g>\n");
941
fprintf(read->svg_output, "</svg>\n");
942
fclose(read->svg_output);
945
static GF_Err swf_svg_define_button(SWFReader *read, SWF_Button *btn)
949
//SWF_ButtonRecord *br;
950
//GF_Node *btn_root, *n, *btn_ts;
955
// read->btn_over = read->btn_not_over = read->btn_active = read->btn_not_active = NULL;
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);
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;
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);
977
// sprintf(szName, "CLIP%d_DL", br->character_id);
978
// character = gf_sg_find_node_by_name(read->load->scene_graph, szName);
981
// gf_node_list_add_child(&((GF_ParentNode*)n)->children, character);
982
// gf_node_register(character, (GF_Node *)n);
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);
989
//s2s_insert_symbol(read, (GF_Node *)btn_root);
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);
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);
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);
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);
1015
///*by default show first character*/
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;
1023
// character = s2s_get_node(read, br->character_id);
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);
1029
// sprintf(szName, "CLIP%d_CTRL", br->character_id);
1030
// sprite_ctrl = gf_sg_find_node_by_name(read->load->scene_graph, szName);
1034
// SFInt32 choice = 0;
1035
// GF_Node *n = s2s_wrap_node(read, character, &br->mx, &br->cmx);
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);
1041
// gf_node_list_add_child(&button->choice, n);
1042
// gf_node_register(n, (GF_Node *)button);
1043
// /*initial state*/
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);
1057
// button->whichChoice = -1;
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);
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);
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);
1079
// s2s_control_sprite(read, read->btn_not_active, br->character_id, choice, 1, 0, 0);
1087
Bool swf_svg_action(SWFReader *read, SWFAction *act)
1096
// dst = read->bifs_au->commands;
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;
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;
1109
// case GF_SWF_AS3_GOTO_FRAME:
1110
// if (act->frame_number>read->current_frame)
1111
// read->wait_frame = act->frame_number;
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);
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);
1124
// s2s_set_field(read, dst, n, "activate", -1, GF_SG_VRML_SFBOOL, &bval, 0);
1126
// case GF_SWF_AS3_PLAY:
1127
// s2s_control_sprite(read, dst, read->current_sprite_id, 0, 1, -1, 0);
1129
// case GF_SWF_AS3_STOP:
1130
// s2s_control_sprite(read, dst, read->current_sprite_id, 1, 0, 0, 0);
1139
GF_Err swf_to_svg_init(SWFReader *read)
1141
char szFileName[GF_MAX_PATH];
1142
sprintf(szFileName, "%s.svg", read->load->fileName);
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;
1174
#endif /*GPAC_DISABLE_SWF_IMPORT*/
1177
GF_Err swf_to_svg_init(SWFReader *read)
1179
return GF_NOT_SUPPORTED;
1182
#endif /*GPAC_DISABLE_VRML*/
2
* GPAC - Multimedia Framework C SDK
4
* Authors: Cyril Concolato
5
* Copyright (c) Telecom ParisTech 2000-2012
8
* This file is part of GPAC / Scene Management sub-project
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)
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.
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.
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>
33
#ifndef GPAC_DISABLE_VRML
35
#ifndef GPAC_DISABLE_SWF_IMPORT
37
#define SWF_TEXT_SCALE (1/1024.0f)
39
typedef struct _swf_svg_sample
46
static void swf_svg_print(SWFReader *read, const char *format, ...) {
53
va_start(args, format);
54
vsprintf(line, format, 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;
66
strcpy(read->svg_data+read->svg_data_size, line);
68
read->svg_data_size = new_size;
71
static void swf_svg_print_color(SWFReader *read, u32 ARGB)
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));
80
static void swf_svg_print_alpha(SWFReader *read, u32 ARGB)
83
alpha = INT2FIX((ARGB>>24)&0xFF)/255;
84
swf_svg_print(read, "%g", FIX2FLT(alpha));
87
static void swg_svg_print_shape_record_to_fill_stroke(SWFReader *read, SWFShapeRec *srec, Bool is_fill)
89
/*get regular appearance reuse*/
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, "\" ");
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);
108
// n->appearance = s2b_get_gradient(read, (GF_Node *) n, shape, srec);
115
//n->appearance = s2b_get_bitmap(read, (GF_Node *) n, shape, srec);
118
swf_report(read, GF_NOT_SUPPORTED, "fill_style %x not supported", srec->type);
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));
133
static void swf_svg_print_shape_record_to_path_d(SWFReader *read, SWFShapeRec *srec)
139
for (i=0; i<srec->path->nbType; i++) {
140
switch (srec->path->types[i]) {
143
swf_svg_print(read, "M%g,%g", FIX2FLT(srec->path->pts[pt_idx].x), FIX2FLT(srec->path->pts[pt_idx].y));
148
swf_svg_print(read, "L%g,%g", FIX2FLT(srec->path->pts[pt_idx].x), FIX2FLT(srec->path->pts[pt_idx].y));
153
swf_svg_print(read, "Q%g,%g", FIX2FLT(srec->path->pts[pt_idx].x), FIX2FLT(srec->path->pts[pt_idx].y));
155
swf_svg_print(read, ",%g,%g", FIX2FLT(srec->path->pts[pt_idx].x), FIX2FLT(srec->path->pts[pt_idx].y));
162
static void swf_svg_print_matrix(SWFReader *read, GF_Matrix2D *mat)
164
if (!gf_mx2d_is_identity(*mat))
167
GF_Point2D translate;
169
if( gf_mx2d_decompose(mat, &scale, &rotate, &translate))
171
swf_svg_print(read, "transform=\"");
172
if (translate.x != 0 || translate.y != 0)
174
swf_svg_print(read, "translate(%g, %g) ", FIX2FLT(translate.x), FIX2FLT(translate.y));
178
swf_svg_print(read, "rotate(%g) ", FIX2FLT(rotate));
180
if (scale.x != FIX_ONE || scale.y != FIX_ONE)
182
swf_svg_print(read, "scale(%g, %g) ", FIX2FLT(scale.x), FIX2FLT(scale.y));
184
swf_svg_print(read, "\" ");
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]) );
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)
199
if (parent_font && (read->flags & GF_SM_SWF_NO_FONT))
204
if (!read->svg_shape_started)
206
swf_svg_print(read, "<defs>\n");
209
swf_svg_print(read, "<g id=\"S%d\" >\n", shape->ID);
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);
219
read->empty_frame = GF_FALSE;
220
read->svg_shape_started = GF_TRUE;
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");
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");
241
read->svg_shape_started = GF_FALSE;
242
swf_svg_print(read, "</g>\n");
243
swf_svg_print(read, "</defs>\n");
248
static GF_Err swf_svg_define_text(SWFReader *read, SWFText *text)
256
use_text = (read->flags & GF_SM_SWF_NO_FONT) ? 1 : 0;
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");
264
while ((gr = (SWFGlyphRec*)gf_list_enum(text->text, &i)))
268
ft = swf_find_font(read, gr->fontID);
269
if (!ft->glyph_codes) {
271
swf_report(read, GF_BAD_PARAM, "Font glyphs are not defined, cannot reference extern font - Forcing glyph embedding");
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));
282
swf_svg_print(read, "font-family=\"%s\" ", ft->fontName);
286
swf_svg_print(read, "font-style=\"italic\" ");
290
swf_svg_print(read, "font-weight=\"bold\" ");
292
swf_svg_print(read, ">");
300
str_w = (u16*)gf_malloc(sizeof(u16) * (gr->nbGlyphs+1));
301
for (j=0; j<gr->nbGlyphs; j++)
303
str_w[j] = ft->glyph_codes[gr->indexes[j]];
306
str = (char*)gf_malloc(sizeof(char) * (gr->nbGlyphs+2));
308
_len = gf_utf8_wcstombs(str, sizeof(u8) * (gr->nbGlyphs+1), (const unsigned short **) &widestr);
309
if (_len != (size_t) -1) {
311
swf_svg_print(read, "%s", str);
314
swf_svg_print(read, "</text>\n");
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));
324
for (j=0; j<gr->nbGlyphs; j++)
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))));
329
swf_svg_print(read, "</g>\n");
332
read->empty_frame = GF_FALSE;
333
swf_svg_print(read, "</g>\n");
334
swf_svg_print(read, "</defs>\n");
338
static GF_Err swf_svg_define_edit_text(SWFReader *read, SWFEditText *text)
344
/*called upon end of sprite or clip*/
345
static void swf_svg_end_of_clip(SWFReader *read)
350
static Bool swf_svg_allocate_depth(SWFReader *read, u32 depth)
355
static GF_Err swf_svg_define_sprite(SWFReader *read, u32 nb_frames)
360
static GF_Err swf_svg_setup_sound(SWFReader *read, SWFSound *snd, Bool soundstream_first_block)
365
static GF_Err swf_svg_setup_image(SWFReader *read, u32 ID, char *fileName)
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");
373
static GF_Err swf_svg_set_backcol(SWFReader *read, u32 xrgb)
376
//rgb.red = INT2FIX((xrgb>>16) & 0xFF) / 255;
377
//rgb.green = INT2FIX((xrgb>>8) & 0xFF) / 255;
378
//rgb.blue = INT2FIX((xrgb) & 0xFF) / 255;
382
static GF_Err swf_svg_start_sound(SWFReader *read, SWFSound *snd, Bool stop)
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)
389
read->empty_frame = GF_FALSE;
393
static GF_Err swf_svg_remove_obj(SWFReader *read, u32 depth, u32 ID)
395
read->empty_frame = GF_FALSE;
399
static GF_Err swf_svg_show_frame(SWFReader *read)
403
GF_List *sdl = gf_list_new(); // sorted display list
405
/* sorting the display list because SVG/CSS z-index is not well supported */
406
while (gf_list_count(read->display_list))
408
Bool inserted = GF_FALSE;
411
s = (DispShape *)gf_list_get(read->display_list, 0);
412
gf_list_rem(read->display_list, 0);
414
for (i = 0; i < gf_list_count(sdl); i++)
416
DispShape *s2 = (DispShape *)gf_list_get(sdl, i);
417
if (s->depth < s2->depth)
419
gf_list_insert(sdl, s, i);
429
gf_list_del(read->display_list);
430
read->display_list = sdl;
432
/* dumping the display list */
433
len = gf_list_count(read->display_list);
434
for (i=0; i<len; i++)
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;
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));
453
swf_svg_print(read, "fill=\"freeze\" ");
455
swf_svg_print(read, "/>\n");
456
read->print_frame_header = GF_FALSE;
458
swf_svg_print(read, "</g>\n");
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;
465
read->empty_frame = GF_TRUE;
469
static void swf_svg_finalize(SWFReader *read)
473
static GF_Err swf_svg_define_button(SWFReader *read, SWF_Button *btn)
478
Bool swf_svg_action(SWFReader *read, SWFAction *act)
483
GF_Err swf_to_svg_init(SWFReader *read, u32 swf_flags, Float swf_flatten_angle)
485
if (!read->user) return GF_BAD_PARAM;
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;
504
read->flags = swf_flags;
505
read->flat_limit = FLT2FIX(swf_flatten_angle);
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;
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;
527
#endif /*GPAC_DISABLE_SWF_IMPORT*/
530
GF_Err swf_to_svg_init(SWFReader *read, u32 swf_flags, Float swf_flatten_angle)
532
return GF_NOT_SUPPORTED;
535
#endif /*GPAC_DISABLE_VRML*/