2019-06-17 04:23:31 +00:00
|
|
|
//! The data structures used in an Adobe SWF file.
|
|
|
|
//!
|
2020-09-19 14:27:24 +00:00
|
|
|
//! These structures are documented in the Adobe SWF File Format Specification
|
2019-06-17 04:23:31 +00:00
|
|
|
//! version 19 (henceforth SWF19):
|
|
|
|
//! https://www.adobe.com/content/dam/acom/en/devnet/pdf/swf-file-format-spec.pdf
|
2021-01-18 21:17:17 +00:00
|
|
|
use crate::string::SwfStr;
|
2021-01-22 00:35:46 +00:00
|
|
|
use bitflags::bitflags;
|
2016-09-09 04:19:51 +00:00
|
|
|
|
2021-04-18 03:52:19 +00:00
|
|
|
mod fixed;
|
2020-05-19 16:50:37 +00:00
|
|
|
mod matrix;
|
|
|
|
|
2021-04-18 03:52:19 +00:00
|
|
|
pub use fixed::*;
|
2020-05-19 16:50:37 +00:00
|
|
|
pub use matrix::Matrix;
|
|
|
|
|
2019-06-17 04:23:31 +00:00
|
|
|
/// A complete header and tags in the SWF file.
|
|
|
|
/// This is returned by the `swf::read_swf` convenience method.
|
2021-05-23 00:19:45 +00:00
|
|
|
#[derive(Debug)]
|
2021-01-18 06:46:18 +00:00
|
|
|
pub struct Swf<'a> {
|
2021-05-23 00:19:45 +00:00
|
|
|
pub header: HeaderExt,
|
2021-01-18 06:46:18 +00:00
|
|
|
pub tags: Vec<Tag<'a>>,
|
2019-06-17 04:23:31 +00:00
|
|
|
}
|
|
|
|
|
2021-01-19 00:46:20 +00:00
|
|
|
/// Returned by `read::decompress_swf`.
|
|
|
|
/// Owns the decompressed SWF data, which will be referenced when parsed by `parse_swf`.
|
|
|
|
pub struct SwfBuf {
|
2021-01-20 04:00:58 +00:00
|
|
|
/// The parsed SWF header.
|
2021-05-23 00:19:45 +00:00
|
|
|
pub header: HeaderExt,
|
2021-01-20 04:00:58 +00:00
|
|
|
|
|
|
|
/// The decompressed SWF tag stream.
|
2021-01-18 06:46:18 +00:00
|
|
|
pub data: Vec<u8>,
|
2019-10-10 20:07:07 +00:00
|
|
|
}
|
|
|
|
|
2019-06-17 04:23:31 +00:00
|
|
|
/// The header of an SWF file.
|
|
|
|
///
|
|
|
|
/// Notably contains the compression format used by the rest of the SWF data.
|
|
|
|
///
|
|
|
|
/// [SWF19 p.27](https://www.adobe.com/content/dam/acom/en/devnet/pdf/swf-file-format-spec.pdf#page=27)
|
2019-11-12 20:05:18 +00:00
|
|
|
#[derive(Debug, PartialEq, Clone)]
|
2019-06-17 04:23:31 +00:00
|
|
|
pub struct Header {
|
2020-10-23 14:06:16 +00:00
|
|
|
pub compression: Compression,
|
2021-01-05 05:52:11 +00:00
|
|
|
pub version: u8,
|
2016-08-29 07:51:32 +00:00
|
|
|
pub stage_size: Rectangle,
|
2021-05-30 20:30:06 +00:00
|
|
|
pub frame_rate: Fixed8,
|
2016-08-29 07:51:32 +00:00
|
|
|
pub num_frames: u16,
|
|
|
|
}
|
|
|
|
|
2021-05-23 00:19:45 +00:00
|
|
|
impl Header {
|
|
|
|
pub fn default_with_swf_version(version: u8) -> Self {
|
|
|
|
Self {
|
|
|
|
compression: Compression::None,
|
|
|
|
version,
|
|
|
|
stage_size: Default::default(),
|
2021-05-30 20:30:06 +00:00
|
|
|
frame_rate: Fixed8::ONE,
|
2021-05-23 00:19:45 +00:00
|
|
|
num_frames: 0,
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/// The extended metadata of an SWF file.
|
|
|
|
///
|
|
|
|
/// This includes the SWF header data as well as metdata from the FileAttributes and
|
|
|
|
/// SetBackgroundColor tags.
|
|
|
|
///
|
|
|
|
/// This metadata may not reflect the actual data inside a malformed SWF; for example,
|
|
|
|
/// the root timeline my actually contain fewer frames than `HeaderExt::num_frames` if it is
|
|
|
|
/// corrupted.
|
|
|
|
#[derive(Clone, Debug)]
|
|
|
|
pub struct HeaderExt {
|
|
|
|
pub(crate) header: Header,
|
|
|
|
pub(crate) file_attributes: FileAttributes,
|
|
|
|
pub(crate) background_color: Option<SetBackgroundColor>,
|
|
|
|
pub(crate) uncompressed_len: u32,
|
|
|
|
}
|
|
|
|
|
|
|
|
impl HeaderExt {
|
|
|
|
#[inline]
|
|
|
|
/// Returns the header for a dummy SWF file with the given SWF version.
|
|
|
|
pub fn default_with_swf_version(version: u8) -> Self {
|
|
|
|
Self {
|
|
|
|
header: Header::default_with_swf_version(version),
|
|
|
|
file_attributes: Default::default(),
|
|
|
|
background_color: None,
|
|
|
|
uncompressed_len: 0,
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/// The background color of the SWF from the SetBackgroundColor tag.
|
|
|
|
///
|
|
|
|
/// `None` will be returned if the SetBackgroundColor tag was not found.
|
|
|
|
#[inline]
|
|
|
|
pub fn background_color(&self) -> Option<Color> {
|
|
|
|
self.background_color.clone()
|
|
|
|
}
|
|
|
|
|
|
|
|
/// The compression format used by the SWF.
|
|
|
|
#[inline]
|
|
|
|
pub fn compression(&self) -> Compression {
|
|
|
|
self.header.compression
|
|
|
|
}
|
|
|
|
|
|
|
|
/// The frame rate of the SWF, in frames per second.
|
|
|
|
#[inline]
|
2021-05-30 20:30:06 +00:00
|
|
|
pub fn frame_rate(&self) -> Fixed8 {
|
2021-05-23 00:19:45 +00:00
|
|
|
self.header.frame_rate
|
|
|
|
}
|
|
|
|
|
|
|
|
/// Whether this SWF contains XMP metadata in a Metadata tag.
|
|
|
|
#[inline]
|
|
|
|
pub fn has_metdata(&self) -> bool {
|
|
|
|
self.file_attributes.contains(FileAttributes::HAS_METADATA)
|
|
|
|
}
|
|
|
|
|
|
|
|
/// Returns the basic SWF header.
|
|
|
|
#[inline]
|
|
|
|
pub fn swf_header(&self) -> &Header {
|
|
|
|
&self.header
|
|
|
|
}
|
|
|
|
|
|
|
|
/// Whether this SWF uses ActionScript 3.0 (AVM2).
|
|
|
|
#[inline]
|
|
|
|
pub fn is_action_script_3(&self) -> bool {
|
|
|
|
self.file_attributes
|
|
|
|
.contains(FileAttributes::IS_ACTION_SCRIPT_3)
|
|
|
|
}
|
|
|
|
|
|
|
|
/// The number of frames on the root timeline.
|
|
|
|
#[inline]
|
|
|
|
pub fn num_frames(&self) -> u16 {
|
|
|
|
self.header.num_frames
|
|
|
|
}
|
|
|
|
|
|
|
|
/// The stage dimensions of this SWF.
|
|
|
|
#[inline]
|
|
|
|
pub fn stage_size(&self) -> &Rectangle {
|
|
|
|
&self.header.stage_size
|
|
|
|
}
|
|
|
|
|
|
|
|
/// The SWF version.
|
|
|
|
#[inline]
|
|
|
|
pub fn version(&self) -> u8 {
|
|
|
|
self.header.version
|
|
|
|
}
|
|
|
|
|
|
|
|
/// The length of the SWF after decompression.
|
|
|
|
#[inline]
|
|
|
|
pub fn uncompressed_len(&self) -> u32 {
|
|
|
|
self.uncompressed_len
|
|
|
|
}
|
|
|
|
|
|
|
|
/// Whether this SWF requests hardware acceleration to blit to the screen.
|
|
|
|
#[inline]
|
|
|
|
pub fn use_direct_blit(&self) -> bool {
|
|
|
|
self.file_attributes
|
|
|
|
.contains(FileAttributes::USE_DIRECT_BLIT)
|
|
|
|
}
|
|
|
|
|
|
|
|
/// Whether this SWF requests hardware acceleration for compositing.
|
|
|
|
#[inline]
|
|
|
|
pub fn use_gpu(&self) -> bool {
|
|
|
|
self.file_attributes.contains(FileAttributes::USE_GPU)
|
|
|
|
}
|
|
|
|
|
|
|
|
/// Whether this SWF should be placed in the network sandbox when run locally.
|
|
|
|
///
|
|
|
|
/// SWFs in the network sandbox can only access network resources, not local resources.
|
|
|
|
/// SWFs in the local sandbox can only access local resources, not network resources.
|
|
|
|
#[inline]
|
|
|
|
pub fn use_network_sandbox(&self) -> bool {
|
|
|
|
self.file_attributes
|
|
|
|
.contains(FileAttributes::USE_NETWORK_SANDBOX)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2020-09-19 14:27:24 +00:00
|
|
|
/// The compression format used internally by the SWF file.
|
2019-06-17 04:23:31 +00:00
|
|
|
///
|
|
|
|
/// The vast majority of SWFs will use zlib compression.
|
|
|
|
/// [SWF19 p.27](https://www.adobe.com/content/dam/acom/en/devnet/pdf/swf-file-format-spec.pdf#page=27)
|
2021-05-23 00:19:45 +00:00
|
|
|
#[derive(Debug, PartialEq, Eq, Clone, Copy)]
|
2016-08-29 07:51:32 +00:00
|
|
|
pub enum Compression {
|
|
|
|
None,
|
|
|
|
Zlib,
|
|
|
|
Lzma,
|
|
|
|
}
|
|
|
|
|
2021-02-06 21:43:42 +00:00
|
|
|
/// A type-safe wrapper type documenting where "twips" are used
|
2019-06-17 04:23:31 +00:00
|
|
|
/// in the SWF format.
|
|
|
|
///
|
2021-02-06 21:43:42 +00:00
|
|
|
/// A twip is 1/20th of a pixel.
|
|
|
|
/// Most coordinates in an SWF file are represented in twips.
|
|
|
|
///
|
|
|
|
/// Use the [`from_pixels`] and [`to_pixels`] methods to convert to and from
|
2019-06-17 04:23:31 +00:00
|
|
|
/// pixel values.
|
2021-02-06 21:43:42 +00:00
|
|
|
///
|
|
|
|
/// [`from_pixels`]: Twips::from_pixels
|
|
|
|
/// [`to_pixels`]: Twips::to_pixels
|
2019-05-17 04:32:18 +00:00
|
|
|
#[derive(Debug, PartialEq, Eq, Clone, Copy, Default, PartialOrd, Ord)]
|
|
|
|
pub struct Twips(i32);
|
|
|
|
|
|
|
|
impl Twips {
|
2019-06-17 04:23:31 +00:00
|
|
|
/// There are 20 twips in a pixel.
|
2019-05-17 04:32:18 +00:00
|
|
|
pub const TWIPS_PER_PIXEL: f64 = 20.0;
|
|
|
|
|
2019-06-17 04:23:31 +00:00
|
|
|
/// Creates a new `Twips` object. Note that the `twips` value is in twips,
|
2021-02-06 21:43:42 +00:00
|
|
|
/// not pixels. Use the [`from_pixels`] method to convert from pixel units.
|
|
|
|
///
|
|
|
|
/// [`from_pixels`]: Twips::from_pixels
|
|
|
|
///
|
|
|
|
/// # Examples
|
|
|
|
///
|
|
|
|
/// ```rust
|
|
|
|
/// use swf::Twips;
|
|
|
|
///
|
|
|
|
/// let twips = Twips::new(40);
|
|
|
|
/// ```
|
2019-05-17 04:32:18 +00:00
|
|
|
pub fn new<T: Into<i32>>(twips: T) -> Self {
|
|
|
|
Self(twips.into())
|
|
|
|
}
|
|
|
|
|
2021-02-06 21:43:42 +00:00
|
|
|
/// Creates a new `Twips` object with a value of `0`.
|
|
|
|
///
|
|
|
|
/// # Examples
|
|
|
|
///
|
|
|
|
/// ```rust
|
|
|
|
/// use swf::Twips;
|
|
|
|
///
|
|
|
|
/// let twips = Twips::zero();
|
|
|
|
/// assert_eq!(twips.get(), 0);
|
|
|
|
/// ```
|
2021-02-11 02:36:23 +00:00
|
|
|
pub const fn zero() -> Self {
|
2020-05-21 14:45:22 +00:00
|
|
|
Self(0)
|
|
|
|
}
|
|
|
|
|
2019-06-17 04:23:31 +00:00
|
|
|
/// Returns the number of twips.
|
2021-02-06 21:43:42 +00:00
|
|
|
///
|
|
|
|
/// # Examples
|
|
|
|
///
|
|
|
|
/// ```rust
|
|
|
|
/// use swf::Twips;
|
|
|
|
///
|
|
|
|
/// let twips = Twips::new(47);
|
|
|
|
/// assert_eq!(twips.get(), 47);
|
|
|
|
/// ```
|
2021-02-11 02:36:23 +00:00
|
|
|
pub const fn get(self) -> i32 {
|
2019-05-17 04:32:18 +00:00
|
|
|
self.0
|
|
|
|
}
|
|
|
|
|
2021-02-06 21:43:42 +00:00
|
|
|
/// Converts the given number of `pixels` into twips.
|
|
|
|
///
|
|
|
|
/// This may be a lossy conversion; any precision more than a twip (1/20 pixels) is truncated.
|
|
|
|
///
|
|
|
|
/// # Examples
|
2019-06-17 04:23:31 +00:00
|
|
|
///
|
2021-02-06 21:43:42 +00:00
|
|
|
/// ```rust
|
|
|
|
/// use swf::Twips;
|
|
|
|
///
|
|
|
|
/// // 40 pixels is equivalent to 800 twips.
|
|
|
|
/// let twips = Twips::from_pixels(40.0);
|
|
|
|
/// assert_eq!(twips.get(), 800);
|
|
|
|
///
|
|
|
|
/// // Output is truncated if more precise than a twip (1/20 pixels).
|
|
|
|
/// let twips = Twips::from_pixels(40.018);
|
|
|
|
/// assert_eq!(twips.get(), 800);
|
|
|
|
/// ```
|
2019-05-17 04:32:18 +00:00
|
|
|
pub fn from_pixels(pixels: f64) -> Self {
|
|
|
|
Self((pixels * Self::TWIPS_PER_PIXEL) as i32)
|
|
|
|
}
|
|
|
|
|
2019-06-17 04:23:31 +00:00
|
|
|
/// Converts this twips value into pixel units.
|
|
|
|
///
|
|
|
|
/// This is a lossless operation.
|
2021-02-06 21:43:42 +00:00
|
|
|
///
|
|
|
|
/// # Examples
|
|
|
|
///
|
|
|
|
/// ```rust
|
|
|
|
/// use swf::Twips;
|
|
|
|
///
|
|
|
|
/// // 800 twips is equivalent to 40 pixels.
|
|
|
|
/// let twips = Twips::new(800);
|
|
|
|
/// assert_eq!(twips.to_pixels(), 40.0);
|
|
|
|
///
|
|
|
|
/// // Twips are sub-pixel: 713 twips represent 35.65 pixels.
|
|
|
|
/// let twips = Twips::new(713);
|
|
|
|
/// assert_eq!(twips.to_pixels(), 35.65);
|
|
|
|
/// ```
|
2019-05-17 04:32:18 +00:00
|
|
|
pub fn to_pixels(self) -> f64 {
|
|
|
|
f64::from(self.0) / Self::TWIPS_PER_PIXEL
|
|
|
|
}
|
2020-11-27 06:19:55 +00:00
|
|
|
|
2021-02-06 21:43:42 +00:00
|
|
|
/// Saturating integer subtraction. Computes `self - rhs`, saturating at the numeric bounds
|
|
|
|
/// of [`i32`] instead of overflowing.
|
|
|
|
///
|
|
|
|
/// # Examples
|
|
|
|
///
|
|
|
|
/// ```rust
|
|
|
|
/// use swf::Twips;
|
|
|
|
///
|
|
|
|
/// assert_eq!(Twips::new(40).saturating_sub(Twips::new(20)), Twips::new(20));
|
|
|
|
/// assert_eq!(Twips::new(i32::MIN).saturating_sub(Twips::new(5)), Twips::new(i32::MIN));
|
|
|
|
/// assert_eq!(Twips::new(i32::MAX).saturating_sub(Twips::new(-100)), Twips::new(i32::MAX));
|
|
|
|
/// ```
|
2021-02-11 02:36:23 +00:00
|
|
|
pub const fn saturating_sub(self, rhs: Self) -> Self {
|
2020-11-27 06:19:55 +00:00
|
|
|
Self(self.0.saturating_sub(rhs.0))
|
|
|
|
}
|
2019-05-17 04:32:18 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
impl std::ops::Add for Twips {
|
|
|
|
type Output = Self;
|
|
|
|
fn add(self, other: Self) -> Self {
|
|
|
|
Self(self.0 + other.0)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
impl std::ops::AddAssign for Twips {
|
|
|
|
fn add_assign(&mut self, other: Self) {
|
|
|
|
self.0 += other.0
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
impl std::ops::Sub for Twips {
|
|
|
|
type Output = Self;
|
|
|
|
fn sub(self, other: Self) -> Self {
|
|
|
|
Self(self.0 - other.0)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
impl std::ops::SubAssign for Twips {
|
|
|
|
fn sub_assign(&mut self, other: Self) {
|
|
|
|
self.0 -= other.0
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
impl std::ops::Mul<i32> for Twips {
|
|
|
|
type Output = Self;
|
|
|
|
fn mul(self, other: i32) -> Self {
|
|
|
|
Self(self.0 * other)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
impl std::ops::MulAssign<i32> for Twips {
|
|
|
|
fn mul_assign(&mut self, other: i32) {
|
|
|
|
self.0 *= other
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
impl std::ops::Div<i32> for Twips {
|
|
|
|
type Output = Self;
|
|
|
|
fn div(self, other: i32) -> Self {
|
|
|
|
Self(self.0 / other)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
impl std::ops::DivAssign<i32> for Twips {
|
|
|
|
fn div_assign(&mut self, other: i32) {
|
|
|
|
self.0 /= other
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
impl std::fmt::Display for Twips {
|
|
|
|
fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
|
|
|
|
write!(f, "{}", self.to_pixels())
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2021-02-06 22:24:48 +00:00
|
|
|
/// A rectangular region defined by minimum
|
|
|
|
/// and maximum x- and y-coordinate positions
|
|
|
|
/// measured in [`Twips`].
|
2019-05-17 04:32:18 +00:00
|
|
|
#[derive(Debug, PartialEq, Clone, Default)]
|
2016-08-29 07:51:32 +00:00
|
|
|
pub struct Rectangle {
|
2021-02-06 22:24:48 +00:00
|
|
|
/// The minimum x-position of the rectangle.
|
2019-05-17 04:32:18 +00:00
|
|
|
pub x_min: Twips,
|
2021-02-06 22:24:48 +00:00
|
|
|
|
|
|
|
/// The maximum x-position of the rectangle.
|
2019-05-17 04:32:18 +00:00
|
|
|
pub x_max: Twips,
|
2021-02-06 22:24:48 +00:00
|
|
|
|
|
|
|
/// The minimum y-position of the rectangle.
|
2019-05-17 04:32:18 +00:00
|
|
|
pub y_min: Twips,
|
2021-02-06 22:24:48 +00:00
|
|
|
|
|
|
|
/// The maximum y-position of the rectangle.
|
2019-05-17 04:32:18 +00:00
|
|
|
pub y_max: Twips,
|
2016-08-29 07:51:32 +00:00
|
|
|
}
|
|
|
|
|
2021-02-06 22:09:48 +00:00
|
|
|
/// An RGBA (red, green, blue, alpha) color.
|
|
|
|
///
|
|
|
|
/// All components are stored as [`u8`] and have a color range of 0-255.
|
2021-03-20 17:15:16 +00:00
|
|
|
#[derive(Debug, PartialEq, Clone)]
|
2016-08-29 07:51:32 +00:00
|
|
|
pub struct Color {
|
2021-02-06 22:09:48 +00:00
|
|
|
/// The red component value.
|
2016-08-29 07:51:32 +00:00
|
|
|
pub r: u8,
|
2021-02-06 22:09:48 +00:00
|
|
|
|
|
|
|
/// The green component value.
|
2016-08-29 07:51:32 +00:00
|
|
|
pub g: u8,
|
2021-02-06 22:09:48 +00:00
|
|
|
|
|
|
|
/// The blue component value.
|
2016-08-29 07:51:32 +00:00
|
|
|
pub b: u8,
|
2021-02-06 22:09:48 +00:00
|
|
|
|
|
|
|
/// The alpha component value.
|
2016-08-29 07:51:32 +00:00
|
|
|
pub a: u8,
|
|
|
|
}
|
|
|
|
|
2020-04-17 08:56:11 +00:00
|
|
|
impl Color {
|
2021-02-06 22:09:48 +00:00
|
|
|
/// Creates a `Color` from a 32-bit `rgb` value and an `alpha` value.
|
|
|
|
///
|
|
|
|
/// The byte-ordering of the 32-bit `rgb` value is XXRRGGBB.
|
|
|
|
/// The most significant byte, represented by XX, is ignored;
|
|
|
|
/// the `alpha` value is provided separately.
|
|
|
|
/// This is followed by the the red (RR), green (GG), and blue (BB) components values,
|
|
|
|
/// respectively.
|
|
|
|
///
|
|
|
|
/// # Examples
|
|
|
|
///
|
|
|
|
/// ```rust
|
|
|
|
/// use swf::Color;
|
|
|
|
///
|
|
|
|
/// let red = Color::from_rgb(0xFF0000, 255);
|
|
|
|
/// let green = Color::from_rgb(0x00FF00, 255);
|
|
|
|
/// let blue = Color::from_rgb(0x0000FF, 255);
|
|
|
|
/// ```
|
2021-02-11 02:36:23 +00:00
|
|
|
pub const fn from_rgb(rgb: u32, alpha: u8) -> Self {
|
2020-04-17 08:56:11 +00:00
|
|
|
Self {
|
|
|
|
r: ((rgb & 0xFF_0000) >> 16) as u8,
|
|
|
|
g: ((rgb & 0x00_FF00) >> 8) as u8,
|
|
|
|
b: (rgb & 0x00_00FF) as u8,
|
|
|
|
a: alpha,
|
|
|
|
}
|
|
|
|
}
|
2021-02-06 22:09:48 +00:00
|
|
|
|
|
|
|
/// Converts the color to a 32-bit RGB value.
|
|
|
|
///
|
|
|
|
/// The alpha value does not get stored.
|
|
|
|
///
|
|
|
|
/// # Examples
|
|
|
|
///
|
|
|
|
/// Basic usage:
|
|
|
|
/// ```rust
|
|
|
|
/// use swf::Color;
|
|
|
|
///
|
|
|
|
/// let color = Color::from_rgb(0xFF00FF, 255);
|
|
|
|
/// assert_eq!(color.to_rgb(), 0xFF00FF);
|
|
|
|
/// ```
|
|
|
|
///
|
|
|
|
/// Alpha values do not get stored:
|
|
|
|
/// ```rust
|
|
|
|
/// use swf::Color;
|
|
|
|
///
|
|
|
|
/// let color1 = Color::from_rgb(0xFF00FF, 255);
|
|
|
|
/// let color2 = Color::from_rgb(0xFF00FF, 0);
|
|
|
|
/// assert_eq!(color1.to_rgb(), color2.to_rgb());
|
|
|
|
/// ```
|
2021-02-11 02:36:23 +00:00
|
|
|
pub const fn to_rgb(&self) -> u32 {
|
2020-12-07 19:15:58 +00:00
|
|
|
((self.r as u32) << 16) | ((self.g as u32) << 8) | (self.b as u32)
|
|
|
|
}
|
2020-04-17 08:56:11 +00:00
|
|
|
}
|
|
|
|
|
2017-06-24 19:56:49 +00:00
|
|
|
#[derive(Debug, PartialEq, Clone)]
|
2016-08-29 07:51:32 +00:00
|
|
|
pub struct ColorTransform {
|
2021-04-18 06:32:53 +00:00
|
|
|
pub r_multiply: Fixed8,
|
|
|
|
pub g_multiply: Fixed8,
|
|
|
|
pub b_multiply: Fixed8,
|
|
|
|
pub a_multiply: Fixed8,
|
2016-08-29 07:51:32 +00:00
|
|
|
pub r_add: i16,
|
|
|
|
pub g_add: i16,
|
|
|
|
pub b_add: i16,
|
|
|
|
pub a_add: i16,
|
|
|
|
}
|
|
|
|
|
2016-09-14 01:55:13 +00:00
|
|
|
impl ColorTransform {
|
2021-02-11 02:36:23 +00:00
|
|
|
pub const fn new() -> ColorTransform {
|
2016-09-14 01:55:13 +00:00
|
|
|
ColorTransform {
|
2021-04-18 06:32:53 +00:00
|
|
|
r_multiply: Fixed8::ONE,
|
|
|
|
g_multiply: Fixed8::ONE,
|
|
|
|
b_multiply: Fixed8::ONE,
|
|
|
|
a_multiply: Fixed8::ONE,
|
2016-09-14 01:55:13 +00:00
|
|
|
r_add: 0,
|
|
|
|
g_add: 0,
|
|
|
|
b_add: 0,
|
|
|
|
a_add: 0,
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2017-06-24 22:03:40 +00:00
|
|
|
impl Default for ColorTransform {
|
|
|
|
fn default() -> Self {
|
|
|
|
Self::new()
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2021-06-05 20:13:01 +00:00
|
|
|
#[derive(Clone, Copy, Debug, Eq, PartialEq, FromPrimitive, ToPrimitive)]
|
2017-02-17 04:15:35 +00:00
|
|
|
pub enum Language {
|
2021-06-05 20:13:01 +00:00
|
|
|
Unknown = 0,
|
|
|
|
Latin = 1,
|
|
|
|
Japanese = 2,
|
|
|
|
Korean = 3,
|
|
|
|
SimplifiedChinese = 4,
|
|
|
|
TraditionalChinese = 5,
|
|
|
|
}
|
|
|
|
|
|
|
|
impl Language {
|
|
|
|
pub fn from_u8(n: u8) -> Option<Self> {
|
|
|
|
num_traits::FromPrimitive::from_u8(n)
|
|
|
|
}
|
|
|
|
|
|
|
|
pub fn to_u8(self) -> u8 {
|
|
|
|
num_traits::ToPrimitive::to_u8(&self).unwrap()
|
|
|
|
}
|
2017-02-17 04:15:35 +00:00
|
|
|
}
|
|
|
|
|
2021-05-22 21:41:49 +00:00
|
|
|
bitflags! {
|
|
|
|
/// Flags that define various characteristic of an SWF file.
|
|
|
|
///
|
|
|
|
/// [SWF19 pp.57-58 ClipEvent](https://www.adobe.com/content/dam/acom/en/devnet/pdf/swf-file-format-spec.pdf#page=47)
|
|
|
|
pub struct FileAttributes: u8 {
|
|
|
|
/// Whether this SWF requests hardware acceleration to blit to the screen.
|
|
|
|
const USE_DIRECT_BLIT = 1 << 6;
|
|
|
|
|
|
|
|
/// Whether this SWF requests hardware acceleration for compositing.
|
|
|
|
const USE_GPU = 1 << 5;
|
|
|
|
|
|
|
|
/// Whether this SWF contains XMP metadata in a Metadata tag.
|
|
|
|
const HAS_METADATA = 1 << 4;
|
|
|
|
|
|
|
|
/// Whether this SWF uses ActionScript 3 (AVM2).
|
|
|
|
const IS_ACTION_SCRIPT_3 = 1 << 3;
|
|
|
|
|
|
|
|
/// Whether this SWF should be placed in the network sandbox when run locally.
|
|
|
|
///
|
|
|
|
/// SWFs in the network sandbox can only access network resources, not local resources.
|
|
|
|
/// SWFs in the local sandbox can only access local resources, not network resources.
|
|
|
|
const USE_NETWORK_SANDBOX = 1 << 0;
|
|
|
|
}
|
2016-08-29 07:51:32 +00:00
|
|
|
}
|
|
|
|
|
2021-05-23 00:19:45 +00:00
|
|
|
impl Default for FileAttributes {
|
|
|
|
fn default() -> Self {
|
|
|
|
// The settings for SWF7 and earlier, which contain no FileAttributes tag.
|
|
|
|
Self::empty()
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2017-06-24 19:56:49 +00:00
|
|
|
#[derive(Debug, PartialEq)]
|
2021-01-18 06:46:18 +00:00
|
|
|
pub struct FrameLabel<'a> {
|
2021-01-20 20:46:22 +00:00
|
|
|
pub label: &'a SwfStr,
|
2019-08-15 23:39:24 +00:00
|
|
|
pub is_anchor: bool,
|
|
|
|
}
|
|
|
|
|
|
|
|
#[derive(Debug, PartialEq)]
|
2021-01-18 06:46:18 +00:00
|
|
|
pub struct DefineSceneAndFrameLabelData<'a> {
|
|
|
|
pub scenes: Vec<FrameLabelData<'a>>,
|
|
|
|
pub frame_labels: Vec<FrameLabelData<'a>>,
|
2019-08-15 23:39:24 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
#[derive(Debug, PartialEq)]
|
2021-01-18 06:46:18 +00:00
|
|
|
pub struct FrameLabelData<'a> {
|
2016-08-29 07:51:32 +00:00
|
|
|
pub frame_num: u32,
|
2021-01-20 20:46:22 +00:00
|
|
|
pub label: &'a SwfStr,
|
2016-08-29 07:51:32 +00:00
|
|
|
}
|
|
|
|
|
2019-12-17 06:47:22 +00:00
|
|
|
pub type Depth = u16;
|
2016-08-29 07:51:32 +00:00
|
|
|
pub type CharacterId = u16;
|
|
|
|
|
2017-06-24 19:56:49 +00:00
|
|
|
#[derive(Debug, PartialEq)]
|
2021-01-18 06:46:18 +00:00
|
|
|
pub struct PlaceObject<'a> {
|
2016-09-06 18:50:36 +00:00
|
|
|
pub version: u8,
|
|
|
|
pub action: PlaceObjectAction,
|
2016-08-29 07:51:32 +00:00
|
|
|
pub depth: Depth,
|
|
|
|
pub matrix: Option<Matrix>,
|
2016-09-08 02:59:59 +00:00
|
|
|
pub color_transform: Option<ColorTransform>,
|
2016-09-06 18:50:36 +00:00
|
|
|
pub ratio: Option<u16>,
|
2021-01-20 20:46:22 +00:00
|
|
|
pub name: Option<&'a SwfStr>,
|
2016-09-06 18:50:36 +00:00
|
|
|
pub clip_depth: Option<Depth>,
|
2021-01-20 20:46:22 +00:00
|
|
|
pub class_name: Option<&'a SwfStr>,
|
2020-09-04 00:41:58 +00:00
|
|
|
pub filters: Option<Vec<Filter>>,
|
2016-09-08 02:59:59 +00:00
|
|
|
pub background_color: Option<Color>,
|
2020-09-04 00:41:58 +00:00
|
|
|
pub blend_mode: Option<BlendMode>,
|
2021-01-18 06:46:18 +00:00
|
|
|
pub clip_actions: Option<Vec<ClipAction<'a>>>,
|
2016-09-09 06:02:43 +00:00
|
|
|
pub is_image: bool,
|
2020-09-04 00:41:58 +00:00
|
|
|
pub is_bitmap_cached: Option<bool>,
|
|
|
|
pub is_visible: Option<bool>,
|
2021-01-18 06:46:18 +00:00
|
|
|
pub amf_data: Option<&'a [u8]>,
|
2016-09-06 18:50:36 +00:00
|
|
|
}
|
|
|
|
|
2017-06-24 19:56:49 +00:00
|
|
|
#[derive(Debug, PartialEq, Clone, Copy)]
|
2016-09-06 18:50:36 +00:00
|
|
|
pub enum PlaceObjectAction {
|
2016-09-08 02:59:59 +00:00
|
|
|
Place(CharacterId),
|
2016-09-06 18:50:36 +00:00
|
|
|
Modify,
|
|
|
|
Replace(CharacterId),
|
|
|
|
}
|
|
|
|
|
2017-06-24 19:56:49 +00:00
|
|
|
#[derive(Debug, PartialEq, Clone)]
|
2016-09-06 18:50:36 +00:00
|
|
|
pub enum Filter {
|
2016-09-09 06:29:12 +00:00
|
|
|
DropShadowFilter(Box<DropShadowFilter>),
|
|
|
|
BlurFilter(Box<BlurFilter>),
|
|
|
|
GlowFilter(Box<GlowFilter>),
|
2016-09-09 07:05:07 +00:00
|
|
|
BevelFilter(Box<BevelFilter>),
|
2016-09-09 06:29:12 +00:00
|
|
|
GradientGlowFilter(Box<GradientGlowFilter>),
|
|
|
|
ConvolutionFilter(Box<ConvolutionFilter>),
|
|
|
|
ColorMatrixFilter(Box<ColorMatrixFilter>),
|
|
|
|
GradientBevelFilter(Box<GradientBevelFilter>),
|
|
|
|
}
|
|
|
|
|
2017-06-24 19:56:49 +00:00
|
|
|
#[derive(Debug, PartialEq, Clone)]
|
2016-09-09 06:29:12 +00:00
|
|
|
pub struct DropShadowFilter {
|
|
|
|
pub color: Color,
|
2021-05-30 20:30:06 +00:00
|
|
|
pub blur_x: Fixed16,
|
|
|
|
pub blur_y: Fixed16,
|
|
|
|
pub angle: Fixed16,
|
|
|
|
pub distance: Fixed16,
|
|
|
|
pub strength: Fixed8,
|
2016-09-09 06:29:12 +00:00
|
|
|
pub is_inner: bool,
|
2016-09-09 07:05:07 +00:00
|
|
|
pub is_knockout: bool,
|
2016-09-09 06:29:12 +00:00
|
|
|
pub num_passes: u8,
|
2016-09-06 18:50:36 +00:00
|
|
|
}
|
|
|
|
|
2017-06-24 19:56:49 +00:00
|
|
|
#[derive(Debug, PartialEq, Clone)]
|
2016-09-09 06:29:12 +00:00
|
|
|
pub struct BlurFilter {
|
2021-05-30 20:30:06 +00:00
|
|
|
pub blur_x: Fixed16,
|
|
|
|
pub blur_y: Fixed16,
|
2016-09-09 07:05:07 +00:00
|
|
|
pub num_passes: u8,
|
2016-09-09 06:29:12 +00:00
|
|
|
}
|
|
|
|
|
2017-06-24 19:56:49 +00:00
|
|
|
#[derive(Debug, PartialEq, Clone)]
|
2016-09-09 06:29:12 +00:00
|
|
|
pub struct GlowFilter {
|
|
|
|
pub color: Color,
|
2021-05-30 20:30:06 +00:00
|
|
|
pub blur_x: Fixed16,
|
|
|
|
pub blur_y: Fixed16,
|
|
|
|
pub strength: Fixed8,
|
2016-09-09 06:29:12 +00:00
|
|
|
pub is_inner: bool,
|
2016-09-09 07:05:07 +00:00
|
|
|
pub is_knockout: bool,
|
2016-09-09 06:29:12 +00:00
|
|
|
pub num_passes: u8,
|
|
|
|
}
|
|
|
|
|
2017-06-24 19:56:49 +00:00
|
|
|
#[derive(Debug, PartialEq, Clone)]
|
2016-09-09 06:29:12 +00:00
|
|
|
pub struct BevelFilter {
|
|
|
|
pub shadow_color: Color,
|
|
|
|
pub highlight_color: Color,
|
2021-05-30 20:30:06 +00:00
|
|
|
pub blur_x: Fixed16,
|
|
|
|
pub blur_y: Fixed16,
|
|
|
|
pub angle: Fixed16,
|
|
|
|
pub distance: Fixed16,
|
|
|
|
pub strength: Fixed8,
|
2016-09-09 06:29:12 +00:00
|
|
|
pub is_inner: bool,
|
2016-09-09 07:05:07 +00:00
|
|
|
pub is_knockout: bool,
|
2016-09-09 06:29:12 +00:00
|
|
|
pub is_on_top: bool,
|
|
|
|
pub num_passes: u8,
|
|
|
|
}
|
|
|
|
|
2017-06-24 19:56:49 +00:00
|
|
|
#[derive(Debug, PartialEq, Clone)]
|
2016-09-09 06:29:12 +00:00
|
|
|
pub struct GradientGlowFilter {
|
|
|
|
pub colors: Vec<GradientRecord>,
|
2021-05-30 20:30:06 +00:00
|
|
|
pub blur_x: Fixed16,
|
|
|
|
pub blur_y: Fixed16,
|
|
|
|
pub angle: Fixed16,
|
|
|
|
pub distance: Fixed16,
|
|
|
|
pub strength: Fixed8,
|
2016-09-09 06:29:12 +00:00
|
|
|
pub is_inner: bool,
|
2016-09-09 07:05:07 +00:00
|
|
|
pub is_knockout: bool,
|
2016-09-10 06:49:57 +00:00
|
|
|
pub is_on_top: bool,
|
2016-09-09 06:29:12 +00:00
|
|
|
pub num_passes: u8,
|
|
|
|
}
|
|
|
|
|
2017-06-24 19:56:49 +00:00
|
|
|
#[derive(Debug, PartialEq, Clone)]
|
2016-09-09 06:29:12 +00:00
|
|
|
pub struct ConvolutionFilter {
|
|
|
|
pub num_matrix_rows: u8,
|
|
|
|
pub num_matrix_cols: u8,
|
2021-05-30 20:30:06 +00:00
|
|
|
pub matrix: Vec<Fixed16>,
|
|
|
|
pub divisor: Fixed16,
|
|
|
|
pub bias: Fixed16,
|
2016-09-09 06:29:12 +00:00
|
|
|
pub default_color: Color,
|
|
|
|
pub is_clamped: bool,
|
|
|
|
pub is_preserve_alpha: bool,
|
|
|
|
}
|
|
|
|
|
2017-06-24 19:56:49 +00:00
|
|
|
#[derive(Debug, PartialEq, Clone)]
|
2016-09-09 06:29:12 +00:00
|
|
|
pub struct ColorMatrixFilter {
|
2021-05-30 20:30:06 +00:00
|
|
|
pub matrix: [Fixed16; 20],
|
2016-09-09 06:29:12 +00:00
|
|
|
}
|
|
|
|
|
2017-06-24 19:56:49 +00:00
|
|
|
#[derive(Debug, PartialEq, Clone)]
|
2016-09-09 06:29:12 +00:00
|
|
|
pub struct GradientBevelFilter {
|
2016-09-09 07:05:07 +00:00
|
|
|
pub colors: Vec<GradientRecord>,
|
2021-05-30 20:30:06 +00:00
|
|
|
pub blur_x: Fixed16,
|
|
|
|
pub blur_y: Fixed16,
|
|
|
|
pub angle: Fixed16,
|
|
|
|
pub distance: Fixed16,
|
|
|
|
pub strength: Fixed8,
|
2016-09-09 07:05:07 +00:00
|
|
|
pub is_inner: bool,
|
|
|
|
pub is_knockout: bool,
|
|
|
|
pub is_on_top: bool,
|
|
|
|
pub num_passes: u8,
|
2016-09-09 06:29:12 +00:00
|
|
|
}
|
2016-09-06 18:50:36 +00:00
|
|
|
|
2021-06-05 20:23:22 +00:00
|
|
|
#[derive(Debug, PartialEq, Eq, Clone, Copy, FromPrimitive, ToPrimitive)]
|
2016-09-06 18:50:36 +00:00
|
|
|
pub enum BlendMode {
|
2021-06-05 20:23:22 +00:00
|
|
|
Normal = 0,
|
|
|
|
Layer = 2,
|
|
|
|
Multiply = 3,
|
|
|
|
Screen = 4,
|
|
|
|
Lighten = 5,
|
|
|
|
Darken = 6,
|
|
|
|
Difference = 7,
|
|
|
|
Add = 8,
|
|
|
|
Subtract = 9,
|
|
|
|
Invert = 10,
|
|
|
|
Alpha = 11,
|
|
|
|
Erase = 12,
|
|
|
|
Overlay = 13,
|
|
|
|
HardLight = 14,
|
|
|
|
}
|
|
|
|
|
|
|
|
impl BlendMode {
|
|
|
|
pub fn from_u8(n: u8) -> Option<Self> {
|
|
|
|
num_traits::FromPrimitive::from_u8(match n {
|
|
|
|
1 => 0,
|
|
|
|
n => n,
|
|
|
|
})
|
|
|
|
}
|
|
|
|
|
|
|
|
pub fn to_u8(self) -> u8 {
|
|
|
|
num_traits::ToPrimitive::to_u8(&self).unwrap()
|
|
|
|
}
|
2017-06-24 19:56:49 +00:00
|
|
|
}
|
2016-09-06 18:50:36 +00:00
|
|
|
|
2019-12-01 19:05:25 +00:00
|
|
|
/// An clip action (a.k.a. clip event) placed on a movieclip instance.
|
|
|
|
/// Created in the Flash IDE using `onClipEvent` or `on` blocks.
|
|
|
|
///
|
2021-01-22 00:35:46 +00:00
|
|
|
/// [SWF19 pp.37-38 ClipActionRecord](https://www.adobe.com/content/dam/acom/en/devnet/pdf/swf-file-format-spec.pdf#page=39)
|
2019-12-01 19:05:25 +00:00
|
|
|
#[derive(Debug, Clone, PartialEq)]
|
2021-01-18 06:46:18 +00:00
|
|
|
pub struct ClipAction<'a> {
|
2021-01-22 00:35:46 +00:00
|
|
|
pub events: ClipEventFlag,
|
2019-12-01 19:05:25 +00:00
|
|
|
pub key_code: Option<KeyCode>,
|
2021-01-18 06:46:18 +00:00
|
|
|
pub action_data: &'a [u8],
|
2016-09-06 18:50:36 +00:00
|
|
|
}
|
|
|
|
|
2021-01-22 00:35:46 +00:00
|
|
|
bitflags! {
|
|
|
|
/// An event that can be attached to a movieclip instance using
|
|
|
|
/// an `onClipEvent` or `on` block.
|
|
|
|
///
|
|
|
|
/// [SWF19 pp.48-50 ClipEvent](https://www.adobe.com/content/dam/acom/en/devnet/pdf/swf-file-format-spec.pdf#page=50)
|
|
|
|
pub struct ClipEventFlag: u32 {
|
|
|
|
const CONSTRUCT = 1 << 0;
|
|
|
|
const DATA = 1 << 1;
|
|
|
|
const DRAG_OUT = 1 << 2;
|
|
|
|
const DRAG_OVER = 1 << 3;
|
|
|
|
const ENTER_FRAME = 1 << 4;
|
|
|
|
const INITIALIZE = 1 << 5;
|
|
|
|
const KEY_UP = 1 << 6;
|
|
|
|
const KEY_DOWN = 1 << 7;
|
|
|
|
const KEY_PRESS = 1 << 8;
|
|
|
|
const LOAD = 1 << 9;
|
|
|
|
const MOUSE_UP = 1 << 10;
|
|
|
|
const MOUSE_DOWN = 1 << 11;
|
|
|
|
const MOUSE_MOVE = 1 << 12;
|
|
|
|
const PRESS = 1 << 13;
|
|
|
|
const ROLL_OUT = 1 << 14;
|
|
|
|
const ROLL_OVER = 1 << 15;
|
|
|
|
const RELEASE = 1 << 16;
|
|
|
|
const RELEASE_OUTSIDE = 1 << 17;
|
|
|
|
const UNLOAD = 1 << 18;
|
|
|
|
}
|
2016-08-29 07:51:32 +00:00
|
|
|
}
|
|
|
|
|
2019-12-01 19:05:25 +00:00
|
|
|
/// A key code used in `ButtonAction` and `ClipAction` key press events.
|
|
|
|
pub type KeyCode = u8;
|
2016-09-09 04:19:51 +00:00
|
|
|
|
2019-06-17 04:23:31 +00:00
|
|
|
/// Represents a tag in an SWF file.
|
|
|
|
///
|
|
|
|
/// The SWF format is made up of a stream of tags. Each tag either
|
|
|
|
/// defines a character (graphic, sound, movieclip), or places/modifies
|
|
|
|
/// an instance of these characters on the display list.
|
|
|
|
///
|
|
|
|
// [SWF19 p.29](https://www.adobe.com/content/dam/acom/en/devnet/pdf/swf-file-format-spec.pdf#page=29)
|
2017-06-24 19:56:49 +00:00
|
|
|
#[derive(Debug, PartialEq)]
|
2021-01-18 06:46:18 +00:00
|
|
|
pub enum Tag<'a> {
|
|
|
|
ExportAssets(ExportAssets<'a>),
|
2017-06-24 19:56:49 +00:00
|
|
|
ScriptLimits {
|
|
|
|
max_recursion_depth: u16,
|
|
|
|
timeout_in_seconds: u16,
|
|
|
|
},
|
2016-08-29 07:51:32 +00:00
|
|
|
ShowFrame,
|
|
|
|
|
2021-01-20 20:46:22 +00:00
|
|
|
Protect(Option<&'a SwfStr>),
|
2017-02-21 04:23:12 +00:00
|
|
|
CsmTextSettings(CsmTextSettings),
|
2019-08-16 16:56:49 +00:00
|
|
|
DebugId(DebugId),
|
2019-04-23 07:31:12 +00:00
|
|
|
DefineBinaryData {
|
|
|
|
id: CharacterId,
|
2021-01-18 06:46:18 +00:00
|
|
|
data: &'a [u8],
|
2019-04-23 07:31:12 +00:00
|
|
|
},
|
|
|
|
DefineBits {
|
|
|
|
id: CharacterId,
|
2021-01-18 06:46:18 +00:00
|
|
|
jpeg_data: &'a [u8],
|
2019-04-23 07:31:12 +00:00
|
|
|
},
|
|
|
|
DefineBitsJpeg2 {
|
|
|
|
id: CharacterId,
|
2021-01-18 06:46:18 +00:00
|
|
|
jpeg_data: &'a [u8],
|
2019-04-23 07:31:12 +00:00
|
|
|
},
|
2021-01-18 06:46:18 +00:00
|
|
|
DefineBitsJpeg3(DefineBitsJpeg3<'a>),
|
|
|
|
DefineBitsLossless(DefineBitsLossless<'a>),
|
|
|
|
DefineButton(Box<Button<'a>>),
|
|
|
|
DefineButton2(Box<Button<'a>>),
|
2019-12-20 20:26:18 +00:00
|
|
|
DefineButtonColorTransform(ButtonColorTransform),
|
2016-09-14 03:36:15 +00:00
|
|
|
DefineButtonSound(Box<ButtonSounds>),
|
2021-01-18 06:46:18 +00:00
|
|
|
DefineEditText(Box<EditText<'a>>),
|
2017-02-21 00:40:53 +00:00
|
|
|
DefineFont(Box<FontV1>),
|
2021-01-18 06:46:18 +00:00
|
|
|
DefineFont2(Box<Font<'a>>),
|
|
|
|
DefineFont4(Font4<'a>),
|
2017-06-24 19:56:49 +00:00
|
|
|
DefineFontAlignZones {
|
|
|
|
id: CharacterId,
|
|
|
|
thickness: FontThickness,
|
|
|
|
zones: Vec<FontAlignZone>,
|
|
|
|
},
|
2021-01-18 06:46:18 +00:00
|
|
|
DefineFontInfo(Box<FontInfo<'a>>),
|
2017-06-24 19:56:49 +00:00
|
|
|
DefineFontName {
|
|
|
|
id: CharacterId,
|
2021-01-20 20:46:22 +00:00
|
|
|
name: &'a SwfStr,
|
|
|
|
copyright_info: &'a SwfStr,
|
2017-06-24 19:56:49 +00:00
|
|
|
},
|
2017-02-23 02:48:12 +00:00
|
|
|
DefineMorphShape(Box<DefineMorphShape>),
|
2017-06-24 19:56:49 +00:00
|
|
|
DefineScalingGrid {
|
|
|
|
id: CharacterId,
|
|
|
|
splitter_rect: Rectangle,
|
|
|
|
},
|
2016-08-29 07:51:32 +00:00
|
|
|
DefineShape(Shape),
|
2021-01-18 06:46:18 +00:00
|
|
|
DefineSound(Box<Sound<'a>>),
|
|
|
|
DefineSprite(Sprite<'a>),
|
2017-02-16 03:07:08 +00:00
|
|
|
DefineText(Box<Text>),
|
2017-02-23 03:53:56 +00:00
|
|
|
DefineVideoStream(DefineVideoStream),
|
2021-01-18 06:46:18 +00:00
|
|
|
DoAbc(DoAbc<'a>),
|
|
|
|
DoAction(DoAction<'a>),
|
2017-06-24 19:56:49 +00:00
|
|
|
DoInitAction {
|
|
|
|
id: CharacterId,
|
2021-01-18 06:46:18 +00:00
|
|
|
action_data: &'a [u8],
|
2017-06-24 19:56:49 +00:00
|
|
|
},
|
2021-01-20 20:46:22 +00:00
|
|
|
EnableDebugger(&'a SwfStr),
|
2019-04-23 07:31:12 +00:00
|
|
|
EnableTelemetry {
|
2021-01-18 06:46:18 +00:00
|
|
|
password_hash: &'a [u8],
|
2019-04-23 07:31:12 +00:00
|
|
|
},
|
2019-06-17 10:23:29 +00:00
|
|
|
End,
|
2021-01-20 20:46:22 +00:00
|
|
|
Metadata(&'a SwfStr),
|
2017-06-24 19:56:49 +00:00
|
|
|
ImportAssets {
|
2021-01-20 20:46:22 +00:00
|
|
|
url: &'a SwfStr,
|
2021-01-18 06:46:18 +00:00
|
|
|
imports: Vec<ExportedAsset<'a>>,
|
2017-06-24 19:56:49 +00:00
|
|
|
},
|
2021-01-18 06:46:18 +00:00
|
|
|
JpegTables(JpegTables<'a>),
|
2019-07-23 01:29:39 +00:00
|
|
|
SetBackgroundColor(SetBackgroundColor),
|
2019-04-23 07:31:12 +00:00
|
|
|
SetTabIndex {
|
|
|
|
depth: Depth,
|
|
|
|
tab_index: u16,
|
|
|
|
},
|
2021-01-18 06:46:18 +00:00
|
|
|
SoundStreamBlock(SoundStreamBlock<'a>),
|
2019-07-23 01:29:39 +00:00
|
|
|
SoundStreamHead(Box<SoundStreamHead>),
|
|
|
|
SoundStreamHead2(Box<SoundStreamHead>),
|
|
|
|
StartSound(StartSound),
|
2017-06-24 19:56:49 +00:00
|
|
|
StartSound2 {
|
2021-01-20 20:46:22 +00:00
|
|
|
class_name: &'a SwfStr,
|
2017-06-24 19:56:49 +00:00
|
|
|
sound_info: Box<SoundInfo>,
|
|
|
|
},
|
2021-01-18 06:46:18 +00:00
|
|
|
SymbolClass(Vec<SymbolClassLink<'a>>),
|
|
|
|
PlaceObject(Box<PlaceObject<'a>>),
|
2019-07-23 01:29:39 +00:00
|
|
|
RemoveObject(RemoveObject),
|
2021-01-18 06:46:18 +00:00
|
|
|
VideoFrame(VideoFrame<'a>),
|
2016-08-29 07:51:32 +00:00
|
|
|
FileAttributes(FileAttributes),
|
|
|
|
|
2021-01-18 06:46:18 +00:00
|
|
|
FrameLabel(FrameLabel<'a>),
|
|
|
|
DefineSceneAndFrameLabelData(DefineSceneAndFrameLabelData<'a>),
|
2016-08-29 07:51:32 +00:00
|
|
|
|
2019-08-16 16:50:54 +00:00
|
|
|
ProductInfo(ProductInfo),
|
2016-08-29 07:51:32 +00:00
|
|
|
|
2019-04-23 07:31:12 +00:00
|
|
|
Unknown {
|
|
|
|
tag_code: u16,
|
2021-01-18 06:46:18 +00:00
|
|
|
data: &'a [u8],
|
2019-04-23 07:31:12 +00:00
|
|
|
},
|
2016-08-29 07:51:32 +00:00
|
|
|
}
|
|
|
|
|
2021-01-18 06:46:18 +00:00
|
|
|
pub type ExportAssets<'a> = Vec<ExportedAsset<'a>>;
|
2019-12-16 19:23:31 +00:00
|
|
|
|
2017-06-24 19:56:49 +00:00
|
|
|
#[derive(Debug, PartialEq, Clone)]
|
2021-01-18 06:46:18 +00:00
|
|
|
pub struct ExportedAsset<'a> {
|
2016-09-10 21:48:02 +00:00
|
|
|
pub id: CharacterId,
|
2021-01-20 20:46:22 +00:00
|
|
|
pub name: &'a SwfStr,
|
2016-09-10 21:48:02 +00:00
|
|
|
}
|
|
|
|
|
2019-07-23 01:29:39 +00:00
|
|
|
#[derive(Debug, PartialEq, Clone)]
|
|
|
|
pub struct RemoveObject {
|
|
|
|
pub depth: Depth,
|
|
|
|
pub character_id: Option<CharacterId>,
|
|
|
|
}
|
|
|
|
|
|
|
|
pub type SetBackgroundColor = Color;
|
|
|
|
|
2017-06-24 19:56:49 +00:00
|
|
|
#[derive(Debug, PartialEq, Clone)]
|
2021-01-18 06:46:18 +00:00
|
|
|
pub struct SymbolClassLink<'a> {
|
2016-09-10 23:55:09 +00:00
|
|
|
pub id: CharacterId,
|
2021-01-20 20:46:22 +00:00
|
|
|
pub class_name: &'a SwfStr,
|
2016-09-10 23:55:09 +00:00
|
|
|
}
|
|
|
|
|
2021-01-17 23:24:20 +00:00
|
|
|
#[derive(Debug, PartialEq, Clone)]
|
|
|
|
pub struct ShapeContext {
|
|
|
|
pub swf_version: u8,
|
|
|
|
pub shape_version: u8,
|
|
|
|
pub num_fill_bits: u8,
|
|
|
|
pub num_line_bits: u8,
|
|
|
|
}
|
|
|
|
|
2020-08-21 06:25:31 +00:00
|
|
|
#[derive(Debug, PartialEq, Clone)]
|
2016-08-29 07:51:32 +00:00
|
|
|
pub struct Shape {
|
|
|
|
pub version: u8,
|
|
|
|
pub id: CharacterId,
|
|
|
|
pub shape_bounds: Rectangle,
|
|
|
|
pub edge_bounds: Rectangle,
|
2016-09-11 02:37:34 +00:00
|
|
|
pub has_fill_winding_rule: bool,
|
|
|
|
pub has_non_scaling_strokes: bool,
|
|
|
|
pub has_scaling_strokes: bool,
|
2016-08-29 07:51:32 +00:00
|
|
|
pub styles: ShapeStyles,
|
|
|
|
pub shape: Vec<ShapeRecord>,
|
|
|
|
}
|
|
|
|
|
2017-06-24 19:56:49 +00:00
|
|
|
#[derive(Debug, PartialEq, Clone)]
|
2021-01-18 06:46:18 +00:00
|
|
|
pub struct Sound<'a> {
|
2016-09-11 19:56:08 +00:00
|
|
|
pub id: CharacterId,
|
2016-09-14 00:29:59 +00:00
|
|
|
pub format: SoundFormat,
|
2016-09-11 19:56:08 +00:00
|
|
|
pub num_samples: u32,
|
2021-01-18 06:46:18 +00:00
|
|
|
pub data: &'a [u8],
|
2016-09-11 19:56:08 +00:00
|
|
|
}
|
|
|
|
|
2017-06-24 19:56:49 +00:00
|
|
|
#[derive(Debug, PartialEq, Clone)]
|
2016-09-12 00:03:55 +00:00
|
|
|
pub struct SoundInfo {
|
|
|
|
pub event: SoundEvent,
|
|
|
|
pub in_sample: Option<u32>,
|
|
|
|
pub out_sample: Option<u32>,
|
|
|
|
pub num_loops: u16,
|
|
|
|
pub envelope: Option<SoundEnvelope>,
|
|
|
|
}
|
|
|
|
|
2021-06-05 20:30:33 +00:00
|
|
|
#[derive(Debug, PartialEq, Clone, Copy, FromPrimitive, ToPrimitive)]
|
2016-09-12 00:03:55 +00:00
|
|
|
pub enum SoundEvent {
|
2021-06-05 20:30:33 +00:00
|
|
|
Event = 0,
|
|
|
|
Start = 1,
|
|
|
|
Stop = 2,
|
|
|
|
}
|
|
|
|
|
|
|
|
impl SoundEvent {
|
|
|
|
pub fn from_u8(n: u8) -> Option<Self> {
|
|
|
|
num_traits::FromPrimitive::from_u8(match n {
|
|
|
|
3 => 2,
|
|
|
|
n => n,
|
|
|
|
})
|
|
|
|
}
|
|
|
|
|
|
|
|
pub fn to_u8(self) -> u8 {
|
|
|
|
num_traits::ToPrimitive::to_u8(&self).unwrap()
|
|
|
|
}
|
2016-09-12 00:03:55 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
pub type SoundEnvelope = Vec<SoundEnvelopePoint>;
|
|
|
|
|
2017-06-24 19:56:49 +00:00
|
|
|
#[derive(Debug, PartialEq, Clone)]
|
2016-09-12 00:03:55 +00:00
|
|
|
pub struct SoundEnvelopePoint {
|
|
|
|
pub sample: u32,
|
|
|
|
pub left_volume: f32,
|
|
|
|
pub right_volume: f32,
|
|
|
|
}
|
|
|
|
|
2019-07-23 01:29:39 +00:00
|
|
|
#[derive(Clone, Debug, PartialEq)]
|
|
|
|
pub struct StartSound {
|
|
|
|
pub id: CharacterId,
|
|
|
|
pub sound_info: Box<SoundInfo>,
|
|
|
|
}
|
|
|
|
|
2017-06-24 19:56:49 +00:00
|
|
|
#[derive(Debug, PartialEq)]
|
2021-01-18 06:46:18 +00:00
|
|
|
pub struct Sprite<'a> {
|
2016-09-08 05:08:24 +00:00
|
|
|
pub id: CharacterId,
|
|
|
|
pub num_frames: u16,
|
2021-01-18 06:46:18 +00:00
|
|
|
pub tags: Vec<Tag<'a>>,
|
2016-09-08 05:08:24 +00:00
|
|
|
}
|
|
|
|
|
2017-02-17 04:15:35 +00:00
|
|
|
#[derive(Clone, Debug, PartialEq)]
|
2016-08-29 07:51:32 +00:00
|
|
|
pub struct ShapeStyles {
|
|
|
|
pub fill_styles: Vec<FillStyle>,
|
|
|
|
pub line_styles: Vec<LineStyle>,
|
|
|
|
}
|
|
|
|
|
2017-02-17 04:15:35 +00:00
|
|
|
#[derive(Clone, Debug, PartialEq)]
|
2016-08-29 07:51:32 +00:00
|
|
|
pub enum ShapeRecord {
|
|
|
|
StyleChange(StyleChangeData),
|
2019-04-23 07:31:12 +00:00
|
|
|
StraightEdge {
|
2019-05-17 04:32:18 +00:00
|
|
|
delta_x: Twips,
|
|
|
|
delta_y: Twips,
|
2019-04-23 07:31:12 +00:00
|
|
|
},
|
2016-08-29 20:32:56 +00:00
|
|
|
CurvedEdge {
|
2019-05-17 04:32:18 +00:00
|
|
|
control_delta_x: Twips,
|
|
|
|
control_delta_y: Twips,
|
|
|
|
anchor_delta_x: Twips,
|
|
|
|
anchor_delta_y: Twips,
|
2016-08-29 20:32:56 +00:00
|
|
|
},
|
2016-08-29 07:51:32 +00:00
|
|
|
}
|
|
|
|
|
2017-02-17 04:15:35 +00:00
|
|
|
#[derive(Clone, Debug, PartialEq)]
|
2016-08-29 07:51:32 +00:00
|
|
|
pub struct StyleChangeData {
|
2019-05-17 04:32:18 +00:00
|
|
|
pub move_to: Option<(Twips, Twips)>,
|
2016-08-29 07:51:32 +00:00
|
|
|
pub fill_style_0: Option<u32>,
|
|
|
|
pub fill_style_1: Option<u32>,
|
|
|
|
pub line_style: Option<u32>,
|
|
|
|
pub new_styles: Option<ShapeStyles>,
|
|
|
|
}
|
|
|
|
|
2017-06-24 19:56:49 +00:00
|
|
|
#[derive(Debug, PartialEq, Clone)]
|
2016-08-29 07:51:32 +00:00
|
|
|
pub enum FillStyle {
|
|
|
|
Color(Color),
|
|
|
|
LinearGradient(Gradient),
|
|
|
|
RadialGradient(Gradient),
|
2016-08-29 20:32:56 +00:00
|
|
|
FocalGradient {
|
|
|
|
gradient: Gradient,
|
2021-05-30 20:30:06 +00:00
|
|
|
focal_point: Fixed8,
|
2016-08-29 20:32:56 +00:00
|
|
|
},
|
|
|
|
Bitmap {
|
|
|
|
id: CharacterId,
|
|
|
|
matrix: Matrix,
|
|
|
|
is_smoothed: bool,
|
|
|
|
is_repeating: bool,
|
|
|
|
},
|
2016-08-29 07:51:32 +00:00
|
|
|
}
|
|
|
|
|
2017-06-24 19:56:49 +00:00
|
|
|
#[derive(Debug, PartialEq, Clone)]
|
2016-08-29 07:51:32 +00:00
|
|
|
pub struct Gradient {
|
2016-09-11 02:37:34 +00:00
|
|
|
pub matrix: Matrix,
|
2016-08-29 07:51:32 +00:00
|
|
|
pub spread: GradientSpread,
|
|
|
|
pub interpolation: GradientInterpolation,
|
|
|
|
pub records: Vec<GradientRecord>,
|
|
|
|
}
|
|
|
|
|
2021-06-05 20:37:47 +00:00
|
|
|
#[derive(Debug, PartialEq, Clone, Copy, FromPrimitive, ToPrimitive)]
|
2016-08-29 07:51:32 +00:00
|
|
|
pub enum GradientSpread {
|
2021-06-05 20:37:47 +00:00
|
|
|
Pad = 0,
|
|
|
|
Reflect = 1,
|
|
|
|
Repeat = 2,
|
|
|
|
}
|
|
|
|
|
|
|
|
impl GradientSpread {
|
|
|
|
pub fn from_u8(n: u8) -> Option<Self> {
|
|
|
|
num_traits::FromPrimitive::from_u8(n)
|
|
|
|
}
|
|
|
|
|
|
|
|
pub fn to_u8(self) -> u8 {
|
|
|
|
num_traits::ToPrimitive::to_u8(&self).unwrap()
|
|
|
|
}
|
2016-08-29 07:51:32 +00:00
|
|
|
}
|
|
|
|
|
2021-06-05 20:47:02 +00:00
|
|
|
#[derive(Debug, PartialEq, Clone, Copy, FromPrimitive, ToPrimitive)]
|
2016-08-29 07:51:32 +00:00
|
|
|
pub enum GradientInterpolation {
|
2021-06-05 20:47:02 +00:00
|
|
|
Rgb = 0,
|
|
|
|
LinearRgb = 1,
|
|
|
|
}
|
|
|
|
|
|
|
|
impl GradientInterpolation {
|
|
|
|
pub fn from_u8(n: u8) -> Option<Self> {
|
|
|
|
num_traits::FromPrimitive::from_u8(n)
|
|
|
|
}
|
|
|
|
|
|
|
|
pub fn to_u8(self) -> u8 {
|
|
|
|
num_traits::ToPrimitive::to_u8(&self).unwrap()
|
|
|
|
}
|
2016-08-29 07:51:32 +00:00
|
|
|
}
|
|
|
|
|
2017-06-24 19:56:49 +00:00
|
|
|
#[derive(Debug, PartialEq, Clone)]
|
2016-08-29 07:51:32 +00:00
|
|
|
pub struct GradientRecord {
|
|
|
|
pub ratio: u8,
|
|
|
|
pub color: Color,
|
|
|
|
}
|
|
|
|
|
2017-06-24 19:56:49 +00:00
|
|
|
#[derive(Debug, PartialEq, Clone)]
|
2016-08-29 07:51:32 +00:00
|
|
|
pub struct LineStyle {
|
2019-05-17 04:32:18 +00:00
|
|
|
pub width: Twips,
|
2016-08-29 07:51:32 +00:00
|
|
|
pub color: Color,
|
2016-09-11 02:37:34 +00:00
|
|
|
pub start_cap: LineCapStyle,
|
|
|
|
pub end_cap: LineCapStyle,
|
|
|
|
pub join_style: LineJoinStyle,
|
|
|
|
pub fill_style: Option<FillStyle>,
|
|
|
|
pub allow_scale_x: bool,
|
|
|
|
pub allow_scale_y: bool,
|
|
|
|
pub is_pixel_hinted: bool,
|
|
|
|
pub allow_close: bool,
|
|
|
|
}
|
|
|
|
|
|
|
|
impl LineStyle {
|
2021-02-11 02:36:23 +00:00
|
|
|
pub const fn new_v1(width: Twips, color: Color) -> LineStyle {
|
2016-09-11 02:37:34 +00:00
|
|
|
LineStyle {
|
2019-04-23 07:24:33 +00:00
|
|
|
width,
|
|
|
|
color,
|
2016-09-11 02:37:34 +00:00
|
|
|
start_cap: LineCapStyle::Round,
|
|
|
|
end_cap: LineCapStyle::Round,
|
|
|
|
join_style: LineJoinStyle::Round,
|
|
|
|
fill_style: None,
|
|
|
|
allow_scale_x: false,
|
|
|
|
allow_scale_y: false,
|
|
|
|
is_pixel_hinted: false,
|
|
|
|
allow_close: true,
|
|
|
|
}
|
|
|
|
}
|
2016-08-29 07:51:32 +00:00
|
|
|
}
|
|
|
|
|
2021-06-05 20:47:02 +00:00
|
|
|
#[derive(Debug, PartialEq, Clone, Copy, FromPrimitive, ToPrimitive)]
|
2016-08-29 07:51:32 +00:00
|
|
|
pub enum LineCapStyle {
|
2021-06-05 20:47:02 +00:00
|
|
|
Round = 0,
|
|
|
|
None = 1,
|
|
|
|
Square = 2,
|
|
|
|
}
|
|
|
|
|
|
|
|
impl LineCapStyle {
|
|
|
|
pub fn from_u8(n: u8) -> Option<Self> {
|
|
|
|
num_traits::FromPrimitive::from_u8(n)
|
|
|
|
}
|
|
|
|
|
|
|
|
pub fn to_u8(self) -> u8 {
|
|
|
|
num_traits::ToPrimitive::to_u8(&self).unwrap()
|
|
|
|
}
|
2016-08-29 07:51:32 +00:00
|
|
|
}
|
2016-09-11 19:56:08 +00:00
|
|
|
|
2017-06-24 19:56:49 +00:00
|
|
|
#[derive(Debug, PartialEq, Clone, Copy)]
|
2016-08-29 07:51:32 +00:00
|
|
|
pub enum LineJoinStyle {
|
|
|
|
Round,
|
|
|
|
Bevel,
|
2021-05-30 20:30:06 +00:00
|
|
|
Miter(Fixed8),
|
2016-09-11 19:56:08 +00:00
|
|
|
}
|
|
|
|
|
2021-06-05 20:52:05 +00:00
|
|
|
#[derive(Debug, PartialEq, Clone, Copy, FromPrimitive, ToPrimitive)]
|
2016-09-11 19:56:08 +00:00
|
|
|
pub enum AudioCompression {
|
2021-06-05 20:52:05 +00:00
|
|
|
UncompressedUnknownEndian = 0,
|
|
|
|
Adpcm = 1,
|
|
|
|
Mp3 = 2,
|
|
|
|
Uncompressed = 3,
|
|
|
|
Nellymoser16Khz = 4,
|
|
|
|
Nellymoser8Khz = 5,
|
|
|
|
Nellymoser = 6,
|
|
|
|
Speex = 11,
|
|
|
|
}
|
|
|
|
|
|
|
|
impl AudioCompression {
|
|
|
|
pub fn from_u8(n: u8) -> Option<Self> {
|
|
|
|
num_traits::FromPrimitive::from_u8(n)
|
|
|
|
}
|
|
|
|
|
|
|
|
pub fn to_u8(self) -> u8 {
|
|
|
|
num_traits::ToPrimitive::to_u8(&self).unwrap()
|
|
|
|
}
|
2016-09-14 00:29:59 +00:00
|
|
|
}
|
|
|
|
|
2017-06-24 19:56:49 +00:00
|
|
|
#[derive(Debug, PartialEq, Clone)]
|
2016-09-14 00:29:59 +00:00
|
|
|
pub struct SoundFormat {
|
|
|
|
pub compression: AudioCompression,
|
|
|
|
pub sample_rate: u16,
|
|
|
|
pub is_stereo: bool,
|
|
|
|
pub is_16_bit: bool,
|
|
|
|
}
|
|
|
|
|
2017-06-24 19:56:49 +00:00
|
|
|
#[derive(Debug, PartialEq, Clone)]
|
2019-07-23 01:29:39 +00:00
|
|
|
pub struct SoundStreamHead {
|
2016-09-14 00:29:59 +00:00
|
|
|
pub stream_format: SoundFormat,
|
|
|
|
pub playback_format: SoundFormat,
|
|
|
|
pub num_samples_per_block: u16,
|
|
|
|
pub latency_seek: i16,
|
2016-09-14 01:55:13 +00:00
|
|
|
}
|
|
|
|
|
2021-01-18 06:46:18 +00:00
|
|
|
pub type SoundStreamBlock<'a> = &'a [u8];
|
2019-07-23 01:29:39 +00:00
|
|
|
|
2017-06-24 19:56:49 +00:00
|
|
|
#[derive(Debug, PartialEq, Clone)]
|
2021-01-18 06:46:18 +00:00
|
|
|
pub struct Button<'a> {
|
2016-09-14 01:55:13 +00:00
|
|
|
pub id: CharacterId,
|
2016-09-17 19:40:50 +00:00
|
|
|
pub is_track_as_menu: bool,
|
2016-09-14 01:55:13 +00:00
|
|
|
pub records: Vec<ButtonRecord>,
|
2021-01-18 06:46:18 +00:00
|
|
|
pub actions: Vec<ButtonAction<'a>>,
|
2016-09-14 01:55:13 +00:00
|
|
|
}
|
|
|
|
|
2017-06-24 19:56:49 +00:00
|
|
|
#[derive(Debug, PartialEq, Clone)]
|
2016-09-14 01:55:13 +00:00
|
|
|
pub struct ButtonRecord {
|
2021-01-23 00:17:22 +00:00
|
|
|
pub states: ButtonState,
|
2016-09-14 01:55:13 +00:00
|
|
|
pub id: CharacterId,
|
|
|
|
pub depth: Depth,
|
|
|
|
pub matrix: Matrix,
|
|
|
|
pub color_transform: ColorTransform,
|
|
|
|
pub filters: Vec<Filter>,
|
|
|
|
pub blend_mode: BlendMode,
|
|
|
|
}
|
|
|
|
|
2021-01-23 00:17:22 +00:00
|
|
|
bitflags! {
|
|
|
|
pub struct ButtonState: u8 {
|
|
|
|
const UP = 1 << 0;
|
|
|
|
const OVER = 1 << 1;
|
|
|
|
const DOWN = 1 << 2;
|
|
|
|
const HIT_TEST = 1 << 3;
|
|
|
|
}
|
2016-09-14 03:36:15 +00:00
|
|
|
}
|
|
|
|
|
2019-12-20 20:26:18 +00:00
|
|
|
#[derive(Debug, PartialEq, Clone)]
|
|
|
|
pub struct ButtonColorTransform {
|
|
|
|
pub id: CharacterId,
|
|
|
|
pub color_transforms: Vec<ColorTransform>,
|
|
|
|
}
|
|
|
|
|
2017-06-24 19:56:49 +00:00
|
|
|
#[derive(Debug, PartialEq, Clone)]
|
2016-09-14 03:36:15 +00:00
|
|
|
pub struct ButtonSounds {
|
|
|
|
pub id: CharacterId,
|
|
|
|
pub over_to_up_sound: Option<ButtonSound>,
|
|
|
|
pub up_to_over_sound: Option<ButtonSound>,
|
|
|
|
pub over_to_down_sound: Option<ButtonSound>,
|
|
|
|
pub down_to_over_sound: Option<ButtonSound>,
|
|
|
|
}
|
|
|
|
|
2016-09-17 19:40:50 +00:00
|
|
|
pub type ButtonSound = (CharacterId, SoundInfo);
|
|
|
|
|
2017-06-24 19:56:49 +00:00
|
|
|
#[derive(Debug, PartialEq, Clone)]
|
2021-01-18 06:46:18 +00:00
|
|
|
pub struct ButtonAction<'a> {
|
2021-01-23 00:47:29 +00:00
|
|
|
pub conditions: ButtonActionCondition,
|
2016-09-17 19:40:50 +00:00
|
|
|
pub key_code: Option<u8>,
|
2021-01-18 06:46:18 +00:00
|
|
|
pub action_data: &'a [u8],
|
2016-09-17 19:40:50 +00:00
|
|
|
}
|
|
|
|
|
2021-01-23 00:47:29 +00:00
|
|
|
bitflags! {
|
|
|
|
pub struct ButtonActionCondition: u16 {
|
|
|
|
const IDLE_TO_OVER_UP = 1 << 0;
|
|
|
|
const OVER_UP_TO_IDLE = 1 << 1;
|
|
|
|
const OVER_UP_TO_OVER_DOWN = 1 << 2;
|
|
|
|
const OVER_DOWN_TO_OVER_UP = 1 << 3;
|
|
|
|
const OVER_DOWN_TO_OUT_DOWN = 1 << 4;
|
|
|
|
const OUT_DOWN_TO_OVER_DOWN = 1 << 5;
|
|
|
|
const OUT_DOWN_TO_IDLE = 1 << 6;
|
|
|
|
const IDLE_TO_OVER_DOWN = 1 << 7;
|
|
|
|
const OVER_DOWN_TO_IDLE = 1 << 8;
|
|
|
|
const KEY_PRESS = 1 << 9;
|
|
|
|
}
|
2017-02-11 01:57:25 +00:00
|
|
|
}
|
|
|
|
|
2017-02-23 02:48:12 +00:00
|
|
|
#[derive(Clone, Debug, PartialEq)]
|
|
|
|
pub struct DefineMorphShape {
|
|
|
|
pub version: u8,
|
|
|
|
pub id: CharacterId,
|
|
|
|
pub has_non_scaling_strokes: bool,
|
|
|
|
pub has_scaling_strokes: bool,
|
|
|
|
pub start: MorphShape,
|
|
|
|
pub end: MorphShape,
|
|
|
|
}
|
|
|
|
|
|
|
|
#[derive(Clone, Debug, PartialEq)]
|
|
|
|
pub struct MorphShape {
|
|
|
|
pub shape_bounds: Rectangle,
|
|
|
|
pub edge_bounds: Rectangle,
|
|
|
|
pub fill_styles: Vec<FillStyle>,
|
|
|
|
pub line_styles: Vec<LineStyle>,
|
|
|
|
pub shape: Vec<ShapeRecord>,
|
|
|
|
}
|
|
|
|
|
2017-02-21 00:40:53 +00:00
|
|
|
#[derive(Clone, Debug, PartialEq)]
|
|
|
|
pub struct FontV1 {
|
|
|
|
pub id: CharacterId,
|
|
|
|
pub glyphs: Vec<Vec<ShapeRecord>>,
|
|
|
|
}
|
|
|
|
|
2017-02-17 04:15:35 +00:00
|
|
|
#[derive(Clone, Debug, PartialEq)]
|
2021-01-18 06:46:18 +00:00
|
|
|
pub struct Font<'a> {
|
2017-02-21 00:40:53 +00:00
|
|
|
pub version: u8,
|
2017-02-11 01:57:25 +00:00
|
|
|
pub id: CharacterId,
|
2021-01-20 20:46:22 +00:00
|
|
|
pub name: &'a SwfStr,
|
2017-02-21 00:40:53 +00:00
|
|
|
pub language: Language,
|
|
|
|
pub layout: Option<FontLayout>,
|
2017-02-11 01:57:25 +00:00
|
|
|
pub glyphs: Vec<Glyph>,
|
2017-02-21 00:40:53 +00:00
|
|
|
pub is_small_text: bool,
|
|
|
|
pub is_shift_jis: bool, // TODO(Herschel): Use enum for Shift-JIS/ANSI/UCS-2
|
|
|
|
pub is_ansi: bool,
|
|
|
|
pub is_bold: bool,
|
|
|
|
pub is_italic: bool,
|
|
|
|
}
|
|
|
|
|
2017-02-21 23:22:59 +00:00
|
|
|
#[derive(Clone, Debug, PartialEq)]
|
2021-01-18 06:46:18 +00:00
|
|
|
pub struct Font4<'a> {
|
2017-02-21 23:22:59 +00:00
|
|
|
pub id: CharacterId,
|
|
|
|
pub is_italic: bool,
|
|
|
|
pub is_bold: bool,
|
2021-01-20 20:46:22 +00:00
|
|
|
pub name: &'a SwfStr,
|
2021-01-18 06:46:18 +00:00
|
|
|
pub data: Option<&'a [u8]>,
|
2017-02-21 23:22:59 +00:00
|
|
|
}
|
|
|
|
|
2017-02-21 00:40:53 +00:00
|
|
|
#[derive(Clone, Debug, PartialEq)]
|
|
|
|
pub struct Glyph {
|
|
|
|
pub shape_records: Vec<ShapeRecord>,
|
|
|
|
pub code: u16,
|
|
|
|
pub advance: Option<i16>,
|
|
|
|
pub bounds: Option<Rectangle>,
|
|
|
|
}
|
|
|
|
|
|
|
|
#[derive(Clone, Debug, Eq, PartialEq)]
|
|
|
|
pub struct FontLayout {
|
|
|
|
pub ascent: u16,
|
|
|
|
pub descent: u16,
|
|
|
|
pub leading: i16,
|
|
|
|
pub kerning: Vec<KerningRecord>,
|
|
|
|
}
|
|
|
|
|
|
|
|
#[derive(Clone, Debug, Eq, PartialEq)]
|
|
|
|
pub struct KerningRecord {
|
|
|
|
pub left_code: u16,
|
|
|
|
pub right_code: u16,
|
2019-05-17 04:32:18 +00:00
|
|
|
pub adjustment: Twips,
|
2017-02-11 01:57:25 +00:00
|
|
|
}
|
|
|
|
|
2017-02-13 04:22:22 +00:00
|
|
|
#[derive(Clone, Debug, PartialEq)]
|
2021-01-18 06:46:18 +00:00
|
|
|
pub struct FontInfo<'a> {
|
2017-02-13 04:22:22 +00:00
|
|
|
pub id: CharacterId,
|
2017-02-17 04:15:35 +00:00
|
|
|
pub version: u8,
|
2021-01-20 20:46:22 +00:00
|
|
|
pub name: &'a SwfStr,
|
2017-02-13 04:22:22 +00:00
|
|
|
pub is_small_text: bool,
|
|
|
|
pub is_shift_jis: bool,
|
|
|
|
pub is_ansi: bool,
|
|
|
|
pub is_bold: bool,
|
|
|
|
pub is_italic: bool,
|
2017-02-17 04:15:35 +00:00
|
|
|
pub language: Language,
|
2017-02-13 04:22:22 +00:00
|
|
|
pub code_table: Vec<u16>,
|
|
|
|
}
|
|
|
|
|
2017-02-16 03:07:08 +00:00
|
|
|
#[derive(Clone, Debug, PartialEq)]
|
|
|
|
pub struct Text {
|
|
|
|
pub id: CharacterId,
|
|
|
|
pub bounds: Rectangle,
|
|
|
|
pub matrix: Matrix,
|
|
|
|
pub records: Vec<TextRecord>,
|
|
|
|
}
|
|
|
|
|
|
|
|
#[derive(Clone, Debug, PartialEq)]
|
|
|
|
pub struct TextRecord {
|
|
|
|
pub font_id: Option<CharacterId>,
|
|
|
|
pub color: Option<Color>,
|
2019-05-17 04:32:18 +00:00
|
|
|
pub x_offset: Option<Twips>,
|
|
|
|
pub y_offset: Option<Twips>,
|
2020-01-20 02:31:22 +00:00
|
|
|
pub height: Option<Twips>,
|
2017-02-16 03:07:08 +00:00
|
|
|
pub glyphs: Vec<GlyphEntry>,
|
|
|
|
}
|
|
|
|
|
|
|
|
#[derive(Clone, Debug, PartialEq)]
|
|
|
|
pub struct GlyphEntry {
|
|
|
|
pub index: u32,
|
|
|
|
pub advance: i32,
|
|
|
|
}
|
2017-02-16 05:16:47 +00:00
|
|
|
|
2017-02-16 21:42:19 +00:00
|
|
|
#[derive(Clone, Debug, PartialEq)]
|
2021-01-18 06:46:18 +00:00
|
|
|
pub struct EditText<'a> {
|
2017-02-16 21:42:19 +00:00
|
|
|
pub id: CharacterId,
|
|
|
|
pub bounds: Rectangle,
|
|
|
|
pub font_id: Option<CharacterId>, // TODO(Herschel): Combine with height
|
2021-01-20 20:46:22 +00:00
|
|
|
pub font_class_name: Option<&'a SwfStr>,
|
2020-01-20 01:52:59 +00:00
|
|
|
pub height: Option<Twips>,
|
2017-02-16 21:42:19 +00:00
|
|
|
pub color: Option<Color>,
|
|
|
|
pub max_length: Option<u16>,
|
|
|
|
pub layout: Option<TextLayout>,
|
2021-01-20 20:46:22 +00:00
|
|
|
pub variable_name: &'a SwfStr,
|
|
|
|
pub initial_text: Option<&'a SwfStr>,
|
2017-02-16 21:42:19 +00:00
|
|
|
pub is_word_wrap: bool,
|
|
|
|
pub is_multiline: bool,
|
|
|
|
pub is_password: bool,
|
|
|
|
pub is_read_only: bool,
|
|
|
|
pub is_auto_size: bool,
|
|
|
|
pub is_selectable: bool,
|
|
|
|
pub has_border: bool,
|
|
|
|
pub was_static: bool,
|
|
|
|
pub is_html: bool,
|
|
|
|
pub is_device_font: bool,
|
|
|
|
}
|
|
|
|
|
|
|
|
#[derive(Clone, Debug, PartialEq)]
|
|
|
|
pub struct TextLayout {
|
|
|
|
pub align: TextAlign,
|
2019-05-17 04:32:18 +00:00
|
|
|
pub left_margin: Twips,
|
|
|
|
pub right_margin: Twips,
|
|
|
|
pub indent: Twips,
|
|
|
|
pub leading: Twips,
|
2017-02-16 21:42:19 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
#[derive(Clone, Copy, Debug, PartialEq, Eq)]
|
|
|
|
pub enum TextAlign {
|
|
|
|
Left,
|
|
|
|
Center,
|
|
|
|
Right,
|
|
|
|
Justify,
|
|
|
|
}
|
|
|
|
|
2017-02-21 04:23:12 +00:00
|
|
|
#[derive(Clone, Debug, PartialEq)]
|
|
|
|
pub struct FontAlignZone {
|
|
|
|
// TODO(Herschel): Read these as f16s.
|
|
|
|
pub left: i16,
|
|
|
|
pub width: i16,
|
|
|
|
pub bottom: i16,
|
|
|
|
pub height: i16,
|
|
|
|
}
|
|
|
|
|
|
|
|
#[derive(Clone, Copy, Debug, PartialEq, Eq)]
|
|
|
|
pub enum FontThickness {
|
|
|
|
Thin,
|
|
|
|
Medium,
|
2017-06-24 19:56:49 +00:00
|
|
|
Thick,
|
2017-02-21 04:23:12 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
#[derive(Clone, Debug, PartialEq)]
|
|
|
|
pub struct CsmTextSettings {
|
|
|
|
pub id: CharacterId,
|
|
|
|
pub use_advanced_rendering: bool,
|
|
|
|
pub grid_fit: TextGridFit,
|
|
|
|
pub thickness: f32, // TODO(Herschel): 0.0 is default. Should be Option?
|
|
|
|
pub sharpness: f32,
|
|
|
|
}
|
|
|
|
|
|
|
|
#[derive(Clone, Copy, Debug, PartialEq, Eq)]
|
|
|
|
pub enum TextGridFit {
|
|
|
|
None,
|
|
|
|
Pixel,
|
|
|
|
SubPixel,
|
|
|
|
}
|
|
|
|
|
2017-02-16 05:16:47 +00:00
|
|
|
#[derive(Clone, Debug, PartialEq)]
|
2021-01-18 06:46:18 +00:00
|
|
|
pub struct DefineBitsLossless<'a> {
|
2017-02-25 03:32:35 +00:00
|
|
|
pub version: u8,
|
2017-02-16 05:16:47 +00:00
|
|
|
pub id: CharacterId,
|
|
|
|
pub format: BitmapFormat,
|
|
|
|
pub width: u16,
|
|
|
|
pub height: u16,
|
|
|
|
pub num_colors: u8,
|
2021-01-18 06:46:18 +00:00
|
|
|
pub data: &'a [u8],
|
2017-02-16 05:16:47 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
#[derive(Clone, Copy, Debug, PartialEq, Eq)]
|
|
|
|
pub enum BitmapFormat {
|
|
|
|
ColorMap8,
|
|
|
|
Rgb15,
|
2017-02-25 03:32:35 +00:00
|
|
|
Rgb32,
|
2017-02-16 05:16:47 +00:00
|
|
|
}
|
2017-02-23 03:53:56 +00:00
|
|
|
|
|
|
|
#[derive(Clone, Debug, PartialEq)]
|
|
|
|
pub struct DefineVideoStream {
|
|
|
|
pub id: CharacterId,
|
|
|
|
pub num_frames: u16,
|
|
|
|
pub width: u16,
|
|
|
|
pub height: u16,
|
|
|
|
pub is_smoothed: bool,
|
|
|
|
pub deblocking: VideoDeblocking,
|
|
|
|
pub codec: VideoCodec,
|
|
|
|
}
|
|
|
|
|
|
|
|
#[derive(Clone, Copy, Debug, PartialEq, Eq)]
|
|
|
|
pub enum VideoDeblocking {
|
|
|
|
UseVideoPacketValue,
|
|
|
|
None,
|
|
|
|
Level1,
|
|
|
|
Level2,
|
|
|
|
Level3,
|
|
|
|
Level4,
|
|
|
|
}
|
|
|
|
|
|
|
|
#[derive(Clone, Copy, Debug, PartialEq, Eq)]
|
|
|
|
pub enum VideoCodec {
|
|
|
|
H263,
|
|
|
|
ScreenVideo,
|
2021-02-12 13:03:17 +00:00
|
|
|
Vp6,
|
|
|
|
Vp6WithAlpha,
|
2021-02-11 19:35:17 +00:00
|
|
|
ScreenVideoV2,
|
2017-02-23 03:53:56 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
#[derive(Clone, Debug, PartialEq)]
|
2021-01-18 06:46:18 +00:00
|
|
|
pub struct VideoFrame<'a> {
|
2017-02-23 03:53:56 +00:00
|
|
|
pub stream_id: CharacterId,
|
|
|
|
pub frame_num: u16,
|
2021-01-18 06:46:18 +00:00
|
|
|
pub data: &'a [u8],
|
2017-02-23 03:53:56 +00:00
|
|
|
}
|
2017-02-25 03:32:35 +00:00
|
|
|
|
|
|
|
#[derive(Clone, Debug, PartialEq)]
|
2021-01-18 06:46:18 +00:00
|
|
|
pub struct DefineBitsJpeg3<'a> {
|
2017-02-25 03:32:35 +00:00
|
|
|
pub id: CharacterId,
|
|
|
|
pub version: u8,
|
2021-05-30 20:30:06 +00:00
|
|
|
pub deblocking: Fixed8,
|
2021-01-18 06:46:18 +00:00
|
|
|
pub data: &'a [u8],
|
|
|
|
pub alpha_data: &'a [u8],
|
2017-02-25 03:32:35 +00:00
|
|
|
}
|
2017-08-26 08:18:51 +00:00
|
|
|
|
|
|
|
#[derive(Clone, Debug, PartialEq)]
|
2021-01-18 06:46:18 +00:00
|
|
|
pub struct DoAbc<'a> {
|
2021-01-20 20:46:22 +00:00
|
|
|
pub name: &'a SwfStr,
|
2017-08-26 08:18:51 +00:00
|
|
|
pub is_lazy_initialize: bool,
|
2021-01-18 06:46:18 +00:00
|
|
|
pub data: &'a [u8],
|
2017-08-26 08:18:51 +00:00
|
|
|
}
|
2019-07-23 01:29:39 +00:00
|
|
|
|
2021-01-18 06:46:18 +00:00
|
|
|
pub type DoAction<'a> = &'a [u8];
|
2019-07-23 01:29:39 +00:00
|
|
|
|
2021-01-18 06:46:18 +00:00
|
|
|
pub type JpegTables<'a> = &'a [u8];
|
2019-08-16 16:50:54 +00:00
|
|
|
|
|
|
|
/// `ProductInfo` contains information about the software used to generate the SWF.
|
2019-08-16 16:56:49 +00:00
|
|
|
/// Not documented in the SWF19 reference. Emitted by mxmlc.
|
2019-08-16 16:50:54 +00:00
|
|
|
/// See http://wahlers.com.br/claus/blog/undocumented-swf-tags-written-by-mxmlc/
|
|
|
|
#[derive(Clone, Debug, PartialEq, Eq)]
|
|
|
|
pub struct ProductInfo {
|
|
|
|
pub product_id: u32,
|
|
|
|
pub edition: u32,
|
|
|
|
pub major_version: u8,
|
|
|
|
pub minor_version: u8,
|
|
|
|
pub build_number: u64,
|
|
|
|
pub compilation_date: u64,
|
|
|
|
}
|
2019-08-16 16:56:49 +00:00
|
|
|
|
|
|
|
/// `DebugId` is a UUID written to debug SWFs and used by the Flash Debugger.
|
|
|
|
pub type DebugId = [u8; 16];
|