@@ -219,6 +219,26 @@ public function color($color)
219
219
return $ this ;
220
220
}
221
221
222
+ /**
223
+ * Automatically set a font and/or background color based on the supplied name.
224
+ *
225
+ * @param bool $foreground
226
+ * @param bool $background
227
+ *
228
+ * @return $this
229
+ */
230
+ public function autoColor (bool $ foreground = true , bool $ background = true , int $ saturation = 85 , int $ luminance = 60 )
231
+ {
232
+ $ hue = (crc32 ($ this ->name ) % 360 ) / 360 ;
233
+ $ saturation /= 100 ;
234
+ $ luminance /= 100 ;
235
+
236
+ $ this ->bgColor = $ this ->convertHSLtoRGB ($ hue , $ saturation , $ luminance );
237
+ $ this ->fontColor = $ this ->getContrastColor ($ this ->bgColor );
238
+
239
+ return $ this ;
240
+ }
241
+
222
242
/**
223
243
* Set the font file by path or int (1-5).
224
244
*
@@ -782,4 +802,116 @@ protected function getFontByScript()
782
802
783
803
return $ this ->getFontFile ();
784
804
}
805
+
806
+ /**
807
+ * Convert HSL color value produced by autoColor() to RGB value expected by image driver.
808
+ */
809
+ protected function convertHSLtoRGB ($ h , $ s , $ l , $ toHex = true )
810
+ {
811
+ assert ((0 <= $ h ) && ($ h <= 1 ));
812
+
813
+ $ red = $ l ;
814
+ $ green = $ l ;
815
+ $ blue = $ l ;
816
+
817
+ $ v = ($ l <= 0.5 ) ? ($ l * (1.0 + $ s )) : ($ l + $ s - $ l * $ s );
818
+ if ($ v > 0 ) {
819
+ $ m = $ l + $ l - $ v ;
820
+ $ sv = ($ v - $ m ) / $ v ;
821
+ $ h *= 6.0 ;
822
+ $ sextant = floor ($ h );
823
+ $ fract = $ h - $ sextant ;
824
+ $ vsf = $ v * $ sv * $ fract ;
825
+ $ mid1 = $ m + $ vsf ;
826
+ $ mid2 = $ v - $ vsf ;
827
+
828
+ switch ($ sextant ) {
829
+ case 0 :
830
+ $ red = $ v ;
831
+ $ green = $ mid1 ;
832
+ $ blue = $ m ;
833
+ break ;
834
+ case 1 :
835
+ $ red = $ mid2 ;
836
+ $ green = $ v ;
837
+ $ blue = $ m ;
838
+ break ;
839
+ case 2 :
840
+ $ red = $ m ;
841
+ $ green = $ v ;
842
+ $ blue = $ mid1 ;
843
+ break ;
844
+ case 3 :
845
+ $ red = $ m ;
846
+ $ green = $ mid2 ;
847
+ $ blue = $ v ;
848
+ break ;
849
+ case 4 :
850
+ $ red = $ mid1 ;
851
+ $ green = $ m ;
852
+ $ blue = $ v ;
853
+ break ;
854
+ case 5 :
855
+ $ red = $ v ;
856
+ $ green = $ m ;
857
+ $ blue = $ mid2 ;
858
+ break ;
859
+ }
860
+ }
861
+
862
+ $ red = round ($ red * 255 , 0 );
863
+ $ green = round ($ green * 255 , 0 );
864
+ $ blue = round ($ blue * 255 , 0 );
865
+
866
+ if ($ toHex ) {
867
+ $ red = ($ red < 15 ) ? '0 ' .dechex ($ red ) : dechex ($ red );
868
+ $ green = ($ green < 15 ) ? '0 ' .dechex ($ green ) : dechex ($ green );
869
+ $ blue = ($ blue < 15 ) ? '0 ' .dechex ($ blue ) : dechex ($ blue );
870
+
871
+ return "# {$ red }{$ green }{$ blue }" ;
872
+ } else {
873
+ return ['red ' => $ red , 'green ' => $ green , 'blue ' => $ blue ];
874
+ }
875
+ }
876
+
877
+ /**
878
+ * Get contrasting foreground color for autoColor background.
879
+ */
880
+ protected function getContrastColor ($ hexColor )
881
+ {
882
+ // hexColor RGB
883
+ $ R1 = hexdec (substr ($ hexColor , 1 , 2 ));
884
+ $ G1 = hexdec (substr ($ hexColor , 3 , 2 ));
885
+ $ B1 = hexdec (substr ($ hexColor , 5 , 2 ));
886
+
887
+ // Black RGB
888
+ $ blackColor = '#000000 ' ;
889
+ $ R2BlackColor = hexdec (substr ($ blackColor , 1 , 2 ));
890
+ $ G2BlackColor = hexdec (substr ($ blackColor , 3 , 2 ));
891
+ $ B2BlackColor = hexdec (substr ($ blackColor , 5 , 2 ));
892
+
893
+ // Calc contrast ratio
894
+ $ L1 = 0.2126 * pow ($ R1 / 255 , 2.2 ) +
895
+ 0.7152 * pow ($ G1 / 255 , 2.2 ) +
896
+ 0.0722 * pow ($ B1 / 255 , 2.2 );
897
+
898
+ $ L2 = 0.2126 * pow ($ R2BlackColor / 255 , 2.2 ) +
899
+ 0.7152 * pow ($ G2BlackColor / 255 , 2.2 ) +
900
+ 0.0722 * pow ($ B2BlackColor / 255 , 2.2 );
901
+
902
+ $ contrastRatio = 0 ;
903
+ if ($ L1 > $ L2 ) {
904
+ $ contrastRatio = (int ) (($ L1 + 0.05 ) / ($ L2 + 0.05 ));
905
+ } else {
906
+ $ contrastRatio = (int ) (($ L2 + 0.05 ) / ($ L1 + 0.05 ));
907
+ }
908
+
909
+ // If contrast is more than 5, return black color
910
+ if ($ contrastRatio > 5 ) {
911
+ return '#000000 ' ;
912
+ } else {
913
+ // if not, return white color.
914
+ return '#FFFFFF ' ;
915
+ }
916
+ }
785
917
}
0 commit comments