|  line  | 
 stmt  | 
 bran  | 
 cond  | 
 sub  | 
 pod  | 
 time  | 
 code  | 
| 
1
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 package Module::Dependency::Grapher;  | 
| 
2
 | 
2
 | 
 
 | 
 
 | 
  
2
  
 | 
 
 | 
38759
 | 
 use strict;  | 
| 
 
 | 
2
 | 
 
 | 
 
 | 
 
 | 
 
 | 
5
 | 
    | 
| 
 
 | 
2
 | 
 
 | 
 
 | 
 
 | 
 
 | 
76
 | 
    | 
| 
3
 | 
2
 | 
 
 | 
 
 | 
  
2
  
 | 
 
 | 
480
 | 
 use Module::Dependency::Info;  | 
| 
 
 | 
2
 | 
 
 | 
 
 | 
 
 | 
 
 | 
4
 | 
    | 
| 
 
 | 
2
 | 
 
 | 
 
 | 
 
 | 
 
 | 
110
 | 
    | 
| 
4
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
5
 | 
2
 | 
 
 | 
 
 | 
 
 | 
 
 | 
41459
 | 
 use vars qw/$VERSION @TIERS %LOOKUP %COLOURS  | 
| 
6
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     @numElements $colWidth $rowHeight  | 
| 
7
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     $nOffset $eOffset $sOffset $wOffset  | 
| 
8
 | 
2
 | 
 
 | 
 
 | 
  
2
  
 | 
 
 | 
11
 | 
     /;  | 
| 
 
 | 
2
 | 
 
 | 
 
 | 
 
 | 
 
 | 
12
 | 
    | 
