1<?php 2 3namespace Mpdf; 4 5use Psr\Log\LoggerInterface; 6use Mpdf\Log\Context as LogContext; 7 8class SizeConverter implements \Psr\Log\LoggerAwareInterface 9{ 10 11 private $dpi; 12 13 private $defaultFontSize; 14 15 /** 16 * @var \Mpdf\Mpdf 17 */ 18 private $mpdf; 19 20 /** 21 * @var \Psr\Log\LoggerInterface 22 */ 23 private $logger; 24 25 public function __construct($dpi, $defaultFontSize, Mpdf $mpdf, LoggerInterface $logger) 26 { 27 $this->dpi = $dpi; 28 $this->defaultFontSize = $defaultFontSize; 29 $this->mpdf = $mpdf; 30 $this->logger = $logger; 31 } 32 33 public function setLogger(LoggerInterface $logger) 34 { 35 $this->logger = $logger; 36 } 37 38 /** 39 * Depends of maxsize value to make % work properly. Usually maxsize == pagewidth 40 * For text $maxsize = $fontsize 41 * Setting e.g. margin % will use maxsize (pagewidth) and em will use fontsize 42 * 43 * @param mixed $size 44 * @param mixed $maxsize 45 * @param mixed $fontsize 46 * @param mixed $usefontsize Set false for e.g. margins - will ignore fontsize for % values 47 * 48 * @return float Final size in mm 49 */ 50 public function convert($size = 5, $maxsize = 0, $fontsize = false, $usefontsize = true) 51 { 52 $size = trim(strtolower($size)); 53 $res = preg_match('/^(?P<size>[-0-9.,]+([eE]\-?[0-9]+)?)?(?P<unit>[%a-z-]+)?$/', $size, $parts); 54 if (!$res) { 55 // ignore definition 56 $this->logger->warning(sprintf('Invalid size representation "%s"', $size), ['context' => LogContext::CSS_SIZE_CONVERSION]); 57 } 58 59 $unit = !empty($parts['unit']) ? $parts['unit'] : null; 60 $size = !empty($parts['size']) ? (float) $parts['size'] : 0.0; 61 62 switch ($unit) { 63 case 'mm': 64 // do nothing 65 break; 66 67 case 'cm': 68 $size *= 10; 69 break; 70 71 case 'pt': 72 $size *= 1 / Mpdf::SCALE; 73 break; 74 75 case 'rem': 76 $size *= $this->mpdf->default_font_size / Mpdf::SCALE; 77 break; 78 79 case '%': 80 if ($fontsize && $usefontsize) { 81 $size *= $fontsize / 100; 82 } else { 83 $size *= $maxsize / 100; 84 } 85 break; 86 87 case 'in': 88 // mm in an inch 89 $size *= 25.4; 90 break; 91 92 case 'pc': 93 // PostScript picas 94 $size *= 38.1 / 9; 95 break; 96 97 case 'ex': 98 // Approximates "ex" as half of font height 99 $size *= $this->multiplyFontSize($fontsize, $maxsize, 0.5); 100 break; 101 102 case 'em': 103 $size *= $this->multiplyFontSize($fontsize, $maxsize, 1); 104 break; 105 106 case 'thin': 107 $size = 1 * (25.4 / $this->dpi); 108 break; 109 110 case 'medium': 111 $size = 3 * (25.4 / $this->dpi); 112 // Commented-out dead code from legacy method 113 // $size *= $this->multiplyFontSize($fontsize, $maxsize, 1); 114 break; 115 116 case 'thick': 117 $size = 5 * (25.4 / $this->dpi); // 5 pixel width for table borders 118 break; 119 120 case 'xx-small': 121 $size *= $this->multiplyFontSize($fontsize, $maxsize, 0.7); 122 break; 123 124 case 'x-small': 125 $size *= $this->multiplyFontSize($fontsize, $maxsize, 0.77); 126 break; 127 128 case 'small': 129 $size *= $this->multiplyFontSize($fontsize, $maxsize, 0.86); 130 break; 131 132 case 'large': 133 $size *= $this->multiplyFontSize($fontsize, $maxsize, 1.2); 134 break; 135 136 case 'x-large': 137 $size *= $this->multiplyFontSize($fontsize, $maxsize, 1.5); 138 break; 139 140 case 'xx-large': 141 $size *= $this->multiplyFontSize($fontsize, $maxsize, 2); 142 break; 143 144 case 'px': 145 default: 146 $size *= (25.4 / $this->dpi); 147 break; 148 } 149 150 return $size; 151 } 152 153 private function multiplyFontSize($fontsize, $maxsize, $ratio) 154 { 155 if ($fontsize) { 156 return $fontsize * $ratio; 157 } 158 159 return $maxsize * $ratio; 160 } 161} 162