1 /* libsswf.h -- written by Alexis WILKE for Made to Order Software Corp. (c) 2002-2009 */
2 #ifndef LIBSSWF_H
3 #define LIBSSWF_H
4
5 /*
6
7 Copyright (c) 2002-2009 Made to Order Software Corp.
8
9 Permission is hereby granted, free of charge, to any
10 person obtaining a copy of this software and
11 associated documentation files (the "Software"), to
12 deal in the Software without restriction, including
13 without limitation the rights to use, copy, modify,
14 merge, publish, distribute, sublicense, and/or sell
15 copies of the Software, and to permit persons to whom
16 the Software is furnished to do so, subject to the
17 following conditions:
18
19 The above copyright notice and this permission notice
20 shall be included in all copies or substantial
21 portions of the Software.
22
23 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF
24 ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT
25 LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
26 FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO
27 EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
28 LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
29 WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
30 ARISING FROM, OUT OF OR IN CONNECTION WITH THE
31 SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
32 SOFTWARE.
33
34 */
35
36 /** \file
37 *
38 * \brief The header to include to use the SSWF C++ library
39 *
40 * The libsswf.h file includes all the necessary classes
41 * for the SSWF library.
42 */
43
44
45
46 #include <stdarg.h>
47 #include <stdio.h>
48 #include <stdlib.h>
49 #ifndef _MSVC
50 #include <unistd.h>
51 #endif
52 #include <string.h>
53 #include <limits.h>
54 #include <errno.h>
55 #include <zlib.h>
56 #include <math.h>
57 #include <ctype.h>
58 #include <wctype.h>
59 #ifdef STATIC_ICONV
60 #include <iconv.h.static>
61 #else
62 #include <iconv.h>
63 #endif
64
65 #if IRIX
66 #include <sys/endian.h>
67 #endif
68
69 #include "sswf/libsswf-config.h"
70
71 #ifndef M_PI
72 #define M_PI 3.14159265358979323846
73 #endif
74
75
76 #ifdef _MSVC
77 #define strcasecmp stricmp
78 #define rint(x) ((double) (long) floor(x + 0.5))
79 #endif
80
81 #if defined(_LIBICONV_VERSION) && _LIBICONV_VERSION < 0x010B
82 #define ICONV_INPUT_CAST
83 #else
84 /* older versions of iconv() were broken in regard to the
85 * input buffer which wasn't const; newer versions have the
86 * _LIBICONV_H #define at the start so this is good to know
87 * whether we have to cast or not.
88 */
89 #define ICONV_INPUT_CAST (char**)
90 #endif
91
92
93
94 /* The following I use to tell my C++ to C tool
95 * what needs to be exposed in C & PHP.
96 * These macros show you what is equivalent in C++
97 *
98 * exposed_class A class we want exposed in C.
99 *
100 * invisible Members which are public in C++ but
101 * not exposed to C users.
102 */
103 #define exposed_class class
104 #define invisible public
105
106
107
108 /** \brief The C++ SSWF library namespace
109 *
110 * The SSWF library is fully defined with the 'sswf' namespace.
111 *
112 * Do 'using namespace sswf;' to "get rid of it".
113 *
114 * The SSWF library is a full set of classes and functions used to create
115 * SWF binary files. The library supports most of the tags available in
116 * SWF and is used to compress them in the appropriate format for use
117 * by a Flash player.
118 *
119 * One important point about this library: it hides from you, the user,
120 * the lower layers of the SWF tags. For one thing, you will never have
121 * to worry about how to compress the data in a valid SWF tag. But not
122 * only that, the library takes care of selecting the appropriate tag
123 * depending on the output movie version and what each tag support.
124 *
125 * For instance, when you create a TagFont, the library hides from you
126 * the fact that it supports 3 different types of DefineFont tags (and
127 * once version 8 is supported, it will hide the DefineFontAlignZones).
128 * This means you don't need to know all the details of how to create
129 * a font. Such details are important for the library, but not to you.
130 *
131 * None the less, it is complicated to create a valid SWF shape and the
132 * library does not do that automatically for you. For more information
133 * about each specific tag, please read the corresponding documentation.
134 */
135 namespace sswf
136 {
137
138
139
140
141 void assert(int cond, const char *format, ...)
142 #ifndef _MSVC
143 __attribute__ ((format (printf, 2, 3)))
144 #endif
145 ;
146
147
148 #if DEBUG
assert(int cond,const char * format,...)149 inline void assert(int cond, const char *format, ...)
150 {
151 va_list ap;
152
153 // if the condition is true then we have no problem!
154 if(cond) {
155 return;
156 }
157 fflush(stdout);
158 fflush(stderr);
159 fprintf(stderr, "\n");
160 va_start(ap, format);
161 vfprintf(stderr, format, ap);
162 va_end(ap);
163 fprintf(stderr, ".\n");
164 fflush(stderr); // some systems don't do this inside the abort()!
165 abort();
166 }
167 #else
assert(int,const char *,...)168 inline void assert(int /*cond*/, const char * /*format*/, ...) {}
169 #endif
170
171
172 typedef unsigned short sswf_id_t; // object ID reference
173 typedef unsigned short sswf_frame_t; // frame counter
174 typedef int32_t sswf_ucs4_t; // a wide character (must be at least 32 bits)
175
176
177 #define SSWF_ID_NONE ((sswf_id_t) -1) // this is an invalid ID (it seems)
178
179
180 extern void swap(void *s1, void *s2, size_t size);
181 extern int wctomb(const sswf_ucs4_t *wc, size_t wc_len, char *mb, size_t& mb_size);
182 extern int mbtowc(const char *mb, size_t mb_len, sswf_ucs4_t *& wc, size_t& wc_len);
183 extern char * wcname(sswf_ucs4_t wc, char *result);
184 extern long wcslen(sswf_ucs4_t *wcstr);
185
swap_short(unsigned short s)186 inline unsigned short swap_short(unsigned short s)
187 {
188 return (s >> 8) | (s << 8);
189 }
190
swap_int(unsigned int l)191 inline unsigned int swap_int(unsigned int l)
192 {
193 return (l >> 24) | (l << 24)
194 | ((l >> 8) & 0x0000FF00)
195 | ((l << 8) & 0x00FF0000);
196 }
197
198 extern const char * sswf_version(void);
199
200
201
202
203 /*
204 * Your class derives from ErrorManager::ErrorHandler, you pass a pointer
205 * to the TagHeader object and whenever an error occurs in the SSWF
206 * library, the OnError() function is called. You can then decide what to do
207 * (i.e. print the message in a file and then throw, exit or return...)
208 */
209 exposed_class ErrorManager
210 {
211 public:
212 enum error_code_t {
213 ERROR_CODE_NONE = 0,
214
215 ERROR_CODE_ACTION_OVERFLOW,
216 ERROR_CODE_ALPHA_MISMATCH,
217 ERROR_CODE_BAD_STATE_FLAGS,
218 ERROR_CODE_BUTTON_MISSING_STATE,
219 ERROR_CODE_CANNOT_CHANGE_STYLE,
220 ERROR_CODE_CHILDREN_NOT_SUPPORTED,
221 ERROR_CODE_COMPRESSED_SOUND_8BITS,
222 ERROR_CODE_EMPTY_POSITION_RANGE,
223 ERROR_CODE_ENDED_ACTION_SCRIPT,
224 ERROR_CODE_ENHANCED_LINE_REQUIRES_ALPHA,
225 ERROR_CODE_ENVELOPE_EXISTS,
226 ERROR_CODE_ENVELOPE_OVERFLOW,
227 ERROR_CODE_FILE_NOT_FOUND,
228 ERROR_CODE_FORMAT_LOCKED,
229 ERROR_CODE_GLYPH_DEFINED_TWICE,
230 ERROR_CODE_ICONV_ENCODER_NOT_AVAILABLE,
231 ERROR_CODE_ICONV_FAILED,
232 ERROR_CODE_IO,
233 ERROR_CODE_INCOMPATIBLE_CHILD,
234 ERROR_CODE_INCOMPATIBLE_MORPH,
235 ERROR_CODE_INTERNAL_ERROR,
236 ERROR_CODE_INVALID_DEPTH,
237 ERROR_CODE_INVALID_EM_SQUARE,
238 ERROR_CODE_INVALID_FILL_PARAMETER,
239 ERROR_CODE_INVALID_FOCAL,
240 ERROR_CODE_INVALID_GLYPH,
241 ERROR_CODE_INVALID_IDENTIFIER,
242 ERROR_CODE_INVALID_IMAGE,
243 ERROR_CODE_INVALID_INTERPOLATION_MODE,
244 ERROR_CODE_INVALID_LINE_INFO,
245 ERROR_CODE_INVALID_MORPH_INDEX,
246 ERROR_CODE_INVALID_OBJECT_EXPORTED,
247 ERROR_CODE_INVALID_POSITION,
248 ERROR_CODE_INVALID_SHAPE,
249 ERROR_CODE_INVALID_SPREAD_MODE,
250 ERROR_CODE_INVALID_STYLE,
251 ERROR_CODE_INVALID_TEXT_SETUP,
252 ERROR_CODE_JPEG,
253 ERROR_CODE_LOOP_ZERO,
254 ERROR_CODE_MISSING_FRAME_NAME,
255 ERROR_CODE_MISSING_SHAPE,
256 ERROR_CODE_MORPH_GRADIENT_LIMIT,
257 ERROR_CODE_MORPH_REQUIRES_ALPHA,
258 ERROR_CODE_NAME_TOO_LONG,
259 ERROR_CODE_NEGATIVE_MITER,
260 ERROR_CODE_NO_FOCAL_WITH_MORPH,
261 ERROR_CODE_NO_HEADER,
262 ERROR_CODE_NO_STATES,
263 ERROR_CODE_NO_SUCH_GLYPH,
264 ERROR_CODE_LABEL_NOT_FOUND,
265 ERROR_CODE_LABEL_OVERFLOW,
266 ERROR_CODE_MORPH_MISMATCH,
267 ERROR_CODE_OBJECT_NOT_FOUND,
268 ERROR_CODE_REGISTER_OVERFLOW,
269 ERROR_CODE_SIZE_MISMATCH,
270 ERROR_CODE_START_SOUND_NO_INFO,
271 ERROR_CODE_TOO_MANY_STYLES,
272 ERROR_CODE_TWO_OR_MORE_JPEGTABLES,
273 ERROR_CODE_TWO_OR_MORE_METADATA,
274 ERROR_CODE_UNEXPECTED_EVENT_FLAG,
275 ERROR_CODE_UNKNOWN_FORMAT,
276 ERROR_CODE_UNKNOWN_OBJECT_EXPORTED,
277 ERROR_CODE_UNSUPPORTED_IMAGE_FORMAT,
278 ERROR_CODE_UNSUPPORTED_SOUND_FORMAT,
279 ERROR_CODE_VERSION_UNSATISFIED,
280 ERROR_CODE_VOLUME_OUT_OF_RANGE,
281
282 ERROR_CODE_max
283 };
284
285 ErrorManager(void);
286
287 void Reset(void);
288 int Count(void) const;
289 static error_code_t KeepFirst(error_code_t a, error_code_t b);
290
291 error_code_t OnError(error_code_t errcode, const char *message, va_list ap) const;
292
293 invisible:
294 class InternalErrorException {};
295
296 class ErrorHandler
297 {
298 public:
299 virtual ~ErrorHandler();
300 virtual error_code_t OnError(error_code_t errcode, const char *msg) = 0;
301 };
302
303 ErrorHandler * SetErrorHandler(ErrorHandler *error_handler);
304 error_code_t OnError(error_code_t errcode, const char *message, ...) const;
305
306 private:
307 mutable int f_error_count;
308 ErrorHandler * f_error_handler;
309 };
310
311
312
313
314
315
316 class Buffer;
317 class MemBuffer
318 {
319 public:
320 MemBuffer(void);
321 virtual ~MemBuffer();
322
323 void AttachBuffer(Buffer *buffer);
324 Buffer * GetBuffer(void) const;
325
326 private:
327 Buffer * f_buffer;
328 };
329
330
331 class Buffer
332 {
333 public:
334 Buffer(Buffer **head, size_t size, const char *info);
335 Buffer(Buffer **head, MemBuffer *ptr, size_t size, const char *info);
336 //Buffer(Buffer **head, void *ptr, size_t size, const char *info);
337 ~Buffer();
338
339 void * Realloc(size_t size);
Data(void)340 void * Data(void) const { return f_data; }
Next(void)341 Buffer * Next(void) const { return (Buffer *) f_next; }
Previous(void)342 Buffer * Previous(void) const { return (Buffer *) f_previous; }
Size(void)343 size_t Size(void) const { return f_size; }
Info(void)344 const char * Info(void) const { return f_info; }
345
346 static Buffer * FindBuffer(void *ptr);
347 #if 0
348 // this is totally wrong and it simply can't be used safely
349 static bool IsBuffer(void *ptr);
350 #endif
351
352 private:
353 /// Hold the magic and a pointer to the actual buffer
354 struct mem_buffer_t {
355 unsigned long f_magic; // to make sure we have indeed a valid buffer
356 Buffer * f_buffer; // reference back to 'this' buffer
357 };
358 enum {
359 DMAGIC = (unsigned long) 0x53535746, // direct (malloc)
360 OMAGIC = (unsigned long) 0x5353574F // object (new/delete)
361 };
362 #define SSWF_ALIGN(value, modulo) (((value) + ((modulo) - 1)) & - (long) (modulo))
363 #define SSWF_SPACE SSWF_ALIGN(sizeof(mem_buffer_t), sizeof(double))
364 #if DEBUG
365 void Test(void);
366 #define SSWF_SAFE (sizeof(double) * 32)
367 #define SSWF_TEST ((long)0xBADC0FFE)
368 #else
369 #define SSWF_SAFE 0
370 #endif
371
372 Buffer ** f_head; // header for this list of buffers
373 Buffer * f_next;
374 Buffer * f_previous;
375 const char * f_info;
376 size_t f_size;
377 mutable void * f_data;
378 };
379
380
381 class MemoryManager
382 {
383 public:
384 MemoryManager(void);
385 virtual ~MemoryManager();
386
387 void MemAttach(MemBuffer *ptr, size_t size, const char *info); // used when you require the use of a ::new ... call
388 void * MemAlloc(size_t size, const char *info);
389 void * MemRealloc(void *ptr, size_t size, const char *info); // info used ONLY if ptr == 0
390 void MemFree(void *ptr);
391 void MemClean(void *ptr);
392 char * StrDup(const char *string);
393 char * StrCat(const char *s1, const char *s2);
394 #if DEBUG
395 void MemTest(void *ptr);
396 #endif
397 unsigned long Size(void *ptr);
398
399 private:
400 Buffer * f_head;
401 };
402
403
404
405 exposed_class ItemBase : public MemBuffer
406 {
407 invisible:
ItemBase(void)408 ItemBase(void) {}
~ItemBase()409 virtual ~ItemBase() {}
410 };
411
412
413 exposed_class Vectors : public MemoryManager, public MemBuffer
414 {
415 public:
416 Vectors(void);
417 Vectors(const Vectors& vector);
418 ~Vectors();
419
420 ItemBase * Get(int index) const;
421 void Set(int index, ItemBase *vector);
422 void Insert(int index, ItemBase *vector);
423 void SetSize(int size);
Count(void)424 int Count(void) const { return f_count; }
Empty(void)425 void Empty(void) { f_count = 0; } // currently we keep the f_vectors buffer
426
427 invisible:
428 Vectors& operator = (const Vectors& vectors);
429
430 private:
431 int f_count; // # of valid pointers
432 int f_max; // max. # of pointers until realloc
433 ItemBase ** f_vectors; // an array of pointers
434 };
435
436
437
438
439
440
441
442 exposed_class Data : public MemoryManager
443 {
444 public:
445 Data(void);
446 ~Data();
447
Empty(void)448 void Empty(void) { f_pos = 0; } // make the buffer empty (reset/restart)
449 void Align(void); // align to the next byte
450 void Overwrite(size_t offset, const void *ptr, size_t size);
451 void OverwriteByte(size_t offset, char c);
452 void OverwriteShort(size_t offset, short s);
453 void OverwriteLong(size_t offset, long l);
454 void Write(const void *ptr, size_t size); // write bytes
455 void WriteBits(long value, size_t bits); // write the 'bits' lower bits of 'value'
456 void PutByte(char c); // write one byte
457 void PutShort(short s); // write one short (auto-swap)
458 void PutLong(long l); // write one long, 32 bits (auto-swap)
459 void PutDLong(int64_t ll); // write one long, 64 bits (auto-swap)
460 void PutShortFloat(float f); // write one float, 16 bits (auto-conversion)
461 void PutLongFloat(float f); // write one float, 32 bits (auto-swap)
462 void PutDoubleFloat(double f); // write one float, 64 bits (auto-swap)
463 void PutString(const char *string); // write a null terminated string (including the terminator)
464 void Append(const Data& append); // append another data buffer in here
465
466 void Read(void *& ptr, size_t& size); // retrieve the buffer and its size rounded up to the next byte (Align() is called once)
467 // if you want the size in bits, use the Size() function call
468
ByteSize(void)469 unsigned long ByteSize(void) const { return (f_pos + CHAR_BIT - 1) / CHAR_BIT; }
GetSize(void)470 unsigned long GetSize(void) const { return f_pos; } // total size in bits
471 void SetSize(unsigned long size);
472
473 private:
474 void AdjustSize(size_t size);
475
476 unsigned long f_pos;
477 unsigned long f_size;
478 char * f_data;
479 };
480
481
482
483
484
485
486 // the following are structures used within the tags defined afterward
487 exposed_class SRectangle
488 {
489 public:
490 SRectangle(void);
491
492 void Reset(void);
493 void Set(long xmin, long xmax, long ymin, long ymax);
494 void SetReorder(long xmin, long xmax, long ymin, long ymax);
495 long XMin(void) const;
496 long XMax(void) const;
497 long YMin(void) const;
498 long YMax(void) const;
499 bool IsEmpty(void) const;
500
501 void Save(Data& data) const;
502
503 private:
504 long f_xmin;
505 long f_xmax;
506 long f_ymin;
507 long f_ymax;
508 };
509
510
511 exposed_class Color
512 {
513 public:
Color(void)514 Color(void) { Reset(); }
515
516 void Reset(void);
517 void Set(unsigned char red, unsigned char green, unsigned char blue, unsigned char alpha = 255);
Red(void)518 unsigned char Red(void) const { return f_red; }
Green(void)519 unsigned char Green(void) const { return f_green; }
Blue(void)520 unsigned char Blue(void) const { return f_blue; }
Alpha(void)521 unsigned char Alpha(void) const { return f_alpha; }
522
523 void Save(Data& data, bool save_alpha = true);
524
IsSolid(void)525 bool IsSolid(void) const { return f_alpha == 255; }
IsInvisible(void)526 bool IsInvisible(void) const { return f_alpha == 0; }
527
528 invisible:
529 bool operator == (const Color& color) const;
530 bool operator != (const Color& color) const;
531
532 private:
533 unsigned char f_red;
534 unsigned char f_green;
535 unsigned char f_blue;
536 unsigned char f_alpha;
537 };
538
539
540
541 exposed_class ColorTransform
542 {
543 public:
544 ColorTransform(void);
545
546 void Reset(void);
547 void SetAdd(double red, double green, double blue, double alpha = 0.0);
548 void SetMult(double red, double green, double blue, double alpha = 1.0);
AddRed(void)549 double AddRed(void) const { return f_add_red; }
AddGreen(void)550 double AddGreen(void) const { return f_add_green; }
AddBlue(void)551 double AddBlue(void) const { return f_add_blue; }
AddAlpha(void)552 double AddAlpha(void) const { return f_add_alpha; }
MultRed(void)553 double MultRed(void) const { return f_add_red; }
MultGreen(void)554 double MultGreen(void) const { return f_add_green; }
MultBlue(void)555 double MultBlue(void) const { return f_add_blue; }
MultAlpha(void)556 double MultAlpha(void) const { return f_add_alpha; }
557
558 void Save(Data& data, bool save_alpha = true);
559
560 bool IsNull(bool with_alpha) const; // if true we can ignore this transformation!
561 bool IsSolidCompatible(void) const; // if true we can ignore the alpha channel!
562
563 private:
564 double f_add_red;
565 double f_add_green;
566 double f_add_blue;
567 double f_add_alpha;
568 double f_mult_red;
569 double f_mult_green;
570 double f_mult_blue;
571 double f_mult_alpha;
572 };
573
574
575
576 exposed_class Matrix
577 {
578 public:
579 Matrix(void);
580
581 void Reset(void);
SetScale(double x,double y)582 void SetScale(double x, double y) { f_scale_x = x; f_scale_y = y; }
SetScale(double scale)583 void SetScale(double scale) { f_scale_x = scale; f_scale_y = scale; }
584 void SetRotate(double rotate);
SetSkew(double skew0,double skew1)585 void SetSkew(double skew0, double skew1) { f_skew_0 = skew0; f_skew_1 = skew1; }
SetTranslate(long x,long y)586 void SetTranslate(long x, long y) { f_translate_x = x; f_translate_y = y; }
587
588 void Save(Data& data);
589
590 bool IsNull(void) const;
591
592 invisible:
593 bool operator == (const Matrix& matrix) const;
594 bool operator != (const Matrix& matrix) const;
595
596 private:
597 /// Matrix of longs; used to compute the matrix to be saved in the movie
598 struct signed_matrix_t {
599 long m[4];
600 };
601
602 void ComputeMatrix(signed_matrix_t& m) const;
603
604 double f_scale_x;
605 double f_scale_y;
606 double f_rotate;
607 long f_translate_x;
608 long f_translate_y;
609 double f_skew_0;
610 double f_skew_1;
611 };
612
613
614
615 exposed_class Envelope : public ItemBase
616 {
617 public:
618 Envelope(unsigned long p, unsigned short l, unsigned short r);
619 Envelope(const Envelope& envelope);
620
621 unsigned long Position(void) const;
622 unsigned short Left(void) const;
623 unsigned short Right(void) const;
624 void Save(Data& data) const;
625
626 private:
627 unsigned long f_position;
628 unsigned short f_left;
629 unsigned short f_right;
630 };
631
632
633 exposed_class SoundInfo : public MemoryManager
634 {
635 public:
636 SoundInfo(ErrorManager& error_manager);
637
638 void SetSoundID(sswf_id_t id);
639 void StopSound(bool stop = true);
640 void NoMultiple(bool no_multiple = true);
641 void SetRange(unsigned long start, unsigned long end);
642 void SetLoop(unsigned short loop);
643 void AddEnvelope(const Envelope& envelope);
644
645 ErrorManager::error_code_t PreSave(void); // called by the TagStartSound::PreSave()
646 void Save(Data& data) const;
647
648 private:
649 ErrorManager& f_error_manager; // the TagHeader
650 sswf_id_t f_sound_id;
651 bool f_stop; // if true, ignore all the other info
652 bool f_no_multiple; // never play this sound more than once
653 unsigned long f_start_position; // start playing from this sample
654 unsigned long f_end_position; // stop playing at this sample
655 unsigned short f_loop; // repeat the sound this many times
656 Vectors f_envelopes; // a list of position + volume information
657 };
658
659
660
661
662 exposed_class BlendMode
663 {
664 public:
665 enum blend_mode_t {
666 BLEND_MODE_UNDEFINED = -1,
667 BLEND_MODE_NORMAL = 1,
668 BLEND_MODE_LAYER = 2,
669 BLEND_MODE_MULTIPLY = 3,
670 BLEND_MODE_SCREEN = 4,
671 BLEND_MODE_LIGHTEN = 5,
672 BLEND_MODE_DARKEN = 6,
673 BLEND_MODE_DIFFERENCE = 7,
674 BLEND_MODE_ADD = 8,
675 BLEND_MODE_SUBTRACT = 9,
676 BLEND_MODE_INVERT = 10,
677 BLEND_MODE_ALPHA = 11,
678 BLEND_MODE_ERASE = 12,
679 BLEND_MODE_OVERLAY = 13,
680 BLEND_MODE_HARDLIGHT = 14
681 };
682
683 BlendMode(void);
684
685 bool HasBlendMode(void) const;
686 void SetBlendMode(blend_mode_t blend_mode_value);
687 bool SetBlendModeByName(const char *blend_mode_name);
688 blend_mode_t GetBlendMode(void) const;
689
690 void Save(Data& data);
691
692 private:
693 blend_mode_t f_blend_mode;
694 };
695
696
697 exposed_class State : public ItemBase
698 {
699 public:
700 // Use with SetFlags()
701 enum state_flags_t {
702 STATE_FLAG_UP = 0x01,
703 STATE_FLAG_OVER = 0x02,
704 STATE_FLAG_DOWN = 0x04,
705 STATE_FLAG_HIT_TEST = 0x08,
706
707 STATE_ALL_FLAGS = 0x0F
708 };
709
710 explicit State(ErrorManager& error_manager);
711
712 void Reset(void);
713 void SetObjectID(sswf_id_t id);
714 bool SetFlags(unsigned char flags);
715 void SetLayer(unsigned short layer);
716 void SetMatrix(const Matrix& matrix);
717 void SetColorTransform(const ColorTransform& color_transform);
718 bool HasColorTransform(void) const;
719 void SetBlendMode(const BlendMode& blend_mode);
720 ErrorManager::error_code_t Save(Data& data, bool color_transform = false);
721
722 unsigned char GetFlags(void) const;
723
724 private:
725 ErrorManager& f_error_manager; // the TagHeader
726 sswf_id_t f_id;
727 bool f_has_color_transform;
728 unsigned char f_flags;
729 unsigned short f_layer;
730 Matrix f_matrix;
731 ColorTransform f_color_transform;
732 BlendMode f_blend_mode;
733 };
734
735
736
737
738
739 class Action;
740 exposed_class Event : public MemoryManager, public ItemBase
741 {
742 public:
743 Event(void);
744
745 void Reset(void);
746 void SetEvents(unsigned long events);
747 void SetKey(unsigned char key);
748 unsigned long Events(void) const; // PlaceObject2 flags
749 unsigned long Conditions(void) const; // DefineButton2 flags
750 unsigned char Key(void) const;
751 Vectors& Actions(void);
752
753 static unsigned long StringToEvents(const char *s);
754 static unsigned char StringToKeyCode(const char *s);
755
756 // the flags are saved with the following bits
757 // in a PlaceObject2
758 // these have to be converted when saved in a
759 // DefineButton2 tag
760 enum event_flag_t {
761 EVENT_COND_MENU_LEAVE = 0x80000000, // for DefineButton2
762 EVENT_COND_MENU_ENTER = 0x40000000, // for DefineButton2
763
764 EVENT_CONSTRUCT = 0x00040000, // V7.x
765 EVENT_KEY_PRESS = 0x00020000, // V6.x
766 EVENT_POINTER_DRAG_LEAVE = 0x00010000, // V6.x shared with DefineButton2
767 EVENT_POINTER_DRAG_ENTER = 0x00008000, // V5.x shared with DefineButton2
768 EVENT_POINTER_LEAVE = 0x00004000, // V5.x shared with DefineButton2
769 EVENT_POINTER_ENTER = 0x00002000, // V5.x shared with DefineButton2
770 EVENT_POINTER_RELEASE_OUTSIDE = 0x00001000, // V5.x shared with DefineButton2
771 EVENT_POINTER_RELEASE_INSIDE = 0x00000800, // V5.x shared with DefineButton2
772 EVENT_POINTER_PUSH = 0x00000400, // V5.x shared with DefineButton2
773 EVENT_INITIALIZE = 0x00000200, // V5.x
774 EVENT_DATA = 0x00000100, // V5.x
775 EVENT_KEY_UP = 0x00000080, // V6.x
776 EVENT_KEY_DOWN = 0x00000040, // V6.x
777 EVENT_POINTER_UP = 0x00000020, // V6.x
778 EVENT_POINTER_DOWN = 0x00000010, // V6.x
779 EVENT_POINTER_MOVE = 0x00000008, // V6.x
780 EVENT_UNLOAD = 0x00000004, // V6.x
781 EVENT_ENTER_FRAME = 0x00000002, // V6.x
782 EVENT_ONLOAD = 0x00000001 // V5.x
783 };
784 #define SSWF_EVENT_V5 0x0000FF01 // flags present in V5
785 #define SSWF_EVENT_V6 0x000300FE // flags added in V6
786 #define SSWF_EVENT_V7 0x00040000 // flag added in V7
787 #define SSWF_EVENT_CONDITIONS 0xC001FC00 // flags used by conditions in DefineButton2
788 #define SSWF_EVENT_COUNT 20
789 struct event_names_t {
790 event_flag_t f_flag;
791 const char * f_name;
792 };
793
794 enum condition_flag_t {
795 CONDITION_KEY_MASK = 0xFE00,
796 CONDITION_KEY_SHIFT = 9,
797 CONDITION_MENU_LEAVE = 0x0100, // OVER_DOWN_TO_IDLE
798 CONDITION_MENU_ENTER = 0x0080, // IDLE_TO_OVER_DOWN
799 CONDITION_POINTER_RELEASE_OUTSIDE = 0x0040, // OUT_DOWN_TO_IDLE
800 CONDITION_POINTER_DRAG_ENTER = 0x0020, // OUT_DOWN_TO_OVER_DOWN
801 CONDITION_POINTER_DRAG_LEAVE = 0x0010, // OVER_DOWN_TO_OUT_DOWN
802 CONDITION_POINTER_RELEASE_INSIDE = 0x0008, // OVER_DOWN_TO_OVER_UP
803 CONDITION_POINTER_PUSH = 0x0004, // OVER_UP_TO_OVER_DOWN
804 CONDITION_POINTER_LEAVE = 0x0002, // OVER_UP_TO_IDLE
805 CONDITION_POINTER_ENTER = 0x0001 // IDLE_TO_OVER_UP
806 };
807
808 enum key_code_t {
809 KEY_CODE_NONE = 0,
810 KEY_CODE_LEFT_ARROW = 1,
811 KEY_CODE_RIGHT_ARROW = 2,
812 KEY_CODE_HOME = 3,
813 KEY_CODE_END = 4,
814 KEY_CODE_INSERT = 5,
815 KEY_CODE_DELETE = 6,
816 KEY_CODE_BACKSPACE = 8,
817 KEY_CODE_ENTER = 13,
818 KEY_CODE_UP_ARROW = 14,
819 KEY_CODE_DOWN_ARROW = 15,
820 KEY_CODE_PAGE_UP = 16,
821 KEY_CODE_PAGE_DOWN = 17,
822 KEY_CODE_TAB = 18,
823 KEY_CODE_ESCAPE = 19,
824 KEY_CODE_SPACE = 20, // equal to ' '
825 // and also all the ASCII codes from 32 to 126
826 };
827 #define SSWF_KEY_COUNT 15
828 struct key_names_t {
829 key_code_t f_code;
830 const char * f_name;
831 };
832
833 invisible:
834 static const event_names_t g_event_names[SSWF_EVENT_COUNT];
835 static const key_names_t g_key_names[SSWF_KEY_COUNT];
836
837 private:
838 unsigned long f_events;
839 unsigned char f_key;
840 Vectors f_actions;
841 };
842
843
844
845
846
847 exposed_class Style : public ItemBase
848 {
849 public:
850 enum style_t {
851 STYLE_TYPE_UNKNOWN = 0,
852 STYLE_TYPE_NO_LINE,
853 STYLE_TYPE_NO_FILL,
854 STYLE_TYPE_LINE,
855 STYLE_TYPE_ENHANCED_LINE, // Line 2
856 STYLE_TYPE_SOLID,
857 STYLE_TYPE_GRADIENT_LINEAR,
858 STYLE_TYPE_GRADIENT_RADIAL,
859 STYLE_TYPE_GRADIENT_FOCAL,
860 STYLE_TYPE_BITMAP_TILLED,
861 STYLE_TYPE_BITMAP_CLIPPED,
862 STYLE_TYPE_BITMAP_HARDEDGE_TILLED,
863 STYLE_TYPE_BITMAP_HARDEDGE_CLIPPED,
864
865 STYLE_TYPE_MATRIX, // intermediate type used when a matrix is defined before
866 // a gradient or bitmap info (or the SetType() is called)
867
868 STYLE_TYPE_max
869 };
870
871 enum cap_t {
872 STYLE_LINE_CAP_SAME = -1,
873 STYLE_LINE_CAP_ROUND = 0,
874 STYLE_LINE_CAP_NONE = 1,
875 STYLE_LINE_CAP_SQUARE = 2
876 };
877
878 enum join_t {
879 STYLE_LINE_JOIN_UNKNOWN = -1,
880 STYLE_LINE_JOIN_ROUND = 0,
881 STYLE_LINE_JOIN_BEVEL = 1,
882 STYLE_LINE_JOIN_MITER = 2
883 };
884
885 enum spread_t {
886 STYLE_GRADIENT_SPREAD_PAD = 0,
887 STYLE_GRADIENT_SPREAD_REFLECT = 1,
888 STYLE_GRADIENT_SPREAD_REPEAT = 2,
889 };
890
891 enum interpolation_t {
892 STYLE_GRADIENT_INTERPOLATION_NORMAL = 0,
893 STYLE_GRADIENT_INTERPOLATION_LINEAR = 1
894 };
895
896 explicit Style(ErrorManager& error_manager);
897 virtual ~Style();
898
899 void Reset(void);
Type(void)900 style_t Type(void) const { return f_style; }
Gradients(void)901 signed char Gradients(void) const { return f_gradient; }
HasMorph(void)902 bool HasMorph(void) const { return f_morph; }
HasAlpha(void)903 bool HasAlpha(void) const { return f_use_alpha; }
HasHardEdges(void)904 bool HasHardEdges(void) const { return f_style == STYLE_TYPE_BITMAP_HARDEDGE_TILLED
905 || f_style == STYLE_TYPE_BITMAP_HARDEDGE_CLIPPED; }
906 bool SetType(style_t style_type);
907 bool SetLine(int index, unsigned short width, const Color& color);
908 bool SetLineCaps(cap_t start, cap_t end = STYLE_LINE_CAP_SAME);
909 bool SetLineJoin(join_t join, float miter_limit_factor = 0.0f);
910 bool SetLineScale(bool horiz, bool vert);
911 bool SetLinePixelHinting(bool pixel_hinting);
912 bool SetLineNoClose(bool no_close);
913 bool SetLineFillStyle(const Style& fill_style);
914 bool SetColor(int index, const Color& color);
915 bool SetGradient(int index, int pos, const Color& color);
916 bool SetGradientModes(spread_t spread, interpolation_t interpolation);
917 bool SetGradientFocal(float focal);
918 bool SetMatrix(int index, const Matrix& matrix);
919 bool SetBitmap(sswf_id_t id_ref);
920 bool SetClipping(void);
921
922 ErrorManager::error_code_t Save(Data& data, bool save_alpha, bool save_morph);
923
924 invisible:
925 /** \brief Defines the total number of gradients available in a gradient style.
926 *
927 * This value represents the maximum number of gradients a
928 * gradient style supports. Older movies would support up to
929 * 8 gradients. Newer movies (since SWF version 8) support
930 * up to 15 gradient definitions.
931 */
932 static const signed char MAX_GRADIENTS = 15;
933
934 bool operator == (const Style& style) const;
935
936 private:
937 // An error manager (TagHeader)
938 ErrorManager& f_error_manager;
939
940 // the style
941 style_t f_style;
942
943 // whether this is for a DefineMorphShape or not
944 bool f_morph;
945
946 // whether some color alpha is not 255
947 bool f_use_alpha;
948
949 // a line width
950 unsigned short f_line_width[2];
951 cap_t f_start_cap_style;
952 cap_t f_end_cap_style;
953 join_t f_join_style;
954 float f_miter_limit_factor; // means we have f_join_style == 2
955 bool f_no_hscale;
956 bool f_no_vscale;
957 bool f_pixel_hinting;
958 bool f_no_close;
959 Style * f_fill_style; // if defined, no color and f_has_fill is set to true in output
960
961 // solid fill or line colors
962 Color f_color[2];
963
964 // bitmap reference (its ID)
965 sswf_id_t f_bitmap_ref;
966
967 // matrices - 1 or 2 - regular of morph shapes
968 Matrix f_matrix[2];
969
970 // gradient positions & colors - 8 or 16 - regular or morph shapes
971 signed char f_gradient; // largest index used (0..7 only or -1 when no gradient)
972 unsigned char f_gradient_pos[MAX_GRADIENTS * 2];
973 Color f_gradient_color[MAX_GRADIENTS * 2];
974 spread_t f_gradient_spread;
975 interpolation_t f_gradient_interpolation;
976 signed short f_gradient_focal;
977 };
978
979
980
981
982
983 exposed_class Edges : public MemoryManager, public ItemBase
984 {
985 invisible:
986 // This structure is too complex at this time to reproduce
987 // automatically in C. We do not need it anyway.
988 struct edge_t {
989 long f_x;
990 long f_y;
991 long f_ctrl_x; /* LONG_MIN if a line only */
992 long f_ctrl_y;
993
edge_tedge_t994 edge_t(void)
995 {
996 f_x = 0;
997 f_y = 0;
998 f_ctrl_x = LONG_MIN;
999 f_ctrl_y = LONG_MIN;
1000 }
edge_tedge_t1001 edge_t(long x, long y)
1002 {
1003 f_x = x;
1004 f_y = y;
1005 f_ctrl_x = LONG_MIN;
1006 f_ctrl_y = LONG_MIN;
1007 }
edge_tedge_t1008 edge_t(long x, long y, long ctrl_x, long ctrl_y)
1009 {
1010 f_x = x;
1011 f_y = y;
1012 f_ctrl_x = ctrl_x;
1013 f_ctrl_y = ctrl_y;
1014 }
edge_tedge_t1015 edge_t(const edge_t& edge)
1016 {
1017 f_x = edge.f_x;
1018 f_y = edge.f_y;
1019 f_ctrl_x = edge.f_ctrl_x;
1020 f_ctrl_y = edge.f_ctrl_y;
1021 }
1022 edge_t& operator = (const edge_t& edge)
1023 {
1024 if(this != &edge) {
1025 f_x = edge.f_x;
1026 f_y = edge.f_y;
1027 f_ctrl_x = edge.f_ctrl_x;
1028 f_ctrl_y = edge.f_ctrl_y;
1029 }
1030 return *this;
1031 }
IsLineedge_t1032 bool IsLine(void) const { return f_ctrl_x == LONG_MIN || f_ctrl_y == LONG_MIN; }
1033 };
1034
1035 public:
1036 // This should be private but cl (C++ compiler from Mr Microsoft) does not
1037 // understand the use of private too well...
1038 enum {
1039 // better with a power of two (we use * and / a lot with it!)
1040 EDGE_BLOCK = 64
1041 };
1042
1043 Edges(void);
1044 virtual ~Edges();
1045
1046 //void Reset(void); -- not implemented yet
Set(long x,long y)1047 void Set(long x, long y) { edge_t edge(x, y); Set(-1, edge); }
Set(long x,long y,long ctrl_x,long ctrl_y)1048 void Set(long x, long y, long ctrl_x, long ctrl_y) { edge_t edge(x, y, ctrl_x, ctrl_y); Set(-1, edge); }
Set(int index,long x,long y,long ctrl_x,long ctrl_y)1049 void Set(int index, long x, long y, long ctrl_x, long ctrl_y) { edge_t edge(x, y, ctrl_x, ctrl_y); Set(index, edge); }
1050
1051 void Save(Data& data, long& x, long& y);
1052
1053 invisible:
Set(const edge_t & edge)1054 void Set(const edge_t& edge) { Set(-1, edge); }
1055 void Set(int index, const edge_t& edge);
1056
1057 private:
1058 /// One set of edges; when full, allocate another
1059 struct array_edge_t : public ItemBase {
1060 edge_t f_edge[EDGE_BLOCK];
1061 };
1062
1063 // no copy operators at this time
Edges(const Edges & edges)1064 Edges(const Edges& edges) {}
1065 Edges& operator = (const Edges& edges) { return *this; }
1066
1067 void SaveEdge(Data& data, const edge_t& edge, long& x, long& y);
1068
1069 Vectors f_edges;
1070 int f_pos; /* position in the current array */
1071 array_edge_t f_array; /* current array; when full, put in f_edges */
1072 };
1073
1074
1075
1076
1077
1078
1079
1080 // one can't create a tag base, only full qualified
1081 // tags can be created (see below)
1082 class TagHeader;
1083 exposed_class TagBase : public MemoryManager
1084 {
1085 public:
1086 // anything in the file is represented by a tag
1087 enum swf_tag_t {
1088 SWF_TAG_UNKNOWN = -1, // undefined tag
1089
1090 // V1.0
1091 SWF_TAG_END = 0, // mark the end of the flash script
1092 SWF_TAG_SHOW_FRAME = 1, // show the current frame
1093 SWF_TAG_DEFINE_SHAPE = 2, // define a vector based shape
1094 SWF_TAG_PLACE_OBJECT = 4, // place an object in the current frame
1095 SWF_TAG_REMOVE_OBJECT = 5, // remove specified object
1096 SWF_TAG_DEFINE_BITS = 6, // JPEG data bit stream (old name, I will obsolete this name at some point)
1097 SWF_TAG_DEFINE_BITS_JPEG = 6, // JPEG data bit stream (renaming)
1098 SWF_TAG_DEFINE_BUTTON = 7, // define an action button
1099 SWF_TAG_JPEG_TABLES = 8, // define the JPEG tables
1100 SWF_TAG_SET_BACKGROUND_COLOR = 9, // define the RGB color for the background
1101 SWF_TAG_DEFINE_FONT = 10, // links a list of shapes to characters
1102 SWF_TAG_DEFINE_TEXT = 11, // define a text to be printed with a font
1103 SWF_TAG_DO_ACTION = 12, // action to perform in this frame
1104 SWF_TAG_DEFINE_FONT_INFO = 13, // font metrics
1105
1106 // V2.0
1107 SWF_TAG_DEFINE_SOUND = 14, // define how a sound effect will be played
1108 SWF_TAG_START_SOUND = 15, // start playing a sound effect
1109 SWF_TAG_STOP_SOUND = 16, // (V9.0) stop playing a sound effect
1110 SWF_TAG_DEFINE_BUTTON_SOUND = 17, // sound effects attached to a button
1111 SWF_TAG_SOUND_STREAM_HEAD = 18, // define how a sound effect will be loaded & played
1112 SWF_TAG_SOUND_STREAM_BLOCK = 19, // actual sound samples to play (embedded with the rest)
1113 SWF_TAG_DEFINE_BITS_LOSSLESS = 20, // a loss less compressed image
1114 SWF_TAG_DEFINE_BITS_JPEG2 = 21, // a complete JPEG definition
1115 SWF_TAG_DEFINE_SHAPE2 = 22, // define a shape including large number of styles
1116 SWF_TAG_DEFINE_BUTTON_COLOR_TRANSFORM = 23, // how a button changes color
1117 SWF_TAG_PROTECT = 24, // whether the resulting file is protected against editing
1118
1119 // V3.0
1120 SWF_TAG_PLACE_OBJECT2 = 26, // extended place
1121 SWF_TAG_REMOVE_OBJECT2 = 28, // simplified remove
1122 SWF_TAG_DEFINE_SHAPE3 = 32, // define a shape including RGBA colors
1123 SWF_TAG_DEFINE_TEXT2 = 33, // define a text to draw including RGBA colors
1124 SWF_TAG_DEFINE_BUTTON2 = 34, // define an action button with RGBA colors and color transformation
1125 SWF_TAG_DEFINE_BITS_JPEG3 = 35, // define two JPEG images, one RGB and one GREY used as the alpha channel
1126 SWF_TAG_DEFINE_BITS_LOSSLESS2 = 36, // define a loss less image with an alpha channel
1127 SWF_TAG_DEFINE_SPRITE = 39, // define a movie as an object to play in another movie
1128 SWF_TAG_PRODUCT_INFO = 41, // generator version info
1129 SWF_TAG_FRAME_LABEL = 43, // name a place holder in the movie
1130 SWF_TAG_DEFINE_BEHAVIOR = 44, // (V9.0) ?
1131 SWF_TAG_SOUND_STREAM_HEAD2 = 45, // define a sound effect with more details for embedded playing
1132 SWF_TAG_DEFINE_MORPH_SHAPE = 46, // define a shape which can easilly be changed with a position
1133 SWF_TAG_DEFINE_FONT2 = 48, // define a set of fonts
1134 SWF_TAG_DEFINE_INFO = 49, // define a comment about the generator, etc.
1135
1136 // V4.0
1137 SWF_TAG_TEXT_FIELD = 37, // define an area with text which can be edited
1138
1139 // V9.0
1140 SWF_TAG_DEFINE_FUNCTION = 53, // ABC function
1141 SWF_TAG_PLACE_FUNCTION = 54, // Place(?) ABC function
1142 SWF_TAG_GENERATE_TAG_OBJECT = 55, // ?
1143
1144 // V5.0
1145 SWF_TAG_EXPORT = 56, // export a set of definitions to other files
1146 SWF_TAG_IMPORT = 57, // look for definitions from another file (supported up to V7.0)
1147 SWF_TAG_PROTECT_DEBUG = 58, // a password to protect debugging of flash movies -- use only in V5.x movies
1148
1149 // V6.0
1150 SWF_TAG_DO_INIT_ACTION = 59, // action to perform once on specified sprite in this frame
1151 SWF_TAG_DEFINE_VIDEO_STREAM = 60, // record defining the following video frames
1152 SWF_TAG_VIDEO_FRAME = 61, // a frame of video
1153 SWF_TAG_DEFINE_FONT_INFO2 = 62, // font metrics including language reference
1154 SWF_TAG_DEBUG_ID = 63, // (SWF 9)
1155 SWF_TAG_PROTECT_DEBUG2 = 64, // a password to protect debugging of flash movies
1156
1157 // V7.0
1158 SWF_TAG_SCRIPT_LIMITS = 65, // the recursive depth and script timeout parameters
1159 SWF_TAG_SET_TAB_INDEX = 66, // the depth of an object to be set at the given index (next/previous Tab key positioning)
1160
1161 // V8.0
1162 SWF_TAG_FILE_ATTRIBUTES = 69, // file attributes appended right after the header (see TagHeader)
1163 SWF_TAG_PLACE_OBJECT3 = 70, // place an object with blend mode, filters, bitmap caching
1164 SWF_TAG_IMPORT2 = 71, // look for definitions from another file (only supported tag in V8.0+)
1165 SWF_TAG_DEFINE_FONT_ALIGN_ZONES = 73, // define hints to properly align fonts to pixel boundaries
1166 SWF_TAG_CSM_TEXT_SETTINGS = 74, // extra information about text (on how to render text)
1167 SWF_TAG_DEFINE_FONT3 = 75, // define a set of fonts which uses lines with caps information
1168 SWF_TAG_METADATA = 77, // an XML document describing the Flash movie
1169 SWF_TAG_DEFINE_SCALING_GRID = 78, // a grid to avoid scaling the edges of an object
1170 SWF_TAG_DEFINE_SHAPE4 = 83, // define a vector based shape with end caps definitions
1171 SWF_TAG_DEFINE_MORPH_SHAPE2 = 84, // define a shape which can easilly be changed with a position
1172
1173 // V9.0
1174 SWF_TAG_ACTIONSCRIPT2 = 72, // define action script version 2
1175 SWF_TAG_ACTIONSCRIPT2_INSTANTIATE = 76, // create an object from an action script version 2
1176 SWF_TAG_ACTIONSCRIPT2_DEFINE = 82, // initialize a named action script version 2
1177 SWF_TAG_SCENE_FRAME_DATA = 86, // define raw data for a scene/frame
1178 SWF_TAG_DEFINE_BINARY_DATA = 87, // define a block of data with an identifier
1179 SWF_TAG_DEFINE_FONT_NAME = 88, // define the name and copyright notice of a font
1180
1181 SWF_TAG_max // just end this list really
1182 };
1183 typedef long swf_type_t;
1184
1185 #define SWF_TYPE_DEFINE 0x00000001 // a definition tag, must be in the main movie
1186 #define SWF_TYPE_CONTROL 0x00000002 // a control tag, can be in sprites as well
1187 #define SWF_TYPE_UNIQUE 0x00000004 // a unique tag, can't be duplicated in the movie (merge if possible)
1188 #define SWF_TYPE_START 0x00000008 // if present, put it near the start of the movie
1189 #define SWF_TYPE_ONE 0x00000010 // (should) use at most one per frame
1190 #define SWF_TYPE_REFERENCE 0x00000020 // object includes references to other objects
1191 #define SWF_TYPE_HAS_ID 0x00000040 // this object was derived from TagBaseID and has an ID
1192
1193 #define SWF_TYPE_SCRIPT 0x20000000 // object can accept action scripts
1194 #define SWF_TYPE_SPRITE 0x40000000 // this is a sprite (can include other tags)
1195 #define SWF_TYPE_HEADER 0x80000000 // the header
1196
1197 virtual ~TagBase();
1198
1199 ErrorManager::error_code_t SaveString(Data& data, const char *string);
1200 static int SaveTag(Data& data, swf_tag_t tag, size_t size);
1201
1202 static long SIBitSize(long value); // return the number of bits necessary to represent a signed integer
1203 static long UIBitSize(unsigned long value); // return the number of bits necessary to represent an unsigned integer
1204 static long Double2Signed16(double value); // return a valid fixed value 8.8 bits from a double
1205 static long Double2Signed(double value); // return a valid fixed value 16.16 bits from a double
1206 static double Signed2Double(long value); // return a valid double from a fixed value 16.16 bits
1207
1208 virtual void MinimumVersion(unsigned char version);
1209 virtual unsigned char Version(void) const;
1210
1211 const char * Name(void) const; // return the name (type) of this tag
1212 const char * Label(void) const;
1213 void ResetFrames(void);
1214 void ShowFrame(void);
1215 sswf_frame_t FrameCount(void) const;
1216
1217 sswf_frame_t WhichFrame(void) const;
1218 void SetLabel(const char *label);
1219 TagBase * FindLabelledTag(const char *label) const;
1220 TagBase * FindTagWithID(sswf_id_t id, bool search_import = true) const;
1221 TagBase * Children(void);
1222 TagBase * Next(void);
1223 TagBase * Previous(void);
1224 TagBase * Parent(void);
1225 TagHeader * Header(void) const;
1226 virtual ErrorManager::error_code_t OnError(ErrorManager::error_code_t errcode, const char *message, va_list ap) const;
1227
1228 invisible:
1229 virtual ErrorManager::error_code_t Save(Data& data) = 0; // print out a tag in a Data buffer
1230 virtual swf_type_t TypeFlags(void) const = 0;
1231 virtual ErrorManager::error_code_t OnError(ErrorManager::error_code_t errcode, const char *message, ...) const;
1232
1233 /** \brief A pointer you are welcome to use
1234 *
1235 * This pointer is public and is provided so users of any one of
1236 * the tag classes can save a pointer back to his/her own
1237 * container.
1238 *
1239 * The library initializes this pointer to NULL on construction
1240 * and never touches it again until the object is deleted.
1241 */
1242 void * f_userdata; // anything you feel necessary!
1243
1244 protected:
1245 // only sub-classes can create a TagBase
1246 TagBase(const char *name, TagBase *parent);
1247 virtual ErrorManager::error_code_t PreSave(void); // called by the header Save() function
1248 virtual ErrorManager::error_code_t PreSave2ndPass(void); // called by the header Save() function after all the PreSave() were called
1249
1250 virtual ErrorManager::error_code_t OnNewChild(const char *child_name) const;
1251
1252 private:
1253 TagBase * FindLabel(const TagBase *p, const char *label) const;
1254 TagBase * FindID(const TagBase *p, sswf_id_t id, bool search_import) const;
1255
1256 const char * f_name;
1257 char * f_label;
1258
1259 TagBase * f_parent;
1260 TagBase * f_next;
1261 TagBase * f_previous;
1262 TagBase * f_children;
1263
1264 sswf_frame_t f_frames; // total number of frames
1265 };
1266
1267
1268
1269
1270
1271
1272 /********************* TAGS WITHOUT IDs (possibly references though) ****/
1273
1274
1275 // The TagHeader includes the TagFileAttributes because
1276 // it is very much like an extension of the header and not
1277 // a separate tag. Also it needs to be unique and saved right
1278 // after the header. Thus it becomes totally transparent to
1279 // you. At this time you have the SetUseNetwork() function to
1280 // set the network flag and add a TagMetadata to set the
1281 // metadata flag (that is automatic.)
1282 exposed_class TagHeader : public TagBase, public ErrorManager
1283 {
1284 public:
1285 TagHeader(void);
1286 virtual ~TagHeader();
1287
1288 virtual ErrorManager::error_code_t Save(Data& data);
1289 ErrorManager::error_code_t SaveEncodedString(Data& data, const char *string);
1290 virtual swf_type_t TypeFlags(void) const;
1291 virtual ErrorManager::error_code_t OnError(ErrorManager::error_code_t errcode, const char *message, va_list ap) const;
1292
1293 sswf_id_t NextID(void);
1294 void RemoveID(sswf_id_t id);
1295
1296 /////////////// SETUP FUNCTIONS
1297 virtual unsigned char Version(void) const; // retrieve the selected version
1298 void SetVersion(unsigned char version); // save a movie with that version if set
1299 void SetMinimumVersion(unsigned char version); // the minimum version you want to support
1300 void SetMaximumVersion(unsigned char version); // the maximum version you want to support
1301
1302 void SetCompress(bool compress = true);
1303 void SetAutoOrder(bool auto_order = true);
1304 void SetUseNetwork(bool use_network = true);
1305 void SetFrame(const SRectangle& rect);
1306 const SRectangle& Frame(void) const;
1307
1308 void SetOutputEncoding(const char *encoding);
1309 void SetRate(float rate);
1310 float Rate(void) const;
1311
1312 invisible:
1313 virtual void MinimumVersion(unsigned char version); // used internally to determine the minimum version
1314 ErrorManager::error_code_t DefineMinimumVersion(int& min_version); // function used to compute the minimum version (a negative result represents an error)
1315 virtual ErrorManager::error_code_t OnError(ErrorManager::error_code_t errcode, const char *message, ...) const;
1316
1317 protected:
1318 virtual ErrorManager::error_code_t PreSave(void); // overwrite the base PreSave() so we can know whether we have a Metadata tag
1319 virtual ErrorManager::error_code_t OnNewChild(const char *child_name) const;
1320
1321 private:
1322 // NOTE: use 0 to get a default version (a version computed from the options used)
1323 unsigned char f_version; // file version (0 to 8 at time of writing)
1324 unsigned char f_min_version; // once the whole file was saved, this is the minimum version we need to use
1325 unsigned char f_minimum_version; // user defined minimum version; the system will start with this minimum version instead of 1
1326 unsigned char f_maximum_version; // user defined maximum version; if a larger version is required, return an error
1327 SRectangle f_frame; // the frame rectangle
1328 float f_rate; // frames per second (8.8 fixed number in file)
1329 bool f_compress; // compress the resulting movie (v6.x upward)
1330 bool f_auto_order; // automatically order definition tags (discard unused definitions also)
1331 bool f_use_network; // whether the SWF movie is authorized to access the network when launched locally
1332 bool f_has_metadata; // whether the SWF movie includes a TagMetadata
1333 bool f_has_jpegtables; // whether the SWF movie includes a TagJPEGTables
1334 sswf_id_t f_next_id; // returned and then increased when NextID() is called
1335 char * f_output_encoding; // encoding used prior V6.x SWF files
1336 bool f_iconvertor_open; // whether the f_iconvertor is a valid descriptor
1337 iconv_t f_iconvertor; // to convert strings from U18N to user specified encoding
1338 #if DEBUG
1339 bool f_saving; // if true the f_min_version can't be changed ever anymore
1340 #endif
1341 };
1342
1343
1344
1345
1346 // Actions:
1347 //
1348 // Whenever you want to create an action, you simply
1349 // create a new Action object with the proper type
1350 // unless you need to use an action which requires
1351 // some additional data. The actions which require
1352 // additional data are listed here:
1353 //
1354 // Action Name Data
1355 //
1356 // ActionBranch label
1357 // ActionCallFrame <nothing -- this is a mistake from Macromedia>
1358 // ActionDictionary strings
1359 // ActionFunction name, registers, parameters, body (actions)
1360 // ActionGoto frame name, play flag
1361 // ActionLabel label (generates no output code)
1362 // ActionPushData strings, floats, doubles, etc.
1363 // ActionSetTarget target name
1364 // ActionStoreRegister register number
1365 // ActionTry try, catch and finally actions and identifier/register
1366 // ActionURL url, target and method
1367 // ActionWaitForFrame frame name, actions
1368 // ActionWith actions to execute with the specified object
1369
1370
1371 class ActionLabel;
1372 exposed_class Action : public ItemBase
1373 {
1374 public:
1375 enum action_t {
1376 ACTION_UNKNOWN = -1, /* unknown action (invalid) */
1377 ACTION_LABEL = -2, /* used to mark a position within the actions */
1378 ACTION_min = 0x00, /* the minimum action number */
1379
1380 /* all the valid Flash actions */
1381 ACTION_END = 0x00, /* this is automatically added by the higher level Save()'s */
1382 ACTION_NEXT_FRAME = 0x04,
1383 ACTION_PREVIOUS_FRAME = 0x05,
1384 ACTION_PLAY = 0x06,
1385 ACTION_STOP = 0x07,
1386 ACTION_TOGGLE_QUALITY = 0x08,
1387 ACTION_STOP_SOUND = 0x09,
1388 ACTION_ADD = 0x0A,
1389 /*ACTION_SUBSTRACT = 0x0B, -- this is the wrong spelling, it is not totally obsolete */
1390 ACTION_SUBTRACT = 0x0B,
1391 ACTION_MULTIPLY = 0x0C,
1392 ACTION_DIVIDE = 0x0D,
1393 ACTION_EQUAL = 0x0E,
1394 ACTION_LESS_THAN = 0x0F,
1395 ACTION_LOGICAL_AND = 0x10,
1396 ACTION_LOGICAL_OR = 0x11,
1397 ACTION_LOGICAL_NOT = 0x12,
1398 ACTION_STRING_EQUAL = 0x13,
1399 ACTION_STRING_LENGTH = 0x14,
1400 ACTION_SUB_STRING = 0x15,
1401 ACTION_POP = 0x17,
1402 ACTION_INTEGRAL_PART = 0x18,
1403 ACTION_GET_VARIABLE = 0x1C,
1404 ACTION_SET_VARIABLE = 0x1D,
1405 ACTION_SET_TARGET2 = 0x20,
1406 ACTION_CONCATENATE = 0x21,
1407 ACTION_GET_PROPERTY = 0x22,
1408 ACTION_SET_PROPERTY = 0x23,
1409 ACTION_DUPLICATE_SPRITE = 0x24,
1410 ACTION_REMOVE_SPRITE = 0x25,
1411 ACTION_TRACE = 0x26,
1412 ACTION_START_DRAG = 0x27,
1413 ACTION_STOP_DRAG = 0x28,
1414 ACTION_STRING_LESS_THAN = 0x29,
1415 ACTION_THROW = 0x2A,
1416 ACTION_CAST_OBJECT = 0x2B,
1417 ACTION_IMPLEMENTS = 0x2C,
1418 ACTION_FSCOMMAND2 = 0x2D,
1419 ACTION_RANDOM = 0x30,
1420 ACTION_MBSTRING_LENGTH = 0x31,
1421 ACTION_ORD = 0x32,
1422 ACTION_CHR = 0x33,
1423 ACTION_GET_TIMER = 0x34,
1424 ACTION_SUB_MBSTRING = 0x35,
1425 ACTION_MBORD = 0x36,
1426 ACTION_MBCHR = 0x37,
1427 ACTION_DELETE = 0x3A,
1428 ACTION_SET_LOCAL_VAR = 0x3C,
1429 ACTION_SET_LOCAL_VARIABLE = 0x3C,
1430 ACTION_CALL_FUNCTION = 0x3D,
1431 ACTION_RETURN = 0x3E,
1432 ACTION_MODULO = 0x3F,
1433 ACTION_NEW = 0x40,
1434 ACTION_DECLARE_LOCAL_VAR = 0x41,
1435 ACTION_DECLARE_LOCAL_VARIABLE = 0x41,
1436 ACTION_DECLARE_ARRAY = 0x42,
1437 ACTION_DECLARE_OBJECT = 0x43,
1438 ACTION_TYPE_OF = 0x44,
1439 ACTION_GET_TARGET = 0x45,
1440 ACTION_ENUMERATE = 0x46,
1441 ACTION_ADD_TYPED = 0x47,
1442 ACTION_LESS_THAN_TYPED = 0x48,
1443 ACTION_EQUAL_TYPED = 0x49,
1444 ACTION_NUMBER = 0x4A,
1445 ACTION_STRING = 0x4B,
1446 ACTION_DUPLICATE = 0x4C,
1447 ACTION_SWAP = 0x4D,
1448 ACTION_GET_MEMBER = 0x4E,
1449 ACTION_SET_MEMBER = 0x4F,
1450 ACTION_INCREMENT = 0x50,
1451 ACTION_DECREMENT = 0x51,
1452 ACTION_CALL_METHOD = 0x52,
1453 ACTION_NEW_METHOD = 0x53,
1454 ACTION_INSTANCE_OF = 0x54,
1455 ACTION_ENUMERATE_OBJECT = 0x55,
1456 ACTION_AND = 0x60,
1457 ACTION_OR = 0x61,
1458 ACTION_XOR = 0x62,
1459 ACTION_SHIFT_LEFT = 0x63,
1460 ACTION_SHIFT_RIGHT = 0x64,
1461 ACTION_SHIFT_RIGHT_UNSIGNED = 0x65,
1462 ACTION_STRICT_EQUAL = 0x66,
1463 ACTION_GREATER_THAN_TYPED = 0x67,
1464 ACTION_STRING_GREATER_THAN = 0x68,
1465 ACTION_EXTENDS = 0x69,
1466 ACTION_GOTO_FRAME = 0x81,
1467 ACTION_URL = 0x83,
1468 ACTION_STORE_REGISTER = 0x87,
1469 ACTION_DECLARE_DICTIONARY = 0x88,
1470 ACTION_STRICT_MODE = 0x89,
1471 ACTION_WAIT_FOR_FRAME = 0x8A,
1472 ACTION_SET_TARGET = 0x8B,
1473 ACTION_GOTO_LABEL = 0x8C,
1474 ACTION_WAIT_FOR_FRAME2 = 0x8D,
1475 ACTION_DECLARE_FUNCTION2 = 0x8E,
1476 ACTION_TRY = 0x8F,
1477 ACTION_WITH = 0x94,
1478 ACTION_PUSH_DATA = 0x96,
1479 ACTION_BRANCH_ALWAYS = 0x99,
1480 ACTION_URL2 = 0x9A,
1481 ACTION_DECLARE_FUNCTION = 0x9B,
1482 ACTION_BRANCH_IF_TRUE = 0x9D,
1483 ACTION_CALL_FRAME = 0x9E,
1484 ACTION_GOTO_EXPRESSION = 0x9F,
1485
1486 ACTION_max = 0xFF /* the maximum action number */
1487 };
1488
1489 Action(TagBase *tag, action_t action);
~Action()1490 virtual ~Action() {}
1491
1492 virtual Action * Duplicate(void) const;
Offset(void)1493 unsigned long Offset(void) const { return f_offset; }
Version(void)1494 virtual unsigned char Version(void) const { return f_min_version; }
1495
1496 ErrorManager::error_code_t Save(Data& data);
1497 virtual Vectors * SubList(void);
1498 ErrorManager::error_code_t SaveList(const Vectors *list, Data& data, const Vectors *extra = 0);
1499 static int MinimumListVersion(const Vectors& list);
1500 static int GetMaximumRegister(const Vectors& list);
1501 static ActionLabel * FindLabel(const Vectors& list, const char *label);
1502
1503 invisible:
1504 ErrorManager::error_code_t OnError(ErrorManager::error_code_t errcode, const char *message, ...) const;
1505
1506 protected:
1507 virtual ErrorManager::error_code_t SaveData(Data& data, Data& nested_data);
1508 virtual ErrorManager::error_code_t Save2ndPass(const Vectors& list, Data& data);
GetMaxRegister(void)1509 virtual int GetMaxRegister(void) const { return 0; }
1510 ErrorManager::error_code_t SaveString(Data& data, const char *string);
Tag(void)1511 TagBase * Tag(void) const { return const_cast<TagBase *>(f_tag); }
1512
1513 const action_t f_action;
1514 unsigned long f_offset; /* offset where this tag is being saved (saved for branches and with statments) */
1515
1516 private:
1517 #if DEBUG
1518 /*
1519 * Forbid copies (only in DEBUG mode so we don't have extra functions
1520 * for nothing otherwise) If you need a copy, use the Duplicate() instead
1521 */
1522 Action(const Action& action);
1523 Action& operator = (const Action& action);
1524 #endif
1525
1526 TagBase * f_tag;
1527 unsigned char f_min_version; /* minimum version to use this action */
1528 };
1529
1530
1531 exposed_class ActionBranch : public Action, public MemoryManager
1532 {
1533 public:
1534 /* one of:
1535 * ACTION_BRANCH_ALWAYS
1536 * ACTION_BRANCH_IF_TRUE
1537 */
1538 ActionBranch(TagBase *tag, action_t action = ACTION_BRANCH_ALWAYS);
1539
1540 void SetLabel(const char *label);
1541
1542 private:
1543 virtual Action * Duplicate(void) const;
1544 virtual ErrorManager::error_code_t SaveData(Data& data, Data& nested_data);
1545 virtual ErrorManager::error_code_t Save2ndPass(const Vectors& list, Data& data);
1546
1547 char * f_label;
1548 };
1549
1550
1551
1552 exposed_class ActionCallFrame : public Action, public MemoryManager
1553 {
1554 public:
1555 ActionCallFrame(TagBase *tag);
1556
1557 private:
1558 virtual ErrorManager::error_code_t SaveData(Data& data, Data& nested_data);
1559 };
1560
1561
1562
1563 exposed_class ActionDictionary : public Action, public MemoryManager
1564 {
1565 public:
1566 ActionDictionary(TagBase *tag);
1567
1568 void AddString(const char *string);
1569
1570 private:
1571 /// Holds one dictionary string
1572 struct string_t : public ItemBase
1573 {
1574 /// Pointer to the dictionary string
1575 char * f_string;
1576 };
1577
1578 virtual Action * Duplicate(void) const;
1579 virtual ErrorManager::error_code_t SaveData(Data& data, Data& nested_data);
1580
1581 /// Array of dictionary strings
1582 Vectors f_strings;
1583 };
1584
1585
1586
1587 exposed_class ActionFunction : public Action, public MemoryManager
1588 {
1589 public:
1590 /* one of:
1591 * ACTION_DECLARE_FUNCTION
1592 * ACTION_DECLARE_FUNCTION2
1593 */
1594 ActionFunction(TagBase *tag, action_t action = ACTION_DECLARE_FUNCTION);
1595
1596 enum action_function_t {
1597 ACTION_FUNCTION_LOAD_THIS = 0x0001,
1598 ACTION_FUNCTION_SUPPRESS_THIS = 0x0002,
1599 ACTION_FUNCTION_LOAD_ARGUMENTS = 0x0004,
1600 ACTION_FUNCTION_SUPPRESS_ARGUMENTS = 0x0008,
1601 ACTION_FUNCTION_LOAD_SUPER = 0x0010,
1602 ACTION_FUNCTION_SUPPRESS_SUPER = 0x0020,
1603 ACTION_FUNCTION_LOAD_ROOT = 0x0040,
1604 ACTION_FUNCTION_LOAD_PARENT = 0x0080,
1605 ACTION_FUNCTION_LOAD_GLOBAL = 0x0100
1606 };
1607
1608 void SetName(const char *name);
1609 void SetRegistersCount(unsigned int count);
1610 void AddParameter(const char *name, int register_number = -1);
1611 void AddAction(Action *action);
1612 virtual Vectors * SubList(void);
1613
1614 // flags for the ASSetPropFlags(obj, props, flags [, allow])
1615 // (see include/sswf/scripts/global/extensions.asc)
1616 enum as_set_prop_flags_t {
1617 PROP_FLAG_IS_HIDDEN = 1,
1618 PROP_FLAG_CAN_DELETE = 2,
1619 PROP_FLAG_CAN_OVERWRITE = 4
1620 };
1621
1622 private:
1623 /// Hold the parameters name and register number
1624 struct parameter_t : public ItemBase
1625 {
1626 /// The name of the parameter
1627 char * f_name;
1628 /// The register number (-1 means no register and 0 means auto-assign the number)
1629 int f_register_number; // if -1, use the name, if 0, auto-assign
1630 };
1631
1632 virtual Action * Duplicate(void) const;
1633 virtual ErrorManager::error_code_t SaveData(Data& data, Data& nested_data);
1634
1635 char * f_name;
1636 unsigned int f_registers_count;
1637 unsigned short f_flags;
1638 Vectors f_parameters;
1639 Vectors f_actions;
1640 };
1641
1642
1643
1644 exposed_class ActionGoto : public Action, public MemoryManager
1645 {
1646 public:
1647 /* one of:
1648 * ACTION_GOTO_FRAME
1649 * ACTION_GOTO_LABEL
1650 * ACTION_GOTO_EXPRESSION
1651 */
1652 ActionGoto(TagBase *tag, action_t action = ACTION_GOTO_FRAME);
1653
1654 void SetFrameName(const char *frame_name);
SetPlay(bool play)1655 void SetPlay(bool play) { f_play = play; }
1656
1657 private:
1658 virtual Action * Duplicate(void) const;
1659 virtual ErrorManager::error_code_t SaveData(Data& data, Data& nested_data);
1660
1661 char * f_frame_name;
1662 bool f_play;
1663 };
1664
1665
1666
1667 exposed_class ActionLabel : public Action, public MemoryManager
1668 {
1669 public:
1670 ActionLabel(TagBase *tag);
1671
1672 void SetLabel(const char *label);
GetLabel(void)1673 const char * GetLabel(void) const { return f_label; }
1674
1675 private:
1676 virtual Action * Duplicate(void) const;
1677 // we shall never even try to save a label! so no SaveData() is necessary
1678
1679 char * f_label;
1680 };
1681
1682
1683
1684
1685 exposed_class ActionPushData : public Action, public MemoryManager
1686 {
1687 public:
1688 ActionPushData(TagBase *tag);
1689
AddEmptyString(void)1690 void AddEmptyString(void) { AddString(0); }
1691 void AddString(const char *string);
AddTrue(void)1692 void AddTrue(void) { AddBoolean(true); }
AddFalse(void)1693 void AddFalse(void) { AddBoolean(false); }
1694 void AddBoolean(bool value);
1695 void AddInteger(long value);
1696 void AddFloat(float value);
1697 void AddDouble(double value);
1698 void AddNull(void);
1699 void AddLookup(unsigned short index);
1700 void AddRegister(unsigned char reg_index);
1701 void AddUndefined(void);
1702
1703 private:
1704 enum action_immediate_type_t
1705 {
1706 ACTION_IMMEDIATE_TYPE_UNKNOWN = -1,
1707 ACTION_IMMEDIATE_TYPE_STRING = 0x00,
1708 ACTION_IMMEDIATE_TYPE_FLOAT = 0x01,
1709 ACTION_IMMEDIATE_TYPE_NULL = 0x02,
1710 ACTION_IMMEDIATE_TYPE_UNDEFINED = 0x03,
1711 ACTION_IMMEDIATE_TYPE_REGISTER = 0x04,
1712 ACTION_IMMEDIATE_TYPE_BOOLEAN = 0x05,
1713 ACTION_IMMEDIATE_TYPE_DOUBLE = 0x06,
1714 ACTION_IMMEDIATE_TYPE_INTEGER = 0x07,
1715 ACTION_IMMEDIATE_TYPE_LOOKUP = 0x08,
1716 ACTION_IMMEDIATE_TYPE_LOOKUP_LARGE = 0x09
1717 };
1718 /// One data entry of a PushData action
1719 struct action_immediate_t : public ItemBase
1720 {
1721 action_immediate_type_t f_type;
1722 union
1723 {
1724 char * f_string;
1725 float f_float32;
1726 double f_float64;
1727 bool f_boolean;
1728 long f_integer32;
1729 unsigned short f_lookup;
1730 unsigned char f_register;
1731 } f_data;
1732
action_immediate_taction_immediate_t1733 action_immediate_t(action_immediate_type_t type)
1734 {
1735 f_type = type;
1736 memset(&f_data, 0, sizeof(f_data));
1737 }
1738 };
1739
1740 virtual Action * Duplicate(void) const;
1741 virtual ErrorManager::error_code_t SaveData(Data& data, Data& nested_data);
1742 virtual int GetMaxRegister(void) const;
1743
1744 Vectors f_data;
1745 };
1746
1747
1748
1749
1750 exposed_class ActionSetTarget : public Action, public MemoryManager
1751 {
1752 public:
1753 ActionSetTarget(TagBase *tag);
1754
1755 void SetTarget(const char *target);
1756
1757 private:
1758 virtual Action * Duplicate(void) const;
1759 virtual ErrorManager::error_code_t SaveData(Data& data, Data& nested_data);
1760
1761 char * f_target;
1762 };
1763
1764
1765 exposed_class ActionStoreRegister : public Action, public MemoryManager
1766 {
1767 public:
1768 ActionStoreRegister(TagBase *tag);
1769
1770 void SetRegister(unsigned char reg);
1771
1772 private:
1773 virtual Action * Duplicate(void) const;
1774 virtual ErrorManager::error_code_t SaveData(Data& data, Data& nested_data);
1775 virtual int GetMaxRegister(void) const;
1776
1777 unsigned char f_reg;
1778 };
1779
1780
1781 exposed_class ActionStrictMode : public Action, public MemoryManager
1782 {
1783 public:
1784 ActionStrictMode(TagBase *tag);
1785
1786 void SetStrict(bool strict);
1787
1788 private:
1789 virtual Action * Duplicate(void) const;
1790 virtual ErrorManager::error_code_t SaveData(Data& data, Data& nested_data);
1791
1792 bool f_strict;
1793 };
1794
1795
1796 exposed_class ActionTry : public Action, public MemoryManager
1797 {
1798 public:
1799 ActionTry(TagBase *tag);
1800
1801 void AddTryAction(Action *action);
1802 void AddCatchAction(Action *action);
1803 void AddFinallyAction(Action *action);
1804 void SetIdentifier(int register_number); // Catch(#)
1805 void SetIdentifier(const char *variable_name); // Catch(var)
1806
1807 Vectors * SubListTry(void);
1808 Vectors * SubListCatch(void);
1809 Vectors * SubListFinally(void);
1810
1811 private:
1812 virtual Action * Duplicate(void) const;
1813 virtual ErrorManager::error_code_t SaveData(Data& data, Data& nested_data);
1814 virtual int GetMaxRegister(void) const;
1815 virtual unsigned char Version(void) const;
1816
1817 int f_register;
1818 char * f_variable_name;
1819 bool f_has_catch;
1820 bool f_has_finally;
1821 Vectors f_actions_try;
1822 Vectors f_actions_catch;
1823 Vectors f_actions_finally;
1824 };
1825
1826
1827
1828 exposed_class ActionURL : public Action, public MemoryManager
1829 {
1830 public:
1831 /* one of:
1832 * ACTION_URL
1833 * ACTION_URL2
1834 */
1835 ActionURL(TagBase *tag, action_t action = ACTION_URL);
1836
1837 enum url_method_t {
1838 URL_METHOD_UNDEFINED = -1,
1839 URL_METHOD_NOVARIABLE = 0,
1840 URL_METHOD_NOVARIABLES = URL_METHOD_NOVARIABLE,
1841 URL_METHOD_GET = 1,
1842 URL_METHOD_POST = 2
1843 };
1844
1845 void SetURL(const char *url, const char *target);
1846 void SetMethod(url_method_t method);
1847
1848 private:
1849 virtual Action * Duplicate(void) const;
1850 virtual ErrorManager::error_code_t SaveData(Data& data, Data& nested_data);
1851
1852 char * f_url;
1853 char * f_target;
1854 url_method_t f_method;
1855 };
1856
1857
1858
1859 exposed_class ActionWaitForFrame : public Action, public MemoryManager
1860 {
1861 public:
1862 /* one of:
1863 * ACTION_WAIT_FOR_FRAME
1864 * ACTION_WAIT_FOR_FRAME2
1865 */
1866 ActionWaitForFrame(TagBase *tag, action_t action = ACTION_WAIT_FOR_FRAME);
1867
1868 void SetFrameName(const char *name);
1869 void AddAction(Action *action);
1870 virtual Vectors * SubList(void);
1871
1872 private:
1873 virtual Action * Duplicate(void) const;
1874 virtual ErrorManager::error_code_t SaveData(Data& data, Data& nested_data);
1875
1876 Vectors f_actions; // actions executed once frame is loaded
1877 char * f_frame_name;
1878 };
1879
1880
1881
1882 exposed_class ActionWith : public Action, public MemoryManager
1883 {
1884 public:
1885 ActionWith(TagBase *tag);
1886
1887 void AddAction(Action *action);
1888 virtual Vectors * SubList(void);
1889
1890 private:
1891 virtual Action * Duplicate(void) const;
1892 virtual ErrorManager::error_code_t SaveData(Data& data, Data& nested_data);
1893
1894 Vectors f_actions;
1895 };
1896
1897
1898
1899
1900
1901
1902 exposed_class TagDoAction : public TagBase
1903 {
1904 public:
1905 /* one of:
1906 * SWF_TAG_DO_ACTION
1907 * SWF_TAG_DO_INIT_ACTION (uses this when sprite ID was defined)
1908 */
1909 TagDoAction(TagBase *parent);
1910
1911 virtual ErrorManager::error_code_t Save(Data& data);
1912 virtual swf_type_t TypeFlags(void) const;
1913
1914 /////////////// SETUP FUNCTIONS
1915 void SetAction(const Action& action);
1916 void SetSprite(sswf_id_t sprite);
Actions(void)1917 Vectors& Actions(void) { return f_actions; }
1918
1919 private:
1920 virtual ErrorManager::error_code_t PreSave(void); // called by the header Save() function
1921
1922 sswf_id_t f_sprite;
1923 Vectors f_actions;
1924 };
1925
1926
1927
1928
1929
1930 exposed_class TagMetadata : public TagBase
1931 {
1932 public:
1933 TagMetadata(TagBase *parent);
1934
1935 virtual ErrorManager::error_code_t Save(Data& data);
1936 virtual swf_type_t TypeFlags(void) const;
1937
1938 /////////////// SETUP FUNCTIONS
1939 // You should not call all of these functions.
1940 // There are three groups decreasing priority:
1941 //
1942 // o Read the RDF from a file
1943 //
1944 // SetFilename()
1945 //
1946 // o Define the RDF verbatim
1947 //
1948 // SetMetadata()
1949 //
1950 // o Set values to be saved in an RDF built by SSWF
1951 //
1952 // SetTitle()
1953 // SetDescription()
1954 // SetAuthor()
1955 // SetPublisher()
1956 // SetCopyright()
1957 // SetURL()
1958 //
1959 void SetFilename(const char *filename);
1960 void SetMetadata(const char *xml);
1961 void SetTitle(const char *title);
1962 void SetDescription(const char *description);
1963 void SetAuthor(const char *description);
1964 void SetPublisher(const char *publisher);
1965 void SetCopyright(const char *copyright);
1966 void SetURL(const char *url);
1967
1968 private:
1969 virtual ErrorManager::error_code_t PreSave(void); // called by the header Save() function
1970
1971 char * f_xml;
1972 char * f_filename;
1973 char * f_title;
1974 char * f_description;
1975 char * f_author;
1976 char * f_publisher;
1977 char * f_copyright;
1978 char * f_url;
1979 };
1980
1981
1982
1983
1984
1985 exposed_class TagPlace : public TagBase
1986 {
1987 public:
1988 TagPlace(TagBase *parent);
1989
1990 virtual ErrorManager::error_code_t Save(Data& data);
1991 virtual swf_type_t TypeFlags(void) const;
1992
1993 /////////////// SETUP FUNCTIONS
1994 void SetObjectID(sswf_id_t id);
1995 void SetDepth(int depth);
1996 void SetClip(int depth);
1997 void SetMatrix(const Matrix& matrix);
1998 void SetColorTransform(const ColorTransform& color_transform);
1999 void SetName(const char *name);
2000 void SetMorphPosition(int position);
2001 void SetBlendMode(const BlendMode& blend_mode);
2002 void SetBitmapCaching(int bitmap_caching);
2003 void Replace(void);
2004 void Place(void);
2005 bool AddEvent(Event *event);
2006
2007 private:
2008 virtual ErrorManager::error_code_t PreSave(void); // called by the header Save() function
2009
2010 bool f_id_defined;
2011 sswf_id_t f_id;
2012 int f_replace;
2013 int f_depth;
2014 int f_clip_depth;
2015 char * f_name;
2016 unsigned long f_events_all_flags;
2017 int f_position; // morph position
2018 BlendMode f_blend_mode;
2019 int f_bitmap_caching;
2020 bool f_has_matrix;
2021 Matrix f_matrix;
2022 ColorTransform f_color_transform;
2023 Vectors f_events;
2024 };
2025
2026
2027
2028 exposed_class TagRemove : public TagBase
2029 {
2030 public:
2031 TagRemove(TagBase *parent);
2032
2033 virtual ErrorManager::error_code_t Save(Data& data);
2034 virtual swf_type_t TypeFlags(void) const;
2035
2036 /////////////// SETUP FUNCTIONS
SetDepth(int depth)2037 void SetDepth(int depth) { f_depth = depth; }
SetObjectID(sswf_id_t id)2038 void SetObjectID(sswf_id_t id) { f_id = id; }
2039
2040 private:
2041 virtual ErrorManager::error_code_t PreSave(void); // called by the header Save() function
2042
2043 int f_depth;
2044 sswf_id_t f_id;
2045 };
2046
2047
2048
2049 exposed_class TagSceneFrameData : public TagBase
2050 {
2051 public:
2052 TagSceneFrameData(TagBase *parent);
2053
2054 virtual ErrorManager::error_code_t Save(Data& data);
2055 virtual swf_type_t TypeFlags(void) const;
2056
2057 /////////////// SETUP FUNCTIONS
2058 bool SetFileData(const char *filename);
2059 void SetSceneFrameData(const char *data, size_t size);
2060
2061 private:
2062 virtual ErrorManager::error_code_t PreSave(void); // called by the header Save() function
2063
2064 char * f_data;
2065 size_t f_size;
2066 };
2067
2068
2069
2070
2071 exposed_class TagScriptLimits : public TagBase
2072 {
2073 public:
2074 TagScriptLimits(TagBase *parent);
2075
2076 virtual ErrorManager::error_code_t Save(Data& data);
2077 virtual swf_type_t TypeFlags(void) const;
2078
2079 /////////////// SETUP FUNCTIONS
2080 void SetMaxRecursionDepth(int depth);
2081 void SetTimeoutSeconds(int timeout);
2082 int GetMaxRecursionDepth(void) const;
2083 int GetTimeoutSeconds(void) const;
2084
2085 private:
2086 virtual ErrorManager::error_code_t PreSave(void);
2087
2088 int f_depth;
2089 int f_timeout;
2090 };
2091
2092
2093
2094 exposed_class TagSetTabIndex : public TagBase
2095 {
2096 public:
2097 TagSetTabIndex(TagBase *parent);
2098
2099 virtual ErrorManager::error_code_t Save(Data& data);
2100 virtual swf_type_t TypeFlags(void) const;
2101
2102 /////////////// SETUP FUNCTIONS
2103 void SetDepth(int depth);
2104 void SetIndex(int timeout);
2105 int GetDepth(void) const;
2106 int GetIndex(void) const;
2107
2108 private:
2109 virtual ErrorManager::error_code_t PreSave(void);
2110
2111 int f_depth;
2112 int f_index;
2113 };
2114
2115
2116
2117 exposed_class TagSetBackgroundColor : public TagBase
2118 {
2119 public:
2120 TagSetBackgroundColor(TagBase *parent);
2121
2122 virtual ErrorManager::error_code_t Save(Data& data);
2123 virtual swf_type_t TypeFlags(void) const;
2124
2125 /////////////// SETUP FUNCTIONS
2126 void SetColor(Color& color);
2127 Color& GetColor(void);
2128
2129 private:
2130 Color f_color;
2131 };
2132
2133
2134 exposed_class TagShowFrame : public TagBase
2135 {
2136 public:
2137 TagShowFrame(TagBase *parent);
2138
2139 virtual ErrorManager::error_code_t Save(Data& data);
2140 virtual swf_type_t TypeFlags(void) const;
2141 };
2142
2143
2144 exposed_class TagEnd : public TagBase
2145 {
2146 public:
2147 TagEnd(TagBase *parent);
2148
2149 virtual ErrorManager::error_code_t Save(Data& data);
2150 virtual swf_type_t TypeFlags(void) const;
2151 };
2152
2153
2154 exposed_class TagFrameLabel : public TagBase
2155 {
2156 public:
2157 TagFrameLabel(TagBase *parent);
2158
2159 virtual ErrorManager::error_code_t Save(Data& data);
2160 virtual swf_type_t TypeFlags(void) const;
2161
2162 /////////////// SETUP FUNCTIONS
2163 void SetFrameLabel(const char *label);
2164
2165 private:
2166 virtual ErrorManager::error_code_t PreSave(void);
2167
2168 char * f_label;
2169 };
2170
2171
2172
2173 exposed_class TagExport : public TagBase
2174 {
2175 public:
2176 TagExport(TagBase *parent);
2177
2178 virtual ErrorManager::error_code_t Save(Data& data);
2179 virtual swf_type_t TypeFlags(void) const;
2180
2181 /////////////// SETUP FUNCTIONS
2182 void SetObject(sswf_id_t id, const char *name, const char *used_glyphs);
2183
2184 private:
2185 /// One export entry with the identifier of the object to export and the export name
2186 struct export_t : public ItemBase
2187 {
2188 sswf_id_t f_id;
2189 const char * f_name;
2190 const char * f_used_glyphs;
2191 };
2192
2193 virtual ErrorManager::error_code_t PreSave(void);
2194
2195 Vectors f_objects;
2196 };
2197
2198
2199
2200 exposed_class TagImport : public TagBase
2201 {
2202 public:
2203 /* one of:
2204 * SWF_TAG_IMPORT (movies before version 8)
2205 * SWF_TAG_IMPORT2 (since version 8)
2206 */
2207 TagImport(TagBase *parent);
2208
2209 virtual ErrorManager::error_code_t Save(Data& data);
2210 virtual swf_type_t TypeFlags(void) const;
2211 const char * HasID(sswf_id_t id) const;
2212 sswf_id_t HasName(const char *name) const;
2213
2214 /////////////// SETUP FUNCTIONS
2215 void SetURL(const char *url);
2216 void SetFilename(const char *filename);
2217 void AddName(const char *name, const char *type);
2218
2219 private:
2220 /// Defines each imported object identifier, name and type
2221 struct import_t : public ItemBase
2222 {
2223 sswf_id_t f_id; // dynamically allocated
2224 const char * f_name; // external symbol name
2225 const char * f_type; // user specified type
2226 };
2227
2228 virtual ErrorManager::error_code_t PreSave(void);
2229
2230 char * f_url;
2231 char * f_filename;
2232 Vectors f_objects;
2233 };
2234
2235
2236
2237 exposed_class TagProtect : public TagBase
2238 {
2239 public:
2240 /* one of:
2241 * SWF_TAG_PROTECT
2242 * SWF_TAG_PROTECT_DEBUG
2243 * SWF_TAG_PROTECT_DEBUG2
2244 * (now with automatic selection only)
2245 */
2246 TagProtect(TagBase *parent);
2247
2248 virtual ErrorManager::error_code_t Save(Data& data);
2249 virtual swf_type_t TypeFlags(void) const;
2250
2251 /////////////// SETUP FUNCTIONS
2252 void SetPassword(const char *password);
2253 void SetEncodedPassword(const char *password);
2254
2255 private:
2256 virtual ErrorManager::error_code_t PreSave(void);
2257
2258 char * f_password;
2259 };
2260
2261
2262
2263 exposed_class TagProductInfo : public TagBase
2264 {
2265 public:
2266 TagProductInfo(TagBase *parent);
2267
2268 virtual ErrorManager::error_code_t Save(Data& data);
2269 virtual swf_type_t TypeFlags(void) const;
2270
2271 /////////////// SETUP FUNCTIONS
2272 void SetProduct(long product_id);
2273 void SetEdition(long edition);
2274 void SetVersion(int major, int minor);
2275 void SetBuild(int64_t build_number);
2276 void SetCompileDate(int64_t date);
2277
2278 private:
2279 virtual ErrorManager::error_code_t PreSave(void);
2280
2281 long f_product_id;
2282 long f_edition;
2283 int f_major;
2284 int f_minor;
2285 int64_t f_build_number;
2286 int64_t f_date;
2287 };
2288
2289
2290
2291 exposed_class TagInfo : public TagBase
2292 {
2293 public:
2294 TagInfo(TagBase *parent);
2295
2296 virtual ErrorManager::error_code_t Save(Data& data);
2297 virtual swf_type_t TypeFlags(void) const;
2298
2299 /////////////// SETUP FUNCTIONS
2300 void SetInfo(const char *info);
2301 void SetVersion(long version);
2302
2303 private:
2304 virtual ErrorManager::error_code_t PreSave(void);
2305
2306 char * f_info;
2307 long f_version;
2308 };
2309
2310
2311 exposed_class TagStartSound : public TagBase
2312 {
2313 public:
2314 TagStartSound(TagBase *parent);
2315
2316 virtual ErrorManager::error_code_t Save(Data& data);
2317 virtual swf_type_t TypeFlags(void) const;
2318
2319 /////////////// SETUP FUNCTIONS
2320 void SetInfo(SoundInfo *sound_info);
2321
2322 private:
2323 virtual ErrorManager::error_code_t PreSave(void);
2324
2325 SoundInfo * f_sound_info;
2326 };
2327
2328
2329
2330
2331
2332
2333
2334
2335 exposed_class TagScalingGrid
2336 {
2337 public:
2338 virtual ~TagScalingGrid();
2339
2340 ErrorManager::error_code_t GridSave(Data& data, sswf_id_t id);
2341 ErrorManager::error_code_t GridPreSave(void);
2342
2343 const SRectangle& Grid(void) const;
2344
2345 /////////////// SETUP FUNCTIONS
2346 void SetGrid(const SRectangle& rect);
2347
2348 private:
2349 SRectangle f_grid;
2350 };
2351
2352
2353
2354
2355
2356
2357
2358
2359
2360
2361 /****************************************/
2362 /****************************************/
2363 /********************* TAGS WITH IDs ****/
2364 /****************************************/
2365 /****************************************/
2366
2367 exposed_class TagBaseID : public TagBase
2368 {
2369 public:
2370 virtual ~TagBaseID();
2371
2372 virtual sswf_id_t Identification(void) const;
2373 void NoIdentification(void);
2374 bool HasIdentification(void) const;
2375
2376 int SaveID(Data& data) const;
2377
2378 invisible:
2379 TagBaseID(const char *name, TagBase *parent);
2380
2381 private:
2382 sswf_id_t f_id;
2383 bool f_identified;
2384 };
2385
2386
2387
2388
2389
2390 exposed_class TagBinaryData : public TagBaseID
2391 {
2392 public:
2393 TagBinaryData(TagBase *parent);
2394 virtual ~TagBinaryData();
2395
2396 virtual ErrorManager::error_code_t Save(Data& data);
2397 virtual swf_type_t TypeFlags(void) const;
2398
2399 /////////////// SETUP FUNCTIONS
2400 void GetData(const char *& data, size_t& size) const;
2401 void SetData(const char *data, size_t size);
2402
2403 private:
2404 virtual ErrorManager::error_code_t PreSave(void);
2405
2406 char * f_data;
2407 size_t f_size;
2408 };
2409
2410
2411
2412
2413 exposed_class TagButton : public TagBaseID, public TagScalingGrid
2414 {
2415 public:
2416 TagButton(TagBase *parent);
2417
2418 virtual ErrorManager::error_code_t Save(Data& data);
2419 virtual swf_type_t TypeFlags(void) const;
2420
2421 /////////////// SETUP FUNCTIONS
2422 bool SetState(const State& state);
2423 void SetAction(const Action& action);
2424 void SetMenu(bool menu = true);
2425 Vectors& Actions(void);
2426 bool AddEvent(Event *event);
2427
2428 private:
2429 virtual ErrorManager::error_code_t PreSave(void); // called by the header Save() function
2430
2431 bool f_save_button2;
2432 bool f_menu; // whether to track as a menu
2433 Vectors f_states;
2434 Vectors f_actions;
2435 Vectors f_events;
2436 };
2437
2438
2439
2440 exposed_class TagCSMTextSettings
2441 {
2442 public:
2443 enum csm_text_renderer_t {
2444 CSM_TEXT_RENDERER_NORMAL = 0,
2445 CSM_TEXT_RENDERER_FLASH = 1
2446 };
2447 enum csm_text_gridfit_t {
2448 CSM_TEXT_GRIDFIT_NO_GRID = 0,
2449 CSM_TEXT_GRIDFIT_PIXEL = 1,
2450 CSM_TEXT_GRIDFIT_SUBPIXEL = 2
2451 };
2452
2453 TagCSMTextSettings(void);
2454 virtual ~TagCSMTextSettings(void);
2455
2456 bool IsCSMTextSettingsDefined(void) const;
2457
2458 void SetRenderer(csm_text_renderer_t csm_text_renderer);
2459 void SetGridFit(csm_text_gridfit_t csm_text_gridfit);
2460 void SetThickness(float thickness);
2461 void SetSharpness(float sharpness);
2462
2463 protected:
2464 // Access via the PreSave()/Save() functions of the TagEditText and TagText
2465 ErrorManager::error_code_t PreSaveCSMTextSettings(void);
2466 ErrorManager::error_code_t SaveCSMTextSettings(Data& data);
2467
2468 private:
2469 csm_text_renderer_t f_csm_text_renderer;
2470 csm_text_gridfit_t f_csm_text_gridfit;
2471 float f_thickness;
2472 float f_sharpness;
2473 };
2474
2475
2476 class TagShape;
2477 exposed_class TagFont : public TagBaseID
2478 {
2479 public:
2480 enum font_type_t {
2481 FONT_TYPE_BEST = 0, // create the best possible result
2482 FONT_TYPE_ASCII,
2483 FONT_TYPE_UNICODE,
2484 FONT_TYPE_SHIFTJIS,
2485 };
2486 enum font_language_t {
2487 FONT_LANGUAGE_UNKNOWN = -1,
2488 FONT_LANGUAGE_LOCALE = 0,
2489 FONT_LANGUAGE_LATIN = 1,
2490 FONT_LANGUAGE_JAPANESE = 2,
2491 FONT_LANGUAGE_KOREAN = 3,
2492 FONT_LANGUAGE_SIMPLIFIED_CHINESE = 4,
2493 FONT_LANGUAGE_TRADITIONAL_CHINESE = 5,
2494
2495 FONT_LANGUAGE_max = 6
2496 };
2497 enum font_thickness_t {
2498 FONT_THICKNESS_UNKNOWN = -1,
2499 FONT_THICKNESS_THIN = 0,
2500 FONT_THICKNESS_MEDIUM = 1,
2501 FONT_THICKNESS_THICK = 2,
2502
2503 FONT_THICKNESS_max = 3
2504 };
2505 enum font_em_size_t {
2506 FONT_EM_SMALL = 0,
2507 FONT_EM_LARGE = 1
2508 };
2509
2510 #define SSWF_FONT_SPACE_INDEX static_cast<unsigned long>(-1)
2511
2512 /// Structure used to handle one glyph information
2513 struct font_info_t {
2514 sswf_ucs4_t f_glyph; // the glyph name ('A', 'B', ...)
2515 unsigned short f_saved_index; // index in the SWF file (within the referenced glyphs)
2516 unsigned long f_index; // index in the memory array (of all glyphs)
2517 unsigned long f_position; // closest position or exact position in the list of glyphs
2518 long f_advance; // the advance in TWIPs
2519 bool f_is_empty; // if true, it's like a space (i.e. invisible)
2520 };
2521
2522 TagFont(TagBase *parent);
2523
2524 virtual ErrorManager::error_code_t Save(Data& data);
2525 virtual swf_type_t TypeFlags(void) const;
2526 ErrorManager::error_code_t GlyphInfo(font_info_t& info) const;
2527 bool HasGlyph(void) const;
2528 bool FindGlyph(font_info_t& info, bool mark_empty_in_use = false) const;
2529 const char * FontName(void) const;
2530 long DefaultAscent(void) const;
2531 long DefaultDescent(void) const;
2532 long DefaultLeadingHeight(void) const;
2533 static font_language_t StringToLanguage(const char *language);
2534 static const char * LanguageToString(font_language_t language);
2535
2536 /////////////// SETUP FUNCTIONS
2537 //
2538 // WARNING: The pointers of the shape referenced are kept as is (the shape is not
2539 // copied in any way)
2540 //
2541 // So you have to make sure that these shapes still exist at the time
2542 // the Save() is called.
2543 //
2544 ErrorManager::error_code_t AddGlyph(sswf_ucs4_t name, const TagBase *ref, long advance = LONG_MIN);
2545 void SetName(const char *font_name);
2546 void SetDisplayName(const char *display_name);
2547 void SetCopyright(const char *copyright);
2548 void SetLayout(long ascent, long descent, long leading_height);
2549 void SetDefaultAdvance(long advance);
2550 void SetSpaceAdvance(long advance);
2551 void SetType(font_type_t type);
2552 void SetLanguage(font_language_t language);
2553 void SetBold(bool bold);
2554 void SetItalic(bool italic);
2555 void SetSmallText(bool small_text = true);
2556 void SetThickness(font_thickness_t thickness);
2557 void SetEMSize(font_em_size_t font_em_size);
2558 void SetWide(bool wide);
2559 ErrorManager::error_code_t SetUsedGlyphs(const char *used_glyphs, bool mark_empty_in_use = false);
2560 ErrorManager::error_code_t SetUsedGlyphs(const sswf_ucs4_t *used_glyphs, bool mark_empty_in_use = false);
2561 void SetUsedByEditText(bool used = true);
2562 void AddKern(sswf_ucs4_t code0, sswf_ucs4_t code1, long advance);
2563
2564 private:
2565 /// Structure used to represent a glyph
2566 struct font_glyph_t : public ItemBase
2567 {
2568 sswf_ucs4_t f_name; /* "A", "B", "0", "1", etc. */
2569 unsigned short f_index; /* index of this item when saved in the output file */
2570 const TagShape *f_shape; /* the shape used for this glyph */
2571 long f_advance; /* the number of TWIPs to advance */
2572 bool f_in_use; /* if true this glyph was referenced at least once */
2573 };
2574 /// Structure used to define one kern entry
2575 struct font_kern_t : public ItemBase
2576 {
2577 sswf_ucs4_t f_code[2];
2578 long f_advance;
2579 };
2580
2581 virtual ErrorManager::error_code_t PreSave(void);
2582 virtual ErrorManager::error_code_t PreSave2ndPass(void);
2583
2584 static const char * g_font_language_name[FONT_LANGUAGE_max];
2585 char * f_font_name;
2586 char * f_display_name;
2587 char * f_copyright;
2588 font_language_t f_language; // v6.x language definition
2589 font_type_t f_type; // unused in v6.x
2590 bool f_bold;
2591 bool f_italic;
2592 bool f_small_text;
2593 bool f_wide;
2594 bool f_has_wide_char; // defined in PreSave2ndPass()
2595 bool f_has_wide_offsets; // defined in PreSave2ndPass()
2596 bool f_has_layout; // defined in PreSave2ndPass()
2597 bool f_used_by_edit_text; // reset in PreSave() used in PreSave2ndPass()
2598 bool f_define_font2; // defined in PreSave2ndPass()
2599 font_thickness_t f_thickness;
2600 font_em_size_t f_font_em_size;
2601 long f_ascent;
2602 long f_descent;
2603 long f_leading_height;
2604 long f_default_advance;
2605 long f_space_advance;
2606 long f_offsets_max; // size of the current f_offsets buffer
2607 unsigned long * f_offsets; // this is a list of unsigned shorts if f_has_wide_offset if false -- defined in PreSave2ndPass()
2608 unsigned long f_count; // the number of glyphs saved (defined in PreSave2ndPass())
2609 Data f_save_glyphs; // defined in PreSave2ndPass()
2610 Vectors f_glyphs;
2611 Vectors f_kerns;
2612 };
2613
2614
2615
2616
2617
2618 exposed_class TagEditText : public TagBaseID, public TagCSMTextSettings
2619 {
2620 public:
2621 enum edit_text_alignment_t {
2622 EDIT_TEXT_ALIGNMENT_LEFT = 0,
2623 EDIT_TEXT_ALIGNMENT_RIGHT = 1,
2624 EDIT_TEXT_ALIGNMENT_CENTER = 2,
2625 EDIT_TEXT_ALIGNMENT_JUSTIFY = 3
2626 };
2627
2628 TagEditText(TagBase *parent);
2629
2630 virtual ErrorManager::error_code_t Save(Data& data);
2631 virtual swf_type_t TypeFlags(void) const;
2632
2633 /////////////// SETUP FUNCTIONS
2634 void SetText(const char *text);
2635 void SetVariableName(const char *name);
2636 void SetFont(const TagFont *font, long height);
2637 void SetMargins(long left, long right);
2638 void SetBounds(const SRectangle& bounds);
2639 void SetAlign(edit_text_alignment_t align);
2640 void SetIndent(long indent);
2641 void SetLeading(long leading);
2642 void SetColor(Color& color);
2643 void SetMaxLength(long length);
2644 void SetWordWrap(bool status = true);
2645 void SetMultiline(bool status = true);
2646 void SetPassword(bool status = true);
2647 void SetReadOnly(bool status = true);
2648 void SetNoSelect(bool status = true);
2649 void SetBorder(bool status = true);
2650 void SetOutline(bool status = true);
2651 void SetHTML(bool status = true);
2652 void SetAutoSize(bool status = true);
2653 void SetUsedGlyphs(const char *lists);
2654 void AddUsedString(const char *string);
2655
2656 private:
2657 virtual ErrorManager::error_code_t PreSave(void);
2658
2659 SRectangle f_bounds; // where the string is drawn
2660 edit_text_alignment_t f_align;
2661 long f_left_margin;
2662 long f_right_margin;
2663 long f_indent;
2664 long f_leading;
2665 const TagFont * f_font;
2666 unsigned short f_font_height;
2667 long f_max_length; // maximum number of character, if <= 0 - undefined
2668 char * f_var_name; // required
2669 char * f_text; // if 0, no initialization text [SaveString() expects a UTF-8 so we keep it that way]
2670 sswf_ucs4_t * f_used_glyphs; // default to "*" if undefined
2671 sswf_ucs4_t * f_used_strings; // concatenation of used strings
2672 Color f_color;
2673 bool f_has_color; // if this is true then the user defined the color
2674 bool f_word_wrap;
2675 bool f_multiline;
2676 bool f_password;
2677 bool f_readonly;
2678 bool f_no_select;
2679 bool f_border;
2680 bool f_outline;
2681 bool f_html;
2682 bool f_autosize;
2683 };
2684
2685
2686 exposed_class TagImage : public TagBaseID
2687 {
2688 public:
2689 enum image_format_t {
2690 IMAGE_FORMAT_UNKNOWN = 0,
2691 IMAGE_FORMAT_LOSSLESS_BEST,
2692 IMAGE_FORMAT_LOSSLESS_8,
2693 IMAGE_FORMAT_LOSSLESS_16,
2694 IMAGE_FORMAT_LOSSLESS_32,
2695 IMAGE_FORMAT_JPEG,
2696 IMAGE_FORMAT_max
2697 };
2698 /// Defines a bitmap
2699 struct image_t {
2700 bool f_alpha; // whether the source had 4 components (depth = 0x20)
2701 long f_width; // size of the image in pixels
2702 long f_height;
2703 unsigned char * f_data; // data of the image
2704 };
2705
2706 TagImage(TagBase *parent);
2707 //virtual ~TagImage();
2708
2709 virtual ErrorManager::error_code_t Save(Data& data);
2710 virtual swf_type_t TypeFlags(void) const;
GetImageData(image_t & image_data)2711 void GetImageData(image_t& image_data) { image_data = f_image; }
2712
2713 /////////////// SETUP FUNCTIONS
SetFormat(image_format_t format)2714 void SetFormat(image_format_t format) { f_format = format; }
SetQuality(int quality)2715 void SetQuality(int quality) { f_quality = quality; }
2716 ErrorManager::error_code_t SetFilename(const char *image, const char *mask);
2717 void SetImage(long width, long height, unsigned char *data, bool alpha = false, long count = 0, unsigned char *colormap = 0);
2718
2719 ErrorManager::error_code_t LoadTGA(const char *filename, image_t& im);
2720 ErrorManager::error_code_t LoadJPEG(const char *filename, image_t& im);
2721 ErrorManager::error_code_t SaveJPEG(Data& encoding, Data& image);
2722 ErrorManager::error_code_t SetAlpha(image_t& im, const image_t& mask);
2723
2724 private:
2725 virtual ErrorManager::error_code_t PreSave(void);
2726
2727 image_format_t f_format; // one of the IMAGE_FORMAT_...
2728 image_t f_image; // the image
2729 int f_quality; // for JPEG, the quality level
2730 long f_count; // number of colors in the colormap
2731 unsigned char * f_colormap; // the colormap when it can be generated
2732 };
2733
2734
2735
2736 exposed_class TagShape : public TagBaseID
2737 {
2738 public:
2739 enum morph_t {
2740 MORPH_MODE_SHAPE0 = 0,
2741 MORPH_MODE_SHAPE1 = 1,
2742 MORPH_MODE_BOTH_SHAPES = 2
2743 };
2744 enum fill_t {
2745 SHAPE_FILL_EVEN = 0, // Also called Fill0
2746 SHAPE_FILL_ODD = 1 // Also called Fill1
2747 };
2748
2749 TagShape(TagBase *parent);
2750
2751 virtual ErrorManager::error_code_t Save(Data& data);
2752 virtual swf_type_t TypeFlags(void) const;
2753 ErrorManager::error_code_t SaveWithoutStyles(Data& data);
2754 void SaveAlignZone(Data& data) const;
2755 bool HasAlignZone(void) const;
HasBounds(void)2756 bool HasBounds(void) const { return !f_bounds[0].IsEmpty() || !f_bounds[1].IsEmpty(); }
Bounds(int index)2757 const SRectangle& Bounds(int index) const { assert(index == 0 || index == 1, "invalid index to query bounds"); return f_bounds[index]; }
2758 bool IsGlyph(void) const;
2759 bool IsEmpty(void) const;
2760
2761
2762 /////////////// SETUP FUNCTIONS
2763 ErrorManager::error_code_t AddMove(morph_t morph_mode, long x, long y);
AddEdge(morph_t morph_mode,long x,long y)2764 ErrorManager::error_code_t AddEdge(morph_t morph_mode, long x, long y) { Edges::edge_t edge(x, y); return AddEdge(morph_mode, edge); }
AddEdge(morph_t morph_mode,long x,long y,long ctrl_x,long ctrl_y)2765 ErrorManager::error_code_t AddEdge(morph_t morph_mode, long x, long y, long ctrl_x, long ctrl_y) { Edges::edge_t edge(x, y, ctrl_x, ctrl_y); return AddEdge(morph_mode, edge); };
2766 void NewStyles(void);
2767 ErrorManager::error_code_t AddStyle(const Style& style, fill_t fill = SHAPE_FILL_EVEN);
2768 void SetAlignZone(const SRectangle& zone);
2769 ErrorManager::error_code_t SetBounds(int index, const SRectangle& rect, bool show = false);
2770 ErrorManager::error_code_t SetStrokesBounds(int index, const SRectangle& rect);
2771 void ShowBounds(bool show = true) { f_show_bounds = show; }
2772 void ShowOrigin(bool show = true) { f_show_origin = show; }
SetNonScalingStrokes(bool has_non_scaling_strokes)2773 void SetNonScalingStrokes(bool has_non_scaling_strokes) { f_has_non_scaling_strokes = has_non_scaling_strokes; }
SetScalingStrokes(bool has_scaling_strokes)2774 void SetScalingStrokes(bool has_scaling_strokes) { f_has_scaling_strokes = has_scaling_strokes; }
2775 void Glyph(void);
2776
HasShowBounds(void)2777 bool HasShowBounds(void) const { return f_show_bounds; }
2778
2779 invisible:
2780 ErrorManager::error_code_t AddEdge(morph_t morph_mode, const Edges::edge_t& edge);
2781
2782 private:
2783 enum what_t {
2784 SHAPE_EDGES,
2785 SHAPE_SETUP
2786 };
2787
2788 /// A base class to define edges and setup information
2789 struct shape_what_t : public ItemBase
2790 {
2791 what_t f_what;
shape_what_tshape_what_t2792 shape_what_t(what_t what) { f_what = what; }
2793 };
2794 /// The set of edges: line and curve segments
2795 struct shape_edges_t : public shape_what_t
2796 {
2797 Edges f_edges;
shape_edges_tshape_edges_t2798 shape_edges_t(what_t what) : shape_what_t(what) {}
2799 };
2800 /// The set of setup: fill, line and move
2801 struct shape_setup_t : public shape_what_t
2802 {
2803 int f_fill_ref[2];
2804 int f_line_ref;
2805 long f_x;
2806 long f_y;
2807
shape_what_tshape_setup_t2808 shape_setup_t(what_t what, bool origin = false) : shape_what_t(what)
2809 {
2810 f_fill_ref[0] = f_fill_ref[1] = f_line_ref = -1;
2811 if(origin) {
2812 f_x = f_y = 0;
2813 }
2814 else {
2815 f_x = f_y = LONG_MIN;
2816 }
2817 }
2818 };
2819
2820 /// Records to separate different sets of styles
2821 struct shape_record_t : public ItemBase { // used to save in f_shapes
2822 Vectors * f_fill_styles;
2823 Vectors * f_line_styles;
2824 Vectors * f_record;
2825 };
2826
2827 /// Holds information used to save a shape
2828 struct save_info_t {
2829 shape_record_t f_sr;
2830 bool f_save_alpha;
2831 bool f_ext_size;
2832 bool f_first;
2833 bool f_save_styles;
2834 bool f_shape4;
2835 Data f_data; // we save it all here (we need to have the size before to create the tag data)
2836 int f_fill_bits_count;
2837 int f_line_bits_count;
2838 };
2839
2840 void RecordEdges(void);
2841 void RecordSetup(void);
2842 void NewEdges(void);
2843 void NewSetup(void);
2844 void SetMorph(void);
2845
2846 // save sub-functions
2847 virtual ErrorManager::error_code_t PreSave(void);
2848 ErrorManager::error_code_t SaveShape(save_info_t& info, shape_setup_t& last_setup);
2849 //ErrorManager::error_code_t SaveMorph(Data& data);
2850 ErrorManager::error_code_t SaveSetup(save_info_t& info, const shape_setup_t& setup, shape_setup_t& last);
2851 ErrorManager::error_code_t SaveStyles(save_info_t& info);
2852 ErrorManager::error_code_t SaveStylesCount(save_info_t& info, long count);
2853
2854 unsigned char f_version; // the minimum version necessary to save this shape (determines the tag)
2855 bool f_morph; // this is a morph shape
2856 bool f_is_glyph; // used only as a glyph (font character)
2857 bool f_show_bounds; // draw the bounding rectangle around the shape
2858 bool f_show_origin; // draw lines showing the origin
2859 bool f_has_non_scaling_strokes; // whether there is at least one non-scaling stroke
2860 bool f_has_scaling_strokes; // whether there is at least one scaling stroke
2861 SRectangle f_align_zone; // to align glyphs the best we can
2862 SRectangle f_bounds[2]; // where the shape is drawn
2863 SRectangle f_strokes_bounds[2]; // where the shape is drawn
2864
2865 Vectors f_shapes; // each shape saved here has its own set of fill & line style
2866
2867 shape_edges_t * f_edges; // if not NULL that's the current Edges to fill
2868 shape_edges_t * f_morph_edges; // if not NULL that's the current Edges to fill the morph (2nd shape)
2869 shape_setup_t * f_setup; // if not NULL that's the current Setup to define
2870 Vectors f_fill_styles;
2871 Vectors f_line_styles;
2872 Vectors f_record; // the current shape being built
2873 Vectors f_morph_record; // the current morph shape being built
2874 };
2875
2876
2877
2878 exposed_class TagSound : public TagBaseID
2879 {
2880 public:
2881 enum sound_format_t {
2882 SOUND_FORMAT_UNKNOWN = -1,
2883 SOUND_FORMAT_RAW = 0,
2884 SOUND_FORMAT_ADPCM = 1,
2885 SOUND_FORMAT_MP3 = 2,
2886 SOUND_FORMAT_UNCOMPRESSED = 3,
2887 SOUND_FORMAT_NELLYMOSER = 6
2888 };
2889 enum sound_endian_t {
2890 SOUND_ENDIAN_LITTLE = 0, // the user data is in little endian
2891 SOUND_ENDIAN_BIG, // the user data is in big endian
2892 SOUND_ENDIAN_SAME, // accept processor endianess as the data endianess
2893 SOUND_ENDIAN_DONTUSE, // use this for 8bits data
2894 SOUND_ENDIAN_UNKNOWN // undefined endianess -- the SetData() will always fail with this value
2895 };
2896
2897 TagSound(TagBase *parent);
2898
2899 virtual ErrorManager::error_code_t Save(Data& data);
2900 virtual swf_type_t TypeFlags(void) const;
2901
2902 size_t GetSamplesCount(void) const;
2903
2904 /////////////// SETUP FUNCTIONS
2905 ErrorManager::error_code_t SetFilename(const char *filename);
2906 void SetFormat(sound_format_t format);
2907 int SetData(const void *data, size_t size, sound_endian_t endian, int width, unsigned int rate, bool stereo);
2908 void SetMono(void);
2909 void Set8Bits(void);
2910
2911 invisible:
2912 static const int g_sound_rates[4];
2913
2914 private:
2915 /// defines an MP3 sound wave (format, channels, rate, alignment, etc.)
2916 struct sound_wave_t {
2917 short format; // the data format (we only support PCM)
2918 short channels; // number of channels (1 - mono, 2 - stereo)
2919 int rate; // exact sample rate to play the sound at
2920 int average_rate; // average rate for the entire set of samples (this may vary in compressed files)
2921 short align; // byte alignment of the samples (every char, short, long...)
2922 /* the following is format dependent, but at this time doesn't vary for us */
2923 short width; // width of the samples (8 or 16)
2924 };
2925
2926 virtual ErrorManager::error_code_t PreSave(void);
2927 short ReadSample(const unsigned char *data, unsigned short adjust, int in_fmt);
2928 void Resample(unsigned char *snd, unsigned int out_bytes, const unsigned char *src, size_t size, unsigned int in_bytes, size_t max, double fix, unsigned short adjust, int in_fmt);
2929 int LoadWaveFile(FILE *f);
2930 int LoadMP3File(FILE *f);
2931 int CheckMP3Header(FILE *f, unsigned char *header, int& frame_size);
2932 int ReadMP3Header(FILE *f, unsigned char *header);
2933
2934 static const int g_bitrates[2][16];
2935 static const int g_frequencies[4][4];
2936
2937 sound_format_t f_format;
2938 bool f_stereo;
2939 int f_rate;
2940 int f_width;
2941 size_t f_samples;
2942 int f_data_size;
2943 int f_data_maxsize;
2944 unsigned char * f_data;
2945 int f_latency_seek;
2946 };
2947
2948
2949
2950
2951
2952
2953 exposed_class TagSprite : public TagBaseID, public TagScalingGrid
2954 {
2955 public:
2956 TagSprite(TagBase *parent);
2957
2958 virtual ErrorManager::error_code_t Save(Data& data);
2959 virtual swf_type_t TypeFlags(void) const;
2960
2961 /////////////// SETUP FUNCTIONS
2962 // Add objects to a sprite by defining the sprite tag as
2963 // the parent of these objects.
2964 // The parent of a sprite must be a TagHeader object.
2965
2966 // We now have one setup function: SetGrid() inherited from
2967 // the TagScalingGrid class
2968
2969 protected:
2970 virtual ErrorManager::error_code_t OnNewChild(const char *child_name) const;
2971
2972 private:
2973 virtual ErrorManager::error_code_t PreSave(void);
2974 };
2975
2976
2977
2978
2979 exposed_class TagText : public TagBaseID, public TagCSMTextSettings
2980 {
2981 public:
2982 TagText(TagBase *parent);
2983
2984 virtual ErrorManager::error_code_t Save(Data& data);
2985 virtual swf_type_t TypeFlags(void) const;
2986
2987 /////////////// SETUP FUNCTIONS
2988 void SetMatrix(const Matrix& matrix);
2989 void SetBounds(const SRectangle& bounds);
2990 ErrorManager::error_code_t AddText(const char *string, long advance = LONG_MIN);
2991 void AddFont(const TagFont *font, long height);
2992 void AddOffsets(long x, long y);
2993 void AddColor(Color& color);
2994
2995 private:
2996 enum text_type_t {
2997 TEXT_ENTRY_TEXT = 0,
2998 TEXT_ENTRY_SETUP
2999 };
3000
3001 /// Structure used to memories the type of definition
3002 struct text_define_t : public ItemBase { // used to save in f_shapes
3003 const text_type_t f_type;
3004
text_define_ttext_define_t3005 text_define_t(text_type_t type) : f_type(type) {}
3006 };
3007
3008 /// Structure representing a text setup
3009 struct text_setup_t : public text_define_t { // used to save in f_shapes
3010 bool f_has_font;
3011 const TagFont * f_font;
3012 unsigned short f_font_height;
3013 bool f_has_xadjust;
3014 long f_xadjust;
3015 bool f_has_xoffset;
3016 long f_x;
3017 bool f_has_yoffset;
3018 long f_y;
3019 bool f_has_color;
3020 Color f_color;
3021
3022 text_setup_t(void);
3023 text_setup_t(const text_setup_t& setup);
3024 void Unused(void);
3025 bool IsUsed(void) const;
3026 };
3027
3028 /// Structure representing a text entry (an actual string)
3029 struct text_entry_t : public text_define_t {
3030 sswf_ucs4_t * f_text;
3031 long f_advance;
3032 unsigned long f_length; // length of the string
3033 unsigned long f_exact_length; // length of string without spaces
3034 TagFont::font_info_t * f_entries; // an array of entries
3035
3036 text_entry_t(sswf_ucs4_t *string, long advance);
3037 };
3038
3039 virtual ErrorManager::error_code_t PreSave(void);
3040 int DefineText(int start, text_setup_t *s, const TagFont *font, int font_height);
3041 ErrorManager::error_code_t RecordSetup(void);
3042 void NewSetup(void);
3043
3044 Matrix f_matrix; // a transformation matrix for this text
3045 SRectangle f_bounds; // where the string is drawn
3046 text_setup_t f_setup; // current setup definition
3047 bool f_new_text; // if true we need to recompute the text info entries
3048 int f_version; // the PreSave() defines this, Save() uses it
3049 Vectors f_records; // text records
3050 };
3051
3052
3053
3054
3055
3056
3057
3058
3059
3060 }; // namespace sswf
3061 #endif /* #ifndef LIBSSWF_H */
3062