Completed
Push — master ( 7cd6f2...7b7591 )
by
unknown
04:24
created

CPDF::page_line()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 5

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 5
rs 10
c 0
b 0
f 0
cc 1
nc 1
nop 7
1
<?php
2
/**
3
 * @package dompdf
4
 * @link    http://dompdf.github.com/
5
 * @author  Benj Carson <[email protected]>
6
 * @author  Orion Richardson <[email protected]>
7
 * @author  Helmut Tischer <[email protected]>
8
 * @author  Fabien Ménager <[email protected]>
9
 * @license http://www.gnu.org/copyleft/lesser.html GNU Lesser General Public License
10
 */
11
12
// FIXME: Need to sanity check inputs to this class
13
namespace Dompdf\Adapter;
14
15
use Dompdf\Canvas;
16
use Dompdf\Dompdf;
17
use Dompdf\Helpers;
18
use Dompdf\Exception;
19
use Dompdf\Image\Cache;
20
use Dompdf\PhpEvaluator;
21
22
/**
23
 * PDF rendering interface
24
 *
25
 * Dompdf\Adapter\CPDF provides a simple stateless interface to the stateful one
26
 * provided by the Cpdf class.
27
 *
28
 * Unless otherwise mentioned, all dimensions are in points (1/72 in).  The
29
 * coordinate origin is in the top left corner, and y values increase
30
 * downwards.
31
 *
32
 * See {@link http://www.ros.co.nz/pdf/} for more complete documentation
33
 * on the underlying {@link Cpdf} class.
34
 *
35
 * @package dompdf
36
 */
37
class CPDF implements Canvas
38
{
39
40
    /**
41
     * Dimensions of paper sizes in points
42
     *
43
     * @var array;
44
     */
45
    static $PAPER_SIZES = array(
0 ignored issues
show
Coding Style introduced by
The visibility should be declared for property $PAPER_SIZES.

The PSR-2 coding standard requires that all properties in a class have their visibility explicitly declared. If you declare a property using

class A {
    var $property;
}

the property is implicitly global.

To learn more about the PSR-2, please see the PHP-FIG site on the PSR-2.

Loading history...
46
        "4a0" => array(0, 0, 4767.87, 6740.79),
47
        "2a0" => array(0, 0, 3370.39, 4767.87),
48
        "a0" => array(0, 0, 2383.94, 3370.39),
49
        "a1" => array(0, 0, 1683.78, 2383.94),
50
        "a2" => array(0, 0, 1190.55, 1683.78),
51
        "a3" => array(0, 0, 841.89, 1190.55),
52
        "a4" => array(0, 0, 595.28, 841.89),
53
        "a5" => array(0, 0, 419.53, 595.28),
54
        "a6" => array(0, 0, 297.64, 419.53),
55
        "a7" => array(0, 0, 209.76, 297.64),
56
        "a8" => array(0, 0, 147.40, 209.76),
57
        "a9" => array(0, 0, 104.88, 147.40),
58
        "a10" => array(0, 0, 73.70, 104.88),
59
        "b0" => array(0, 0, 2834.65, 4008.19),
60
        "b1" => array(0, 0, 2004.09, 2834.65),
61
        "b2" => array(0, 0, 1417.32, 2004.09),
62
        "b3" => array(0, 0, 1000.63, 1417.32),
63
        "b4" => array(0, 0, 708.66, 1000.63),
64
        "b5" => array(0, 0, 498.90, 708.66),
65
        "b6" => array(0, 0, 354.33, 498.90),
66
        "b7" => array(0, 0, 249.45, 354.33),
67
        "b8" => array(0, 0, 175.75, 249.45),
68
        "b9" => array(0, 0, 124.72, 175.75),
69
        "b10" => array(0, 0, 87.87, 124.72),
70
        "c0" => array(0, 0, 2599.37, 3676.54),
71
        "c1" => array(0, 0, 1836.85, 2599.37),
72
        "c2" => array(0, 0, 1298.27, 1836.85),
73
        "c3" => array(0, 0, 918.43, 1298.27),
74
        "c4" => array(0, 0, 649.13, 918.43),
75
        "c5" => array(0, 0, 459.21, 649.13),
76
        "c6" => array(0, 0, 323.15, 459.21),
77
        "c7" => array(0, 0, 229.61, 323.15),
78
        "c8" => array(0, 0, 161.57, 229.61),
79
        "c9" => array(0, 0, 113.39, 161.57),
80
        "c10" => array(0, 0, 79.37, 113.39),
81
        "ra0" => array(0, 0, 2437.80, 3458.27),
82
        "ra1" => array(0, 0, 1729.13, 2437.80),
83
        "ra2" => array(0, 0, 1218.90, 1729.13),
84
        "ra3" => array(0, 0, 864.57, 1218.90),
85
        "ra4" => array(0, 0, 609.45, 864.57),
86
        "sra0" => array(0, 0, 2551.18, 3628.35),
87
        "sra1" => array(0, 0, 1814.17, 2551.18),
88
        "sra2" => array(0, 0, 1275.59, 1814.17),
89
        "sra3" => array(0, 0, 907.09, 1275.59),
90
        "sra4" => array(0, 0, 637.80, 907.09),
91
        "letter" => array(0, 0, 612.00, 792.00),
92
        "half-letter" => array(0, 0, 396.00, 612.00),
93
        "legal" => array(0, 0, 612.00, 1008.00),
94
        "ledger" => array(0, 0, 1224.00, 792.00),
95
        "tabloid" => array(0, 0, 792.00, 1224.00),
96
        "executive" => array(0, 0, 521.86, 756.00),
97
        "folio" => array(0, 0, 612.00, 936.00),
98
        "commercial #10 envelope" => array(0, 0, 684, 297),
99
        "catalog #10 1/2 envelope" => array(0, 0, 648, 864),
100
        "8.5x11" => array(0, 0, 612.00, 792.00),
101
        "8.5x14" => array(0, 0, 612.00, 1008.0),
102
        "11x17" => array(0, 0, 792.00, 1224.00),
103
    );
104
105
    /**
106
     * The Dompdf object
107
     *
108
     * @var Dompdf
109
     */
110
    private $_dompdf;
111
112
    /**
113
     * Instance of Cpdf class
114
     *
115
     * @var Cpdf
116
     */
117
    private $_pdf;
118
119
    /**
120
     * PDF width, in points
121
     *
122
     * @var float
123
     */
124
    private $_width;
125
126
    /**
127
     * PDF height, in points
128
     *
129
     * @var float;
130
     */
131
    private $_height;
132
133
    /**
134
     * Current page number
135
     *
136
     * @var int
137
     */
138
    private $_page_number;
139
140
    /**
141
     * Total number of pages
142
     *
143
     * @var int
144
     */
145
    private $_page_count;
146
147
    /**
148
     * Text to display on every page
149
     *
150
     * @var array
151
     */
152
    private $_page_text;
153
154
    /**
155
     * Array of pages for accesing after rendering is initially complete
156
     *
157
     * @var array
158
     */
159
    private $_pages;
160
161
    /**
162
     * Array of temporary cached images to be deleted when processing is complete
163
     *
164
     * @var array
165
     */
166
    private $_image_cache;
167
168
    /**
169
     * Currently-applied opacity level (0 - 1)
170
     *
171
     * @var float
172
     */
173
    private $_current_opacity = 1;
174
175
    /**
176
     * Class constructor
177
     *
178
     * @param mixed $paper The size of paper to use in this PDF ({@link CPDF::$PAPER_SIZES})
179
     * @param string $orientation The orientation of the document (either 'landscape' or 'portrait')
180
     * @param Dompdf $dompdf The Dompdf instance
181
     */
182
    public function __construct($paper = "letter", $orientation = "portrait", Dompdf $dompdf)
183
    {
184 View Code Duplication
        if (is_array($paper)) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
185
            $size = $paper;
186
        } else if (isset(self::$PAPER_SIZES[mb_strtolower($paper)])) {
187
            $size = self::$PAPER_SIZES[mb_strtolower($paper)];
188
        } else {
189
            $size = self::$PAPER_SIZES["letter"];
190
        }
191
192 View Code Duplication
        if (mb_strtolower($orientation) === "landscape") {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
193
            list($size[2], $size[3]) = array($size[3], $size[2]);
194
        }
195
196
        $this->_dompdf = $dompdf;
197
198
        $this->_pdf = new \Cpdf(
0 ignored issues
show
Documentation Bug introduced by
It seems like new \Cpdf($size, true, $...ptions()->getTempDir()) of type object<Cpdf> is incompatible with the declared type object<Dompdf\Adapter\CPDF> of property $_pdf.

Our type inference engine has found an assignment to a property that is incompatible with the declared type of that property.

Either this assignment is in error or the assigned type should be added to the documentation/type hint for that property..

Loading history...
199
            $size,
200
            true,
201
            $dompdf->getOptions()->getFontCache(),
202
            $dompdf->getOptions()->getTempDir()
203
        );
204
205
        $this->_pdf->addInfo("Producer", sprintf("%s + CPDF", $dompdf->version));
0 ignored issues
show
Documentation introduced by
The property $version is declared private in Dompdf\Dompdf. Since you implemented __get(), maybe consider adding a @property or @property-read annotation. This makes it easier for IDEs to provide auto-completion.

Since your code implements the magic setter _set, this function will be called for any write access on an undefined variable. You can add the @property annotation to your class or interface to document the existence of this variable.

<?php

/**
 * @property int $x
 * @property int $y
 * @property string $text
 */
class MyLabel
{
    private $properties;

    private $allowedProperties = array('x', 'y', 'text');

    public function __get($name)
    {
        if (isset($properties[$name]) && in_array($name, $this->allowedProperties)) {
            return $properties[$name];
        } else {
            return null;
        }
    }

    public function __set($name, $value)
    {
        if (in_array($name, $this->allowedProperties)) {
            $properties[$name] = $value;
        } else {
            throw new \LogicException("Property $name is not defined.");
        }
    }

}

Since the property has write access only, you can use the @property-write annotation instead.

Of course, you may also just have mistyped another name, in which case you should fix the error.

See also the PhpDoc documentation for @property.

Loading history...
206
        $time = substr_replace(date('YmdHisO'), '\'', -2, 0) . '\'';
207
        $this->_pdf->addInfo("CreationDate", "D:$time");
208
        $this->_pdf->addInfo("ModDate", "D:$time");
209
210
        $this->_width = $size[2] - $size[0];
0 ignored issues
show
Documentation Bug introduced by
It seems like $size[2] - $size[0] can also be of type integer. However, the property $_width is declared as type double. Maybe add an additional type check?

Our type inference engine has found a suspicous assignment of a value to a property. This check raises an issue when a value that can be of a mixed type is assigned to a property that is type hinted more strictly.

For example, imagine you have a variable $accountId that can either hold an Id object or false (if there is no account id yet). Your code now assigns that value to the id property of an instance of the Account class. This class holds a proper account, so the id value must no longer be false.

Either this assignment is in error or a type check should be added for that assignment.

class Id
{
    public $id;

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

}

class Account
{
    /** @var  Id $id */
    public $id;
}

$account_id = false;

if (starsAreRight()) {
    $account_id = new Id(42);
}

$account = new Account();
if ($account instanceof Id)
{
    $account->id = $account_id;
}
Loading history...
211
        $this->_height = $size[3] - $size[1];
212
213
        $this->_page_number = $this->_page_count = 1;
214
        $this->_page_text = array();
215
216
        $this->_pages = array($this->_pdf->getFirstPageId());
217
218
        $this->_image_cache = array();
219
    }
