Test Failed
Push — master ( a0e7d0...b649da )
by Dan
03:02
created

CloudBuilder::addWords()   B

Complexity

Conditions 4
Paths 4

Size

Total Lines 26
Code Lines 17

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 15
CRAP Score 4

Importance

Changes 0
Metric Value
dl 0
loc 26
ccs 15
cts 15
cp 1
rs 8.5806
c 0
b 0
f 0
cc 4
eloc 17
nc 4
nop 2
crap 4
1
<?php
2
namespace SixtyNine\Cloud\Builder;
3
4
use Imagine\Gd\Font;
5
use Imagine\Image\Color;
6
use Imagine\Image\Point;
7
use SixtyNine\Cloud\Factory\FontsFactory;
8
use SixtyNine\Cloud\Factory\PlacerFactory;
9
use SixtyNine\Cloud\FontMetrics;
10
use SixtyNine\Cloud\FontSize\FontSizeGeneratorInterface;
11
use SixtyNine\Cloud\FontSize\LinearFontSizeGenerator;
12
use SixtyNine\Cloud\Model\Cloud;
13
use SixtyNine\Cloud\Model\CloudWord;
14
use SixtyNine\Cloud\Model\Word;
15
use SixtyNine\Cloud\Model\WordsList;
16
use SixtyNine\Cloud\Usher\Usher;
17
18
class CloudBuilder
19
{
20
    /** @var WordsList */
21
    protected $list;
22
    /** @var int */
23
    protected $width = 800;
24
    /** @var int */
25
    protected $height = 600;
26
    /** @var string */
27
    protected $font;
28
    /** @var string */
29
    protected $backgroundColor = '#ffffff';
30
    /** @var FontSizeGeneratorInterface */
31
    protected $sizeGenerator;
32
    /** @var string */
33
    protected $placerName;
34
    /** @var int */
35
    protected $minFontSize = 10;
36
    /** @var int */
37
    protected $maxFontSize = 60;
38
    /** @var FontsFactory */
39
    protected $fontsFactory;
40
    /** @var bool */
41 4
    protected $precise = false;
42
43 4
    protected function __construct(FontsFactory $fontsFactory)
44 4
    {
45
        $this->fontsFactory = $fontsFactory;
46
    }
47
48
    /**
49 4
     * @return CloudBuilder
50
     */
51 4
    public static function create(FontsFactory $fontsFactory)
52
    {
53
        return new self($fontsFactory);
54
    }
55
56
    /**
57
     * @param int $width
58
     * @param int $height
59 2
     * @return CloudBuilder
60
     */
61 2
    public function setDimension($width, $height)
62 2
    {
63 2
        $this->width = $width;
64
        $this->height = $height;
65
        return $this;
66 2
    }
67
68 2
    public function setBackgroundColor($color)
69 2
    {
70
        $this->backgroundColor = $color;
71
        return $this;
72 4
    }
73
74 4
    public function setFont($name)
75 4
    {
76
        $this->font = $name;
77
        return $this;
78
    }
79
80
    public function setSizeGenerator(FontSizeGeneratorInterface $generator)
81
    {
82
        $this->sizeGenerator = $generator;
83
        return $this;
84
    }
85
86
    public function setFontSizes($minSize, $maxSize)
87
    {
88
        $this->minFontSize = $minSize;
89
        $this->maxFontSize = $maxSize;
90
        return $this;
91 1
    }
92
93 1
    public function setPlacer($name)
94
    {
95
        if (!in_array($name, PlacerFactory::getInstance()->getPlacersNames())) {
96
            throw new \InvalidArgumentException('Placer not found: ' . $name);
97 1
        }
98 1
99
        $this->placerName = $name;
100
        return $this;
101 3
    }
102
103 3
    public function setPrecise()
104 3
    {
105
        $this->precise = true;
106
    }
107 4
108
    public function useList(WordsList $list)
109 4
    {
110
        $this->list = $list;
111
        return $this;
112
    }
113 4
114
    public function build()
115 4
    {
116 4
        if (!$this->font) {
117 4
            throw new \InvalidArgumentException('Font not set');
118 4
        }
119
120
        $cloud = new Cloud();
121 4
        $cloud
122 3
            ->setFont($this->font)
123 3
            ->setWidth($this->width)
124
            ->setHeight($this->height)
125
            ->setBackgroundColor($this->backgroundColor)
126 4
        ;
127
128
        if ($this->list) {
129 3
            $this->addWords($cloud, $this->list);
130
            $this->placeWords($cloud);
131 3
        }
132 3
133
        return $cloud;
134 3
    }
135 3
136
    protected function addWords(Cloud $cloud, WordsList $list)
137
    {
138
        $words = $list->getWordsOrdered();
139 3
        $maxCount = $list->getWordsMaxCount();
140 3
141
        if (!$this->sizeGenerator) {
142 3
            $this->sizeGenerator = new LinearFontSizeGenerator();
143 3
        }
144 3
145 3
        /** @var Word $word */
146 3
        foreach ($words as $word) {
147 3
            $cloudWord = new CloudWord();
148 3
            $cloudWord
149
                ->setCloud($cloud)
150 3
                ->setPosition(array(0, 0))
151
                ->setSize($this->sizeGenerator->calculateFontSize($word->getCount(), $maxCount, $this->minFontSize, $this->maxFontSize))
152
                ->setAngle($word->getOrientation() === Word::DIR_VERTICAL ? 270 : 0)
153 3
                ->setColor($word->getColor())
154
                ->setText($word->getText())
155
                ->setIsVisible(true)
156 3
            ;
157
            $cloud->addWord($cloudWord);
158 3
        }
159 1
160 3
        return $this;
161
    }
162
163 3
    protected function placeWords(Cloud $cloud)
164 3
    {
165
        $placer = $this->placerName
166
            ? PlacerFactory::getInstance()->getPlacer($this->placerName, $cloud->getWidth(), $cloud->getHeight())
167 3
            : PlacerFactory::getInstance()->getDefaultPlacer($cloud->getWidth(), $cloud->getHeight())
168
        ;
169 3
170
        $metrics = new FontMetrics($this->fontsFactory);
171 3
        $usher = new Usher($cloud->getWidth(), $cloud->getHeight(), $placer, $metrics);
172
173 3
        /** @var CloudWord $word */
174
        foreach ($cloud->getWords() as $word) {
175 3
176 3
            $place = $usher->getPlace($word->getText(), $cloud->getFont(), $word->getSize(), $word->getAngle(), $this->precise);
177
178 3
            $word->setIsVisible((bool)$place);
179 2
180 2
            if ($place) {
181 2
182
                $box = $place->getDimensions();
183
                $word->setBox(array($box->getWidth(), $box->getHeight()));
184
185 3
                if ($word->getAngle() !== 0) {
186
                    $place = new Point(
187
                        $place->getX() + $box->getWidth(),
188 3
                        $place->getY() + $box->getHeight()
189
                    );
190
                }
191
192
                $word->setPosition(array((int)$place->getX(), (int)$place->getY()));
193
            }
194
        }
195
    }
196
197
}
198