--- loncom/homework/drawimage.pm 2004/03/16 23:08:23 1.5 +++ loncom/homework/drawimage.pm 2024/04/05 22:44:19 1.13 @@ -1,7 +1,7 @@ # The LearningOnline Network with CAPA # programatic image drawing # -# $Id: drawimage.pm,v 1.5 2004/03/16 23:08:23 albertel Exp $ +# $Id: drawimage.pm,v 1.13 2024/04/05 22:44:19 raeburn Exp $ # # Copyright Michigan State University Board of Trustees # @@ -29,46 +29,83 @@ package Apache::drawimage; use strict; use Apache::loncommon; +use Apache::lonnet; +use Apache::lonxml; +use lib '/home/httpd/lib/perl/'; +use Time::HiRes qw(gettimeofday); +use LONCAPA; + my %args; my $cgi_id; +my @cgi_ids; BEGIN { &Apache::lonxml::register('Apache::drawimage',('drawimage')); } sub start_drawimage { my ($target,$token,$tagstack,$parstack,$parser,$safeeval,$style)=@_; - &Apache::lonxml::register('Apache::drawimage',('text','line','rectangle','arc','fill')); + &Apache::lonxml::register('Apache::drawimage',('text','line','rectangle','arc','fill','polygon','image')); if ($target eq 'web' || $target eq 'tex') { - $cgi_id=&Apache::loncommon::get_cgi_id(); - %args=(); + my $new_id=&Apache::loncommon::get_cgi_id(); + if ($cgi_id) { push(@cgi_ids,$cgi_id); } else { undef(%args); } + $cgi_id=$new_id; } + return ''; } sub end_drawimage { my ($target,$token,$tagstack,$parstack,$parser,$safeeval,$style)=@_; my $result; + # need to call rand everytime start_script would evaluate, as the + # safe space rand number generator and the global rand generator + # are not separate + my $randnumber; + if ($target eq 'web' || $target eq 'tex' || $target eq 'grade' || + $target eq 'answer') { + $randnumber=int(rand(1000)); + } if ($target eq 'web' || $target eq 'tex') { - if ($target eq 'web') { - my $width = - &Apache::lonxml::get_param('width',$parstack,$safeeval); - my $height = - &Apache::lonxml::get_param('height',$parstack,$safeeval); - my $bgcolor = - &Apache::lonxml::get_param('bgcolor',$parstack,$safeeval); - if (!$width) { $width=300; } - if (!$height) { $height=300; } + my $width = &Apache::lonxml::get_param('width',$parstack,$safeeval); + my $height =&Apache::lonxml::get_param('height',$parstack,$safeeval); + my $bgcolor =&Apache::lonxml::get_param('bgcolor',$parstack,$safeeval); + if (!$width) { $width=300; } + if (!$height) { $height=300; } + $args{"cgi.$cgi_id.BGCOLOR"}=join(':',($bgcolor)); + if ($target eq 'tex') { + my $texwidth=&Apache::lonxml::get_param('texwidth',$parstack,$safeeval,undef,1); + if (!$texwidth) { $texwidth='90'; } + $args{"cgi.$cgi_id.SIZE"}=join(':',($width,$height,$texwidth)); + my $tmpdir = LONCAPA::tempdir(); # Where temporary files live: + ## Determine filename + my ($seconds, $microseconds) = gettimeofday; + my $filename = $env{'user.name'}.'_'.$env{'user.domain'}. + '_'.$seconds.'_'.$microseconds.'_'.$$.$randnumber.'_drawimage.eps'; + $args{"cgi.$cgi_id.EPSFILE"} = $env{'user.name'}.'_'.$env{'user.domain'}. + '_'.$seconds.'_'.$microseconds.'_'.$$.$randnumber. + '_drawimage.eps'; + $result = "%DYNAMICIMAGE:$width:$height:$texwidth\n"; + $result .= '\graphicspath{{'.$tmpdir.'}}'."\n"; + $result .= '\includegraphics[width='.$texwidth.' mm]{'.$filename.'}'; + &Apache::lonxml::register_ssi('/adm/randomlabel.png?token='.$cgi_id); + } else { + $args{"cgi.$cgi_id.SIZE"}=join(':',($width,$height)); $result.="\n"; - $args{"cgi.$cgi_id.SIZE"}=join(':',($width,$height)); - $args{"cgi.$cgi_id.BGCOLOR"}=join(':',($bgcolor)); - &Apache::lonnet::appenv(%args); - } elsif ($target eq 'tex') { - #FIXME generate image some how - #probably Simple::PostScript + } + &Apache::lonnet::appenv(\%args); + if (@cgi_ids) { + $cgi_id=pop(@cgi_ids); + } else { + undef($cgi_id); } + } elsif ($target eq 'edit') { + } elsif ($target eq 'modified') { } - &Apache::lonxml::deregister('Apache::drawimage',('line','rectangle')); + + &Apache::lonxml::register('Apache::drawimage', + ('text','line','rectangle','arc','fill', + 'polygon')); return $result; } @@ -76,26 +113,30 @@ sub start_text { my ($target,$token,$tagstack,$parstack,$parser,$safeeval,$style)=@_; my $result; if ($target eq 'web' || $target eq 'tex') { + &Apache::lonxml::startredirection(); + } + return $result; +} + +sub end_text { + my ($target,$token,$tagstack,$parstack,$parser,$safeeval,$style)=@_; + my $result; + if ($target eq 'web' || $target eq 'tex') { my $x = &Apache::lonxml::get_param('x',$parstack,$safeeval); my $y = &Apache::lonxml::get_param('y',$parstack,$safeeval); my $font = &Apache::lonxml::get_param('font',$parstack,$safeeval); my $color = &Apache::lonxml::get_param('color',$parstack,$safeeval); my $direction = &Apache::lonxml::get_param('direction',$parstack,$safeeval); - my $text = &Apache::lonxml::get_all_text("/text",$parser); - $text = &Apache::lonnet::escape($text); + my $rotation = &Apache::lonxml::get_param('rotation',$parstack,$safeeval); + my $text = &Apache::lonxml::endredirection(); + $text = &escape($text); $args{"cgi.$cgi_id.OBJTYPE"}.='LABEL:'; my $i=$args{"cgi.$cgi_id.OBJCOUNT"}++; - $args{"cgi.$cgi_id.OBJ$i"}=join(':',($x,$y,$text,$font,$color,$direction)); + $args{"cgi.$cgi_id.OBJ$i"}=join(':',($x,$y,$text,$font,$color,$direction,$rotation)); } return $result; } -sub end_text { - my ($target,$token,$tagstack,$parstack,$parser,$safeeval,$style)=@_; - my $result; - return $result; -} - sub start_line { my ($target,$token,$tagstack,$parstack,$parser,$safeeval,$style)=@_; my $result; @@ -194,6 +235,88 @@ sub end_fill { return $result; } +my @polygon; +sub start_polygon { + my ($target,$token,$tagstack,$parstack,$parser,$safeeval,$style)=@_; + my $result; + &Apache::lonxml::register('Apache::drawimage',('point')); + if ($target eq 'web' || $target eq 'tex') { + undef(@polygon); + } + return $result; +} +sub end_polygon { + my ($target,$token,$tagstack,$parstack,$parser,$safeeval,$style)=@_; + my $result; + if ($target eq 'web' || $target eq 'tex') { + my $color=&Apache::lonxml::get_param('color',$parstack,$safeeval); + my $filled=&Apache::lonxml::get_param('filled',$parstack,$safeeval); + my $open=&Apache::lonxml::get_param('open',$parstack,$safeeval); + my $thickness = &Apache::lonxml::get_param('thickness',$parstack, + $safeeval); + my $i=$args{"cgi.$cgi_id.OBJCOUNT"}++; + $args{"cgi.$cgi_id.OBJTYPE"}.='POLYGON:'; + $args{"cgi.$cgi_id.OBJ$i"}=join(':',($color,$thickness,$open,$filled)); + $args{"cgi.$cgi_id.OBJEXTRA$i"}=join('-',@polygon); + } + &Apache::lonxml::deregister('Apache::drawimage',('point')); + return $result; +} + +sub start_point { + my ($target,$token,$tagstack,$parstack,$parser,$safeeval,$style)=@_; + my $result; + if ($target eq 'web' || $target eq 'tex') { + my $x = &Apache::lonxml::get_param('x',$parstack,$safeeval); + my $y = &Apache::lonxml::get_param('y',$parstack,$safeeval); + push (@polygon,"($x,$y)"); + } + return $result; +} + +sub end_point { + my ($target,$token,$tagstack,$parstack,$parser,$safeeval,$style)=@_; + my $result; + return $result; +} + +sub start_image { + my ($target,$token,$tagstack,$parstack,$parser,$safeeval,$style)=@_; + my $result; + if ($target eq 'web' || $target eq 'tex') { + &Apache::lonxml::startredirection(); + } + return $result; +} + +sub end_image { + my ($target,$token,$tagstack,$parstack,$parser,$safeeval,$style)=@_; + my $result; + if ($target eq 'web' || $target eq 'tex') { + my $bgimg=&Apache::lonxml::endredirection(); + my $x = &Apache::lonxml::get_param('x',$parstack,$safeeval); + my $y = &Apache::lonxml::get_param('y',$parstack,$safeeval); + my $clipx = &Apache::lonxml::get_param('clipx',$parstack,$safeeval); + my $clipy = &Apache::lonxml::get_param('clipy',$parstack,$safeeval); + my $clipwidth = + &Apache::lonxml::get_param('clipwidth',$parstack,$safeeval); + my $clipheight = + &Apache::lonxml::get_param('clipheight',$parstack,$safeeval); + my $scaledwidth = + &Apache::lonxml::get_param('scaledwidth',$parstack,$safeeval); + my $scaledheight = + &Apache::lonxml::get_param('scaledheight',$parstack,$safeeval); + my $transparent = + &Apache::lonxml::get_param('transparent',$parstack,$safeeval); + $bgimg=&Apache::imageresponse::clean_up_image($bgimg); + my $i=$args{"cgi.$cgi_id.OBJCOUNT"}++; + $args{"cgi.$cgi_id.OBJTYPE"}.='IMAGE:'; + $args{"cgi.$cgi_id.OBJ$i"} = + join(':',($x,$y,&escape($bgimg),$transparent, + $clipx,$clipy,$scaledwidth,$scaledheight,$clipwidth,$clipheight)); + } + return $result; +} 1; __END__