220
221
    /**
222
     * @return Dompdf
223
     */
224
    public function get_dompdf()
225
    {
226
        return $this->_dompdf;
227
    }
228
229
    /**
230
     * Class destructor
231
     *
232
     * Deletes all temporary image files
233
     */
234
    public function __destruct()
235
    {
236
        foreach ($this->_image_cache as $img) {
237
            // The file might be already deleted by 3rd party tmp cleaner,
238
            // the file might not have been created at all
239
            // (if image outputting commands failed)
240
            // or because the destructor was called twice accidentally.
241
            if (!file_exists($img)) {
242
                continue;
243
            }
244
245
            if ($this->_dompdf->getOptions()->getDebugPng()) {
246
                print '[__destruct unlink ' . $img . ']';
247
            }
248
            if (!$this->_dompdf->getOptions()->getDebugKeepTemp()) {
249
                unlink($img);
250
            }
251
        }
252
    }
253
254
    /**
255
     * Returns the Cpdf instance
256
     *
257
     * @return \Cpdf
258
     */
259
    public function get_cpdf()
260
    {
261
        return $this->_pdf;
262
    }
263
264
    /**
265
     * Add meta information to the PDF
266
     *
267
     * @param string $label label of the value (Creator, Producer, etc.)
268
     * @param string $value the text to set
269
     */
270
    public function add_info($label, $value)
271
    {
272
        $this->_pdf->addInfo($label, $value);
0 ignored issues
show
Bug introduced by
The method addInfo() does not seem to exist on object<Dompdf\Adapter\CPDF>.

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...
273
    }
274
275
    /**
276
     * Opens a new 'object'
277
     *
278
     * While an object is open, all drawing actions are recored in the object,
279
     * as opposed to being drawn on the current page.  Objects can be added
280
     * later to a specific page or to several pages.
281
     *
282
     * The return value is an integer ID for the new object.
283
     *
284
     * @see CPDF::close_object()
285
     * @see CPDF::add_object()
286
     *
287
     * @return int
288
     */
289
    public function open_object()
290
    {
291
        $ret = $this->_pdf->openObject();
0 ignored issues
show
Bug introduced by
The method openObject() does not seem to exist on object<Dompdf\Adapter\CPDF>.

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...
292
        $this->_pdf->saveState();
0 ignored issues
show
Bug introduced by
The method saveState() does not seem to exist on object<Dompdf\Adapter\CPDF>.

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...
293
        return $ret;
294
    }
295
296
    /**
297
     * Reopens an existing 'object'
298
     *
299
     * @see CPDF::open_object()
300
     * @param int $object the ID of a previously opened object
301
     */
302
    public function reopen_object($object)
303
    {
304
        $this->_pdf->reopenObject($object);
0 ignored issues
show
Bug introduced by
The method reopenObject() does not seem to exist on object<Dompdf\Adapter\CPDF>.

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...
305
        $this->_pdf->saveState();
0 ignored issues
show
Bug introduced by
The method saveState() does not seem to exist on object<Dompdf\Adapter\CPDF>.

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...
306
    }
307
308
    /**
309
     * Closes the current 'object'
310
     *
311
     * @see CPDF::open_object()
312
     */
313
    public function close_object()
