DrawingTest::testDrawingWithPreciseUsher()   A
last analyzed

Complexity

Conditions 4
Paths 4

Size

Total Lines 37

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 37
rs 9.328
c 0
b 0
f 0
cc 4
nc 4
nop 0
1
<?php
2
3
namespace SixtyNine\Cloud\Tests\Builder;
4
5
use Imagine\Gd\Imagine;
6
use Imagine\Image\Box as ImagineBox;
7
use Imagine\Image\Color;
8
use Imagine\Image\ImageInterface;
9
use Imagine\Image\Point;
10
use Imagine\Image\PointInterface;
11
use SixtyNine\Cloud\Drawer\Drawer;
12
use SixtyNine\Cloud\Factory\FontsFactory;
13
use SixtyNine\Cloud\Factory\PlacerFactory;
14
use SixtyNine\Cloud\FontMetrics;
15
use SixtyNine\Cloud\Model\Cloud;
16
use SixtyNine\Cloud\Renderer\CloudRenderer;
17
use SixtyNine\Cloud\Usher\Usher;
18
use PHPUnit\Framework\TestCase;
19
20
class DrawingTest extends TestCase
21
{
22
    public function setUp()
0 ignored issues
show
Coding Style introduced by
setUp uses the super-global variable $_ENV which is generally not recommended.

Instead of super-globals, we recommend to explicitly inject the dependencies of your class. This makes your code less dependent on global state and it becomes generally more testable:

// Bad
class Router
{
    public function generate($path)
    {
        return $_SERVER['HOST'].$path;
    }
}

// Better
class Router
{
    private $host;

    public function __construct($host)
    {
        $this->host = $host;
    }

    public function generate($path)
    {
        return $this->host.$path;
    }
}

class Controller
{
    public function myAction(Request $request)
    {
        // Instead of
        $page = isset($_GET['page']) ? intval($_GET['page']) : 1;

        // Better (assuming you use the Symfony2 request)
        $page = $request->query->get('page', 1);
    }
}
Loading history...
23
    {
24
        if (array_key_exists('CI', $_ENV) && $_ENV['CI']) {
25
            $this->markTestSkipped('Avoid risky tests in CI env');
26
        }
27
    }
28
29
    /**
30
     * Illustrate the difficulty to properly draw a bounding box around rotated text with Imagine.
31
     */
32
    public function testDrawing()
33
    {
34
        $imagine = new Imagine();
35
        $image = $imagine->create(new ImagineBox(400, 400), new Color('#000000'));
36
37
        $text = 'Foobar';
38
        $size = 80;
39
40
        $factory = FontsFactory::create(__DIR__ . '/fixtures/fonts');
41
        $metrics = new FontMetrics($factory);
42
        $font = $factory->getImagineFont('Arial.ttf', $size, '#ffffff');
43
44
        $fontSize = $metrics->calculateSize($text, 'Arial.ttf', $size, 0);
45
        $pos = array(200, 200);
46
        $box = array($fontSize->getWidth(), $fontSize->getHeight());
47
48
        $image->draw()->text($text, $font, new Point($pos[0], $pos[1]), 0);
49
        $image->draw()->text($text, $font, new Point($pos[0], $pos[1]), 90);
50
        $image->draw()->text($text, $font, new Point($pos[0], $pos[1]), 180);
51
        $image->draw()->text($text, $font, new Point($pos[0], $pos[1]), 270);
52
53
        // Angle = 0 - so far so good...
54
        $this->drawBox($image, $this->createPoint($pos[0], $pos[1]), $box[0], $box[1], 0xFF0000);
55
56
        // Angle = 90 - Y needs to be adjusted, dimensions inverted
57
        $this->drawBox($image, $this->createPoint($pos[0], $pos[1] + $box[1]), $box[1], $box[0], 0xFF0000);
58
59
        // Angle = 180 - X and Y need adjustments, X might go out of the image on the left (which Imagine does not like)
60
        $x = $pos[0] - $box[0];
61
        $width = $x >= 0 ? $box[0] : $box[0] + $x;
62
        $this->drawBox($image, $this->createPoint($x, $pos[1] + $box[1]), $width, $box[1], 0xFF0000);
63
64
        // Angle = 270 - X and Y need adjustments, it depends on the font size, Y might go out of the image on the top, dimensions inverted
65
        $y = $pos[1] - $box[0] + $size;
66
        $height = $y >= 0 ? $box[0] : $box[0] + $y;
67
        $this->drawBox($image, $this->createPoint($pos[0] - $box[1], $y), $box[1], $height, 0xFF0000);
68
69
        $image->save('/tmp/test1.png');
70
    }
71
72
    /**
73
     * Now the same using the Drawer class.
74
     */
75
    public function testDrawingWithDrawer()
76
    {
77
        $text = 'Foobar';
78
        $size = 80;
79
80
        $factory = FontsFactory::create(__DIR__ . '/fixtures/fonts');
81
        $metrics = new FontMetrics($factory);
82
        $fontSize = $metrics->calculateSize($text, 'Arial.ttf', $size, 0);
83
        $pos = array(200, 200);
84
        $box = array($fontSize->getWidth(), $fontSize->getHeight());
85
86
        $image = Drawer::create($factory)
87
            ->createImage(400, 400, '#000000')
88
            ->setFont('Arial.ttf')
89
            ->drawText($pos[0], $pos[1], $text, $size, '#FFFFFF', 0)
90
            ->drawText($pos[0], $pos[1], $text, $size, '#FFFFFF', 90)
91
            ->drawText($pos[0], $pos[1], $text, $size, '#FFFFFF', 180)
92
            ->drawText($pos[0], $pos[1], $text, $size, '#FFFFFF', 270)
93
            ->drawBoxForText($pos[0], $pos[1], $box[0], $box[1], 0, '#00ffff')
94
            ->drawBoxForText($pos[0], $pos[1], $box[0], $box[1], 90, '#00ffff')
95
            ->drawBoxForText($pos[0], $pos[1], $box[0], $box[1], 180, '#00ffff')
96
            ->drawBoxForText($pos[0], $pos[1], $box[0], $box[1], 270, '#00ffff')
97
            ->getImage()
98
        ;
99
100
        $image->save('/tmp/test2.png');
101
    }
102
103
    public function testDrawingAtOrigin()
104
    {
105
        $text = 'Foobar';
106
        $size = 80;
107
108
        $factory = FontsFactory::create(__DIR__ . '/fixtures/fonts');
109
        $metrics = new FontMetrics($factory);
110
        $fontSize = $metrics->calculateSize($text, 'Arial.ttf', $size, 0);
111
        $pos = array(0, 0);
112
        $box = array($fontSize->getWidth(), $fontSize->getHeight());
113
114
        $image = Drawer::create($factory)
115
            ->createImage(400, 400, '#000000')
116
            ->setFont('Arial.ttf')
117
            ->drawText($pos[0], $pos[1], $text, $size, '#FFFFFF', 0)
118
            ->drawBoxForText($pos[0], $pos[1], $box[0], $box[1], 0, '#00ffff')
119
            ->getImage()
120
        ;
121
122
        $image->save('/tmp/test3.png');
123
    }
124
125
    public function testDrawingWithUsher()
126
    {
127
        $factory = FontsFactory::create(__DIR__ . '/fixtures/fonts');
128
        $metrics = new FontMetrics($factory);
129
        $placer = PlacerFactory::getInstance()->getPlacer(PlacerFactory::PLACER_CIRCULAR, 400, 400, 5);
130
        $usher = new Usher(400, 400, $placer, $metrics);
131
        $drawer = Drawer::create($factory)
132
            ->createImage(400, 400, '#000000')
133
            ->setFont('Arial.ttf')
134
        ;
135
136
        $words = array(
137
            array('first', 50, 0, '#ff0000'),
138
            array('second', 20, 270, '#0000ff'),
139
            array('third', 24, 0, '#00ff00'),
140
            array('fourth', 36, 270, '#00ffff'),
141
            array('fifth', 36, 0, '#ff00ff'),
142
            array('sixth', 20, 0, '#ffff00'),
143
            array('seventh', 24, 270, '#aaaaaa'),
144
        );
145
146
        foreach ($words as $values) {
147
            $place = $usher->getPlace($values[0], 'Arial.ttf', $values[1], $values[2]);
148
            if ($place) {
149
                if ($values[2] === 0) {
150
                    $drawer->drawText($place->getX(), $place->getY(), $values[0], $values[1], $values[3], $values[2]);
151
                } else {
152
                    $drawer->drawText($place->getX() + $place->getWidth(), $place->getY() + $place->getHeight() - $values[1], $values[0], $values[1], $values[3], $values[2]);
153
                }
154
                $drawer->drawBox($place->getX(), $place->getY(), $place->getWidth(), $place->getHeight(), $values[3]);
155
            }
156
        }
157
158
        $drawer->drawMask($usher->getMask(), '#ffffff');
159
160
        $drawer->getImage()->save('/tmp/test4.png');
161
    }
162
163
    public function testDrawingWithPreciseUsher()
164
    {
165
        $factory = FontsFactory::create(__DIR__ . '/fixtures/fonts');
166
        $metrics = new FontMetrics($factory);
167
        $placer = PlacerFactory::getInstance()->getPlacer(PlacerFactory::PLACER_CIRCULAR, 400, 400, 5);
168
        $usher = new Usher(400, 400, $placer, $metrics, true);
169
        $drawer = Drawer::create($factory)
170
            ->createImage(400, 400, '#000000')
171
            ->setFont('Arial.ttf')
172
        ;
173
174
        $words = array(
175
            array('first', 50, 0, '#ff0000'),
176
            array('second', 20, 270, '#0000ff'),
177
            array('third', 24, 0, '#00ff00'),
178
            array('fourth', 36, 270, '#00ffff'),
179
            array('fifth', 36, 0, '#ff00ff'),
180
            array('sixth', 40, 0, '#ffff00'),
181
            array('seventh', 24, 270, '#aaaaaa'),
182
        );
183
184
        foreach ($words as $values) {
185
            $place = $usher->getPlace($values[0], 'Arial.ttf', $values[1], $values[2]);
186
            if ($place) {
187
                if ($values[2] === 0) {
188
                    $drawer->drawText($place->getX(), $place->getY(), $values[0], $values[1], $values[3], $values[2]);
189
                } else {
190
                    $drawer->drawText($place->getX() + $place->getWidth(), $place->getY() + $place->getHeight() - $values[1], $values[0], $values[1], $values[3], $values[2]);
191
                }
192
                $drawer->drawBox($place->getX(), $place->getY(), $place->getWidth(), $place->getHeight(), $values[3]);
193
            }
194
        }
195
196
        $drawer->drawMask($usher->getMask(), '#ffffff');
197
198
        $drawer->getImage()->save('/tmp/test5.png');
199
    }
200
201
    /**
202
     * @param ImageInterface $image
203
     * @param PointInterface $pos
204
     * @param int $width
205
     * @param int $height
206
     * @param string $color
207
     */
208
    protected function drawBox(ImageInterface $image, PointInterface $pos, $width, $height, $color = '#ffffff')
209
    {
210
        $x = $pos->getX();
211
        $y = $pos->getY();
212
213
        $points = array(
214
            $this->createPoint($x, $y),
215
            $this->createPoint($x + $width, $y),
216
            $this->createPoint($x + $width, $y + $height),
217
            $this->createPoint($x, $y + $height),
218
        );
219
        $image->draw()->polygon($points, new Color($color));
220
    }
221
222
    /**
223
     * @param int $x
224
     * @param int $y
225
     * @return Point
226
     */
227
    protected function createPoint($x, $y)
228
    {
229
        $x = $x >= 0 ? $x : 0;
230
        $y = $y >= 0 ? $y : 0;
231
        return new Point($x, $y);
232
    }
233
}
234