1=pod
2
3=head1 NAME
4
5examples/blend.pl - Prima alpha blending
6
7=head1 FEATURES
8
9Demonstrates use of Prima image alpha blending with C<rop::blend($ALPHA)>.
10
11=cut
12
13
14use strict;
15use warnings;
16use Prima qw(Application Label Sliders ImageViewer);
17
18my ($rop_name, $rop_val);
19my $w = Prima::MainWindow->new(
20	size => [ 600, 500 ],
21	designScale => [7, 16],
22	text => 'Blending example',
23	menuItems => [
24		[ '~Binary' => [ map { [$_, $_, \&bin, {group => 1}] } qw(
25			CopyPut XorPut AndPut OrPut NotPut Invert Blackness
26			NotDestAnd NotDestOr Whiteness NotSrcAnd NotSrcOr NotXor
27			NotAnd NotOr NoOper
28		)]],
29		[ 'Porter-~Duff' => [ map { [$_, $_, \&pd, {group => 1}] } qw(
30			SrcOver Xor DstOver SrcCopy DstCopy Clear
31			SrcIn DstIn SrcOut DstOut SrcAtop DstAtop
32		)]],
33		[ '~Photoshop' => [ map { [$_, $_, \&pd, {group => 1}] } qw(
34			Add Multiply Screen Overlay Darken
35			Lighten ColorDodge ColorBurn HardLight
36			SoftLight Difference Exclusion
37		)]],
38	]
39);
40
41my $a = Prima::Image->new(
42	size => [200,200],
43	type => im::RGB,
44);
45$a->begin_paint;
46$a->new_gradient( palette => [cl::LightGreen, cl::Blue ])->bar(0, 0, $a->size);
47$a->end_paint;
48my $ia = Prima::Icon->new(
49	size => [200,200],
50	type => im::RGB,
51	maskType => im::bpp8,
52	autoMasking => am::MaskColor,
53	maskColor => cl::Black,
54);
55$ia->put_image(0,0,$a);
56$ia->color(cl::Black);
57$ia->bar(0,0,30,200);
58$ia->bar(170,0,200,200);
59
60my $b = $a->dup;
61$b->begin_paint;
62$b->bar(0,0,$b->size);
63$b->new_gradient( palette => [cl::LightRed, cl::Yellow ])-> ellipse($b->width/2,$b->height/2, $b->size);
64$b->end_paint;
65
66my $ib = Prima::Icon->new(
67	size => [200,200],
68	type => im::RGB,
69	maskType => im::bpp8,
70	autoMasking => am::MaskColor,
71	maskColor => cl::Black,
72);
73$ib->put_image( 0,0,$b);
74
75my $base = $a->dup;
76$base->set( backColor => cl::White, color => cl::Black, fillPattern => [(0xF0)x4, (0xF)x4], rop2 => rop::CopyPut);
77$base->bar(0,0,$base->size);
78
79my $canvas = $a->dup;
80my $precanvas = Prima::Icon->new(
81	size => [200,200],
82	type => im::RGB,
83	maskType => im::bpp8,
84	autoMasking => am::None,
85);
86$ia->autoMasking(am::None);
87
88my $mask = Prima::Image->new(
89	size => [200,200],
90	type => im::Byte,
91);
92
93sub repaint
94{
95	my $sa = $w->SliderA;
96	my $sb = $w->SliderB;
97	if ( $sa->enabled ) {
98		$precanvas->put_image(0,0,$ia, rop::alpha( rop::SrcCopy | rop::Premultiply, $sa->value));
99		$precanvas->put_image(0,0,$ib, rop::alpha( $rop_val     | rop::Premultiply, $sb->value));
100		$canvas->put_image(0,0,$base);
101		$canvas->put_image(0,0,$precanvas);
102	} else {
103		$canvas->put_image(0,0,$a);
104		$canvas->put_image(0,0,$b,$rop_val);
105	}
106
107	my $fader = $w->Fader;
108	$canvas->put_image(2, 2, $fader->{banner}, rop::alpha( rop::SrcOver | rop::Premultiply, $fader->{alpha} ))
109		if $fader->{banner};
110	$w-> ImageViewer1->repaint;
111}
112
113sub select_rop
114{
115	my ($newrop, $with_slider) = @_;
116	$rop_name = $newrop;
117	$rop_val = &{${rop::}{$rop_name}}();
118	$w->SliderA->enabled( $with_slider );
119	$w->SliderA->readOnly( !$with_slider );
120	$w->SliderB->enabled( $with_slider );
121	$w->SliderB->readOnly( !$with_slider );
122	$w->Fader->{text} = $rop_name;
123	delete $w->Fader->{left};
124	$w->Fader->{steps} = 30;
125	$w->Fader->start;
126	repaint();
127}
128
129sub set_slider
130{
131	$w->Fader->{text} = shift->value;
132	$w->Fader->{steps} = 15;
133	delete $w->Fader->{left};
134	$w->Fader->start;
135	repaint();
136}
137sub bin { select_rop($_[1], 0) }
138sub pd  { select_rop($_[1], 1) }
139
140
141$w-> insert( ImageViewer =>
142	pack => {side => 'top', fill => 'both', pad => 10, expand => 1},
143	image => $canvas,
144	stretch => 1,
145);
146
147$w->insert( Label =>
148	text => '~Green transparency',
149	focusLink => 'SliderA',
150	pack => {side => 'top', fill => 'x', padx => 15},
151);
152
153$w->insert( Slider =>
154	min => 0,
155	max => 255,
156	value => 200,
157	scheme => ss::Axis,
158	increment => 16,
159	name => 'SliderA',
160	pack => {side => 'top', fill => 'x'},
161	onChange => \&set_slider,
162);
163
164$w->insert( Label =>
165	text => '~Red transparency',
166	focusLink => 'SliderB',
167	pack => {side => 'top', fill => 'x', padx => 15},
168);
169
170$w->insert( Slider =>
171	min => 0,
172	max => 255,
173	scheme => ss::Axis,
174	increment => 16,
175	value => 200,
176	name => 'SliderB',
177	pack => {side => 'top', fill => 'x'},
178	onChange => \&set_slider,
179);
180
181$w-> insert( Timer =>
182	timeout => 50,
183	name => 'Fader',
184	onTick => sub {
185		my $self = shift;
186		if ( !defined $self->{left}) {
187			$self->{left} = $self->{steps};
188			$canvas-> begin_paint_info;
189			$canvas->font->set( size => 18, style => fs::Bold );
190			my $f = $canvas->font;
191			my $b = Prima::Icon->new(
192				type        => im::RGB,
193				size        => [ $canvas->get_text_width( $self->{text}, 1 ) + 4, $f-> height + 4 ],
194				color       => cl::Yellow,
195				backColor   => cl::Black,
196				lineWidth   => 5,
197				maskType    => 8,
198				autoMasking => 0,
199				font        => { vector => 1 },
200			);
201			$canvas-> end_paint_info;
202			$b->begin_paint;
203			$b->clear;
204			$b->font->set( size => 18, style => fs::Bold );
205			$b->color(0x010101); # black but not zero
206			my $path = $b->new_path;
207			$path->translate(2,2);
208			$path->text( $self->{text});
209			$path->stroke;
210			$b->color(cl::Yellow);
211			$b->text_out($self->{text}, 2, 2);
212			$b->end_paint;
213
214			my $bb = $b->clone( type => im::Byte, rop2 => rop::CopyPut );
215			$bb->map(0x000000); # black and zero
216			$b->mask( $bb->data );
217
218			$self->{banner} = $b;
219			$self->{alpha} = 255;
220		} elsif ( --$self->{left} <= 0 ) {
221			delete $self->{banner};
222			delete $self->{left};
223			$self->stop;
224		} else {
225			$self->{alpha} -= 256 / $self->{steps};
226		}
227		repaint;
228	},
229);
230$w->Fader->{steps} = 30;
231
232select_rop('SrcOver', 1);
233
234run Prima;
235