314
    {
315
        $this->_pdf->restoreState();
0 ignored issues
show
Bug introduced by
The method restoreState() does not exist on Dompdf\Adapter\CPDF. Did you maybe mean restore()?

This check marks calls to methods that do not seem to exist on an object.

This is most likely the result of a method being renamed without all references to it being renamed likewise.

Loading history...
316
        $this->_pdf->closeObject();
0 ignored issues
show
Bug introduced by
The method closeObject() does not seem to exist on object<Dompdf\Adapter\CPDF>.

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...
317
    }
318
319
    /**
320
     * Adds a specified 'object' to the document
321
     *
322
     * $object int specifying an object created with {@link
323
     * CPDF::open_object()}.  $where can be one of:
324
     * - 'add' add to current page only
325
     * - 'all' add to every page from the current one onwards
326
     * - 'odd' add to all odd numbered pages from now on
327
     * - 'even' add to all even numbered pages from now on
328
     * - 'next' add the object to the next page only
329
     * - 'nextodd' add to all odd numbered pages from the next one
330
     * - 'nexteven' add to all even numbered pages from the next one
331
     *
332
     * @see Cpdf::addObject()
333
     *
334
     * @param int $object
335
     * @param string $where
336
     */
337
    public function add_object($object, $where = 'all')
338
    {
339
        $this->_pdf->addObject($object, $where);
0 ignored issues
show
Bug introduced by
The method addObject() does not seem to exist on object<Dompdf\Adapter\CPDF>.

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...
340
    }
341
342
    /**
343
     * Stops the specified 'object' from appearing in the document.
344
     *
345
     * The object will stop being displayed on the page following the current
346
     * one.
347
     *
348
     * @param int $object
349
     */
350
    public function stop_object($object)
351
    {
352
        $this->_pdf->stopObject($object);
0 ignored issues
show
Bug introduced by
The method stopObject() does not seem to exist on object<Dompdf\Adapter\CPDF>.

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...
353
    }
354
355
    /**
356
     * @access private
357
     */
358
    public function serialize_object($id)
359
    {
360
        // Serialize the pdf object's current state for retrieval later
361
        return $this->_pdf->serializeObject($id);
0 ignored issues
show
Bug introduced by
The method serializeObject() does not exist on Dompdf\Adapter\CPDF. Did you maybe mean serialize_object()?

This check marks calls to methods that do not seem to exist on an object.

This is most likely the result of a method being renamed without all references to it being renamed likewise.

Loading history...
362
    }
363
364
    /**
365
     * @access private
366
     */
367
    public function reopen_serialized_object($obj)
368
    {
369
        return $this->_pdf->restoreSerializedObject($obj);
0 ignored issues
show
Bug introduced by
The method restoreSerializedObject() does not exist on Dompdf\Adapter\CPDF. Did you maybe mean restore()?

This check marks calls to methods that do not seem to exist on an object.

This is most likely the result of a method being renamed without all references to it being renamed likewise.

Loading history...
370
    }
371
372
    //........................................................................
0 ignored issues
show
Unused Code Comprehensibility introduced by
100% of this comment could be valid code. Did you maybe forget this after debugging?

Sometimes obsolete code just ends up commented out instead of removed. In this case it is better to remove the code once you have checked you do not need it.

The code might also have been commented out for debugging purposes. In this case it is vital that someone uncomments it again or your project may behave in very unexpected ways in production.

This check looks for comments that seem to be mostly valid code and reports them.

Loading history...
373
374
    /**
375
     * Returns the PDF's width in points
376
     * @return float
377
     */
378
    public function get_width()
379
    {
380
        return $this->_width;
381
    }
382
383
    /**
384
     * Returns the PDF's height in points
385
     * @return float
386
     */
387
    public function get_height()
388
    {
389
        return $this->_height;
390
    }
391
392
    /**
393
     * Returns the current page number
394
     * @return int
395
     */
396
    public function get_page_number()
397
    {
398
        return $this->_page_number;
399
    }
400
401
    /**
402
     * Returns the total number of pages in the document
403
     * @return int
404
     */
405
    public function get_page_count()
406
    {
407
        return $this->_page_count;
408
    }
409
410
    /**
411
     * Sets the current page number
412
     *
413
     * @param int $num
414
     */
415
    public function set_page_number($num)
416
    {
417
        $this->_page_number = $num;
418
    }
419
420
    /**
421
     * Sets the page count
422
     *
423
     * @param int $count
424
     */
425
    public function set_page_count($count)
426
    {
427
        $this->_page_count = $count;
428
    }
429
430
    /**
431
     * Sets the stroke color
432
     *
433
     * See {@link Style::set_color()} for the format of the color array.
434
     * @param array $color
435
     */
436 View Code Duplication
    protected function _set_stroke_color($color)
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
437
    {
438
        $this->_pdf->setStrokeColor($color);
0 ignored issues
show
Bug introduced by
The method setStrokeColor() does not seem to exist on object<Dompdf\Adapter\CPDF>.

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...
439
        $alpha = isset($color["alpha"]) ? $color["alpha"] : 1;
440
        if ($this->_current_opacity != 1) {
441
            $alpha *= $this->_current_opacity;
442
        }
443
        $this->_set_line_transparency("Normal", $alpha);
444
    }
445
446
    /**
447
     * Sets the fill colour
448
     *
449
     * See {@link Style::set_color()} for the format of the colour array.
450
     * @param array $color
451
     */
452 View Code Duplication
    protected function _set_fill_color($color)
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
453
    {
454
        $this->_pdf->setColor($color);
0 ignored issues
show
Bug introduced by
The method setColor() does not seem to exist on object<Dompdf\Adapter\CPDF>.

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...
455
        $alpha = isset($color["alpha"]) ? $color["alpha"] : 1;
456
        if ($this->_current_opacity) {
457
            $alpha *= $this->_current_opacity;
458
        }
459
        $this->_set_fill_transparency("Normal", $alpha);
460
    }
461
462
    /**
463
     * Sets line transparency
464
     * @see Cpdf::setLineTransparency()
465
     *
466
     * Valid blend modes are (case-sensitive):
467
     *
468
     * Normal, Multiply, Screen, Overlay, Darken, Lighten,
469
     * ColorDodge, ColorBurn, HardLight, SoftLight, Difference,
470
     * Exclusion
471
     *
472
     * @param string $mode the blending mode to use
473
     * @param float $opacity 0.0 fully transparent, 1.0 fully opaque
474
     */
475
    protected function _set_line_transparency($mode, $opacity)
476
    {
477
        $this->_pdf->setLineTransparency($mode, $opacity);
0 ignored issues
show
Bug introduced by
The method setLineTransparency() does not seem to exist on object<Dompdf\Adapter\CPDF>.

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...
478
    }
479
480
    /**
481
     * Sets fill transparency
482
     * @see Cpdf::setFillTransparency()
483
     *
484
     * Valid blend modes are (case-sensitive):
485
     *
486
     * Normal, Multiply, Screen, Overlay, Darken, Lighten,
487
     * ColorDogde, ColorBurn, HardLight, SoftLight, Difference,
488
     * Exclusion
489
     *
490
     * @param string $mode the blending mode to use
491
     * @param float $opacity 0.0 fully transparent, 1.0 fully opaque
492
     */
493
    protected function _set_fill_transparency($mode, $opacity)
494
    {
495
        $this->_pdf->setFillTransparency($mode, $opacity);
0 ignored issues
show
Bug introduced by
The method setFillTransparency() does not seem to exist on object<Dompdf\Adapter\CPDF>.

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...
496
    }
