Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
100.00% covered (success)
100.00%
46 / 46
100.00% covered (success)
100.00%
9 / 9
CRAP
100.00% covered (success)
100.00%
1 / 1
Button
100.00% covered (success)
100.00%
46 / 46
100.00% covered (success)
100.00%
9 / 9
24
100.00% covered (success)
100.00%
1 / 1
 addOption
100.00% covered (success)
100.00%
6 / 6
100.00% covered (success)
100.00%
1 / 1
1
 hasOptions
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 setNoToggleToOff
100.00% covered (success)
100.00%
3 / 3
100.00% covered (success)
100.00%
1 / 1
2
 setRadio
100.00% covered (success)
100.00%
3 / 3
100.00% covered (success)
100.00%
1 / 1
2
 setPushButton
100.00% covered (success)
100.00%
3 / 3
100.00% covered (success)
100.00%
1 / 1
2
 setRadiosInUnison
100.00% covered (success)
100.00%
3 / 3
100.00% covered (success)
100.00%
1 / 1
2
 isRadio
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 isPushButton
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 getStream
100.00% covered (success)
100.00%
25 / 25
100.00% covered (success)
100.00%
1 / 1
12
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\Field;
16
17use Pop\Color\Color;
18
19/**
20 * Pdf page button field class
21 *
22 * @category   Pop
23 * @package    Pop\Pdf
24 * @author     Nick Sagona, III <nick@popphp.org>
25 * @copyright  Copyright (c) 2009-2026 Nick Sagona, III
26 * @license    https://www.popphp.org/license     New BSD License
27 * @version    6.0.0
28 */
29class Button extends AbstractField
30{
31
32    /**
33     * Field options
34     * @var array
35     */
36    protected array $options = [];
37
38    /**
39     * Add an option
40     *
41     * @param  string $option
42     * @param  int    $xOffset
43     * @param  int    $yOffset
44     * @return Button
45     */
46    public function addOption(string $option, int $xOffset = 0, int $yOffset = 0): Button
47    {
48        $this->options[] = [
49            'option'  => $option,
50            'xOffset' => $xOffset,
51            'yOffset' => $yOffset
52        ];
53
54        return $this;
55    }
56
57    /**
58     * Has options
59     *
60     * @return bool
61     */
62    public function hasOptions(): bool
63    {
64        return (count($this->options) > 0);
65    }
66
67    /**
68     * Set no toggle to off
69     *
70     * @return Button
71     */
72    public function setNoToggleToOff(): Button
73    {
74        if (!in_array(15, $this->flagBits)) {
75            $this->flagBits[] = 15;
76        }
77        return $this;
78    }
79
80    /**
81     * Set radio
82     *
83     * @return Button
84     */
85    public function setRadio(): Button
86    {
87        if (!in_array(16, $this->flagBits)) {
88            $this->flagBits[] = 16;
89        }
90        return $this;
91    }
92
93    /**
94     * Set push button
95     *
96     * @return Button
97     */
98    public function setPushButton(): Button
99    {
100        if (!in_array(17, $this->flagBits)) {
101            $this->flagBits[] = 17;
102        }
103        return $this;
104    }
105
106    /**
107     * Set radios in unison
108     *
109     * @return Button
110     */
111    public function setRadiosInUnison(): Button
112    {
113        if (!in_array(26, $this->flagBits)) {
114            $this->flagBits[] = 26;
115        }
116        return $this;
117    }
118
119    /**
120     * Is radio
121     *
122     * @return bool
123     */
124    public function isRadio(): bool
125    {
126        return in_array(16, $this->flagBits);
127    }
128
129    /**
130     * Is push button
131     *
132     * @return bool
133     */
134    public function isPushButton(): bool
135    {
136        return in_array(17, $this->flagBits);
137    }
138
139    /**
140     * Get the field stream
141     *
142     * @param  int     $i
143     * @param  int     $pageIndex
144     * @param  ?string $fontReference
145     * @param  int     $x
146     * @param  int     $y
147     * @return string
148     */
149    public function getStream(int $i, int $pageIndex, ?string $fontReference, int $x, int $y): string
150    {
151        $text    = null;
152        $options = null;
153        $color   = '0 g';
154
155        if ($this->fontColor !== null) {
156            if ($this->fontColor instanceof Color\Rgb) {
157                $color = $this->fontColor->render(Color\Rgb::PERCENT) . " rg";
158            } else if ($this->fontColor instanceof Color\Cmyk) {
159                $color = $this->fontColor->render(Color\Cmyk::PERCENT) . " k";
160            } else if ($this->fontColor instanceof Color\Grayscale) {
161                $color = $this->fontColor->render(Color\Grayscale::PERCENT) . " g";
162            }
163        }
164
165        if ($fontReference !== null) {
166            $fontReference = substr($fontReference, 0, strpos($fontReference, ' '));
167            $text          = '    /DA(' . $fontReference . ' ' . $this->size . ' Tf ' . $color . ')';
168        }
169
170        $name    = ($this->name !== null) ? '    /T(' . $this->name . ')/TU(' . $this->name . ')/TM(' . $this->name . ')' : '';
171        $flags   = (count($this->flagBits) > 0) ? "\n    /Ff " . $this->getFlags() . "\n" : null;
172        $value   = ($this->value !== null) ? "\n    /V " . $this->value . "\n" : null;
173        $default = ($this->defaultValue !== null) ? "\n    /DV " . $this->defaultValue . "\n" : null;
174
175        if (count($this->options) > 0) {
176            $options = "    /Opt [ ";
177            foreach ($this->options as $option) {
178                $options .= '(' . $option['option'] . ') ';
179            }
180            $options .= "]\n";
181        }
182
183        // Return the stream
184        return "{$i} 0 obj\n<<\n    /Type /Annot\n    /Subtype /Widget\n    /FT /Btn\n    /Rect [{$x} {$y} " .
185            ($this->width + $x) . " " . ($this->height + $y) . "]{$value}{$default}\n    /P {$pageIndex} 0 R\n" .
186            "    \n{$text}\n{$name}\n{$flags}\n{$options}>>\nendobj\n\n";
187    }
188
189}