swf_tree/
tags.rs

1use ::serde::{Deserialize, Serialize};
2
3use crate::basic_types::{ColorTransformWithAlpha, LanguageCode, Matrix, NamedId, Rect, SRgb8, StraightSRgba8};
4use crate::button::ButtonRecord;
5use crate::button::{ButtonCondAction, ButtonSound};
6use crate::float_is::Is;
7use crate::helpers::{buffer_to_hex, hex_to_buffer, hex_to_optional_buffer, optional_buffer_to_hex};
8use crate::shape::MorphShape;
9use crate::shape::{ClipAction, Glyph, Shape};
10use crate::sound::{AudioCodingFormat, SoundInfo, SoundRate, SoundSize, SoundType};
11use crate::text::{
12  CsmTableHint, EmSquareSize, FontAlignmentZone, FontLayout, GridFitting, TextAlignment, TextRecord, TextRenderer,
13};
14use crate::ImageType;
15use crate::Tag;
16use crate::{BlendMode, ColorTransform};
17use crate::{Filter, VideoCodec, VideoDeblocking};
18
19#[derive(Copy, Clone, Debug, Serialize, Deserialize)]
20#[serde(rename_all = "snake_case")]
21pub struct CsmTextSettings {
22  pub text_id: u16,
23  pub renderer: TextRenderer,
24  pub fitting: GridFitting,
25  pub thickness: f32,
26  pub sharpness: f32,
27}
28
29impl ::std::cmp::PartialEq for CsmTextSettings {
30  fn eq(&self, other: &Self) -> bool {
31    self.text_id == other.text_id
32      && self.renderer == other.renderer
33      && self.fitting == other.fitting
34      && self.thickness.is(&other.thickness)
35      && self.sharpness.is(&other.sharpness)
36  }
37
38  fn ne(&self, other: &Self) -> bool {
39    !self.eq(other)
40  }
41}
42
43impl ::std::cmp::Eq for CsmTextSettings {}
44
45#[derive(Clone, Debug, PartialEq, Eq, PartialOrd, Ord, Hash, Serialize, Deserialize)]
46#[serde(rename_all = "snake_case")]
47pub struct DefineBinaryData {
48  pub id: u16,
49  #[serde(serialize_with = "buffer_to_hex", deserialize_with = "hex_to_buffer")]
50  pub data: Vec<u8>,
51}
52
53#[derive(Clone, Debug, PartialEq, Eq, PartialOrd, Ord, Hash, Serialize, Deserialize)]
54#[serde(rename_all = "snake_case")]
55pub struct DefineBitmap {
56  pub id: u16,
57  pub width: u16,
58  pub height: u16,
59  pub media_type: ImageType,
60  #[serde(serialize_with = "buffer_to_hex", deserialize_with = "hex_to_buffer")]
61  pub data: Vec<u8>,
62}
63
64#[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize)]
65#[serde(rename_all = "snake_case")]
66pub struct DefineButton {
67  pub id: u16,
68  pub track_as_menu: bool,
69  pub characters: Vec<ButtonRecord>,
70  pub actions: Vec<ButtonCondAction>,
71}
72
73#[derive(Clone, Debug, PartialEq, Eq, PartialOrd, Ord, Hash, Serialize, Deserialize)]
74#[serde(rename_all = "snake_case")]
75pub struct DefineButtonColorTransform {
76  pub button_id: u16,
77  pub transform: ColorTransform,
78}
79
80#[derive(Clone, Debug, PartialEq, Eq, PartialOrd, Ord, Hash, Serialize, Deserialize)]
81#[serde(rename_all = "snake_case")]
82pub struct DefineButtonSound {
83  pub button_id: u16,
84  #[serde(skip_serializing_if = "Option::is_none")]
85  pub over_up_to_idle: Option<ButtonSound>,
86  #[serde(skip_serializing_if = "Option::is_none")]
87  pub idle_to_over_up: Option<ButtonSound>,
88  #[serde(skip_serializing_if = "Option::is_none")]
89  pub over_up_to_over_down: Option<ButtonSound>,
90  #[serde(skip_serializing_if = "Option::is_none")]
91  pub over_down_to_over_up: Option<ButtonSound>,
92}
93
94#[derive(Clone, Debug, PartialEq, Eq, PartialOrd, Ord, Hash, Serialize, Deserialize)]
95#[serde(rename_all = "snake_case")]
96pub struct DefineCffFont {
97  pub id: u16,
98  pub font_name: String,
99  pub is_bold: bool,
100  pub is_italic: bool,
101  #[serde(
102    skip_serializing_if = "Option::is_none",
103    serialize_with = "optional_buffer_to_hex",
104    deserialize_with = "hex_to_optional_buffer"
105  )]
106  pub data: Option<Vec<u8>>,
107}
108
109#[derive(Clone, Debug, PartialEq, Eq, PartialOrd, Ord, Hash, Serialize, Deserialize)]
110#[serde(rename_all = "snake_case")]
111pub struct DefineDynamicText {
112  pub id: u16,
113  pub bounds: Rect,
114  pub word_wrap: bool,
115  pub multiline: bool,
116  pub password: bool,
117  pub readonly: bool,
118  pub auto_size: bool,
119  pub no_select: bool,
120  pub border: bool,
121  pub was_static: bool,
122  pub html: bool,
123  pub use_glyph_font: bool,
124  #[serde(skip_serializing_if = "Option::is_none")]
125  pub font_id: Option<u16>,
126  #[serde(skip_serializing_if = "Option::is_none")]
127  pub font_class: Option<String>,
128  #[serde(skip_serializing_if = "Option::is_none")]
129  pub font_size: Option<u16>,
130  #[serde(skip_serializing_if = "Option::is_none")]
131  pub color: Option<StraightSRgba8>,
132  #[serde(skip_serializing_if = "Option::is_none")]
133  pub max_length: Option<usize>,
134  pub align: TextAlignment,
135  pub margin_left: u16,
136  pub margin_right: u16,
137  pub indent: u16,
138  pub leading: i16,
139  #[serde(skip_serializing_if = "Option::is_none")]
140  pub variable_name: Option<String>,
141  #[serde(skip_serializing_if = "Option::is_none")]
142  pub text: Option<String>,
143}
144
145#[derive(Clone, Debug, PartialEq, Eq, PartialOrd, Ord, Hash, Serialize, Deserialize)]
146#[serde(rename_all = "snake_case")]
147pub struct DefineFont {
148  pub id: u16,
149  pub font_name: String,
150  pub is_bold: bool,
151  pub is_italic: bool,
152  pub is_ansi: bool,
153  pub is_small: bool,
154  pub is_shift_jis: bool,
155  pub em_square_size: EmSquareSize,
156  pub language: LanguageCode,
157  #[serde(skip_serializing_if = "Option::is_none")]
158  pub glyphs: Option<Vec<Glyph>>,
159  #[serde(skip_serializing_if = "Option::is_none")]
160  pub code_units: Option<Vec<u16>>,
161  #[serde(skip_serializing_if = "Option::is_none")]
162  pub layout: Option<FontLayout>,
163}
164
165#[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize)]
166#[serde(rename_all = "snake_case")]
167pub struct DefineFontAlignZones {
168  pub font_id: u16,
169  pub csm_table_hint: CsmTableHint,
170  pub zones: Vec<FontAlignmentZone>,
171}
172
173#[derive(Clone, Debug, PartialEq, Eq, PartialOrd, Ord, Hash, Serialize, Deserialize)]
174#[serde(rename_all = "snake_case")]
175pub struct DefineFontInfo {
176  pub font_id: u16,
177  pub font_name: String,
178  pub is_bold: bool,
179  pub is_italic: bool,
180  pub is_ansi: bool,
181  pub is_shift_jis: bool,
182  pub is_small: bool,
183  pub language: LanguageCode,
184  pub code_units: Vec<u16>,
185}
186
187#[derive(Clone, Debug, PartialEq, Eq, PartialOrd, Ord, Hash, Serialize, Deserialize)]
188#[serde(rename_all = "snake_case")]
189pub struct DefineFontName {
190  pub font_id: u16,
191  pub name: String,
192  pub copyright: String,
193}
194
195#[derive(Clone, Debug, PartialEq, Eq, PartialOrd, Ord, Hash, Serialize, Deserialize)]
196#[serde(rename_all = "snake_case")]
197pub struct DefineGlyphFont {
198  pub id: u16,
199  pub glyphs: Vec<Glyph>,
200}
201
202#[derive(Clone, Debug, PartialEq, Eq, PartialOrd, Ord, Hash, Serialize, Deserialize)]
203#[serde(rename_all = "snake_case")]
204pub struct DefineJpegTables {
205  #[serde(serialize_with = "buffer_to_hex", deserialize_with = "hex_to_buffer")]
206  pub data: Vec<u8>,
207}
208
209#[derive(Clone, Debug, PartialEq, Eq, PartialOrd, Ord, Hash, Serialize, Deserialize)]
210#[serde(rename_all = "snake_case")]
211pub struct DefineMorphShape {
212  pub id: u16,
213  pub bounds: Rect,
214  pub morph_bounds: Rect,
215  // TODO: Combine edgeBounds and morphEdgeBounds in something like MorphRect
216  #[serde(skip_serializing_if = "Option::is_none")]
217  pub edge_bounds: Option<Rect>,
218  #[serde(skip_serializing_if = "Option::is_none")]
219  pub morph_edge_bounds: Option<Rect>,
220  pub has_scaling_strokes: bool,
221  pub has_non_scaling_strokes: bool,
222  pub shape: MorphShape,
223}
224
225#[derive(Copy, Clone, Debug, PartialEq, Eq, PartialOrd, Ord, Hash, Serialize, Deserialize)]
226#[serde(rename_all = "snake_case")]
227pub struct DefineScalingGrid {
228  pub character_id: u16,
229  pub splitter: Rect,
230}
231
232#[derive(Clone, Debug, PartialEq, Eq, PartialOrd, Ord, Hash, Serialize, Deserialize)]
233#[serde(rename_all = "snake_case")]
234pub struct DefineSceneAndFrameLabelData {
235  pub scenes: Vec<Scene>,
236  pub labels: Vec<Label>,
237}
238
239// TODO(demurgos): Move to a different file since it is not a tag
240#[derive(Clone, Debug, PartialEq, Eq, PartialOrd, Ord, Hash, Serialize, Deserialize)]
241#[serde(rename_all = "snake_case")]
242pub struct Scene {
243  pub offset: u32,
244  pub name: String,
245}
246
247// TODO(demurgos): Move to a different file since it is not a tag
248#[derive(Clone, Debug, PartialEq, Eq, PartialOrd, Ord, Hash, Serialize, Deserialize)]
249#[serde(rename_all = "snake_case")]
250pub struct Label {
251  pub frame: u32,
252  pub name: String,
253}
254
255#[derive(Clone, Debug, PartialEq, Eq, PartialOrd, Ord, Hash, Serialize, Deserialize)]
256#[serde(rename_all = "snake_case")]
257pub struct DefineShape {
258  pub id: u16,
259  pub bounds: Rect,
260  #[serde(skip_serializing_if = "Option::is_none")]
261  pub edge_bounds: Option<Rect>,
262  pub has_fill_winding: bool,
263  pub has_non_scaling_strokes: bool,
264  pub has_scaling_strokes: bool,
265  pub shape: Shape,
266}
267
268#[derive(Clone, Debug, PartialEq, Eq, PartialOrd, Ord, Hash, Serialize, Deserialize)]
269#[serde(rename_all = "snake_case")]
270pub struct DefineSound {
271  pub id: u16,
272  pub sound_type: SoundType,
273  pub sound_size: SoundSize,
274  pub sound_rate: SoundRate,
275  pub format: AudioCodingFormat,
276  pub sample_count: u32,
277  #[serde(serialize_with = "buffer_to_hex", deserialize_with = "hex_to_buffer")]
278  pub data: Vec<u8>,
279}
280
281#[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize)]
282#[serde(rename_all = "snake_case")]
283pub struct DefineSprite {
284  pub id: u16,
285  pub frame_count: usize,
286  pub tags: Vec<Tag>,
287}
288
289#[derive(Clone, Debug, PartialEq, Eq, PartialOrd, Ord, Hash, Serialize, Deserialize)]
290#[serde(rename_all = "snake_case")]
291pub struct DefineText {
292  pub id: u16,
293  pub bounds: Rect,
294  pub matrix: Matrix,
295  pub records: Vec<TextRecord>,
296}
297
298#[derive(Clone, Debug, PartialEq, Eq, PartialOrd, Ord, Hash, Serialize, Deserialize)]
299#[serde(rename_all = "snake_case")]
300pub struct DefineVideoStream {
301  pub id: u16,
302  pub frame_count: usize,
303  pub width: u16,
304  pub height: u16,
305  pub use_smoothing: bool,
306  pub deblocking: VideoDeblocking,
307  pub codec: VideoCodec,
308}
309
310#[derive(Clone, Debug, PartialEq, Eq, PartialOrd, Ord, Hash, Serialize, Deserialize)]
311#[serde(rename_all = "snake_case")]
312pub struct DoAbc {
313  pub flags: u32,
314  pub name: String,
315  #[serde(serialize_with = "buffer_to_hex", deserialize_with = "hex_to_buffer")]
316  pub data: Vec<u8>,
317}
318
319#[derive(Clone, Debug, PartialEq, Eq, PartialOrd, Ord, Hash, Serialize, Deserialize)]
320#[serde(rename_all = "snake_case")]
321pub struct DoAction {
322  #[serde(serialize_with = "buffer_to_hex", deserialize_with = "hex_to_buffer")]
323  pub actions: Vec<u8>,
324}
325
326#[derive(Clone, Debug, PartialEq, Eq, PartialOrd, Ord, Hash, Serialize, Deserialize)]
327#[serde(rename_all = "snake_case")]
328pub struct DoInitAction {
329  pub sprite_id: u16,
330  #[serde(serialize_with = "buffer_to_hex", deserialize_with = "hex_to_buffer")]
331  pub actions: Vec<u8>,
332}
333
334#[derive(Clone, Debug, PartialEq, Eq, PartialOrd, Ord, Hash, Serialize, Deserialize)]
335#[serde(rename_all = "snake_case")]
336pub struct EnableDebugger {
337  pub password: String,
338}
339
340#[derive(Clone, Debug, PartialEq, Eq, PartialOrd, Ord, Hash, Serialize, Deserialize)]
341#[serde(rename_all = "snake_case")]
342pub struct ExportAssets {
343  pub assets: Vec<NamedId>,
344}
345
346#[derive(Copy, Clone, Debug, PartialEq, Eq, PartialOrd, Ord, Hash, Serialize, Deserialize)]
347#[serde(rename_all = "snake_case")]
348pub struct FileAttributes {
349  pub use_network: bool,
350  pub use_relative_urls: bool,
351  pub no_cross_domain_caching: bool,
352  pub use_as3: bool,
353  pub has_metadata: bool,
354  pub use_gpu: bool,
355  pub use_direct_blit: bool,
356}
357
358#[derive(Clone, Debug, PartialEq, Eq, PartialOrd, Ord, Hash, Serialize, Deserialize)]
359#[serde(rename_all = "snake_case")]
360pub struct FrameLabel {
361  pub name: String,
362  pub is_anchor: bool,
363}
364
365#[derive(Clone, Debug, PartialEq, Eq, PartialOrd, Ord, Hash, Serialize, Deserialize)]
366#[serde(rename_all = "snake_case")]
367pub struct ImportAssets {
368  pub url: String,
369  pub assets: Vec<NamedId>,
370}
371
372#[derive(Clone, Debug, PartialEq, Eq, PartialOrd, Ord, Hash, Serialize, Deserialize)]
373#[serde(rename_all = "snake_case")]
374pub struct Metadata {
375  pub metadata: String,
376}
377
378#[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize)]
379#[serde(rename_all = "snake_case")]
380pub struct PlaceObject {
381  /// Corresponds to `is_move` in the SWF spec.
382  pub is_update: bool,
383  pub depth: u16,
384  #[serde(skip_serializing_if = "Option::is_none")]
385  pub character_id: Option<u16>,
386  #[serde(skip_serializing_if = "Option::is_none")]
387  pub class_name: Option<String>,
388  #[serde(skip_serializing_if = "Option::is_none")]
389  pub matrix: Option<Matrix>,
390  #[serde(skip_serializing_if = "Option::is_none")]
391  pub color_transform: Option<ColorTransformWithAlpha>,
392  #[serde(skip_serializing_if = "Option::is_none")]
393  pub ratio: Option<u16>,
394  #[serde(skip_serializing_if = "Option::is_none")]
395  pub name: Option<String>,
396  #[serde(skip_serializing_if = "Option::is_none")]
397  pub clip_depth: Option<u16>,
398  #[serde(skip_serializing_if = "Option::is_none")]
399  pub filters: Option<Vec<Filter>>,
400  #[serde(skip_serializing_if = "Option::is_none")]
401  pub blend_mode: Option<BlendMode>,
402  #[serde(skip_serializing_if = "Option::is_none")]
403  pub bitmap_cache: Option<bool>,
404  #[serde(skip_serializing_if = "Option::is_none")]
405  pub visible: Option<bool>,
406  #[serde(skip_serializing_if = "Option::is_none")]
407  pub background_color: Option<StraightSRgba8>,
408  #[serde(skip_serializing_if = "Option::is_none")]
409  pub clip_actions: Option<Vec<ClipAction>>,
410}
411
412#[derive(Clone, Debug, PartialEq, Eq, PartialOrd, Ord, Hash, Serialize, Deserialize)]
413#[serde(rename_all = "snake_case")]
414pub struct Protect {
415  pub password: String,
416}
417
418#[derive(Copy, Clone, Debug, PartialEq, Eq, PartialOrd, Ord, Hash, Serialize, Deserialize)]
419#[serde(rename_all = "snake_case")]
420pub struct RemoveObject {
421  #[serde(skip_serializing_if = "Option::is_none")]
422  pub character_id: Option<u16>,
423  pub depth: u16,
424}
425
426#[derive(Copy, Clone, Debug, PartialEq, Eq, PartialOrd, Ord, Hash, Serialize, Deserialize)]
427#[serde(rename_all = "snake_case")]
428pub struct ScriptLimits {
429  pub max_recursion_depth: u16,
430  pub script_timeout: u16,
431}
432
433#[derive(Copy, Clone, Debug, PartialEq, Eq, PartialOrd, Ord, Hash, Serialize, Deserialize)]
434#[serde(rename_all = "snake_case")]
435pub struct SetBackgroundColor {
436  /// Color of the display background
437  pub color: SRgb8,
438}
439
440#[derive(Copy, Clone, Debug, PartialEq, Eq, PartialOrd, Ord, Hash, Serialize, Deserialize)]
441#[serde(rename_all = "snake_case")]
442pub struct SetTabIndex {
443  pub depth: u16,
444  pub index: u16,
445}
446
447#[derive(Clone, Debug, PartialEq, Eq, PartialOrd, Ord, Hash, Serialize, Deserialize)]
448#[serde(rename_all = "snake_case")]
449pub struct SoundStreamBlock {
450  #[serde(serialize_with = "buffer_to_hex", deserialize_with = "hex_to_buffer")]
451  pub data: Vec<u8>,
452}
453
454#[derive(Copy, Clone, Debug, PartialEq, Eq, PartialOrd, Ord, Hash, Serialize, Deserialize)]
455#[serde(rename_all = "snake_case")]
456pub struct SoundStreamHead {
457  pub playback_sound_type: SoundType,
458  pub playback_sound_size: SoundSize,
459  pub playback_sound_rate: SoundRate,
460  pub stream_sound_type: SoundType,
461  pub stream_sound_size: SoundSize,
462  pub stream_sound_rate: SoundRate,
463  pub stream_format: AudioCodingFormat,
464  pub stream_sample_count: u16,
465  #[serde(skip_serializing_if = "Option::is_none")]
466  pub latency_seek: Option<i16>,
467}
468
469#[derive(Clone, Debug, PartialEq, Eq, PartialOrd, Ord, Hash, Serialize, Deserialize)]
470#[serde(rename_all = "snake_case")]
471pub struct StartSound {
472  pub sound_id: u16,
473  pub sound_info: SoundInfo,
474}
475
476#[derive(Clone, Debug, PartialEq, Eq, PartialOrd, Ord, Hash, Serialize, Deserialize)]
477#[serde(rename_all = "snake_case")]
478pub struct StartSound2 {
479  pub sound_class_name: String,
480  pub sound_info: SoundInfo,
481}
482
483#[derive(Clone, Debug, PartialEq, Eq, PartialOrd, Ord, Hash, Serialize, Deserialize)]
484#[serde(rename_all = "snake_case")]
485pub struct SymbolClass {
486  pub symbols: Vec<NamedId>,
487}
488
489#[derive(Clone, Debug, PartialEq, Eq, PartialOrd, Ord, Hash, Serialize, Deserialize)]
490#[serde(rename_all = "snake_case")]
491pub struct Telemetry {
492  #[serde(
493    skip_serializing_if = "Option::is_none",
494    serialize_with = "optional_buffer_to_hex",
495    deserialize_with = "hex_to_optional_buffer"
496  )]
497  pub password: Option<Vec<u8>>,
498}
499
500#[derive(Clone, Debug, PartialEq, Eq, PartialOrd, Ord, Hash, Serialize, Deserialize)]
501#[serde(rename_all = "snake_case")]
502pub struct Unknown {
503  pub code: u16,
504  #[serde(serialize_with = "buffer_to_hex", deserialize_with = "hex_to_buffer")]
505  pub data: Vec<u8>,
506}
507
508#[derive(Clone, Debug, PartialEq, Eq, PartialOrd, Ord, Hash, Serialize, Deserialize)]
509#[serde(rename_all = "snake_case")]
510pub struct VideoFrame {
511  pub video_id: u16,
512  pub frame: u16,
513  #[serde(serialize_with = "buffer_to_hex", deserialize_with = "hex_to_buffer")]
514  pub packet: Vec<u8>,
515}