497
498
    /**
499
     * Sets the line style
500
     *
501
     * @see Cpdf::setLineStyle()
502
     *
503
     * @param float $width
504
     * @param string $cap
505
     * @param string $join
506
     * @param array $dash
507
     */
508
    protected function _set_line_style($width, $cap, $join, $dash)
509
    {
510
        $this->_pdf->setLineStyle($width, $cap, $join, $dash);
0 ignored issues
show
Bug introduced by
The method setLineStyle() does not seem to exist on object<Dompdf\Adapter\CPDF>.

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...
511
    }
512
513
    /**
514
     * Sets the opacity
515
     *
516
     * @param $opacity
517
     * @param $mode
518
     */
519
    public function set_opacity($opacity, $mode = "Normal")
520
    {
521
        $this->_set_line_transparency($mode, $opacity);
522
        $this->_set_fill_transparency($mode, $opacity);
523
        $this->_current_opacity = $opacity;
524
    }
525
526
    public function set_default_view($view, $options = array())
527
    {
528
        array_unshift($options, $view);
529
        call_user_func_array(array($this->_pdf, "openHere"), $options);
530
    }
531
532
    /**
533
     * Remaps y coords from 4th to 1st quadrant
534
     *
535
     * @param float $y
536
     * @return float
537
     */
538
    protected function y($y)
539
    {
540
        return $this->_height - $y;
541
    }
542
543
    /**
544
     * Canvas implementation
545
     *
546
     * @param float $x1
547
     * @param float $y1
548
     * @param float $x2
549
     * @param float $y2
550
     * @param array $color
551
     * @param float $width
552
     * @param array $style
553
     */
554
    public function line($x1, $y1, $x2, $y2, $color, $width, $style = array())
555
    {
556
        $this->_set_stroke_color($color);
557
        $this->_set_line_style($width, "butt", "", $style);
558
559
        $this->_pdf->line($x1, $this->y($y1),
0 ignored issues
show
Bug introduced by
The call to line() misses some required arguments starting with $color.
Loading history...
560
            $x2, $this->y($y2));
561
        $this->_set_line_transparency("Normal", $this->_current_opacity);
562
    }
563
564
    /**
565
     * Draw line at the specified coordinates on every page.
566
     *
567
     * See {@link Style::munge_color()} for the format of the colour array.
568
     *
569
     * @param float $x1
570
     * @param float $y1
571
     * @param float $x2
572
     * @param float $y2
573
     * @param array $color
574
     * @param float $width
575
     * @param array $style optional
576
     */
577
    public function page_line($x1, $y1, $x2, $y2, $color, $width, $style = array())
578
    {
579
        $_t = 'line';
580
        $this->_page_text[] = compact('_t', 'x1', 'y1', 'x2', 'y2', 'color', 'width', 'style');
581
    }
582
583
    /**
584
     * @param float $x
585
     * @param float $y
586
     * @param float $r1
587
     * @param float $r2
588
     * @param float $astart
589
     * @param float $aend
590
     * @param array $color
591
     * @param float $width
592
     * @param array $style
593
     */
594
    public function arc($x, $y, $r1, $r2, $astart, $aend, $color, $width, $style = array())
595
    {
596
        $this->_set_stroke_color($color);
597
        $this->_set_line_style($width, "butt", "", $style);
598
599
        $this->_pdf->ellipse($x, $this->y($y), $r1, $r2, 0, 8, $astart, $aend, false, false, true, false);
0 ignored issues
show
Bug introduced by
The method ellipse() does not seem to exist on object<Dompdf\Adapter\CPDF>.

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...
600
        $this->_set_line_transparency("Normal", $this->_current_opacity);
601
    }
602
603
    /**
604
     * Convert a GIF or BMP image to a PNG image
605
     *
606
     * @param string $image_url
607
     * @param integer $type
608
     *
609
     * @throws Exception
610
     * @return string The url of the newly converted image
611
     */
612
    protected function _convert_gif_bmp_to_png($image_url, $type)
613
    {
614
        $func_name = "imagecreatefrom$type";
615
616 View Code Duplication
        if (!function_exists($func_name)) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
617
            if (!method_exists("Dompdf\Helpers", $func_name)) {
618
                throw new Exception("Function $func_name() not found.  Cannot convert $type image: $image_url.  Please install the image PHP extension.");
619
            }
620
            $func_name = "\\Dompdf\\Helpers::" . $func_name;
621
        }
622
623
        set_error_handler(array("\\Dompdf\\Helpers", "record_warnings"));
624
        $im = call_user_func($func_name, $image_url);
625
626
        if ($im) {
627
            imageinterlace($im, false);
628
629
            $tmp_dir = $this->_dompdf->getOptions()->getTempDir();
630
            $tmp_name = tempnam($tmp_dir, "{$type}dompdf_img_");
631
            @unlink($tmp_name);
0 ignored issues
show
Security Best Practice introduced by
It seems like you do not handle an error condition here. This can introduce security issues, and is generally not recommended.

If you suppress an error, we recommend checking for the error condition explicitly:

// For example instead of
@mkdir($dir);

// Better use
if (@mkdir($dir) === false) {
    throw new \RuntimeException('The directory '.$dir.' could not be created.');
}
Loading history...
632
            $filename = "$tmp_name.png";
633
            $this->_image_cache[] = $filename;
634
635
            imagepng($im, $filename);
636
            imagedestroy($im);
637
        } else {
638
            $filename = Cache::$broken_image;
639
        }
640
641
        restore_error_handler();
642
643
        return $filename;
644
    }
645
646
    /**
647
     * @param float $x1
648
     * @param float $y1
649
     * @param float $w
650
     * @param float $h
651
     * @param array $color
652
     * @param float $width
653
     * @param array $style
654
     */
655
    public function rectangle($x1, $y1, $w, $h, $color, $width, $style = array())
656
    {
657
        $this->_set_stroke_color($color);
658
        $this->_set_line_style($width, "butt", "", $style);
659
        $this->_pdf->rectangle($x1, $this->y($y1) - $h, $w, $h);
0 ignored issues
show
Bug introduced by
The call to rectangle() misses some required arguments starting with $color.
Loading history...
660
        $this->_set_line_transparency("Normal", $this->_current_opacity);
661
    }
662
663
    /**
664
     * @param float $x1
665
     * @param float $y1
666
     * @param float $w
667
     * @param float $h
668
     * @param array $color
669
     */
670
    public function filled_rectangle($x1, $y1, $w, $h, $color)
671
    {
672
        $this->_set_fill_color($color);
673
        $this->_pdf->filledRectangle($x1, $this->y($y1) - $h, $w, $h);
0 ignored issues
show
Bug introduced by
The method filledRectangle() does not exist on Dompdf\Adapter\CPDF. Did you maybe mean rectangle()?

This check marks calls to methods that do not seem to exist on an object.

This is most likely the result of a method being renamed without all references to it being renamed likewise.

Loading history...
674
        $this->_set_fill_transparency("Normal", $this->_current_opacity);
675
    }
676
677
    /**
678
     * @param float $x1
679
     * @param float $y1
680
     * @param float $w
681
     * @param float $h
682
     */
683
    public function clipping_rectangle($x1, $y1, $w, $h)
684
    {
685
        $this->_pdf->clippingRectangle($x1, $this->y($y1) - $h, $w, $h);
0 ignored issues
show
Bug introduced by
The method clippingRectangle() does not exist on Dompdf\Adapter\CPDF. Did you maybe mean rectangle()?

This check marks calls to methods that do not seem to exist on an object.

This is most likely the result of a method being renamed without all references to it being renamed likewise.

Loading history...
686
    }
