swf: Use bitflags for `LineStyleFlag`
This commit is contained in:
parent
e88c7102f5
commit
fd06fa0537
|
@ -1367,24 +1367,25 @@ impl<'a> Reader<'a> {
|
|||
))
|
||||
} else {
|
||||
// MorphLineStyle2 in DefineMorphShape2.
|
||||
let flags0 = self.read_u8()?;
|
||||
let flags1 = self.read_u8()?;
|
||||
let start_cap = LineCapStyle::from_u8(flags0 >> 6)
|
||||
.ok_or_else(|| Error::invalid_data("Invalid line cap type."))?;
|
||||
let join_style_id = (flags0 >> 4) & 0b11;
|
||||
let has_fill = (flags0 & 0b1000) != 0;
|
||||
let allow_scale_x = (flags0 & 0b100) == 0;
|
||||
let allow_scale_y = (flags0 & 0b10) == 0;
|
||||
let is_pixel_hinted = (flags0 & 0b1) != 0;
|
||||
let allow_close = (flags1 & 0b100) == 0;
|
||||
let end_cap = LineCapStyle::from_u8(flags1 & 0b11)
|
||||
.ok_or_else(|| Error::invalid_data("Invalid line cap type."))?;
|
||||
let join_style = match join_style_id {
|
||||
0 => LineJoinStyle::Round,
|
||||
1 => LineJoinStyle::Bevel,
|
||||
2 => LineJoinStyle::Miter(self.read_fixed8()?),
|
||||
let flags = LineStyleFlag::from_bits_truncate(self.read_u16()?);
|
||||
let is_pixel_hinted = flags.contains(LineStyleFlag::PIXEL_HINTING);
|
||||
let allow_scale_y = !flags.contains(LineStyleFlag::NO_V_SCALE);
|
||||
let allow_scale_x = !flags.contains(LineStyleFlag::NO_H_SCALE);
|
||||
let has_fill = flags.contains(LineStyleFlag::HAS_FILL);
|
||||
let join_style = match flags & LineStyleFlag::JOIN_STYLE {
|
||||
LineStyleFlag::ROUND => LineJoinStyle::Round,
|
||||
LineStyleFlag::BEVEL => LineJoinStyle::Bevel,
|
||||
LineStyleFlag::MITER => LineJoinStyle::Miter(self.read_fixed8()?),
|
||||
_ => return Err(Error::invalid_data("Invalid line cap type.")),
|
||||
};
|
||||
let start_cap =
|
||||
LineCapStyle::from_u8(((flags & LineStyleFlag::START_CAP_STYLE).bits() >> 6) as u8)
|
||||
.ok_or_else(|| Error::invalid_data("Invalid line cap type."))?;
|
||||
let end_cap =
|
||||
LineCapStyle::from_u8(((flags & LineStyleFlag::END_CAP_STYLE).bits() >> 8) as u8)
|
||||
.ok_or_else(|| Error::invalid_data("Invalid line cap type."))?;
|
||||
let allow_close = !flags.contains(LineStyleFlag::ALLOW_CLOSE);
|
||||
|
||||
let (start_color, end_color) = if !has_fill {
|
||||
(self.read_rgba()?, self.read_rgba()?)
|
||||
} else {
|
||||
|
@ -1681,37 +1682,36 @@ impl<'a> Reader<'a> {
|
|||
}
|
||||
|
||||
fn read_line_style(&mut self, shape_version: u8) -> Result<LineStyle> {
|
||||
let width = Twips::new(self.read_u16()?);
|
||||
if shape_version < 4 {
|
||||
// LineStyle1
|
||||
Ok(LineStyle::new_v1(
|
||||
Twips::new(self.read_u16()?),
|
||||
if shape_version >= 3 {
|
||||
let color = if shape_version >= 3 {
|
||||
self.read_rgba()?
|
||||
} else {
|
||||
self.read_rgb()?
|
||||
},
|
||||
))
|
||||
};
|
||||
Ok(LineStyle::new_v1(width, color))
|
||||
} else {
|
||||
// LineStyle2 in DefineShape4
|
||||
let width = Twips::new(self.read_u16()?);
|
||||
let flags0 = self.read_u8()?;
|
||||
let flags1 = self.read_u8()?;
|
||||
let start_cap = LineCapStyle::from_u8(flags0 >> 6)
|
||||
.ok_or_else(|| Error::invalid_data("Invalid line cap type."))?;
|
||||
let join_style_id = (flags0 >> 4) & 0b11;
|
||||
let has_fill = (flags0 & 0b1000) != 0;
|
||||
let allow_scale_x = (flags0 & 0b100) == 0;
|
||||
let allow_scale_y = (flags0 & 0b10) == 0;
|
||||
let is_pixel_hinted = (flags0 & 0b1) != 0;
|
||||
let allow_close = (flags1 & 0b100) == 0;
|
||||
let end_cap = LineCapStyle::from_u8(flags1 & 0b11)
|
||||
.ok_or_else(|| Error::invalid_data("Invalid line cap type."))?;
|
||||
let join_style = match join_style_id {
|
||||
0 => LineJoinStyle::Round,
|
||||
1 => LineJoinStyle::Bevel,
|
||||
2 => LineJoinStyle::Miter(self.read_fixed8()?),
|
||||
let flags = LineStyleFlag::from_bits_truncate(self.read_u16()?);
|
||||
let is_pixel_hinted = flags.contains(LineStyleFlag::PIXEL_HINTING);
|
||||
let allow_scale_y = !flags.contains(LineStyleFlag::NO_V_SCALE);
|
||||
let allow_scale_x = !flags.contains(LineStyleFlag::NO_H_SCALE);
|
||||
let has_fill = flags.contains(LineStyleFlag::HAS_FILL);
|
||||
let join_style = match flags & LineStyleFlag::JOIN_STYLE {
|
||||
LineStyleFlag::ROUND => LineJoinStyle::Round,
|
||||
LineStyleFlag::BEVEL => LineJoinStyle::Bevel,
|
||||
LineStyleFlag::MITER => LineJoinStyle::Miter(self.read_fixed8()?),
|
||||
_ => return Err(Error::invalid_data("Invalid line cap type.")),
|
||||
};
|
||||
let start_cap =
|
||||
LineCapStyle::from_u8(((flags & LineStyleFlag::START_CAP_STYLE).bits() >> 6) as u8)
|
||||
.ok_or_else(|| Error::invalid_data("Invalid line cap type."))?;
|
||||
let end_cap =
|
||||
LineCapStyle::from_u8(((flags & LineStyleFlag::END_CAP_STYLE).bits() >> 8) as u8)
|
||||
.ok_or_else(|| Error::invalid_data("Invalid line cap type."))?;
|
||||
let allow_close = !flags.contains(LineStyleFlag::ALLOW_CLOSE);
|
||||
|
||||
let color = if !has_fill {
|
||||
self.read_rgba()?
|
||||
} else {
|
||||
|
|
|
@ -1145,6 +1145,27 @@ impl LineStyle {
|
|||
}
|
||||
}
|
||||
|
||||
bitflags! {
|
||||
pub struct LineStyleFlag: u16 {
|
||||
// First byte.
|
||||
const PIXEL_HINTING = 1 << 0;
|
||||
const NO_V_SCALE = 1 << 1;
|
||||
const NO_H_SCALE = 1 << 2;
|
||||
const HAS_FILL = 1 << 3;
|
||||
const JOIN_STYLE = 0b11 << 4;
|
||||
const START_CAP_STYLE = 0b11 << 6;
|
||||
|
||||
// Second byte.
|
||||
const END_CAP_STYLE = 0b11 << 8;
|
||||
const ALLOW_CLOSE = 1 << 10;
|
||||
|
||||
// JOIN_STYLE mask values.
|
||||
const ROUND = 0b00 << 4;
|
||||
const BEVEL = 0b01 << 4;
|
||||
const MITER = 0b10 << 4;
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, PartialEq, Clone, Copy, FromPrimitive)]
|
||||
pub enum LineCapStyle {
|
||||
Round = 0,
|
||||
|
|
|
@ -1622,25 +1622,22 @@ impl<W: Write> Writer<W> {
|
|||
// TODO(Herschel): Handle overflow.
|
||||
self.write_u16(line_style.width.get() as u16)?;
|
||||
if shape_version >= 4 {
|
||||
let mut bits = self.bits();
|
||||
// LineStyle2
|
||||
bits.write_ubits(2, line_style.start_cap as u32)?;
|
||||
bits.write_ubits(
|
||||
2,
|
||||
match line_style.join_style {
|
||||
LineJoinStyle::Round => 0,
|
||||
LineJoinStyle::Bevel => 1,
|
||||
LineJoinStyle::Miter(_) => 2,
|
||||
},
|
||||
)?;
|
||||
bits.write_bit(line_style.fill_style.is_some())?;
|
||||
bits.write_bit(!line_style.allow_scale_x)?;
|
||||
bits.write_bit(!line_style.allow_scale_y)?;
|
||||
bits.write_bit(line_style.is_pixel_hinted)?;
|
||||
bits.write_ubits(5, 0)?;
|
||||
bits.write_bit(!line_style.allow_close)?;
|
||||
bits.write_ubits(2, line_style.end_cap as u32)?;
|
||||
drop(bits);
|
||||
let mut flags = LineStyleFlag::empty();
|
||||
flags.set(LineStyleFlag::PIXEL_HINTING, line_style.is_pixel_hinted);
|
||||
flags.set(LineStyleFlag::NO_V_SCALE, !line_style.allow_scale_y);
|
||||
flags.set(LineStyleFlag::NO_H_SCALE, !line_style.allow_scale_x);
|
||||
flags.set(LineStyleFlag::HAS_FILL, line_style.fill_style.is_some());
|
||||
flags |= match line_style.join_style {
|
||||
LineJoinStyle::Round => LineStyleFlag::ROUND,
|
||||
LineJoinStyle::Bevel => LineStyleFlag::BEVEL,
|
||||
LineJoinStyle::Miter(_) => LineStyleFlag::MITER,
|
||||
};
|
||||
let mut flags = flags.bits();
|
||||
flags |= (line_style.start_cap as u16) << 6;
|
||||
flags |= (line_style.end_cap as u16) << 8;
|
||||
self.write_u16(flags)?;
|
||||
|
||||
if let LineJoinStyle::Miter(miter_factor) = line_style.join_style {
|
||||
self.write_fixed8(miter_factor)?;
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue