use strict; use PDF::API2::Lite; use Time::Local; my $dpi = 72; sub inch { my ($inch) = @_; return $inch *$dpi; } my $paperwidth = inch(3); my $paperheight = inch(5); #my $paperwidth = inch(8.5); #my $paperheight = inch(11); my $cardheight = inch(5); my $cardwidth = inch(3); my $cardTopMargin = inch(.125); my $cardSideMargin = inch(.125); my $yearFontSize = 18; my $monthTopMargin = inch(.25); my $columns = 3; my $rows = 4; #my $year = 2008; my @months = qw(January February March April May June July August September October November December); my @days = qw(Su Mo Tu We Th Fr Sa); my $aligns = { left => 0, center => 1, right => 2 }; #my $localtime = timelocal($sec,$min,$hour,$mday,$mon,$year); my $file = './hpda.pdf'; unlink $file; my $pdf = PDF::API2::Lite->new(); my $font = $pdf->corefont('Helvetica'); #$pdf->print $font, $size, $x, $y, $rot, $just, $text # origin for text is lower left? # size is the height of a character in "dots"? my @years = (2023..2033); my $page; for my $y (@years) { $page = $pdf->page($paperwidth,$paperheight); &drawyear($y,0,$paperheight-$cardheight); #&drawyear(2008,($paperwidth-$cardwidth)/2,$paperheight-$cardheight); } $pdf->saveas($file); exit; sub drawyear { my ($year,$xoffset,$yoffset) = @_; $pdf->strokecolor("black"); $pdf->linedash(10,10); $pdf->rect($xoffset,$yoffset,$cardwidth,$cardheight); $pdf->stroke; $pdf->print ($font, $yearFontSize, $xoffset+$cardSideMargin, $yoffset+$cardheight-$yearFontSize-$cardTopMargin/2, 0, $aligns->{left}, "$year"); $pdf->linedash(); for my $m (0..11) { my ($x, $y, $w, $h) = &monthcorners($m, $xoffset, $yoffset); &drawmonth($x, $y, $w, $h, $m); } &drawdays($year, $xoffset,$yoffset); } sub drawmonth { my ($x, $y, $width, $height, $month) = @_; $pdf->linedash(); $pdf->rect($x, $y, $width, $height); $pdf->stroke; $pdf->print($font, 10, $x+$width/2, $y+$height-inch(1/8), 0, $aligns->{center}, $months[$month]); for my $d (0..6) { $pdf->print($font, 5, $x+ ($d+.5)*$width/7, $y+$height-$monthTopMargin, 0, $aligns->{center}, $days[$d]); } } sub drawdays { my ($year, $xoffset, $yoffset) = @_; my $localtime = timelocal(1,0,0,1,0,$year); my ($sec,$min,$hour,$mday,$mon,$yr,$wday,$yday,$isdst); my $weekcount = 1; $yr = $year-1900; ($sec,$min,$hour,$mday,$mon,$yr,$wday,$yday,$isdst) = localtime($localtime); while ($yr == $year-1900) { if ($mday == 1) { $weekcount = 1; } # print ("".$yr+1900 . " $months[$mon] $mday $days[$wday] \n"); my ($x, $y, $w, $h) = &monthcorners($mon, $xoffset,$yoffset); $pdf->print($font, 5, $x + ($wday+0.5)*$w/7, $y+$h-inch(1/4)-$weekcount*inch(1/9), 0, $aligns->{center}, "$mday"); $localtime += 24*60*60; # add one day ($sec,$min,$hour,$mday,$mon,$yr,$wday,$yday,$isdst) = localtime($localtime); if ($wday == 0) { $weekcount++; } } } # return $x,$y,$w,$h for where a month should go sub monthcorners { my ($m, $xoffset,$yoffset) = @_; my $columnwidth = ($cardwidth-$cardSideMargin*2) / $columns; my $rowheight = 6.5*inch(1/9)+$monthTopMargin; # 6 weeks possible + .5 week margin * 8 dots/week + 15 dots for the month header my $i = $m % 3; my $j = int ($m / 3); return ($columnwidth*$i+$xoffset+$cardSideMargin, $yoffset+$cardheight-$rowheight*($j+1)-$cardTopMargin-$yearFontSize, $columnwidth, $rowheight); }