687
688
    /**
689
     * @param float $x1
690
     * @param float $y1
691
     * @param float $w
692
     * @param float $h
693
     * @param float $rTL
694
     * @param float $rTR
695
     * @param float $rBR
696
     * @param float $rBL
697
     */
698
    public function clipping_roundrectangle($x1, $y1, $w, $h, $rTL, $rTR, $rBR, $rBL)
699
    {
700
        $this->_pdf->clippingRectangleRounded($x1, $this->y($y1) - $h, $w, $h, $rTL, $rTR, $rBR, $rBL);
0 ignored issues
show
Bug introduced by
The method clippingRectangleRounded() does not exist on Dompdf\Adapter\CPDF. Did you maybe mean rectangle()?

This check marks calls to methods that do not seem to exist on an object.

This is most likely the result of a method being renamed without all references to it being renamed likewise.

Loading history...
701
    }
702
703
    /**
704
     *
705
     */
706
    public function clipping_end()
707
    {
708
        $this->_pdf->clippingEnd();
0 ignored issues
show
Bug introduced by
The method clippingEnd() does not seem to exist on object<Dompdf\Adapter\CPDF>.

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...
709
    }
710
711
    /**
712
     *
713
     */
714
    public function save()
715
    {
716
        $this->_pdf->saveState();
0 ignored issues
show
Bug introduced by
The method saveState() does not seem to exist on object<Dompdf\Adapter\CPDF>.

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...
717
    }
718
719
    /**
720
     *
721
     */
722
    public function restore()
723
    {
724
        $this->_pdf->restoreState();
0 ignored issues
show
Bug introduced by
The method restoreState() does not exist on Dompdf\Adapter\CPDF. Did you maybe mean restore()?

This check marks calls to methods that do not seem to exist on an object.

This is most likely the result of a method being renamed without all references to it being renamed likewise.

Loading history...
725
    }
726
727
    /**
728
     * @param $angle
729
     * @param $x
730
     * @param $y
731
     */
732
    public function rotate($angle, $x, $y)
733
    {
734
        $this->_pdf->rotate($angle, $x, $y);
735
    }
736
737
    /**
738
     * @param $angle_x
739
     * @param $angle_y
740
     * @param $x
741
     * @param $y
742
     */
743
    public function skew($angle_x, $angle_y, $x, $y)
744
    {
745
        $this->_pdf->skew($angle_x, $angle_y, $x, $y);
746
    }
747
748
    /**
749
     * @param $s_x
750
     * @param $s_y
751
     * @param $x
752
     * @param $y
753
     */
754
    public function scale($s_x, $s_y, $x, $y)
755
    {
756
        $this->_pdf->scale($s_x, $s_y, $x, $y);
757
    }
758
759
    /**
760
     * @param $t_x
761
     * @param $t_y
762
     */
763
    public function translate($t_x, $t_y)
764
    {
765
        $this->_pdf->translate($t_x, $t_y);
766
    }
767
768
    /**
769
     * @param $a
770
     * @param $b
771
     * @param $c
772
     * @param $d
773
     * @param $e
774
     * @param $f
775
     */
776
    public function transform($a, $b, $c, $d, $e, $f)
777
    {
778
        $this->_pdf->transform(array($a, $b, $c, $d, $e, $f));
0 ignored issues
show
Bug introduced by
The call to transform() misses some required arguments starting with $b.
Loading history...
779
    }
780
781
    /**
782
     * @param array $points
783
     * @param array $color
784
     * @param null $width
785
     * @param array $style
786
     * @param bool $fill
787
     */
788
    public function polygon($points, $color, $width = null, $style = array(), $fill = false)
789
    {
790
        $this->_set_fill_color($color);
791
        $this->_set_stroke_color($color);
792
793
        // Adjust y values
794
        for ($i = 1; $i < count($points); $i += 2) {
0 ignored issues
show
Performance Best Practice introduced by
It seems like you are calling the size function count() as part of the test condition. You might want to compute the size beforehand, and not on each iteration.

If the size of the collection does not change during the iteration, it is generally a good practice to compute it beforehand, and not on each iteration:

for ($i=0; $i<count($array); $i++) { // calls count() on each iteration
}

// Better
for ($i=0, $c=count($array); $i<$c; $i++) { // calls count() just once
}
Loading history...
795
            $points[$i] = $this->y($points[$i]);
796
        }
797
798
        $this->_pdf->polygon($points, count($points) / 2, $fill);
0 ignored issues
show
Documentation introduced by
count($points) / 2 is of type integer, but the function expects a array.

It seems like the type of the argument is not accepted by the function/method which you are calling.

In some cases, in particular if PHP’s automatic type-juggling kicks in this might be fine. In other cases, however this might be a bug.

We suggest to add an explicit type cast like in the following example:

function acceptsInteger($int) { }

$x = '123'; // string "123"

// Instead of
acceptsInteger($x);

// we recommend to use
acceptsInteger((integer) $x);
Loading history...
799
800
        $this->_set_fill_transparency("Normal", $this->_current_opacity);
801
        $this->_set_line_transparency("Normal", $this->_current_opacity);
802
    }
803
804
    /**
805
     * @param float $x
806
     * @param float $y
807
     * @param float $r1
808
     * @param array $color
809
     * @param null $width
810
     * @param null $style
811
     * @param bool $fill
812
     */
813
    public function circle($x, $y, $r1, $color, $width = null, $style = null, $fill = false)
814
    {
815
        $this->_set_fill_color($color);
816
        $this->_set_stroke_color($color);
817
818
        if (!$fill && isset($width)) {
819
            $this->_set_line_style($width, "round", "round", $style);
0 ignored issues
show
Documentation introduced by
$style is of type null, but the function expects a array.

It seems like the type of the argument is not accepted by the function/method which you are calling.

In some cases, in particular if PHP’s automatic type-juggling kicks in this might be fine. In other cases, however this might be a bug.

We suggest to add an explicit type cast like in the following example:

function acceptsInteger($int) { }

$x = '123'; // string "123"

// Instead of
acceptsInteger($x);

// we recommend to use
acceptsInteger((integer) $x);
Loading history...
820
        }
821
822
        $this->_pdf->ellipse($x, $this->y($y), $r1, 0, 0, 8, 0, 360, 1, $fill);
0 ignored issues
show
Bug introduced by
The method ellipse() does not seem to exist on object<Dompdf\Adapter\CPDF>.

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...
823
824
        $this->_set_fill_transparency("Normal", $this->_current_opacity);
825
        $this->_set_line_transparency("Normal", $this->_current_opacity);
826
    }
827
828
    /**
829
     * @param string $img
830
     * @param float $x
831
     * @param float $y
832
     * @param int $w
833
     * @param int $h
834
     * @param string $resolution
835
     */
836
    public function image($img, $x, $y, $w, $h, $resolution = "normal")
