2 * Copyright (C) 2003-2006 David Schleef <ds@schleef.org>
3 * 2005-2006 Eric Anholt <eric@anholt.net>
4 * 2006-2007 Benjamin Otte <otte@gnome.org>
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public
8 * License as published by the Free Software Foundation; either
9 * version 2.1 of the License, or (at your option) any later version.
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Lesser General Public License for more details.
16 * You should have received a copy of the GNU Lesser General Public
17 * License along with this library; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin Street, Fifth Floor,
19 * Boston, MA 02110-1301 USA
26 #include "swfdec_shape_parser.h"
27 #include "swfdec_debug.h"
28 #include "swfdec_path.h"
29 #include "swfdec_stroke.h"
31 /*** PATH CONSTRUCTION ***/
34 SWFDEC_SHAPE_TYPE_END
= 0,
35 SWFDEC_SHAPE_TYPE_CHANGE
,
36 SWFDEC_SHAPE_TYPE_LINE
,
37 SWFDEC_SHAPE_TYPE_CURVE
40 static SwfdecShapeType
41 swfdec_shape_peek_type (SwfdecBits
*bits
)
43 guint ret
= swfdec_bits_peekbits (bits
, 6);
46 return SWFDEC_SHAPE_TYPE_END
;
47 if ((ret
& 0x20) == 0)
48 return SWFDEC_SHAPE_TYPE_CHANGE
;
49 if ((ret
& 0x10) == 0)
50 return SWFDEC_SHAPE_TYPE_CURVE
;
51 return SWFDEC_SHAPE_TYPE_LINE
;
61 swfdec_sub_path_match (SwfdecSubPath
*from
, SwfdecSubPath
*to
)
63 return from
->x_end
== to
->x_start
&& from
->y_end
== to
->y_start
;
67 SwfdecDraw
* draw
; /* drawing operation that should take the subpaths or NULL on parsing error */
68 GSList
* subpaths
; /* indexes into SubPath array */
71 struct _SwfdecShapeParser
{
73 GSList
* draws
; /* completely accumulated drawing commands */
74 SwfdecParseDrawFunc parse_fill
; /* function to call to parse a fill style */
75 SwfdecParseDrawFunc parse_line
; /* function to call to parse a line style */
76 gpointer data
; /* data to pass to parse functions */
77 /* used while parsing */
78 GArray
* fillstyles
; /* SwfdecStyle objects */
79 GArray
* linestyles
; /* SwfdecStyle objects */
80 GArray
* subpaths
; /* SwfdecSubPath partial paths */
86 /* for morph styles */
87 GArray
* subpaths2
; /* SwfdecSubPath partial paths */
96 swfdec_shape_parser_new_styles (SwfdecShapeParser
*parser
, SwfdecBits
*bits
)
98 guint i
, n_fill_styles
, n_line_styles
;
100 swfdec_bits_syncbits (bits
);
101 if (parser
->parse_fill
) {
102 n_fill_styles
= swfdec_bits_get_u8 (bits
);
103 if (n_fill_styles
== 0xff) {
104 n_fill_styles
= swfdec_bits_get_u16 (bits
);
106 SWFDEC_LOG (" n_fill_styles %d", n_fill_styles
);
107 g_array_set_size (parser
->fillstyles
, n_fill_styles
);
108 for (i
= 0; i
< n_fill_styles
&& swfdec_bits_left (bits
); i
++) {
109 g_array_index (parser
->fillstyles
, SwfdecStyle
, i
).draw
=
110 parser
->parse_fill (bits
, parser
->data
);
113 n_line_styles
= swfdec_bits_get_u8 (bits
);
114 if (n_line_styles
== 0xff) {
115 n_line_styles
= swfdec_bits_get_u16 (bits
);
117 SWFDEC_LOG (" n_line_styles %d", n_line_styles
);
118 g_array_set_size (parser
->linestyles
, n_line_styles
);
119 for (i
= 0; i
< n_line_styles
&& swfdec_bits_left (bits
); i
++) {
120 g_array_index (parser
->linestyles
, SwfdecStyle
, i
).draw
=
121 parser
->parse_line (bits
, parser
->data
);
124 /* This is the magic part for DefineFont */
125 g_array_set_size (parser
->fillstyles
, 1);
126 g_array_index (parser
->fillstyles
, SwfdecStyle
, 0).draw
=
127 SWFDEC_DRAW (swfdec_pattern_new_color (0xFFFFFFFF));
129 parser
->n_fill_bits
= swfdec_bits_getbits (bits
, 4);
130 parser
->n_line_bits
= swfdec_bits_getbits (bits
, 4);
135 swfdec_shape_parser_new (SwfdecParseDrawFunc parse_fill
,
136 SwfdecParseDrawFunc parse_line
, gpointer data
)
138 SwfdecShapeParser
*list
;
140 list
= g_slice_new0 (SwfdecShapeParser
);
141 list
->parse_fill
= parse_fill
;
142 list
->parse_line
= parse_line
;
144 list
->fillstyles
= g_array_new (FALSE
, TRUE
, sizeof (SwfdecStyle
));
145 list
->linestyles
= g_array_new (FALSE
, TRUE
, sizeof (SwfdecStyle
));
146 list
->subpaths
= g_array_new (FALSE
, TRUE
, sizeof (SwfdecSubPath
));
147 list
->subpaths2
= g_array_new (FALSE
, TRUE
, sizeof (SwfdecSubPath
));
153 swfdec_shape_parser_clear_one (GArray
*array
)
157 for (i
= 0; i
< array
->len
; i
++) {
158 SwfdecStyle
*style
= &g_array_index (array
, SwfdecStyle
, i
);
160 g_object_unref (style
->draw
);
161 g_slist_free (style
->subpaths
);
163 g_array_set_size (array
, 0);
167 swfdec_shape_parser_clear (SwfdecShapeParser
*list
)
171 swfdec_shape_parser_clear_one (list
->fillstyles
);
172 swfdec_shape_parser_clear_one (list
->linestyles
);
174 for (i
= 0; i
< list
->subpaths
->len
; i
++) {
175 SwfdecSubPath
*path
= &g_array_index (list
->subpaths
, SwfdecSubPath
, i
);
176 swfdec_path_reset (&path
->path
);
178 g_array_set_size (list
->subpaths
, 0);
179 for (i
= 0; i
< list
->subpaths2
->len
; i
++) {
180 SwfdecSubPath
*path
= &g_array_index (list
->subpaths2
, SwfdecSubPath
, i
);
181 swfdec_path_reset (&path
->path
);
183 g_array_set_size (list
->subpaths2
, 0);
187 swfdec_shape_parser_reset (SwfdecShapeParser
*parser
)
189 GSList
*draws
= parser
->draws
;
191 parser
->draws
= NULL
;
196 swfdec_shape_parser_free (SwfdecShapeParser
*parser
)
198 GSList
*draws
= parser
->draws
;
200 swfdec_shape_parser_clear (parser
);
201 g_array_free (parser
->fillstyles
, TRUE
);
202 g_array_free (parser
->linestyles
, TRUE
);
203 g_array_free (parser
->subpaths
, TRUE
);
204 g_array_free (parser
->subpaths2
, TRUE
);
205 g_slice_free (SwfdecShapeParser
, parser
);
207 draws
= g_slist_reverse (draws
);
211 /* NB: assumes all fill paths are closed */
213 swfdec_style_finish (SwfdecStyle
*style
, SwfdecSubPath
*paths
, SwfdecSubPath
*paths2
, gboolean line
)
217 /* checked before calling this function */
218 g_assert (style
->draw
);
220 /* accumulate paths one by one */
221 while (style
->subpaths
) {
222 SwfdecSubPath
*start
, *last
;
223 SwfdecSubPath
*start2
= NULL
, *last2
= NULL
;
225 last
= start
= &paths
[GPOINTER_TO_UINT (style
->subpaths
->data
)];
226 swfdec_path_move_to (&style
->draw
->path
, start
->x_start
, start
->y_start
);
227 swfdec_path_append (&style
->draw
->path
, &start
->path
);
229 last2
= start2
= &paths2
[GPOINTER_TO_UINT (style
->subpaths
->data
)];
230 swfdec_path_move_to (&style
->draw
->end_path
, start2
->x_start
, start2
->y_start
);
231 swfdec_path_append (&style
->draw
->end_path
, &start2
->path
);
233 style
->subpaths
= g_slist_delete_link (style
->subpaths
, style
->subpaths
);
234 while (!swfdec_sub_path_match (last
, start
) ||
235 (paths2
!= NULL
&& !swfdec_sub_path_match (last2
, start2
))) {
236 for (walk
= style
->subpaths
; walk
; walk
= walk
->next
) {
237 SwfdecSubPath
*cur
= &paths
[GPOINTER_TO_UINT (walk
->data
)];
238 if (swfdec_sub_path_match (last
, cur
)) {
240 SwfdecSubPath
*cur2
= &paths2
[GPOINTER_TO_UINT (walk
->data
)];
241 if (!swfdec_sub_path_match (last2
, cur2
))
243 swfdec_path_append (&style
->draw
->end_path
, &cur2
->path
);
246 swfdec_path_append (&style
->draw
->path
, &cur
->path
);
252 style
->subpaths
= g_slist_delete_link (style
->subpaths
, walk
);
255 SWFDEC_ERROR ("fill path not closed");
261 swfdec_draw_recompute (style
->draw
);
264 /* merge subpaths into draws, then reset */
266 swfdec_shape_parser_finish (SwfdecShapeParser
*parser
)
269 for (i
= 0; i
< parser
->fillstyles
->len
; i
++) {
270 SwfdecStyle
*style
= &g_array_index (parser
->fillstyles
, SwfdecStyle
, i
);
271 if (style
->draw
== NULL
)
273 if (style
->subpaths
) {
274 swfdec_style_finish (style
, (SwfdecSubPath
*) (void *) parser
->subpaths
->data
,
275 parser
->subpaths2
->len
? (SwfdecSubPath
*) (void *) parser
->subpaths2
->data
: NULL
, FALSE
);
276 parser
->draws
= g_slist_prepend (parser
->draws
, g_object_ref (style
->draw
));
278 SWFDEC_INFO ("fillstyle %u has no path", i
);
281 for (i
= 0; i
< parser
->linestyles
->len
; i
++) {
282 SwfdecStyle
*style
= &g_array_index (parser
->linestyles
, SwfdecStyle
, i
);
283 if (style
->draw
== NULL
)
285 if (style
->subpaths
) {
286 swfdec_style_finish (style
, (SwfdecSubPath
*) (void *) parser
->subpaths
->data
,
287 parser
->subpaths2
->len
? (SwfdecSubPath
*) (void *) parser
->subpaths2
->data
: NULL
, TRUE
);
288 parser
->draws
= g_slist_prepend (parser
->draws
, g_object_ref (style
->draw
));
290 SWFDEC_WARNING ("linestyle %u has no path", i
);
293 swfdec_shape_parser_clear (parser
);
297 swfdec_shape_parser_end_path (SwfdecShapeParser
*parser
, SwfdecSubPath
*path1
, SwfdecSubPath
*path2
,
298 int x1
, int y1
, int x2
, int y2
)
302 if (path1
->path
.num_data
== 0) {
303 SWFDEC_INFO ("ignoring empty path");
313 /* check our assumptions about morph styles */
314 if ((parser
->fill0style
!= parser
->fill0style2
&&
315 parser
->fill0style
!= parser
->fill1style2
) ||
316 (parser
->fill1style
!= parser
->fill0style2
&&
317 parser
->fill1style
!= parser
->fill1style2
)) {
318 SWFDEC_ERROR ("fillstyle assumptions don't hold for %u %u vs %u %u",
319 parser
->fill0style
, parser
->fill1style
, parser
->fill0style2
,
320 parser
->fill1style2
);
323 if (parser
->linestyle
!= parser
->linestyle2
) {
324 SWFDEC_ERROR ("linestyle change from %u to %u", parser
->linestyle
,
330 /* add the path to their styles */
331 if (parser
->fill0style
) {
332 if (parser
->fill0style
> parser
->fillstyles
->len
) {
333 SWFDEC_ERROR ("fillstyle too big (%u > %u)", parser
->fill0style
,
334 parser
->fillstyles
->len
);
336 SwfdecStyle
*style
= &g_array_index (parser
->fillstyles
,
337 SwfdecStyle
, parser
->fill0style
- 1);
338 style
->subpaths
= g_slist_prepend (style
->subpaths
,
339 GUINT_TO_POINTER (parser
->subpaths
->len
- 1));
342 if (parser
->fill1style
) {
343 if (parser
->fill1style
> parser
->fillstyles
->len
) {
344 SWFDEC_ERROR ("fillstyle too big (%u > %u)", parser
->fill1style
,
345 parser
->fillstyles
->len
);
347 SwfdecStyle
*style
= &g_array_index (parser
->fillstyles
,
348 SwfdecStyle
, parser
->fill1style
- 1);
350 if (swfdec_sub_path_match (path1
, path1
) &&
351 (path2
== NULL
|| swfdec_sub_path_match (path2
, path2
))) {
352 style
->subpaths
= g_slist_prepend (style
->subpaths
,
353 GUINT_TO_POINTER (parser
->subpaths
->len
- 1));
355 SwfdecSubPath reverse
;
356 SWFDEC_LOG ("reversing path from %d %d to %d %d", path1
->x_start
, path1
->y_start
,
357 path1
->x_end
, path1
->y_end
);
358 reverse
.x_start
= path1
->x_end
;
359 reverse
.y_start
= path1
->y_end
;
360 reverse
.x_end
= path1
->x_start
;
361 reverse
.y_end
= path1
->y_start
;
362 swfdec_path_init (&reverse
.path
);
363 swfdec_path_append_reverse (&reverse
.path
, &path1
->path
, reverse
.x_end
, reverse
.y_end
);
364 style
->subpaths
= g_slist_prepend (style
->subpaths
,
365 GUINT_TO_POINTER (parser
->subpaths
->len
));
366 g_array_append_val (parser
->subpaths
, reverse
);
368 reverse
.x_start
= path2
->x_end
;
369 reverse
.y_start
= path2
->y_end
;
370 reverse
.x_end
= path2
->x_start
;
371 reverse
.y_end
= path2
->y_start
;
372 swfdec_path_init (&reverse
.path
);
373 swfdec_path_append_reverse (&reverse
.path
, &path2
->path
, reverse
.x_end
, reverse
.y_end
);
374 g_array_append_val (parser
->subpaths2
, reverse
);
379 if (parser
->linestyle
) {
380 if (parser
->linestyle
> parser
->linestyles
->len
) {
381 SWFDEC_ERROR ("linestyle too big (%u > %u)", parser
->linestyle
,
382 parser
->linestyles
->len
);
384 SwfdecStyle
*style
= &g_array_index (parser
->linestyles
,
385 SwfdecStyle
, parser
->linestyle
- 1);
386 style
->subpaths
= g_slist_prepend (style
->subpaths
,
387 GUINT_TO_POINTER (parser
->subpaths
->len
- 1));
392 static SwfdecSubPath
*
393 swfdec_sub_path_create (GArray
*array
, int x
, int y
)
397 g_array_set_size (array
, array
->len
+ 1);
398 path
= &g_array_index (array
, SwfdecSubPath
, array
->len
- 1);
399 swfdec_path_init (&path
->path
);
406 static SwfdecSubPath
*
407 swfdec_shape_parser_parse_change (SwfdecShapeParser
*parser
, SwfdecBits
*bits
, int *x
, int *y
)
409 int state_new_styles
, state_line_styles
, state_fill_styles1
, state_fill_styles0
, state_moveto
;
412 if (swfdec_bits_getbit (bits
) != 0) {
413 g_assert_not_reached ();
416 state_new_styles
= swfdec_bits_getbit (bits
);
417 state_line_styles
= swfdec_bits_getbit (bits
);
418 state_fill_styles1
= swfdec_bits_getbit (bits
);
419 state_fill_styles0
= swfdec_bits_getbit (bits
);
420 state_moveto
= swfdec_bits_getbit (bits
);
423 int n_bits
= swfdec_bits_getbits (bits
, 5);
424 *x
= swfdec_bits_getsbits (bits
, n_bits
);
425 *y
= swfdec_bits_getsbits (bits
, n_bits
);
427 SWFDEC_LOG (" moveto %d,%d", *x
, *y
);
429 if (state_fill_styles0
) {
430 parser
->fill0style
= swfdec_bits_getbits (bits
, parser
->n_fill_bits
);
431 SWFDEC_LOG (" * fill0style = %d", parser
->fill0style
);
433 SWFDEC_LOG (" * not changing fill0style");
435 if (state_fill_styles1
) {
436 parser
->fill1style
= swfdec_bits_getbits (bits
, parser
->n_fill_bits
);
437 SWFDEC_LOG (" * fill1style = %d", parser
->fill1style
);
439 SWFDEC_LOG (" * not changing fill1style");
441 if (state_line_styles
) {
442 parser
->linestyle
= swfdec_bits_getbits (bits
, parser
->n_line_bits
);
443 SWFDEC_LOG (" * linestyle = %d", parser
->linestyle
);
445 SWFDEC_LOG (" * not changing linestyle");
447 if (state_new_styles
) {
448 SWFDEC_LOG (" * new styles");
449 swfdec_shape_parser_finish (parser
);
450 swfdec_shape_parser_new_styles (parser
, bits
);
452 path
= swfdec_sub_path_create (parser
->subpaths
, *x
, *y
);
457 swfdec_shape_parser_parse_curve (SwfdecBits
*bits
, SwfdecSubPath
*path
,
462 int control_x
, control_y
;
464 if (swfdec_bits_getbits (bits
, 2) != 2) {
465 g_assert_not_reached ();
468 n_bits
= swfdec_bits_getbits (bits
, 4) + 2;
473 control_x
= cur_x
+ swfdec_bits_getsbits (bits
, n_bits
);
474 control_y
= cur_y
+ swfdec_bits_getsbits (bits
, n_bits
);
475 SWFDEC_LOG (" control %d,%d", control_x
, control_y
);
477 *x
= control_x
+ swfdec_bits_getsbits (bits
, n_bits
);
478 *y
= control_y
+ swfdec_bits_getsbits (bits
, n_bits
);
479 SWFDEC_LOG (" anchor %d,%d", *x
, *y
);
481 swfdec_path_curve_to (&path
->path
,
483 control_x
, control_y
,
486 SWFDEC_ERROR ("no path to curve in");
491 swfdec_shape_parser_parse_line (SwfdecBits
*bits
, SwfdecSubPath
*path
,
492 int *x
, int *y
, gboolean add_as_curve
)
495 int general_line_flag
;
498 if (swfdec_bits_getbits (bits
, 2) != 3) {
499 g_assert_not_reached ();
504 n_bits
= swfdec_bits_getbits (bits
, 4) + 2;
505 general_line_flag
= swfdec_bits_getbit (bits
);
506 if (general_line_flag
== 1) {
507 *x
+= swfdec_bits_getsbits (bits
, n_bits
);
508 *y
+= swfdec_bits_getsbits (bits
, n_bits
);
510 int vert_line_flag
= swfdec_bits_getbit (bits
);
511 if (vert_line_flag
== 0) {
512 *x
+= swfdec_bits_getsbits (bits
, n_bits
);
514 *y
+= swfdec_bits_getsbits (bits
, n_bits
);
517 SWFDEC_LOG (" line to %d,%d", *x
, *y
);
520 swfdec_path_curve_to (&path
->path
, cur_x
, cur_y
,
521 (cur_x
+ *x
) / 2, (cur_y
+ *y
) / 2, *x
, *y
);
523 swfdec_path_line_to (&path
->path
, *x
, *y
);
525 SWFDEC_ERROR ("no path to line in");
530 swfdec_shape_parser_parse (SwfdecShapeParser
*parser
, SwfdecBits
*bits
)
533 SwfdecSubPath
*path
= NULL
;
534 SwfdecShapeType type
;
536 swfdec_shape_parser_new_styles (parser
, bits
);
538 while ((type
= swfdec_shape_peek_type (bits
))) {
540 case SWFDEC_SHAPE_TYPE_CHANGE
:
541 swfdec_shape_parser_end_path (parser
, path
, NULL
, x
, y
, 0, 0);
542 path
= swfdec_shape_parser_parse_change (parser
, bits
, &x
, &y
);
544 case SWFDEC_SHAPE_TYPE_LINE
:
545 swfdec_shape_parser_parse_line (bits
, path
, &x
, &y
, FALSE
);
547 case SWFDEC_SHAPE_TYPE_CURVE
:
548 swfdec_shape_parser_parse_curve (bits
, path
, &x
, &y
);
550 case SWFDEC_SHAPE_TYPE_END
:
552 g_assert_not_reached ();
556 swfdec_shape_parser_end_path (parser
, path
, NULL
, x
, y
, 0, 0);
557 swfdec_bits_getbits (bits
, 6);
558 swfdec_bits_syncbits (bits
);
560 swfdec_shape_parser_finish (parser
);
563 static SwfdecSubPath
*
564 swfdec_shape_parser_parse_morph_change (SwfdecShapeParser
*parser
,
565 SwfdecBits
*bits
, int *x
, int *y
)
568 int state_line_styles
, state_fill_styles1
, state_fill_styles0
, state_moveto
;
570 if (swfdec_bits_getbit (bits
) != 0) {
571 g_assert_not_reached ();
573 if (swfdec_bits_getbit (bits
)) {
574 SWFDEC_ERROR ("new styles aren't allowed in end edges, ignoring");
576 state_line_styles
= swfdec_bits_getbit (bits
);
577 state_fill_styles1
= swfdec_bits_getbit (bits
);
578 state_fill_styles0
= swfdec_bits_getbit (bits
);
579 state_moveto
= swfdec_bits_getbit (bits
);
581 int n_bits
= swfdec_bits_getbits (bits
, 5);
582 *x
= swfdec_bits_getsbits (bits
, n_bits
);
583 *y
= swfdec_bits_getsbits (bits
, n_bits
);
585 SWFDEC_LOG (" moveto %d,%d", *x
, *y
);
587 path
= swfdec_sub_path_create (parser
->subpaths2
, *x
, *y
);
588 if (state_fill_styles0
) {
589 parser
->fill0style2
= swfdec_bits_getbits (bits
, parser
->n_fill_bits2
);
591 if (state_fill_styles1
) {
592 parser
->fill1style2
= swfdec_bits_getbits (bits
, parser
->n_fill_bits2
);
594 if (state_line_styles
) {
595 parser
->linestyle2
= swfdec_bits_getbits (bits
, parser
->n_line_bits2
);
602 swfdec_shape_parser_parse_morph (SwfdecShapeParser
*parser
, SwfdecBits
*bits1
, SwfdecBits
*bits2
)
604 int x1
= 0, y1
= 0, x2
= 0, y2
= 0;
605 SwfdecSubPath
*path1
= NULL
, *path2
= NULL
;
606 SwfdecShapeType type1
, type2
;
608 swfdec_shape_parser_new_styles (parser
, bits1
);
609 parser
->n_fill_bits2
= swfdec_bits_getbits (bits2
, 4);
610 parser
->n_line_bits2
= swfdec_bits_getbits (bits2
, 4);
611 parser
->fill0style2
= parser
->fill0style
;
612 parser
->fill1style2
= parser
->fill1style
;
613 parser
->linestyle2
= parser
->linestyle
;
614 SWFDEC_LOG ("%u fill bits, %u line bits in end shape", parser
->n_fill_bits2
, parser
->n_line_bits2
);
616 while ((type1
= swfdec_shape_peek_type (bits1
))) {
617 type2
= swfdec_shape_peek_type (bits2
);
618 if (type2
== SWFDEC_SHAPE_TYPE_CHANGE
|| type1
== SWFDEC_SHAPE_TYPE_CHANGE
) {
619 swfdec_shape_parser_end_path (parser
, path1
, path2
, x1
, y1
, x2
, y2
);
620 if (type1
== SWFDEC_SHAPE_TYPE_CHANGE
) {
621 path1
= swfdec_shape_parser_parse_change (parser
, bits1
, &x1
, &y1
);
622 parser
->fill0style2
= parser
->fill0style
;
623 parser
->fill1style2
= parser
->fill1style
;
624 parser
->linestyle2
= parser
->linestyle
;
626 path1
= swfdec_sub_path_create (parser
->subpaths
, x1
, y1
);
628 if (type2
== SWFDEC_SHAPE_TYPE_CHANGE
) {
629 path2
= swfdec_shape_parser_parse_morph_change (parser
, bits2
, &x2
, &y2
);
631 path2
= swfdec_sub_path_create (parser
->subpaths2
, x2
, y2
);
636 case SWFDEC_SHAPE_TYPE_LINE
:
637 swfdec_shape_parser_parse_line (bits2
, path2
, &x2
, &y2
, type1
!= SWFDEC_SHAPE_TYPE_LINE
);
639 case SWFDEC_SHAPE_TYPE_CURVE
:
640 swfdec_shape_parser_parse_curve (bits2
, path2
, &x2
, &y2
);
642 case SWFDEC_SHAPE_TYPE_END
:
643 SWFDEC_ERROR ("morph shape ends too early, aborting");
645 case SWFDEC_SHAPE_TYPE_CHANGE
:
647 g_assert_not_reached ();
651 case SWFDEC_SHAPE_TYPE_LINE
:
652 swfdec_shape_parser_parse_line (bits1
, path1
, &x1
, &y1
, type2
!= SWFDEC_SHAPE_TYPE_LINE
);
654 case SWFDEC_SHAPE_TYPE_CURVE
:
655 swfdec_shape_parser_parse_curve (bits1
, path1
, &x1
, &y1
);
657 case SWFDEC_SHAPE_TYPE_CHANGE
:
658 case SWFDEC_SHAPE_TYPE_END
:
660 g_assert_not_reached ();
665 swfdec_shape_parser_end_path (parser
, path1
, path2
, x1
, y1
, x2
, y2
);
666 swfdec_bits_getbits (bits1
, 6);
667 swfdec_bits_syncbits (bits1
);
668 if (swfdec_bits_getbits (bits2
, 6) != 0) {
669 SWFDEC_ERROR ("end shapes are not finished when start shapes are");
671 swfdec_bits_syncbits (bits2
);
673 swfdec_shape_parser_finish (parser
);