package ONO::FW::Apps::Core::Graphics;
################################################################################
# COPYRIGHT / LICENSE #
################################################################################
#
# This file is part of the ONO Software Project.
#
# Copyright (C) 2000-2025 Jos KIRPS [ www.kirps.com | jos_AT_kirps_DOT_com ]
# and The Joopita Project [ www.joopita.org | contact_AT_joopita_DOT_com ]
#
# This file, as well as other parts of the ONO Software Project or related
# elements, are FREE SOFTWARE available under the ARTISTIC LICENSE 2.0.
#
# This program is distributed in the hope that it will be useful, but
# WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
#
# For the full license, see /ono/osr/license/LICENSE.txt, or write to
# jos_AT_kirps_DOT_com or contact_AT_joopita_DOT_com.
#
################################################################################
# END OF COPYRIGHT / LICENSE, HERE COMES THE CODE ... #
################################################################################
use strict;
use ONO::IO;
use ONO::Lib::Basic;
use ONO::Lib::PDF::Draw;
use ONO::Lib::PDF::ToolBox;
use ONO::Lib::DateTime::ToolBox;
use ONO::Lib::Code::RandomID;
use ONO::Lib::Web::Domain;
use ONO::FW::Apps::Core;
use ONO::FW::Apps::PDF;
use ONO::FW::Apps::Core::Save;
###################################################################
#
###################################################################
#: This module offers a number of PDF generation helpers for ONO
#: apps.
sub pdf_draw_item_numbers {
my (
$self,
$canvas,
$pdf_x,
$pdf_y,
$start,
$nums,
$switches,
$vars_ref,
) = @_;
my %vars = %$vars_ref;
#: Draw item numbers on a sheet.
#:
#: Switches:
#:
#: -C correction mode (b/w)
#: -d lower lines 1/2
#: -D lower lines 2/2
#: -f force (same as -F, but compatible with pdf_draw_item_number)
#: -F force (same as -f, but will only work in "five div mode")
#: -H horizontal line
#: -l print half last line if app_input_result_hints
#: -L don't print last item if app_input_result_hints
#: -S start with Second item (1234 -> .123)
#: -V vertical line
#: -W Worksheet Builder mode, will respect the custom layout logic,
#: using vars worksheet_builder_layout
my $switches2;
if ($switches =~ /C/) {
$switches2 .= "C";
}
if ($switches =~ /f/) {
$switches2 .= "f";
}
if (($vars{'app_input_print_options_item_numbers'} && !$vars{'output_worksheet_maker'}) || $switches =~ /(f|F)/) {
my $first_i = 0;
if ($switches =~ /S/) {
$first_i = 1;
}
for (my $i = $first_i; $i < $nums; $i++) {
my $new_x = $pdf_x;
my $new_y = $pdf_y+$i*190/$nums;
if ($switches !~ /L/ || !$vars{'app_input_result_hints'} || $i < $nums-1) {
my $fix_y = 0;
if ($switches =~ /W/ && $vars{'worksheet_builder_layout'}) {
if ($vars{'worksheet_builder_layout'} == 3) {
$fix_y = -16;
if ($i == 0) {
$fix_y = 32;
}
if ($i == 1) {
$new_y = $pdf_y+190/4*2;
}
if ($i == 2) {
$new_y = $pdf_y+190/4*3;
}
}
if ($vars{'worksheet_builder_layout'} == 4) {
$fix_y = -16;
if ($i == 1) {
$new_y = $pdf_y+190/4;
}
if ($i == 2) {
$new_y = $pdf_y+190/4*2;
$fix_y = 32;
}
}
if ($vars{'worksheet_builder_layout'} == 5) {
$fix_y = -16;
if ($i == 1) {
$new_y = $pdf_y+190/4;
$fix_y = 32;
}
if ($i == 2) {
$new_y = $pdf_y+190/4*3;
}
}
}
&pdf_draw_item_number("",$canvas,$pdf_x,$new_y,$start+$i-$first_i,$switches2,$vars_ref);
if ($switches =~ /V/) {
my $new_y2 = $new_y-10+190/$nums;
if ($switches =~ /H/) {
$new_y2 = $new_y2 + 4;
if ($switches =~ /d/) {
$new_y2 = $new_y2 + 2;
}
if ($switches =~ /D/) {
$new_y2 = $new_y2 + 2;
}
}
$new_y2 = $new_y2 + $fix_y;
ONO::Lib::PDF::Draw->line($canvas,$new_x,$new_y+10,$new_x,$new_y2,0.75,"0:188:188:188");
ONO::Lib::PDF::Draw->arc($canvas,$new_x+4,$new_y2,4,3,0.75,"","0:188:188:188");
if ($switches =~ /H/) {
my $mul = 1;
if ($i == $nums-1 && $switches =~ /l/ && $vars{'app_input_result_hints'}) {
$mul = 0.5;
if ($vars{'pdf_draw_item_numbers_last_line_mul'}) {
$mul = $vars{'pdf_draw_item_numbers_last_line_mul'};
}
}
ONO::Lib::PDF::Draw->line($canvas,$new_x+4,$new_y2+4,$new_x+172*$mul,$new_y2+4,0.75,"0:188:188:188");
ONO::Lib::PDF::Draw->arc($canvas,$new_x+172*$mul,$new_y2,4,2,0.75,"","0:188:188:188");
}
}
}
}
}
}
sub pdf_draw_item_number_html {
#: Draw item number - HTML version.
return qq~<div class="p2 radius$_[1]" style="background-color:#ffddbb"><div class="block$_[1] radius$_[1] xsmall bold cole center" style="background-color:#dd6611;line-height:16px">$_[2]</div></div>~;
}
sub pdf_draw_item_number_html_example_mini {
#: Draw item number - HTML version, smaller.
my $RENUM;
for (my $i = 1; $i < 4; $i++) {
$RENUM .= qq~<td>~;
$RENUM .= &pdf_draw_item_number_html("",16,$i);
$RENUM .= qq~</td>~;
}
return qq~<td>(</td>$RENUM<td>)</td>~;
}
sub pdf_draw_item_number {
my (
$self,
$canvas,
$pdf_x,
$pdf_y,
$num,
$switches,
$vars_ref,
) = @_;
my %vars = %$vars_ref;
#: Draw a single item number on a sheet.
#:
#: Switches:
#:
#: -a auto mode,
#: -A like -a, but also max = 4
#: -C correction mode (b/w)
#: -f force mode
#: -F five mode: only display if num / 5 is zero
#: -W override in worksheet maker mode
#: -y pdf_y auto detect mode, sets number based on y coordinate,
#: this works with both 3 and 4 rows using approximation...
my $exec;
if ($vars{'app_input_print_options_item_numbers'}) {
$exec = 1;
}
if ($switches =~ /W/ && $vars{'output_worksheet_maker'}) {
$exec = 0;
}
if ($switches =~ /F/ && $num%5 != 0) {
$exec = 0;
}
if ($switches =~ /(a|A)/) {
$num = int($num/5)+1;
}
if ($switches =~ /A/ && $num > 4) {
$exec = 0;
}
if ($switches =~ /f/) {
$exec = 1;
}
if ($switches =~ /y/) {
$num = 1;
if ($pdf_y > 40) {
$num = 2;
if ($pdf_y > 80) {
$num = 3;
if ($pdf_y > 140) {
$num = 4;
if ($pdf_y > 160) {
$exec = 0;
}
}
}
}
}
if ($vars{'app_input_paper_format_status'} eq "q170/190") {
$exec = 0;
}
if ($num && $exec) {
my @cols = ("0:220:110:30","0:250:210:180");
if ($switches =~ /C/) {
@cols = ("0:120:120:120","0:210:210:210");
}
ONO::Lib::PDF::Draw->circle($canvas,$pdf_x,$pdf_y+5,4,2,$cols[0],$cols[1]);
ONO::Lib::PDF::Draw->font("HB");
ONO::Lib::PDF::Draw->color("0:250:250:250");
ONO::Lib::PDF::Draw->text($canvas,$pdf_x,$pdf_y+6.5,$num,"c");
ONO::Lib::PDF::Draw->font("H");
ONO::Lib::PDF::Draw->color();
}
}
sub pdf_draw_house {
my (
$self,
$canvas,
$x,
$y,
$cols,
$res,
$op,
$offset,
$corr,
$switches,
) = @_;
#: Draw a house image.
#:
#: Switches:
#:
#: -i image mode (first row is much higher)
$x = $x+$offset;
$y = $y+$offset;
my $rows = 10;
if ($cols =~ s~:(.*)$~~) {
$rows = $1;
}
my $inc = 7;
my $width = 45;
my $height = $rows*$inc;
if ($switches =~ /i/) {
$height = $height + 10;
}
my $r1 = 150+int(rand(100));
my $r2 = int(rand(75));
my $r3 = int(rand(75));
my $RED = "0:$r1:$r2:$r3";
if ($corr) {
$RED = "0:111:111:111";
}
ONO::Lib::PDF::Draw->triangle($canvas,$x,$y+10,$x+10,$y,$x+10,$y+10,0,"",$RED);
ONO::Lib::PDF::Draw->triangle($canvas,$x+35,$y,$x+35,$y+10,$x+$width,$y+10,0,"",$RED);
ONO::Lib::PDF::Draw->rect($canvas,$x+9.9,$y,$x+35.1,$y+10,0,"",$RED);
ONO::Lib::PDF::Draw->line($canvas,$x+10,$y,$x+35,$y,1);
ONO::Lib::PDF::Draw->line($canvas,$x,$y+10,$x+10,$y,1);
ONO::Lib::PDF::Draw->line($canvas,$x+$width,$y+10,$x+35,$y,1);
if ($corr) {
ONO::Lib::PDF::Draw->rect($canvas,$x,$y+10,$x+$width,$y+16,"","","0:200:200:200");
} else {
ONO::Lib::PDF::Draw->rect($canvas,$x,$y+10,$x+$width,$y+16,"","","0:250:230:175");
}
ONO::Lib::PDF::Draw->line($canvas,$x,$y+16,$x+$width,$y+16,2);
ONO::Lib::PDF::Draw->text_math_symbol($canvas,$x+22.5,$y+13.25,2.5,$op);
my $off_y;
if ($switches =~ /i/) {
$off_y = 10;
}
for (my $i = 1; $i < $rows+1; $i++) {
for (my $j = 1; $j < $cols+1; $j++) {
my $GREY = &pdf_grey();
if ($corr) {
$GREY = "0:250:250:250";
}
if ($switches =~ /i/) {
$GREY = ONO::Lib::PDF::Draw->color_calc($GREY,-100);
}
if ($switches !~ /i/ || $i == 2) {
ONO::Lib::PDF::Draw->rect($canvas,$x+($j-1)*($width/$cols),$y+$inc+$i*$inc+2+$off_y,$x+($j)*($width/$cols),$y+$inc+($i+1)*$inc+2+$off_y,0,"",$GREY);
}
}
}
ONO::Lib::PDF::Draw->rect($canvas,$x,$y+10,$x+$width,$y+16+$height,1);
if ($switches =~ /i/) {
ONO::Lib::PDF::Draw->line($canvas,$x,$y+33,$x+$width,$y+33,1);
ONO::Lib::PDF::Draw->rect($canvas,$x+5,$y+32,$x+18,$y+41,1,"0:22:22:22","0:244:244:244",2);
ONO::Lib::PDF::Draw->rect($canvas,$x+27,$y+32,$x+40,$y+41,1,"0:22:22:22","0:244:244:244",2);
} else {
for (my $i = 1; $i < $rows+1; $i++) {
ONO::Lib::PDF::Draw->line($canvas,$x,$y+$inc+$i*$inc+2,$x+$width,$y+$inc+$i*$inc+2);
}
}
for (my $i = 1; $i < $cols; $i++) {
ONO::Lib::PDF::Draw->line($canvas,$x+$i*($width/$cols),$y+16,$x+$i*($width/$cols),$y+16+$height);
}
ONO::Lib::PDF::Draw->font('HB');
if ($switches =~ /i/) {
ONO::Lib::PDF::Draw->rect($canvas,$x+15,$y+2,$x+30,$y+11,1,"0:22:22:22","0:244:244:244",2);
ONO::Lib::PDF::Draw->text($canvas,$x+22.5,$y+8,$res,"center");
} else {
ONO::Lib::PDF::Draw->color("0:250:250:250");
ONO::Lib::PDF::Draw->text($canvas,$x+22.5,$y+7,$res,"center");
}
ONO::Lib::PDF::Draw->font('H');
ONO::Lib::PDF::Draw->color();
return "";
}
sub pdf_draw_wall {
my (
$self,
$canvas,
$x,
$y,
$rows,
$nums_ref,
$op,
$numsys,
$mode,
$vars_ref,
$num_comma,
$switches,
) = @_;
#: Draw a wall image.
#:
#: op - add, sub, corr
#:
#: Switches:
#:
#: -W less wide (12.5 instead of 15 mm)
my (%vars,@nums,$counter,$HTML,$stat_correct,$stat_wrong,$stat_todo_total,$first_question);
if ($vars_ref) {
%vars = %$vars_ref;
}
if ($nums_ref) {
@nums = @$nums_ref;
}
my $maxwidth = $rows * 15;
my $top = 20+((5-$rows)*70);
my $pdf_width = 15;
my $pdf_height = 7.5;
if ($switches =~ /W/) {
$pdf_width = 12.5;
}
for (my $r = 0; $r < $rows; $r++) {
my $subrand = int(rand($r));
if ($mode eq "web") {
if ($vars{"output_web_cache_subrand_$r"} ne "") {
$subrand = $vars{"output_web_cache_subrand_$r"};
}
$HTML .= qq~<input type="hidden" name="output_web_cache_subrand_$r" value="$subrand">
<table class="default_table auto">
<tr class="bt bb">
~;
}
for (my $w = 0; $w < $r+1; $w++) {
my $off_x = (($rows-$r)*$pdf_width/2)-$pdf_width/2;
my $off_y = $r * 0.17;
my $BG = "fabric";
my $NUMBER;
if ($mode eq "pdf") {
ONO::Lib::PDF::Draw->rect($canvas,$x+($w*$pdf_width)+$off_x,$y+($r*$pdf_height)-$off_y,$x+(($w+1)*$pdf_width)+$off_x,$y+(($r+1)*$pdf_height)-$off_y,0.5,"",&pdf_grey());
}
if ($nums[$counter] =~ /[0-9]/ && ($mode eq "web" || $op eq "corr" || ($op eq "add" && $r == $rows-1) || ($op eq "sub" && ($r == 0 || $w == $subrand)))) {
($nums[$counter]) = ONO::FW::Apps::Core->numsys(ONO::FW::Apps::Core->fix_fp_rounding($nums[$counter]),0,0,$numsys);
if ($num_comma ne ".") {
$nums[$counter] =~ s~\.~$num_comma~g;
}
if ($mode eq "web") {
if (($op eq "add" && $r == $rows-1) || ($op eq "sub" && ($r == 0 || $w == $subrand))) {
$NUMBER = qq~<div class="p20"> $nums[$counter] </div>~;
} else {
$stat_todo_total++;
$vars{"output_web_answer_$counter"} = ONO::FW::Apps::Core->clean_answer_math($vars{"output_web_answer_$counter"},"r");
$NUMBER = qq~<div class="pad10_2" style="height:48px;padding-top:20px">
<input type="text" id="output_web_answer_id_$counter" name="output_web_answer_$counter" value="$vars{"output_web_answer_$counter"}"
class="center w90" placeholder="?">
</div>
~;
if (!$first_question) {
$NUMBER .= qq~<script>document.getElementById('output_web_answer_id_$counter').focus();</script>~;
}
if ($vars{"output_web_answer_$counter"} ne "") {
$stat_todo_total--;
$stat_wrong++;
$BG = "red";
if ($vars{"output_web_answer_$counter"} eq $nums[$counter]) {
$stat_correct++;
$stat_wrong--;
$BG = "green green bold";
$NUMBER = qq~<div class="p20">$nums[$counter]</div><input type="hidden" name="output_web_answer_$counter" value="$vars{"output_web_answer_$counter"}">~;
} else {
$vars{'output_web_mistakes'}++;
}
} else {
$first_question++;
}
}
} else {
my $resize;
if (length $nums[$counter] > 5) {
$resize = 16 - (length $nums[$counter]);
ONO::Lib::PDF::Draw->font('',$resize);
}
ONO::Lib::PDF::Draw->text($canvas,$x+($w*$pdf_width)+$off_x+$pdf_width/2,$y+($r*$pdf_height)-$off_y+5.25,$nums[$counter],"center");
if ($resize) {
ONO::Lib::PDF::Draw->font('',12);
}
}
}
if ($mode eq "web") {
if ($NUMBER !~ /[0-9]/) {
$NUMBER = 0;
}
$HTML.= qq~ <td class="p0 bg_$BG bl br"><div class="center" style="width:140px">$NUMBER</div></td>~;
}
$counter++;
}
if ($mode eq "web") {
$HTML .= qq~ </tr>
</table>
~;
}
}
return (
qq~<div style="margin-top:${top}px">$HTML</div>~,
$stat_correct,
$stat_wrong,
$stat_todo_total,
$vars{'output_web_mistakes'},
);
}
sub pdf_draw_stepcalc {
my (
$self,
$canvas,
$pdf_x,
$pdf_y,
$type,
$size,
$op,
$nums_ref,
$switches,
) = @_;
#: Draw a step-calc image.
#:
#: type can be "boxes", "arrows" or "numline"
#:
#: Switches:
#:
#: -B black & white (greyscale)
my @nums = @$nums_ref;
my $SIGN = "+";
my $GREY = "0:155:155:155";
my $GREY2 = "0:100:100:100";
my $GREY3 = $GREY; #"0:222:222:222";
my $COL1 = "0:200:250:200";
my $COL2 = "0:120:210:120";
my $COL3 = "0:220:255:220";
if ($op eq "sub") {
$SIGN = "-";
$COL1 = "0:250:200:200";
$COL2 = "0:210:120:120";
$COL3 = "0:255:220:220";
}
if ($switches =~ /B/) {
$COL1 = "0:220:220:220";
$COL2 = "0:160:160:160";
$COL3 = "0:240:240:240";
}
# devstation: total size
if (ONO::IO->devstation) {
# ONO::Lib::PDF::Draw->rect($canvas,$pdf_x+5*$size,$pdf_y,$pdf_x+49*$size,$pdf_y+18*$size,1);
}
if (!$type || $type eq "boxes") {
foreach my $opt (1,4,5) {
if ($nums[$opt] ne "") {
$nums[$opt] = "$SIGN$nums[$opt]";
}
}
# upper line / arrow
ONO::Lib::PDF::Draw->line($canvas, $pdf_x+15*$size, $pdf_y+3.5*$size, $pdf_x+39*$size, $pdf_y+3.5*$size, 1, "", "", "s:4", "a:4");
# diagonal color lines
ONO::Lib::PDF::Draw->line($canvas, $pdf_x+28*$size, $pdf_y+3.5*$size, $pdf_x+38*$size, $pdf_y+13.5*$size, 7*$size );
ONO::Lib::PDF::Draw->line($canvas, $pdf_x+28*$size, $pdf_y+3.5*$size, $pdf_x+38*$size, $pdf_y+13.5*$size, 5*$size, $COL2 );
ONO::Lib::PDF::Draw->line($canvas, $pdf_x+26*$size, $pdf_y+3.5*$size, $pdf_x+16*$size, $pdf_y+13.5*$size, 7*$size );
ONO::Lib::PDF::Draw->line($canvas, $pdf_x+26*$size, $pdf_y+3.5*$size, $pdf_x+16*$size, $pdf_y+13.5*$size, 5*$size, $COL2 );
# main boxes
ONO::Lib::PDF::Draw->rect($canvas, $pdf_x+5*$size, $pdf_y, $pdf_x+14*$size, $pdf_y+7*$size, 1,"0:25:25:25","0:240:240:240",1);
ONO::Lib::PDF::Draw->rect($canvas, $pdf_x+22*$size, $pdf_y, $pdf_x+32*$size, $pdf_y+7*$size, 1,"0:25:25:25",$COL1,1);
ONO::Lib::PDF::Draw->rect($canvas, $pdf_x+40*$size, $pdf_y, $pdf_x+49*$size, $pdf_y+7*$size, 1,"0:25:25:25","0:240:240:240",1);
# lower line
ONO::Lib::PDF::Draw->line($canvas, $pdf_x+11*$size, $pdf_y+13.5*$size, $pdf_x+43*$size, $pdf_y+13.5*$size, 1,$GREY);
ONO::Lib::PDF::Draw->arc($canvas, $pdf_x+11*$size, $pdf_y+11.5*$size, 2*$size, 3,1, "",$GREY);
ONO::Lib::PDF::Draw->arc($canvas, $pdf_x+43*$size, $pdf_y+11.5*$size, 2*$size, 2,1, "",$GREY);
ONO::Lib::PDF::Draw->line($canvas, $pdf_x+9*$size, $pdf_y+8*$size, $pdf_x+9*$size, $pdf_y+11.5*$size, 1,$GREY);
ONO::Lib::PDF::Draw->line($canvas, $pdf_x+45*$size, $pdf_y+8*$size, $pdf_x+45*$size, $pdf_y+11.5*$size, 1,$GREY);
ONO::Lib::PDF::Draw->line($canvas, $pdf_x+45*$size, $pdf_y+8*$size, $pdf_x+43.5*$size, $pdf_y+9.5*$size, 1,$GREY);
ONO::Lib::PDF::Draw->line($canvas, $pdf_x+45*$size, $pdf_y+8*$size, $pdf_x+46.5*$size, $pdf_y+9.5*$size, 1,$GREY);
ONO::Lib::PDF::Draw->line($canvas, $pdf_x+7.5*$size, $pdf_y+8*$size, $pdf_x+10.5*$size, $pdf_y+8*$size, 1,$GREY);
# sub boxes
ONO::Lib::PDF::Draw->rect($canvas, $pdf_x+12*$size, $pdf_y+9*$size, $pdf_x+21*$size, $pdf_y+16*$size, 1,$GREY,$COL3,1);
ONO::Lib::PDF::Draw->rect($canvas, $pdf_x+23*$size, $pdf_y+11*$size, $pdf_x+31*$size, $pdf_y+18*$size, 1,$GREY,"0:250:250:250",1);
ONO::Lib::PDF::Draw->rect($canvas, $pdf_x+33*$size, $pdf_y+9*$size, $pdf_x+42*$size, $pdf_y+16*$size, 1,$GREY,$COL3,1);
# numbers
ONO::Lib::PDF::Draw->font("HB",12*$size);
ONO::Lib::PDF::Draw->text($canvas, $pdf_x+9.25*$size, $pdf_y+5*$size, $nums[0], "c");
ONO::Lib::PDF::Draw->text($canvas, $pdf_x+44.75*$size, $pdf_y+5*$size, $nums[2], "c");
ONO::Lib::PDF::Draw->font("H",12*$size);
ONO::Lib::PDF::Draw->text($canvas, $pdf_x+27*$size, $pdf_y+5*$size, $nums[1], "c");
ONO::Lib::PDF::Draw->font("HB",10*$size);
ONO::Lib::PDF::Draw->text($canvas, $pdf_x+27*$size, $pdf_y+15.75*$size, $nums[3], "c");
if (!$nums[4] && !$nums[5]) {
ONO::Lib::PDF::Draw->font("H",8*$size);
ONO::Lib::PDF::Draw->text($canvas, $pdf_x+13*$size, $pdf_y+13.25*$size, $SIGN, "");
ONO::Lib::PDF::Draw->text($canvas, $pdf_x+34*$size, $pdf_y+13.25*$size, $SIGN, "");
} else {
ONO::Lib::PDF::Draw->font("H",10*$size);
ONO::Lib::PDF::Draw->text($canvas, $pdf_x+16*$size, $pdf_y+13.75*$size, $nums[4], "c");
ONO::Lib::PDF::Draw->text($canvas, $pdf_x+38*$size, $pdf_y+13.75*$size, $nums[5], "c");
}
# T/O
# if ($size > 1.2) {
#
# ONO::Lib::PDF::Draw->circle($canvas, $pdf_x+20.5*$size, $pdf_y+9.5*$size, 2.5,1,"0:250:250:250");
# ONO::Lib::PDF::Draw->circle($canvas, $pdf_x+33.5*$size, $pdf_y+9.5*$size, 2.5,1,"0:250:250:250");
#
# ONO::Lib::PDF::Draw->font("H",6*$size);
#
# ONO::Lib::PDF::Draw->text($canvas, $pdf_x+19.75*$size, $pdf_y+10.25*$size, "Z");
# ONO::Lib::PDF::Draw->text($canvas, $pdf_x+32.75*$size, $pdf_y+10.25*$size, "E");
#
# }
ONO::Lib::PDF::Draw->font("H",12*$size);
}
if ($type eq "arrows") {
# instruction
ONO::Lib::PDF::Draw->font("H",10*$size);
if ($nums[2] ne "") {
ONO::Lib::PDF::Draw->text($canvas, $pdf_x+5*$size, $pdf_y+2.5*$size, "$nums[0] $SIGN $nums[1] = $nums[2]");
} else {
ONO::Lib::PDF::Draw->text($canvas, $pdf_x+5*$size, $pdf_y+2.5*$size, "$nums[0] $SIGN $nums[1] = ____");
}
# line
# ONO::Lib::PDF::Draw->line($canvas, $pdf_x+5*$size, $pdf_y+12*$size, $pdf_x+49*$size, $pdf_y+12*$size, 1);
#
# ONO::Lib::PDF::Draw->line($canvas, $pdf_x+9.5*$size, $pdf_y+11*$size, $pdf_x+9.5*$size, $pdf_y+13*$size, 1);
# ONO::Lib::PDF::Draw->line($canvas, $pdf_x+29*$size, $pdf_y+11*$size, $pdf_x+29*$size, $pdf_y+13*$size, 1);
# ONO::Lib::PDF::Draw->line($canvas, $pdf_x+44.5*$size, $pdf_y+11*$size, $pdf_x+44.5*$size, $pdf_y+13*$size, 1);
# main boxes
ONO::Lib::PDF::Draw->rect($canvas, $pdf_x+5*$size, $pdf_y+12*$size, $pdf_x+14*$size, $pdf_y+18*$size, 1,"0:25:25:25","0:240:240:240",1);
ONO::Lib::PDF::Draw->rect($canvas, $pdf_x+24*$size, $pdf_y+12*$size, $pdf_x+34*$size, $pdf_y+18*$size, 1,"0:25:25:25","0:240:240:240",1);
ONO::Lib::PDF::Draw->rect($canvas, $pdf_x+40*$size, $pdf_y+12*$size, $pdf_x+49*$size, $pdf_y+18*$size, 1,"0:25:25:25","0:240:240:240",1);
# arrows: arc 2 first:
ONO::Lib::PDF::Draw->arc($canvas, $pdf_x+32.75*$size, $pdf_y+11.5*$size, 3.75*$size, 4,1, "",$GREY2);
ONO::Lib::PDF::Draw->arc($canvas, $pdf_x+40.75*$size, $pdf_y+11.5*$size, 3.75*$size, 1,1, "",$GREY2);
ONO::Lib::PDF::Draw->rect($canvas, $pdf_x+28*$size, $pdf_y+9*$size, $pdf_x+32*$size, $pdf_y+11*$size, 1, "0:255:255:255","0:255:255:255");
# arrows: arc 1 is second:
ONO::Lib::PDF::Draw->line($canvas, $pdf_x+13.25*$size, $pdf_y+7.75*$size, $pdf_x+25.25*$size, $pdf_y+7.75*$size, 1,$GREY2);
ONO::Lib::PDF::Draw->arc($canvas, $pdf_x+13.25*$size, $pdf_y+11.5*$size, 3.75*$size, 4,1, "",$GREY2);
ONO::Lib::PDF::Draw->arc($canvas, $pdf_x+25.25*$size, $pdf_y+11.5*$size, 3.75*$size, 1,1, "",$GREY2);
# arrows: pointy end 1:
ONO::Lib::PDF::Draw->line($canvas, $pdf_x+29.10*$size, $pdf_y+11.5*$size, $pdf_x+27.25*$size, $pdf_y+10*$size, 1,$GREY2);
ONO::Lib::PDF::Draw->line($canvas, $pdf_x+29*$size, $pdf_y+11.5*$size, $pdf_x+30*$size, $pdf_y+9.6*$size, 1,$GREY2);
# arrows: pointy end 2:
ONO::Lib::PDF::Draw->line($canvas, $pdf_x+44.60*$size, $pdf_y+11.5*$size, $pdf_x+42.75*$size, $pdf_y+10*$size, 1,$GREY2);
ONO::Lib::PDF::Draw->line($canvas, $pdf_x+44.5*$size, $pdf_y+11.5*$size, $pdf_x+45.5*$size, $pdf_y+9.6*$size, 1,$GREY2);
# sub boxes
ONO::Lib::PDF::Draw->rect($canvas, $pdf_x+14.25*$size, $pdf_y+5.25*$size, $pdf_x+24.25*$size, $pdf_y+10.25*$size, 1,$GREY,$COL3,1);
ONO::Lib::PDF::Draw->rect($canvas, $pdf_x+32.75*$size, $pdf_y+5.25*$size, $pdf_x+40.75*$size, $pdf_y+10.25*$size, 1,$GREY,$COL3,1);
# numbers
ONO::Lib::PDF::Draw->font("HB",12*$size);
ONO::Lib::PDF::Draw->text($canvas, $pdf_x+9.25*$size, $pdf_y+16.5*$size, $nums[0], "c");
ONO::Lib::PDF::Draw->text($canvas, $pdf_x+29*$size, $pdf_y+16.5*$size, $nums[3], "c");
ONO::Lib::PDF::Draw->text($canvas, $pdf_x+44.75*$size, $pdf_y+16.5*$size, $nums[2], "c");
if (!$nums[4] && !$nums[5]) {
ONO::Lib::PDF::Draw->font("H",8*$size);
ONO::Lib::PDF::Draw->text($canvas, $pdf_x+15*$size, $pdf_y+8.75*$size, "$SIGN", "");
ONO::Lib::PDF::Draw->text($canvas, $pdf_x+33.25*$size, $pdf_y+8.75*$size, "$SIGN", "");
} else {
ONO::Lib::PDF::Draw->font("H",10*$size);
ONO::Lib::PDF::Draw->text($canvas, $pdf_x+19*$size, $pdf_y+9*$size, "$SIGN$nums[4]", "c");
ONO::Lib::PDF::Draw->text($canvas, $pdf_x+36.5*$size, $pdf_y+9*$size, "$SIGN$nums[5]", "c");
}
}
if ($type eq "rows") {
# main
ONO::Lib::PDF::Draw->rect($canvas, $pdf_x+21.5, $pdf_y+10, $pdf_x+33.5, $pdf_y+34, 0,$COL1,$COL1);
ONO::Lib::PDF::Draw->circle($canvas, $pdf_x+27.5, $pdf_y+8.5, 7 , 0,$COL2,$COL2);
ONO::Lib::PDF::Draw->circle($canvas, $pdf_x+27.5, $pdf_y+34, 6 , 0,$COL1,$COL1);
# lines
ONO::Lib::PDF::Draw->line($canvas, $pdf_x+7, $pdf_y+11,$pdf_x+19.5,$pdf_y+11,1);
ONO::Lib::PDF::Draw->line($canvas, $pdf_x+35.5, $pdf_y+11,$pdf_x+50,$pdf_y+11,1);
for (my $l = 0; $l < 2; $l++) {
ONO::Lib::PDF::Draw->line($canvas, $pdf_x+5, $pdf_y+23+$l*11,$pdf_x+19.5,$pdf_y+23+$l*11,0.5);
ONO::Lib::PDF::Draw->line($canvas, $pdf_x+22.5, $pdf_y+23+$l*11,$pdf_x+32.5,$pdf_y+23+$l*11,0.5,$COL2);
if (!$l) {
ONO::Lib::PDF::Draw->line($canvas,$pdf_x+35.5,$pdf_y+23+$l*11,$pdf_x+48,$pdf_y+23+$l*11,0.5);
} else {
ONO::Lib::PDF::Draw->line($canvas,$pdf_x+35.5,$pdf_y+23+$l*11,$pdf_x+50,$pdf_y+23+$l*11,0.5);
}
}
# arrow 1
ONO::Lib::PDF::Draw->circle($canvas, $pdf_x+6.75, $pdf_y+8.75, 1.58, 0,$GREY3,$GREY3);
ONO::Lib::PDF::Draw->arc($canvas, $pdf_x+7.5, $pdf_y+11.25, 2, 4,2, "",$GREY3);
ONO::Lib::PDF::Draw->line($canvas, $pdf_x+5.5, $pdf_y+11, $pdf_x+5.5, $pdf_y+18.5, 2,$GREY3);
ONO::Lib::PDF::Draw->line($canvas, $pdf_x+7.5, $pdf_y+20.5, $pdf_x+9, $pdf_y+20.5, 2,$GREY3);
ONO::Lib::PDF::Draw->arc($canvas, $pdf_x+7.5, $pdf_y+18.5, 2, 3,2, "",$GREY3);
ONO::Lib::PDF::Draw->line($canvas, $pdf_x+7.5, $pdf_y+19, $pdf_x+9.25, $pdf_y+20.75, 2,$GREY3);
ONO::Lib::PDF::Draw->line($canvas, $pdf_x+7.5, $pdf_y+22, $pdf_x+9.25, $pdf_y+20.25, 2,$GREY3);
# arrow 2
ONO::Lib::PDF::Draw->circle($canvas, $pdf_x+38, $pdf_y+23.75, 1.58, 0,$GREY3,$GREY3);
ONO::Lib::PDF::Draw->arc($canvas, $pdf_x+35.5, $pdf_y+24, 2, 2,2, "",$GREY3);
ONO::Lib::PDF::Draw->line($canvas, $pdf_x+18, $pdf_y+26, $pdf_x+35.5, $pdf_y+26, 2,$GREY3);
ONO::Lib::PDF::Draw->line($canvas, $pdf_x+22, $pdf_y+26, $pdf_x+33, $pdf_y+26, 2,$COL2);
ONO::Lib::PDF::Draw->line($canvas, $pdf_x+19.25, $pdf_y+24.5, $pdf_x+17.5, $pdf_y+26.25, 2,$GREY3);
ONO::Lib::PDF::Draw->line($canvas, $pdf_x+19.25, $pdf_y+27.5, $pdf_x+17.5, $pdf_y+25.75, 2,$GREY3);
# arrow 3
ONO::Lib::PDF::Draw->arc($canvas, $pdf_x+47.5, $pdf_y+26.25, 2, 2,2, "",$GREY3);
ONO::Lib::PDF::Draw->circle($canvas, $pdf_x+47.75, $pdf_y+28.75, 1.58, 0,$GREY3,$GREY3);
ONO::Lib::PDF::Draw->line($canvas, $pdf_x+49.5, $pdf_y+12.5, $pdf_x+49.5, $pdf_y+26.5, 2,$GREY3);
ONO::Lib::PDF::Draw->line($canvas, $pdf_x+49.75, $pdf_y+12.25, $pdf_x+47.5, $pdf_y+14.5, 2,$GREY3);
ONO::Lib::PDF::Draw->line($canvas, $pdf_x+49.25, $pdf_y+12.25, $pdf_x+51.5, $pdf_y+14.5, 2,$GREY3);
ONO::Lib::PDF::Draw->font('HB','14');
ONO::Lib::PDF::Draw->text($canvas, $pdf_x+19, $pdf_y+10, $nums[0], "r");
ONO::Lib::PDF::Draw->color("0:255:255:255");
if ($nums[1] > 99) {
ONO::Lib::PDF::Draw->text($canvas, $pdf_x+27.5, $pdf_y+10, "$SIGN$nums[1]","c");
} else {
ONO::Lib::PDF::Draw->text($canvas, $pdf_x+27.5, $pdf_y+10, "$SIGN $nums[1]","c");
}
ONO::Lib::PDF::Draw->color();
# A B C
ONO::Lib::PDF::Draw->font('HB',6);
ONO::Lib::PDF::Draw->color("0:255:255:255");
ONO::Lib::PDF::Draw->text($canvas, $pdf_x+6.75, $pdf_y+9.5, "A","c");
ONO::Lib::PDF::Draw->text($canvas, $pdf_x+38, $pdf_y+24.5, "B","c");
ONO::Lib::PDF::Draw->text($canvas, $pdf_x+47.75, $pdf_y+29.5, "C","c");
ONO::Lib::PDF::Draw->font('H',12);
ONO::Lib::PDF::Draw->color();
# text...
# @nums = ($num1,$num2,$res,$step,$s1,$s2);
ONO::Lib::PDF::Draw->text($canvas, $pdf_x+36, $pdf_y+10, "=", "");
if ($nums[2] ne "") {
ONO::Lib::PDF::Draw->text($canvas, $pdf_x+49, $pdf_y+10, $nums[2], "r");
}
if ($nums[4] > 99 || $nums[5] > 99) {
ONO::Lib::PDF::Draw->font('H','10');
} else {
ONO::Lib::PDF::Draw->font('H','14');
}
if ($nums[2] ne "") {
ONO::Lib::PDF::Draw->text($canvas, $pdf_x+47, $pdf_y+33, $nums[2], "r");
}
if ($nums[3] ne "") {
ONO::Lib::PDF::Draw->text($canvas, $pdf_x+19.5, $pdf_y+22, $nums[0], "r");
ONO::Lib::PDF::Draw->text($canvas, $pdf_x+47, $pdf_y+22, $nums[3], "r");
}
if ($nums[4] ne "") {
ONO::Lib::PDF::Draw->text($canvas, $pdf_x+32, $pdf_y+22, $nums[4], "r");
ONO::Lib::PDF::Draw->text($canvas, $pdf_x+19.5, $pdf_y+33, $nums[3], "r");
}
ONO::Lib::PDF::Draw->text($canvas, $pdf_x+23, $pdf_y+22, $SIGN, "");
ONO::Lib::PDF::Draw->text($canvas, $pdf_x+35.5, $pdf_y+22, "=", "");
if ($nums[5] ne "") {
ONO::Lib::PDF::Draw->text($canvas, $pdf_x+32, $pdf_y+33, $nums[5], "r");
}
ONO::Lib::PDF::Draw->text($canvas, $pdf_x+23, $pdf_y+33, $SIGN, "");
ONO::Lib::PDF::Draw->text($canvas, $pdf_x+35.5, $pdf_y+33, "=", "");
}
ONO::Lib::PDF::Draw->font('H',12);
}
sub pdf_draw_result_hints {
my (
$self,
$canvas,
$x,
$y,
$width,
$height,
$items_x,
$items_y,
$res_ref,
$switches,
$comma,
) = @_;
#: Draw result hints.
#:
#: Switches:
#:
#: -b bold
#: -d text down / lower (0.5 mm)
#: -D text down / lower (1 mm)
#: -E don't display empty boxes (will still display zero results)
#: -l font larger (14)
#: -L font x-large (16)
#: -n font normal size (12)
#: -u text up / higher (0.5 mm)
#: -U text up / higher (1 mm)
#: -Z don't display zero results
my @res = ONO::Lib::Basic->randomize_array(@$res_ref);
my ($counter,$font_y);
my $rw = $width/$items_x;
my $rh = $height/$items_y;
if ($switches =~ /b/) {
ONO::Lib::PDF::Draw->font("HB");
}
if ($switches =~ /n/) {
ONO::Lib::PDF::Draw->font("",12);
}
if ($switches =~ /l/) {
ONO::Lib::PDF::Draw->font("",14);
}
if ($switches =~ /L/) {
ONO::Lib::PDF::Draw->font("",16);
}
if ($switches =~ /u/) {
$font_y = -0.5;
}
if ($switches =~ /U/) {
$font_y = -1;
}
if ($switches =~ /d/) {
$font_y = 0.5;
}
if ($switches =~ /D/) {
$font_y = 1;
}
for (my $ix = 0; $ix < $items_x; $ix++) {
for (my $iy = 0; $iy < $items_y; $iy++) {
my $result = $res[$counter];
my ($smaller,$off_x,$hide);
if ($switches =~ /Z/ && !$result) {
$hide = 1;
}
if ($switches =~ /E/ && $result eq "") {
$hide = 1;
}
if (!$hide) {
my $min_width = (length $result)*2.5;
if ($min_width < $rw) {
$smaller = int($rw - $min_width)/4;
$off_x = int(rand($smaller*2)-$smaller)/2;
}
if ($comma ne "" && $comma ne ".") {
$result =~ s~\.~$comma~g;
}
my ($c1,$c2,$c3) = (220+int(rand(rand(33))),220+int(rand(rand(33))),220+int(rand(rand(33))));
ONO::Lib::PDF::Draw->rect($canvas,$x+($ix*$rw)+1+$smaller+$off_x,$y+($iy*$rh)+1,$x+(($ix+1)*$rw)-1-$smaller+$off_x,$y+(($iy+1)*$rh)-1,1,"0:25:25:25","0:$c1:$c2:$c3",2);
ONO::Lib::PDF::Draw->text($canvas,$x+$ix*$rw+$rw/2+$off_x,$y+($iy*$rh)+$rh/1.5+$font_y,$result,"c");
}
$counter++;
}
}
}
sub pdf_draw_result_hints_resblock {
my (
$self,
$res_ref,
$b1,
$b2,
) = @_;
#: Draw a result hints block.
my @res = @$res_ref;
$b1 = $b1*5;
$b2 = $b2*5;
my @block = ($res[$b1],$res[$b1+1],$res[$b1+2],$res[$b1+3],$res[$b1+4]);
if ($b2) {
@block = (@block,$res[$b2],$res[$b2+1],$res[$b2+2],$res[$b2+3],$res[$b2+4]);
}
return @block;
}
sub pdf_grey {
#: Generate grey color.
my $r1 = 230+int(rand(20));
if (int(rand(100)) > 33) {
$r1 = 250;
if (int(rand(100)) > 66) {
$r1 = 230;
}
}
return "0:$r1:$r1:$r1";
}
sub pdf_black {
#: Generate black (dark) color.
my $r1 = int(rand(100));
return "0:$r1:$r1:$r1";
}
###################################################################
# OLD STUFF...
###################################################################
sub mkpdf {
my (
$self,
$BLK_ref,
$vars_ref,
$HTTP,
$BASE,
) = @_;
#: Generate a PDF file via ONO app - start.
my %BLK = %$BLK_ref;
my %vars = %$vars_ref;
my (
$sec,$min,$hour,
$mday,$mon,$year,
$wday,$yday,$isdst
) = ONO::Lib::DateTime::ToolBox->get;
my $pdfkey = "$year$mon$mday\_".ONO::Lib::Code::RandomID->make;
# generate the file
my $FILE = "pdf/pdf-$pdfkey.pdf";
my $TEMPLATE = "ono-data/school/pdf/oli.pdf";
if ($vars{'auto_eval'}) {
$TEMPLATE = "ono-data/school/pdf/oli_smilies.pdf";
}
if (ONO::Lib::Web::Domain->variation eq "education") {
$FILE = "oli/lu/$FILE";
$TEMPLATE = "oli/lu/$TEMPLATE";
}
ONO::FW::Apps::PDF->new($FILE,$TEMPLATE);
# print the headers
ONO::FW::Apps::Core->headers(\%vars);
if ($vars{'auto_eval'}) {
ONO::FW::Apps::PDF->self_evaluation(\%BLK,\%vars);
}
# make statistics
my $string = "x";
if ($vars{'app_input_print_options_unique_copies'} > 1) {
for (my $i = 1; $i < $vars{'app_input_print_options_unique_copies'}; $i++) {
$string .= "x";
}
}
my $community = ONO::IO->community();
ONO::IO->append("var/community/$community/statistics/school_pdf_pages.txt",$string);
ONO::IO->append("var/community/$community/statistics/school_pdf_pages/$year$mon$mday.txt",$string);
if ($vars{'output_paper_save'}) {
return "";
} else {
# return the "please wait" message
return qq~<bgimage="/images/app_backgrounds/printing.jpg" alt="">~.ONO::FW::Apps::PDF->please_wait($pdfkey,\%BLK,\%vars,"",$HTTP,$BASE);
}
}
sub output_paper {
my (
$self,
$pdfkey,
$BLK_ref,
$vars_ref,
$HTTP,
$BASE,
$switches,
) = @_;
#: Generate a PDF file via ONO app - finish.
#:
#: Switches:
#:
#: Simply transmitted to ONO_FW_Edu_PDF_please_wait, adding switch -I,
#: see please_wait function for details.
my %vars = %$vars_ref;
my (
$sec,$min,$hour,
$mday,$mon,$year,
$wday,$yday,$isdst
) = ONO::Lib::DateTime::ToolBox->get;
my $community = ONO::IO->community();
my $string = "x";
if ($vars{'app_input_print_options_unique_copies'} > 1) {
for (my $i = 1; $i < $vars{'app_input_print_options_unique_copies'}; $i++) {
$string .= "x";
}
}
if (!$vars{'output_worksheet_maker'}) {
ONO::IO->append("var/community/$community/statistics/school_pdf_pages.txt",$string);
ONO::IO->append("var/community/$community/statistics/school_pdf_pages/$year$mon$mday.txt",$string);
}
if ($pdfkey !~ /^tmp(_|-)/ && $pdfkey !~ /(_|-)tmp(_|-)/ && $pdfkey !~ /(_|-)tmp$/) {
ONO::Lib::PDF::ToolBox->compress("pdf/pdf-$pdfkey.pdf","pdf/pdf-$pdfkey.pdf","oO");
}
if ($vars{'username'} && ($vars{'output_paper_save_exec'} || $vars{'output_paper_save_target_change'} || $vars{'output_paper_save_target_app_change'})) {
return "";
} else {
return ONO::FW::Apps::PDF->please_wait($pdfkey,$BLK_ref,$vars_ref,"",$HTTP,$BASE,"I$switches");
}
}
sub image_ids {
#: Default list of Morzino Picture Dictionary IDs that may be used
#: in ONO apps.
return (
'0005',
'0006',
'0017',
'0019',
'0020',
'0021',
'0027',
'0029',
'0030',
'0031',
'0034',
'0036',
'0038',
'0042',
'0044',
'0046',
'0050',
'0065',
'0066',
'0075',
'0087',
'0088',
'0093',
'0095',
'0096',
'0099',
'0101',
'0128',
'0144',
'0163',
'0164',
'0173',
'0183',
'0187',
'0191',
'0195',
'0202',
'0215',
'0224',
'0225',
'0238',
'0262',
'0293',
'0294',
'0312',
'0364',
'0371',
'0401',
'0418',
'0419',
'0427',
'0428',
'0429',
'0430',
'0493',
'0500',
);
}
###################################################################
# THAT'S IT :-D
###################################################################
1;
__END__