837
    {
838
        list($width, $height, $type) = Helpers::dompdf_getimagesize($img, $this->get_dompdf()->getHttpContext());
839
840
        $debug_png = $this->_dompdf->getOptions()->getDebugPng();
841
842
        if ($debug_png) {
843
            print "[image:$img|$width|$height|$type]";
844
        }
845
846
        switch ($type) {
847 View Code Duplication
            case "jpeg":
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
848
                if ($debug_png) {
849
                    print '!!!jpg!!!';
850
                }
851
                $this->_pdf->addJpegFromFile($img, $x, $this->y($y) - $h, $w, $h);
0 ignored issues
show
Bug introduced by
The method addJpegFromFile() does not seem to exist on object<Dompdf\Adapter\CPDF>.

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...
852
                break;
853
854
            case "gif":
0 ignored issues
show
Coding Style introduced by
There must be a comment when fall-through is intentional in a non-empty case body
Loading history...
855
            /** @noinspection PhpMissingBreakStatementInspection */
856
            case "bmp":
0 ignored issues
show
Coding Style introduced by
There must be a comment when fall-through is intentional in a non-empty case body
Loading history...
857
                if ($debug_png) print '!!!bmp or gif!!!';
858
                // @todo use cache for BMP and GIF
859
                $img = $this->_convert_gif_bmp_to_png($img, $type);
860
861 View Code Duplication
            case "png":
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
862
                if ($debug_png) print '!!!png!!!';
863
864
                $this->_pdf->addPngFromFile($img, $x, $this->y($y) - $h, $w, $h);
0 ignored issues
show
Bug introduced by
The method addPngFromFile() does not seem to exist on object<Dompdf\Adapter\CPDF>.

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...
865
                break;
866
867 View Code Duplication
            case "svg":
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
868
                if ($debug_png) print '!!!SVG!!!';
869
870
                $this->_pdf->addSvgFromFile($img, $x, $this->y($y) - $h, $w, $h);
0 ignored issues
show
Bug introduced by
The method addSvgFromFile() does not seem to exist on object<Dompdf\Adapter\CPDF>.

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...
871
                break;
872
873
            default:
874
                if ($debug_png) print '!!!unknown!!!';
875
        }
876
    }
877
878
    /**
879
     * @param float $x
880
     * @param float $y
881
     * @param string $text
882
     * @param string $font
883
     * @param float $size
884
     * @param array $color
885
     * @param float $word_space
886
     * @param float $char_space
887
     * @param float $angle
888
     */
889
    public function text($x, $y, $text, $font, $size, $color = array(0, 0, 0), $word_space = 0.0, $char_space = 0.0, $angle = 0.0)
890
    {
891
        $pdf = $this->_pdf;
892
893
        $this->_set_fill_color($color);
894
895
        $font .= ".afm";
896
        $pdf->selectFont($font);
0 ignored issues
show
Bug introduced by
The method selectFont() does not seem to exist on object<Dompdf\Adapter\CPDF>.

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...
897
898
        //FontMetrics::getFontHeight($font, $size) ==
0 ignored issues
show
Unused Code Comprehensibility introduced by
55% of this comment could be valid code. Did you maybe forget this after debugging?

Sometimes obsolete code just ends up commented out instead of removed. In this case it is better to remove the code once you have checked you do not need it.

The code might also have been commented out for debugging purposes. In this case it is vital that someone uncomments it again or your project may behave in very unexpected ways in production.

This check looks for comments that seem to be mostly valid code and reports them.

Loading history...
899
        //$this->getFontHeight($font, $size) ==
0 ignored issues
show
Unused Code Comprehensibility introduced by
64% of this comment could be valid code. Did you maybe forget this after debugging?

Sometimes obsolete code just ends up commented out instead of removed. In this case it is better to remove the code once you have checked you do not need it.

The code might also have been commented out for debugging purposes. In this case it is vital that someone uncomments it again or your project may behave in very unexpected ways in production.

This check looks for comments that seem to be mostly valid code and reports them.

Loading history...
900
        //$this->_pdf->selectFont($font),$this->_pdf->getFontHeight($size)
0 ignored issues
show
Unused Code Comprehensibility introduced by
77% of this comment could be valid code. Did you maybe forget this after debugging?

Sometimes obsolete code just ends up commented out instead of removed. In this case it is better to remove the code once you have checked you do not need it.

The code might also have been commented out for debugging purposes. In this case it is vital that someone uncomments it again or your project may behave in very unexpected ways in production.

This check looks for comments that seem to be mostly valid code and reports them.

Loading history...
901
        //- FontBBoxheight+FontHeightOffset, scaled to $size, in pt
902
        //$this->_pdf->getFontDescender($size)
0 ignored issues
show
Unused Code Comprehensibility introduced by
75% of this comment could be valid code. Did you maybe forget this after debugging?

Sometimes obsolete code just ends up commented out instead of removed. In this case it is better to remove the code once you have checked you do not need it.

The code might also have been commented out for debugging purposes. In this case it is vital that someone uncomments it again or your project may behave in very unexpected ways in production.

This check looks for comments that seem to be mostly valid code and reports them.

Loading history...
903
        //- Descender scaled to size
904
        //
905
        //$this->_pdf->fonts[$this->_pdf->currentFont] sizes:
0 ignored issues
show
Unused Code Comprehensibility introduced by
58% of this comment could be valid code. Did you maybe forget this after debugging?

Sometimes obsolete code just ends up commented out instead of removed. In this case it is better to remove the code once you have checked you do not need it.

The code might also have been commented out for debugging purposes. In this case it is vital that someone uncomments it again or your project may behave in very unexpected ways in production.

This check looks for comments that seem to be mostly valid code and reports them.

Loading history...
906
        //['FontBBox'][0] left, ['FontBBox'][1] bottom, ['FontBBox'][2] right, ['FontBBox'][3] top
0 ignored issues
show
Unused Code Comprehensibility introduced by
72% of this comment could be valid code. Did you maybe forget this after debugging?

Sometimes obsolete code just ends up commented out instead of removed. In this case it is better to remove the code once you have checked you do not need it.

The code might also have been commented out for debugging purposes. In this case it is vital that someone uncomments it again or your project may behave in very unexpected ways in production.

This check looks for comments that seem to be mostly valid code and reports them.

Loading history...
907
        //Maximum extent of all glyphs of the font from the baseline point
908
        //['Ascender'] maximum height above baseline except accents
909
        //['Descender'] maximum depth below baseline, negative number means below baseline
910
        //['FontHeightOffset'] manual enhancement of .afm files to trim windows fonts. currently not used.
911
        //Values are in 1/1000 pt for a font size of 1 pt
912
        //
913
        //['FontBBox'][1] should be close to ['Descender']
0 ignored issues
show
Unused Code Comprehensibility introduced by
50% of this comment could be valid code. Did you maybe forget this after debugging?

Sometimes obsolete code just ends up commented out instead of removed. In this case it is better to remove the code once you have checked you do not need it.

The code might also have been commented out for debugging purposes. In this case it is vital that someone uncomments it again or your project may behave in very unexpected ways in production.

This check looks for comments that seem to be mostly valid code and reports them.

Loading history...
914
        //['FontBBox'][3] should be close to ['Ascender']+Accents
0 ignored issues
show
Unused Code Comprehensibility introduced by
45% of this comment could be valid code. Did you maybe forget this after debugging?

Sometimes obsolete code just ends up commented out instead of removed. In this case it is better to remove the code once you have checked you do not need it.

The code might also have been commented out for debugging purposes. In this case it is vital that someone uncomments it again or your project may behave in very unexpected ways in production.

This check looks for comments that seem to be mostly valid code and reports them.

Loading history...
915
        //in practice, FontBBox values are a little bigger
916
        //
917
        //The text position is referenced to the baseline, not to the lower corner of the FontBBox,
918
        //for what the left,top corner is given.
919
        //FontBBox spans also the background box for the text.
920
        //If the lower corner would be used as reference point, the Descents of the glyphs would
921
        //hang over the background box border.
922
        //Therefore compensate only the extent above the Baseline.
923
        //
924
        //print '<pre>['.$font.','.$size.','.$pdf->getFontHeight($size).','.$pdf->getFontDescender($size).','.$pdf->fonts[$pdf->currentFont]['FontBBox'][3].','.$pdf->fonts[$pdf->currentFont]['FontBBox'][1].','.$pdf->fonts[$pdf->currentFont]['FontHeightOffset'].','.$pdf->fonts[$pdf->currentFont]['Ascender'].','.$pdf->fonts[$pdf->currentFont]['Descender'].']</pre>';
0 ignored issues
show
Unused Code Comprehensibility introduced by
71% of this comment could be valid code. Did you maybe forget this after debugging?

Sometimes obsolete code just ends up commented out instead of removed. In this case it is better to remove the code once you have checked you do not need it.

The code might also have been commented out for debugging purposes. In this case it is vital that someone uncomments it again or your project may behave in very unexpected ways in production.

This check looks for comments that seem to be mostly valid code and reports them.

Loading history...
925
        //
926
        //$pdf->addText($x, $this->y($y) - ($pdf->fonts[$pdf->currentFont]['FontBBox'][3]*$size)/1000, $size, $text, $angle, $word_space, $char_space);
0 ignored issues
show
Unused Code Comprehensibility introduced by
72% of this comment could be valid code. Did you maybe forget this after debugging?

Sometimes obsolete code just ends up commented out instead of removed. In this case it is better to remove the code once you have checked you do not need it.

The code might also have been commented out for debugging purposes. In this case it is vital that someone uncomments it again or your project may behave in very unexpected ways in production.

This check looks for comments that seem to be mostly valid code and reports them.

Loading history...
927
        $pdf->addText($x, $this->y($y) - $pdf->getFontHeight($size), $size, $text, $angle, $word_space, $char_space);
0 ignored issues
show
Bug introduced by
The method getFontHeight() does not seem to exist on object<Dompdf\Adapter\CPDF>.

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...
Bug introduced by
The method addText() does not seem to exist on object<Dompdf\Adapter\CPDF>.

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...
928
929
        $this->_set_fill_transparency("Normal", $this->_current_opacity);
930
    }
