composer package updates
[openemr.git] / vendor / mpdf / mpdf / src / Conversion / DecToRoman.php
blob4a20361bbaaa792b1496b3a1f54cd71a29de5f23
1 <?php
3 namespace Mpdf\Conversion;
5 /**
6 * @link https://github.com/JeroenDeDauw/RomanNumbers
7 * @license GNU GPL v2+
8 */
9 class DecToRoman
12 private $symbolMap;
14 public function __construct(array $symbolMap = [])
16 if ($symbolMap !== []) {
17 $this->symbolMap = $symbolMap;
18 } else {
19 $this->symbolMap = [['I', 'V'], ['X', 'L'], ['C', 'D'], ['M']];
23 public function convert($number)
25 $this->ensureNumberIsAnInteger($number);
26 $this->ensureNumberIsWithinBounds($number);
28 return $this->constructRomanString($number);
31 private function ensureNumberIsAnInteger($number)
33 if (!is_int($number)) {
34 throw new \InvalidArgumentException('Can only translate integers to roman');
38 private function ensureNumberIsWithinBounds($number)
40 if ($number < 1) {
41 throw new \OutOfRangeException('Numbers under one cannot be translated to roman');
44 if ($number > $this->getUpperBound()) {
45 throw new \OutOfBoundsException('The provided number is to big to be fully translated to roman');
49 public function getUpperBound()
51 $symbolGroupCount = count($this->symbolMap);
52 $valueOfOne = 10 ** ($symbolGroupCount - 1);
54 $hasFiveSymbol = array_key_exists(1, $this->symbolMap[$symbolGroupCount - 1]);
56 return $valueOfOne * ($hasFiveSymbol ? 9 : 4) - 1;
59 private function constructRomanString($number)
61 $romanNumber = '';
63 $symbolMapCount = count($this->symbolMap);
64 for ($i = 0; $i < $symbolMapCount; $i++) {
65 $divisor = 10 ** ($i + 1);
66 $remainder = $number % $divisor;
67 $digit = $remainder / (10 ** $i);
69 $number -= $remainder;
70 $romanNumber = $this->formatDigit($digit, $i) . $romanNumber;
72 if ($number === 0) {
73 break;
77 return $romanNumber;
80 private function formatDigit($digit, $orderOfMagnitude)
82 if ($digit === 0) {
83 return '';
86 if ($digit === 4 || $digit === 9) {
87 return $this->formatFourOrNine($digit, $orderOfMagnitude);
90 $romanNumber = '';
92 if ($digit >= 5) {
93 $digit -= 5;
94 $romanNumber .= $this->getFiveSymbol($orderOfMagnitude);
97 $romanNumber .= $this->formatOneToThree($orderOfMagnitude, $digit);
99 return $romanNumber;
102 private function formatFourOrNine($digit, $orderOfMagnitude)
104 $firstSymbol = $this->getOneSymbol($orderOfMagnitude);
105 $secondSymbol = $digit === 4
106 ? $this->getFiveSymbol($orderOfMagnitude)
107 : $this->getTenSymbol($orderOfMagnitude);
109 return $firstSymbol . $secondSymbol;
112 private function formatOneToThree($orderOfMagnitude, $digit)
114 return str_repeat($this->getOneSymbol($orderOfMagnitude), $digit);
117 private function getOneSymbol($orderOfMagnitude)
119 return $this->symbolMap[$orderOfMagnitude][0];
122 private function getFiveSymbol($orderOfMagnitude)
124 return $this->symbolMap[$orderOfMagnitude][1];
127 private function getTenSymbol($orderOfMagnitude)
129 return $this->symbolMap[$orderOfMagnitude + 1][0];