1<?php 2 3namespace Mpdf\Tag; 4use \dokuwiki\plugin\dw2pdf\DokuImageProcessorDecorator as ImageProcessor; 5 6use Mpdf\Mpdf; 7 8class Img extends Tag 9{ 10 11 public function open($attr, &$ahtml, &$ihtml) 12 { 13 $this->mpdf->ignorefollowingspaces = false; 14 $objattr = []; 15 $objattr['margin_top'] = 0; 16 $objattr['margin_bottom'] = 0; 17 $objattr['margin_left'] = 0; 18 $objattr['margin_right'] = 0; 19 $objattr['padding_top'] = 0; 20 $objattr['padding_bottom'] = 0; 21 $objattr['padding_left'] = 0; 22 $objattr['padding_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 if (isset($attr['SRC'])) { 30 $srcpath = $attr['SRC']; 31 $orig_srcpath = (isset($attr['ORIG_SRC']) ? $attr['ORIG_SRC'] : ''); 32 $properties = $this->cssManager->MergeCSS('', 'IMG', $attr); 33 if (isset($properties ['DISPLAY']) && strtolower($properties ['DISPLAY']) === 'none') { 34 return; 35 } 36 if (isset($properties['Z-INDEX']) && $this->mpdf->current_layer == 0) { 37 $v = (int) $properties['Z-INDEX']; 38 if ($v > 0) { 39 $objattr['z-index'] = $v; 40 } 41 } 42 43 $objattr['visibility'] = 'visible'; 44 if (isset($properties['VISIBILITY'])) { 45 $v = strtolower($properties['VISIBILITY']); 46 if (($v === 'hidden' || $v === 'printonly' || $v === 'screenonly') && $this->mpdf->visibility === 'visible') { 47 $objattr['visibility'] = $v; 48 } 49 } 50 51 // VSPACE and HSPACE converted to margins in MergeCSS 52 if (isset($properties['MARGIN-TOP'])) { 53 $objattr['margin_top'] = $this->sizeConverter->convert( 54 $properties['MARGIN-TOP'], 55 $this->mpdf->blk[$this->mpdf->blklvl]['inner_width'], 56 $this->mpdf->FontSize, 57 false 58 ); 59 } 60 if (isset($properties['MARGIN-BOTTOM'])) { 61 $objattr['margin_bottom'] = $this->sizeConverter->convert( 62 $properties['MARGIN-BOTTOM'], 63 $this->mpdf->blk[$this->mpdf->blklvl]['inner_width'], 64 $this->mpdf->FontSize, 65 false 66 ); 67 } 68 if (isset($properties['MARGIN-LEFT'])) { 69 $objattr['margin_left'] = $this->sizeConverter->convert( 70 $properties['MARGIN-LEFT'], 71 $this->mpdf->blk[$this->mpdf->blklvl]['inner_width'], 72 $this->mpdf->FontSize, 73 false 74 ); 75 } 76 if (isset($properties['MARGIN-RIGHT'])) { 77 $objattr['margin_right'] = $this->sizeConverter->convert( 78 $properties['MARGIN-RIGHT'], 79 $this->mpdf->blk[$this->mpdf->blklvl]['inner_width'], 80 $this->mpdf->FontSize, 81 false 82 ); 83 } 84 85 if (isset($properties['PADDING-TOP'])) { 86 $objattr['padding_top'] = $this->sizeConverter->convert( 87 $properties['PADDING-TOP'], 88 $this->mpdf->blk[$this->mpdf->blklvl]['inner_width'], 89 $this->mpdf->FontSize, 90 false 91 ); 92 } 93 if (isset($properties['PADDING-BOTTOM'])) { 94 $objattr['padding_bottom'] = $this->sizeConverter->convert( 95 $properties['PADDING-BOTTOM'], 96 $this->mpdf->blk[$this->mpdf->blklvl]['inner_width'], 97 $this->mpdf->FontSize, 98 false 99 ); 100 } 101 if (isset($properties['PADDING-LEFT'])) { 102 $objattr['padding_left'] = $this->sizeConverter->convert( 103 $properties['PADDING-LEFT'], 104 $this->mpdf->blk[$this->mpdf->blklvl]['inner_width'], 105 $this->mpdf->FontSize, 106 false 107 ); 108 } 109 if (isset($properties['PADDING-RIGHT'])) { 110 $objattr['padding_right'] = $this->sizeConverter->convert( 111 $properties['PADDING-RIGHT'], 112 $this->mpdf->blk[$this->mpdf->blklvl]['inner_width'], 113 $this->mpdf->FontSize, 114 false 115 ); 116 } 117 118 if (isset($properties['BORDER-TOP'])) { 119 $objattr['border_top'] = $this->mpdf->border_details($properties['BORDER-TOP']); 120 } 121 if (isset($properties['BORDER-BOTTOM'])) { 122 $objattr['border_bottom'] = $this->mpdf->border_details($properties['BORDER-BOTTOM']); 123 } 124 if (isset($properties['BORDER-LEFT'])) { 125 $objattr['border_left'] = $this->mpdf->border_details($properties['BORDER-LEFT']); 126 } 127 if (isset($properties['BORDER-RIGHT'])) { 128 $objattr['border_right'] = $this->mpdf->border_details($properties['BORDER-RIGHT']); 129 } 130 131 if (isset($properties['VERTICAL-ALIGN'])) { 132 $objattr['vertical-align'] = $this->getAlign($properties['VERTICAL-ALIGN']); 133 } 134 $w = 0; 135 $h = 0; 136 if (isset($properties['WIDTH'])) { 137 $w = $this->sizeConverter->convert( 138 $properties['WIDTH'], 139 $this->mpdf->blk[$this->mpdf->blklvl]['inner_width'], 140 $this->mpdf->FontSize, 141 false 142 ); 143 } elseif (isset($attr['WIDTH'])) { 144 $w = $this->sizeConverter->convert( 145 $attr['WIDTH'], 146 $this->mpdf->blk[$this->mpdf->blklvl]['inner_width'], 147 $this->mpdf->FontSize, 148 false 149 ); 150 } 151 if (isset($properties['HEIGHT'])) { 152 $h = $this->sizeConverter->convert( 153 $properties['HEIGHT'], 154 $this->mpdf->blk[$this->mpdf->blklvl]['inner_width'], 155 $this->mpdf->FontSize, 156 false 157 ); 158 } elseif (isset($attr['HEIGHT'])) { 159 $h = $this->sizeConverter->convert( 160 $attr['HEIGHT'], 161 $this->mpdf->blk[$this->mpdf->blklvl]['inner_width'], 162 $this->mpdf->FontSize, 163 false 164 ); 165 } 166 $maxw = $maxh = $minw = $minh = false; 167 if (isset($properties['MAX-WIDTH'])) { 168 $maxw = $this->sizeConverter->convert( 169 $properties['MAX-WIDTH'], 170 $this->mpdf->blk[$this->mpdf->blklvl]['inner_width'], 171 $this->mpdf->FontSize, 172 false 173 ); 174 } elseif (isset($attr['MAX-WIDTH'])) { 175 $maxw = $this->sizeConverter->convert( 176 $attr['MAX-WIDTH'], 177 $this->mpdf->blk[$this->mpdf->blklvl]['inner_width'], 178 $this->mpdf->FontSize, 179 false 180 ); 181 } 182 if (isset($properties['MAX-HEIGHT'])) { 183 $maxh = $this->sizeConverter->convert( 184 $properties['MAX-HEIGHT'], 185 $this->mpdf->blk[$this->mpdf->blklvl]['inner_width'], 186 $this->mpdf->FontSize, 187 false 188 ); 189 } elseif (isset($attr['MAX-HEIGHT'])) { 190 $maxh = $this->sizeConverter->convert( 191 $attr['MAX-HEIGHT'], 192 $this->mpdf->blk[$this->mpdf->blklvl]['inner_width'], 193 $this->mpdf->FontSize, 194 false 195 ); 196 } 197 if (isset($properties['MIN-WIDTH'])) { 198 $minw = $this->sizeConverter->convert( 199 $properties['MIN-WIDTH'], 200 $this->mpdf->blk[$this->mpdf->blklvl]['inner_width'], 201 $this->mpdf->FontSize, 202 false 203 ); 204 } elseif (isset($attr['MIN-WIDTH'])) { 205 $minw = $this->sizeConverter->convert( 206 $attr['MIN-WIDTH'], 207 $this->mpdf->blk[$this->mpdf->blklvl]['inner_width'], 208 $this->mpdf->FontSize, 209 false 210 ); 211 } 212 if (isset($properties['MIN-HEIGHT'])) { 213 $minh = $this->sizeConverter->convert( 214 $properties['MIN-HEIGHT'], 215 $this->mpdf->blk[$this->mpdf->blklvl]['inner_width'], 216 $this->mpdf->FontSize, 217 false 218 ); 219 } elseif (isset($attr['MIN-HEIGHT'])) { 220 $minh = $this->sizeConverter->convert( 221 $attr['MIN-HEIGHT'], 222 $this->mpdf->blk[$this->mpdf->blklvl]['inner_width'], 223 $this->mpdf->FontSize, 224 false 225 ); 226 } 227 228 if (isset($properties['OPACITY']) && $properties['OPACITY'] > 0 && $properties['OPACITY'] <= 1) { 229 $objattr['opacity'] = $properties['OPACITY']; 230 } 231 if ($this->mpdf->HREF) { 232 if (strpos($this->mpdf->HREF, '.') === false && strpos($this->mpdf->HREF, '@') !== 0) { 233 $href = $this->mpdf->HREF; 234 while (array_key_exists($href, $this->mpdf->internallink)) { 235 $href = '#' . $href; 236 } 237 $this->mpdf->internallink[$href] = $this->mpdf->AddLink(); 238 $objattr['link'] = $this->mpdf->internallink[$href]; 239 } else { 240 $objattr['link'] = $this->mpdf->HREF; 241 } 242 } 243 $extraheight = $objattr['padding_top'] + $objattr['padding_bottom'] + $objattr['margin_top'] 244 + $objattr['margin_bottom'] + $objattr['border_top']['w'] + $objattr['border_bottom']['w']; 245 246 $extrawidth = $objattr['padding_left'] + $objattr['padding_right'] + $objattr['margin_left'] 247 + $objattr['margin_right'] + $objattr['border_left']['w'] + $objattr['border_right']['w']; 248 249 // mPDF 5.7.3 TRANSFORMS 250 if (isset($properties['BACKGROUND-COLOR']) && $properties['BACKGROUND-COLOR'] != '') { 251 $objattr['bgcolor'] = $this->colorConverter->convert($properties['BACKGROUND-COLOR'], $this->mpdf->PDFAXwarnings); 252 } 253 254 /* -- BACKGROUNDS -- */ 255 if (isset($properties['GRADIENT-MASK']) && preg_match('/(-moz-)*(repeating-)*(linear|radial)-gradient/', $properties['GRADIENT-MASK'])) { 256 $objattr['GRADIENT-MASK'] = $properties['GRADIENT-MASK']; 257 } 258 /* -- END BACKGROUNDS -- */ 259 260 // mPDF 6 261 $interpolation = false; 262 if (!empty($properties['IMAGE-RENDERING'])) { 263 $interpolation = false; 264 if (strtolower($properties['IMAGE-RENDERING']) === 'crisp-edges') { 265 $interpolation = false; 266 } elseif (strtolower($properties['IMAGE-RENDERING']) === 'optimizequality') { 267 $interpolation = true; 268 } elseif (strtolower($properties['IMAGE-RENDERING']) === 'smooth') { 269 $interpolation = true; 270 } elseif (strtolower($properties['IMAGE-RENDERING']) === 'auto') { 271 $interpolation = $this->mpdf->interpolateImages; 272 } 273 $info['interpolation'] = $interpolation; 274 } 275 276 // Image file 277 $info = $this->imageProcessor->getImage($srcpath, true, true, $orig_srcpath, $interpolation); // mPDF 6 278 if (!$info) { 279 $info = $this->imageProcessor->getImage($this->mpdf->noImageFile); 280 if ($info) { 281 $srcpath = $this->mpdf->noImageFile; 282 $w = ($info['w'] * (25.4 / $this->mpdf->img_dpi)); 283 $h = ($info['h'] * (25.4 / $this->mpdf->img_dpi)); 284 } 285 } 286 if (!$info) { 287 return; 288 } 289 290 $image_orientation = 0; 291 if (isset($attr['ROTATE'])) { 292 $image_orientation = $attr['ROTATE']; 293 } elseif (isset($properties['IMAGE-ORIENTATION'])) { 294 $image_orientation = $properties['IMAGE-ORIENTATION']; 295 } 296 if ($image_orientation) { 297 if ($image_orientation == 90 || $image_orientation == -90 || $image_orientation == 270) { 298 $tmpw = $info['w']; 299 $info['w'] = $info['h']; 300 $info['h'] = $tmpw; 301 } 302 $objattr['ROTATE'] = $image_orientation; 303 } 304 305 $objattr['file'] = $srcpath; 306 //Default width and height calculation if needed 307 if ($w == 0 && $h == 0) { 308 /* -- IMAGES-WMF -- */ 309 if ($info['type'] === 'wmf') { 310 // WMF units are twips (1/20pt) 311 // divide by 20 to get points 312 // divide by k to get user units 313 $w = abs($info['w']) / (20 * Mpdf::SCALE); 314 $h = abs($info['h']) / (20 * Mpdf::SCALE); 315 } else { /* -- END IMAGES-WMF -- */ 316 if ($info['type'] === 'svg') { 317 // SVG units are pixels 318 $w = abs($info['w']) / Mpdf::SCALE; 319 $h = abs($info['h']) / Mpdf::SCALE; 320 } else { 321 //Put image at default image dpi 322 $w = ($info['w'] / Mpdf::SCALE) * (72 / $this->mpdf->img_dpi); 323 $h = ($info['h'] / Mpdf::SCALE) * (72 / $this->mpdf->img_dpi); 324 } 325 } 326 if (isset($properties['IMAGE-RESOLUTION'])) { 327 if (preg_match('/from-image/i', $properties['IMAGE-RESOLUTION']) && isset($info['set-dpi']) && $info['set-dpi'] > 0) { 328 $w *= $this->mpdf->img_dpi / $info['set-dpi']; 329 $h *= $this->mpdf->img_dpi / $info['set-dpi']; 330 } elseif (preg_match('/(\d+)dpi/i', $properties['IMAGE-RESOLUTION'], $m)) { 331 $dpi = $m[1]; 332 if ($dpi > 0) { 333 $w *= $this->mpdf->img_dpi / $dpi; 334 $h *= $this->mpdf->img_dpi / $dpi; 335 } 336 } 337 } 338 } 339 // IF WIDTH OR HEIGHT SPECIFIED 340 if ($w == 0) { 341 $w = $info['h'] ? abs($h * $info['w'] / $info['h']) : INF; 342 } 343 344 if ($h == 0) { 345 $h = $info['w'] ? abs($w * $info['h'] / $info['w']) : INF; 346 } 347 348 if ($minw && $w < $minw) { 349 $w = $minw; 350 $h = $info['w'] ? abs($w * $info['h'] / $info['w']) : INF; 351 } 352 if ($maxw && $w > $maxw) { 353 $w = $maxw; 354 $h = $info['w'] ? abs($w * $info['h'] / $info['w']) : INF; 355 } 356 if ($minh && $h < $minh) { 357 $h = $minh; 358 $w = $info['h'] ? abs($h * $info['w'] / $info['h']) : INF; 359 } 360 if ($maxh && $h > $maxh) { 361 $h = $maxh; 362 $w = $info['h'] ? abs($h * $info['w'] / $info['h']) : INF; 363 } 364 365 // Resize to maximum dimensions of page 366 $maxWidth = $this->mpdf->blk[$this->mpdf->blklvl]['inner_width']; 367 $maxHeight = $this->mpdf->h - ($this->mpdf->tMargin + $this->mpdf->bMargin + 1); 368 if ($this->mpdf->fullImageHeight) { 369 $maxHeight = $this->mpdf->fullImageHeight; 370 } 371 if (($w + $extrawidth) > ($maxWidth + 0.0001)) { // mPDF 5.7.4 0.0001 to allow for rounding errors when w==maxWidth 372 $w = $maxWidth - $extrawidth; 373 $h = abs($w * $info['h'] / $info['w']); 374 } 375 376 if ($h + $extraheight > $maxHeight) { 377 $h = $maxHeight - $extraheight; 378 $w = abs($h * $info['w'] / $info['h']); 379 } 380 $objattr['type'] = 'image'; 381 $objattr['itype'] = $info['type']; 382 383 $objattr['orig_h'] = $info['h']; 384 $objattr['orig_w'] = $info['w']; 385 /* -- IMAGES-WMF -- */ 386 if ($info['type'] === 'wmf') { 387 $objattr['wmf_x'] = $info['x']; 388 $objattr['wmf_y'] = $info['y']; 389 } else { /* -- END IMAGES-WMF -- */ 390 if ($info['type'] === 'svg') { 391 $objattr['wmf_x'] = $info['x']; 392 $objattr['wmf_y'] = $info['y']; 393 } 394 } 395 $objattr['height'] = $h + $extraheight; 396 $objattr['width'] = $w + $extrawidth; 397 $objattr['image_height'] = $h; 398 $objattr['image_width'] = $w; 399 /* -- CSS-IMAGE-FLOAT -- */ 400 if (!$this->mpdf->ColActive && !$this->mpdf->tableLevel && !$this->mpdf->listlvl && !$this->mpdf->kwt) { 401 if (isset($properties['FLOAT']) && (strtoupper($properties['FLOAT']) === 'RIGHT' || strtoupper($properties['FLOAT']) === 'LEFT')) { 402 $objattr['float'] = strtoupper(substr($properties['FLOAT'], 0, 1)); 403 } 404 } 405 /* -- END CSS-IMAGE-FLOAT -- */ 406 // mPDF 5.7.3 TRANSFORMS 407 if (isset($properties['TRANSFORM']) && !$this->mpdf->ColActive && !$this->mpdf->kwt) { 408 $objattr['transform'] = $properties['TRANSFORM']; 409 } 410 411 $e = "\xbb\xa4\xactype=image,objattr=" . serialize($objattr) . "\xbb\xa4\xac"; 412 413 /* -- TABLES -- */ 414 // Output it to buffers 415 if ($this->mpdf->tableLevel) { 416 $this->mpdf->_saveCellTextBuffer($e, $this->mpdf->HREF); 417 $this->mpdf->cell[$this->mpdf->row][$this->mpdf->col]['s'] += $objattr['width']; 418 } else { 419 /* -- END TABLES -- */ 420 $this->mpdf->_saveTextBuffer($e, $this->mpdf->HREF); 421 } // *TABLES* 422 /* -- ANNOTATIONS -- */ 423 if ($this->mpdf->title2annots && isset($attr['TITLE'])) { 424 $objattr = []; 425 $objattr['margin_top'] = 0; 426 $objattr['margin_bottom'] = 0; 427 $objattr['margin_left'] = 0; 428 $objattr['margin_right'] = 0; 429 $objattr['width'] = 0; 430 $objattr['height'] = 0; 431 $objattr['border_top']['w'] = 0; 432 $objattr['border_bottom']['w'] = 0; 433 $objattr['border_left']['w'] = 0; 434 $objattr['border_right']['w'] = 0; 435 $objattr['CONTENT'] = $attr['TITLE']; 436 $objattr['type'] = 'annot'; 437 $objattr['POS-X'] = 0; 438 $objattr['POS-Y'] = 0; 439 $objattr['ICON'] = 'Comment'; 440 $objattr['AUTHOR'] = ''; 441 $objattr['SUBJECT'] = ''; 442 $objattr['OPACITY'] = $this->mpdf->annotOpacity; 443 $objattr['COLOR'] = $this->colorConverter->convert('yellow', $this->mpdf->PDFAXwarnings); 444 $e = "\xbb\xa4\xactype=annot,objattr=" . serialize($objattr) . "\xbb\xa4\xac"; 445 if ($this->mpdf->tableLevel) { // *TABLES* 446 $this->mpdf->cell[$this->mpdf->row][$this->mpdf->col]['textbuffer'][] = [$e]; // *TABLES* 447 } // *TABLES* 448 else { // *TABLES* 449 $this->mpdf->textbuffer[] = [$e]; 450 } // *TABLES* 451 } 452 /* -- END ANNOTATIONS -- */ 453 } 454 } 455 456 public function close(&$ahtml, &$ihtml) 457 { 458 } 459} 460