931
932
    /**
933
     * @param string $code
934
     */
935
    public function javascript($code)
936
    {
937
        $this->_pdf->addJavascript($code);
0 ignored issues
show
Bug introduced by
The method addJavascript() does not exist on Dompdf\Adapter\CPDF. Did you maybe mean javascript()?

This check marks calls to methods that do not seem to exist on an object.

This is most likely the result of a method being renamed without all references to it being renamed likewise.

Loading history...
938
    }
939
940
    //........................................................................
0 ignored issues
show
Unused Code Comprehensibility introduced by
100% of this comment could be valid code. Did you maybe forget this after debugging?

Sometimes obsolete code just ends up commented out instead of removed. In this case it is better to remove the code once you have checked you do not need it.

The code might also have been commented out for debugging purposes. In this case it is vital that someone uncomments it again or your project may behave in very unexpected ways in production.

This check looks for comments that seem to be mostly valid code and reports them.

Loading history...
941
942
    /**
943
     * Add a named destination (similar to <a name="foo">...</a> in html)
944
     *
945
     * @param string $anchorname The name of the named destination
946
     */
947
    public function add_named_dest($anchorname)
948
    {
949
        $this->_pdf->addDestination($anchorname, "Fit");
0 ignored issues
show
Bug introduced by
The method addDestination() does not seem to exist on object<Dompdf\Adapter\CPDF>.

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...
950
    }
951
952
    /**
953
     * Add a link to the pdf
954
     *
955
     * @param string $url The url to link to
956
     * @param float $x The x position of the link
957
     * @param float $y The y position of the link
958
     * @param float $width The width of the link
959
     * @param float $height The height of the link
960
     */
961
    public function add_link($url, $x, $y, $width, $height)
962
    {
963
        $y = $this->y($y) - $height;
964
965
        if (strpos($url, '#') === 0) {
966
            // Local link
967
            $name = substr($url, 1);
968
            if ($name) {
969
                $this->_pdf->addInternalLink($name, $x, $y, $x + $width, $y + $height);
0 ignored issues
show
Bug introduced by
The method addInternalLink() does not seem to exist on object<Dompdf\Adapter\CPDF>.

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...
970
            }
971
        } else {
972
            $this->_pdf->addLink(rawurldecode($url), $x, $y, $x + $width, $y + $height);
0 ignored issues
show
Bug introduced by
The method addLink() does not seem to exist on object<Dompdf\Adapter\CPDF>.

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...
973
        }
974
    }
975
976
    /**
977
     * @param string $text
978
     * @param string $font
979
     * @param float $size
980
     * @param int $word_spacing
981
     * @param int $char_spacing
982
     * @return float|int
983
     */
984
    public function get_text_width($text, $font, $size, $word_spacing = 0, $char_spacing = 0)
985
    {
986
        $this->_pdf->selectFont($font);
0 ignored issues
show
Bug introduced by
The method selectFont() does not seem to exist on object<Dompdf\Adapter\CPDF>.

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...
987
        return $this->_pdf->getTextWidth($size, $text, $word_spacing, $char_spacing);
0 ignored issues
show
Bug introduced by
The method getTextWidth() does not seem to exist on object<Dompdf\Adapter\CPDF>.

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...
988
    }
989
990
    /**
991
     * @param $font
992
     * @param $string
993
     */
994
    public function register_string_subset($font, $string)
995
    {
996
        $this->_pdf->registerText($font, $string);
0 ignored issues
show
Bug introduced by
The method registerText() does not seem to exist on object<Dompdf\Adapter\CPDF>.

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...
997
    }
998
999
    /**
1000
     * @param string $font
1001
     * @param float $size
1002
     * @return float|int
1003
     */
1004
    public function get_font_height($font, $size)
1005
    {
1006
        $this->_pdf->selectFont($font);
0 ignored issues
show
Bug introduced by
The method selectFont() does not seem to exist on object<Dompdf\Adapter\CPDF>.

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...
1007
1008
        $ratio = $this->_dompdf->getOptions()->getFontHeightRatio();
1009
        return $this->_pdf->getFontHeight($size) * $ratio;
0 ignored issues
show
Bug introduced by
The method getFontHeight() does not seem to exist on object<Dompdf\Adapter\CPDF>.

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...
1010
    }
1011
1012
    /*function get_font_x_height($font, $size) {
0 ignored issues
show
Unused Code Comprehensibility introduced by
61% of this comment could be valid code. Did you maybe forget this after debugging?

Sometimes obsolete code just ends up commented out instead of removed. In this case it is better to remove the code once you have checked you do not need it.

The code might also have been commented out for debugging purposes. In this case it is vital that someone uncomments it again or your project may behave in very unexpected ways in production.

This check looks for comments that seem to be mostly valid code and reports them.

Loading history...
1013
      $this->_pdf->selectFont($font);
1014
      $ratio = $this->_dompdf->getOptions()->getFontHeightRatio();
1015
      return $this->_pdf->getFontXHeight($size) * $ratio;
1016
    }*/
1017
1018
    /**
1019
     * @param string $font
1020
     * @param float $size
1021
     * @return float
1022
     */
1023
    public function get_font_baseline($font, $size)
1024
    {
1025
        $ratio = $this->_dompdf->getOptions()->getFontHeightRatio();
1026
        return $this->get_font_height($font, $size) / $ratio;
1027
    }
