1<?php
2
3namespace Mpdf\Tag;
4
5use Mpdf\Utils\UtfString;
6
7abstract class InlineTag extends Tag
8{
9
10	public function open($attr, &$ahtml, &$ihtml)
11	{
12		$tag = $this->getTagName();
13
14		/* -- ANNOTATIONS -- */
15		if ($this->mpdf->title2annots && isset($attr['TITLE'])) {
16			$objattr = [];
17			$objattr['margin_top'] = 0;
18			$objattr['margin_bottom'] = 0;
19			$objattr['margin_left'] = 0;
20			$objattr['margin_right'] = 0;
21			$objattr['width'] = 0;
22			$objattr['height'] = 0;
23			$objattr['border_top']['w'] = 0;
24			$objattr['border_bottom']['w'] = 0;
25			$objattr['border_left']['w'] = 0;
26			$objattr['border_right']['w'] = 0;
27
28			$objattr['CONTENT'] = $attr['TITLE'];
29			$objattr['type'] = 'annot';
30			$objattr['POS-X'] = 0;
31			$objattr['POS-Y'] = 0;
32			$objattr['ICON'] = 'Comment';
33			$objattr['AUTHOR'] = '';
34			$objattr['SUBJECT'] = '';
35			$objattr['OPACITY'] = $this->mpdf->annotOpacity;
36			$objattr['COLOR'] = $this->colorConverter->convert('yellow', $this->mpdf->PDFAXwarnings);
37			$annot = "\xbb\xa4\xactype=annot,objattr=" . serialize($objattr) . "\xbb\xa4\xac";
38		}
39		/* -- END ANNOTATIONS -- */
40
41		// mPDF 5.7.3 Inline tags
42		if (!isset($this->mpdf->InlineProperties[$tag])) {
43			$this->mpdf->InlineProperties[$tag] = [$this->mpdf->saveInlineProperties()];
44		} else {
45			$this->mpdf->InlineProperties[$tag][] = $this->mpdf->saveInlineProperties();
46		}
47		if (isset($annot)) {  // *ANNOTATIONS*
48			if (!isset($this->mpdf->InlineAnnots[$tag])) {
49				$this->mpdf->InlineAnnots[$tag] = [];
50			} // *ANNOTATIONS*
51			$this->mpdf->InlineAnnots[$tag][] = $annot;
52		} // *ANNOTATIONS*
53
54		$properties = $this->cssManager->MergeCSS('INLINE', $tag, $attr);
55		if (!empty($properties)) {
56			$this->mpdf->setCSS($properties, 'INLINE');
57		}
58
59		// mPDF 6 Bidirectional formatting for inline elements
60		$bdf = false;
61		$bdf2 = '';
62		$popd = '';
63
64		// Get current direction
65		$currdir = 'ltr';
66		if (isset($this->mpdf->blk[$this->mpdf->blklvl]['direction'])) {
67			$currdir = $this->mpdf->blk[$this->mpdf->blklvl]['direction'];
68		}
69		if ($this->mpdf->tableLevel
70			&& isset($this->mpdf->cell[$this->mpdf->row][$this->mpdf->col]['direction'])
71			&& $this->mpdf->cell[$this->mpdf->row][$this->mpdf->col]['direction'] === 'rtl') {
72			$currdir = 'rtl';
73		}
74		if (isset($attr['DIR']) && $attr['DIR'] != '') {
75			$currdir = strtolower($attr['DIR']);
76		}
77		if (isset($properties['DIRECTION'])) {
78			$currdir = strtolower($properties['DIRECTION']);
79		}
80
81		// mPDF 6 bidi
82		// cf. http://www.w3.org/TR/css3-writing-modes/#unicode-bidi
83		if ($tag === 'BDO') {
84			if (isset($attr['DIR']) && strtolower($attr['DIR']) === 'rtl') {
85				$bdf = 0x202E;
86				$popd = 'RLOPDF';
87			} // U+202E RLO
88			elseif (isset($attr['DIR']) && strtolower($attr['DIR']) === 'ltr') {
89				$bdf = 0x202D;
90				$popd = 'LROPDF';
91			} // U+202D LRO
92		} elseif ($tag === 'BDI') {
93			if (isset($attr['DIR']) && strtolower($attr['DIR']) === 'rtl') {
94				$bdf = 0x2067;
95				$popd = 'RLIPDI';
96			} // U+2067 RLI
97			elseif (isset($attr['DIR']) && strtolower($attr['DIR']) === 'ltr') {
98				$bdf = 0x2066;
99				$popd = 'LRIPDI';
100			} // U+2066 LRI
101			else {
102				$bdf = 0x2068;
103				$popd = 'FSIPDI';
104			} // U+2068 FSI
105		} elseif (isset($properties ['UNICODE-BIDI']) && strtolower($properties ['UNICODE-BIDI']) === 'bidi-override') {
106			if ($currdir === 'rtl') {
107				$bdf = 0x202E;
108				$popd = 'RLOPDF';
109			} // U+202E RLO
110			else {
111				$bdf = 0x202D;
112				$popd = 'LROPDF';
113			} // U+202D LRO
114		} elseif (isset($properties ['UNICODE-BIDI']) && strtolower($properties ['UNICODE-BIDI']) === 'embed') {
115			if ($currdir === 'rtl') {
116				$bdf = 0x202B;
117				$popd = 'RLEPDF';
118			} // U+202B RLE
119			else {
120				$bdf = 0x202A;
121				$popd = 'LREPDF';
122			} // U+202A LRE
123		} elseif (isset($properties ['UNICODE-BIDI']) && strtolower($properties ['UNICODE-BIDI']) === 'isolate') {
124			if ($currdir === 'rtl') {
125				$bdf = 0x2067;
126				$popd = 'RLIPDI';
127			} // U+2067 RLI
128			else {
129				$bdf = 0x2066;
130				$popd = 'LRIPDI';
131			} // U+2066 LRI
132		} elseif (isset($properties ['UNICODE-BIDI']) && strtolower($properties ['UNICODE-BIDI']) === 'isolate-override') {
133			if ($currdir === 'rtl') {
134				$bdf = 0x2067;
135				$bdf2 = 0x202E;
136				$popd = 'RLIRLOPDFPDI';
137			} // U+2067 RLI // U+202E RLO
138			else {
139				$bdf = 0x2066;
140				$bdf2 = 0x202D;
141				$popd = 'LRILROPDFPDI';
142			} // U+2066 LRI  // U+202D LRO
143		} elseif (isset($properties ['UNICODE-BIDI']) && strtolower($properties ['UNICODE-BIDI']) === 'plaintext') {
144			$bdf = 0x2068;
145			$popd = 'FSIPDI'; // U+2068 FSI
146		} else {
147			if (isset($attr['DIR']) && strtolower($attr['DIR']) === 'rtl') {
148				$bdf = 0x202B;
149				$popd = 'RLEPDF';
150			} // U+202B RLE
151			elseif (isset($attr['DIR']) && strtolower($attr['DIR']) === 'ltr') {
152				$bdf = 0x202A;
153				$popd = 'LREPDF';
154			} // U+202A LRE
155		}
156
157		if ($bdf) {
158			// mPDF 5.7.3 Inline tags
159			if (!isset($this->mpdf->InlineBDF[$tag])) {
160				$this->mpdf->InlineBDF[$tag] = [[$popd, $this->mpdf->InlineBDFctr]];
161			} else {
162				$this->mpdf->InlineBDF[$tag][] = [$popd, $this->mpdf->InlineBDFctr];
163			}
164			$this->mpdf->InlineBDFctr++;
165			if ($bdf2) {
166				$bdf2 = UtfString::code2utf($bdf);
167			}
168			$this->mpdf->OTLdata = [];
169			if ($this->mpdf->tableLevel) {
170				$this->mpdf->_saveCellTextBuffer(UtfString::code2utf($bdf) . $bdf2);
171			} else {
172				$this->mpdf->_saveTextBuffer(UtfString::code2utf($bdf) . $bdf2);
173			}
174			$this->mpdf->biDirectional = true;
175		}
176	}
177
178	public function close(&$ahtml, &$ihtml)
179	{
180		$tag = $this->getTagName();
181
182		$annot = false; // mPDF 6
183		$bdf = false; // mPDF 6
184
185		// mPDF 5.7.3 Inline tags
186		if ($tag === 'PROGRESS' || $tag === 'METER') {
187			if (!empty($this->mpdf->InlineProperties[$tag])) {
188				$this->mpdf->restoreInlineProperties($this->mpdf->InlineProperties[$tag]);
189			}
190			unset($this->mpdf->InlineProperties[$tag]);
191			if (!empty($this->mpdf->InlineAnnots[$tag])) {
192				$annot = $this->mpdf->InlineAnnots[$tag];
193			} // *ANNOTATIONS*
194			unset($this->mpdf->InlineAnnots[$tag]); // *ANNOTATIONS*
195		} else {
196			if (isset($this->mpdf->InlineProperties[$tag]) && count($this->mpdf->InlineProperties[$tag])) {
197				$tmpProps = array_pop($this->mpdf->InlineProperties[$tag]); // mPDF 5.7.4
198				$this->mpdf->restoreInlineProperties($tmpProps);
199			}
200			if (isset($this->mpdf->InlineAnnots[$tag]) && count($this->mpdf->InlineAnnots[$tag])) {  // *ANNOTATIONS*
201				$annot = array_pop($this->mpdf->InlineAnnots[$tag]);  // *ANNOTATIONS*
202			} // *ANNOTATIONS*
203			if (isset($this->mpdf->InlineBDF[$tag]) && count($this->mpdf->InlineBDF[$tag])) {  // mPDF 6
204				$bdfarr = array_pop($this->mpdf->InlineBDF[$tag]);
205				$bdf = $bdfarr[0];
206			}
207		}
208
209		/* -- ANNOTATIONS -- */
210		if ($annot) { // mPDF 6
211			if ($this->mpdf->tableLevel) { // *TABLES*
212				$this->mpdf->cell[$this->mpdf->row][$this->mpdf->col]['textbuffer'][] = [$annot]; // *TABLES*
213			} // *TABLES*
214			else { // *TABLES*
215				$this->mpdf->textbuffer[] = [$annot];
216			} // *TABLES*
217		}
218		/* -- END ANNOTATIONS -- */
219
220		// mPDF 6 bidi
221		// mPDF 6 Bidirectional formatting for inline elements
222		if ($bdf) {
223			$popf = $this->mpdf->_setBidiCodes('end', $bdf);
224			$this->mpdf->OTLdata = [];
225			if ($this->mpdf->tableLevel) {
226				$this->mpdf->_saveCellTextBuffer($popf);
227			} else {
228				$this->mpdf->_saveTextBuffer($popf);
229			}
230		}
231	}
232}
233