root/sovereignty/label.php @ 461

Revision 246, 6.5 KB (checked in by exi, 13 years ago)

Added current sovereignty codebase

Line 
1<?php
2
3class labelmanager
4{
5    function labelmanager()
6    {
7        $this->labels = array();
8    }
9
10    // x,y,text,size,font,color,type
11    function add($x, $y, $text, $size, $font, $color, $type)
12    {
13        $label = array('x' => $x, 'y' => $y, 'text' => $text, 'size' => $size,
14                       'font' => $font, 'color' => $color, 'type' => $type);
15        $this->labels[] = $label;
16    }
17
18    function resort(&$image)
19    {
20        // calculate the ideal position for each label
21        foreach ($this->labels as $index => $label)
22        {
23            $bbox = imageftbbox($label['size'], 0, $label['font'], $label['text']);
24            $width = abs($bbox[4] - $bbox[0]);
25            $height = abs($bbox[5] - $bbox[1]);
26            $this->labels[$index]['nx'] = $this->labels[$index]['x'] = $label['x']-$width/2;
27            $this->labels[$index]['ny'] = $this->labels[$index]['y'] = $label['y']+$height/2;
28            $this->labels[$index]['box'] = $bbox;
29            $this->labels[$index]['width'] = $width;
30            $this->labels[$index]['height'] = $height;
31        }
32
33        $this->calcIntersects();
34        for ($i=0; $i<100; $i++)
35         {
36            foreach ($this->intersects as $index => $sections)
37            {
38                foreach ($sections as $section)
39                {
40                    $vector = $this->getDirection($index, $section);
41
42                    $intx = $vector[0];
43                    $inty = $vector[1];
44
45                    // if the original point is not inside the new label - limit
46                    if (!$this->pointInLabel($intx+$this->labels[$section]['nx'], $inty+$this->labels[$section]['ny'], $this->labels[$section]))
47                    {
48                        $minx = $this->labels[$section]['x'];
49                        $miny = $this->labels[$section]['y']-$this->labels[$section]['height'];
50                        // no label leaves the area!
51                        $minx = max(0, $minx);
52                        $miny = max($this->labels[$section]['height'], $miny);
53
54                        $maxx = $this->labels[$section]['x']+$this->labels[$section]['width'];
55                        $maxy = $this->labels[$section]['y'];;
56
57                        $intx = min(max($intx+$this->labels[$section]['nx'], $minx), $maxx)-$this->labels[$section]['nx'];
58                        $inty = min(max($inty+$this->labels[$section]['ny'], $miny), $maxy)-$this->labels[$section]['ny'];
59                    }
60
61                    $this->labels[$section]['nx'] += $intx;
62                    $this->labels[$section]['ny'] += $inty;
63                }
64            }
65
66            $this->calcIntersects();
67        }
68    }
69
70    // return the best direction to move tag $i2
71    function getDirection($i1, $i2)
72    {
73        $x = $this->labels[$i2]['nx'] - $this->labels[$i1]['nx'];
74        $y = $this->labels[$i2]['ny'] - $this->labels[$i1]['ny'];
75
76        if ($x == 0)
77        {
78            $divisor = $y;
79        }
80        elseif ($y == 0)
81        {
82            $divisor = $x;
83        }
84        else
85        {
86            $divisor = max(abs($x), abs($y));
87        }
88        if ($divisor != 0)
89        {
90            $x /= $divisor;
91            $y /= $divisor;
92        }
93        return array($x, $y);
94    }
95
96    function pointInLabel($x, $y, $label)
97    {
98        return (($label['width'] >= abs($x - $label['x']))
99             && ($label['height'] >= abs($y - $label['y'])));
100    }
101
102    function calcIntersects()
103    {
104        $this->intersects = array();
105        foreach ($this->labels as $index => $label)
106        {
107            foreach ($this->labels as $index2 => $label2)
108            {
109                if ($index != $index2 && $this->canIntersect($label, $label2))
110                {
111                    $this->intersects[$index][] = $index2;
112                }
113            }
114        }
115    }
116
117
118    function sortHelper($a, $b)
119    {
120        return count($this->intersects[$b]) - count($this->intersects[$a]);
121    }
122
123    function canIntersect($label1, $label2, $debug = false)
124    {
125        $xmatch = $ymatch = false;
126        if ($label2['nx'] > $label1['nx'])
127        {
128            $l1x = $label1['nx']+$label1['width']+4;
129            $l2x = $label2['nx'];
130            if ($l1x >= $l2x)
131            {
132                $xmatch = true;
133            }
134        }
135        else
136        {
137            $l1x = $label1['nx'];
138            $l2x = $label2['nx']+$label2['width']+4;
139            if ($l2x >= $l1x)
140            {
141                $xmatch = true;
142            }
143        }
144        if ($label2['ny'] > $label1['ny'])
145        {
146            $l1y = $label1['ny'];
147            $l2y = $label2['ny']-$label2['height']-2;
148            if ($l1y >= $l2y)
149            {
150                $ymatch = true;
151            }
152        }
153        else
154        {
155            $l1y = $label1['ny']-$label1['height']-2;
156            $l2y = $label2['ny'];
157            if ($l2y >= $l1y)
158            {
159                $ymatch = true;
160            }
161        }
162        if ($debug)
163        {
164            echo 'xmatch: '.(int)$xmatch.")\n";
165            echo 'ymatch: '.(int)$ymatch.")\n";
166        }
167        return ($xmatch && $ymatch);
168    }
169
170    function draw(&$image)
171    {
172        $this->resort($image);
173        $black = imagecolorallocate($image, 0, 0, 0);
174
175        foreach ($this->labels as $index => $label)
176        {
177            $this->labels[$index]['x'] = $label['nx'];
178            $this->labels[$index]['y'] = $label['ny'];
179        }
180
181        foreach ($this->labels as $label)
182        {
183            if ($label['type'] == 'region')
184            {
185                imagefttext($image, $label['size'], 0, $label['x'], $label['y'], $label['color'], $label['font'], $label['text']);
186            }
187            elseif ($label['type'] == 'alliance')
188            {
189                imagefttext($image, $label['size'], 0, $label['x']-1, $label['y'], $black, $label['font'], $label['text']);
190                imagefttext($image, $label['size'], 0, $label['x']+1, $label['y'], $black, $label['font'], $label['text']);
191                imagefttext($image, $label['size'], 0, $label['x'], $label['y']-1, $black, $label['font'], $label['text']);
192                imagefttext($image, $label['size'], 0, $label['x'], $label['y']+1, $black, $label['font'], $label['text']);
193
194                imagefttext($image, $label['size'], 0, $label['x'], $label['y'], $label['color'], $label['font'], $label['text']);
195            }
196        }
197    }
198}
199?>
Note: See TracBrowser for help on using the browser.