1<?php 2 3namespace Mpdf\Color; 4 5use Mpdf\Mpdf; 6 7class ColorSpaceRestrictor 8{ 9 10 const RESTRICT_TO_GRAYSCALE = 1; 11 12 const RESTRICT_TO_RGB_SPOT_GRAYSCALE = 2; 13 14 const RESTRICT_TO_CMYK_SPOT_GRAYSCALE = 3; 15 16 /** 17 * @var \Mpdf\Mpdf 18 */ 19 private $mpdf; 20 21 /** 22 * @var \Mpdf\Color\ColorModeConverter 23 */ 24 private $colorModeConverter; 25 26 /** 27 * @var int 28 */ 29 private $mode; 30 31 /** 32 * Process $mode settings 33 * 1 - allow GRAYSCALE only [convert CMYK/RGB->gray] 34 * 2 - allow RGB / SPOT COLOR / Grayscale [convert CMYK->RGB] 35 * 3 - allow CMYK / SPOT COLOR / Grayscale [convert RGB->CMYK] 36 * 37 * @param \Mpdf\Mpdf $mpdf 38 * @param \Mpdf\Color\ColorModeConverter $colorModeConverter 39 * @param int $mode 40 */ 41 public function __construct(Mpdf $mpdf, ColorModeConverter $colorModeConverter, $mode) 42 { 43 $this->mpdf = $mpdf; 44 $this->colorModeConverter = $colorModeConverter; 45 $this->mode = $mode; 46 } 47 48 /** 49 * @param mixed $c 50 * @param string $color 51 * @param string[] $PDFAXwarnings 52 * 53 * @return float[]|mixed 54 */ 55 public function restrictColorSpace($c, $color, &$PDFAXwarnings = []) 56 { 57 if (!is_array($c)) { 58 return $c; 59 } 60 61 $mode = (int) $c[0]; 62 switch ($mode) { 63 case 1: 64 return $c; 65 case 2: 66 return $this->restrictSpotColorSpace($c, $PDFAXwarnings); 67 case 3: 68 return $this->restrictRgbColorSpace($c, $color, $PDFAXwarnings); 69 case 4: 70 return $this->restrictCmykColorSpace($c, $color, $PDFAXwarnings); 71 case 5: 72 return $this->restrictRgbaColorSpace($c, $color, $PDFAXwarnings); 73 case 6: 74 return $this->restrictCmykaColorSpace($c, $color, $PDFAXwarnings); 75 } 76 77 return $c; 78 } 79 80 /** 81 * @param string $c 82 * @param string[] $PDFAXwarnings 83 * 84 * @return float[] 85 */ 86 private function restrictSpotColorSpace($c, &$PDFAXwarnings = []) 87 { 88 if (!isset($this->mpdf->spotColorIDs[$c[1]])) { 89 throw new \Mpdf\MpdfException('Error: Spot colour has not been defined - ' . $this->mpdf->spotColorIDs[$c[1]]); 90 } 91 92 if ($this->mpdf->PDFA) { 93 if ($this->mpdf->PDFA && !$this->mpdf->PDFAauto) { 94 $PDFAXwarnings[] = "Spot color specified '" . $this->mpdf->spotColorIDs[$c[1]] . "' (converted to process color)"; 95 } 96 if ($this->mode != 3) { 97 $sp = $this->mpdf->spotColors[$this->mpdf->spotColorIDs[$c[1]]]; 98 $c = $this->colorModeConverter->cmyk2rgb([4, $sp['c'], $sp['m'], $sp['y'], $sp['k']]); 99 } 100 } elseif ($this->mode == 1) { 101 $sp = $this->mpdf->spotColors[$this->mpdf->spotColorIDs[$c[1]]]; 102 $c = $this->colorModeConverter->cmyk2gray([4, $sp['c'], $sp['m'], $sp['y'], $sp['k']]); 103 } 104 105 return $c; 106 } 107 108 /** 109 * @param mixed $c 110 * @param string $color 111 * @param string[] $PDFAXwarnings 112 * 113 * @return float[] 114 */ 115 private function restrictRgbColorSpace($c, $color, &$PDFAXwarnings = []) 116 { 117 if ($this->mpdf->PDFX || ($this->mpdf->PDFA && $this->mode == 3)) { 118 if (($this->mpdf->PDFA && !$this->mpdf->PDFAauto) || ($this->mpdf->PDFX && !$this->mpdf->PDFXauto)) { 119 $PDFAXwarnings[] = "RGB color specified '" . $color . "' (converted to CMYK)"; 120 } 121 $c = $this->colorModeConverter->rgb2cmyk($c); 122 } elseif ($this->mode == 1) { 123 $c = $this->colorModeConverter->rgb2gray($c); 124 } elseif ($this->mode == 3) { 125 $c = $this->colorModeConverter->rgb2cmyk($c); 126 } 127 128 return $c; 129 } 130 131 /** 132 * @param mixed $c 133 * @param string $color 134 * @param string[] $PDFAXwarnings 135 * 136 * @return float[] 137 */ 138 private function restrictCmykColorSpace($c, $color, &$PDFAXwarnings = []) 139 { 140 if ($this->mpdf->PDFA && $this->mode != 3) { 141 if ($this->mpdf->PDFA && !$this->mpdf->PDFAauto) { 142 $PDFAXwarnings[] = "CMYK color specified '" . $color . "' (converted to RGB)"; 143 } 144 $c = $this->colorModeConverter->cmyk2rgb($c); 145 } elseif ($this->mode == 1) { 146 $c = $this->colorModeConverter->cmyk2gray($c); 147 } elseif ($this->mode == 2) { 148 $c = $this->colorModeConverter->cmyk2rgb($c); 149 } 150 151 return $c; 152 } 153 154 /** 155 * @param mixed $c 156 * @param string $color 157 * @param string[] $PDFAXwarnings 158 * 159 * @return float[] 160 */ 161 private function restrictRgbaColorSpace($c, $color, &$PDFAXwarnings = []) 162 { 163 if ($this->mpdf->PDFX || ($this->mpdf->PDFA && $this->mode == 3)) { 164 if (($this->mpdf->PDFA && !$this->mpdf->PDFAauto) || ($this->mpdf->PDFX && !$this->mpdf->PDFXauto)) { 165 $PDFAXwarnings[] = "RGB color with transparency specified '" . $color . "' (converted to CMYK without transparency)"; 166 } 167 $c = $this->colorModeConverter->rgb2cmyk($c); 168 $c = [4, $c[1], $c[2], $c[3], $c[4]]; 169 } elseif ($this->mpdf->PDFA && $this->mode != 3) { 170 if (!$this->mpdf->PDFAauto) { 171 $PDFAXwarnings[] = "RGB color with transparency specified '" . $color . "' (converted to RGB without transparency)"; 172 } 173 $c = $this->colorModeConverter->rgb2cmyk($c); 174 $c = [4, $c[1], $c[2], $c[3], $c[4]]; 175 } elseif ($this->mode == 1) { 176 $c = $this->colorModeConverter->rgb2gray($c); 177 } elseif ($this->mode == 3) { 178 $c = $this->colorModeConverter->rgb2cmyk($c); 179 } 180 181 return $c; 182 } 183 184 /** 185 * @param mixed $c 186 * @param string $color 187 * @param string[] $PDFAXwarnings 188 * 189 * @return float[] 190 */ 191 private function restrictCmykaColorSpace($c, $color, &$PDFAXwarnings = []) 192 { 193 if ($this->mpdf->PDFA && $this->mode != 3) { 194 if (($this->mpdf->PDFA && !$this->mpdf->PDFAauto) || ($this->mpdf->PDFX && !$this->mpdf->PDFXauto)) { 195 $PDFAXwarnings[] = "CMYK color with transparency specified '" . $color . "' (converted to RGB without transparency)"; 196 } 197 $c = $this->colorModeConverter->cmyk2rgb($c); 198 $c = [3, $c[1], $c[2], $c[3]]; 199 } elseif ($this->mpdf->PDFX || ($this->mpdf->PDFA && $this->mode == 3)) { 200 if (($this->mpdf->PDFA && !$this->mpdf->PDFAauto) || ($this->mpdf->PDFX && !$this->mpdf->PDFXauto)) { 201 $PDFAXwarnings[] = "CMYK color with transparency specified '" . $color . "' (converted to CMYK without transparency)"; 202 } 203 $c = $this->colorModeConverter->cmyk2rgb($c); 204 $c = [3, $c[1], $c[2], $c[3]]; 205 } elseif ($this->mode == 1) { 206 $c = $this->colorModeConverter->cmyk2gray($c); 207 } elseif ($this->mode == 2) { 208 $c = $this->colorModeConverter->cmyk2rgb($c); 209 } 210 211 return $c; 212 } 213 214} 215