Add date information to MailingJob Schema
[civicrm-core.git] / CRM / Utils / Color.php
index 5d965dd342e6371c5a411c3ae76594c5d4a0a2ca..95872433f52598cc65e7334f0850928545d5de4e 100644 (file)
@@ -3,7 +3,7 @@
  +--------------------------------------------------------------------+
  | CiviCRM version 5                                                  |
  +--------------------------------------------------------------------+
- | Copyright CiviCRM LLC (c) 2004-2018                                |
+ | Copyright CiviCRM LLC (c) 2004-2019                                |
  +--------------------------------------------------------------------+
  | This file is a part of CiviCRM.                                    |
  |                                                                    |
@@ -28,7 +28,7 @@
 /**
  *
  * @package CRM
- * @copyright CiviCRM LLC (c) 2004-2018
+ * @copyright CiviCRM LLC (c) 2004-2019
  */
 
 /**
  */
 class CRM_Utils_Color {
 
+  const COLOR_FILE = '[civicrm.root]/bower_components/css-color-names/css-color-names.json';
+
   /**
    * Determine the appropriate text color for a given background.
    *
    * Based on YIQ value.
    *
-   * @param string $hexcolor
+   * @param string $color
+   * @param string $black
+   * @param string $white
    * @return string
    */
-  public static function getContrast($hexcolor) {
-    $hexcolor = trim($hexcolor, ' #');
-    $r = hexdec(substr($hexcolor, 0, 2));
-    $g = hexdec(substr($hexcolor, 2, 2));
-    $b = hexdec(substr($hexcolor, 4, 2));
+  public static function getContrast($color, $black = 'black', $white = 'white') {
+    list($r, $g, $b) = self::getRgb($color);
     $yiq = (($r * 299) + ($g * 587) + ($b * 114)) / 1000;
-    return ($yiq >= 128) ? 'black' : 'white';
+    return ($yiq >= 128) ? $black : $white;
+  }
+
+  /**
+   * Parse any color string into rgb decimal values
+   *
+   * Accepted formats:
+   *   Full hex:     "#ffffff"
+   *   Short hex:    "#fff"
+   *   Color name    "white"
+   *   RGB notation: "rgb(255, 255, 255)"
+   *
+   * @param string $color
+   * @return int[]|null
+   *   [red, green, blue]
+   */
+  public static function getRgb($color) {
+    $color = str_replace(' ', '', $color);
+    $color = self::nameToHex($color) ?? $color;
+    if (strpos($color, 'rgb(') === 0) {
+      return explode(',', substr($color, 4, strpos($color, ')') - 4));
+    }
+    $color = ltrim($color, '#');
+    if (strlen($color) === 3) {
+      $color = $color[0] . $color[0] . $color[1] . $color[1] . $color[2] . $color[2];
+    }
+    if (!CRM_Utils_Rule::color('#' . $color)) {
+      return NULL;
+    }
+    return [
+      hexdec(substr($color, 0, 2)),
+      hexdec(substr($color, 2, 2)),
+      hexdec(substr($color, 4, 2)),
+    ];
+  }
+
+  /**
+   * Calculate a highlight color from a base color
+   *
+   * @param $color
+   * @return string
+   */
+  public static function getHighlight($color) {
+    $rgb = self::getRgb($color);
+    $avg = array_sum($rgb) / 3;
+    foreach ($rgb as &$v) {
+      if ($avg > 242) {
+        // For very bright values, lower the brightness
+        $v -= 50;
+      }
+      else {
+        // Bump up brightness on a nonlinear curve - darker colors get more of a boost
+        $v = min(255, intval((-.0035 * ($v - 242) ** 2) + 260));
+      }
+    }
+    return self::rgbToHex($rgb);
+  }
+
+  /**
+   * Convert named color (e.g. springgreen) to hex
+   *
+   * @param $colorName
+   * @return string|null
+   */
+  public static function nameToHex($colorName) {
+    if (strpos($colorName, '#') !== FALSE || strpos($colorName, '(') !== FALSE) {
+      return NULL;
+    }
+    if (empty(Civi::$statics[__CLASS__]['names'])) {
+      Civi::$statics[__CLASS__]['names'] = json_decode(file_get_contents(Civi::paths()->getPath(self::COLOR_FILE)), TRUE);
+    }
+    return Civi::$statics[__CLASS__]['names'][strtolower($colorName)] ?? NULL;
+  }
+
+  /**
+   * Converts rgb array to hex string
+   *
+   * @param int[] $rgb
+   * @return string
+   */
+  public static function rgbToHex($rgb) {
+    $ret = '#';
+    foreach ($rgb as $dec) {
+      $ret .= str_pad(dechex($dec), 2, '0', STR_PAD_LEFT);
+    }
+    return $ret;
+  }
+
+  /**
+   * Validate color input and convert it to standard hex notation
+   *
+   * @param string $color
+   * @return bool
+   */
+  public static function normalize(&$color) {
+    $rgb = self::getRgb($color);
+    if ($rgb) {
+      $color = self::rgbToHex($rgb);
+      return TRUE;
+    }
+    return FALSE;
   }
 
 }