Image   F
last analyzed

Complexity

Total Complexity 402

Size/Duplication

Total Lines 2474
Duplicated Lines 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
eloc 1345
c 1
b 0
f 0
dl 0
loc 2474
rs 0.8
wmc 402

85 Methods

Rating   Name   Duplication   Size   Complexity  
A Stream() 0 17 6
B DrawLine() 0 87 6
A FillToBorder() 0 7 2
A Bevel() 0 15 3
A ShadowRectangle() 0 41 4
A SetCanvasH() 0 4 1
A Arc() 0 12 3
B Polygon() 0 26 7
A NormAngle() 0 17 4
A CloneCanvasH() 0 7 1
B imageSmoothCircle() 0 54 6
B GetBBoxTTF() 0 54 11
F StrokeBoxedText() 0 112 13
A __get() 0 15 3
A Circle() 0 3 1
A SetStartPoint() 0 4 1
A SetInterlace() 0 3 1
A AddTxtCR() 0 13 2
B StyleLine() 0 49 11
A FilledBevel() 0 4 1
A CakeSlice() 0 33 4
B imagettfbbox_fixed() 0 85 10
F StrokeBoxedText2() 0 162 18
A GetBBoxHeight() 0 5 1
A GetTextHeight() 0 28 6
B CopyMerge() 0 42 9
A Line() 0 15 2
A PopColor() 0 7 2
A SetAlphaBlending() 0 3 1
A DashedLineForGrid() 0 33 3
A StyleLineTo() 0 5 1
A FilledPolygon() 0 14 3
A Rectangle() 0 3 1
A SetQuality() 0 3 1
A GetWidth() 0 7 2
A SetTransparent() 0 3 1
A SetCanvasColor() 0 3 1
A Point() 0 3 1
A SetFont() 0 19 6
A GetFontHeight() 0 5 1
A CreateImgCanvas() 0 27 3
A FilledRoundedRectangle() 0 30 2
A FilledArc() 0 18 5
A GetFontWidth() 0 5 1
A DashedLine() 0 28 3
A lip() 0 8 1
A FilledCircle() 0 3 1
B FilledRectangle2() 0 29 6
A Fill() 0 3 1
A __set() 0 3 1
A SetMargin() 0 13 5
A CreateFromString() 0 9 2
A SetLineWeight() 0 7 1
A CopyCanvasH() 0 10 2
A GetTTFBBox() 0 5 1
A DoSupersampling() 0 11 2
A LineTo() 0 5 1
A SetTextAlign() 0 4 1
A SetAntiAliasing() 0 5 2
A SetExpired() 0 3 1
B GetTextWidth() 0 42 9
B SetLineStyle() 0 25 9
A GetBBoxWidth() 0 5 1
F _StrokeBuiltinFont() 0 62 19
A DrawImageSmoothArc() 0 7 1
B imageSmoothArc() 0 79 11
A PushColor() 0 9 2
F _StrokeTTF() 0 202 30
A GetAntiAliasing() 0 3 1
F _imageSmoothArcDrawSegment() 0 259 63
A Headers() 0 27 4
A FilledRectangle() 0 3 1
D SetImgFormat() 0 44 21
A Destroy() 0 3 1
A Ellipse() 0 3 1
A StrokeText() 0 21 6
A RoundedRectangle() 0 23 2
A __construct() 0 21 3
A CreateColorForImageSmoothArc() 0 8 1
A SetColor() 0 11 2
A GetHeight() 0 7 2
A SetAutoMargin() 0 8 1
A CreateRawCanvas() 0 23 6
A Copy() 0 3 1
A FilledCakeSlice() 0 3 1

How to fix   Complexity   

Complex Class

Complex classes like Image often do a lot of different things. To break such a class down, we need to identify a cohesive component within that class. A common approach to find such a component is to look for fields/methods that share the same prefixes, or suffixes.

Once you have determined the fields that belong together, you can apply the Extract Class refactoring. If the component makes sense as a sub-class, Extract Subclass is also a candidate, and is often faster.

While breaking up the class, it is a good idea to analyze how other classes use Image, and based on these observations, apply Extract Interface, too.

1
<?php
2
3
/**
4
 * JPGraph v4.0.3
5
 */
6
7
namespace Amenadiel\JpGraph\Image;
8
9
use Amenadiel\JpGraph\Text\LanguageConv;
10
use Amenadiel\JpGraph\Text\TTF;
11
use Amenadiel\JpGraph\Util;
12
use Amenadiel\JpGraph\Util\ErrMsgText;
13
14
// load fonts only once, and define a constant for them
15
define("GD_FF_FONT0", imageloadfont(dirname(dirname(__FILE__)) . '/fonts/FF_FONT0.gdf'));
16
define("GD_FF_FONT1", imageloadfont(dirname(dirname(__FILE__)) . '/fonts/FF_FONT1.gdf'));
17
define("GD_FF_FONT2", imageloadfont(dirname(dirname(__FILE__)) . '/fonts/FF_FONT2.gdf'));
18
define("GD_FF_FONT1_BOLD", imageloadfont(dirname(dirname(__FILE__)) . '/fonts/FF_FONT1-Bold.gdf'));
19
define("GD_FF_FONT2_BOLD", imageloadfont(dirname(dirname(__FILE__)) . '/fonts/FF_FONT2-Bold.gdf'));
20
21
/**
22
 * File:        GD_IMAGE.INC.PHP
23
 * // Description: PHP Graph Plotting library. Low level image drawing routines
24
 * // Created:     2001-01-08, refactored 2008-03-29
25
 * // Ver:         $Id: gd_image.inc.php 1922 2010-01-11 11:42:50Z ljp $
26
 * //
27
 * // Copyright (c) Asial Corporation. All rights reserved.
28
 */
29
30
/**
31
 * @class Image
32
 * // Description: The very coor image drawing class that encapsulates all
33
 * //              calls to the GD library
34
 * //              Note: The class used by the library is the decendant
35
 * //              class RotImage which extends the Image class with transparent
36
 * //              rotation.
37
 */
