our
$VERSION
=
"0.01"
;
{
sub
new {
my
$class
=
shift
;
my
$self
=
bless
{
_current_line_width
=> 1,
_current_X
=> 0,
_current_Y
=> 0,
_edges
=> SWF::Element::SHAPE->ShapeRecords->new,
_bounds
=> SWF::Builder::ExElement::BoundaryRect->new,
},
$class
;
}
sub
_set_bounds {
my
(
$self
,
$x
,
$y
) =
@_
;
my
$cw
=
$self
->{_current_line_width} / 2;
$self
->{_bounds}->set_boundary(
$x
-
$cw
,
$y
-
$cw
,
$x
+
$cw
,
$y
+
$cw
);
}
sub
_get_stylerecord {
my
$self
=
shift
;
my
$edges
=
$self
->{_edges};
my
$r
;
if
(
ref
(
$edges
->[-1])=~/STYLECHANGERECORD$/) {
$r
=
$edges
->[-1];
}
else
{
$r
=
$edges
->new_element;
push
@$edges
,
$r
;
}
return
$r
;
}
sub
r_lineto {
my
$self
=
shift
;
my
$edges
=
$self
->{_edges};
while
(
my
(
$dx
,
$dy
) =
splice
(
@_
, 0, 2)) {
push
@$edges
,
$edges
->new_element(
DeltaX
=>
$dx
*20,
DeltaY
=>
$dy
*20 );
$dx
= (
$self
->{_current_X} +=
$dx
);
$dy
= (
$self
->{_current_Y} +=
$dy
);
$self
->_set_bounds(
$dx
,
$dy
);
}
$self
;
}
sub
lineto {
my
$self
=
shift
;
my
$edges
=
$self
->{_edges};
while
(
my
(
$x
,
$y
) =
splice
(
@_
, 0, 2)) {
push
@$edges
,
$edges
->new_element(
DeltaX
=> (
$x
-
$self
->{_current_X})*20,
DeltaY
=> (
$y
-
$self
->{_current_Y})*20 );
$self
->{_current_X} =
$x
;
$self
->{_current_Y} =
$y
;
$self
->_set_bounds(
$x
,
$y
);
}
$self
;
}
sub
r_curveto {
my
$self
=
shift
;
my
$edges
=
$self
->{_edges};
while
(
my
(
$cdx
,
$cdy
,
$adx
,
$ady
) =
splice
(
@_
, 0, 4)) {
my
$curx
=
$self
->{_current_X};
my
$cury
=
$self
->{_current_Y};
push
@$edges
,
$edges
->new_element
(
ControlDeltaX
=>
$cdx
*20,
ControlDeltaY
=>
$cdy
*20,
AnchorDeltaX
=>
$adx
*20,
AnchorDeltaY
=>
$ady
*20,
);
$adx
= (
$self
->{_current_X} +=
$cdx
+
$adx
);
$ady
= (
$self
->{_current_Y} +=
$cdy
+
$ady
);
$self
->_set_bounds(
$adx
,
$ady
);
$self
->_set_bounds(
$curx
+
$cdx
,
$cury
+
$cdy
);
}
$self
;
}
sub
curveto {
my
$self
=
shift
;
my
$edges
=
$self
->{_edges};
while
(
my
(
$cx
,
$cy
,
$ax
,
$ay
) =
splice
(
@_
, 0, 4)) {
my
$curx
=
$self
->{_current_X};
my
$cury
=
$self
->{_current_Y};
push
@$edges
,
$edges
->new_element
(
ControlDeltaX
=> (
$cx
-
$curx
)*20,
ControlDeltaY
=> (
$cy
-
$cury
)*20,
AnchorDeltaX
=> (
$ax
-
$cx
)*20,
AnchorDeltaY
=> (
$ay
-
$cy
)*20,
);
$self
->{_current_X} =
$ax
;
$self
->{_current_Y} =
$ay
;
$self
->_set_bounds(
$ax
,
$ay
);
$self
->_set_bounds(
$cx
,
$cy
);
}
$self
;
}
sub
moveto {
my
(
$self
,
$x
,
$y
)=
@_
;
my
$r
=
$self
->_get_stylerecord;
$r
->MoveDeltaX(
$x
*20);
$r
->MoveDeltaY(
$y
*20);
$self
->{_current_X} =
$x
;
$self
->{_current_Y} =
$y
;
$self
->_set_bounds(
$x
,
$y
);
$self
;
}
sub
r_moveto {
my
(
$self
,
$dx
,
$dy
)=
@_
;
my
$r
=
$self
->_get_stylerecord;
$dx
= (
$self
->{_current_X} +=
$dx
);
$dy
= (
$self
->{_current_Y} +=
$dy
);
$r
->MoveDeltaX(
$dx
*20);
$r
->MoveDeltaY(
$dy
*20);
$self
->_set_bounds(
$dx
,
$dy
);
$self
;
}
sub
box {
my
(
$self
,
$x1
,
$y1
,
$x2
,
$y2
) =
@_
;
$self
->moveto(
$x1
,
$y1
)
->lineto(
$x2
,
$y1
)
->lineto(
$x2
,
$y2
)
->lineto(
$x1
,
$y2
)
->lineto(
$x1
,
$y1
);
}
my
%style
= (
'none'
=> 0,
'fill'
=> 1,
'draw'
=> 1);
sub
fillstyle {
my
(
$self
,
$f
) =
@_
;
my
$r
=
$self
->_get_stylerecord;
my
$index
;
if
(
exists
$style
{
$f
}) {
$index
=
$style
{
$f
};
}
else
{
$index
=
$f
;
}
$r
->FillStyle0(
$index
);
$self
;
}
*fillstyle0
= \
&fillstyle
;
sub
fillstyle1 {
my
(
$self
,
$f
) =
@_
;
my
$r
=
$self
->_get_stylerecord;
my
$index
;
if
(
exists
$style
{
$f
}) {
$index
=
$style
{
$f
};
}
else
{
$index
=
$f
;
}
$r
->FillStyle1(
$index
);
$self
;
}
sub
linestyle {
my
(
$self
,
$f
) =
@_
;
my
$r
=
$self
->_get_stylerecord;
my
$index
;
if
(
exists
$style
{
$f
}) {
$index
=
$style
{
$f
};
}
else
{
$index
=
$f
;
}
$r
->LineStyle(
$index
);
$self
;
}
}
{
@SWF::Builder::Shape::DefineShape::ISA
=
qw/ SWF::Builder::Shape SWF::Builder::Character::Displayable SWF::Builder::ExElement::Color::AddColor /
;
sub
new {
my
$self
=
shift
->SUPER::new;
$self
->SWF::Builder::Character::Displayable::_init;
$self
->SWF::Builder::ExElement::Color::AddColor::_init;
$self
->{_edges} = SWF::Element::SHAPEWITHSTYLE3->ShapeRecords->new;
$self
->{_current_line_width} = -1;
$self
->{_current_line_color} =
undef
;
$self
->{_current_fill_style} =
''
;
$self
->{_line_styles} =
$self
->{_shape_line_styles} = SWF::Element::SHAPEWITHSTYLE3->LineStyles->new;
$self
->{_line_style_hash} = {};
$self
->{_fill_styles} =
$self
->{_shape_fill_styles} = SWF::Element::SHAPEWITHSTYLE3->FillStyles->new;
$self
->{_fill_style_hash} = {};
$self
;
}
sub
_add_gradient {
my
(
$self
,
$gradient
) =
@_
;
$self
->{_is_alpha}->configure(
$self
->{_is_alpha}->value |
$gradient
->{_is_alpha}->value);
return
bless
{
_is_alpha
=>
$self
->{_is_alpha},
_gradient
=>
$gradient
,
},
'SWF::Builder::Shape::Gradient'
;
}
sub
linestyle {
my
$self
=
shift
;
my
(
$r
,
$index
,
$width
,
$color
);
$r
=
$self
->_get_stylerecord;
if
(
$_
[0] eq
'none'
or
$_
[0] eq 0) {
$index
= 0;
$width
= -1;
$color
=
undef
;
}
else
{
my
%param
;
if
(
$_
[0] eq
'Width'
or
$_
[0] eq
'Color'
) {
%param
=
@_
;
}
else
{
%param
= (
Width
=>
$_
[0],
Color
=>
$_
[1]);
}
$width
=
$param
{Width};
$width
=
$self
->{_current_line_width}
unless
defined
$width
;
if
(
defined
$param
{Color}) {
$color
=
$self
->_add_color(
$param
{Color});
}
else
{
$color
=
$self
->{_current_line_color};
}
return
$self
if
(
$width
==
$self
->{_current_line_width} and
$color
eq
$self
->{_current_line_color});
if
(
exists
$self
->{_line_style_hash}{
"$width:$color"
}) {
$index
=
$self
->{_line_style_hash}{
"$width:$color"
};
}
else
{
if
(@{
$self
->{_line_styles}} >= 65534) {
$self
->{_line_styles} =
$r
->LineStyles;
$self
->{_line_style_hash} = {};
$self
->{_fill_styles} =
$r
->FillStyles;
$self
->{_fill_style_hash} = {};
}
my
$ls
=
$self
->{_line_styles};
push
@$ls
,
$ls
->new_element(
Width
=>
$width
*20,
Color
=>
$color
);
$index
=
$self
->{_line_style_hash}{
"$width:$color"
} =
@$ls
;
}
}
$r
->LineStyle(
$index
);
$self
->{_current_line_width} =
$width
;
$self
->{_current_line_color} =
$color
;
$self
;
}
sub
_fillstyle {
my
$self
=
shift
;
my
$setstyle
=
shift
;
my
(
$r
,
$index
,
$fillkey
);
$r
=
$self
->_get_stylerecord;
if
(
$_
[0] eq
'none'
or
$_
[0] eq 0) {
$index
= 0;
return
unless
$self
->{_current_fill_style};
$fillkey
=
''
;
}
else
{
my
%param
;
if
(
$_
[0] eq
'Color'
or
$_
[0] eq
'Gradient'
or
$_
[0] eq
'Bitmap'
) {
%param
=
@_
;
}
else
{
for
(
ref
(
$_
[0])) {
/Gradient/ and
do
{
%param
= (
Gradient
=>
$_
[0],
Type
=>
$_
[1],
Matrix
=>
$_
[2]);
last
;
};
/Bitmap/ and
do
{
%param
= (
Bitmap
=>
$_
[0],
Type
=>
$_
[1],
Matrix
=>
$_
[2]);
last
;
};
%param
= (
Color
=>
$_
[0]);
}
}
my
@param2
;
$fillkey
=
join
(
','
,
%param
);
if
(
exists
$param
{Gradient}) {
push
@param2
,
Gradient
=>
$self
->_add_gradient(
$param
{Gradient}),
FillStyleType
=>
(
lc
(
$param
{Type}) eq
'radial'
? 0x12 : 0x10),
GradientMatrix
=>
$param
{Matrix};
}
elsif
(
exists
$param
{Bitmap}) {
push
@param2
,
BitmapID
=>
$param
{Bitmap}->{ID},
FillStyleType
=>
(
lc
(
$param
{Type}) =~ /^clip(ped)?$/ ? 0x41 : 0x40),
BitmapMatrix
=>
$param
{Matrix};
$self
->{_is_alpha}->configure(
$self
->{_is_alpha} |
$param
{Bitmap}{_is_alpha});
$self
->_depends(
$param
{Bitmap});
}
else
{
push
@param2
,
Color
=>
$self
->_add_color(
$param
{Color}),
FillStyleType
=> 0x00;
}
return
$self
if
$self
->{_current_fill_style} eq
$fillkey
;
if
(
exists
$self
->{_fill_style_hash}{
$fillkey
}) {
$index
=
$self
->{_fill_style_hash}{
$fillkey
};
}
else
{
if
(@{
$self
->{_fill_styles}} >= 65534) {
$self
->{_line_styles} =
$r
->LineStyles;
$self
->{_line_style_hash} = {};
$self
->{_fill_styles} =
$r
->FillStyles;
$self
->{_fill_style_hash} = {};
}
my
$fs
=
$self
->{_fill_styles};
push
@$fs
,
$fs
->new_element(
@param2
);
$index
=
$self
->{_fill_style_hash}{
$fillkey
} =
@$fs
;
}
}
$r
->
$setstyle
(
$index
);
$self
->{_current_fill_style} =
$fillkey
;
$self
;
}
sub
fillstyle {
my
$self
=
shift
;
_fillstyle(
$self
,
'FillStyle0'
,
@_
);
}
*fillstyle0
= \
&fillstyle
;
sub
fillstyle1 {
my
$self
=
shift
;
_fillstyle(
$self
,
'FillStyle1'
,
@_
);
}
sub
get_bbox {
return
@{
shift
->{_bounds}};
}
sub
pack
{
my
(
$self
,
$stream
) =
@_
;
$self
->prepare_to_pack(
$stream
) or
return
;
my
$tag
= (
$self
->{_is_alpha} ? SWF::Element::Tag::DefineShape3->new : SWF::Element::Tag::DefineShape2->new);
$tag
->ShapeID(
$self
->{ID});
$tag
->ShapeBounds(
$self
->{_bounds});
$tag
->Shapes
(
FillStyles
=>
$self
->{_shape_fill_styles},
LineStyles
=>
$self
->{_shape_line_styles},
ShapeRecords
=>
$self
->{_edges},
);
$tag
->
pack
(
$stream
);
}
}
{
@SWF::Builder::Shape::Gradient::ISA
= (
'SWF::Element::Array::GRADIENT3'
);
sub
pack
{
my
(
$self
,
$stream
) =
@_
;
my
$g
=
$self
->{_gradient};
my
$a
=
$g
->{_is_alpha}->value;
$g
->{_is_alpha}->configure(
$self
->{_is_alpha});
$g
->
pack
(
$stream
);
$g
->{_is_alpha}->configure(
$a
);
}
}
1;