1<?php
2
3namespace Mpdf\Tag;
4
5use Mpdf\Mpdf;
6use Mpdf\Utils\UtfString;
7
8class Input extends Tag
9{
10
11	public function open($attr, &$ahtml, &$ihtml)
12	{
13		$tag = $this->getTagName();
14		$this->mpdf->ignorefollowingspaces = false;
15		if (!isset($attr['TYPE'])) {
16			$attr['TYPE'] = 'TEXT';
17		}
18		$objattr = [];
19		$objattr['margin_top'] = 0;
20		$objattr['margin_bottom'] = 0;
21		$objattr['margin_left'] = 0;
22		$objattr['margin_right'] = 0;
23		$objattr['width'] = 0;
24		$objattr['height'] = 0;
25		$objattr['border_top']['w'] = 0;
26		$objattr['border_bottom']['w'] = 0;
27		$objattr['border_left']['w'] = 0;
28		$objattr['border_right']['w'] = 0;
29		$objattr['type'] = 'input';
30		if (isset($attr['DISABLED'])) {
31			$objattr['disabled'] = true;
32		}
33		if (isset($attr['READONLY'])) {
34			$objattr['readonly'] = true;
35		}
36		if (isset($attr['REQUIRED'])) {
37			$objattr['required'] = true;
38		}
39		if (isset($attr['SPELLCHECK']) && strtolower($attr['SPELLCHECK']) === 'true') {
40			$objattr['spellcheck'] = true;
41		}
42		if (isset($attr['TITLE'])) {
43			$objattr['title'] = $attr['TITLE'];
44		} elseif (isset($attr['ALT'])) {
45			$objattr['title'] = $attr['ALT'];
46		} else {
47			$objattr['title'] = '';
48		}
49		$objattr['title'] = UtfString::strcode2utf($objattr['title']);
50		$objattr['title'] = $this->mpdf->lesser_entity_decode($objattr['title']);
51		if ($this->mpdf->onlyCoreFonts) {
52			$objattr['title'] = mb_convert_encoding($objattr['title'], $this->mpdf->mb_enc, 'UTF-8');
53		}
54		if ($this->mpdf->useActiveForms && isset($attr['NAME'])) {
55			$objattr['fieldname'] = $attr['NAME'];
56		}
57		if (isset($attr['VALUE'])) {
58			$attr['VALUE'] = UtfString::strcode2utf($attr['VALUE']);
59			$attr['VALUE'] = $this->mpdf->lesser_entity_decode($attr['VALUE']);
60			if ($this->mpdf->onlyCoreFonts) {
61				$attr['VALUE'] = mb_convert_encoding($attr['VALUE'], $this->mpdf->mb_enc, 'UTF-8');
62			}
63			$objattr['value'] = $attr['VALUE'];
64		}
65
66		$this->mpdf->InlineProperties['INPUT'] = $this->mpdf->saveInlineProperties();
67		$properties = $this->cssManager->MergeCSS('', 'INPUT', $attr);
68		$objattr['vertical-align'] = '';
69
70		if (isset($properties['FONT-FAMILY'])) {
71			$this->mpdf->SetFont($properties['FONT-FAMILY'], $this->mpdf->FontStyle, 0, false);
72		}
73		if (isset($properties['FONT-SIZE'])) {
74			$mmsize = $this->sizeConverter->convert($properties['FONT-SIZE'], $this->mpdf->default_font_size / Mpdf::SCALE);
75			$this->mpdf->SetFontSize($mmsize * Mpdf::SCALE, false);
76		}
77		if (isset($properties['COLOR'])) {
78			$objattr['color'] = $this->colorConverter->convert($properties['COLOR'], $this->mpdf->PDFAXwarnings);
79		}
80		$objattr['fontfamily'] = $this->mpdf->FontFamily;
81		$objattr['fontsize'] = $this->mpdf->FontSizePt;
82		if ($this->mpdf->useActiveForms) {
83			if (isset($attr['ALIGN'])) {
84				$objattr['text_align'] = $this->getAlign($attr['ALIGN']);
85			} elseif (isset($properties['TEXT-ALIGN'])) {
86				$objattr['text_align'] = $this->getAlign($properties['TEXT-ALIGN']);
87			}
88			if (isset($properties['BORDER-TOP-COLOR'])) {
89				$objattr['border-col'] = $this->colorConverter->convert($properties['BORDER-TOP-COLOR'], $this->mpdf->PDFAXwarnings);
90			}
91			if (isset($properties['BACKGROUND-COLOR'])) {
92				$objattr['background-col'] = $this->colorConverter->convert($properties['BACKGROUND-COLOR'], $this->mpdf->PDFAXwarnings);
93			}
94		}
95
96		$type = '';
97		$texto = '';
98		$height = $this->mpdf->FontSize;
99		$width = 0;
100		$spacesize = $this->mpdf->GetCharWidth(' ', false);
101
102		$w = 0;
103		if (isset($properties['WIDTH'])) {
104			$w = $this->sizeConverter->convert($properties['WIDTH'], $this->mpdf->blk[$this->mpdf->blklvl]['inner_width']);
105		}
106
107		if ($properties['VERTICAL-ALIGN']) {
108			$objattr['vertical-align'] = $this->getAlign($properties['VERTICAL-ALIGN']);
109		}
110
111		switch (strtoupper($attr['TYPE'])) {
112			case 'HIDDEN':
113				$this->mpdf->ignorefollowingspaces = true; //Eliminate exceeding left-side spaces
114				if ($this->mpdf->useActiveForms) {
115					$this->form->SetFormText(0, 0, $objattr['fieldname'], $objattr['value'], $objattr['value'], '', 0, '', true);
116				}
117				if ($this->mpdf->InlineProperties[$tag]) {
118					$this->mpdf->restoreInlineProperties($this->mpdf->InlineProperties[$tag]);
119				}
120				unset($this->mpdf->InlineProperties[$tag]);
121				return;
122
123			case 'CHECKBOX': //Draw Checkbox
124				$type = 'CHECKBOX';
125				if (isset($attr['CHECKED'])) {
126					$objattr['checked'] = true;
127				} else {
128					$objattr['checked'] = false;
129				}
130				$width = $this->mpdf->FontSize;
131				$height = $this->mpdf->FontSize;
132				break;
133
134			case 'RADIO': //Draw Radio button
135				$type = 'RADIO';
136				if (isset($attr['CHECKED'])) {
137					$objattr['checked'] = true;
138				}
139				$width = $this->mpdf->FontSize;
140				$height = $this->mpdf->FontSize;
141				break;
142
143			/* -- IMAGES-CORE -- */
144			case 'IMAGE': // Draw an Image button
145				if (isset($attr['SRC'])) {
146					$type = 'IMAGE';
147					$srcpath = $attr['SRC'];
148					$orig_srcpath = $attr['ORIG_SRC'];
149					// VSPACE and HSPACE converted to margins in MergeCSS
150					if (isset($properties['MARGIN-TOP'])) {
151						$objattr['margin_top'] = $this->sizeConverter->convert(
152							$properties['MARGIN-TOP'],
153							$this->mpdf->blk[$this->mpdf->blklvl]['inner_width'],
154							$this->mpdf->FontSize,
155							false
156						);
157					}
158					if (isset($properties['MARGIN-BOTTOM'])) {
159						$objattr['margin_bottom'] = $this->sizeConverter->convert(
160							$properties['MARGIN-BOTTOM'],
161							$this->mpdf->blk[$this->mpdf->blklvl]['inner_width'],
162							$this->mpdf->FontSize,
163							false
164						);
165					}
166					if (isset($properties['MARGIN-LEFT'])) {
167						$objattr['margin_left'] = $this->sizeConverter->convert(
168							$properties['MARGIN-LEFT'],
169							$this->mpdf->blk[$this->mpdf->blklvl]['inner_width'],
170							$this->mpdf->FontSize,
171							false
172						);
173					}
174					if (isset($properties['MARGIN-RIGHT'])) {
175						$objattr['margin_right'] = $this->sizeConverter->convert(
176							$properties['MARGIN-RIGHT'],
177							$this->mpdf->blk[$this->mpdf->blklvl]['inner_width'],
178							$this->mpdf->FontSize,
179							false
180						);
181					}
182
183					if (isset($properties['BORDER-TOP'])) {
184						$objattr['border_top'] = $this->mpdf->border_details($properties['BORDER-TOP']);
185					}
186					if (isset($properties['BORDER-BOTTOM'])) {
187						$objattr['border_bottom'] = $this->mpdf->border_details($properties['BORDER-BOTTOM']);
188					}
189					if (isset($properties['BORDER-LEFT'])) {
190						$objattr['border_left'] = $this->mpdf->border_details($properties['BORDER-LEFT']);
191					}
192					if (isset($properties['BORDER-RIGHT'])) {
193						$objattr['border_right'] = $this->mpdf->border_details($properties['BORDER-RIGHT']);
194					}
195
196					$objattr['padding_top'] = 0;
197					$objattr['padding_bottom'] = 0;
198					$objattr['padding_left'] = 0;
199					$objattr['padding_right'] = 0;
200
201					if (isset($properties['VERTICAL-ALIGN'])) {
202						$objattr['vertical-align'] = $this->getAlign($properties['VERTICAL-ALIGN']);
203					}
204
205					$w = 0;
206					$h = 0;
207					if (isset($properties['WIDTH'])) {
208						$w = $this->sizeConverter->convert($properties['WIDTH'], $this->mpdf->blk[$this->mpdf->blklvl]['inner_width']);
209					}
210					if (isset($properties['HEIGHT'])) {
211						$h = $this->sizeConverter->convert($properties['HEIGHT'], $this->mpdf->blk[$this->mpdf->blklvl]['inner_width']);
212					}
213
214					$extraheight = $objattr['margin_top'] + $objattr['margin_bottom'] + $objattr['border_top']['w'] + $objattr['border_bottom']['w'];
215					$extrawidth = $objattr['margin_left'] + $objattr['margin_right'] + $objattr['border_left']['w'] + $objattr['border_right']['w'];
216
217					// Image file
218					$info = $this->imageProcessor->getImage($srcpath, true, true, $orig_srcpath);
219					if (!$info) {
220						$info = $this->imageProcessor->getImage($this->mpdf->noImageFile);
221						if ($info) {
222							$srcpath = $this->mpdf->noImageFile;
223							$w = ($info['w'] * (25.4 / $this->mpdf->img_dpi));
224							$h = ($info['h'] * (25.4 / $this->mpdf->img_dpi));
225						}
226					}
227					if (!$info) {
228						break;
229					}
230					if ($info['cs'] === 'Indexed') {
231						$objattr['Indexed'] = true;
232					}
233					$objattr['file'] = $srcpath;
234					//Default width and height calculation if needed
235					if ($w == 0 && $h == 0) {
236						/* -- IMAGES-WMF -- */
237						if ($info['type'] === 'wmf') {
238							// WMF units are twips (1/20pt)
239							// divide by 20 to get points
240							// divide by k to get user units
241							$w = abs($info['w']) / (20 * Mpdf::SCALE);
242							$h = abs($info['h']) / (20 * Mpdf::SCALE);
243						} else { 									/* -- END IMAGES-WMF -- */
244							if ($info['type'] === 'svg') {
245								// SVG units are pixels
246								$w = abs($info['w']) / Mpdf::SCALE;
247								$h = abs($info['h']) / Mpdf::SCALE;
248							} else {
249								//Put image at default image dpi
250								$w = ($info['w'] / Mpdf::SCALE) * (72 / $this->mpdf->img_dpi);
251								$h = ($info['h'] / Mpdf::SCALE) * (72 / $this->mpdf->img_dpi);
252							}
253						}
254						if (isset($properties['IMAGE-RESOLUTION'])) {
255							if (preg_match('/from-image/i', $properties['IMAGE-RESOLUTION']) && isset($info['set-dpi']) && $info['set-dpi'] > 0) {
256								$w *= $this->mpdf->img_dpi / $info['set-dpi'];
257								$h *= $this->mpdf->img_dpi / $info['set-dpi'];
258							} elseif (preg_match('/(\d+)dpi/i', $properties['IMAGE-RESOLUTION'], $m)) {
259								$dpi = $m[1];
260								if ($dpi > 0) {
261									$w *= $this->mpdf->img_dpi / $dpi;
262									$h *= $this->mpdf->img_dpi / $dpi;
263								}
264							}
265						}
266					}
267					// IF WIDTH OR HEIGHT SPECIFIED
268					if ($w == 0) {
269						$w = $h * $info['w'] / $info['h'];
270					}
271					if ($h == 0) {
272						$h = $w * $info['h'] / $info['w'];
273					}
274					// Resize to maximum dimensions of page
275					$maxWidth = $this->mpdf->blk[$this->mpdf->blklvl]['inner_width'];
276					$maxHeight = $this->mpdf->h - ($this->mpdf->tMargin + $this->mpdf->bMargin + 10);
277					if ($this->mpdf->fullImageHeight) {
278						$maxHeight = $this->mpdf->fullImageHeight;
279					}
280					if (($w + $extrawidth) > ($maxWidth + 0.0001)) { // mPDF 5.7.4  0.0001 to allow for rounding errors when w==maxWidth
281						$w = $maxWidth - $extrawidth;
282						$h = $w * $info['h'] / $info['w'];
283					}
284					if ($h + $extraheight > $maxHeight) {
285						$h = $maxHeight - $extraheight;
286						$w = $h * $info['w'] / $info['h'];
287					}
288					$height = $h + $extraheight;
289					$width = $w + $extrawidth;
290					$objattr['type'] = 'image';
291					$objattr['itype'] = $info['type'];
292					$objattr['orig_h'] = $info['h'];
293					$objattr['orig_w'] = $info['w'];
294					/* -- IMAGES-WMF -- */
295					if ($info['type'] === 'wmf') {
296						$objattr['wmf_x'] = $info['x'];
297						$objattr['wmf_y'] = $info['y'];
298						/* -- END IMAGES-WMF -- */
299					} else {
300						if ($info['type'] === 'svg') {
301							$objattr['wmf_x'] = $info['x'];
302							$objattr['wmf_y'] = $info['y'];
303						}
304					}
305					$objattr['height'] = $h + $extraheight;
306					$objattr['width'] = $w + $extrawidth;
307
308					$objattr['image_height'] = $h;
309					$objattr['image_width'] = $w;
310					$objattr['ID'] = $info['i'];
311					$texto = 'X';
312					if ($this->mpdf->useActiveForms) {
313						if (isset($attr['ONCLICK'])) {
314							$objattr['onClick'] = $attr['ONCLICK'];
315						}
316						$objattr['type'] = 'input';
317						$type = 'IMAGE';
318					}
319					break;
320				}
321			/* -- END IMAGES-CORE -- */
322
323			case 'BUTTON': // Draw a button
324			case 'SUBMIT':
325			case 'RESET':
326				$type = strtoupper($attr['TYPE']);
327				if ($type === 'IMAGE') {
328					$type = 'BUTTON';
329				} // src path not found
330				if (isset($attr['NOPRINT'])) {
331					$objattr['noprint'] = true;
332				}
333				if (!isset($attr['VALUE'])) {
334					$objattr['value'] = ucfirst(strtolower($type));
335				}
336
337				$texto = ' ' . $objattr['value'] . ' ';
338
339				$width = $this->mpdf->GetStringWidth($texto) + ($this->form->form_element_spacing['button']['outer']['h'] * 2)
340					+ ($this->form->form_element_spacing['button']['inner']['h'] * 2);
341
342				$height = $this->mpdf->FontSize + ($this->form->form_element_spacing['button']['outer']['v'] * 2)
343					+ ($this->form->form_element_spacing['button']['inner']['v'] * 2);
344
345				if ($this->mpdf->useActiveForms && isset($attr['ONCLICK'])) {
346					$objattr['onClick'] = $attr['ONCLICK'];
347				}
348				break;
349
350			case 'PASSWORD':
351			case 'TEXT':
352			default:
353				if ($type == '') {
354					$type = 'TEXT';
355				}
356				if (strtoupper($attr['TYPE']) === 'PASSWORD') {
357					$type = 'PASSWORD';
358				}
359				if (isset($attr['VALUE'])) {
360					if ($type === 'PASSWORD') {
361						$num_stars = mb_strlen($attr['VALUE'], $this->mpdf->mb_enc);
362						$texto = str_repeat('*', $num_stars);
363					} else {
364						$texto = $attr['VALUE'];
365					}
366				}
367				$xw = ($this->form->form_element_spacing['input']['outer']['h'] * 2) + ($this->form->form_element_spacing['input']['inner']['h'] * 2);
368				$xh = ($this->form->form_element_spacing['input']['outer']['v'] * 2) + ($this->form->form_element_spacing['input']['inner']['v'] * 2);
369				if ($w) {
370					$width = $w + $xw;
371				} else {
372					$width = (20 * $spacesize) + $xw;
373				} // Default width in chars
374				if (isset($attr['SIZE']) && ctype_digit($attr['SIZE'])) {
375					$width = ($attr['SIZE'] * $spacesize) + $xw;
376				}
377				$height = $this->mpdf->FontSize + $xh;
378				if (isset($attr['MAXLENGTH']) && ctype_digit($attr['MAXLENGTH'])) {
379					$objattr['maxlength'] = $attr['MAXLENGTH'];
380				}
381				if ($this->mpdf->useActiveForms) {
382					if (isset($attr['ONCALCULATE'])) {
383						$objattr['onCalculate'] = $attr['ONCALCULATE'];
384					} elseif (isset($attr['ONCHANGE'])) {
385						$objattr['onCalculate'] = $attr['ONCHANGE'];
386					}
387					if (isset($attr['ONVALIDATE'])) {
388						$objattr['onValidate'] = $attr['ONVALIDATE'];
389					}
390					if (isset($attr['ONKEYSTROKE'])) {
391						$objattr['onKeystroke'] = $attr['ONKEYSTROKE'];
392					}
393					if (isset($attr['ONFORMAT'])) {
394						$objattr['onFormat'] = $attr['ONFORMAT'];
395					}
396				}
397				break;
398		}
399
400		$objattr['subtype'] = $type;
401		$objattr['text'] = $texto;
402		$objattr['width'] = $width;
403		$objattr['height'] = $height;
404		$e = "\xbb\xa4\xactype=input,objattr=" . serialize($objattr) . "\xbb\xa4\xac";
405
406		/* -- TABLES -- */
407		// Output it to buffers
408		if ($this->mpdf->tableLevel) {
409			$this->mpdf->_saveCellTextBuffer($e, $this->mpdf->HREF);
410			$this->mpdf->cell[$this->mpdf->row][$this->mpdf->col]['s'] += $objattr['width'];
411		} else {
412			/* -- END TABLES -- */
413			$this->mpdf->_saveTextBuffer($e, $this->mpdf->HREF);
414		} // *TABLES*
415
416		if ($this->mpdf->InlineProperties[$tag]) {
417			$this->mpdf->restoreInlineProperties($this->mpdf->InlineProperties[$tag]);
418		}
419		unset($this->mpdf->InlineProperties[$tag]);
420	}
421
422	public function close(&$ahtml, &$ihtml)
423	{
424	}
425}
426