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";
24 die "No rows.\n" unless (@rows);
26 my $image = new Image::Imlib2->new(1,1);
27 $image->add_font_path ("/usr/share/fonts/truetype/msttcorefonts");
28 $image->load_font($font);
29 ($fh, $fh) = $image->get_text_size("(Ay)");
30 $image = new Image::Imlib2->new($maxwidth, ($#rows+1)*($fh*2+$pd*12+2));
31 $image->add_font_path ("/usr/share/fonts/truetype/msttcorefonts");
32 $image->load_font($font);
33 $image->set_color(255,255,255,255);
34 #$image->fill_rectangle(0,0,$maxwidth,($#rows+1)*($fh*2+$pd*12+2));
37 my ($image, $text, $x, $y, $underline)=@_;
38 $image->load_font($font);
39 my ($w, $h) = $image->get_text_size($text);
40 $image->set_color(255,255,255,255);
41 $image->fill_rectangle($x,$y,$w+2*$pd+2,$fh+2*$pd+2);
42 $image->set_color(0,0,0,255);
43 $image->draw_rectangle($x,$y,$w+2*$pd+2,$fh+2*$pd+2);
44 $image->draw_text($x+$pd,$y+$pd,$text);
45 if(($underline||0)==1) {
46 $image->draw_line($x+$pd,$y+$pd+$fh,$x+$w+$pd,$y+$pd+$fh);
47 } elsif(($underline||0)==2) {
48 for(my $i=0;$i<$w;$i+=5) {
49 $image->draw_line($x+$pd+$i,$y+$pd+$fh,
50 $x+$pd+($i+2>$w?$w$i+2),$y+$pd+$fh);
59 foreach my $row (@rows) {
60 my ($title,$element,@depends) = split (':',$row);
61 my @elements = split (',',$element);
64 my ($toffset)=(2*$pd);
65 while ($title =~ s/^>//) {
68 my ($offset) = ($toffset);
69 foreach $element (@elements) {
71 if ($element =~ s/^_//) {
74 } elsif ($element =~ s/^\.//) {
79 warn "Element $element in $title not marked as ".
80 "primary or foreign key.\n" if ($element=~/_ID$/);
82 my $o=draw_boxed_text($image,$element,$offset,$line+$fh+5*$pd,$under);
83 $elcenters{$element}=($offset+$o/2);
88 if((($#depends>=0 and $depends[0] eq 'auto') or $#depends=-1)
89 and $#in>=0 and $#out>=0) {
90 $depends[0]=(join(",",@out)."/".join(",",@in));
91 } elsif($#depends>=0 and $depends[0] eq 'auto') {
94 foreach my $depend (@depends) {
99 $image->set_color(0,(32*($updown>>1))%128,(64*($updown>>1))%256,255);
100 my ($out,$in) = split('/',$depend);
102 my @out = split(',', $out);
103 my @in = split(',', $in );
104 my @temp = sort { $elcenters{$a} <=> $elcenters{$b} } (@out, @in);
107 $near=$line+$fh+5*$pd-1;
108 $far=$line+$fh+1*$pd-1;
110 $near=$line+2*$fh+7*$pd+2;
111 $far=$line+2*$fh+11*$pd+2;
113 $image->draw_line($elcenters{$temp[0]}+$pd*($updown>>1),
114 $far,$elcenters{$temp[$#temp]}+$pd*($updown>>1),$far);
115 foreach $out (@out) {
116 $image->draw_line($elcenters{$out}+$pd*($updown>>1),
117 $far,$elcenters{$out}+$pd*($updown>>1),$near);
120 my $arrow = Image::Imlib2::Polygon->new();
121 $arrow->add_point($elcenters{$in}+$pd*($updown>>1),$near);
122 $arrow->add_point($elcenters{$in}+$pd+$pd*($updown>>1),
124 $arrow->add_point($elcenters{$in}-$pd+$pd*($updown>>1),
126 $arrow->add_point($elcenters{$in},$near);
128 $image->draw_line($elcenters{$in}+$pd*($updown>>1),
129 $far,$elcenters{$in}+$pd*($updown>>1),$near);
130 $image->draw_polygon($arrow,1);
134 $image->set_color(0,0,0,255);
135 $image->draw_text($toffset+$pd*2,$line+4*$pd-$shifttitle*(7*$pd/2),$title);
136 $line+=2*$fh+12*$pd+2;