1028
1029
    /**
1030
     * Writes text at the specified x and y coordinates on every page
1031
     *
1032
     * The strings '{PAGE_NUM}' and '{PAGE_COUNT}' are automatically replaced
1033
     * with their current values.
1034
     *
1035
     * See {@link Style::munge_color()} for the format of the colour array.
1036
     *
1037
     * @param float $x
1038
     * @param float $y
1039
     * @param string $text the text to write
1040
     * @param string $font the font file to use
1041
     * @param float $size the font size, in points
1042
     * @param array $color
1043
     * @param float $word_space word spacing adjustment
1044
     * @param float $char_space char spacing adjustment
1045
     * @param float $angle angle to write the text at, measured CW starting from the x-axis
1046
     */
1047
    public function page_text($x, $y, $text, $font, $size, $color = array(0, 0, 0), $word_space = 0.0, $char_space = 0.0, $angle = 0.0)
1048
    {
1049
        $_t = "text";
1050
        $this->_page_text[] = compact("_t", "x", "y", "text", "font", "size", "color", "word_space", "char_space", "angle");
1051
    }
1052
1053
    /**
1054
     * Processes a script on every page
1055
     *
1056
     * The variables $pdf, $PAGE_NUM, and $PAGE_COUNT are available.
1057
     *
1058
     * This function can be used to add page numbers to all pages
1059
     * after the first one, for example.
1060
     *
1061
     * @param string $code the script code
1062
     * @param string $type the language type for script
1063
     */
1064
    public function page_script($code, $type = "text/php")
1065
    {
1066
        $_t = "script";
1067
        $this->_page_text[] = compact("_t", "code", "type");
1068
    }
1069
1070
    /**
1071
     * @return int
1072
     */
1073
    public function new_page()
1074
    {
1075
        $this->_page_number++;
1076
        $this->_page_count++;
1077
1078
        $ret = $this->_pdf->newPage();
0 ignored issues
show
Bug introduced by
The method newPage() does not seem to exist on object<Dompdf\Adapter\CPDF>.

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...
1079
        $this->_pages[] = $ret;
1080
        return $ret;
1081
    }
1082
1083
    /**
1084
     * Add text to each page after rendering is complete
1085
     */
1086
    protected function _add_page_text()
1087
    {
1088
        if (!count($this->_page_text)) {
1089
            return;
1090
        }
1091
1092
        $page_number = 1;
1093
        $eval = null;
1094
1095
        foreach ($this->_pages as $pid) {
1096
            $this->reopen_object($pid);
1097
1098 View Code Duplication
            foreach ($this->_page_text as $pt) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
1099
                extract($pt);
1100
1101
                switch ($_t) {
1102
                    case "text":
1103
                        $text = str_replace(array("{PAGE_NUM}", "{PAGE_COUNT}"),
1104
                            array($page_number, $this->_page_count), $text);
1105
                        $this->text($x, $y, $text, $font, $size, $color, $word_space, $char_space, $angle);
1106
                        break;
1107
1108
                    case "script":
1109
                        if (!$eval) {
1110
                            $eval = new PhpEvaluator($this);
1111
                        }
1112
                        $eval->evaluate($code, array('PAGE_NUM' => $page_number, 'PAGE_COUNT' => $this->_page_count));
1113
                        break;
1114
1115
                    case 'line':
1116
                        $this->line( $x1, $y1, $x2, $y2, $color, $width, $style );
1117
                        break;
1118
                }
1119
            }
1120
1121
            $this->close_object();
1122
            $page_number++;
1123
        }
1124
    }
1125
1126
    /**
1127
     * Streams the PDF to the client.
1128
     *
1129
     * @param string $filename The filename to present to the client.
1130
     * @param array $options Associative array: 'compress' => 1 or 0 (default 1); 'Attachment' => 1 or 0 (default 1).
1131
     */
1132
    public function stream($filename = "document.pdf", $options = array())
1133
    {
1134
        if (headers_sent()) {
1135
            die("Unable to stream pdf: headers already sent");
0 ignored issues
show
Coding Style Compatibility introduced by
The method stream() contains an exit expression.

An exit expression should only be used in rare cases. For example, if you write a short command line script.

In most cases however, using an exit expression makes the code untestable and often causes incompatibilities with other libraries. Thus, unless you are absolutely sure it is required here, we recommend to refactor your code to avoid its usage.

Loading history...
1136
        }
1137
1138
        if (!isset($options["compress"])) $options["compress"] = true;
1139
        if (!isset($options["Attachment"])) $options["Attachment"] = true;
1140
1141
        $this->_add_page_text();
1142
1143
        $debug = !$options['compress'];
1144
        $tmp = ltrim($this->_pdf->output($debug));
0 ignored issues
show
Documentation introduced by
$debug is of type boolean, but the function expects a array.

It seems like the type of the argument is not accepted by the function/method which you are calling.

In some cases, in particular if PHP’s automatic type-juggling kicks in this might be fine. In other cases, however this might be a bug.

We suggest to add an explicit type cast like in the following example:

function acceptsInteger($int) { }

$x = '123'; // string "123"

// Instead of
acceptsInteger($x);

// we recommend to use
acceptsInteger((integer) $x);
Loading history...
1145
1146
        header("Cache-Control: private");
1147
        header("Content-Type: application/pdf");
1148
        header("Content-Length: " . mb_strlen($tmp, "8bit"));
1149
1150
        $filename = str_replace(array("\n", "'"), "", basename($filename, ".pdf")) . ".pdf";
1151
        $attachment = $options["Attachment"] ? "attachment" : "inline";
1152
        header(Helpers::buildContentDispositionHeader($attachment, $filename));
1153
1154
        echo $tmp;
1155
        flush();
1156
    }
1157
1158
    /**
1159
     * Returns the PDF as a string.
1160
     *
1161
     * @param array $options Associative array: 'compress' => 1 or 0 (default 1).
1162
     * @return string
1163
     */
1164
    public function output($options = array())
1165
    {
1166
        if (!isset($options["compress"])) $options["compress"] = true;
1167
1168
        $this->_add_page_text();
1169
1170
        $debug = !$options['compress'];
1171
1172
        return $this->_pdf->output($debug);
0 ignored issues
show
Documentation introduced by
$debug is of type boolean, but the function expects a array.

It seems like the type of the argument is not accepted by the function/method which you are calling.

In some cases, in particular if PHP’s automatic type-juggling kicks in this might be fine. In other cases, however this might be a bug.

We suggest to add an explicit type cast like in the following example:

function acceptsInteger($int) { }

$x = '123'; // string "123"

// Instead of
acceptsInteger($x);

// we recommend to use
acceptsInteger((integer) $x);
Loading history...
1173
    }
1174
1175
    /**
1176
     * Returns logging messages generated by the Cpdf class
1177
     *
1178
     * @return string
1179
     */
1180
    public function get_messages()
1181
    {
1182
        return $this->_pdf->messages;
0 ignored issues
show
Bug introduced by
The property messages does not exist. Did you maybe forget to declare it?

In PHP it is possible to write to properties without declaring them. For example, the following is perfectly valid PHP code:

class MyClass { }

$x = new MyClass();
$x->foo = true;

Generally, it is a good practice to explictly declare properties to avoid accidental typos and provide IDE auto-completion:

class MyClass {
    public $foo;
}

$x = new MyClass();
$x->foo = true;
Loading history...
1183
    }
1184
}
1185