Image-Base-X11-Protocol
view release on metacpan or search on metacpan
lib/Image/Base/X11/Protocol/Drawable.pm view on Meta::CPAN
### reply: $X->unpack_reply($elem->{'request_type'}, $elem->{'reply'})
my ($pixel) = $X->unpack_reply ($elem->{'request_type'}, $elem->{'reply'});
$colour_to_pixel->{$colour} = $pixel;
if ($pixel_to_colour) {
$pixel_to_colour->{$pixel} = $colour;
}
};
while (@_) {
my $colour = shift;
next if defined $colour_to_pixel->{$colour}; # already known
delete $self->{'-pixel_to_colour'};
# black_pixel or white_pixel of a default colormap
if (my $field = $colour_to_screen_field{$colour}) { # "black" or "white"
if (my $screen_info = X11::Protocol::Other::default_colormap_to_screen_info($X,$colormap)) {
my $pixel = $colour_to_pixel->{$colour} = $screen_info->{$field};
if ($pixel_to_colour) {
$pixel_to_colour->{$pixel} = $colour;
}
next;
}
}
my $elem = { colour => $colour };
my @req;
# Crib: [:xdigit:] new in 5.6, so only 0-9A-F, and in any case as of
# perl 5.12.4 [:xdigit:] matches some wide chars but hex() doesn't
# accept them
if (my @rgb = X11::Protocol::Other::hexstr_to_rgb($colour)) {
@req = ('AllocColor', $colormap, map {hex} @rgb);
} else {
@req = ('AllocNamedColor', $colormap, $colour);
}
$elem->{'request_type'} = $req[0];
my $seq = $elem->{'seq'} = $X->send(@req);
$X->add_reply ($seq, \$elem->{'reply'});
### $elem
push @queued, $elem;
if (@queued > 256) {
&$wait_queue();
}
}
while (@queued) {
&$wait_queue();
}
if (@failed_colours) {
die "Unknown colour(s): ",join(', ', @failed_colours);
}
}
#------------------------------------------------------------------------------
# clipping to signed 16-bit parameters
use constant _LO => -0x8000; # -32768
use constant _HI => 0x7FFF; # +32767
# $x1,$y1, $x2,$y2 are the endpoints of a line.
# Return new endpoints which are clipped to within -0x8000 to +0x7FFF which is
# signed 16-bits for X protocol.
# If given line is entirely outside the signed 16-bit rectangle then return
# an empty list.
#
sub _line_clip {
my ($x1,$y1, $x2,$y2) = @_;
### _line_clip_16bit(): "$x1,$y1, $x2,$y2"
unless (_line_any_positive($x1,$y1, $x2,$y2)) {
### nothing positive ...
return;
}
my ($x1new,$y1new) = _line_end_clip($x1,$y1, $x2,$y2)
or do {
### x1,y1 end nothing in range ...
return;
};
($x2,$y2) = _line_end_clip($x2,$y2, $x1,$y1)
or return;
return ($x1new,$y1new, $x2,$y2);
}
# $x1,$y1, $x2,$y2 are the endpoints of a line.
# Return new values for the $x2,$y2 end which clips it to within
# LO <= x2 <= HI
# LO <= y2 <= HI
#
# If the line is entirely outside LO to HI then return an empty list.
# If x2,y2 is already within LO to HI then return them unchanged.
#
# x1,y1
# /
# +-------- if x2 outside
# | / then
# |/ move it to x2new=LO
# x2new,y2new * and y2new=corresponding pos on line
# /|
# / |
# x2,y2 +--------
# LO
#
# +---------
# | if y2 outside,
# | x1,y1 including moved y2new outside
# | / then
# +--*----- move it to y2new=LO
# /x2new, and x2new=corresponding pos on line
# / y2new
# first y2new *
# /
# /
# x2,y2
#
sub _line_end_clip {
my ($x1,$y1, $x2,$y2) = @_;
### _line_end_clip(): "$x1,$y1, $x2,$y2"
my ($x2new, $y2new);
if ($x2 < _LO || $x2 > _HI) {
# x2 is outside LO to HI, clip to x2=LOorHI and y2 set to corresponding
my $xlen = $x2 - $x1
or return; # xlen==0 means x1==x2 so entirely outside LO to HI
$x2new = ($x2 < _LO ? _LO : _HI);
$y2new = floor(($y2*($x2new-$x1) + $y1*($x2-$x2new)) / $xlen + 0.5);
### x clip: "to $x2new,$y2new frac ".($y2*($x2new-$x1) + $y1*($x2-$x2new))." / $xlen"
} else {
$x2new = $x2;
$y2new = $y2;
}
if ($y2new < _LO || $y2new > _HI) {
my $ylen = $y2 - $y1
or return; # ylen==0 means y1==y2 so entirely outside LO to HI
$y2new = ($y2 < _LO ? _LO : _HI);
$x2new = floor(($x2*($y2new-$y1) + $x1*($y2-$y2new)) / $ylen + 0.5);
### y clip: "to $x2new,$y2new left ".($y2new-$y1)." right ".($y2-$y2new)
if ($x2new < _LO || $x2new > _HI) {
### x2new outside ...
return;
}
}
( run in 1.675 second using v1.01-cache-2.11-cpan-524268b4103 )