1
|
|
|
<?php |
2
|
|
|
|
3
|
|
|
namespace SixtyNine\Cloud\Usher; |
4
|
|
|
|
5
|
|
|
use SixtyNine\Cloud\FontMetrics; |
6
|
|
|
use SixtyNine\Cloud\Model\Box; |
7
|
|
|
use SixtyNine\Cloud\Placer\PlacerInterface; |
8
|
|
|
|
9
|
|
|
/** |
10
|
|
|
* Responsible to find a place for the word in the cloud |
11
|
|
|
*/ |
12
|
|
|
|
13
|
|
|
class Usher |
14
|
|
|
{ |
15
|
|
|
const DEFAULT_MAX_TRIES = 100000; |
16
|
|
|
|
17
|
|
|
/** @var int */ |
18
|
|
|
protected $maxTries; |
19
|
|
|
|
20
|
|
|
/** @var \SixtyNine\Cloud\Usher\MaskInterface */ |
21
|
|
|
protected $mask; |
22
|
|
|
|
23
|
|
|
/** @var \SixtyNine\Cloud\Placer\PlacerInterface */ |
24
|
|
|
protected $placer; |
25
|
|
|
|
26
|
|
|
/** @var \SixtyNine\Cloud\FontMetrics */ |
27
|
|
|
protected $metrics; |
28
|
|
|
|
29
|
|
|
/** |
30
|
|
|
* @param int $imgWidth |
31
|
|
|
* @param int $imgHeight |
32
|
|
|
* @param PlacerInterface $placer |
33
|
|
|
* @param FontMetrics $metrics |
34
|
|
|
* @param int $maxTries |
35
|
|
|
*/ |
36
|
4 |
|
public function __construct( |
37
|
|
|
$imgWidth, |
38
|
|
|
$imgHeight, |
39
|
|
|
PlacerInterface $placer, |
40
|
|
|
FontMetrics $metrics, |
41
|
|
|
$maxTries = self::DEFAULT_MAX_TRIES |
42
|
|
|
) { |
43
|
|
|
// $this->mask = new SimpleMask(); |
|
|
|
|
44
|
4 |
|
$this->mask = new QuadTreeMask($imgWidth, $imgHeight); |
45
|
4 |
|
$this->metrics = $metrics; |
46
|
4 |
|
$this->imgHeight = $imgHeight; |
|
|
|
|
47
|
4 |
|
$this->imgWidth = $imgWidth; |
|
|
|
|
48
|
4 |
|
$this->maxTries = $maxTries; |
49
|
4 |
|
$this->placer = $placer; |
50
|
4 |
|
} |
51
|
|
|
|
52
|
|
|
/** |
53
|
|
|
* @param string $word |
54
|
|
|
* @param string $font |
55
|
|
|
* @param int $size |
56
|
|
|
* @param int $angle |
57
|
|
|
* @return bool|Box |
58
|
|
|
*/ |
59
|
4 |
|
public function getPlace($word, $font, $size, $angle) |
60
|
|
|
{ |
61
|
4 |
|
$bounds = new Box(0, 0, $this->imgWidth, $this->imgHeight); |
62
|
4 |
|
$box = $this->metrics->calculateSize($word, $font, $size, $angle); |
63
|
4 |
|
$place = $this->searchPlace($bounds, $box); |
64
|
|
|
|
65
|
4 |
|
if ($place) { |
66
|
4 |
|
$this->mask->add($place->getPosition(), $box); |
67
|
4 |
|
return $place; |
68
|
|
|
} |
69
|
|
|
|
70
|
|
|
return false; |
71
|
|
|
} |
72
|
|
|
|
73
|
|
|
/** |
74
|
|
|
* Search a free place for a new box. |
75
|
|
|
* @param \SixtyNine\Cloud\Model\Box $bounds |
76
|
|
|
* @param \SixtyNine\Cloud\Model\Box $box |
77
|
|
|
* @return bool|Box |
78
|
|
|
*/ |
79
|
4 |
|
protected function searchPlace(Box $bounds, Box $box) |
80
|
|
|
{ |
81
|
4 |
|
$placeFound = false; |
82
|
4 |
|
$current = $this->placer->getFirstPlaceToTry(); |
83
|
4 |
|
$curTry = 1; |
84
|
|
|
|
85
|
4 |
|
while (!$placeFound) { |
86
|
|
|
|
87
|
4 |
|
if (!$current) { |
88
|
|
|
return false; |
89
|
|
|
} |
90
|
|
|
|
91
|
4 |
|
if ($curTry > $this->maxTries) { |
92
|
|
|
return false; |
93
|
|
|
} |
94
|
|
|
|
95
|
4 |
|
$currentBox = $box->move($current->getX(), $current->getY()); |
96
|
4 |
|
$placeFound = !$this->mask->overlaps($currentBox); |
97
|
|
|
|
98
|
4 |
|
$placeFound = $placeFound && $currentBox->inside($bounds); |
99
|
|
|
|
100
|
4 |
|
if ($placeFound) { |
101
|
4 |
|
break; |
102
|
|
|
} |
103
|
|
|
|
104
|
4 |
|
$current = $this->placer->getNextPlaceToTry($current); |
105
|
4 |
|
$curTry++; |
106
|
|
|
} |
107
|
|
|
|
108
|
4 |
|
$currentBox = $box->move($current->getX(), $current->getY()); |
109
|
4 |
|
return $currentBox->inside($bounds) ? $currentBox : false; |
110
|
|
|
} |
111
|
|
|
} |
112
|
|
|
|
Sometimes obsolete code just ends up commented out instead of removed. In this case it is better to remove the code once you have checked you do not need it.
The code might also have been commented out for debugging purposes. In this case it is vital that someone uncomments it again or your project may behave in very unexpected ways in production.
This check looks for comments that seem to be mostly valid code and reports them.