Font.php 5.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246
  1. <?php
  2. /**
  3. * Class with Font related methods.
  4. */
  5. declare(strict_types=1);
  6. namespace PhpMyAdmin;
  7. use function ceil;
  8. use function is_array;
  9. use function mb_strlen;
  10. use function mb_strtolower;
  11. use function preg_replace;
  12. use function str_replace;
  13. /**
  14. * Class with Font related methods.
  15. */
  16. class Font
  17. {
  18. /**
  19. * Get list with characters and the corresponding width modifiers.
  20. *
  21. * @return array with characters and corresponding width modifier
  22. *
  23. * @access public
  24. */
  25. public function getCharLists(): array
  26. {
  27. // list of characters and their width modifiers
  28. $charLists = [];
  29. //ijl
  30. $charLists[] = [
  31. 'chars' => [
  32. 'i',
  33. 'j',
  34. 'l',
  35. ],
  36. 'modifier' => 0.23,
  37. ];
  38. //f
  39. $charLists[] = [
  40. 'chars' => ['f'],
  41. 'modifier' => 0.27,
  42. ];
  43. //tI
  44. $charLists[] = [
  45. 'chars' => [
  46. 't',
  47. 'I',
  48. ],
  49. 'modifier' => 0.28,
  50. ];
  51. //r
  52. $charLists[] = [
  53. 'chars' => ['r'],
  54. 'modifier' => 0.34,
  55. ];
  56. //1
  57. $charLists[] = [
  58. 'chars' => ['1'],
  59. 'modifier' => 0.49,
  60. ];
  61. //cksvxyzJ
  62. $charLists[] = [
  63. 'chars' => [
  64. 'c',
  65. 'k',
  66. 's',
  67. 'v',
  68. 'x',
  69. 'y',
  70. 'z',
  71. 'J',
  72. ],
  73. 'modifier' => 0.5,
  74. ];
  75. //abdeghnopquL023456789
  76. $charLists[] = [
  77. 'chars' => [
  78. 'a',
  79. 'b',
  80. 'd',
  81. 'e',
  82. 'g',
  83. 'h',
  84. 'n',
  85. 'o',
  86. 'p',
  87. 'q',
  88. 'u',
  89. 'L',
  90. '0',
  91. '2',
  92. '3',
  93. '4',
  94. '5',
  95. '6',
  96. '7',
  97. '8',
  98. '9',
  99. ],
  100. 'modifier' => 0.56,
  101. ];
  102. //FTZ
  103. $charLists[] = [
  104. 'chars' => [
  105. 'F',
  106. 'T',
  107. 'Z',
  108. ],
  109. 'modifier' => 0.61,
  110. ];
  111. //ABEKPSVXY
  112. $charLists[] = [
  113. 'chars' => [
  114. 'A',
  115. 'B',
  116. 'E',
  117. 'K',
  118. 'P',
  119. 'S',
  120. 'V',
  121. 'X',
  122. 'Y',
  123. ],
  124. 'modifier' => 0.67,
  125. ];
  126. //wCDHNRU
  127. $charLists[] = [
  128. 'chars' => [
  129. 'w',
  130. 'C',
  131. 'D',
  132. 'H',
  133. 'N',
  134. 'R',
  135. 'U',
  136. ],
  137. 'modifier' => 0.73,
  138. ];
  139. //GOQ
  140. $charLists[] = [
  141. 'chars' => [
  142. 'G',
  143. 'O',
  144. 'Q',
  145. ],
  146. 'modifier' => 0.78,
  147. ];
  148. //mM
  149. $charLists[] = [
  150. 'chars' => [
  151. 'm',
  152. 'M',
  153. ],
  154. 'modifier' => 0.84,
  155. ];
  156. //W
  157. $charLists[] = [
  158. 'chars' => ['W'],
  159. 'modifier' => 0.95,
  160. ];
  161. //" "
  162. $charLists[] = [
  163. 'chars' => [' '],
  164. 'modifier' => 0.28,
  165. ];
  166. return $charLists;
  167. }
  168. /**
  169. * Get width of string/text
  170. *
  171. * The text element width is calculated depending on font name
  172. * and font size.
  173. *
  174. * @param string $text string of which the width will be calculated
  175. * @param string $font name of the font like Arial,sans-serif etc
  176. * @param int $fontSize size of font
  177. * @param array|null $charLists list of characters and their width modifiers
  178. *
  179. * @return int width of the text
  180. *
  181. * @access public
  182. */
  183. public function getStringWidth(
  184. string $text,
  185. string $font,
  186. int $fontSize,
  187. ?array $charLists = null
  188. ): int {
  189. if (! isset($charLists[0]['chars'], $charLists[0]['modifier']) || empty($charLists)
  190. || ! is_array($charLists[0]['chars'])
  191. ) {
  192. $charLists = $this->getCharLists();
  193. }
  194. /*
  195. * Start by counting the width, giving each character a modifying value
  196. */
  197. $count = 0;
  198. foreach ($charLists as $charList) {
  199. $count += (mb_strlen($text)
  200. - mb_strlen(str_replace($charList['chars'], '', $text))
  201. ) * $charList['modifier'];
  202. }
  203. $text = str_replace(' ', '', $text);//remove the " "'s
  204. //all other chars
  205. $count += mb_strlen((string) preg_replace('/[a-z0-9]/i', '', $text)) * 0.3;
  206. $modifier = 1;
  207. $font = mb_strtolower($font);
  208. switch ($font) {
  209. /*
  210. * no modifier for arial and sans-serif
  211. */
  212. case 'arial':
  213. case 'sans-serif':
  214. break;
  215. /*
  216. * .92 modifier for time, serif, brushscriptstd, and californian fb
  217. */
  218. case 'times':
  219. case 'serif':
  220. case 'brushscriptstd':
  221. case 'californian fb':
  222. $modifier = .92;
  223. break;
  224. /*
  225. * 1.23 modifier for broadway
  226. */
  227. case 'broadway':
  228. $modifier = 1.23;
  229. break;
  230. }
  231. $textWidth = $count * $fontSize;
  232. return (int) ceil($textWidth * $modifier);
  233. }
  234. }