38
class Image
39
{
40
    public $img;
41
    public $rgb;
42
    public $img_format;
43
    public $ttf;
44
    public $line_style = LINESTYLE_SOLID;
45
    public $current_color;
46
    public $current_color_name;
47
    public $original_width  = 0;
48
    public $original_height = 0;
49
    public $plotwidth       = 0;
50
    public $plotheight      = 0;
51
52
    // for __get, __set
53
    private $_left_margin   = 30;
54
    private $_right_margin  = 30;
55
    private $_top_margin    = 20;
56
    private $_bottom_margin = 30;
57
    //private $_plotwidth=0,$_plotheight=0;
58
    private $_width       = 0;
59
    private $_height      = 0;
60
    private $_line_weight = 1;
61
62
    protected $expired           = true;
63
    protected $lastx             = 0;
64
    protected $lasty             = 0;
65
    protected $obs_list          = [];
66
    protected $font_size         = 12;
67
    protected $font_family       = FF_DEFAULT;
68
    protected $font_style        = FS_NORMAL;
69
    protected $font_file         = '';
70
    protected $text_halign       = 'left';
71
    protected $text_valign       = 'bottom';
72
    protected $use_anti_aliasing = false;
73
    protected $quality;
74
    protected $colorstack    = [];
75
    protected $colorstackidx = 0;
76
    protected $canvascolor   = 'white';
77
    protected $langconv;
78
    protected $iInterlace = false;
79
    protected $bbox_cache = []; // STore the last found tetx bounding box
80
    protected $ff_font0;
81
    protected $ff_font0_bold;
82
    protected $ff_font1;
83
    protected $ff_font1_bold;
84
    protected $ff_font2;
85
    protected $ff_font2_bold;
86
87
    /**
88
     * CONSTRUCTOR.
89
     *
90
     * @param mixed $aWidth
91
     * @param mixed $aHeight
92
     * @param mixed $aFormat
93
     * @param mixed $aSetAutoMargin
94
     */
95
    public function __construct($aWidth = 0, $aHeight = 0, $aFormat = DEFAULT_GFORMAT, $aSetAutoMargin = true)
96
    {
97
        $this->original_width  = $aWidth;
98
        $this->original_height = $aHeight;
99
        $this->CreateImgCanvas($aWidth, $aHeight);
100
101
        if ($aSetAutoMargin) {
102
            $this->SetAutoMargin();
103
        }
104
105
        if (!$this->SetImgFormat($aFormat)) {
0 ignored issues
show
Bug Best Practice introduced by
The expression $this->SetImgFormat($aFormat) of type null|true is loosely compared to false; this is ambiguous if the boolean can be false. You might want to explicitly use !== null instead.

If an expression can have both false, and null as possible values. It is generally a good practice to always use strict comparison to clearly distinguish between those two values.

$a = canBeFalseAndNull();

// Instead of
if ( ! $a) { }

// Better use one of the explicit versions:
if ($a !== null) { }
if ($a !== false) { }
if ($a !== null && $a !== false) { }
Loading history...
106
            Util\JpGraphError::RaiseL(25081, $aFormat); //("JpGraph: Selected graphic format is either not supported or unknown [$aFormat]");
107
        }
108
        $this->ttf      = new TTF();
109
        $this->langconv = new LanguageConv();
110
111
        $this->ff_font0 =  GD_FF_FONT0;
112
        $this->ff_font1 =  GD_FF_FONT1;
113
        $this->ff_font2 =  GD_FF_FONT2;
114
        $this->ff_font1_bold =  GD_FF_FONT1_BOLD;
115
        $this->ff_font2_bold =  GD_FF_FONT2_BOLD;
116
    }
117
118
    // Enable interlacing in images
119
    public function SetInterlace($aFlg = true)
120
    {
121
        $this->iInterlace = $aFlg;
122
    }
123
124
    // Should we use anti-aliasing. Note: This really slows down graphics!
125
    public function SetAntiAliasing($aFlg = true)
126
    {
127
        $this->use_anti_aliasing = $aFlg;
128
        if (function_exists('imageantialias')) {
129
            imageantialias($this->img, $aFlg);
130
        } /*else {
131
    Util\JpGraphError::RaiseL(25128); //('The function imageantialias() is not available in your PHP installation. Use the GD version that comes with PHP and not the standalone version.')
132
    }*/
133
    }
134
135
    public function GetAntiAliasing()
136
    {
137
        return $this->use_anti_aliasing;
138
    }
139
140
    public function CreateRawCanvas($aWidth = 0, $aHeight = 0)
141
    {
142
        $aWidth *= SUPERSAMPLING_SCALE;
143
        $aHeight *= SUPERSAMPLING_SCALE;
144
145
        if ($aWidth <= 1 || $aHeight <= 1) {
146
            Util\JpGraphError::RaiseL(25082, $aWidth, $aHeight); //("Illegal sizes specified for width or height when creating an image, (width=$aWidth, height=$aHeight)");
147
        }
148
149
        $this->img = @imagecreatetruecolor($aWidth, $aHeight);
150
        if ($this->img === false) {
151
            Util\JpGraphError::RaiseL(25126);
152
            //die("Can't create truecolor image. Check that you really have GD2 library installed.");
153
        }
154
        $this->SetAlphaBlending();
155
156
        if ($this->iInterlace) {
157
            imageinterlace($this->img, 1);
158
        }
159
        if ($this->rgb != null) {
160
            $this->rgb->img = $this->img;
161
        } else {
162
            $this->rgb = new RGB($this->img);
163
        }
164
    }
165
166
    public function CloneCanvasH()
167
    {
168
        $oldimage = $this->img;
169
        $this->CreateRawCanvas($this->width, $this->height);
170
        imagecopy($this->img, $oldimage, 0, 0, 0, 0, $this->width, $this->height);
0 ignored issues
show
Bug introduced by
$this->height of type double is incompatible with the type integer expected by parameter $src_h of imagecopy(). ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

170
        imagecopy($this->img, $oldimage, 0, 0, 0, 0, $this->width, /** @scrutinizer ignore-type */ $this->height);
Loading history...
Bug introduced by
$this->width of type double is incompatible with the type integer expected by parameter $src_w of imagecopy(). ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

170
        imagecopy($this->img, $oldimage, 0, 0, 0, 0, /** @scrutinizer ignore-type */ $this->width, $this->height);
Loading history...
171
172
        return $oldimage;
173
    }
174
175
    public function CreateImgCanvas($aWidth = 0, $aHeight = 0)
176
    {
177
        $old = [$this->img, $this->width, $this->height];
178
179
        $aWidth  = round($aWidth);
180
        $aHeight = round($aHeight);
181
182
        $this->width  = $aWidth;
0 ignored issues
show
Bug Best Practice introduced by
The property width does not exist. Although not strictly required by PHP, it is generally a best practice to declare properties explicitly.
Loading history...
183
        $this->height = $aHeight;
0 ignored issues
show
Bug Best Practice introduced by
The property height does not exist. Although not strictly required by PHP, it is generally a best practice to declare properties explicitly.
Loading history...
184
185
        if ($aWidth == 0 || $aHeight == 0) {
186
            // We will set the final size later.
187
            // Note: The size must be specified before any other
188
            // img routines that stroke anything are called.
189
            $this->img = null;
190
            $this->rgb = null;
191
192
            return $old;
193
        }
194
195
        $this->CreateRawCanvas($aWidth, $aHeight);
196
        // Set canvas color (will also be the background color for a
197
        // a pallett image
198
        $this->SetColor($this->canvascolor);
199
        $this->FilledRectangle(0, 0, $this->width - 1, $this->height - 1);
200
201
        return $old;
202
    }
203
204
    public function CopyCanvasH($aToHdl, $aFromHdl, $aToX, $aToY, $aFromX, $aFromY, $aWidth, $aHeight, $aw = -1, $ah = -1)
205
    {
206
        if ($aw === -1) {
207
            $aw = $aWidth;
208
            $ah = $aHeight;
209
            $f  = 'imagecopyresized';
210
        } else {
211
            $f = 'imagecopyresampled';
212
        }
213
        $f($aToHdl, $aFromHdl, $aToX, $aToY, $aFromX, $aFromY, $aWidth, $aHeight, $aw, $ah);
214
    }
215
216
    public function Copy($fromImg, $toX, $toY, $fromX, $fromY, $toWidth, $toHeight, $fromWidth = -1, $fromHeight = -1)
217
    {
218
        $this->CopyCanvasH($this->img, $fromImg, $toX, $toY, $fromX, $fromY, $toWidth, $toHeight, $fromWidth, $fromHeight);
219
    }
220
221
    public function CopyMerge($fromImg, $toX, $toY, $fromX, $fromY, $toWidth, $toHeight, $fromWidth = -1, $fromHeight = -1, $aMix = 100)
222
    {
223
        if ($aMix == 100) {
224
            $this->CopyCanvasH(
225
                $this->img,
226
                $fromImg,
227
                $toX,
228
                $toY,
229
                $fromX,
230
                $fromY,
231
                $toWidth,
232
                $toHeight,
233
                $fromWidth,
234
                $fromHeight
235
            );
236
        } else {
237
            if (($fromWidth != -1 && ($fromWidth != $toWidth)) || ($fromHeight != -1 && ($fromHeight != $fromHeight))) {
238
                // Create a new canvas that will hold the re-scaled original from image
239
                if ($toWidth <= 1 || $toHeight <= 1) {
240
                    Util\JpGraphError::RaiseL(25083); //('Illegal image size when copying image. Size for copied to image is 1 pixel or less.');
241
                }
242
243
                $tmpimg = @imagecreatetruecolor($toWidth, $toHeight);
244
245
                if ($tmpimg < 1) {
246
                    Util\JpGraphError::RaiseL(25084); //('Failed to create temporary GD canvas. Out of memory ?');
247
                }
248
                $this->CopyCanvasH(
249
                    $tmpimg,
250
                    $fromImg,
251
                    0,
252
                    0,
253
                    0,
254
                    0,
255
                    $toWidth,
256
                    $toHeight,
257
                    $fromWidth,
258
                    $fromHeight
259
                );
260
                $fromImg = $tmpimg;
261
            }
262
            imagecopymerge($this->img, $fromImg, $toX, $toY, $fromX, $fromY, $toWidth, $toHeight, $aMix);
263
        }
264
    }
265
266
    public static function GetWidth($aImg = null)
267
    {
268
        if ($aImg === null) {
269
            $aImg = $this->img;
0 ignored issues
show
Comprehensibility Best Practice introduced by
Using $this inside a static method is generally not recommended and can lead to errors in newer PHP versions.
Loading history...
270
        }
271
272
        return imagesx($aImg);
273
    }
274
275
    public static function GetHeight($aImg = null)
276
    {
277
        if ($aImg === null) {
278
            $aImg = $this->img;
0 ignored issues
show
Comprehensibility Best Practice introduced by
Using $this inside a static method is generally not recommended and can lead to errors in newer PHP versions.
Loading history...
279
        }
280
281
        return imagesy($aImg);
282
    }
283
284
    public static function CreateFromString($aStr)
285
    {
286
        $img = imagecreatefromstring($aStr);
287
        if ($img === false) {
288
            Util\JpGraphError::RaiseL(25085);
289
            //('An image can not be created from the supplied string. It is either in a format not supported or the string is representing an corrupt image.');
290
        }
291
292
        return $img;
293
    }
294
295
    public function SetCanvasH($aHdl)
296
    {
297
        $this->img      = $aHdl;
298
        $this->rgb->img = $aHdl;
299
    }
300
301
    public function SetCanvasColor($aColor)
302
    {
303
        $this->canvascolor = $aColor;
304
    }
305
306
    public function SetAlphaBlending($aFlg = true)
307
    {
308
        imagealphablending($this->img, $aFlg);
309
    }
310
311
    public function SetAutoMargin()
312
    {
313
        $min_bm = 5;
314
        $lm     = min(40, $this->width / 7);
315
        $rm     = min(20, $this->width / 10);
316
        $tm     = max(5, $this->height / 7);
317
        $bm     = max($min_bm, $this->height / 6);
318
        $this->SetMargin($lm, $rm, $tm, $bm);
319
    }
320
321
    /**
322
     * PUBLIC METHODS.
323
     *
324
     * @param mixed $family
325
     * @param mixed $style
326
     * @param mixed $size
327
     */
328
    public function SetFont($family, $style = FS_NORMAL, $size = 10)
329
    {
330
        $this->font_family = $family;
331
        $this->font_style  = $style;
332
        $this->font_size   = $size * SUPERSAMPLING_SCALE;
333
        $this->font_file   = '';
334
        if (($this->font_family == FF_FONT1 || $this->font_family == FF_FONT2) && $this->font_style == FS_BOLD) {
335
            ++$this->font_family;
336
        }
337
        if ($this->font_family > FF_FONT2 + 1) {
338
            // A TTF font so get the font file
339
340
            // Check that this PHP has support for TTF fonts
341
            if (!function_exists('imagettfbbox')) {
342
                // use internal font when php is configured without '--with-ttf'
343
                $this->font_family = FF_FONT1;
344
            //  Util\JpGraphError::RaiseL(25087);//('This PHP build has not been configured with TTF support. You need to recompile your PHP installation with FreeType support.');
345
            } else {
346
                $this->font_file = $this->ttf->File($this->font_family, $this->font_style);
347
            }
348
        }
349
    }
350
351
    // Get the specific height for a text string
352
    public function GetTextHeight($txt = '', $angle = 0)
353
    {
354
        $tmp = preg_split('/\n/', $txt);
355
        $n   = safe_count($tmp);
356
        $m   = 0;
357
        for ($i = 0; $i < $n; ++$i) {
358
            $m = max($m, strlen($tmp[$i]));
359
        }
360
361
        if ($this->font_family <= FF_FONT2 + 1) {
362
            if ($angle == 0) {
363
                $h = imagefontheight($this->font_family);
364
                if ($h === false) {
365
                    Util\JpGraphError::RaiseL(25088); //('You have a misconfigured GD font support. The call to imagefontwidth() fails.');
366
                }
367
368
                return $n * $h;
369
            }
370
            $w = @imagefontwidth($this->font_family);
371
            if ($w === false) {
372
                Util\JpGraphError::RaiseL(25088); //('You have a misconfigured GD font support. The call to imagefontwidth() fails.');
373
            }
374
375
            return $m * $w;
376
        }
377
        $bbox = $this->GetTTFBBox($txt, $angle);
378
379
        return $bbox[1] - $bbox[5] + 1;
380
    }
381
382
    // Estimate font height
383
    public function GetFontHeight($angle = 0)
384
    {
385
        $txt = 'XOMg';
386
387
        return $this->GetTextHeight($txt, $angle);
388
    }
389
390
    // Approximate font width with width of letter "O"
391
    public function GetFontWidth($angle = 0)
392
    {
393
        $txt = 'O';
394
395
        return $this->GetTextWidth($txt, $angle);
396
    }
397
398
    // Get actual width of text in absolute pixels. Note that the width is the
399
    // texts projected with onto the x-axis. Call with angle=0 to get the true
400
    // etxt width.
401
    public function GetTextWidth($txt, $angle = 0)
402
    {
403
        $tmp = preg_split('/\n/', $txt);
404
        $n   = safe_count($tmp);
405
        if ($this->font_family <= FF_FONT2 + 1) {
406
            $m = 0;
407
            for ($i = 0; $i < $n; ++$i) {
408
                $l = strlen($tmp[$i]);
409
                if ($l > $m) {
410
                    $m = $l;
411
                }
412
            }
413
414
            if ($angle == 0) {
415
                $w = @imagefontwidth($this->font_family);
416
                if ($w === false) {
417
                    Util\JpGraphError::RaiseL(25088); //('You have a misconfigured GD font support. The call to imagefontwidth() fails.');
418
                }
419
420
                return $m * $w;
421
            }
422
            // 90 degrees internal so height becomes width
423
            $h = @imagefontheight($this->font_family);
424
            if ($h === false) {
425
                Util\JpGraphError::RaiseL(25089); //('You have a misconfigured GD font support. The call to imagefontheight() fails.');
426
            }
427
428
            return $n * $h;
429
        }
430
        // For TTF fonts we must walk through a lines and find the
431
        // widest one which we use as the width of the multi-line
432
        // paragraph
433
        $m = 0;
434
        for ($i = 0; $i < $n; ++$i) {
435
            $bbox = $this->GetTTFBBox($tmp[$i], $angle);
436
            $mm   = $bbox[2] - $bbox[0];
437
            if ($mm > $m) {
438
                $m = $mm;
439
            }
440
        }
441
442
        return $m;
443
    }
444
445
    // Draw text with a box around it
446
    public function StrokeBoxedText(
447
        $x,
448
        $y,
449
        $txt,
450
        $dir = 0,
451
        $fcolor = 'white',
452
        $bcolor = 'black',
453
        $shadowcolor = false,
454
        $paragraph_align = 'left',
455
        $xmarg = 6,
456
        $ymarg = 4,
457
        $cornerradius = 0,
458
        $dropwidth = 3
459
    ) {
460
        $oldx = $this->lastx;
461
        $oldy = $this->lasty;
462
463
        if (!is_numeric($dir)) {
464
            if ($dir == 'h') {
465
                $dir = 0;
466
            } elseif ($dir == 'v') {
467
                $dir = 90;
468
            } else {
469
                Util\JpGraphError::RaiseL(25090, $dir);
470
            }
471
            //(" Unknown direction specified in call to StrokeBoxedText() [$dir]");
472
        }
473
474
        if ($this->font_family >= FF_FONT0 && $this->font_family <= FF_FONT2 + 1) {
475
            $width  = $this->GetTextWidth($txt, $dir);
476
            $height = $this->GetTextHeight($txt, $dir);
477
        } else {
478
            $width  = $this->GetBBoxWidth($txt, $dir);
479
            $height = $this->GetBBoxHeight($txt, $dir);
480
        }
481
482
        $height += 2 * $ymarg;
483
        $width += 2 * $xmarg;
484
485
        if ($this->text_halign == 'right') {
486
            $x -= $width;
487
        } elseif ($this->text_halign == 'center') {
488
            $x -= $width / 2;
489
        }
490
491
        if ($this->text_valign == 'bottom') {
492
            $y -= $height;
493
        } elseif ($this->text_valign == 'center') {
494
            $y -= $height / 2;
495
        }
496
497
        $olda = $this->SetAngle(0);
0 ignored issues
show
introduced by
The method SetAngle() does not exist on Amenadiel\JpGraph\Image\Image. Maybe you want to declare this class abstract? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

497
        /** @scrutinizer ignore-call */ 
498
        $olda = $this->SetAngle(0);
Loading history...
498
499
        if ($shadowcolor) {
500
            $this->PushColor($shadowcolor);
501
            $this->FilledRoundedRectangle(
502
                $x - $xmarg + $dropwidth,
503
                $y - $ymarg + $dropwidth,
504
                $x + $width + $dropwidth,
505
                $y + $height - $ymarg + $dropwidth,
506
                $cornerradius
507
            );
508
            $this->PopColor();
509
            $this->PushColor($fcolor);
510
            $this->FilledRoundedRectangle(
511
                $x - $xmarg,
512
                $y - $ymarg,
513
                $x + $width,
514
                $y + $height - $ymarg,
515
                $cornerradius
516
            );
517
            $this->PopColor();
518
            $this->PushColor($bcolor);
519
            $this->RoundedRectangle(
520
                $x - $xmarg,
521
                $y - $ymarg,
522
                $x + $width,
523
                $y + $height - $ymarg,
524
                $cornerradius
525
            );
526
            $this->PopColor();
527
        } else {
528
            if ($fcolor) {
529
                $oc = $this->current_color;
530
                $this->SetColor($fcolor);
531
                $this->FilledRoundedRectangle($x - $xmarg, $y - $ymarg, $x + $width, $y + $height - $ymarg, $cornerradius);
532
                $this->current_color = $oc;
533
            }
534
            if ($bcolor) {
535
                $oc = $this->current_color;
536
                $this->SetColor($bcolor);
537
                $this->RoundedRectangle($x - $xmarg, $y - $ymarg, $x + $width, $y + $height - $ymarg, $cornerradius);
538
                $this->current_color = $oc;
539
            }
540
        }
541
542
        $h = $this->text_halign;
543
        $v = $this->text_valign;
544
        $this->SetTextAlign('left', 'top');
545
546
        $debug = false;
547
        $this->StrokeText($x, $y, $txt, $dir, $paragraph_align, $debug);
548
549
        $bb = [$x - $xmarg, $y + $height - $ymarg, $x + $width, $y + $height - $ymarg,
550
            $x + $width, $y - $ymarg, $x - $xmarg, $y - $ymarg, ];
551
        $this->SetTextAlign($h, $v);
552
553
        $this->SetAngle($olda);
554
        $this->lastx = $oldx;
555
        $this->lasty = $oldy;
556
557
        return $bb;
558
    }
559
560
    // Draw text with a box around it. This time the box will be rotated
561
    // with the text. The previous method will just make a larger enough non-rotated
562
    // box to hold the text inside.
563
    public function StrokeBoxedText2(
564
        $x,
565
        $y,
566
        $txt,
567
        $dir = 0,
568
        $fcolor = 'white',
569
        $bcolor = 'black',
570
        $shadowcolor = false,
571
        $paragraph_align = 'left',
572
        $xmarg = 6,
573
        $ymarg = 4,
574
        $cornerradius = 0,
575
        $dropwidth = 3
576
    ) {
577
        // This version of boxed text will stroke a rotated box round the text
578
        // thta will follow the angle of the text.
579
        // This has two implications:
580
        // 1) This methos will only support TTF fonts
581
        // 2) The only two alignment that makes sense are centered or baselined
582
583
        if ($this->font_family <= FF_FONT2 + 1) {
584
            Util\JpGraphError::RaiseL(25131); //StrokeBoxedText2() Only support TTF fonts and not built in bitmap fonts
585
        }
586
587
        $oldx = $this->lastx;
588
        $oldy = $this->lasty;
589
        $dir  = $this->NormAngle($dir);
590
591
        if (!is_numeric($dir)) {
592
            if ($dir == 'h') {
593
                $dir = 0;
594
            } elseif ($dir == 'v') {
595
                $dir = 90;
596
            } else {
597
                Util\JpGraphError::RaiseL(25090, $dir);
598
            }
599
            //(" Unknown direction specified in call to StrokeBoxedText() [$dir]");
600
        }
601
602
        $width       = $this->GetTextWidth($txt, 0) + 2 * $xmarg;
603
        $height      = $this->GetTextHeight($txt, 0) + 2 * $ymarg;
604
        $rect_width  = $this->GetBBoxWidth($txt, $dir);
605
        $rect_height = $this->GetBBoxHeight($txt, $dir);
606
607
        $baseline_offset = $this->bbox_cache[1] - 1;
0 ignored issues
show
Unused Code introduced by
The assignment to $baseline_offset is dead and can be removed.
Loading history...
608
609
        if ($this->text_halign == 'center') {
610
            if ($dir >= 0 && $dir <= 90) {
611
                $x -= $rect_width / 2;
612
                $x += sin($dir * M_PI / 180) * $height;
613
                $y += $rect_height / 2;
614
            } elseif ($dir >= 270 && $dir <= 360) {
615
                $x -= $rect_width / 2;
616
                $y -= $rect_height / 2;
617
                $y += cos($dir * M_PI / 180) * $height;
618
            } elseif ($dir >= 90 && $dir <= 180) {
619
                $x += $rect_width / 2;
620
                $y += $rect_height / 2;
621
                $y += cos($dir * M_PI / 180) * $height;
622
            } else {
623
                // $dir > 180 &&  $dir < 270
624
                $x += $rect_width / 2;
625
                $x += sin($dir * M_PI / 180) * $height;
626
                $y -= $rect_height / 2;
627
            }
628
        }
629
630
        // Rotate the box around this point
631
        $this->SetCenter($x, $y);
0 ignored issues
show
introduced by
The method SetCenter() does not exist on Amenadiel\JpGraph\Image\Image. Maybe you want to declare this class abstract? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

631
        $this->/** @scrutinizer ignore-call */ 
632
               SetCenter($x, $y);
Loading history...
632
        $olda = $this->SetAngle(-$dir);
633
634
        // We need to use adjusted coordinats for the box to be able
635
        // to draw the box below the baseline. This cannot be done before since
636
        // the rotating point must be the original x,y since that is arounbf the
637
        // point where the text will rotate and we cannot change this since
638
        // that is where the GD/GreeType will rotate the text
639
640
        // For smaller <14pt font we need to do some additional
641
        // adjustments to make it look good
642
        if ($this->font_size < 14) {
643
            $x -= 2;
644
            $y += 2;
645
        }
646
        //  $y += $baseline_offset;
647
648
        if ($shadowcolor) {
649
            $this->PushColor($shadowcolor);
650
            $this->FilledRectangle(
651
                $x - $xmarg + $dropwidth,
652
                $y + $ymarg + $dropwidth - $height,
653
                $x + $width + $dropwidth,
654
                $y + $ymarg + $dropwidth
655
            );
656
            //$cornerradius);
657
            $this->PopColor();
658
            $this->PushColor($fcolor);
659
            $this->FilledRectangle(
660
                $x - $xmarg,
661
                $y + $ymarg - $height,
662
                $x + $width,
663
                $y + $ymarg
664
            );
665
            //$cornerradius);
666
            $this->PopColor();
667
            $this->PushColor($bcolor);
668
            $this->Rectangle(
669
                $x - $xmarg,
670
                $y + $ymarg - $height,
671
                $x + $width,
672
                $y + $ymarg
673
            );
674
            //$cornerradius);
675
            $this->PopColor();
676
        } else {
677
            if ($fcolor) {
678
                $oc = $this->current_color;
679
                $this->SetColor($fcolor);
680
                $this->FilledRectangle($x - $xmarg, $y + $ymarg - $height, $x + $width, $y + $ymarg); //,$cornerradius);
681
                $this->current_color = $oc;
682
            }
683
            if ($bcolor) {
684
                $oc = $this->current_color;
685
                $this->SetColor($bcolor);
686
                $this->Rectangle($x - $xmarg, $y + $ymarg - $height, $x + $width, $y + $ymarg); //,$cornerradius);
687
                $this->current_color = $oc;
688
            }
689
        }
690
691
        if ($this->font_size < 14) {
692
            $x += 2;
693
            $y -= 2;
694
        }
695
696
        // Restore the original y before we stroke the text
697
        // $y -= $baseline_offset;
698
699
        $this->SetCenter(0, 0);
700
        $this->SetAngle($olda);
701
702
        $h = $this->text_halign;
703
        $v = $this->text_valign;
704
        if ($this->text_halign == 'center') {
705
            $this->SetTextAlign('center', 'basepoint');
706
        } else {
707
            $this->SetTextAlign('basepoint', 'basepoint');
708
        }
709
710
        $debug = false;
711
        $this->StrokeText($x, $y, $txt, $dir, $paragraph_align, $debug);
712
713
        $bb = [$x - $xmarg, $y + $height - $ymarg,
714
            $x + $width, $y + $height - $ymarg,
715
            $x + $width, $y - $ymarg,
716
            $x - $xmarg, $y - $ymarg, ];
717
718
        $this->SetTextAlign($h, $v);
719
        $this->SetAngle($olda);
720
721
        $this->lastx = $oldx;
722
        $this->lasty = $oldy;
723
724
        return $bb;
725
    }
726
727
    // Set text alignment
728
    public function SetTextAlign($halign, $valign = 'bottom')
729
    {
730
        $this->text_halign = $halign;
731
        $this->text_valign = $valign;
732
    }
733
734
    public function _StrokeBuiltinFont($x, $y, $txt, $dir, $paragraph_align, &$aBoundingBox, $aDebug = false)
735
    {
736
        if (is_numeric($dir) && $dir != 90 && $dir != 0) {
737
            Util\JpGraphError::RaiseL(25091);
738
        }
739
        //(" Internal font does not support drawing text at arbitrary angle. Use TTF fonts instead.");
740
741
        $h  = $this->GetTextHeight($txt);
742
        $fh = $this->GetFontHeight();
743
        $w  = $this->GetTextWidth($txt);
744
745
        if ($this->text_halign == 'right') {
746
            $x -= $dir == 0 ? $w : $h;
747
        } elseif ($this->text_halign == 'center') {
748
            // For center we subtract 1 pixel since this makes the middle
749
            // be prefectly in the middle
750
            $x -= $dir == 0 ? $w / 2 - 1 : $h / 2;
751
        }
752
        if ($this->text_valign == 'top') {
753
            $y += $dir == 0 ? $h : $w;
754
        } elseif ($this->text_valign == 'center') {
755
            $y += $dir == 0 ? $h / 2 : $w / 2;
756
        }
757
758
        $use_font = $this->font_family;
759
760
        if ($dir == 90) {
761
            imagestringup($this->img, $use_font, $x, $y, $txt, $this->current_color);
762
            $aBoundingBox = [round($x), round($y), round($x), round($y - $w), round($x + $h), round($y - $w), round($x + $h), round($y)];
763
            if ($aDebug) {
764
                // Draw bounding box
765
                $this->PushColor('green');
766
                $this->Polygon($aBoundingBox, true);
767
                $this->PopColor();
768
            }
769
        } else {
770
            if (preg_match('/\n/', $txt)) {
771
                $tmp = preg_split('/\n/', $txt);
772
                for ($i = 0; $i < safe_count($tmp); ++$i) {
773
                    $w1 = $this->GetTextWidth($tmp[$i]);
774
                    if ($paragraph_align == 'left') {
775
                        imagestring($this->img, $use_font, $x, $y - $h + 1 + $i * $fh, $tmp[$i], $this->current_color);
776
                    } elseif ($paragraph_align == 'right') {
777
                        imagestring($this->img, $use_font, $x + ($w - $w1), $y - $h + 1 + $i * $fh, $tmp[$i], $this->current_color);
778
                    } else {
779
                        imagestring($this->img, $use_font, $x + $w / 2 - $w1 / 2, $y - $h + 1 + $i * $fh, $tmp[$i], $this->current_color);
780
                    }
781
                }
782
            } else {
783
                //Put the text
784
                imagestring($this->img, $use_font, $x, $y - $h + 1, $txt, $this->current_color);
785
            }
786
            if ($aDebug) {
787
                // Draw the bounding rectangle and the bounding box
788
                $p1 = [round($x), round($y), round($x), round($y - $h), round($x + $w), round($y - $h), round($x + $w), round($y)];
789
790
                // Draw bounding box
791
                $this->PushColor('green');
792
                $this->Polygon($p1, true);
793
                $this->PopColor();
794
            }
795
            $aBoundingBox = [round($x), round($y), round($x), round($y - $h), round($x + $w), round($y - $h), round($x + $w), round($y)];
796
        }
797
    }
798
799
    public function AddTxtCR($aTxt)
800
    {
801
        // If the user has just specified a '\n'
802
        // instead of '\n\t' we have to add '\r' since
803
        // the width will be too muchy otherwise since when
804
        // we print we stroke the individually lines by hand.
805
        $e = explode("\n", $aTxt);
806
        $n = safe_count($e);
807
        for ($i = 0; $i < $n; ++$i) {
808
            $e[$i] = str_replace("\r", '', $e[$i]);
809
        }
810
811
        return implode("\n\r", $e);
812
    }
813
814
    public function NormAngle($a)
815
    {
816
        // Normalize angle in degrees
817
        // Normalize angle to be between 0-360
818
        while ($a > 360) {
819
            $a -= 360;
820
        }
821
822
        while ($a < -360) {
823
            $a += 360;
824
        }
825
826
        if ($a < 0) {
827
            $a = 360 + $a;
828
        }
829
830
        return $a;
831
    }
832
833
    public function imagettfbbox_fixed($size, $angle, $fontfile, $text)
834
    {
835
        if (!USE_LIBRARY_IMAGETTFBBOX) {
836
            $bbox = @imagettfbbox($size, $angle, $fontfile, $text);
837
            if ($bbox === false) {
838
                Util\JpGraphError::RaiseL(25092, $this->font_file);
839
                //("There is either a configuration problem with TrueType or a problem reading font file (".$this->font_file."). Make sure file exists and is in a readable place for the HTTP process. (If 'basedir' restriction is enabled in PHP then the font file must be located in the document root.). It might also be a wrongly installed FreeType library. Try uppgrading to at least FreeType 2.1.13 and recompile GD with the correct setup so it can find the new FT library.");
840
            }
841
            $this->bbox_cache = $bbox;
842
843
            return $bbox;
844
        }
845
846
        // The built in imagettfbbox is buggy for angles != 0 so
847
        // we calculate this manually by getting the bounding box at
848
        // angle = 0 and then rotate the bounding box manually
849
        $bbox = @imagettfbbox($size, 0, $fontfile, $text);
850
        if ($bbox === false && !is_readable($this->font_file)) {
851
            Util\JpGraphError::RaiseL(25092, $this->font_file);
852
            //("There is either a configuration problem with TrueType or a problem reading font file (".$this->font_file."). Make sure file exists and is in a readable place for the HTTP process. (If 'basedir' restriction is enabled in PHP then the font file must be located in the document root.). It might also be a wrongly installed FreeType library. Try uppgrading to at least FreeType 2.1.13 and recompile GD with the correct setup so it can find the new FT library.");
853
        }
854
855
        $angle = $this->NormAngle($angle);
856
857
        $a   = $angle * M_PI / 180;
858
        $ca  = cos($a);
859
        $sa  = sin($a);
860
        $ret = [];
861
862
        // We always add 1 pixel to the left since the left edge of the bounding
863
        // box is sometimes coinciding with the first pixel of the text
864
        //$bbox[0] -= 1;
865
        //$bbox[6] -= 1;
866
867
        // For roatated text we need to add extra width for rotated
868
        // text since the kerning and stroking of the TTF is not the same as for
869
        // text at a 0 degree angle
870
871
        if ($angle > 0.001 && abs($angle - 360) > 0.001) {
872
            $h = abs($bbox[7] - $bbox[1]);
873
            $w = abs($bbox[2] - $bbox[0]);
874
875
            $bbox[0] -= 2;
876
            $bbox[6] -= 2;
877
            // The width is underestimated so compensate for that
878
            $bbox[2] += round($w * 0.06);
879
            $bbox[4] += round($w * 0.06);
880
881
            // and we also need to compensate with increased height
882
            $bbox[5] -= round($h * 0.1);
883
            $bbox[7] -= round($h * 0.1);
884
885
            if ($angle > 90) {
886
                // For angles > 90 we also need to extend the height further down
887
                // by the baseline since that is also one more problem
888
                $bbox[1] += round($h * 0.15);
889
                $bbox[3] += round($h * 0.15);
890
891
                // and also make it slighty less height
892
                $bbox[7] += round($h * 0.05);
893
                $bbox[5] += round($h * 0.05);
894
895
                // And we need to move the box slightly top the rright (from a tetx perspective)
896
                $bbox[0] += round($w * 0.02);
897
                $bbox[6] += round($w * 0.02);
898
899
                if ($angle > 180) {
900
                    // And we need to move the box slightly to the left (from a text perspective)
901
                    $bbox[0] -= round($w * 0.02);
902
                    $bbox[6] -= round($w * 0.02);
903
                    $bbox[2] -= round($w * 0.02);
904
                    $bbox[4] -= round($w * 0.02);
905
                }
906
            }
907
            for ($i = 0; $i < 7; $i += 2) {
908
                $ret[$i]     = round($bbox[$i] * $ca + $bbox[$i + 1] * $sa);
909
                $ret[$i + 1] = round($bbox[$i + 1] * $ca - $bbox[$i] * $sa);
910
            }
911
            $this->bbox_cache = $ret;
912
913
            return $ret;
914
        }
915
        $this->bbox_cache = $bbox;
916
917
        return $bbox;
918
    }
919
920
    // Deprecated
921
    public function GetTTFBBox($aTxt, $aAngle = 0)
922
    {
923
        $bbox = $this->imagettfbbox_fixed($this->font_size, $aAngle, $this->font_file, $aTxt);
924
925
        return $bbox;
926
    }
927
928
    public function GetBBoxTTF($aTxt, $aAngle = 0)
929
    {
930
        // Normalize the bounding box to become a minimum
931
        // enscribing rectangle
932
933
        $aTxt = $this->AddTxtCR($aTxt);
934
935
        if (!is_readable($this->font_file)) {
936
            Util\JpGraphError::RaiseL(25093, $this->font_file);
937
            //('Can not read font file ('.$this->font_file.') in call to Image::GetBBoxTTF. Please make sure that you have set a font before calling this method and that the font is installed in the TTF directory.');
938
        }
939
        $bbox = $this->imagettfbbox_fixed($this->font_size, $aAngle, $this->font_file, $aTxt);
940
941
        if ($aAngle == 0) {
942
            return $bbox;
943
        }
944
945
        if ($aAngle >= 0) {
946
            if ($aAngle <= 90) {
947
                //<=0
948
                $bbox = [$bbox[6], $bbox[1], $bbox[2], $bbox[1],
949
                    $bbox[2], $bbox[5], $bbox[6], $bbox[5], ];
950
            } elseif ($aAngle <= 180) {
951
                //<= 2
952
                $bbox = [$bbox[4], $bbox[7], $bbox[0], $bbox[7],
953
                    $bbox[0], $bbox[3], $bbox[4], $bbox[3], ];
954
            } elseif ($aAngle <= 270) {
955
                //<= 3
956
                $bbox = [$bbox[2], $bbox[5], $bbox[6], $bbox[5],
957
                    $bbox[6], $bbox[1], $bbox[2], $bbox[1], ];
958
            } else {
959
                $bbox = [$bbox[0], $bbox[3], $bbox[4], $bbox[3],
960
                    $bbox[4], $bbox[7], $bbox[0], $bbox[7], ];
961
            }
962
        } elseif ($aAngle < 0) {
963
            if ($aAngle <= -270) {
964
                // <= -3
965
                $bbox = [$bbox[6], $bbox[1], $bbox[2], $bbox[1],
966
                    $bbox[2], $bbox[5], $bbox[6], $bbox[5], ];
967
            } elseif ($aAngle <= -180) {
968
                // <= -2
969
                $bbox = [$bbox[0], $bbox[3], $bbox[4], $bbox[3],
970
                    $bbox[4], $bbox[7], $bbox[0], $bbox[7], ];
971
            } elseif ($aAngle <= -90) {
972
                // <= -1
973
                $bbox = [$bbox[2], $bbox[5], $bbox[6], $bbox[5],
974
                    $bbox[6], $bbox[1], $bbox[2], $bbox[1], ];
975
            } else {
976
                $bbox = [$bbox[0], $bbox[3], $bbox[4], $bbox[3],
977
                    $bbox[4], $bbox[7], $bbox[0], $bbox[7], ];
978
            }
979
        }
980
981
        return $bbox;
982
    }
983
984
    public function GetBBoxHeight($aTxt, $aAngle = 0)
985
    {
986
        $box = $this->GetBBoxTTF($aTxt, $aAngle);
987
988
        return abs($box[7] - $box[1]);
989
    }
990
991
    public function GetBBoxWidth($aTxt, $aAngle = 0)
992
    {
993
        $box = $this->GetBBoxTTF($aTxt, $aAngle);
994
995
        return $box[2] - $box[0] + 1;
996
    }
997
998
    public function _StrokeTTF($x, $y, $txt, $dir, $paragraph_align, &$aBoundingBox, $debug = false)
999
    {
1000
        // Setup default inter line margin for paragraphs to be
1001
        // 3% of the font height.
1002
        $ConstLineSpacing = 0.03;
1003
1004
        // Remember the anchor point before adjustment
1005
        if ($debug) {
1006
            $ox = $x;
1007
            $oy = $y;
1008
        }
1009
1010
        if (!preg_match('/\n/', $txt) || ($dir > 0 && preg_match('/\n/', $txt))) {
1011
            // Format a single line
1012
1013
            $txt    = $this->AddTxtCR($txt);
1014
            $bbox   = $this->GetBBoxTTF($txt, $dir);
1015
            $width  = $this->GetBBoxWidth($txt, $dir);
1016
            $height = $this->GetBBoxHeight($txt, $dir);
1017
1018
            // The special alignment "basepoint" is mostly used internally
1019
            // in the library. This will put the anchor position at the left
1020
            // basepoint of the tetx. This is the default anchor point for
1021
            // TTF text.
1022
1023
            if ($this->text_valign != 'basepoint') {
1024
                // Align x,y ot lower left corner of bbox
1025
1026
                if ($this->text_halign == 'right') {
1027
                    $x -= $width;
1028
                    $x -= $bbox[0];
1029
                } elseif ($this->text_halign == 'center') {
1030
                    $x -= $width / 2;
1031
                    $x -= $bbox[0];
1032
                } elseif ($this->text_halign == 'baseline') {
1033
                    // This is only support for text at 90 degree !!
1034
                    // Do nothing the text is drawn at baseline by default
1035
                }
1036
1037
                if ($this->text_valign == 'top') {
1038
                    $y -= $bbox[1]; // Adjust to bottom of text
1039
                    $y += $height;
1040
                } elseif ($this->text_valign == 'center') {
1041
                    $y -= $bbox[1]; // Adjust to bottom of text
1042
                    $y += $height / 2;
1043
                } elseif ($this->text_valign == 'baseline') {
1044
                    // This is only support for text at 0 degree !!
1045
                    // Do nothing the text is drawn at baseline by default
1046
                }
1047
            }
1048
            imagettftext(
1049
                $this->img,
1050
                $this->font_size,
1051
                $dir,
1052
                $x,
1053
                $y,
1054
                $this->current_color,
1055
                $this->font_file,
1056
                $txt
1057
            );
1058
1059
            // Calculate and return the co-ordinates for the bounding box
1060
            $box = $this->imagettfbbox_fixed($this->font_size, $dir, $this->font_file, $txt);
1061
            $p1  = [];
1062
1063
            for ($i = 0; $i < 4; ++$i) {
1064
                $p1[] = round($box[$i * 2] + $x);
1065
                $p1[] = round($box[$i * 2 + 1] + $y);
1066
            }
1067
            $aBoundingBox = $p1;
1068
1069
            // Debugging code to highlight the bonding box and bounding rectangle
1070
            // For text at 0 degrees the bounding box and bounding rectangle are the
1071
            // same
1072
            if ($debug) {
1073
                // Draw the bounding rectangle and the bounding box
1074
1075
                $p  = [];
1076
                $p1 = [];
1077
1078
                for ($i = 0; $i < 4; ++$i) {
1079
                    $p[]  = $bbox[$i * 2] + $x;
1080
                    $p[]  = $bbox[$i * 2 + 1] + $y;
1081
                    $p1[] = $box[$i * 2] + $x;
1082
                    $p1[] = $box[$i * 2 + 1] + $y;
1083
                }
1084
1085
                // Draw bounding box
1086
                $this->PushColor('green');
1087
                $this->Polygon($p1, true);
1088
                $this->PopColor();
1089
1090
                // Draw bounding rectangle
1091
                $this->PushColor('darkgreen');
1092
                $this->Polygon($p, true);
1093
                $this->PopColor();
1094
1095
                // Draw a cross at the anchor point
1096
                $this->PushColor('red');
1097
                $this->Line($ox - 15, $oy, $ox + 15, $oy);
0 ignored issues
show
Comprehensibility Best Practice introduced by
The variable $oy does not seem to be defined for all execution paths leading up to this point.
Loading history...
Comprehensibility Best Practice introduced by
The variable $ox does not seem to be defined for all execution paths leading up to this point.
Loading history...
1098
                $this->Line($ox, $oy - 15, $ox, $oy + 15);
1099
                $this->PopColor();
1100
            }
1101
        } else {
1102
            // Format a text paragraph
1103
            $fh = $this->GetFontHeight();
1104
1105
            // Line margin is 25% of font height
1106
            $linemargin = round($fh * $ConstLineSpacing);
1107
            $fh += $linemargin;
1108
            $w = $this->GetTextWidth($txt);
1109
1110
            $y -= $linemargin / 2;
1111
            $tmp = preg_split('/\n/', $txt);
1112
            $nl  = safe_count($tmp);
1113
            $h   = $nl * $fh;
1114
1115
            if ($this->text_halign == 'right') {
1116
                $x -= $dir == 0 ? $w : $h;
1117
            } elseif ($this->text_halign == 'center') {
1118
                $x -= $dir == 0 ? $w / 2 : $h / 2;
1119
            }
1120
1121
            if ($this->text_valign == 'top') {
1122
                $y += $dir == 0 ? $h : $w;
1123
            } elseif ($this->text_valign == 'center') {
1124
                $y += $dir == 0 ? $h / 2 : $w / 2;
1125
            }
1126
1127
            // Here comes a tricky bit.
1128
            // Since we have to give the position for the string at the
1129
            // baseline this means thaht text will move slightly up
1130
            // and down depending on any of it's character descend below
1131
            // the baseline, for example a 'g'. To adjust the Y-position
1132
            // we therefore adjust the text with the baseline Y-offset
1133
            // as used for the current font and size. This will keep the
1134
            // baseline at a fixed positoned disregarding the actual
1135
            // characters in the string.
1136
            $standardbox  = $this->GetTTFBBox('Gg', $dir);
1137
            $yadj         = $standardbox[1];
1138
            $xadj         = $standardbox[0];
0 ignored issues
show
Unused Code introduced by
The assignment to $xadj is dead and can be removed.
Loading history...
1139
            $aBoundingBox = [];
1140
            for ($i = 0; $i < $nl; ++$i) {
1141
                $wl   = $this->GetTextWidth($tmp[$i]);
1142
                $bbox = $this->GetTTFBBox($tmp[$i], $dir);
1143
                if ($paragraph_align == 'left') {
1144
                    $xl = $x;
1145
                } elseif ($paragraph_align == 'right') {
1146
                    $xl = $x + ($w - $wl);
1147
                } else {
1148
                    // Center
1149
                    $xl = $x + $w / 2 - $wl / 2;
1150
                }
1151
1152
                // In theory we should adjust with full pre-lead to get the lines
1153
                // lined up but this doesn't look good so therfore we only adjust with
1154
                // half th pre-lead
1155
                $xl -= $bbox[0] / 2;
1156
                $yl = $y - $yadj;
1157
                //$xl = $xl- $xadj;
1158
                imagettftext(
1159
                    $this->img,
1160
                    $this->font_size,
1161
                    $dir,
1162
                    $xl,
1163
                    $yl - ($h - $fh) + $fh * $i,
0 ignored issues
show
Bug introduced by
$yl - $h - $fh + $fh * $i of type double is incompatible with the type integer expected by parameter $y of imagettftext(). ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

1163
                    /** @scrutinizer ignore-type */ $yl - ($h - $fh) + $fh * $i,
Loading history...
1164
                    $this->current_color,
1165
                    $this->font_file,
1166
                    $tmp[$i]
1167
                );
1168
1169
                // echo "xl=$xl,".$tmp[$i]." <br>";
1170
                if ($debug) {
1171
                    // Draw the bounding rectangle around each line
1172
                    $box = @imagettfbbox($this->font_size, $dir, $this->font_file, $tmp[$i]);
0 ignored issues
show
Unused Code introduced by
The assignment to $box is dead and can be removed.
Loading history...
1173
                    $p   = [];
1174
                    for ($j = 0; $j < 4; ++$j) {
1175
                        $p[] = $bbox[$j * 2] + $xl;
1176
                        $p[] = $bbox[$j * 2 + 1] + $yl - ($h - $fh) + $fh * $i;
1177
                    }
1178
1179
                    // Draw bounding rectangle
1180
                    $this->PushColor('darkgreen');
1181
                    $this->Polygon($p, true);
1182
                    $this->PopColor();
1183
                }
1184
            }
1185
1186
            // Get the bounding box
1187
            $bbox = $this->GetBBoxTTF($txt, $dir);
1188
            for ($j = 0; $j < 4; ++$j) {
1189
                $bbox[$j * 2] += round($x);
1190
                $bbox[$j * 2 + 1] += round($y - ($h - $fh) - $yadj);
1191
            }
1192
            $aBoundingBox = $bbox;
1193
1194
            if ($debug) {
1195
                // Draw a cross at the anchor point
1196
                $this->PushColor('red');
1197
                $this->Line($ox - 25, $oy, $ox + 25, $oy);
1198
                $this->Line($ox, $oy - 25, $ox, $oy + 25);
1199
                $this->PopColor();
1200
            }
1201
        }
1202
    }
1203
1204
    public function StrokeText($x, $y, $txt, $dir = 0, $paragraph_align = 'left', $debug = false)
1205
    {
1206
        $x = round($x);
1207
        $y = round($y);
1208
1209
        // Do special language encoding
1210
        $txt = $this->langconv->Convert($txt, $this->font_family);
1211
1212
        if (!is_numeric($dir)) {
1213
            Util\JpGraphError::RaiseL(25094); //(" Direction for text most be given as an angle between 0 and 90.");
1214
        }
1215
1216
        if ($this->font_family >= FF_FONT0 && $this->font_family <= FF_FONT2 + 1) {
1217
            $this->_StrokeBuiltinFont($x, $y, $txt, $dir, $paragraph_align, $boundingbox, $debug);
1218
        } elseif ($this->font_family >= _FIRST_FONT && $this->font_family <= _LAST_FONT) {
1219
            $this->_StrokeTTF($x, $y, $txt, $dir, $paragraph_align, $boundingbox, $debug);
1220
        } else {
1221
            Util\JpGraphError::RaiseL(25095); //(" Unknown font font family specification. ");
1222
        }
1223
1224
        return $boundingbox;
0 ignored issues
show
Comprehensibility Best Practice introduced by
The variable $boundingbox does not seem to be defined for all execution paths leading up to this point.
Loading history...
1225
    }
1226
1227
    public function SetMargin($lm, $rm, $tm, $bm)
1228
    {
1229
        $this->left_margin   = $lm;
0 ignored issues
show
Bug Best Practice introduced by
The property left_margin does not exist. Although not strictly required by PHP, it is generally a best practice to declare properties explicitly.
Loading history...
1230
        $this->right_margin  = $rm;
0 ignored issues
show
Bug Best Practice introduced by
The property right_margin does not exist. Although not strictly required by PHP, it is generally a best practice to declare properties explicitly.
Loading history...
1231
        $this->top_margin    = $tm;
0 ignored issues
show
Bug Best Practice introduced by
The property top_margin does not exist. Although not strictly required by PHP, it is generally a best practice to declare properties explicitly.
Loading history...
1232
        $this->bottom_margin = $bm;
0 ignored issues
show
Bug Best Practice introduced by
The property bottom_margin does not exist. Although not strictly required by PHP, it is generally a best practice to declare properties explicitly.
Loading history...
1233
1234
        $this->plotwidth  = $this->width - $this->left_margin - $this->right_margin;
1235
        $this->plotheight = $this->height - $this->top_margin - $this->bottom_margin;
1236
1237
        if ($this->width > 0 && $this->height > 0) {
1238
            if ($this->plotwidth < 0 || $this->plotheight < 0) {
1239
                Util\JpGraphError::RaiseL(25130, $this->plotwidth, $this->plotheight);
1240
                //Util\JpGraphError::raise("To small plot area. ($lm,$rm,$tm,$bm : $this->plotwidth x $this->plotheight). With the given image size and margins there is to little space left for the plot. Increase the plot size or reduce the margins.");
1241
            }
1242
        }
1243
    }
1244
1245
    public function SetTransparent($color)
1246
    {
1247
        imagecolortransparent($this->img, $this->rgb->allocate($color));
0 ignored issues
show
Bug introduced by
The method allocate() does not exist on null. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

1247
        imagecolortransparent($this->img, $this->rgb->/** @scrutinizer ignore-call */ allocate($color));

This check looks for calls to methods that do not seem to exist on a given type. It looks for the method on the type itself as well as in inherited classes or implemented interfaces.

This is most likely a typographical error or the method has been renamed.

Loading history...
1248
    }
1249
1250
    public function SetColor($color, $aAlpha = 0)
1251
    {
1252
        $this->current_color_name = $color;
1253
        $this->current_color      = $this->rgb->allocate($color, $aAlpha);
1254
        if ($this->current_color == -1) {
1255
            $tc = imagecolorstotal($this->img);
0 ignored issues
show
Unused Code introduced by
The assignment to $tc is dead and can be removed.
Loading history...
1256
            Util\JpGraphError::RaiseL(25096);
1257
            //("Can't allocate any more colors. Image has already allocated maximum of <b>$tc colors</b>. This might happen if you have anti-aliasing turned on together with a background image or perhaps gradient fill since this requires many, many colors. Try to turn off anti-aliasing. If there is still a problem try downgrading the quality of the background image to use a smaller pallete to leave some entries for your graphs. You should try to limit the number of colors in your background image to 64. If there is still problem set the constant DEFINE(\"USE_APPROX_COLORS\",true); in jpgraph.php This will use approximative colors when the palette is full. Unfortunately there is not much JpGraph can do about this since the palette size is a limitation of current graphic format and what the underlying GD library suppports.");
1258
        }
1259
1260
        return $this->current_color;
1261
    }
1262
1263
    public function PushColor($color)
1264
    {
1265
        if ($color != '') {
1266
            $this->colorstack[$this->colorstackidx]     = $this->current_color_name;
1267
            $this->colorstack[$this->colorstackidx + 1] = $this->current_color;
1268
            $this->colorstackidx += 2;
1269
            $this->SetColor($color);
1270
        } else {
1271
            Util\JpGraphError::RaiseL(25097); //("Color specified as empty string in PushColor().");
1272
        }
1273
    }
1274
1275
    public function PopColor()
1276
    {
1277
        if ($this->colorstackidx < 1) {
1278
            Util\JpGraphError::RaiseL(25098); //(" Negative Color stack index. Unmatched call to PopColor()");
1279
        }
1280
        $this->current_color      = $this->colorstack[--$this->colorstackidx];
1281
        $this->current_color_name = $this->colorstack[--$this->colorstackidx];
1282
    }
1283
1284
    public function SetLineWeight($weight)
1285
    {
1286
        $old = $this->line_weight;
1287
        imagesetthickness($this->img, $weight);
1288
        $this->line_weight = $weight;
0 ignored issues
show
Bug Best Practice introduced by
The property line_weight does not exist. Although not strictly required by PHP, it is generally a best practice to declare properties explicitly.
Loading history...
1289
1290
        return $old;
1291
    }
1292
1293
    public function SetStartPoint($x, $y)
1294
    {
1295
        $this->lastx = round($x);
1296
        $this->lasty = round($y);
1297
    }
1298
1299
    public function Arc($cx, $cy, $w, $h, $s, $e)
1300
    {
1301
        // GD Arc doesn't like negative angles
1302
        while ($s < 0) {
1303
            $s += 360;
1304
        }
1305
1306
        while ($e < 0) {
1307
            $e += 360;
1308
        }
1309
1310
        imagearc($this->img, round($cx), round($cy), round($w), round($h), $s, $e, $this->current_color);
0 ignored issues
show
Bug introduced by
round($cy) of type double is incompatible with the type integer expected by parameter $cy of imagearc(). ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

1310
        imagearc($this->img, round($cx), /** @scrutinizer ignore-type */ round($cy), round($w), round($h), $s, $e, $this->current_color);
Loading history...
Bug introduced by
round($cx) of type double is incompatible with the type integer expected by parameter $cx of imagearc(). ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

1310
        imagearc($this->img, /** @scrutinizer ignore-type */ round($cx), round($cy), round($w), round($h), $s, $e, $this->current_color);
Loading history...
Bug introduced by
round($h) of type double is incompatible with the type integer expected by parameter $height of imagearc(). ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

1310
        imagearc($this->img, round($cx), round($cy), round($w), /** @scrutinizer ignore-type */ round($h), $s, $e, $this->current_color);
Loading history...
Bug introduced by
round($w) of type double is incompatible with the type integer expected by parameter $width of imagearc(). ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

1310
        imagearc($this->img, round($cx), round($cy), /** @scrutinizer ignore-type */ round($w), round($h), $s, $e, $this->current_color);
Loading history...
1311
    }
1312
1313
    public function FilledArc($xc, $yc, $w, $h, $s, $e, $style = '')
1314
    {
1315
        $s = round($s);
1316
        $e = round($e);
1317
        while ($s < 0) {
1318
            $s += 360;
1319
        }
1320
1321
        while ($e < 0) {
1322
            $e += 360;
1323
        }
1324
1325
        if ($style == '') {
1326
            $style = IMG_ARC_PIE;
1327
        }
1328
1329
        if (abs($s - $e) > 0) {
1330
            imagefilledarc($this->img, round($xc), round($yc), round($w), round($h), $s, $e, $this->current_color, $style);
0 ignored issues
show
Bug introduced by
It seems like $s can also be of type double; however, parameter $start of imagefilledarc() does only seem to accept integer, maybe add an additional type check? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

1330
            imagefilledarc($this->img, round($xc), round($yc), round($w), round($h), /** @scrutinizer ignore-type */ $s, $e, $this->current_color, $style);
Loading history...
Bug introduced by
round($xc) of type double is incompatible with the type integer expected by parameter $cx of imagefilledarc(). ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

1330
            imagefilledarc($this->img, /** @scrutinizer ignore-type */ round($xc), round($yc), round($w), round($h), $s, $e, $this->current_color, $style);
Loading history...
Bug introduced by
round($yc) of type double is incompatible with the type integer expected by parameter $cy of imagefilledarc(). ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

1330
            imagefilledarc($this->img, round($xc), /** @scrutinizer ignore-type */ round($yc), round($w), round($h), $s, $e, $this->current_color, $style);
Loading history...
Bug introduced by
round($w) of type double is incompatible with the type integer expected by parameter $width of imagefilledarc(). ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

1330
            imagefilledarc($this->img, round($xc), round($yc), /** @scrutinizer ignore-type */ round($w), round($h), $s, $e, $this->current_color, $style);
Loading history...
Bug introduced by
round($h) of type double is incompatible with the type integer expected by parameter $height of imagefilledarc(). ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

1330
            imagefilledarc($this->img, round($xc), round($yc), round($w), /** @scrutinizer ignore-type */ round($h), $s, $e, $this->current_color, $style);
Loading history...
Bug introduced by
It seems like $e can also be of type double; however, parameter $end of imagefilledarc() does only seem to accept integer, maybe add an additional type check? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

1330
            imagefilledarc($this->img, round($xc), round($yc), round($w), round($h), $s, /** @scrutinizer ignore-type */ $e, $this->current_color, $style);
Loading history...
1331
            //            $this->DrawImageSmoothArc($this->img,round($xc),round($yc),round($w),round($h),$s,$e,$this->current_color,$style);
1332
        }
1333
    }
1334
1335
    public function FilledCakeSlice($cx, $cy, $w, $h, $s, $e)
1336
    {
1337
        $this->CakeSlice($cx, $cy, $w, $h, $s, $e, $this->current_color_name);
1338
    }
1339
1340
    public function CakeSlice($xc, $yc, $w, $h, $s, $e, $fillcolor = '', $arccolor = '')
1341
    {
1342
        $s  = round($s);
1343
        $e  = round($e);
1344
        $w  = round($w);
1345
        $h  = round($h);
1346
        $xc = round($xc);
1347
        $yc = round($yc);
1348
        if ($s == $e) {
1349
            // A full circle. We draw this a plain circle
1350
            $this->PushColor($fillcolor);
1351
            imagefilledellipse($this->img, $xc, $yc, 2 * $w, 2 * $h, $this->current_color);
0 ignored issues
show
Bug introduced by
$yc of type double is incompatible with the type integer expected by parameter $cy of imagefilledellipse(). ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

1351
            imagefilledellipse($this->img, $xc, /** @scrutinizer ignore-type */ $yc, 2 * $w, 2 * $h, $this->current_color);
Loading history...
Bug introduced by
2 * $h of type double is incompatible with the type integer expected by parameter $height of imagefilledellipse(). ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

1351
            imagefilledellipse($this->img, $xc, $yc, 2 * $w, /** @scrutinizer ignore-type */ 2 * $h, $this->current_color);
Loading history...
Bug introduced by
$xc of type double is incompatible with the type integer expected by parameter $cx of imagefilledellipse(). ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

1351
            imagefilledellipse($this->img, /** @scrutinizer ignore-type */ $xc, $yc, 2 * $w, 2 * $h, $this->current_color);
Loading history...
Bug introduced by
2 * $w of type double is incompatible with the type integer expected by parameter $width of imagefilledellipse(). ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

1351
            imagefilledellipse($this->img, $xc, $yc, /** @scrutinizer ignore-type */ 2 * $w, 2 * $h, $this->current_color);
Loading history...
1352
1353
            // If antialiasing is used then we often don't have any color no the surrounding
1354
            // arc. So, we need to check for this special case so we don't send an empty
1355
            // color to the push function. In this case we use the fill color for the arc as well
1356
            if ($arccolor != '') {
1357
                $this->PopColor();
1358
                $this->PushColor($arccolor);
1359
            }
1360
            imageellipse($this->img, $xc, $yc, 2 * $w, 2 * $h, $this->current_color);
0 ignored issues
show
Bug introduced by
$yc of type double is incompatible with the type integer expected by parameter $cy of imageellipse(). ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

1360
            imageellipse($this->img, $xc, /** @scrutinizer ignore-type */ $yc, 2 * $w, 2 * $h, $this->current_color);
Loading history...
Bug introduced by
2 * $w of type double is incompatible with the type integer expected by parameter $width of imageellipse(). ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

1360
            imageellipse($this->img, $xc, $yc, /** @scrutinizer ignore-type */ 2 * $w, 2 * $h, $this->current_color);
Loading history...
Bug introduced by
2 * $h of type double is incompatible with the type integer expected by parameter $height of imageellipse(). ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

1360
            imageellipse($this->img, $xc, $yc, 2 * $w, /** @scrutinizer ignore-type */ 2 * $h, $this->current_color);
Loading history...
Bug introduced by
$xc of type double is incompatible with the type integer expected by parameter $cx of imageellipse(). ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

1360
            imageellipse($this->img, /** @scrutinizer ignore-type */ $xc, $yc, 2 * $w, 2 * $h, $this->current_color);
Loading history...
1361
            $this->Line($xc, $yc, cos($s * M_PI / 180) * $w + $xc, $yc + sin($s * M_PI / 180) * $h);
1362
            $this->PopColor();
1363
        } else {
1364
            $this->PushColor($fillcolor);
1365
            $this->FilledArc($xc, $yc, 2 * $w, 2 * $h, $s, $e);
1366
            $this->PopColor();
1367
            if ($arccolor != '') {
1368
                $this->PushColor($arccolor);
1369
                // We add 2 pixels to make the Arc() better aligned with
1370
                // the filled arc.
1371
                imagefilledarc($this->img, $xc, $yc, 2 * $w, 2 * $h, $s, $e, $this->current_color, IMG_ARC_NOFILL | IMG_ARC_EDGED);
0 ignored issues
show
Bug introduced by
$yc of type double is incompatible with the type integer expected by parameter $cy of imagefilledarc(). ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

1371
                imagefilledarc($this->img, $xc, /** @scrutinizer ignore-type */ $yc, 2 * $w, 2 * $h, $s, $e, $this->current_color, IMG_ARC_NOFILL | IMG_ARC_EDGED);
Loading history...
Bug introduced by
2 * $h of type double is incompatible with the type integer expected by parameter $height of imagefilledarc(). ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

1371
                imagefilledarc($this->img, $xc, $yc, 2 * $w, /** @scrutinizer ignore-type */ 2 * $h, $s, $e, $this->current_color, IMG_ARC_NOFILL | IMG_ARC_EDGED);
Loading history...
Bug introduced by
2 * $w of type double is incompatible with the type integer expected by parameter $width of imagefilledarc(). ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

1371
                imagefilledarc($this->img, $xc, $yc, /** @scrutinizer ignore-type */ 2 * $w, 2 * $h, $s, $e, $this->current_color, IMG_ARC_NOFILL | IMG_ARC_EDGED);
Loading history...
Bug introduced by
$xc of type double is incompatible with the type integer expected by parameter $cx of imagefilledarc(). ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

1371
                imagefilledarc($this->img, /** @scrutinizer ignore-type */ $xc, $yc, 2 * $w, 2 * $h, $s, $e, $this->current_color, IMG_ARC_NOFILL | IMG_ARC_EDGED);
Loading history...
Bug introduced by
$e of type double is incompatible with the type integer expected by parameter $end of imagefilledarc(). ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

1371
                imagefilledarc($this->img, $xc, $yc, 2 * $w, 2 * $h, $s, /** @scrutinizer ignore-type */ $e, $this->current_color, IMG_ARC_NOFILL | IMG_ARC_EDGED);
Loading history...
Bug introduced by
$s of type double is incompatible with the type integer expected by parameter $start of imagefilledarc(). ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

1371
                imagefilledarc($this->img, $xc, $yc, 2 * $w, 2 * $h, /** @scrutinizer ignore-type */ $s, $e, $this->current_color, IMG_ARC_NOFILL | IMG_ARC_EDGED);
Loading history...
1372
                $this->PopColor();
1373
            }
1374
        }
1375
    }
1376
1377
    public function Ellipse($xc, $yc, $w, $h)
1378
    {
1379
        $this->Arc($xc, $yc, $w, $h, 0, 360);
1380
    }
1381
1382
    public function Circle($xc, $yc, $r)
1383
    {
1384
        imageellipse($this->img, round($xc), round($yc), $r * 2, $r * 2, $this->current_color);
0 ignored issues
show
Bug introduced by
round($yc) of type double is incompatible with the type integer expected by parameter $cy of imageellipse(). ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

1384
        imageellipse($this->img, round($xc), /** @scrutinizer ignore-type */ round($yc), $r * 2, $r * 2, $this->current_color);
Loading history...
Bug introduced by
round($xc) of type double is incompatible with the type integer expected by parameter $cx of imageellipse(). ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

1384
        imageellipse($this->img, /** @scrutinizer ignore-type */ round($xc), round($yc), $r * 2, $r * 2, $this->current_color);
Loading history...
1385
        //        $this->DrawImageSmoothArc($this->img,round($xc),round($yc),$r*2+1,$r*2+1,0,360,$this->current_color);
1386
        //        $this->imageSmoothCircle($this->img, round($xc),round($yc), $r*2+1, $this->current_color);
1387
    }
1388
1389
    public function FilledCircle($xc, $yc, $r)
1390
    {
1391
        imagefilledellipse($this->img, round($xc), round($yc), 2 * $r, 2 * $r, $this->current_color);
0 ignored issues
show
Bug introduced by
round($yc) of type double is incompatible with the type integer expected by parameter $cy of imagefilledellipse(). ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

1391
        imagefilledellipse($this->img, round($xc), /** @scrutinizer ignore-type */ round($yc), 2 * $r, 2 * $r, $this->current_color);
Loading history...
Bug introduced by
round($xc) of type double is incompatible with the type integer expected by parameter $cx of imagefilledellipse(). ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

1391
        imagefilledellipse($this->img, /** @scrutinizer ignore-type */ round($xc), round($yc), 2 * $r, 2 * $r, $this->current_color);
Loading history...
1392
        //        $this->DrawImageSmoothArc($this->img, round($xc), round($yc), 2*$r, 2*$r, 0, 360, $this->current_color);
1393
    }
1394
1395
    // Linear Color InterPolation
1396
    public function lip($f, $t, $p)
1397
    {
1398
        $p = round($p, 1);
1399
        $r = $f[0] + ($t[0] - $f[0]) * $p;
1400
        $g = $f[1] + ($t[1] - $f[1]) * $p;
1401
        $b = $f[2] + ($t[2] - $f[2]) * $p;
1402
1403
        return [$r, $g, $b];
1404
    }
1405
1406
    // Set line style dashed, dotted etc
1407
    public function SetLineStyle($s)
1408
    {
1409
        if (is_numeric($s)) {
1410
            if ($s < 1 || $s > 4) {
1411
                Util\JpGraphError::RaiseL(25101, $s); //(" Illegal numeric argument to SetLineStyle(): ($s)");
1412
            }
1413
        } elseif (is_string($s)) {
1414
            if ($s == 'solid') {
1415
                $s = 1;
1416
            } elseif ($s == 'dotted') {
1417
                $s = 2;
1418
            } elseif ($s == 'dashed') {
1419
                $s = 3;
1420
            } elseif ($s == 'longdashed') {
1421
                $s = 4;
1422
            } else {
1423
                Util\JpGraphError::RaiseL(25102, $s); //(" Illegal string argument to SetLineStyle(): $s");
1424
            }
1425
        } else {
1426
            Util\JpGraphError::RaiseL(25103, $s); //(" Illegal argument to SetLineStyle $s");
1427
        }
1428
        $old              = $this->line_style;
1429
        $this->line_style = $s;
1430
1431
        return $old;
1432
    }
1433
1434
    // Same as Line but take the line_style into account
1435
    public function StyleLine($x1, $y1, $x2, $y2, $aStyle = '', $from_grid_class = false)
1436
    {
1437
        if ($this->line_weight <= 0) {
1438
            return;
1439
        }
1440
1441
        if ($aStyle === '') {
1442
            $aStyle = $this->line_style;
1443
        }
1444
1445
        $dashed_line_method = 'DashedLine';
1446
        if ($from_grid_class) {
1447
            $dashed_line_method = 'DashedLineForGrid';
1448
        }
1449
1450
        // Add error check since dashed line will only work if anti-alias is disabled
1451
        // this is a limitation in GD
1452
1453
        if ($aStyle == 1) {
1454
            // Solid style. We can handle anti-aliasing for this
1455
            $this->Line($x1, $y1, $x2, $y2);
1456
        } else {
1457
            // Since the GD routines doesn't handle AA for styled line
1458
            // we have no option than to turn it off to get any lines at
1459
            // all if the weight > 1
1460
            $oldaa = $this->GetAntiAliasing();
1461
            if ($oldaa && $this->line_weight > 1) {
1462
                $this->SetAntiAliasing(false);
1463
            }
1464
1465
            switch ($aStyle) {
1466
                case 2: // Dotted
1467
                    $this->{$dashed_line_method}($x1, $y1, $x2, $y2, 2, 6);
1468
1469
                    break;
1470
                case 3: // Dashed
1471
                    $this->{$dashed_line_method}($x1, $y1, $x2, $y2, 5, 9);
1472
1473
                    break;
1474
                case 4: // Longdashes
1475
                    $this->{$dashed_line_method}($x1, $y1, $x2, $y2, 9, 13);
1476
1477
                    break;
1478
                default:
1479
                    Util\JpGraphError::RaiseL(25104, $this->line_style); //(" Unknown line style: $this->line_style ");
1480
                    break;
1481
            }
1482
            if ($oldaa) {
1483
                $this->SetAntiAliasing(true);
1484
            }
1485
        }
1486
    }
1487
1488
    public function DashedLine($x1, $y1, $x2, $y2, $dash_length = 1, $dash_space = 4)
1489
    {
1490
        if ($this->line_weight <= 0) {
1491
            return;
1492
        }
1493
1494
        // Add error check to make sure anti-alias is not enabled.
1495
        // Dashed line does not work with anti-alias enabled. This
1496
        // is a limitation in GD.
1497
        if ($this->use_anti_aliasing) {
1498
            //            Util\JpGraphError::RaiseL(25129); // Anti-alias can not be used with dashed lines. Please disable anti-alias or use solid lines.
1499
        }
1500
1501
        $x1 = round($x1);
1502
        $x2 = round($x2);
1503
        $y1 = round($y1);
1504
        $y2 = round($y2);
1505
1506
        $dash_length *= SUPERSAMPLING_SCALE;
1507
        $dash_space *= SUPERSAMPLING_SCALE;
1508
1509
        $style = array_fill(0, $dash_length, $this->current_color);
1510
        $style = array_pad($style, $dash_space, IMG_COLOR_TRANSPARENT);
1511
        imagesetstyle($this->img, $style);
1512
        imageline($this->img, $x1, $y1, $x2, $y2, IMG_COLOR_STYLED);
0 ignored issues
show
Bug introduced by
$y1 of type double is incompatible with the type integer expected by parameter $y1 of imageline(). ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

1512
        imageline($this->img, $x1, /** @scrutinizer ignore-type */ $y1, $x2, $y2, IMG_COLOR_STYLED);
Loading history...
Bug introduced by
$x2 of type double is incompatible with the type integer expected by parameter $x2 of imageline(). ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

1512
        imageline($this->img, $x1, $y1, /** @scrutinizer ignore-type */ $x2, $y2, IMG_COLOR_STYLED);
Loading history...
Bug introduced by
$x1 of type double is incompatible with the type integer expected by parameter $x1 of imageline(). ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

1512
        imageline($this->img, /** @scrutinizer ignore-type */ $x1, $y1, $x2, $y2, IMG_COLOR_STYLED);
Loading history...
Bug introduced by
$y2 of type double is incompatible with the type integer expected by parameter $y2 of imageline(). ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

1512
        imageline($this->img, $x1, $y1, $x2, /** @scrutinizer ignore-type */ $y2, IMG_COLOR_STYLED);
Loading history...
1513
1514
        $this->lastx = $x2;
1515
        $this->lasty = $y2;
1516
    }
1517
1518
    public function DashedLineForGrid($x1, $y1, $x2, $y2, $dash_length = 1, $dash_space = 4)
1519
    {
1520
        if ($this->line_weight <= 0) {
1521
            return;
1522
        }
1523
1524
        // Add error check to make sure anti-alias is not enabled.
1525
        // Dashed line does not work with anti-alias enabled. This
1526
        // is a limitation in GD.
1527
        if ($this->use_anti_aliasing) {
1528
            //            Util\JpGraphError::RaiseL(25129); // Anti-alias can not be used with dashed lines. Please disable anti-alias or use solid lines.
1529
        }
1530
1531
        $x1 = round($x1);
1532
        $x2 = round($x2);
1533
        $y1 = round($y1);
1534
        $y2 = round($y2);
1535
1536
        /*
1537
        $dash_length *= $this->scale;
1538
        $dash_space  *= $this->scale;
1539
         */
1540
1541
        $dash_length = 2;
0 ignored issues
show
Unused Code introduced by
The assignment to $dash_length is dead and can be removed.
Loading history...
1542
        $dash_length = 4;
1543
        imagesetthickness($this->img, 1);
1544
        $style = array_fill(0, $dash_length, $this->current_color); //hexdec('CCCCCC'));
1545
        $style = array_pad($style, $dash_space, IMG_COLOR_TRANSPARENT);
1546
        imagesetstyle($this->img, $style);
1547
        imageline($this->img, $x1, $y1, $x2, $y2, IMG_COLOR_STYLED);
0 ignored issues
show
Bug introduced by
$x2 of type double is incompatible with the type integer expected by parameter $x2 of imageline(). ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

1547
        imageline($this->img, $x1, $y1, /** @scrutinizer ignore-type */ $x2, $y2, IMG_COLOR_STYLED);
Loading history...
Bug introduced by
$x1 of type double is incompatible with the type integer expected by parameter $x1 of imageline(). ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

1547
        imageline($this->img, /** @scrutinizer ignore-type */ $x1, $y1, $x2, $y2, IMG_COLOR_STYLED);
Loading history...
Bug introduced by
$y2 of type double is incompatible with the type integer expected by parameter $y2 of imageline(). ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

1547
        imageline($this->img, $x1, $y1, $x2, /** @scrutinizer ignore-type */ $y2, IMG_COLOR_STYLED);
Loading history...
Bug introduced by
$y1 of type double is incompatible with the type integer expected by parameter $y1 of imageline(). ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

1547
        imageline($this->img, $x1, /** @scrutinizer ignore-type */ $y1, $x2, $y2, IMG_COLOR_STYLED);
Loading history...
1548
1549
        $this->lastx = $x2;
1550
        $this->lasty = $y2;
1551
    }
1552
1553
    public function Line($x1, $y1, $x2, $y2)
1554
    {
1555
        if ($this->line_weight <= 0) {
1556
            return;
1557
        }
1558
1559
        $x1 = round($x1);
1560
        $x2 = round($x2);
1561
        $y1 = round($y1);
1562
        $y2 = round($y2);
1563
1564
        imageline($this->img, $x1, $y1, $x2, $y2, $this->current_color);
0 ignored issues
show
Bug introduced by
$x2 of type double is incompatible with the type integer expected by parameter $x2 of imageline(). ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

1564
        imageline($this->img, $x1, $y1, /** @scrutinizer ignore-type */ $x2, $y2, $this->current_color);
Loading history...
Bug introduced by
$y2 of type double is incompatible with the type integer expected by parameter $y2 of imageline(). ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

1564
        imageline($this->img, $x1, $y1, $x2, /** @scrutinizer ignore-type */ $y2, $this->current_color);
Loading history...
Bug introduced by
$x1 of type double is incompatible with the type integer expected by parameter $x1 of imageline(). ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

1564
        imageline($this->img, /** @scrutinizer ignore-type */ $x1, $y1, $x2, $y2, $this->current_color);
Loading history...
Bug introduced by
$y1 of type double is incompatible with the type integer expected by parameter $y1 of imageline(). ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

1564
        imageline($this->img, $x1, /** @scrutinizer ignore-type */ $y1, $x2, $y2, $this->current_color);
Loading history...
1565
        //        $this->DrawLine($this->img, $x1, $y1, $x2, $y2, $this->line_weight, $this->current_color);
1566
        $this->lastx = $x2;
1567
        $this->lasty = $y2;
1568
    }
1569
1570
    public function Polygon($p, $closed = false, $fast = false)
1571
    {
1572
        if ($this->line_weight <= 0) {
1573
            return;
1574
        }
1575
1576
        $n    = safe_count($p);
1577
        $oldx = $p[0];
1578
        $oldy = $p[1];
1579
        if ($fast) {
1580
            for ($i = 2; $i < $n; $i += 2) {
1581
                imageline($this->img, $oldx, $oldy, $p[$i], $p[$i + 1], $this->current_color);
1582
                $oldx = $p[$i];
1583
                $oldy = $p[$i + 1];
1584
            }
1585
            if ($closed) {
1586
                imageline($this->img, $p[$n * 2 - 2], $p[$n * 2 - 1], $p[0], $p[1], $this->current_color);
1587
            }
1588
        } else {
1589
            for ($i = 2; $i < $n; $i += 2) {
1590
                $this->StyleLine($oldx, $oldy, $p[$i], $p[$i + 1]);
1591
                $oldx = $p[$i];
1592
                $oldy = $p[$i + 1];
1593
            }
1594
            if ($closed) {
1595
                $this->StyleLine($oldx, $oldy, $p[0], $p[1]);
1596
            }
1597
        }
1598
    }
1599
1600
    public function FilledPolygon($pts)
1601
    {
1602
        $n = safe_count($pts);
1603
        if ($n == 0) {
1604
            Util\JpGraphError::RaiseL(25105); //('NULL data specified for a filled polygon. Check that your data is not NULL.');
1605
        }
1606
        for ($i = 0; $i < $n; ++$i) {
1607
            $pts[$i] = round($pts[$i]);
1608
        }
1609
        $old = $this->line_weight;
1610
        imagesetthickness($this->img, 1);
1611
        imagefilledpolygon($this->img, $pts, safe_count($pts) / 2, $this->current_color);
1612
        $this->line_weight = $old;
0 ignored issues
show
Bug Best Practice introduced by
The property line_weight does not exist. Although not strictly required by PHP, it is generally a best practice to declare properties explicitly.
Loading history...
1613
        imagesetthickness($this->img, $old);
1614
    }
1615
1616
    public function Rectangle($xl, $yu, $xr, $yl)
1617
    {
1618
        $this->Polygon([$xl, $yu, $xr, $yu, $xr, $yl, $xl, $yl, $xl, $yu]);
1619
    }
1620
1621
    public function FilledRectangle($xl, $yu, $xr, $yl)
1622
    {
1623
        $this->FilledPolygon([$xl, $yu, $xr, $yu, $xr, $yl, $xl, $yl]);
1624
    }
1625
1626
    public function FilledRectangle2($xl, $yu, $xr, $yl, $color1, $color2, $style = 1)
1627
    {
1628
        // Fill a rectangle with lines of two colors
1629
        if ($style === 1) {
1630
            // Horizontal stripe
1631
            if ($yl < $yu) {
1632
                $t  = $yl;
1633
                $yl = $yu;
1634
                $yu = $t;
1635
            }
1636
            for ($y = $yu; $y <= $yl; ++$y) {
1637
                $this->SetColor($color1);
1638
                $this->Line($xl, $y, $xr, $y);
1639
                ++$y;
1640
                $this->SetColor($color2);
1641
                $this->Line($xl, $y, $xr, $y);
1642
            }
1643
        } else {
1644
            if ($xl < $xl) {
1645
                $t  = $xl;
1646
                $xl = $xr;
1647
                $xr = $t;
1648
            }
1649
            for ($x = $xl; $x <= $xr; ++$x) {
1650
                $this->SetColor($color1);
1651
                $this->Line($x, $yu, $x, $yl);
1652
                ++$x;
1653
                $this->SetColor($color2);
1654
                $this->Line($x, $yu, $x, $yl);
1655
            }
1656
        }
1657
    }
1658
1659
    public function ShadowRectangle($xl, $yu, $xr, $yl, $fcolor = false, $shadow_width = 4, $shadow_color = 'darkgray', $useAlpha = true)
1660
    {
1661
        // This is complicated by the fact that we must also handle the case where
1662
        // the reactangle has no fill color
1663
        $xl = floor($xl);
1664
        $yu = floor($yu);
1665
        $xr = floor($xr);
1666
        $yl = floor($yl);
1667
        $this->PushColor($shadow_color);
1668
        $shadowAlpha = 0;
1669
        $this->SetLineWeight(1);
1670
        $this->SetLineStyle('solid');
1671
        $basecolor    = $this->rgb->Color($shadow_color);
1672
        $shadow_color = [$basecolor[0], $basecolor[1], $basecolor[2]];
1673
        for ($i = 0; $i < $shadow_width; ++$i) {
1674
            $this->SetColor($shadow_color, $shadowAlpha);
1675
            $this->Line(
1676
                $xr - $shadow_width + $i,
1677
                $yu + $shadow_width,
1678
                $xr - $shadow_width + $i,
1679
                $yl - $shadow_width - 1 + $i
1680
            );
1681
            $this->Line(
1682
                $xl + $shadow_width,
1683
                $yl - $shadow_width + $i,
1684
                $xr - $shadow_width + $i,
1685
                $yl - $shadow_width + $i
1686
            );
1687
            if ($useAlpha) {
1688
                $shadowAlpha += 1.0 / $shadow_width;
1689
            }
1690
        }
1691
1692
        $this->PopColor();
1693
        if ($fcolor == false) {
1694
            $this->Rectangle($xl, $yu, $xr - $shadow_width - 1, $yl - $shadow_width - 1);
1695
        } else {
1696
            $this->PushColor($fcolor);
1697
            $this->FilledRectangle($xl, $yu, $xr - $shadow_width - 1, $yl - $shadow_width - 1);
1698
            $this->PopColor();
1699
            $this->Rectangle($xl, $yu, $xr - $shadow_width - 1, $yl - $shadow_width - 1);
1700
        }
1701
    }
1702
1703
    public function FilledRoundedRectangle($xt, $yt, $xr, $yl, $r = 5)
1704
    {
1705
        if ($r == 0) {
1706
            $this->FilledRectangle($xt, $yt, $xr, $yl);
1707
1708
            return;
1709
        }
1710
1711
        // To avoid overlapping fillings (which will look strange
1712
        // when alphablending is enabled) we have no choice but
1713
        // to fill the five distinct areas one by one.
1714
1715
        // Center square
1716
        $this->FilledRectangle($xt + $r, $yt + $r, $xr - $r, $yl - $r);
1717
        // Top band
1718
        $this->FilledRectangle($xt + $r, $yt, $xr - $r, $yt + $r);
1719
        // Bottom band
1720
        $this->FilledRectangle($xt + $r, $yl - $r, $xr - $r, $yl);
1721
        // Left band
1722
        $this->FilledRectangle($xt, $yt + $r, $xt + $r, $yl - $r);
1723
        // Right band
1724
        $this->FilledRectangle($xr - $r, $yt + $r, $xr, $yl - $r);
1725
1726
        // Topleft & Topright arc
1727
        $this->FilledArc($xt + $r, $yt + $r, $r * 2, $r * 2, 180, 270);
1728
        $this->FilledArc($xr - $r, $yt + $r, $r * 2, $r * 2, 270, 360);
1729
1730
        // Bottomleft & Bottom right arc
1731
        $this->FilledArc($xt + $r, $yl - $r, $r * 2, $r * 2, 90, 180);
1732
        $this->FilledArc($xr - $r, $yl - $r, $r * 2, $r * 2, 0, 90);
1733
    }
1734
1735
    public function RoundedRectangle($xt, $yt, $xr, $yl, $r = 5)
1736
    {
1737
        if ($r == 0) {
1738
            $this->Rectangle($xt, $yt, $xr, $yl);
1739
1740
            return;
1741
        }
1742
1743
        // Top & Bottom line
1744
        $this->Line($xt + $r, $yt, $xr - $r, $yt);
1745
        $this->Line($xt + $r, $yl, $xr - $r, $yl);
1746
1747
        // Left & Right line
1748
        $this->Line($xt, $yt + $r, $xt, $yl - $r);
1749
        $this->Line($xr, $yt + $r, $xr, $yl - $r);
1750
1751
        // Topleft & Topright arc
1752
        $this->Arc($xt + $r, $yt + $r, $r * 2, $r * 2, 180, 270);
1753
        $this->Arc($xr - $r, $yt + $r, $r * 2, $r * 2, 270, 360);
1754
1755
        // Bottomleft & Bottomright arc
1756
        $this->Arc($xt + $r, $yl - $r, $r * 2, $r * 2, 90, 180);
1757
        $this->Arc($xr - $r, $yl - $r, $r * 2, $r * 2, 0, 90);
1758
    }
1759
1760
    public function FilledBevel($x1, $y1, $x2, $y2, $depth = 2, $color1 = '[email protected]', $color2 = '[email protected]')
1761
    {
1762
        $this->FilledRectangle($x1, $y1, $x2, $y2);
1763
        $this->Bevel($x1, $y1, $x2, $y2, $depth, $color1, $color2);
1764
    }
1765
1766
    public function Bevel($x1, $y1, $x2, $y2, $depth = 2, $color1 = '[email protected]', $color2 = '[email protected]')
1767
    {
1768
        $this->PushColor($color1);
1769
        for ($i = 0; $i < $depth; ++$i) {
1770
            $this->Line($x1 + $i, $y1 + $i, $x1 + $i, $y2 - $i);
1771
            $this->Line($x1 + $i, $y1 + $i, $x2 - $i, $y1 + $i);
1772
        }
1773
        $this->PopColor();
1774
1775
        $this->PushColor($color2);
1776
        for ($i = 0; $i < $depth; ++$i) {
1777
            $this->Line($x1 + $i, $y2 - $i, $x2 - $i, $y2 - $i);
1778
            $this->Line($x2 - $i, $y1 + $i, $x2 - $i, $y2 - $i - 1);
1779
        }
1780
        $this->PopColor();
1781
    }
1782
1783
    public function StyleLineTo($x, $y)
1784
    {
1785
        $this->StyleLine($this->lastx, $this->lasty, $x, $y);
1786
        $this->lastx = $x;
1787
        $this->lasty = $y;
1788
    }
1789
1790
    public function LineTo($x, $y)
1791
    {
1792
        $this->Line($this->lastx, $this->lasty, $x, $y);
1793
        $this->lastx = $x;
1794
        $this->lasty = $y;
1795
    }
1796
1797
    public function Point($x, $y)
1798
    {
1799
        imagesetpixel($this->img, round($x), round($y), $this->current_color);
0 ignored issues
show
Bug introduced by
round($x) of type double is incompatible with the type integer expected by parameter $x of imagesetpixel(). ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

1799
        imagesetpixel($this->img, /** @scrutinizer ignore-type */ round($x), round($y), $this->current_color);
Loading history...
Bug introduced by
round($y) of type double is incompatible with the type integer expected by parameter $y of imagesetpixel(). ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

1799
        imagesetpixel($this->img, round($x), /** @scrutinizer ignore-type */ round($y), $this->current_color);
Loading history...
1800
    }
1801
1802
    public function Fill($x, $y)
1803
    {
1804
        imagefill($this->img, round($x), round($y), $this->current_color);
0 ignored issues
show
Bug introduced by
round($x) of type double is incompatible with the type integer expected by parameter $x of imagefill(). ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

1804
        imagefill($this->img, /** @scrutinizer ignore-type */ round($x), round($y), $this->current_color);
Loading history...
Bug introduced by
round($y) of type double is incompatible with the type integer expected by parameter $y of imagefill(). ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

1804
        imagefill($this->img, round($x), /** @scrutinizer ignore-type */ round($y), $this->current_color);
Loading history...
1805
    }
1806
1807
    public function FillToBorder($x, $y, $aBordColor)
1808
    {
1809
        $bc = $this->rgb->allocate($aBordColor);
1810
        if ($bc == -1) {
1811
            Util\JpGraphError::RaiseL(25106); //('Image::FillToBorder : Can not allocate more colors');
1812
        }
1813
        imagefilltoborder($this->img, round($x), round($y), $bc, $this->current_color);
0 ignored issues
show
Bug introduced by
round($y) of type double is incompatible with the type integer expected by parameter $y of imagefilltoborder(). ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

1813
        imagefilltoborder($this->img, round($x), /** @scrutinizer ignore-type */ round($y), $bc, $this->current_color);
Loading history...
Bug introduced by
round($x) of type double is incompatible with the type integer expected by parameter $x of imagefilltoborder(). ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

1813
        imagefilltoborder($this->img, /** @scrutinizer ignore-type */ round($x), round($y), $bc, $this->current_color);
Loading history...
1814
    }
1815
1816
    public function SetExpired($aFlg = true)
1817
    {
1818
        $this->expired = $aFlg;
1819
    }
1820
1821
    // Generate image header
1822
    public function Headers()
1823
    {
1824
        // In case we are running from the command line with the client version of
1825
        // PHP we can't send any headers.
1826
        $sapi = php_sapi_name();
1827
        if ($sapi == 'cli') {
1828
            return;
1829
        }
1830
1831
        // These parameters are set by headers_sent() but they might cause
1832
        // an undefined variable error unless they are initilized
1833
        $file   = '';
1834
        $lineno = '';
1835
        if (headers_sent($file, $lineno)) {
0 ignored issues
show
Bug introduced by
$lineno of type string is incompatible with the type integer expected by parameter $line of headers_sent(). ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

1835
        if (headers_sent($file, /** @scrutinizer ignore-type */ $lineno)) {
Loading history...
1836
            $file = basename($file);
1837
            $t    = new ErrMsgText();
1838
            $msg  = $t->Get(10, $file, $lineno);
1839
            die($msg);
0 ignored issues
show
Best Practice introduced by
Using exit here is not recommended.

In general, usage of exit should be done with care and only when running in a scripting context like a CLI script.

Loading history...
1840
        }
1841
1842
        if ($this->expired) {
1843
            header('Expires: Mon, 26 Jul 1997 05:00:00 GMT');
1844
            header('Last-Modified: ' . gmdate('D, d M Y H:i:s') . 'GMT');
1845
            header('Cache-Control: no-cache, must-revalidate');
1846
            header('Pragma: no-cache');
1847
        }
1848
        header("Content-type: image/{$this->img_format}");
1849
    }
1850
1851
    // Adjust image quality for formats that allow this
1852
    public function SetQuality($q)
1853
    {
1854
        $this->quality = $q;
1855
    }
1856
1857
    // Stream image to browser or to file
1858
    public function Stream($aFile = '')
1859
    {
1860
        $this->DoSupersampling();
1861
1862
        $func = 'image' . $this->img_format;
1863
        if ($this->img_format == 'jpeg' && $this->quality != null) {
1864
            $res = @$func($this->img, $aFile, $this->quality);
0 ignored issues
show
Unused Code introduced by
The assignment to $res is dead and can be removed.
Loading history...
1865
        } else {
1866
            if ($aFile != '') {
1867
                $res = @$func($this->img, $aFile);
1868
                if (!$res) {
1869
                    Util\JpGraphError::RaiseL(25107, $aFile); //("Can't write to file '$aFile'. Check that the process running PHP has enough permission.");
1870
                }
1871
            } else {
1872
                $res = @$func($this->img);
1873
                if (!$res) {
1874
                    Util\JpGraphError::RaiseL(25108); //("Can't stream image. This is most likely due to a faulty PHP/GD setup. Try to recompile PHP and use the built-in GD library that comes with PHP.");
1875
                }
1876
            }
1877
        }
1878
    }
1879
1880
    // Do SuperSampling using $scale
1881
    public function DoSupersampling()
1882
    {
1883
        if (SUPERSAMPLING_SCALE <= 1) {
1884
            return $this->img;
1885
        }
1886
1887
        $dst_img = @imagecreatetruecolor($this->original_width, $this->original_height);
1888
        imagecopyresampled($dst_img, $this->img, 0, 0, 0, 0, $this->original_width, $this->original_height, $this->width, $this->height);
0 ignored issues
show
Bug introduced by
It seems like $dst_img can also be of type false; however, parameter $dst_image of imagecopyresampled() does only seem to accept GdImage|resource, maybe add an additional type check? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

1888
        imagecopyresampled(/** @scrutinizer ignore-type */ $dst_img, $this->img, 0, 0, 0, 0, $this->original_width, $this->original_height, $this->width, $this->height);
Loading history...
Bug introduced by
$this->height of type double is incompatible with the type integer expected by parameter $src_h of imagecopyresampled(). ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

1888
        imagecopyresampled($dst_img, $this->img, 0, 0, 0, 0, $this->original_width, $this->original_height, $this->width, /** @scrutinizer ignore-type */ $this->height);
Loading history...
Bug introduced by
$this->width of type double is incompatible with the type integer expected by parameter $src_w of imagecopyresampled(). ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

1888
        imagecopyresampled($dst_img, $this->img, 0, 0, 0, 0, $this->original_width, $this->original_height, /** @scrutinizer ignore-type */ $this->width, $this->height);
Loading history...
1889
        $this->Destroy();
1890
1891
        return $this->img = $dst_img;
1892
    }
1893
1894
    // Clear resources used by image (this is normally not used since all resources are/should be
1895
    // returned when the script terminates
1896
    public function Destroy()
1897
    {
1898
        imagedestroy($this->img);
1899
    }
1900
1901
    // Specify image format. Note depending on your installation
1902
    // of PHP not all formats may be supported.
1903
    public function SetImgFormat($aFormat, $aQuality = 75)
1904
    {
1905
        $this->quality = $aQuality;
1906
        $aFormat       = strtolower($aFormat);
1907
        $tst           = true;
1908
        $supported     = imagetypes();
1909
        if ($aFormat == 'auto') {
1910
            if ($supported & IMG_PNG) {
1911
                $this->img_format = 'png';
1912
            } elseif ($supported & IMG_JPG) {
1913
                $this->img_format = 'jpeg';
1914
            } elseif ($supported & IMG_GIF) {
1915
                $this->img_format = 'gif';
1916
            } elseif ($supported & IMG_WBMP) {
1917
                $this->img_format = 'wbmp';
1918
            } elseif ($supported & IMG_XPM) {
1919
                $this->img_format = 'xpm';
1920
            } else {
1921
                Util\JpGraphError::RaiseL(25109); //("Your PHP (and GD-lib) installation does not appear to support any known graphic formats. You need to first make sure GD is compiled as a module to PHP. If you also want to use JPEG images you must get the JPEG library. Please see the PHP docs for details.");
1922
            }
1923
1924
            return true;
1925
        }
1926
        if ($aFormat == 'jpeg' || $aFormat == 'png' || $aFormat == 'gif') {
1927
            if ($aFormat == 'jpeg' && !($supported & IMG_JPG)) {
1928
                $tst = false;
1929
            } elseif ($aFormat == 'png' && !($supported & IMG_PNG)) {
1930
                $tst = false;
1931
            } elseif ($aFormat == 'gif' && !($supported & IMG_GIF)) {
1932
                $tst = false;
1933
            } elseif ($aFormat == 'wbmp' && !($supported & IMG_WBMP)) {
1934
                $tst = false;
1935
            } elseif ($aFormat == 'xpm' && !($supported & IMG_XPM)) {
1936
                $tst = false;
1937
            } else {
1938
                $this->img_format = $aFormat;
1939
1940
                return true;
1941
            }
1942
        } else {
1943
            $tst = false;
1944
        }
1945
        if (!$tst) {
0 ignored issues
show
introduced by
The condition $tst is always false.
Loading history...
1946
            Util\JpGraphError::RaiseL(25110, $aFormat); //(" Your PHP installation does not support the chosen graphic format: $aFormat");
1947
        }
1948
    }
1949
1950
    /**
1951
     * Draw Line.
1952
     *
1953
     * @param mixed $im
1954
     * @param mixed $x1
1955
     * @param mixed $y1
1956
     * @param mixed $x2
1957
     * @param mixed $y2
1958
     * @param mixed $weight
1959
     * @param mixed $color
1960
     */
1961
    public function DrawLine($im, $x1, $y1, $x2, $y2, $weight, $color)
1962
    {
1963
        if ($weight == 1) {
1964
            return imageline($im, $x1, $y1, $x2, $y2, $color);
1965
        }
1966
1967
        $angle = (atan2(($y1 - $y2), ($x2 - $x1)));
1968
1969
        $dist_x = $weight * (sin($angle)) / 2;
1970
        $dist_y = $weight * (cos($angle)) / 2;
1971
1972
        $p1x = ceil(($x1 + $dist_x));
1973
        $p1y = ceil(($y1 + $dist_y));
1974
        $p2x = ceil(($x2 + $dist_x));
1975
        $p2y = ceil(($y2 + $dist_y));
1976
        $p3x = ceil(($x2 - $dist_x));
1977
        $p3y = ceil(($y2 - $dist_y));
1978
        $p4x = ceil(($x1 - $dist_x));
1979
        $p4y = ceil(($y1 - $dist_y));
1980
1981
        $array = [$p1x, $p1y, $p2x, $p2y, $p3x, $p3y, $p4x, $p4y];
1982
        imagefilledpolygon($im, $array, (safe_count($array) / 2), $color);
1983
1984
        // for antialias
1985
        imageline($im, $p1x, $p1y, $p2x, $p2y, $color);
0 ignored issues
show
Bug introduced by
$p1x of type double is incompatible with the type integer expected by parameter $x1 of imageline(). ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

1985
        imageline($im, /** @scrutinizer ignore-type */ $p1x, $p1y, $p2x, $p2y, $color);
Loading history...
Bug introduced by
$p1y of type double is incompatible with the type integer expected by parameter $y1 of imageline(). ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

1985
        imageline($im, $p1x, /** @scrutinizer ignore-type */ $p1y, $p2x, $p2y, $color);
Loading history...
Bug introduced by
$p2y of type double is incompatible with the type integer expected by parameter $y2 of imageline(). ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

1985
        imageline($im, $p1x, $p1y, $p2x, /** @scrutinizer ignore-type */ $p2y, $color);
Loading history...
Bug introduced by
$p2x of type double is incompatible with the type integer expected by parameter $x2 of imageline(). ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

1985
        imageline($im, $p1x, $p1y, /** @scrutinizer ignore-type */ $p2x, $p2y, $color);
Loading history...
1986
        imageline($im, $p3x, $p3y, $p4x, $p4y, $color);
1987
1988
        return;
1989
1990
        return imageline($this->img, $x1, $y1, $x2, $y2, $this->current_color);
0 ignored issues
show
Unused Code introduced by
return imageline($this->..., $this->current_color) is not reachable.

This check looks for unreachable code. It uses sophisticated control flow analysis techniques to find statements which will never be executed.

Unreachable code is most often the result of return, die or exit statements that have been added for debug purposes.

function fx() {
    try {
        doSomething();
        return true;
    }
    catch (\Exception $e) {
        return false;
    }

    return false;
}

In the above example, the last return false will never be executed, because a return statement has already been met in every possible execution path.

Loading history...
1991
        $weight = 8;
1992
        if ($weight <= 1) {
1993
            return imageline($this->img, $x1, $y1, $x2, $y2, $this->current_color);
1994
        }
1995
1996
        $pts = [];
1997
1998
        $weight /= 2;
1999
2000
        if ($y2 - $y1 == 0) {
2001
            // x line
2002
            $pts   = [];
2003
            $pts[] = $x1;
2004
            $pts[] = $y1 - $weight;
2005
            $pts[] = $x1;
2006
            $pts[] = $y1 + $weight;
2007
            $pts[] = $x2;
2008
            $pts[] = $y2 + $weight;
2009
            $pts[] = $x2;
2010
            $pts[] = $y2 - $weight;
2011
        } elseif ($x2 - $x1 == 0) {
2012
            // y line
2013
            $pts   = [];
2014
            $pts[] = $x1 - $weight;
2015
            $pts[] = $y1;
2016
            $pts[] = $x1 + $weight;
2017
            $pts[] = $y1;
2018
            $pts[] = $x2 + $weight;
2019
            $pts[] = $y2;
2020
            $pts[] = $x2 - $weight;
2021
            $pts[] = $y2;
2022
        } else {
2023
            $length = sqrt(pow($x2 - $x1, 2) + pow($y2 - $y1, 2));
2024
            exit;
0 ignored issues
show
Best Practice introduced by
Using exit here is not recommended.

In general, usage of exit should be done with care and only when running in a scripting context like a CLI script.

Loading history...
2025
2026
            /*
2027
        $lean = ($y2 - $y1) / ($x2 - $x1);
2028
        $lean2 = -1 / $lean;
2029
        $sin = $lean / ($y2 - $y1);
2030
        $cos = $lean / ($x2 - $x1);
2031
2032
        $pts[] = $x1 + (-$weight * $sin); $pts[] = $y1 + (-$weight * $cos);
2033
        $pts[] = $x1 + (+$weight * $sin); $pts[] = $y1 + (+$weight * $cos);
2034
        $pts[] = $x2 + (+$weight * $sin); $pts[] = $y2 + (+$weight * $cos);
2035
        $pts[] = $x2 + (-$weight * $sin); $pts[] = $y2 + (-$weight * $cos);
2036
         */
2037
        }
2038
2039
        //print_r($pts);exit;
2040
        if (safe_count($pts) / 2 < 3) {
2041
            return;
2042
        }
2043
2044
        imagesetthickness($im, 1);
2045
        imagefilledpolygon($im, $pts, safe_count($pts) / 2, $color);
2046
2047
        $weight *= 2;
2048
2049
        //        $this->DrawImageSmoothArc($im, $x1, $y1, $weight, $weight, 0, 360, $color);
2050
        //        $this->DrawImageSmoothArc($im, $x2, $y2, $weight, $weight, 0, 360, $color);
2051
    }
2052
2053
    public function DrawImageSmoothArc($im, $xc, $yc, $w, $h, $s, $e, $color, $style = null)
2054
    {
2055
        $tmp = $s;
2056
        $s   = (360 - $e) / 180 * M_PI;
2057
        $e   = (360 - $tmp) / 180 * M_PI;
2058
2059
        return $this->imageSmoothArc($im, round($xc), round($yc), round($w), round($h), $this->CreateColorForImageSmoothArc($color), $s, $e);
2060
    }
2061
2062
    public function CreateColorForImageSmoothArc($color)
2063
    {
2064
        $alpha = $color >> 24 & 0xFF;
2065
        $red   = $color >> 16 & 0xFF;
2066
        $green = $color >> 8 & 0xFF;
2067
        $blue  = $color & 0xFF;
2068
2069
        return [$red, $green, $blue, $alpha];
2070
    }
2071
2072
    public function imageSmoothCircle(&$img, $cx, $cy, $cr, $color)
2073
    {
2074
        $ir   = $cr;
2075
        $ix   = 0;
2076
        $iy   = $ir;
2077
        $ig   = 2 * $ir - 3;
2078
        $idgr = -6;
2079
        $idgd = 4 * $ir - 10;
2080
        $fill = imagecolorexactalpha($img, $color['R'], $color['G'], $color['B'], 0);
2081
        imageline($img, $cx + $cr - 1, $cy, $cx, $cy, $fill);
2082
        imageline($img, $cx - $cr + 1, $cy, $cx - 1, $cy, $fill);
2083
        imageline($img, $cx, $cy + $cr - 1, $cx, $cy + 1, $fill);
2084
        imageline($img, $cx, $cy - $cr + 1, $cx, $cy - 1, $fill);
2085
        $draw = imagecolorexactalpha($img, $color['R'], $color['G'], $color['B'], 42);
2086
        imagesetpixel($img, $cx + $cr, $cy, $draw);
2087
        imagesetpixel($img, $cx - $cr, $cy, $draw);
2088
        imagesetpixel($img, $cx, $cy + $cr, $draw);
2089
        imagesetpixel($img, $cx, $cy - $cr, $draw);
2090
        while ($ix <= $iy - 2) {
2091
            if ($ig < 0) {
2092
                $ig += $idgd;
2093
                $idgd -= 8;
2094
                --$iy;
2095
            } else {
2096
                $ig += $idgr;
2097
                $idgd -= 4;
2098
            }
2099
            $idgr -= 4;
2100
            ++$ix;
2101
            imageline($img, $cx + $ix, $cy + $iy - 1, $cx + $ix, $cy + $ix, $fill);
2102
            imageline($img, $cx + $ix, $cy - $iy + 1, $cx + $ix, $cy - $ix, $fill);
2103
            imageline($img, $cx - $ix, $cy + $iy - 1, $cx - $ix, $cy + $ix, $fill);
2104
            imageline($img, $cx - $ix, $cy - $iy + 1, $cx - $ix, $cy - $ix, $fill);
2105
            imageline($img, $cx + $iy - 1, $cy + $ix, $cx + $ix, $cy + $ix, $fill);
2106
            imageline($img, $cx + $iy - 1, $cy - $ix, $cx + $ix, $cy - $ix, $fill);
2107
            imageline($img, $cx - $iy + 1, $cy + $ix, $cx - $ix, $cy + $ix, $fill);
2108
            imageline($img, $cx - $iy + 1, $cy - $ix, $cx - $ix, $cy - $ix, $fill);
2109
            $filled = 0;
2110
            for ($xx = $ix - 0.45; $xx < $ix + 0.5; $xx += 0.2) {
2111
                for ($yy = $iy - 0.45; $yy < $iy + 0.5; $yy += 0.2) {
2112
                    if (sqrt(pow($xx, 2) + pow($yy, 2)) < $cr) {
2113
                        $filled += 4;
2114
                    }
2115
                }
2116
            }
2117
            $draw = imagecolorexactalpha($img, $color['R'], $color['G'], $color['B'], (100 - $filled));
2118
            imagesetpixel($img, $cx + $ix, $cy + $iy, $draw);
2119
            imagesetpixel($img, $cx + $ix, $cy - $iy, $draw);
2120
            imagesetpixel($img, $cx - $ix, $cy + $iy, $draw);
2121
            imagesetpixel($img, $cx - $ix, $cy - $iy, $draw);
2122
            imagesetpixel($img, $cx + $iy, $cy + $ix, $draw);
2123
            imagesetpixel($img, $cx + $iy, $cy - $ix, $draw);
2124
            imagesetpixel($img, $cx - $iy, $cy + $ix, $draw);
2125
            imagesetpixel($img, $cx - $iy, $cy - $ix, $draw);
2126
        }
2127
    }
2128
2129
    public function __get($name)
2130
    {
2131
        if (strpos($name, 'raw_') !== false) {
2132
            // if $name == 'raw_left_margin' , return $this->_left_margin;
2133
            $variable_name = '_' . str_replace('raw_', '', $name);
2134
2135
            return $this->{$variable_name};
2136
        }
2137
2138
        $variable_name = '_' . $name;
2139
2140
        if (isset($this->{$variable_name})) {
2141
            return $this->{$variable_name} * SUPERSAMPLING_SCALE;
2142
        }
2143
        Util\JpGraphError::RaiseL('25132', $name);
2144
    }
2145
2146
    public function __set($name, $value)
2147
    {
2148
        $this->{'_' . $name} = $value;
2149
    }
2150
2151
    /**
2152
     * Originally written from scratch by Ulrich Mierendorff, 06/2006
2153
     * Rewritten and improved, 04/2007, 07/2007.
2154
     *
2155
     * @param mixed $cx
2156
     * @param mixed $cy
2157
     * @param mixed $a
2158
     * @param mixed $b
2159
     * @param mixed $aaAngleX
2160
     * @param mixed $aaAngleY
2161
     * @param mixed $color
2162
     * @param mixed $start
2163
     * @param mixed $stop
2164
     * @param mixed $seg
2165
     * @param mixed $img
2166
     */
2167
    private function _imageSmoothArcDrawSegment(&$img, $cx, $cy, $a, $b, $aaAngleX, $aaAngleY, $color, $start, $stop, $seg)
2168
    {
2169
        $fillColor = imagecolorexactalpha($img, $color[0], $color[1], $color[2], $color[3]);
2170
2171
        $xStart  = abs($a * cos($start));
2172
        $yStart  = abs($b * sin($start));
2173
        $xStop   = abs($a * cos($stop));
2174
        $yStop   = abs($b * sin($stop));
2175
        $dxStart = 0;
2176
        $dyStart = 0;
2177
        $dxStop  = 0;
2178
        $dyStop  = 0;
2179
        if ($xStart != 0) {
2180
            $dyStart = $yStart / $xStart;
2181
        }
2182
        if ($xStop != 0) {
2183
            $dyStop = $yStop / $xStop;
2184
        }
2185
        if ($yStart != 0) {
2186
            $dxStart = $xStart / $yStart;
2187
        }
2188
        if ($yStop != 0) {
2189
            $dxStop = $xStop / $yStop;
2190
        }
2191
        if (abs($xStart) >= abs($yStart)) {
2192
            $aaStartX = true;
2193
        } else {
2194
            $aaStartX = false;
2195
        }
2196
        if ($xStop >= $yStop) {
2197
            $aaStopX = true;
2198
        } else {
2199
            $aaStopX = false;
2200
        }
2201
        //$xp = +1; $yp = -1; $xa = +1; $ya = 0;
2202
        for ($x = 0; $x < $a; ++$x) {
2203
            /*$y = $b * sqrt( 1 - ($x*$x)/($a*$a) );
2204
2205
            $error = $y - (int)($y);
2206
            $y = (int)($y);
2207
2208
            $diffColor = imageColorExactAlpha( $img, $color[0], $color[1], $color[2], 127-(127-$color[3])*$error );*/
2209
2210
            $_y1 = $dyStop * $x;
2211
            $_y2 = $dyStart * $x;
2212
            if ($xStart > $xStop) {
2213
                $error1 = $_y1 - (int) ($_y1);
2214
                $error2 = 1 - $_y2 + (int) $_y2;
2215
                $_y1    = $_y1 - $error1;
2216
                $_y2    = $_y2 + $error2;
2217
            } else {
2218
                $error1 = 1 - $_y1 + (int) $_y1;
2219
                $error2 = $_y2 - (int) ($_y2);
2220
                $_y1    = $_y1 + $error1;
2221
                $_y2    = $_y2 - $error2;
2222
            }
2223
            /*
2224
            if ($aaStopX)
2225
            $diffColor1 = imageColorExactAlpha( $img, $color[0], $color[1], $color[2], 127-(127-$color[3])*$error1 );
2226
            if ($aaStartX)
2227
            $diffColor2 = imageColorExactAlpha( $img, $color[0], $color[1], $color[2], 127-(127-$color[3])*$error2 );
2228
             */
2229
2230
            if ($seg == 0 || $seg == 2) {
2231
                $i = $seg;
2232
                if (!($start > $i * M_PI / 2 && $x > $xStart)) {
2233
                    if ($i == 0) {
2234
                        $xp = +1;
2235
                        $yp = -1;
2236
                        $xa = +1;
2237
                        $ya = 0;
2238
                    } else {
2239
                        $xp = -1;
2240
                        $yp = +1;
2241
                        $xa = 0;
2242
                        $ya = +1;
2243
                    }
2244
                    if ($stop < ($i + 1) * (M_PI / 2) && $x <= $xStop) {
2245
                        $diffColor1 = imagecolorexactalpha($img, $color[0], $color[1], $color[2], 127 - (127 - $color[3]) * $error1);
0 ignored issues
show
Bug introduced by
127 - 127 - $color[3] * $error1 of type double is incompatible with the type integer expected by parameter $alpha of imagecolorexactalpha(). ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

2245
                        $diffColor1 = imagecolorexactalpha($img, $color[0], $color[1], $color[2], /** @scrutinizer ignore-type */ 127 - (127 - $color[3]) * $error1);
Loading history...
2246
                        $y1         = $_y1;
2247
                        if ($aaStopX) {
2248
                            imagesetpixel($img, $cx + $xp * ($x) + $xa, $cy + $yp * ($y1 + 1) + $ya, $diffColor1);
0 ignored issues
show
Bug introduced by
$cy + $yp * $y1 + 1 + $ya of type double is incompatible with the type integer expected by parameter $y of imagesetpixel(). ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

2248
                            imagesetpixel($img, $cx + $xp * ($x) + $xa, /** @scrutinizer ignore-type */ $cy + $yp * ($y1 + 1) + $ya, $diffColor1);
Loading history...
2249
                        }
2250
                    } else {
2251
                        $y         = $b * sqrt(1 - ($x * $x) / ($a * $a));
2252
                        $error     = $y - (int) ($y);
2253
                        $y         = (int) ($y);
2254
                        $diffColor = imagecolorexactalpha($img, $color[0], $color[1], $color[2], 127 - (127 - $color[3]) * $error);
2255
                        $y1        = $y;
2256
                        if ($x < $aaAngleX) {
2257
                            imagesetpixel($img, $cx + $xp * $x + $xa, $cy + $yp * ($y1 + 1) + $ya, $diffColor);
2258
                        }
2259
                    }
2260
                    if ($start > $i * M_PI / 2 && $x <= $xStart) {
2261
                        $diffColor2 = imagecolorexactalpha($img, $color[0], $color[1], $color[2], 127 - (127 - $color[3]) * $error2);
2262
                        $y2         = $_y2;
2263
                        if ($aaStartX) {
2264
                            imagesetpixel($img, $cx + $xp * $x + $xa, $cy + $yp * ($y2 - 1) + $ya, $diffColor2);
2265
                        }
2266
                    } else {
2267
                        $y2 = 0;
2268
                    }
2269
                    if ($y2 <= $y1) {
2270
                        imageline($img, $cx + $xp * $x + $xa, $cy + $yp * $y1 + $ya, $cx + $xp * $x + $xa, $cy + $yp * $y2 + $ya, $fillColor);
0 ignored issues
show
Bug introduced by
$cy + $yp * $y1 + $ya of type double is incompatible with the type integer expected by parameter $y1 of imageline(). ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

2270
                        imageline($img, $cx + $xp * $x + $xa, /** @scrutinizer ignore-type */ $cy + $yp * $y1 + $ya, $cx + $xp * $x + $xa, $cy + $yp * $y2 + $ya, $fillColor);
Loading history...
Bug introduced by
$cy + $yp * $y2 + $ya of type double is incompatible with the type integer expected by parameter $y2 of imageline(). ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

2270
                        imageline($img, $cx + $xp * $x + $xa, $cy + $yp * $y1 + $ya, $cx + $xp * $x + $xa, /** @scrutinizer ignore-type */ $cy + $yp * $y2 + $ya, $fillColor);
Loading history...
2271
                    }
2272
                }
2273
            }
2274
2275
            if ($seg == 1 || $seg == 3) {
2276
                $i = $seg;
2277
                if (!($stop < ($i + 1) * M_PI / 2 && $x > $xStop)) {
2278
                    if ($i == 1) {
2279
                        $xp = -1;
2280
                        $yp = -1;
2281
                        $xa = 0;
2282
                        $ya = 0;
2283
                    } else {
2284
                        $xp = +1;
2285
                        $yp = +1;
2286
                        $xa = 1;
2287
                        $ya = 1;
2288
                    }
2289
                    if ($start > $i * M_PI / 2 && $x < $xStart) {
2290
                        $diffColor2 = imagecolorexactalpha($img, $color[0], $color[1], $color[2], 127 - (127 - $color[3]) * $error2);
2291
                        $y1         = $_y2;
2292
                        if ($aaStartX) {
2293
                            imagesetpixel($img, $cx + $xp * $x + $xa, $cy + $yp * ($y1 + 1) + $ya, $diffColor2);
2294
                        }
2295
                    } else {
2296
                        $y         = $b * sqrt(1 - ($x * $x) / ($a * $a));
2297
                        $error     = $y - (int) ($y);
2298
                        $y         = (int) $y;
2299
                        $diffColor = imagecolorexactalpha($img, $color[0], $color[1], $color[2], 127 - (127 - $color[3]) * $error);
2300
                        $y1        = $y;
2301
                        if ($x < $aaAngleX) {
2302
                            imagesetpixel($img, $cx + $xp * $x + $xa, $cy + $yp * ($y1 + 1) + $ya, $diffColor);
2303
                        }
2304
                    }
2305
                    if ($stop < ($i + 1) * M_PI / 2 && $x <= $xStop) {
2306
                        $diffColor1 = imagecolorexactalpha($img, $color[0], $color[1], $color[2], 127 - (127 - $color[3]) * $error1);
2307
                        $y2         = $_y1;
2308
                        if ($aaStopX) {
2309
                            imagesetpixel($img, $cx + $xp * $x + $xa, $cy + $yp * ($y2 - 1) + $ya, $diffColor1);
2310
                        }
2311
                    } else {
2312
                        $y2 = 0;
2313
                    }
2314
                    if ($y2 <= $y1) {
2315
                        imageline($img, $cx + $xp * $x + $xa, $cy + $yp * $y1 + $ya, $cx + $xp * $x + $xa, $cy + $yp * $y2 + $ya, $fillColor);
2316
                    }
2317
                }
2318
            }
2319
        }
2320
2321
        ///YYYYY
2322
2323
        for ($y = 0; $y < $b; ++$y) {
2324
            /*$x = $a * sqrt( 1 - ($y*$y)/($b*$b) );
2325
2326
            $error = $x - (int)($x);
2327
            $x = (int)($x);
2328
2329
            $diffColor = imageColorExactAlpha( $img, $color[0], $color[1], $color[2], 127-(127-$color[3])*$error );
2330
             */
2331
            $_x1 = $dxStop * $y;
2332
            $_x2 = $dxStart * $y;
2333
            if ($yStart > $yStop) {
2334
                $error1 = $_x1 - (int) ($_x1);
2335
                $error2 = 1 - $_x2 + (int) $_x2;
2336
                $_x1    = $_x1 - $error1;
2337
                $_x2    = $_x2 + $error2;
2338
            } else {
2339
                $error1 = 1 - $_x1 + (int) $_x1;
2340
                $error2 = $_x2 - (int) ($_x2);
2341
                $_x1    = $_x1 + $error1;
2342
                $_x2    = $_x2 - $error2;
2343
            }
2344
            /*
2345
            if (!$aaStopX)
2346
            $diffColor1 = imageColorExactAlpha( $img, $color[0], $color[1], $color[2], 127-(127-$color[3])*$error1 );
2347
            if (!$aaStartX)
2348
            $diffColor2 = imageColorExactAlpha( $img, $color[0], $color[1], $color[2], 127-(127-$color[3])*$error2 );
2349
             */
2350
2351
            if ($seg == 0 || $seg == 2) {
2352
                $i = $seg;
2353
                if (!($start > $i * M_PI / 2 && $y > $yStop)) {
2354
                    if ($i == 0) {
2355
                        $xp = +1;
2356
                        $yp = -1;
2357
                        $xa = 1;
2358
                        $ya = 0;
2359
                    } else {
2360
                        $xp = -1;
2361
                        $yp = +1;
2362
                        $xa = 0;
2363
                        $ya = 1;
2364
                    }
2365
                    if ($stop < ($i + 1) * (M_PI / 2) && $y <= $yStop) {
2366
                        $diffColor1 = imagecolorexactalpha($img, $color[0], $color[1], $color[2], 127 - (127 - $color[3]) * $error1);
2367
                        $x1         = $_x1;
2368
                        if (!$aaStopX) {
2369
                            imagesetpixel($img, $cx + $xp * ($x1 - 1) + $xa, $cy + $yp * ($y) + $ya, $diffColor1);
0 ignored issues
show
Bug introduced by
$cx + $xp * $x1 - 1 + $xa of type double is incompatible with the type integer expected by parameter $x of imagesetpixel(). ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

2369
                            imagesetpixel($img, /** @scrutinizer ignore-type */ $cx + $xp * ($x1 - 1) + $xa, $cy + $yp * ($y) + $ya, $diffColor1);
Loading history...
2370
                        }
2371
                    }
2372
                    if ($start > $i * M_PI / 2 && $y < $yStart) {
2373
                        $diffColor2 = imagecolorexactalpha($img, $color[0], $color[1], $color[2], 127 - (127 - $color[3]) * $error2);
2374
                        $x2         = $_x2;
2375
                        if (!$aaStartX) {
2376
                            imagesetpixel($img, $cx + $xp * ($x2 + 1) + $xa, $cy + $yp * ($y) + $ya, $diffColor2);
2377
                        }
2378
                    } else {
2379
                        $x         = $a * sqrt(1 - ($y * $y) / ($b * $b));
2380
                        $error     = $x - (int) ($x);
2381
                        $x         = (int) ($x);
2382
                        $diffColor = imagecolorexactalpha($img, $color[0], $color[1], $color[2], 127 - (127 - $color[3]) * $error);
2383
                        $x1        = $x;
2384
                        if ($y < $aaAngleY && $y <= $yStop) {
2385
                            imagesetpixel($img, $cx + $xp * ($x1 + 1) + $xa, $cy + $yp * $y + $ya, $diffColor);
2386
                        }
2387
                    }
2388
                }
2389
            }
2390
2391
            if ($seg == 1 || $seg == 3) {
2392
                $i = $seg;
2393
                if (!($stop < ($i + 1) * M_PI / 2 && $y > $yStart)) {
2394
                    if ($i == 1) {
2395
                        $xp = -1;
2396
                        $yp = -1;
2397
                        $xa = 0;
2398
                        $ya = 0;
2399
                    } else {
2400
                        $xp = +1;
2401
                        $yp = +1;
2402
                        $xa = 1;
2403
                        $ya = 1;
2404
                    }
2405
                    if ($start > $i * M_PI / 2 && $y < $yStart) {
2406
                        $diffColor2 = imagecolorexactalpha($img, $color[0], $color[1], $color[2], 127 - (127 - $color[3]) * $error2);
2407
                        $x1         = $_x2;
2408
                        if (!$aaStartX) {
2409
                            imagesetpixel($img, $cx + $xp * ($x1 - 1) + $xa, $cy + $yp * $y + $ya, $diffColor2);
2410
                        }
2411
                    }
2412
                    if ($stop < ($i + 1) * M_PI / 2 && $y <= $yStop) {
2413
                        $diffColor1 = imagecolorexactalpha($img, $color[0], $color[1], $color[2], 127 - (127 - $color[3]) * $error1);
2414
                        $x2         = $_x1;
2415
                        if (!$aaStopX) {
2416
                            imagesetpixel($img, $cx + $xp * ($x2 + 1) + $xa, $cy + $yp * $y + $ya, $diffColor1);
2417
                        }
2418
                    } else {
2419
                        $x         = $a * sqrt(1 - ($y * $y) / ($b * $b));
2420
                        $error     = $x - (int) ($x);
2421
                        $x         = (int) ($x);
2422
                        $diffColor = imagecolorexactalpha($img, $color[0], $color[1], $color[2], 127 - (127 - $color[3]) * $error);
2423
                        $x1        = $x;
2424
                        if ($y < $aaAngleY && $y < $yStart) {
2425
                            imagesetpixel($img, $cx + $xp * ($x1 + 1) + $xa, $cy + $yp * $y + $ya, $diffColor);
2426
                        }
2427
                    }
2428
                }
2429
            }
2430
        }
2431
    }
2432
2433
    public function imageSmoothArc(&$img, $cx, $cy, $w, $h, $color, $start, $stop)
2434
    {
2435
        // Originally written from scratch by Ulrich Mierendorff, 06/2006
2436
        // Rewritten and improved, 04/2007, 07/2007
2437
        // compared to old version:
2438
        // + Support for transparency added
2439
        // + Improved quality of edges & antialiasing
2440
2441
        // note: This function does not represent the fastest way to draw elliptical
2442
        // arcs. It was written without reading any papers on that subject. Better
2443
        // algorithms may be twice as fast or even more.
2444
2445
        // what it cannot do: It does not support outlined arcs, only filled
2446
2447
        // Parameters:
2448
        // $cx      - Center of ellipse, X-coord
2449
        // $cy      - Center of ellipse, Y-coord
2450
        // $w       - Width of ellipse ($w >= 2)
2451
        // $h       - Height of ellipse ($h >= 2 )
2452
        // $color   - Color of ellipse as a four component array with RGBA
2453
        // $start   - Starting angle of the arc, no limited range!
2454
        // $stop    - Stop     angle of the arc, no limited range!
2455
        // $start _can_ be greater than $stop!
2456
        // If any value is not in the given range, results are undefined!
2457
2458
        // This script does not use any special algorithms, everything is completely
2459
        // written from scratch; see http://de.wikipedia.org/wiki/Ellipse for formulas.
2460
2461
        while ($start < 0) {
2462
            $start += 2 * M_PI;
2463
        }
2464
        while ($stop < 0) {
2465
            $stop += 2 * M_PI;
2466
        }
2467
2468
        while ($start > 2 * M_PI) {
2469
            $start -= 2 * M_PI;
2470
        }
2471
2472
        while ($stop > 2 * M_PI) {
2473
            $stop -= 2 * M_PI;
2474
        }
2475
2476
        if ($start > $stop) {
2477
            $this->imageSmoothArc($img, $cx, $cy, $w, $h, $color, $start, 2 * M_PI);
2478
            $this->imageSmoothArc($img, $cx, $cy, $w, $h, $color, 0, $stop);
2479
2480
            return;
2481
        }
2482
2483
        $a  = 1.0 * round($w / 2);
2484
        $b  = 1.0 * round($h / 2);
2485
        $cx = 1.0 * round($cx);
2486
        $cy = 1.0 * round($cy);
2487
2488
        $aaAngle  = atan(($b * $b) / ($a * $a) * tan(0.25 * M_PI));
2489
        $aaAngleX = $a * cos($aaAngle);
2490
        $aaAngleY = $b * sin($aaAngle);
2491
2492
        $a -= 0.5; // looks better...
2493
        $b -= 0.5;
2494
2495
        for ($i = 0; $i < 4; ++$i) {
2496
            if ($start < ($i + 1) * M_PI / 2) {
2497
                if ($start > $i * M_PI / 2) {
2498
                    if ($stop > ($i + 1) * M_PI / 2) {
2499
                        $this->_imageSmoothArcDrawSegment($img, $cx, $cy, $a, $b, $aaAngleX, $aaAngleY, $color, $start, ($i + 1) * M_PI / 2, $i);
2500
                    } else {
2501
                        $this->_imageSmoothArcDrawSegment($img, $cx, $cy, $a, $b, $aaAngleX, $aaAngleY, $color, $start, $stop, $i);
2502
2503
                        break;
2504
                    }
2505
                } else {
2506
                    if ($stop > ($i + 1) * M_PI / 2) {
2507
                        $this->_imageSmoothArcDrawSegment($img, $cx, $cy, $a, $b, $aaAngleX, $aaAngleY, $color, $i * M_PI / 2, ($i + 1) * M_PI / 2, $i);
2508
                    } else {
2509
                        $this->_imageSmoothArcDrawSegment($img, $cx, $cy, $a, $b, $aaAngleX, $aaAngleY, $color, $i * M_PI / 2, $stop, $i);
2510
2511
                        break;
2512
                    }
2513
                }
2514
            }
2515
        }
2516
    }
2517
} // @class
2518