GDI
(Graphics Device Interface).GDI est le moteur graphique qui gère tous les graphiques à l'écran, sur les imprimantes
et peut aussi générer des bitmaps.
Avec Perl, on peut accéder à un petit nombre de fonctions du GDI grâce au
package (mal connu) Win32::NPRG.
Win32::NPRG comprend deux modules :
Wingraph.pm qui donne accès à un sous-ensemble de routines du GDI,
NPRG.pm qui permet d'imprimer des tableaux.
NPRG-0.31.zip.
Vous pouvez plus simplement installer une version binaire avec PPM, sur
mon "ppm repository" personnel.
(Ce binaire a été compilé avec Visual-C++ 6.0 Service Pack 5)
Pour cela, tapez dans une console DOS (ou faites un couper/coller) :
ppm install http://www.bribes.org/perl/ppm/Win32-NPRG.ppd
Le module Alias est nécessaire. Installez-le si ce n'est déjà fait :
ppm install Alias
Wingraph et
NPRG.Ellipse,
Arc, SetArcDirection, PolyBezier ne sont pas décrites.
Les trois scripts dans un fichier Zip : printer.zip
hello.pdf
#!perl use strict; use Win32::Wingraph; # La fonction GetCurrentPrinter retourne l'imprimante par défaut. sub GetCurrentPrinter { my %RegHash; use Win32::TieRegistry ( TiedHash => \%RegHash ); if ( Win32::IsWinNT() ) { # pour Win NT/2000/XP my $SKey=$RegHash{'\HKEY_CURRENT_USER\Software\Microsoft\Windows NT'. '\CurrentVersion\Windows'} or return undef; return (split "," , $SKey->GetValue('Device'))[0]; } else { # pour Win 9x my $SKey=$RegHash{'HKEY_CURRENT_CONFIG\System\CurrentControlSet'. '\Control\Print\Printers'} or return undef; return $SKey->GetValue('Default'); } } # programme principal my $cp=GetCurrentPrinter() or die "Pas d'imprimante ??"; my $dc=new Win32::Wingraph( device=>"$cp", desc=>'test') or die "Imprimante $cp inactive."; print "Debut impression sur $cp\n"; $dc->SetFont("Times new roman italic,36,252"); $dc->TextOut(50,100, "Salut tout le monde !"); print "Fin d'impression\n";
test.pdf
#!perl use strict; use Win32::Wingraph; # La fonction GetCurrentPrinter retourne l'imprimante par défaut. sub GetCurrentPrinter { my %RegHash; use Win32::TieRegistry ( TiedHash => \%RegHash ); if ( Win32::IsWinNT() ) { # pour Win NT/2000/XP my $SKey=$RegHash{'\HKEY_CURRENT_USER\Software\Microsoft\Windows NT'. '\CurrentVersion\Windows'} or return undef; return (split "," , $SKey->GetValue('Device'))[0]; } else { # pour Win 9x my $SKey=$RegHash{'HKEY_CURRENT_CONFIG\System\CurrentControlSet'. '\Control\Print\Printers'} or return undef; return $SKey->GetValue('Default'); } } # programme principal my $cp = GetCurrentPrinter() or die "Pas d'imprimante ??"; my $dc = new Win32::Wingraph( device => "$cp", desc => 'test' ) or die "Imprimante $cp inactive."; my $s = 'abcdef éèêëçàù ABCDEF ÉÈÊÎÏÇÀÙ'; my $y = 50; $dc->SetFont("Times new roman , 12, 252"); # Tnr normal $dc->TextOut( 100, $y, "Times (12 pts) : " . $s ); $y += 20; $dc->SetFont("Times new roman , 16, 252"); $dc->TextOut( 100, $y, "Times (16 pts) : " . $s ); $y += 32; $dc->SetFont("Times New roman Italic, 12, 252"); # TNr italique $dc->TextOut( 100, $y, "Times italique (12 pts) : " . $s ); $y += 20; $dc->SetFont("Times New roman Italic , 16, 252"); $dc->TextOut( 100, $y, "Times italique (16 pts) : " . $s ); $y += 32; $dc->SetFont("Times New Roman bold, 12, 252"); # TNR bold $dc->TextOut( 100, $y, "Times bold (12 pts) : " . $s ); $y += 20; $dc->SetFont("Times New Roman bold, 16, 252"); $dc->TextOut( 100, $y, "Times bold (16 pts) : " . $s ); $y += 32; $dc->SetFont("Arial, 12, 252"); # Arial normal $dc->TextOut( 100, $y, "Arial (12 pts) : " . $s ); $y += 20; $dc->SetFont("ARial italic, 16, 252"); # ARial italic $dc->TextOut( 100, $y, "Arial italique (16 pts) : " . $s ); $y += 32; $dc->SetFont("ARIal bold, 12, 252"); # ARIal bold $dc->TextOut( 100, $y, "Arial bold (12 pts) : " . $s ); $y += 20; $dc->SetFont("ARIAl bold italic, 12, 252"); # ARIAl bold italic $dc->TextOut( 100, $y, "Arial bold italique (12 pts) : " . $s ); $y += 50; foreach ( 2, 4, 8, 16, 32 ) { $dc->SetPen($_); $dc->MoveTo( 100, $y ); $dc->LineTo( 750, $y ); $y += 2 * $_; } $y -= 20; my $x = 100; foreach ( 0, 32, 64, 96, 128, 160 ) { $dc->SetBrush($_); $dc->FillRect( $x, $y, 100, 50 ); $x += 120; } $y += 100; $x = 100; $dc->SetPen(8); foreach ( 0, 32, 64, 96, 128, 160 ) { $dc->SetBrush($_); $dc->Ellipse( $x, $y, $x + 100, $y + 50 ); $x += 120; }
list.pl permet de lister une série de fichiers texte.W pour déterminer le nombre de caractères par ligne et après on découpe les
lignes trop longues à la hache : c'est un procédé trop rustique pour une police proportionnelle.
> perl list.pl list.pllist.pdf
#!perl use strict; use Win32::Wingraph; use Text::Tabs; # La fonction GetCurrentPrinter retourne l'imprimante par défaut. sub GetCurrentPrinter { my %RegHash; use Win32::TieRegistry ( TiedHash => \%RegHash ); if ( Win32::IsWinNT() ) { # pour Win NT/2000/XP my $SKey=$RegHash{'\HKEY_CURRENT_USER\Software\Microsoft\Windows NT'. '\CurrentVersion\Windows'} or return undef; return (split "," , $SKey->GetValue('Device'))[0]; } else { # pour Win 9x my $SKey=$RegHash{'HKEY_CURRENT_CONFIG\System\CurrentControlSet'. '\Control\Print\Printers'} or return undef; return $SKey->GetValue('Default'); } } # programme principal if ( not @ARGV ) { print " Usage : perl list.pl file1.txt file2.txt ...\n"; exit; } # ------ paramètres à personnaliser my $format = 'A4'; # format du papier A4, A3, LETTER, LEGAL ...etc my $police = 'Courier new'; # police non proport. my $taille = 10; # taille police en pt my $haut = 40; # marge haut de page my $gauche = 100; # marge gauche my $droite = 100; # marge droite my $bas = 40; # marge bas de page $tabstop = 2; # nombre d'espaces pour une tabulation \t # ------ my $cp = GetCurrentPrinter() or die "Pas d'imprimante ??"; my $dc = new Win32::Wingraph( device => $cp, desc => 'list', papersize => $format ) or die "Imprimante $cp inactive."; $dc->SetFont("$police, $taille, 252"); # codepage WinLatin1 = 252 my ( $w, $h ) = $dc->TextSize('W'); # dim caractère $w *= 1.06; # pitch = 6% de $w my $ncol = int( ( $dc->maxx - $droite - $gauche ) / $w ); my $decalg = int( 1.1 * $h ); # interligne = 10% de $h my $nlig = int( ( $dc->maxy - $haut - $bas ) / $decalg ); print "Police = $police ($taille points) $nlig lignes de $ncol caracteres\n"; my $start = 1; while ( my $fichier = shift ) { if ( open F, "<$fichier" ) { print "Impression de $fichier\n"; if ($start) { $start = 0; } else { $dc->NextPage(); $dc->SetFont("$police, $taille, 252"); } my $vert = $haut; my $c = 1; while (<F>) { $_ = expand($_); chop; if ( $_ eq '' ) { $_ = ' ' } # ligne vide while ( my $r = substr( $_, 0, $ncol, '' ) ) { $dc->TextOut( $gauche, $vert, substr( $r, 0, $ncol ) ); $vert += $decalg; $c++; if ( $c > $nlig ) { $dc->NextPage(); $dc->SetFont("$police, $taille, 252"); $c = 1; $vert = $haut; } } } close F; } else { print "Erreur ouverture $fichier\n"; } }