3 # -*- perl -*- vim:set ft=perl sw=4 sts=4:
5 # Usage: relational-schema out.png RELATION:_Primary_Key,.Foreign_Key,Etc
6 # To clarifiy, specifiy the relation name, followed by a colon, followed by
7 # the attributes seperated by commas. Primary keys should be prefixed with
8 # an underscore, and foreign keys with a period.
9 # It is also possible to override or augment the functional dependencies by
10 # adding a second colon and additional specifications. Since this was
11 # unnecessary for the assignment, it is not documented here.
16 use vars qw($font $maxwidth $pd $fh);
21 my $out = shift or die "No output file specified.\n";
23 die "No rows.\n" unless (@rows);
25 my $image = new Image::Imlib2->new(1,1);
26 $image->add_font_path ("/usr/share/fonts/truetype/msttcorefonts");
27 $image->load_font($font);
28 ($fh, $fh) = $image->get_text_size("(Ay)");
29 $image = new Image::Imlib2->new($maxwidth, ($#rows+1)*($fh*2+$pd*12+2));
30 $image->add_font_path ("/usr/share/fonts/truetype/msttcorefonts");
31 $image->load_font($font);
32 $image->set_color(255,255,255,255);
33 #$image->fill_rectangle(0,0,$maxwidth,($#rows+1)*($fh*2+$pd*12+2));
36 my ($image, $text, $x, $y, $underline)=@_;
37 $image->load_font($font);
38 my ($w, $h) = $image->get_text_size($text);
39 $image->set_color(255,255,255,255);
40 $image->fill_rectangle($x,$y,$w+2*$pd+2,$fh+2*$pd+2);
41 $image->set_color(0,0,0,255);
42 $image->draw_rectangle($x,$y,$w+2*$pd+2,$fh+2*$pd+2);
43 $image->draw_text($x+$pd,$y+$pd,$text);
44 if(($underline||0)==1) {
45 $image->draw_line($x+$pd,$y+$pd+$fh,$x+$w+$pd,$y+$pd+$fh);
46 } elsif(($underline||0)==2) {
47 for(my $i=0;$i<$w;$i+=5) {
48 $image->draw_line($x+$pd+$i,$y+$pd+$fh,
49 $x+$pd+($i+2>$w?$w$i+2),$y+$pd+$fh);
58 foreach my $row (@rows) {
59 my ($title,$element,@depends) = split (':',$row);
60 my @elements = split (',',$element);
63 my ($toffset)=(2*$pd);
64 while ($title =~ s/^>//) {
67 my ($offset) = ($toffset);
68 foreach $element (@elements) {
70 if ($element =~ s/^_//) {
73 } elsif ($element =~ s/^\.//) {
78 warn "Element $element in $title not marked as ".
79 "primary or foreign key.\n" if ($element=~/_ID$/);
81 my $o=draw_boxed_text($image,$element,$offset,$line+$fh+5*$pd,$under);
82 $elcenters{$element}=($offset+$o/2);
87 if((($#depends>=0 and $depends[0] eq 'auto') or $#depends=-1)
88 and $#in>=0 and $#out>=0) {
89 $depends[0]=(join(",",@out)."/".join(",",@in));
90 } elsif($#depends>=0 and $depends[0] eq 'auto') {
93 foreach my $depend (@depends) {
98 $image->set_color(0,(32*($updown>>1))%128,(64*($updown>>1))%256,255);
99 my ($out,$in) = split('/',$depend);
101 my @out = split(',', $out);
102 my @in = split(',', $in );
103 my @temp = sort { $elcenters{$a} <=> $elcenters{$b} } (@out, @in);
106 $near=$line+$fh+5*$pd-1;
107 $far=$line+$fh+1*$pd-1;
109 $near=$line+2*$fh+7*$pd+2;
110 $far=$line+2*$fh+11*$pd+2;
112 $image->draw_line($elcenters{$temp[0]}+$pd*($updown>>1),
113 $far,$elcenters{$temp[$#temp]}+$pd*($updown>>1),$far);
114 foreach $out (@out) {
115 $image->draw_line($elcenters{$out}+$pd*($updown>>1),
116 $far,$elcenters{$out}+$pd*($updown>>1),$near);
119 my $arrow = Image::Imlib2::Polygon->new();
120 $arrow->add_point($elcenters{$in}+$pd*($updown>>1),$near);
121 $arrow->add_point($elcenters{$in}+$pd+$pd*($updown>>1),
123 $arrow->add_point($elcenters{$in}-$pd+$pd*($updown>>1),
125 $arrow->add_point($elcenters{$in},$near);
127 $image->draw_line($elcenters{$in}+$pd*($updown>>1),
128 $far,$elcenters{$in}+$pd*($updown>>1),$near);
129 $image->draw_polygon($arrow,1);
133 $image->set_color(0,0,0,255);
134 $image->draw_text($toffset+$pd*2,$line+4*$pd-$shifttitle*(7*$pd/2),$title);
135 $line+=2*$fh+12*$pd+2;