Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
100.00% covered (success)
100.00%
46 / 46
100.00% covered (success)
100.00%
5 / 5
CRAP
100.00% covered (success)
100.00%
1 / 1
Alignment
100.00% covered (success)
100.00%
46 / 46
100.00% covered (success)
100.00%
5 / 5
15
100.00% covered (success)
100.00%
1 / 1
 createLeft
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 createRight
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 createCenter
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 getStrings
100.00% covered (success)
100.00%
42 / 42
100.00% covered (success)
100.00%
1 / 1
11
 isCenter
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
1<?php
2declare(strict_types=1);
3/**
4 * Pop PHP Framework (https://www.popphp.org/)
5 *
6 * @link       https://github.com/popphp/popphp-framework
7 * @author     Nick Sagona, III <nick@popphp.org>
8 * @copyright  Copyright (c) 2009-2026 Nick Sagona, III
9 * @license    https://www.popphp.org/license     New BSD License
10 */
11
12/**
13 * @namespace
14 */
15namespace Pop\Pdf\Document\Page\Text;
16
17use Pop\Pdf\Document\Exception;
18use Pop\Pdf\Document\Page;
19use Pop\Pdf\Document\Font;
20
21/**
22 * Pdf page text alignment class
23 *
24 * @category   Pop
25 * @package    Pop\Pdf
26 * @author     Nick Sagona, III <nick@popphp.org>
27 * @copyright  Copyright (c) 2009-2026 Nick Sagona, III
28 * @license    https://www.popphp.org/license     New BSD License
29 * @version    6.2.0
30 */
31class Alignment extends AbstractAlignment
32{
33
34    /**
35     * Alignment constants
36     */
37    const CENTER = 'CENTER';
38
39    /**
40     * Create LEFT alignment object
41     *
42     * @param int    $leftX
43     * @param int    $rightX
44     * @param int    $leading
45     * @return Alignment
46     */
47    public static function createLeft(int $leftX = 0, int $rightX = 0, int $leading = 0): Alignment
48    {
49        return new self(self::LEFT, $leftX, $rightX, $leading);
50    }
51
52    /**
53     * Create RIGHT alignment object
54     *
55     * @param int    $leftX
56     * @param int    $rightX
57     * @param int    $leading
58     * @return Alignment
59     */
60    public static function createRight(int $leftX = 0, int $rightX = 0, int $leading = 0): Alignment
61    {
62        return new self(self::RIGHT, $leftX, $rightX, $leading);
63    }
64
65    /**
66     * Create CENTER alignment object
67     *
68     * @param int    $leftX
69     * @param int    $rightX
70     * @param int    $leading
71     * @return Alignment
72     */
73    public static function createCenter(int $leftX = 0, int $rightX = 0, int $leading = 0): Alignment
74    {
75        return new self(self::CENTER, $leftX, $rightX, $leading);
76    }
77
78    /**
79     * Get strings
80     *
81     * @param  Page\Text $text
82     * @param  Font $font
83     * @param  int $startY
84     * @throws Exception
85     * @return array
86     */
87    public function getStrings(Page\Text $text, Font $font, int $startY): array
88    {
89        $strings    = [];
90        $curString  = '';
91        $curWidth   = 0;
92        // Split the raw (unescaped) string, not getString() - the fragments
93        // are handed back to fresh Text objects that escape them again on
94        // their own, so starting from an already-escaped string would
95        // double-escape backslashes/parens.
96        $words      = explode(' ', $text->getRawString());
97        $wrapLength = abs($this->rightX - $this->leftX);
98        $startX     = $this->leftX;
99        $size       = $text->getSize();
100        $spaceWidth = $font->getStringWidth(' ', $size);
101
102        if ((int)$this->leading == 0) {
103            $this->leading = $size;
104        }
105
106        foreach ($words as $word) {
107            $newString = ($curString != '') ? $curString . ' ' . $word : $word;
108            $wordWidth = $font->getStringWidth($word, $size);
109            $newWidth  = ($curString != '') ? ($curWidth + $spaceWidth + $wordWidth) : $wordWidth;
110
111            if ($newWidth <= $wrapLength) {
112                $curString = $newString;
113                $curWidth  = $newWidth;
114            } else {
115                if ($this->isRight()) {
116                    $x = $this->leftX + ($wrapLength - $curWidth);
117                } else if ($this->isCenter()) {
118                    $x = $this->leftX + (($wrapLength - $curWidth) / 2);
119                } else {
120                    $x = $startX;
121                }
122
123                $strings[] = [
124                    'string' => $curString,
125                    'x'      => $x,
126                    'y'      => $startY
127                ];
128                $curString = $word;
129                $curWidth  = $wordWidth;
130                $startY   -= $this->leading;
131            }
132        }
133
134        if (!empty($curString)) {
135            if ($this->isRight()) {
136                $x = $this->leftX + ($wrapLength - $curWidth);
137            } else if ($this->isCenter()) {
138                $x = $this->leftX + (($wrapLength - $curWidth) / 2);
139            } else {
140                $x = $startX;
141            }
142            $strings[] = [
143                'string' => $curString,
144                'x'      => $x,
145                'y'      => $startY
146            ];
147        }
148
149        return $strings;
150    }
151
152    /**
153     * Is CENTER alignment
154     *
155     * @return bool
156     */
157    public function isCenter(): bool
158    {
159        return ($this->alignment == self::CENTER);
160    }
161
162}