1use strict;
2use warnings;
3
4use Test::More;
5use Prima::sys::Test qw(noX11);
6
7sub bytes { unpack('H*', shift ) }
8
9sub is_bytes
10{
11	my ( $bytes_actual, $bytes_expected, $name ) = @_;
12	my $ok = $bytes_actual eq $bytes_expected;
13	ok( $ok, $name );
14	warn "#   bytes(" . bytes($bytes_actual) . " (actual)\n#   " . bytes($bytes_expected) . " (expected)\n" unless $ok;
15#	exit unless $ok;
16}
17
18my $i = Prima::Image->create(
19	width    => 2,
20	height   => 4,
21	type     => im::Byte,
22	data     => "12345678",
23	lineSize => 2,
24);
25
26my $j = $i->dup;
27$j->rotate(90);
28is( $j->width, 4, "rotate(90) width ok");
29is( $j->height, 2, "rotate(90) height ok");
30is($j->data, "75318642", "rotate(90) data ok");
31
32$j = $i->dup;
33$j->rotate(270);
34is( $j->width, 4, "rotate(270) width ok");
35is( $j->height, 2, "rotate(270) height ok");
36is($j->data, "24681357", "rotate(270) data ok");
37
38$j->rotate(180);
39is( $j->width, 4, "rotate(180) width ok");
40is( $j->height, 2, "rotate(180) height ok");
41is($j->data, "75318642", "rotate(180) data ok");
42
43my $k = Prima::Image->create(
44	width    => 2,
45	height   => 2,
46	type     => im::Short,
47	data     => "12345678",
48	lineSize => 4,
49);
50
51$k->rotate(90);
52is($k->data, "56127834", "short: rotate(90) data ok");
53
54$k->data("12345678");
55$k->rotate(270);
56is($k->data, "34781256", "short: rotate(270) data ok");
57
58$k->data("12345678");
59$k->rotate(180);
60is($k->data, "78563412", "short: rotate(180) data ok");
61
62# mirroring
63$j->data("12345678");
64$j->mirror(1);
65is( $j->data, "56781234", "byte: vertical mirroring ok");
66$j->data("12345678");
67$j->mirror(0);
68is( $j->data, "43218765", "byte: horizontal mirroring ok");
69
70$j->type(im::Short);
71$j->data("123456789ABCDEFG");
72$j->mirror(1);
73is( $j->data, "9ABCDEFG12345678", "short: vertical mirroring ok");
74$j->data("123456789ABCDEFG");
75$j->mirror(0);
76is( $j->data, "78563412FGDEBC9A", "short: horizontal mirroring ok");
77
78# rotation
79$k = Prima::Image->create(
80	width    => 140,
81	height   => 140,
82	type     => im::Byte,
83);
84
85$k->bar(0,0,$k->size);
86$k->pixel(138, 70, cl::White);
87
88my $p = Prima::Image->create(
89	width    => 200,
90	height   => 200,
91	type     => im::Byte,
92);
93$p->bar(0,0,$k->size);
94for (my $i = 0; $i < 360; $i++) {
95	my $d = $k->dup;
96	$d->rotate($i);
97	my $dx = ($p-> width  - $d->width) / 2;
98	my $dy = ($p-> height - $d->height) / 2;
99	$p->put_image($dx,$dy,$d,rop::OrPut);
100}
101my $sum = $p->sum / 255;
102ok(( $sum > 250 && $sum < 430), "rotation 360 seems performing");
103$p->color(cl::Black);
104$p->lineWidth(8);
105$p->ellipse( 100, 100, 138, 138 );
106is( $p->sum, 0, "rotation 360 is correct");
107
108$p = Prima::Image->create(
109	width    => 200,
110	height   => 200,
111	type     => im::Byte,
112);
113$p->bar(0,0,$k->size);
114for (my $i = 0; $i < 360; $i++) {
115	my $d = $k->dup;
116	my $cos = cos($i / 3.14159 * 180.0);
117	my $sin = sin($i / 3.14159 * 180.0);
118	$d->transform($cos, $sin, -$sin, $cos + 0.001); # to make sure it's 2D transform, not a rotation
119	my $dx = ($p-> width  - $d->width) / 2;
120	my $dy = ($p-> height - $d->height) / 2;
121	$p->put_image($dx,$dy,$d,rop::OrPut);
122}
123$sum = $p->sum / 255;
124ok(( $sum > 250 && $sum < 430), "rotation 360 by transform2d seems performing");
125$p->color(cl::Black);
126$p->lineWidth(8);
127$p->ellipse( 100, 100, 138, 138 );
128is( $p->sum, 0, "rotation 360 transform2d is correct");
129
130$p = Prima::Icon->create(
131	width    => 2,
132	height   => 2,
133	type     => im::Byte,
134	maskType => 8,
135	mask     => "\1\2..\3\4",
136	data     => "\4\5..\6\7",
137);
138$p->shear(2,0);
139is_bytes( $p->data, "\4\5\0\0\0\0\6\7", "xshear(2) integral data");
140is_bytes( $p->mask, "\1\2\0\0\0\0\3\4", "xshear(2) integral mask");
141
142$p = Prima::Image->create(
143	width    => 2,
144	height   => 2,
145	type     => im::Byte,
146	data     => "\1\4..\3\6");
147$p->shear(0,0.5);
148$p = $p->data;
149$p = substr($p,0,2) . substr($p,4,2) . substr($p,8,2);
150is_bytes( $p, join('', map { chr } (1, (0+4)/2), 3, (4+6)/2, 0, (6+0)/2), "yshear subpixel");
151
152done_testing;
153