| 
9
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
10
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 $VERSION = (q$Revision: 6632 $ =~ /(\d+)/g)[0];  | 
| 
11
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
12
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 %COLOURS = (  | 
| 
13
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     type      => [ 0,   0,   0 ],  | 
| 
14
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     links     => [ 164, 192, 255 ],  | 
| 
15
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     blob_to   => [ 192, 0,   0 ],  | 
| 
16
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     blob_from => [ 0,   192, 0 ],  | 
| 
17
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     border    => [ 192, 192, 192 ],  | 
| 
18
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     title1    => [ 64,  0,   0 ],  | 
| 
19
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     test      => [ 255, 0,   0 ],  | 
| 
20
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     black     => [ 0,   0,   0 ],  | 
| 
21
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     white     => [ 255, 255, 255 ],  | 
| 
22
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 );  | 
| 
23
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
24
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 ### PUBLIC INTERFACE FUNCTIONS  | 
| 
25
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
26
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 sub setIndex {  | 
| 
27
 | 
1
 | 
 
 | 
 
 | 
  
1
  
 | 
  
1
  
 | 
7205
 | 
     Module::Dependency::Info::setIndex(@_);  | 
| 
28
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 }  | 
| 
29
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
30
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 sub makeText {  | 
| 
31
 | 
5
 | 
 
 | 
 
 | 
  
5
  
 | 
  
1
  
 | 
2415
 | 
     my ( $kind, $seeds, $filename, $options ) = @_;  | 
| 
32
 | 
5
 | 
 
 | 
 
 | 
 
 | 
 
 | 
40
 | 
     my ( $maxitems, $pushed ) =  | 
| 
33
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
         _makeCols( $kind, $seeds, $options->{IncludeRegex}, $options->{ExcludeRegex} );  | 
| 
34
 | 
5
 | 
 
 | 
  
 50
  
 | 
 
 | 
 
 | 
41
 | 
     my $imgtitle = $options->{'Title'} || 'Dependency Tree';  | 
| 
35
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
36
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     # print the text out  | 
| 
37
 | 
5
 | 
 
 | 
 
 | 
 
 | 
 
 | 
15
 | 
     TRACE("Printing text to $filename");  | 
| 
38
 | 
5
 | 
 
 | 
 
 | 
 
 | 
 
 | 
17
 | 
     local *TXT;  | 
| 
39
 | 
5
 | 
  
 50
  
 | 
 
 | 
 
 | 
 
 | 
523
 | 
     open( TXT, "> $filename" ) or die("Can't open $filename for text write: $!");  | 
| 
40
 | 
5
 | 
 
 | 
 
 | 
 
 | 
 
 | 
124
 | 
     print TXT $imgtitle, "\n", ( '-' x length($imgtitle) ) . "\n\n";  | 
| 
41
 | 
5
 | 
  
100
  
 | 
 
 | 
 
 | 
 
 | 
114
 | 
     print TXT q[Key: Parent> indicates parent dependencies  | 
| 
42
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
       Child> are child dependencies  | 
| 
43
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
        ****> indicates the item(s) from which the relationships are drawn  | 
| 
44
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
45
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 ]                                                                unless $options->{'NoLegend'};  | 
| 
46
 | 
5
 | 
  
100
  
 | 
 
 | 
 
 | 
 
 | 
235
 | 
     print( TXT "Grapher.pm $VERSION - " . localtime() . "\n\n" ) unless $options->{'NoVersion'};  | 
| 
47
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
48
 | 
5
 | 
 
 | 
 
 | 
 
 | 
 
 | 
14
 | 
     my $pref = 'Parent>';  | 
| 
49
 | 
5
 | 
 
 | 
 
 | 
 
 | 
 
 | 
14
 | 
     for ( 0 .. $#TIERS ) {  | 
| 
50
 | 
21
 | 
  
100
  
 | 
 
 | 
 
 | 
 
 | 
52
 | 
         if    ( $_ == $pushed )     { $pref = '****>'; }  | 
| 
 
 | 
5
 | 
  
100
  
 | 
 
 | 
 
 | 
 
 | 
10
 | 
    | 
| 
51
 | 
4
 | 
 
 | 
 
 | 
 
 | 
 
 | 
7
 | 
         elsif ( $_ == $pushed + 1 ) { $pref = 'Child>'; }  | 
| 
52
 | 
21
 | 
 
 | 
 
 | 
 
 | 
 
 | 
27
 | 
         printf( TXT "%8s %s %s\n", $pref, '+-', join( ', ', sort { $a cmp $b } @{ $TIERS[$_] } ) );  | 
| 
 
 | 
40
 | 
 
 | 
 
 | 
 
 | 
 
 | 
106
 | 
    | 
| 
 
 | 
21
 | 
 
 | 
 
 | 
 
 | 
 
 | 
81
 | 
    | 
| 
53
 | 
21
 | 
  
100
  
 | 
 
 | 
 
 | 
 
 | 
73
 | 
         print( TXT "         |\n" ) unless ( $_ == $#TIERS );  | 
| 
54
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     }  | 
| 
55
 | 
5
 | 
 
 | 
 
 | 
 
 | 
 
 | 
228
 | 
     close TXT;  | 
| 
56
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 }  | 
| 
57
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
58
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 sub makeHtml {  | 
| 
59
 | 
0
 | 
 
 | 
 
 | 
  
0
  
 | 
  
1
  
 | 
0
 | 
     my ( $kind, $seeds, $filename, $options ) = @_;  | 
| 
60
 | 
0
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
     my ( $maxitems, $pushed ) =  | 
| 
61
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
         _makeCols( $kind, $seeds, $options->{IncludeRegex}, $options->{ExcludeRegex} );  | 
| 
62
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
63
 | 
0
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
     my %rowclasses = (  | 
| 
64
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
         parent => 'MDGraphParent',  | 
| 
65
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
         seed   => 'MDGraphSeed',  | 
| 
66
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
         child  => 'MDGraphChild',  | 
| 
67
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     );  | 
| 
68
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
69
 | 
0
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
     my %notes = (  | 
| 
70
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
         parent => 'Parent',  | 
| 
71
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
         seed   => '****',  | 
| 
72
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
         child  => 'Child',  | 
| 
73
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     );  | 
| 
74
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
75
 | 
0
 | 
 
 | 
  
  0
  
 | 
 
 | 
 
 | 
0
 | 
     my $imgtitle = $options->{'Title'} || 'Dependency Tree';  | 
| 
76
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
77
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     # print the HTML out  | 
| 
78
 | 
0
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
     TRACE("Printing HTML to $filename");  | 
| 
79
 | 
0
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
     local *HTML;  | 
| 
80
 | 
0
 | 
  
  0
  
 | 
 
 | 
 
 | 
 
 | 
0
 | 
     open( HTML, "> $filename" ) or die("Can't open $filename for HTML write: $!");  | 
| 
81
 | 
0
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
     print HTML qq($imgtitle\n);  | 
| 
82
 | 
0
 | 
  
  0
  
 | 
 
 | 
 
 | 
 
 | 
0
 | 
     print( HTML "Grapher.pm $VERSION - " . localtime() . "\n" )  | 
| 
83
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
         unless $options->{'NoVersion'};  | 
| 
84
 | 
0
 | 
  
  0
  
 | 
 
 | 
 
 | 
 
 | 
0
 | 
     print HTML qq[Key: $notes{'parent'} indicates parent dependencies   | 
| 
85
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 	$notes{'seed'} indicates the item(s) from which the relationships are drawn   | 
| 
86
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     $notes{'child'} are child dependencies \n\n] unless $options->{'NoLegend'};  | 
| 
87
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
88
 | 
0
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
     my $type = 'parent';  | 
| 
89
 | 
0
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
     print HTML qq(\n); 
| 
90
 | 
0
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
     print HTML qq( |  | Kind | Items |  \n); 
| 
91
 | 
0
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
     for ( 0 .. $#TIERS ) {  | 
 
| 
92
 | 
0
 | 
  
  0
  
 | 
 
 | 
 
 | 
 
 | 
0
 | 
         if    ( $_ == $pushed )     { $type = 'seed'; }  | 
 
| 
 
 | 
0
 | 
  
  0
  
 | 
 
 | 
 
 | 
 
 | 
0
 | 
    | 
 
| 
93
 | 
0
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
         elsif ( $_ == $pushed + 1 ) { $type = 'child'; }  | 
 
| 
94
 | 
0
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
         print( HTML  | 
 
| 
95
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
                 qq( |  | $notes{$type} | ),  | 
 
| 
96
 | 
0
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
             join( ', ', sort { $a cmp $b } @{ $TIERS[$_] } ),  | 
 
| 
 
 | 
0
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
    | 
 
| 
97
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
             " |  \n" 
| 
98
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
         );  | 
 
| 
99
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     }  | 
 
| 
100
 | 
0
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
     print HTML " |   \n\n";  | 
| 
101
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
102
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     # create the imagemap  | 
| 
103
 | 
0
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
     my $rv = 1;  | 
| 
104
 | 
0
 | 
  
  0
  
 | 
 
 | 
 
 | 
 
 | 
0
 | 
     if ( $options->{ImageMap} ) {  | 
| 
105
 | 
0
 | 
 
 | 
  
  0
  
 | 
 
 | 
 
 | 
0
 | 
         my $code = $options->{ImageMapCode} || \&_imgmapdefault;  | 
| 
106
 | 
0
 | 
 
 | 
  
  0
  
 | 
 
 | 
 
 | 
0
 | 
         my $frmt = $options->{HrefFormat}   || '';  | 
| 
107
 | 
0
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
         _imageDimsSet();  | 
| 
108
 | 
0
 | 
  
  0
  
 | 
 
 | 
 
 | 
 
 | 
0
 | 
         if ( $maxitems < 8 ) {  | 
| 
 
 | 
 
 | 
  
  0
  
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
109
 | 
0
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
             $rowHeight = 8 * $rowHeight * 1.5 / $maxitems;  | 
| 
110
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
         }  | 
| 
111
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
         elsif ( $maxitems < 16 ) {  | 
| 
112
 | 
0
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
             $rowHeight = 16 * $rowHeight / $maxitems;  | 
| 
113
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
         }  | 
| 
114
 | 
0
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
         _packObjects( $rowHeight * $maxitems, 5 );  | 
| 
115
 | 
0
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
         my $str = qq( | 
| 
116
 | 
0
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
         foreach my $v ( values %LOOKUP ) { $str .= $code->( $v, $frmt ); }  | 
| 
 
 | 
0
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
    | 
| 
117
 | 
0
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
         $str .= qq(\n);  | 
| 
118
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
119
 | 
0
 | 
  
  0
  
 | 
 
 | 
 
 | 
 
 | 
0
 | 
         if ( lc( $options->{ImageMap} ) eq 'print' ) {  | 
| 
120
 | 
0
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
             print HTML $str;  | 
| 
121
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
         }  | 
| 
122
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
         else {  | 
| 
123
 | 
0
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
             $rv = $str;  | 
| 
124
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
         }  | 
| 
125
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     }  | 
| 
126
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
127
 | 
0
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
     close HTML;  | 
| 
128
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
129
 | 
0
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
     return $rv;  | 
| 
130
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 }  | 
| 
131
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
132
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 sub _imgmapdefault {  | 
| 
133
 | 
0
 | 
 
 | 
 
 | 
  
0
  
 | 
 
 | 
0
 | 
     my ( $v, $frmt ) = @_;  | 
| 
134
 | 
0
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
     my $pack = $v->{'package'};  | 
| 
135
 | 
0
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
     my $alt  = "Root the dependency tree on '$pack'";  | 
| 
136
 | 
0
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
     return qq(
137
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
         . sprintf( $frmt, $pack )  | 
| 
138
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
         . q(" shape="rect" coords=")  | 
| 
139
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
         . int( $v->{'x'} - 3 ) . ','  | 
| 
140
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
         . int( $v->{'y'} - 1 ) . ','  | 
| 
141
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
         . int( $v->{'x2'} + 3 ) . ','  | 
| 
142
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
         . int( $v->{'y'} + 9 )  | 
| 
143
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
         . qq(" alt="$alt" title="$alt" />\n);  | 
| 
144
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 }  | 
| 
145
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
146
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 sub makeImage {  | 
| 
147
 | 
0
 | 
 
 | 
 
 | 
  
0
  
 | 
  
1
  
 | 
0
 | 
     require GD;  | 
| 
148
 | 
0
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
     import GD;  | 
| 
149
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
150
 | 
0
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
     my ( $kind, $seeds, $filename, $options ) = @_;  | 
| 
151
 | 
0
 | 
 
 | 
  
  0
  
 | 
 
 | 
 
 | 
0
 | 
     my $type     = uc( $options->{'Format'} ) || 'PNG';  | 
| 
152
 | 
0
 | 
 
 | 
  
  0
  
 | 
 
 | 
 
 | 
0
 | 
     my $imgtitle = $options->{'Title'}        || 'Dependency Chart';  | 
| 
153
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
154
 | 
0
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
     my ( $maxitems, $pushed ) =  | 
| 
155
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
         _makeCols( $kind, $seeds, $options->{IncludeRegex}, $options->{ExcludeRegex} );  | 
| 
156
 | 
0
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
     _imageDimsSet();  | 
| 
157
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
158
 | 
0
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
     LOG("Making image to $filename");  | 
| 
159
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
160
 | 
0
 | 
  
  0
  
 | 
 
 | 
 
 | 
 
 | 
0
 | 
     if ( $maxitems < 8 ) {  | 
| 
 
 | 
 
 | 
  
  0
  
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
161
 | 
0
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
         $rowHeight = 8 * $rowHeight * 1.5 / $maxitems;  | 
| 
162
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     }  | 
| 
163
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     elsif ( $maxitems < 16 ) {  | 
| 
164
 | 
0
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
         $rowHeight = 16 * $rowHeight / $maxitems;  | 
| 
165
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     }  | 
| 
166
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
167
 | 
0
 | 
  
  0
  
 | 
 
 | 
 
 | 
 
 | 
0
 | 
     my $imgWidth  = $colWidth * ( scalar(@TIERS) < 3 ? 3 : scalar(@TIERS) );  | 
| 
168
 | 
0
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
     my $imgHeight = $rowHeight * $maxitems;  | 
| 
169
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
170
 | 
0
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
     my $realImgWidth  = $imgWidth + $wOffset + $eOffset;  | 
| 
171
 | 
0
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
     my $realImgHeight = $imgHeight + $nOffset + $sOffset;  | 
| 
172
 | 
0
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
     LOG("Rows are $rowHeight px, maxitems is $maxitems, image is $realImgWidth * $realImgWidth");  | 
| 
173
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
174
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     # set up image object  | 
| 
175
 | 
0
 | 
 
 | 
  
  0
  
 | 
 
 | 
 
 | 
0
 | 
     my $im = new GD::Image( $imgWidth + $wOffset + $eOffset, $imgHeight + $nOffset + $sOffset )  | 
| 
176
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
         || die("Couldn't build GD object: $!");  | 
| 
177
 | 
0
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
     my $colours;  | 
| 
178
 | 
0
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
     $im->colorAllocate( 255, 255, 255 );  | 
| 
179
 | 
0
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
     while ( my ( $k, $v ) = each %COLOURS ) { $colours->{$k} = $im->colorAllocate(@$v); }  | 
| 
 
 | 
0
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
    | 
| 
180
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
181
 | 
0
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
     _packObjects( $imgHeight, 5 );    # gdTinyFont has 5 pixel wide characters  | 
| 
182
 | 
0
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
     _linkObjects( $im, $colours );  | 
| 
183
 | 
0
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
     _labelObjects( $im, $colours );  | 
| 
184
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
185
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     # add legend and prettiness  | 
| 
186
 | 
0
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
     TRACE("Drawing legend etc");  | 
| 
187
 | 
0
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
     $im->string( gdMediumBoldFont(), 5, 3, $imgtitle, $colours->{'title1'} );  | 
| 
188
 | 
0
 | 
  
  0
  
 | 
 
 | 
 
 | 
 
 | 
0
 | 
     $im->string( gdSmallFont(), 5, 17, "Grapher.pm $VERSION - " . localtime(),  | 
| 
189
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
         $colours->{'title1'} )  | 
| 
190
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
         unless $options->{'NoVersion'};  | 
| 
191
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
192
 | 
0
 | 
  
  0
  
 | 
 
 | 
 
 | 
 
 | 
0
 | 
     _drawLegend( $im, $colours, $realImgWidth - 160 - $eOffset, 3 ) unless $options->{'NoLegend'};  | 
| 
193
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
194
 | 
0
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
     TRACE("Printing image");  | 
| 
195
 | 
0
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
     local *IMG;  | 
| 
196
 | 
0
 | 
  
  0
  
 | 
 
 | 
 
 | 
 
 | 
0
 | 
     open( IMG, "> $filename" ) or die("Can't open $filename for image write: $!");  | 
| 
197
 | 
0
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
     binmode(IMG);  | 
| 
198
 | 
0
 | 
  
  0
  
 | 
 
 | 
 
 | 
 
 | 
0
 | 
     if ( $type eq 'GIF' ) {  | 
| 
 
 | 
 
 | 
  
  0
  
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
 
 | 
 
 | 
  
  0
  
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
 
 | 
 
 | 
  
  0
  
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
199
 | 
0
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
         print IMG $im->gif;  | 
| 
200
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     }  | 
| 
201
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     elsif ( $type eq 'PNG' ) {  | 
| 
202
 | 
0
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
         print IMG $im->png;  | 
| 
203
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     }  | 
| 
204
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     elsif ( $type eq 'JPG' ) {  | 
| 
205
 | 
0
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
         print IMG $im->jpg;  | 
| 
206
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     }  | 
| 
207
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     elsif ( $type eq 'GD' ) {  | 
| 
208
 | 
0
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
         print IMG $im->gd;  | 
| 
209
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     }  | 
| 
210
 | 
0
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
     else { die("Unrecognized image type $type"); }  | 
| 
211
 | 
0
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
     close IMG;  | 
| 
212
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 }  | 
| 
213
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
214
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 # SVG has an origin at the top-left, like GD, and an SVG image can use unitless coordinates: so we can borrow a lot from makeImage()  | 
| 
215
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 sub makeSvg {  | 
| 
216
 | 
0
 | 
 
 | 
 
 | 
  
0
  
 | 
  
1
  
 | 
0
 | 
     require SVG;  | 
| 
217
 | 
0
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
     import SVG;  | 
| 
218
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
219
 | 
0
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
     my ( $kind, $seeds, $filename, $options ) = @_;  | 
| 
220
 | 
0
 | 
 
 | 
  
  0
  
 | 
 
 | 
 
 | 
0
 | 
     my $imgtitle = $options->{'Title'} || 'Dependency Chart';  | 
| 
221
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
222
 | 
0
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
     my ( $maxitems, $pushed ) =  | 
| 
223
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
         _makeCols( $kind, $seeds, $options->{IncludeRegex}, $options->{ExcludeRegex} );  | 
| 
224
 | 
0
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
     _imageDimsSet();  | 
| 
225
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
226
 | 
0
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
     LOG("Making SVG to $filename");  | 
| 
227
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
228
 | 
0
 | 
  
  0
  
 | 
 
 | 
 
 | 
 
 | 
0
 | 
     if ( $maxitems < 8 ) {  | 
| 
 
 | 
 
 | 
  
  0
  
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
229
 | 
0
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
         $rowHeight = 8 * $rowHeight * 1.5 / $maxitems;  | 
| 
230
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     }  | 
| 
231
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     elsif ( $maxitems < 16 ) {  | 
| 
232
 | 
0
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
         $rowHeight = 16 * $rowHeight / $maxitems;  | 
| 
233
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     }  | 
| 
234
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
235
 | 
0
 | 
  
  0
  
 | 
 
 | 
 
 | 
 
 | 
0
 | 
     my $imgWidth  = $colWidth * ( scalar(@TIERS) < 3 ? 3 : scalar(@TIERS) );  | 
| 
236
 | 
0
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
     my $imgHeight = $rowHeight * $maxitems;  | 
| 
237
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
238
 | 
0
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
     my $realImgWidth  = $imgWidth + $wOffset + $eOffset;  | 
| 
239
 | 
0
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
     my $realImgHeight = $imgHeight + $nOffset + $sOffset;  | 
| 
240
 | 
0
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
     LOG("Rows are $rowHeight px, maxitems is $maxitems, image is $realImgWidth * $realImgWidth");  | 
| 
241
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
242
 | 
0
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
     my $im = new SVG(  | 
| 
243
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
         'viewBox' => (  | 
| 
244
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
                   '0 0 '  | 
| 
245
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
                 . ( $imgWidth + $wOffset + $eOffset ) . ' '  | 
| 
246
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
                 . ( $imgHeight + $nOffset + $sOffset )  | 
| 
247
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
         ),  | 
| 
248
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
         'preserveAspectRatio' => 'xMidYMid',  | 
| 
249
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
         '-indent'             => "\t"  | 
| 
250
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     );  | 
| 
251
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
252
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     # set up image object  | 
| 
253
 | 
0
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
     my $colours;  | 
| 
254
 | 
0
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
     while ( my ( $k, $v ) = each %COLOURS ) {  | 
| 
255
 | 
0
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
         $colours->{$k} = sprintf( '#%2.2x%2.2x%2.2x', @$v );  | 
| 
256
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     }  | 
| 
257
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
258
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     $im->rectangle(  | 
| 
259
 | 
0
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
         'x'      => 0,  | 
| 
260
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
         'y'      => 0,  | 
| 
261
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
         'width'  => ( $imgWidth + $wOffset + $eOffset ),  | 
| 
262
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
         'height' => ( $imgHeight + $nOffset + $sOffset ),  | 
| 
263
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
         stroke   => $colours->{'black'},  | 
| 
264
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
         fill     => 'none'  | 
| 
265
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     );  | 
| 
266
 | 
0
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
     _packObjects( $imgHeight, 5 );  | 
| 
267
 | 
0
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
     _linkObjects( $im, $colours );  | 
| 
268
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
269
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     # are things clickable? Bit of a kludge, this  | 
| 
270
 | 
0
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
     $colours->{'_HREF_FORMAT'} = $options->{'HrefFormat'};  | 
| 
271
 | 
0
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
     _labelObjects( $im, $colours );  | 
| 
272
 | 
0
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
     delete $colours->{'_HREF_FORMAT'};  | 
| 
273
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
274
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     # add legend and prettiness  | 
| 
275
 | 
0
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
     TRACE("Drawing legend etc");  | 
| 
276
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
277
 | 
0
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
     $im->text(  | 
| 
278
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
         'x'     => 5,  | 
| 
279
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
         'y'     => 12,  | 
| 
280
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
         'fill'  => $colours->{'title1'},  | 
| 
281
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
         'style' => { 'font-size' => '12px' }  | 
| 
282
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     )->cdata($imgtitle);  | 
| 
283
 | 
0
 | 
  
  0
  
 | 
 
 | 
 
 | 
 
 | 
0
 | 
     $im->text(  | 
| 
284
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
         'x'     => 5,  | 
| 
285
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
         'y'     => 23,  | 
| 
286
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
         'fill'  => $colours->{'title1'},  | 
| 
287
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
         'style' => { 'font-size' => '9px' }  | 
| 
288
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
         )->cdata( "Grapher.pm $VERSION - " . localtime() )  | 
| 
289
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
         unless $options->{'NoVersion'};  | 
| 
290
 | 
0
 | 
  
  0
  
 | 
 
 | 
 
 | 
 
 | 
0
 | 
     _drawLegend( $im, $colours, $realImgWidth - 160 - $eOffset, 3 ) unless $options->{'NoLegend'};  | 
| 
291
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
292
 | 
0
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
     $im->title( id => 'document-title' )->cdata($imgtitle);  | 
| 
293
 | 
0
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
     $im->desc( id => 'document-desc' )  | 
| 
294
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
         ->cdata('This image shows dependency relationships between perl programs and modules');  | 
| 
295
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
296
 | 
0
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
     TRACE("Printing SVG");  | 
| 
297
 | 
0
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
     local *IMG;  | 
| 
298
 | 
0
 | 
  
  0
  
 | 
 
 | 
 
 | 
 
 | 
0
 | 
     open( IMG, "> $filename" ) or die("Can't open $filename for image write: $!");  | 
| 
299
 | 
0
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
     print IMG $im->xmlify;  | 
| 
300
 | 
0
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
     close IMG;  | 
| 
301
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 }  | 
| 
302
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
303
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 sub makePs {  | 
| 
304
 | 
0
 | 
 
 | 
 
 | 
  
0
  
 | 
  
1
  
 | 
0
 | 
     require PostScript::Simple;  | 
| 
305
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
306
 | 
0
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
     my ( $kind, $seeds, $filename, $options ) = @_;  | 
| 
307
 | 
0
 | 
 
 | 
  
  0
  
 | 
 
 | 
 
 | 
0
 | 
     my $imgtitle = $options->{'Title'} || 'Dependency Chart';  | 
| 
308
 | 
0
 | 
  
  0
  
 | 
 
 | 
 
 | 
 
 | 
0
 | 
     my $eps = ( uc( $options->{'Format'} ) eq 'PS' ) ? 0 : 1;  | 
| 
309
 | 
0
 | 
  
  0
  
 | 
 
 | 
 
 | 
 
 | 
0
 | 
     my $colour = exists( $options->{'Colour'} ) ? $options->{'Colour'} : 1;  | 
| 
310
 | 
0
 | 
 
 | 
  
  0
  
 | 
 
 | 
 
 | 
0
 | 
     my $font = $options->{'Font'} || 'Helvetica';  | 
| 
311
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
312
 | 
0
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
     my ( $maxitems, $pushed ) =  | 
| 
313
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
         _makeCols( $kind, $seeds, $options->{IncludeRegex}, $options->{ExcludeRegex} );  | 
| 
314
 | 
0
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
     _psDimsSet();  | 
| 
315
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
316
 | 
0
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
     LOG("Making postscript to $filename");  | 
| 
317
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
318
 | 
0
 | 
  
  0
  
 | 
 
 | 
 
 | 
 
 | 
0
 | 
     if ( $maxitems < 8 ) {  | 
| 
 
 | 
 
 | 
  
  0
  
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
319
 | 
0
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
         $rowHeight = 8 * $rowHeight * 1.5 / $maxitems;  | 
| 
320
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     }  | 
| 
321
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     elsif ( $maxitems < 16 ) {  | 
| 
322
 | 
0
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
         $rowHeight = 16 * $rowHeight / $maxitems;  | 
| 
323
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     }  | 
| 
324
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
325
 | 
0
 | 
  
  0
  
 | 
 
 | 
 
 | 
 
 | 
0
 | 
     my $imgWidth  = $colWidth * ( scalar(@TIERS) < 3 ? 3 : scalar(@TIERS) );  | 
| 
326
 | 
0
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
     my $imgHeight = $rowHeight * $maxitems;  | 
| 
327
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
328
 | 
0
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
     my $realImgWidth  = $imgWidth + $wOffset + $eOffset;  | 
| 
329
 | 
0
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
     my $realImgHeight = $imgHeight + $nOffset + $sOffset;  | 
| 
330
 | 
0
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
     LOG("Rows are $rowHeight px, maxitems is $maxitems, image is $realImgWidth * $realImgWidth");  | 
| 
331
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
332
 | 
0
 | 
 
 | 
  
  0
  
 | 
 
 | 
 
 | 
0
 | 
     my $p = new PostScript::Simple(  | 
| 
333
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
         eps       => $eps,  | 
| 
334
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
         colour    => $colour,  | 
| 
335
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
         clip      => 1,  | 
| 
336
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
         landscape => ( !$eps ),  | 
| 
337
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
         xsize     => $realImgWidth,  | 
| 
338
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
         ysize     => $realImgHeight,  | 
| 
339
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
         units     => 'bp'  | 
| 
340
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
         )    # we use points because they're close to pixels, as used in GD  | 
| 
341
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
         || die("Can't build Postscript object: $!");  | 
| 
342
 | 
0
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
     $p->setlinewidth(0.5);  | 
| 
343
 | 
0
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
     $p->setfont( $font, 9 );  | 
| 
344
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
345
 | 
0
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
     _packObjects( $imgHeight, 5.5 );  | 
| 
346
 | 
0
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
     _linkObjects($p);  | 
| 
347
 | 
0
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
     $p->setcolour( @{ $COLOURS{'type'} } );  | 
| 
 
 | 
0
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
    | 
| 
348
 | 
0
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
     _labelObjects($p);  | 
| 
349
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
350
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     # add legend and prettiness  | 
| 
351
 | 
0
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
     TRACE("Drawing legend etc");  | 
| 
352
 | 
0
 | 
  
  0
  
 | 
 
 | 
 
 | 
 
 | 
0
 | 
     _drawPsLegend( $p, $realImgWidth - 160 - $eOffset, 16 ) unless $options->{'NoLegend'};  | 
| 
353
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
354
 | 
0
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
     $p->setfont( $font, 16 );  | 
| 
355
 | 
0
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
     $p->setcolour( @{ $COLOURS{'title1'} } );  | 
| 
 
 | 
0
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
    | 
| 
356
 | 
0
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
     $p->text( 15, 18, $imgtitle );  | 
| 
357
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
358
 | 
0
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
     $p->setfont( $font, 12 );  | 
| 
359
 | 
0
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
     $p->setcolour( @{ $COLOURS{'title1'} } );  | 
| 
 
 | 
0
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
    | 
| 
360
 | 
0
 | 
  
  0
  
 | 
 
 | 
 
 | 
 
 | 
0
 | 
     $p->text( 15, 35, "Grapher.pm $VERSION - " . localtime() ) unless $options->{'NoVersion'};  | 
| 
361
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
362
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 # 	$p->setcolour( @{$COLOURS{'test'}} ); 	$p->line( 0, $nOffset, $realImgWidth, $nOffset); 	$p->line( 0, $realImgHeight-$sOffset, $realImgWidth, $realImgHeight-$sOffset); 	$p->line( $wOffset, 0, $wOffset, $realImgHeight); 	$p->line( $realImgWidth-$eOffset, 0, $realImgWidth-$eOffset, $realImgHeight);  | 
| 
363
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
364
 | 
0
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
     TRACE("Printing image");  | 
| 
365
 | 
0
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
     $p->output($filename);  | 
| 
366
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 }  | 
| 
367
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
368
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 ### PRIVATE INTERNAL ROUTINES  | 
| 
369
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
370
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 # algorithm which sorts dependencies into a series of generations (the @TIERS array)  | 
| 
371
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 sub _makeCols {  | 
| 
372
 | 
5
 | 
 
 | 
 
 | 
  
5
  
 | 
 
 | 
9
 | 
     my $kind  = shift();  | 
| 
373
 | 
5
 | 
 
 | 
 
 | 
 
 | 
 
 | 
7
 | 
     my $seeds = shift();  | 
| 
374
 | 
5
 | 
 
 | 
  
 50
  
 | 
 
 | 
 
 | 
215
 | 
     my $re    = shift() || '';  | 
| 
375
 | 
5
 | 
 
 | 
  
 50
  
 | 
 
 | 
 
 | 
31
 | 
     my $xre   = shift() || '';  | 
| 
376
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
377
 | 
5
 | 
 
 | 
 
 | 
 
 | 
 
 | 
14
 | 
     $kind = uc($kind);  | 
| 
378
 | 
5
 | 
 
 | 
 
 | 
 
 | 
 
 | 
33
 | 
     TRACE("makeCols: kind <$kind> re <$re> xre <$xre>");  | 
| 
379
 | 
5
 | 
  
 50
  
 | 
 
 | 
 
 | 
 
 | 
22
 | 
     unless ( ref($seeds) ) { $seeds = [$seeds]; }  | 
| 
 
 | 
5
 | 
 
 | 
 
 | 
 
 | 
 
 | 
13
 | 
    | 
| 
380
 | 
5
 | 
  
 50
  
 | 
  
100
  
 | 
 
 | 
 
 | 
44
 | 
     unless ( $kind eq 'CHILD' || $kind eq 'PARENT' || $kind eq 'BOTH' ) {  | 
| 
 
 | 
 
 | 
 
 | 
  
 66
  
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
381
 | 
0
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
         die("unrecognized sort of tree required: $kind - should be 'child', 'parent' or 'both'");  | 
| 
382
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     }  | 
| 
383
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
384
 | 
5
 | 
 
 | 
 
 | 
 
 | 
 
 | 
18
 | 
     @TIERS = ();  | 
| 
385
 | 
5
 | 
 
 | 
 
 | 
 
 | 
 
 | 
25
 | 
     my %seen = ();  | 
| 
386
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
387
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     # this entry is where we start the tree discovery off from  | 
| 
388
 | 
5
 | 
 
 | 
 
 | 
 
 | 
 
 | 
12
 | 
     my $seedrow = [@$seeds];  | 
| 
389
 | 
5
 | 
 
 | 
 
 | 
 
 | 
 
 | 
8
 | 
     push( @TIERS, $seedrow );  | 
| 
390
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
391
 | 
5
 | 
 
 | 
 
 | 
 
 | 
 
 | 
7
 | 
     my $found = 0;  | 
| 
392
 | 
5
 | 
 
 | 
 
 | 
 
 | 
 
 | 
47
 | 
     my $ptr   = 0;  | 
| 
393
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
394
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     # get child dependencies  | 
| 
395
 | 
5
 | 
  
100
  
 | 
  
100
  
 | 
 
 | 
 
 | 
28
 | 
     if ( $kind eq 'CHILD' || $kind eq 'BOTH' ) {  | 
| 
396
 | 
4
 | 
 
 | 
 
 | 
 
 | 
 
 | 
11
 | 
         TRACE("makeCols: child dependencies");  | 
| 
397
 | 
4
 | 
 
 | 
 
 | 
 
 | 
 
 | 
5
 | 
         do {  | 
| 
398
 | 
12
 | 
 
 | 
 
 | 
 
 | 
 
 | 
14
 | 
             $found = 0;  | 
| 
399
 | 
12
 | 
 
 | 
 
 | 
 
 | 
 
 | 
20
 | 
             my $temp = [];  | 
| 
400
 | 
12
 | 
 
 | 
 
 | 
 
 | 
 
 | 
13
 | 
             foreach ( @{ $TIERS[$ptr] } ) {  | 
| 
 
 | 
12
 | 
 
 | 
 
 | 
 
 | 
 
 | 
25
 | 
    | 
| 
401
 | 
28
 | 
 
 | 
 
 | 
 
 | 
 
 | 
66
 | 
                 my $obj = Module::Dependency::Info::getItem($_);  | 
| 
402
 | 
28
 | 
  
100
  
 | 
 
 | 
 
 | 
 
 | 
79
 | 
                 next unless $obj->{filename};  | 
| 
403
 | 
16
 | 
 
 | 
 
 | 
 
 | 
 
 | 
28
 | 
                 $LOOKUP{$_} = $obj;  | 
| 
404
 | 
16
 | 
 
 | 
 
 | 
 
 | 
 
 | 
23
 | 
                 $seen{$_}   = 1;  | 
| 
405
 | 
16
 | 
 
 | 
 
 | 
 
 | 
 
 | 
37
 | 
                 TRACE("...for $obj->{'package'}");  | 
| 
406
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
407
 | 
16
 | 
 
 | 
 
 | 
 
 | 
 
 | 
21
 | 
                 foreach my $dep ( @{ $obj->{'depends_on'} } ) {  | 
| 
 
 | 
16
 | 
 
 | 
 
 | 
 
 | 
 
 | 
35
 | 
    | 
| 
408
 | 
28
 | 
  
100
  
 | 
 
 | 
 
 | 
 
 | 
65
 | 
                     next if $seen{$dep};  | 
| 
409
 | 
24
 | 
  
 50
  
 | 
  
 33
  
 | 
 
 | 
 
 | 
118
 | 
                     if ( ( $re && $dep !~ m/$re/ ) || ( $xre && $dep =~ m/$xre/ ) )  | 
| 
 
 | 
 
 | 
 
 | 
  
 33
  
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
 
 | 
 
 | 
 
 | 
  
 33
  
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
410
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
                     {    # if given regexps then apply filter  | 
| 
411
 | 
0
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
                         TRACE("  !..$dep skipped by regex");  | 
| 
412
 | 
0
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
                         $seen{$dep} = 1;  | 
| 
413
 | 
0
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
                         next;  | 
| 
414
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
                     }  | 
| 
415
 | 
24
 | 
 
 | 
 
 | 
 
 | 
 
 | 
57
 | 
                     TRACE("  ...found $dep");  | 
| 
416
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
                     $LOOKUP{$dep} = Module::Dependency::Info::getItem($dep)  | 
| 
417
 | 
24
 | 
 
 | 
  
 33
  
 | 
 
 | 
 
 | 
50
 | 
                         || do { $seen{$dep} = 1; next; };  | 
| 
418
 | 
24
 | 
 
 | 
 
 | 
 
 | 
 
 | 
46
 | 
                     push( @$temp, $dep );  | 
| 
419
 | 
24
 | 
 
 | 
 
 | 
 
 | 
 
 | 
38
 | 
                     $seen{$dep} = 1;  | 
| 
420
 | 
24
 | 
 
 | 
 
 | 
 
 | 
 
 | 
59
 | 
                     $found = 1;  | 
| 
421
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
                 }  | 
| 
422
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
             }  | 
| 
423
 | 
12
 | 
  
100
  
 | 
 
 | 
 
 | 
 
 | 
32
 | 
             push( @TIERS, $temp ) if $found;  | 
| 
424
 | 
12
 | 
 
 | 
 
 | 
 
 | 
 
 | 
32
 | 
             $ptr++;  | 
| 
425
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
         } while ( $found == 1 );  | 
| 
426
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     }  | 
| 
427
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
428
 | 
5
 | 
 
 | 
 
 | 
 
 | 
 
 | 
6
 | 
     my $pushed = 0;  | 
| 
429
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
430
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     # get parent dependencies  | 
| 
431
 | 
5
 | 
  
100
  
 | 
  
100
  
 | 
 
 | 
 
 | 
28
 | 
     if ( $kind eq 'PARENT' || $kind eq 'BOTH' ) {  | 
| 
432
 | 
4
 | 
 
 | 
 
 | 
 
 | 
 
 | 
9
 | 
         TRACE("makeCols: parent dependencies");  | 
| 
433
 | 
4
 | 
 
 | 
 
 | 
 
 | 
 
 | 
4
 | 
         do {  | 
| 
434
 | 
12
 | 
 
 | 
 
 | 
 
 | 
 
 | 
15
 | 
             $found = 0;  | 
| 
435
 | 
12
 | 
 
 | 
 
 | 
 
 | 
 
 | 
20
 | 
             my $temp = [];  | 
| 
436
 | 
12
 | 
 
 | 
 
 | 
 
 | 
 
 | 
16
 | 
             foreach ( @{ $TIERS[0] } ) {  | 
| 
 
 | 
12
 | 
 
 | 
 
 | 
 
 | 
 
 | 
23
 | 
    | 
| 
437
 | 
24
 | 
 
 | 
 
 | 
 
 | 
 
 | 
51
 | 
                 my $obj = Module::Dependency::Info::getItem($_);  | 
| 
438
 | 
24
 | 
  
 50
  
 | 
 
 | 
 
 | 
 
 | 
56
 | 
                 next unless $obj->{filename};  | 
| 
439
 | 
24
 | 
 
 | 
 
 | 
 
 | 
 
 | 
39
 | 
                 $LOOKUP{$_} = $obj;  | 
| 
440
 | 
24
 | 
 
 | 
 
 | 
 
 | 
 
 | 
31
 | 
                 $seen{$_}   = 1;  | 
| 
441
 | 
24
 | 
 
 | 
 
 | 
 
 | 
 
 | 
59
 | 
                 TRACE("...for $obj->{'package'}");  | 
| 
442
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
443
 | 
24
 | 
 
 | 
 
 | 
 
 | 
 
 | 
30
 | 
                 foreach my $dep ( @{ $obj->{'depended_upon_by'} } ) {  | 
| 
 
 | 
24
 | 
 
 | 
 
 | 
 
 | 
 
 | 
59
 | 
    | 
| 
444
 | 
32
 | 
  
100
  
 | 
 
 | 
 
 | 
 
 | 
82
 | 
                     next if $seen{$dep};  | 
| 
445
 | 
20
 | 
  
 50
  
 | 
  
 33
  
 | 
 
 | 
 
 | 
96
 | 
                     if ( ( $re && $dep !~ m/$re/ ) || ( $xre && $dep =~ m/$xre/ ) )  | 
| 
 
 | 
 
 | 
 
 | 
  
 33
  
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
 
 | 
 
 | 
 
 | 
  
 33
  
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
446
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
                     {    # if given regexps then apply filter  | 
| 
447
 | 
0
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
                         TRACE("  !..$dep skipped by regex");  | 
| 
448
 | 
0
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
                         $seen{$dep} = 1;  | 
| 
449
 | 
0
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
                         next;  | 
| 
450
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
                     }  | 
| 
451
 | 
20
 | 
 
 | 
 
 | 
 
 | 
 
 | 
50
 | 
                     TRACE("  ...found $dep");  | 
| 
452
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
                     $LOOKUP{$dep} = Module::Dependency::Info::getItem($dep)  | 
| 
453
 | 
20
 | 
 
 | 
  
 33
  
 | 
 
 | 
 
 | 
44
 | 
                         || do { $seen{$dep} = 1; next; };  | 
| 
454
 | 
20
 | 
 
 | 
 
 | 
 
 | 
 
 | 
32
 | 
                     push( @$temp, $dep );  | 
| 
455
 | 
20
 | 
 
 | 
 
 | 
 
 | 
 
 | 
37
 | 
                     $seen{$dep} = 1;  | 
| 
456
 | 
20
 | 
 
 | 
 
 | 
 
 | 
 
 | 
40
 | 
                     $found = 1;  | 
| 
457
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
                 }  | 
| 
458
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
             }  | 
| 
459
 | 
12
 | 
  
100
  
 | 
 
 | 
 
 | 
 
 | 
33
 | 
             if ($found) {  | 
| 
460
 | 
8
 | 
 
 | 
 
 | 
 
 | 
 
 | 
13
 | 
                 unshift( @TIERS, $temp );  | 
| 
461
 | 
8
 | 
 
 | 
 
 | 
 
 | 
 
 | 
22
 | 
                 $pushed += 1;  | 
| 
462
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
             }  | 
| 
463
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
         } while ( $found == 1 );  | 
| 
464
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     }  | 
| 
465
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
466
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     # extract sizes of each column  | 
| 
467
 | 
5
 | 
 
 | 
 
 | 
 
 | 
 
 | 
9
 | 
     @numElements = ();  | 
| 
468
 | 
5
 | 
 
 | 
 
 | 
 
 | 
 
 | 
8
 | 
     my $maxitems = 1;  | 
| 
469
 | 
5
 | 
 
 | 
 
 | 
 
 | 
 
 | 
9
 | 
     foreach (@TIERS) {  | 
| 
470
 | 
21
 | 
 
 | 
 
 | 
 
 | 
 
 | 
23
 | 
         my $num = $#{$_} + 1;  | 
| 
 
 | 
21
 | 
 
 | 
 
 | 
 
 | 
 
 | 
32
 | 
    | 
| 
471
 | 
21
 | 
  
100
  
 | 
 
 | 
 
 | 
 
 | 
47
 | 
         $maxitems = $num if $num > $maxitems;  | 
| 
472
 | 
21
 | 
 
 | 
 
 | 
 
 | 
 
 | 
34
 | 
         push( @numElements, $num );  | 
| 
473
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     }  | 
| 
474
 | 
5
 | 
 
 | 
 
 | 
 
 | 
 
 | 
24
 | 
     return ( $maxitems, $pushed );  | 
| 
475
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 }  | 
| 
476
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
477
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 # work out _where_ we're going to put the items  | 
| 
478
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 sub _packObjects {  | 
| 
479
 | 
0
 | 
 
 | 
 
 | 
  
0
  
 | 
 
 | 
0
 | 
     my ( $imgHeight, $charwidth ) = @_;  | 
| 
480
 | 
0
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
     TRACE("Packing objects");  | 
| 
481
 | 
0
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
     for my $x ( 0 .. $#TIERS ) {  | 
| 
482
 | 
0
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
         my $y = 0;  | 
| 
483
 | 
0
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
         foreach ( sort { $a cmp $b } @{ $TIERS[$x] } ) {  | 
| 
 
 | 
0
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
    | 
| 
 
 | 
0
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
    | 
| 
484
 | 
0
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
             my $obj = $LOOKUP{$_};  | 
| 
485
 | 
0
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
             my $cx  = ( $colWidth * $x ) + $wOffset;  | 
| 
486
 | 
0
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
             my $cy  = ( ( $imgHeight * ( $y + 1 ) ) / ( $numElements[$x] + 1 ) ) + $nOffset;  | 
| 
487
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
488
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
             #			TRACE( "Putting text $obj->{'package'} at $cx, $cy" );  | 
| 
489
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
             # use the first, i.e. highest up the food chain, coordinates only  | 
| 
490
 | 
0
 | 
  
  0
  
 | 
 
 | 
 
 | 
 
 | 
0
 | 
             unless ( exists $obj->{'x'} ) {  | 
| 
491
 | 
0
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
                 $obj->{'x'}  = $cx;  | 
| 
492
 | 
0
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
                 $obj->{'y'}  = $cy;  | 
| 
493
 | 
0
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
                 $obj->{'x2'} =  | 
| 
494
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
                     $cx + 1 + $charwidth * length( $obj->{'package'} )  | 
| 
495
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
                     ;    # gdTinyFont has characters 5 pixels wide  | 
| 
496
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
             }  | 
| 
497
 | 
0
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
             $y++;  | 
| 
498
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
         }  | 
| 
499
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     }  | 
| 
500
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 }  | 
| 
501
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
502
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 sub _linkObjects {  | 
| 
503
 | 
0
 | 
 
 | 
 
 | 
  
0
  
 | 
 
 | 
0
 | 
     my ( $im, $colours ) = @_;  | 
| 
504
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
505
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     # draw a load of lines...  | 
| 
506
 | 
0
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
     TRACE("Drawing links between items");  | 
| 
507
 | 
0
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
     foreach my $x (@TIERS) {  | 
| 
508
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
509
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
         #...for every object  | 
| 
510
 | 
0
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
         foreach (@$x) {  | 
| 
511
 | 
0
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
             my $obj = $LOOKUP{$_};  | 
| 
512
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
513
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
             #...link to all its dependencies  | 
| 
514
 | 
0
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
             foreach my $dep ( @{ $obj->{'depends_on'} } ) {  | 
| 
 
 | 
0
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
    | 
| 
515
 | 
0
 | 
  
  0
  
 | 
 
 | 
 
 | 
 
 | 
0
 | 
                 next unless ( exists $LOOKUP{$dep} );  | 
| 
516
 | 
0
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
                 my $depObj = $LOOKUP{$dep};  | 
| 
517
 | 
0
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
                 TRACE( $obj->{'package'} . ' -> ' . $depObj->{'package'} );  | 
| 
518
 | 
0
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
                 _drawLink( $im, $colours, $obj->{'x2'}, $obj->{'y'}, $depObj->{'x'},  | 
| 
519
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
                     $depObj->{'y'} );  | 
| 
520
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
             }  | 
| 
521
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
         }  | 
| 
522
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     }  | 
| 
523
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 }  | 
| 
524
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
525
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 sub _labelObjects {  | 
| 
526
 | 
0
 | 
 
 | 
 
 | 
  
0
  
 | 
 
 | 
0
 | 
     my ( $p, $colours ) = @_;  | 
| 
527
 | 
0
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
     TRACE("Drawing the text");  | 
| 
528
 | 
0
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
     foreach my $x (@TIERS) {  | 
| 
529
 | 
0
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
         foreach (@$x) {  | 
| 
530
 | 
0
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
             my $obj = $LOOKUP{$_};  | 
| 
531
 | 
0
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
             _drawText( $p, $colours, $obj->{'x'}, $obj->{'y'}, $obj->{'package'} );  | 
| 
532
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
         }  | 
| 
533
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     }  | 
| 
534
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 }  | 
| 
535
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
536
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 # ! behaves differently for each image type  | 
| 
537
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 sub _drawLegend {  | 
| 
538
 | 
0
 | 
 
 | 
 
 | 
  
0
  
 | 
 
 | 
0
 | 
     my ( $im, $colours, $x, $y ) = @_;  | 
| 
539
 | 
0
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
     my $type = ref($im);  | 
| 
540
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
541
 | 
0
 | 
  
  0
  
 | 
 
 | 
 
 | 
 
 | 
0
 | 
     if ( $type =~ m/^GD/ ) {  | 
| 
 
 | 
 
 | 
  
  0
  
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
542
 | 
0
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
         $im->rectangle( $x, $y, $x + 138, $y + 37, $colours->{'border'} );  | 
| 
543
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     }  | 
| 
544
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     elsif ( $type =~ m/SVG/ ) {  | 
| 
545
 | 
0
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
         $im->rectangle(  | 
| 
546
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
             'x'      => $x,  | 
| 
547
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
             'y'      => $y,  | 
| 
548
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
             'width'  => 138,  | 
| 
549
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
             'height' => 37,  | 
| 
550
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
             stroke   => 'none',  | 
| 
551
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
             stroke   => $colours->{'border'},  | 
| 
552
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
             fill     => 'none'  | 
| 
553
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
         );  | 
| 
554
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     }  | 
| 
555
 | 
0
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
     $x += 4;  | 
| 
556
 | 
0
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
     $y += 3;  | 
| 
557
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
558
 | 
0
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
     _drawText( $im, $colours, $x, $y, 'Legend' );  | 
| 
559
 | 
0
 | 
  
  0
  
 | 
 
 | 
 
 | 
 
 | 
0
 | 
     if ( $type =~ m/^GD/ ) {  | 
| 
 
 | 
 
 | 
  
  0
  
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
560
 | 
0
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
         $im->line( $x, $y + 8, $x + 30, $y + 8, $colours->{'type'} );  | 
| 
561
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     }  | 
| 
562
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     elsif ( $type =~ m/SVG/ ) {  | 
| 
563
 | 
0
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
         $im->line(  | 
| 
564
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
             x1     => $x,  | 
| 
565
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
             y1     => $y + 8,  | 
| 
566
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
             x2     => $x + 30,  | 
| 
567
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
             y2     => $y + 8,  | 
| 
568
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
             stroke => $colours->{'type'}  | 
| 
569
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
         );  | 
| 
570
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     }  | 
| 
571
 | 
0
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
     $y += 12;  | 
| 
572
 | 
0
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
     _drawLink( $im, $colours, $x + 31, $y, 100 + $x, $y );  | 
| 
573
 | 
0
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
     _drawText( $im, $colours, $x, $y, 'Foo.pl' );  | 
| 
574
 | 
0
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
     _drawText( $im, $colours, 100 + $x, $y, 'Bar' );  | 
| 
575
 | 
0
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
     $y += 12;  | 
| 
576
 | 
0
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
     _drawText( $im, $colours, $x, $y, 'Foo.pl depends upon Bar.pm' );  | 
| 
577
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 }  | 
| 
578
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
579
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 sub _drawPsLegend {  | 
| 
580
 | 
0
 | 
 
 | 
 
 | 
  
0
  
 | 
 
 | 
0
 | 
     my ( $p, $x, $y ) = @_;  | 
| 
581
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
582
 | 
0
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
     _drawText( $p, undef, $x + 2, $y + 26, 'Legend' );  | 
| 
583
 | 
0
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
     $p->setlinewidth(0.4);  | 
| 
584
 | 
0
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
     $p->line( $x + 2, $y + 25, $x + 32, $y + 25 );  | 
| 
585
 | 
0
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
     _drawText( $p, undef, $x + 2,   $y + 14, 'Foo.pl' );  | 
| 
586
 | 
0
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
     _drawText( $p, undef, $x + 102, $y + 14, 'Bar' );  | 
| 
587
 | 
0
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
     _drawText( $p, undef, $x + 2,   $y + 2,  'Foo.pl depends upon Bar.pm' );  | 
| 
588
 | 
0
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
     _drawLink( $p, undef, $x + 29, $y + 14, $x + 102, $y + 14 );  | 
| 
589
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
590
 | 
0
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
     $p->setlinewidth(0.25);  | 
| 
591
 | 
0
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
     $p->setcolour( @{ $COLOURS{'black'} } );  | 
| 
 
 | 
0
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
    | 
| 
592
 | 
0
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
     $p->box( $x, $y - 1, $x + 120, $y + 34 );  | 
| 
593
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 }  | 
| 
594
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
595
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 # ! behaves differently for each image type  | 
| 
596
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 sub _drawText {  | 
| 
597
 | 
0
 | 
 
 | 
 
 | 
  
0
  
 | 
 
 | 
0
 | 
     my ( $im, $colours, $x, $y, $text ) = @_;  | 
| 
598
 | 
0
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
     my $type = ref($im);  | 
| 
599
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
600
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     #	TRACE("_drawText for $type");  | 
| 
601
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
602
 | 
0
 | 
  
  0
  
 | 
 
 | 
 
 | 
 
 | 
0
 | 
     if ( $type =~ m/^GD/ ) {  | 
| 
 
 | 
 
 | 
  
  0
  
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
 
 | 
 
 | 
  
  0
  
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
603
 | 
0
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
         $im->string( gdTinyFont(), $x, $y, $text, $colours->{'type'} );  | 
| 
604
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     }  | 
| 
605
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     elsif ( $type =~ m/^PostScript/ ) {  | 
| 
606
 | 
0
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
         $im->text( $x, $y, $text );  | 
| 
607
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     }  | 
| 
608
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     elsif ( $type =~ m/^SVG/ ) {  | 
| 
609
 | 
0
 | 
  
  0
  
 | 
 
 | 
 
 | 
 
 | 
0
 | 
         if ( $colours->{'_HREF_FORMAT'} ) {  | 
| 
610
 | 
0
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
             $im->anchor( -href => sprintf( $colours->{'_HREF_FORMAT'}, $text ) )->text(  | 
| 
611
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
                 'x'     => $x,  | 
| 
612
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
                 'y'     => $y + 5.5,  | 
| 
613
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
                 'fill'  => $colours->{'type'},  | 
| 
614
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
                 'style' => { 'font-size' => '8px', 'font-family' => 'Courier, Monaco, monospaced' }  | 
| 
615
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
             )->cdata($text);  | 
| 
616
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
         }  | 
| 
617
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
         else {  | 
| 
618
 | 
0
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
             $im->text(  | 
| 
619
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
                 'x'     => $x,  | 
| 
620
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
                 'y'     => $y + 5.5,  | 
| 
621
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
                 'fill'  => $colours->{'type'},  | 
| 
622
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
                 'style' => { 'font-size' => '8px', 'font-family' => 'Courier, Monaco, monospaced' }  | 
| 
623
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
             )->cdata($text);  | 
| 
624
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
         }  | 
| 
625
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     }  | 
| 
626
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 }  | 
| 
627
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
628
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 # ! behaves differently for each image type  | 
| 
629
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 sub _drawLink {  | 
| 
630
 | 
0
 | 
 
 | 
 
 | 
  
0
  
 | 
 
 | 
0
 | 
     my ( $im, $colours, $xa, $ya, $xb, $yb ) = @_;  | 
| 
631
 | 
0
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
     my $type = ref($im);  | 
| 
632
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
633
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     #	TRACE("_drawLink for $type");  | 
| 
634
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
635
 | 
0
 | 
  
  0
  
 | 
 
 | 
 
 | 
 
 | 
0
 | 
     if ( $type =~ m/^GD/ ) {  | 
| 
 
 | 
 
 | 
  
  0
  
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
 
 | 
 
 | 
  
  0
  
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
636
 | 
0
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
         $im->line( $xa, $ya + 3, $xb - 3, $yb + 3, $colours->{'links'} );  | 
| 
637
 | 
0
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
         $im->rectangle( $xa, $ya + 2, $xa + 1, $ya + 4, $colours->{'blob_from'} );  | 
| 
638
 | 
0
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
         $im->rectangle( $xb - 3, $yb + 2, $xb - 4, $yb + 4, $colours->{'blob_to'} );  | 
| 
639
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     }  | 
| 
640
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     elsif ( $type =~ m/^PostScript/ ) {  | 
| 
641
 | 
0
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
         $im->setlinewidth(0.22);  | 
| 
642
 | 
0
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
         $im->line( $xa, $ya + 3, $xb - 3, $yb + 3, @{ $COLOURS{'black'} } );  | 
| 
 
 | 
0
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
    | 
| 
643
 | 
0
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
         $im->setcolour( @{ $COLOURS{'white'} } );  | 
| 
 
 | 
0
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
    | 
| 
644
 | 
0
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
         $im->circle( $xb - 3, $yb + 3, 1, 1 );  | 
| 
645
 | 
0
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
         $im->setcolour( @{ $COLOURS{'black'} } );  | 
| 
 
 | 
0
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
    | 
| 
646
 | 
0
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
         $im->circle( $xa, $ya + 3, 1, 1 );  | 
| 
647
 | 
0
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
         $im->circle( $xb - 3, $yb + 3, 1, 0 );  | 
| 
648
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     }  | 
| 
649
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     elsif ( $type =~ m/^SVG/ ) {  | 
| 
650
 | 
0
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
         $im->line(  | 
| 
651
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
             x1     => $xa,  | 
| 
652
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
             y1     => $ya + 3,  | 
| 
653
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
             x2     => $xb - 3,  | 
| 
654
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
             y2     => $yb + 3,  | 
| 
655
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
             stroke => $colours->{'links'}  | 
| 
656
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
         );  | 
| 
657
 | 
0
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
         $im->rectangle(  | 
| 
658
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
             'x'      => $xa,  | 
| 
659
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
             'y'      => $ya + 2,  | 
| 
660
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
             'width'  => 2,  | 
| 
661
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
             'height' => 2,  | 
| 
662
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
             stroke   => 'none',  | 
| 
663
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
             fill     => $colours->{'blob_from'}  | 
| 
664
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
         );  | 
| 
665
 | 
0
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
         $im->rectangle(  | 
| 
666
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
             'x'      => $xb - 4,  | 
| 
667
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
             'y'      => $yb + 2,  | 
| 
668
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
             'width'  => 2,  | 
| 
669
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
             'height' => 2,  | 
| 
670
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
             stroke   => 'none',  | 
| 
671
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
             fill     => $colours->{'blob_to'}  | 
| 
672
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
         );  | 
| 
673
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     }  | 
| 
674
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     else {  | 
| 
675
 | 
0
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
         die 'This indicates that the object model has changed somewhere. Should not happen.';  | 
| 
676
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     }  | 
| 
677
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 }  | 
| 
678
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
679
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 sub _imageDimsSet {  | 
| 
680
 | 
0
 | 
 
 | 
 
 | 
  
0
  
 | 
 
 | 
0
 | 
     $colWidth  = 200;  | 
| 
681
 | 
0
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
     $rowHeight = 12;  | 
| 
682
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
683
 | 
0
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
     $nOffset = 40;  | 
| 
684
 | 
0
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
     $sOffset = 10;  | 
| 
685
 | 
0
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
     $wOffset = 20;  | 
| 
686
 | 
0
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
     $eOffset = 1;  | 
| 
687
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 }  | 
| 
688
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
689
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 sub _psDimsSet {  | 
| 
690
 | 
0
 | 
 
 | 
 
 | 
  
0
  
 | 
 
 | 
0
 | 
     $colWidth  = 150;  | 
| 
691
 | 
0
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
     $rowHeight = 12;  | 
| 
692
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
693
 | 
0
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
     $nOffset = 60;  | 
| 
694
 | 
0
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
     $sOffset = 40;  | 
| 
695
 | 
0
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
     $wOffset = 40;  | 
| 
696
 | 
0
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
     $eOffset = 30;  | 
| 
697
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 }  | 
| 
698
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
699
 | 
102
 | 
 
 | 
 
 | 
  
102
  
 | 
  
0
  
 | 
128
 | 
 sub TRACE { }  | 
| 
700
 | 
0
 | 
 
 | 
 
 | 
  
0
  
 | 
  
0
  
 | 
 
 | 
 sub LOG   { }  | 
| 
701
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
702
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 1;  | 
| 
703
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
704
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 =head1 NAME  | 
| 
705
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
706
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 Module::Dependency::Grapher - creates visual dependency charts and accessible text versions  | 
| 
707
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
708
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 =head1 SYNOPSIS  | 
| 
709
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
710
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 	use Module::Dependency::Grapher;  | 
| 
711
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 	Module::Dependency::Grapher::setIndex( '/var/tmp/dependence/unified.dat' );  | 
| 
712
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 	Module::Dependency::Grapher::makeImage( 'both', ['Foo::Bar', 'Foo::Baz'], '/home/www/foodep.png', {Format => 'png'} );  | 
| 
713
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 	Module::Dependency::Grapher::makePs( 'both', ['Foo::Bar', 'Foo::Baz'], '/home/www/foodep.eps' );  | 
| 
714
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 	Module::Dependency::Grapher::makeText( 'both', ['Foo::Bar', 'Foo::Baz'], '/home/www/foodep.txt', {NoLegend => 1} );  | 
| 
715
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 	Module::Dependency::Grapher::makeHtml( 'both', ['Foo::Bar', 'Foo::Baz'], '/home/www/foodep.ssi', {NoLegend => 1} );  | 
| 
716
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
717
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 =head1 DESCRIPTION  | 
| 
718
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
719
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 =over 4  | 
| 
720
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
721
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 =item Module::Dependency::Grapher::setIndex( $filename );  | 
| 
722
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
723
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 This tells the module where the database is. It doesn't affect the other  | 
| 
724
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 modules - they have their own setIndex routines. The default is /var/tmp/dependence/unified.dat  | 
| 
725
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
726
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 =item Module::Dependency::Grapher::makeImage( $kind, $seeds, $filename, $options );  | 
| 
727
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
728
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 Draws an image showing the dependency links between a set of items. The 'tree' of dependencies is  | 
| 
729
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 started at the item or items named in the $seeds array reference. The code then links to all  | 
| 
730
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 the parent and/or child dependencies of those seeds. And repeat for those items, etc.  | 
| 
731
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
732
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 $kind is 'parent', 'child' or 'both'. This parameter tells the code whether to plot (respectively)  | 
| 
733
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 things that depend upon the seed items, things that the seed items depend upon, or both directions.  | 
| 
734
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
735
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 $seeds is a reference to an array of item names  | 
| 
736
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
737
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 $filename is the file to which the output should go. Use '-' for STDOUT. Clobbers existing files.  | 
| 
738
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
739
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 See below for the options. See README.EXAMPLES too.  | 
| 
740
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
741
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 =item Module::Dependency::Grapher::makePs( $kind, $seeds, $filename, $options );  | 
| 
742
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
743
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 As makeImage() but does it in PostScript or EPS. EPS is the default. See below for the options. See README.EXAMPLES too.  | 
| 
744
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
745
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 =item Module::Dependency::Grapher::makeSvg( $kind, $seeds, $filename, $options );  | 
| 
746
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
747
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 As makeImage() but does it in SVG. See below for the options. See README.EXAMPLES too.  | 
| 
748
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
749
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 =item Module::Dependency::Grapher::makeText( $kind, $seeds, $filename, $options );  | 
| 
750
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
751
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 Creates a plain-text rendition of the dependency heirarchy. As it's only ASCII it can't plot  | 
| 
752
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 the individual links between items, so it simplifies and presents only each level of the   | 
| 
753
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 tree as a whole.  | 
| 
754
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
755
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 Parameters are as for makeImage()  | 
| 
756
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
757
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 See below for options. See README.EXAMPLES too.  | 
| 
758
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
759
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 =item Module::Dependency::Grapher::makeHtml( $kind, $seeds, $filename, $options );  | 
| 
760
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
761
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 Creates an HTML fragment rendition of the dependency heirarchy. As it's only text it can't plot  | 
| 
762
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 the individual links between items, so it simplifies and presents only each level of the   | 
| 
763
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 tree. Information comes out in a table, and the whole fragment uses CLASS attributes so that you  | 
| 
764
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 can apply CSS to it. Typical fragment is:  | 
| 
765
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
766
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 	Dependencies for all scripts  | 
| 
767
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 	Grapher.pm 1.7 - Fri Jan 11 00:00:56 2002  | 
| 
768
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 	Key: Parent indicates parent dependencies   | 
| 
769
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 		**** indicates the item(s) from which the relationships are drawn   | 
| 
770
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 	    Child are child dependencies   | 
| 
771
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
772
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 	  | 
| 
777
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 	  | 
| 
778
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
779
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 Parameters are as for makeImage().   | 
| 
780
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
781
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 See below for options - especially the ImageMap (and related) options, which allows this method to return an HTML client-side  | 
| 
782
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 imagemap. See README.EXAMPLES too.  | 
| 
783
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
784
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 =back  | 
| 
785
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
786
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 =head2 OPTIONS  | 
| 
787
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
788
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 Options are case-sensitive, and you pass them in as a hash reference, e.g.  | 
| 
789
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
790
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 	Module::Dependency::Grapher::makeImage( $kind, $objlist, $IMGFILE, {Title => $title, Format => 'GIF'} );  | 
| 
791
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
792
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 These are the recognized options:  | 
| 
793
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
794
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 =over 4  | 
| 
795
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
796
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 =item Title  | 
| 
797
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
798
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 Sets the title of the output to whatever string you want. Displayed at the top.  | 
| 
799
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
800
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 =item Format  | 
| 
801
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
802
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 The output image format - can be (case-insensitive) GIF, PNG, GD, or JPG - but some may not be available  | 
| 
803
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 depending on how your local copy of libgd was compiled. You'll need to examine you local GD setup (PNG is  | 
| 
804
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 pretty standard thesedays though) Default is PNG.  | 
| 
805
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
806
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 The makePs() method recognizes only 'EPS' or 'PS' as format options. Default is 'EPS'.  | 
| 
807
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
808
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 =item IncludeRegex  | 
| 
809
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
810
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 A regular expression use to filter the items displayed. If this is '::' for example then the output will only  | 
| 
811
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 show dependencies that contain those characters.  | 
| 
812
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
813
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 =item ExcludeRegex  | 
| 
814
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
815
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 A regular expression use to filter the items displayed. If this is '::' for example then the output will B  | 
| 
816
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 show dependencies that contain those characters.  | 
| 
817
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
818
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 =item NoLegend  | 
| 
819
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
820
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 If true, don't print the 'legend' box/text  | 
| 
821
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
822
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 =item NoVersion  | 
| 
823
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
824
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 If true, don't print the version/date line.  | 
| 
825
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
826
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 =item Colour  | 
| 
827
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
828
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 Used by makePs() only - if 1 it makes a colour image, if 0 it makes a greyscale image. Default is 1.  | 
| 
829
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
830
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 =item Font  | 
| 
831
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
832
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 sed by makePs() only. Set the font used in the drawing. Default is 'Helvetica'.  | 
| 
833
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
834
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 =item ImageMap  | 
| 
835
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
836
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 Used by makeHtml() only - if set to 'print' it will print a skeleton imagemap to the output file; if set to 'return' then the imagemap text  | 
| 
837
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 is the return value of makeHtml() so that the caller can process the string further.  | 
| 
838
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
839
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 An imagemap looks like this example, but you can change the href attributes using the HrefFormat option (see below) so that they match what your CGI  | 
| 
840
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 program is expecting.  | 
| 
841
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
842
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 	 | 
| 
843
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 	  | 
| 
844
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 	  | 
| 
845
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 	  | 
| 
846
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
847
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 If you want to totally change the format of each 'area' element see the ImageMapCode option below.  | 
| 
848
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
849
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 Note that the href attributes are deliberately left empty, for users of the 'return' method to easily post-process the string. The PACK comment  | 
| 
850
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 at the start of each line is provided to tell you what the package or scriptname is. The imagemap corresponds to the image that _would_  | 
| 
851
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 be produced by makeImage() if it were given the same arguments.  | 
| 
852
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
853
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 See the bundled 'cgidepend.plx' CGI program to see a use for this imagemap.  | 
| 
854
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
855
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 =item ImageMapCode  | 
| 
856
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
857
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 Used by makeHtml() only - must be a code reference. Called once for each 'area' required. The first argument is the package name  | 
| 
858
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 that the 'area' corresponds to, 'Foo::Bar' or 'baz.pl' for example. The second argument is the current HrefFormat setting, but you  | 
| 
859
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 may ignore that, seeing as you're going to be writing the entire element. The default coderef creates the 'area' elements as shown above  | 
| 
860
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 and respects the HrefFormat option.  | 
| 
861
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
862
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 =item HrefFormat  | 
| 
863
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
864
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 Used by makeHtml() and makeSvg() only - default is ''. A sprintf() formatting string used to format the 'href'  | 
| 
865
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 attribute in EACH 'area' element of the imagemap, or the href of the anchors in SVG output.  | 
| 
866
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 E.g. '?myparam=%s' would create an href of '?myparam=Foo'.  | 
| 
867
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
868
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 If empty (as is the default) then you get no clickable links in the SVG output.  | 
| 
869
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
870
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 =back  | 
| 
871
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
872
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 =head1 PREREQUISITES  | 
| 
873
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
874
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 If you want to use the makePs() method you'll need PostScript::Simple installed.  | 
| 
875
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 If you want to use the makeImage() method you'll need GD installed.  | 
| 
876
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 If you want to use the makeSvg() method you'll need the SVG module.  | 
| 
877
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 However, these modules are 'require'd as needed so you can quite happily use the makeText and makeHtml routines.  | 
| 
878
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
879
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 =head1 SEE ALSO  | 
| 
880
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
881
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 Module::Dependency and the README files.  | 
| 
882
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
883
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 =head1 VERSION  | 
| 
884
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
885
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 $Id: Grapher.pm 6632 2006-07-11 14:00:38Z timbo $  | 
| 
886
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
887
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 =cut  | 
| 
888
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    |