- <?php
- * @file
- * Allows users to change the color scheme of themes.
- */
-
- * Implements hook_theme().
- */
- function color_theme() {
- return array(
- 'color_preview' => array(
- 'render element' => 'form',
- 'file' => 'color.theme.inc',
- ),
- );
- }
-
- * Implements hook_form_FORM_ID_alter().
- */
- function color_form_system_theme_settings_alter(&$form, &$form_state) {
- if (isset($form_state['build_info']['args'][0])
- && ($theme_name = $form_state['build_info']['args'][0])
- && ($theme_info = color_get_info($theme_name))
- && isset($theme_info['fields'])) {
- $form['color'] = array(
- '#type' => 'fieldset',
- '#title' => t('Color scheme'),
- '#weight' => -1,
- '#attributes' => array(
- 'id' => 'color_scheme_form',
- 'class' => array('color-form'),
- ),
- );
-
- $theme_info['schemes'][''] = array('title' => t('Custom'), 'colors' => array());
- $color_sets = array();
- $schemes = array();
- foreach ($theme_info['schemes'] as $key => $scheme) {
- $color_sets[$key] = $scheme['title'];
- $schemes[$key] = $scheme['colors'];
- $schemes[$key] += $theme_info['schemes']['default']['colors'];
- }
-
-
-
- $current_scheme = theme_get_setting('color.palette', $theme_name);
- foreach ($schemes as $key => $scheme) {
- if ($current_scheme == $scheme) {
- $scheme_name = $key;
- break;
- }
- }
- if (empty($scheme_name)) {
- if (empty($current_scheme)) {
- $scheme_name = 'default';
- }
- else {
- $scheme_name = '';
- }
- }
-
-
- $preview_url = url('<front>', array(
- 'query' => array(
- 'preview' => $theme_name
- ),
- 'absolute' => TRUE,
- ));
- $preview_markup = theme('color_preview', array('preview_url' => $preview_url));
-
- $base = backdrop_get_path('module', 'color');
-
- $form['color']['scheme'] = array(
- '#type' => 'select',
- '#title' => t('Color set'),
- '#options' => $color_sets,
- '#default_value' => $scheme_name,
- '#attributes' => array(
- 'data-color-schemes' => backdrop_json_encode($schemes),
- 'data-color-theme-name' => $theme_name,
- 'data-color-preview-markup' => $preview_markup,
- 'data-color-preview-token' => backdrop_get_token('color_token'),
- ),
- '#attached' => array(
-
- 'css' => array(
- $base . '/css/color.admin.css' => array(),
- ),
-
- 'js' => array(
- $base . '/js/color.js'
- ),
- ),
- );
-
- $form['color']['palette'] = array(
- '#type' => 'container',
- '#attributes' => array('id' => 'palette'),
- '#tree' => TRUE,
- );
-
-
- foreach ($theme_info['fields'] as $name => $label) {
-
- if (!isset($form['#color_elements']) || !in_array($name, $form['#color_elements'])) {
- $form['color']['palette'][$name] = color_get_color_element($theme_name, $name, $form);
- }
- }
-
- $form['color']['theme'] = array('#type' => 'value', '#value' => $theme_name);
- $form['color']['info'] = array('#type' => 'value', '#value' => $theme_info);
-
- $form['#validate'][] = 'color_scheme_form_validate';
- array_unshift($form['#submit'], 'color_scheme_form_submit');
-
-
-
- if ($theme_name === 'bartik') {
- module_load_include('inc', 'color', 'color.legacy');
- bartik_form_system_theme_settings_alter($form, $form_state);
- }
- }
- }
-
- * Creates the render array for a color element.
- *
- * The function also stores a list of which color elements have already been
- * generated, so that the color module does not attempt to print out color
- * settings twice.
- *
- * @param string $theme_name
- * The theme to get color settings from.
- * @param string $color_name
- * The name of the color element to return.
- * @param array $form
- * The form array for the theme settings form.
- *
- * @return array
- * The render array for the color element.
- *
- * @since 1.12.2
- */
- function color_get_color_element($theme_name, $color_name, &$form) {
-
- $theme_info = color_get_info($theme_name);
- $palette = color_get_palette($theme_name);
-
-
- $form['#color_elements'][] = $color_name;
-
-
- return array(
- '#type' => 'color',
- '#title' => check_plain($theme_info['fields'][$color_name]),
- '#value_callback' => 'color_palette_color_value',
- '#default_value' => $palette[$color_name],
- '#size' => 8,
- '#parents' => array('palette', $color_name),
- '#attributes' => array(
- 'data-color-name' => $color_name,
- ),
- );
- }
-
- * Implements hook_css_alter().
- *
- * Replaces style sheets with color-altered style sheets.
- */
- function color_css_alter(&$css) {
- global $theme_key;
- $preview_theme = _color_preview_theme();
- if ($preview_theme) {
-
- $theme_info = color_get_info($preview_theme);
- if ($theme_info) {
- $theme_path = backdrop_get_path('theme', $preview_theme);
- if (isset($_SESSION['color'][$theme_key])) {
- $preview_data = $_SESSION['color'][$theme_key];
- $paths = array(
- 'source' => $theme_path . '/',
- 'map' => array(),
- );
- foreach ($theme_info['css'] as $file) {
- $filename = _color_get_file_path($file, $preview_theme);
- $stylesheet = file_get_contents($filename);
- $paths['source'] = backdrop_get_path('theme', _color_get_theme_from_file($file, $preview_theme));
- $base = base_path() . dirname($filename) . '/';
- _backdrop_build_css_path(NULL, $base);
-
- $stylesheet = preg_replace_callback('/url\([\'"]?(?![a-z]+:|\/+)([^\'")]+)[\'"]?\)/i', '_backdrop_build_css_path', $stylesheet);
- $stylesheet = _color_rewrite_stylesheet($preview_theme, $theme_info, $paths, $preview_data['palette'], $stylesheet);
-
- foreach ($css as $path => $data) {
- if ($path == $filename) {
- $css[$path]['type'] = 'inline';
- $css[$path]['preprocess'] = 'false';
- $css[$path]['data'] = $stylesheet;
- break;
- }
- }
- }
- }
- }
- }
- if (!isset($preview_data)) {
-
- $color_paths = theme_get_setting('color.stylesheets');
-
- if (!empty($color_paths)) {
- $info = color_get_info($theme_key);
-
-
- $old_paths = array();
- foreach ($info['css'] as $file) {
-
-
- $old_paths[$file] = _color_get_file_path($file, $theme_key);
- }
-
-
- foreach($color_paths as $color_path) {
- $basename = backdrop_basename($color_path);
- if (array_key_exists($basename, $old_paths)) {
-
-
- $css[$old_paths[$basename]]['data'] = $color_path;
- }
- }
- }
- }
- }
-
- * Implements hook_menu().
- */
- function color_menu() {
- $items = array();
-
- $items['color/save_preview_settings/%'] = array(
- 'page callback' => 'color_save_preview_settings',
- 'page arguments' => array(2),
- 'type' => MENU_CALLBACK,
- 'access arguments' => array('administer themes'),
- 'delivery callback' => 'backdrop_json_deliver',
- );
-
- return $items;
- }
-
- * Callback function to handle saving preview settings to the user's session.
- */
- function color_save_preview_settings($theme_name) {
- if (!isset($_GET['token']) || !backdrop_valid_token($_GET['token'], "color_token")) {
- return MENU_ACCESS_DENIED;
- }
-
- $themes = list_themes();
- if (in_array($theme_name, array_keys($themes))) {
- $theme_info = color_get_info($theme_name);
-
-
- if (isset($_POST['scheme'])
- && !empty($_POST['scheme'])
- && in_array($_POST['scheme'], array_keys($theme_info['schemes']))) {
- $scheme = $_POST['scheme'];
- }
- else {
- $scheme = '';
- }
-
-
- if (isset($_POST['palette']) && is_array($_POST['palette'])) {
- $palette = $_POST['palette'];
- foreach ($palette as $field => $color) {
- if (!in_array($field, array_keys($theme_info['fields'])) || !color_valid_hexadecimal_string($color)) {
- unset($palette[$field]);
- }
- }
- }
-
- $_SESSION['color'][$theme_name] = array(
- 'scheme' => $scheme,
- 'palette' => $palette,
- );
-
- $data = array('success' => 1);
- backdrop_json_output($data);
- }
- }
-
- * Implements hook_custom_theme().
- */
- function color_custom_theme() {
- $preview = _color_preview_theme();
- if ($preview) {
-
- if (module_exists('admin_bar')) {
- admin_bar_suppress();
- }
- return $preview;
- }
- }
-
- * Implements hook_url_outbound_alter().
- */
- function color_url_outbound_alter(&$path, &$options, $original_path) {
- $preview = &backdrop_static(__FUNCTION__);
- if (!isset($preview)) {
- $preview = _color_preview_theme();
- }
-
- if ($preview) {
- $options['query']['preview'] = $preview;
- }
- }
-
- * Implements hook_config_create().
- */
- function color_config_create(Config $staging_config) {
- _color_config_save($staging_config);
- }
-
- * Implements hook_config_update().
- */
- function color_config_update(Config $staging_config, Config $active_config) {
- _color_config_save($staging_config);
- }
-
- * Shared callback used by color_config_create() and hook_config_update().
- *
- * @param Config $staging_config
- * The configuration about to be imported into the site.
- */
- function _color_config_save(Config $staging_config) {
-
- $config_name = $staging_config->getName();
- list($theme_name, $settings) = explode('.', $config_name);
- if ($settings === 'settings') {
- $themes = list_themes();
- if (array_key_exists($theme_name, $themes)) {
- $new_color_config = $staging_config->get('color');
- $color_info = color_get_info($theme_name);
- if ($color_info) {
- $palette = isset($new_color_config['palette']) ? $new_color_config['palette'] : NULL;
- $updated_config = color_save_configuration($theme_name, $color_info, $palette);
-
-
- $staging_config->set('color', $updated_config);
- }
- }
- }
- }
-
- * Retrieves the Color module information for a particular theme.
- */
- function color_get_info($theme) {
- static $color_info = array();
-
- if (!isset($color_info[$theme])) {
- $info = array();
- $path = backdrop_get_path('theme', $theme);
- $file = BACKDROP_ROOT . '/' . $path . '/color/color.inc';
- if ($path && file_exists($file)) {
- include $file;
- }
-
- $themes = list_themes();
- $theme_info = $themes[$theme];
-
- if (empty($info) || !isset($info['css'])) {
- $info['css'] = array();
- if (isset($theme_info->stylesheets)) {
- foreach ($theme_info->stylesheets as $group) {
- $info['css'] = array_merge($info['css'], array_keys($group));
- }
- }
- }
-
- foreach ($info['css'] as $key => $file) {
- $info['css'][$key] = backdrop_basename($file);
- }
-
- if (isset($theme_info->base_theme) && !empty($theme_info->base_theme)) {
- $base_info = color_get_info($theme_info->base_theme);
- $info = backdrop_array_merge_deep($info, $base_info);
- }
-
- $info['css'] = array_unique($info['css']);
-
- $color_info[$theme] = $info;
- }
-
- return $color_info[$theme];
- }
-
- * Retrieves the color palette for a particular theme.
- */
- function color_get_palette($theme, $default = FALSE) {
-
- $info = color_get_info($theme);
- $palette = $info['schemes']['default']['colors'];
- foreach ($palette as $item => $color) {
- $palette[$item] = backdrop_strtolower($color);
- }
-
- if (!$default && ($theme_palette = theme_get_setting('color.palette', $theme))) {
- foreach ($theme_palette as $color_name => $color_code) {
- $palette[$color_name] = $color_code;
- }
- }
- return $palette;
- }
-
- * Determines the value for a palette color field.
- *
- * @param $element
- * The form element whose value is being populated.
- * @param $input
- * The incoming input to populate the form element. If this is FALSE,
- * the element's default value should be returned.
- * @param $form_state
- * A keyed array containing the current state of the form.
- *
- * @return
- * The data that will appear in the $form_state['values'] collection for this
- * element. Return nothing to use the default.
- */
- function color_palette_color_value($element, $input = FALSE, $form_state = array()) {
-
-
-
- if ($input !== FALSE) {
-
-
- $value = form_type_textfield_value($element, $input, $form_state);
- if (!$value || !isset($form_state['complete form']['#token']) || color_valid_hexadecimal_string($value) || backdrop_valid_token($form_state['values']['form_token'], $form_state['complete form']['#token'])) {
- return $value;
- }
- else {
- return $element['#default_value'];
- }
- }
- }
-
- * Determines if a hexadecimal CSS color string is valid.
- *
- * @param $color
- * The string to check.
- *
- * @return
- * TRUE if the string is a valid hexadecimal CSS color string, or FALSE if it
- * isn't.
- */
- function color_valid_hexadecimal_string($color) {
- return preg_match('/^#([a-f0-9]{3}){1,2}$/iD', $color);
- }
-
-
- * Returns the name of the theme currently being previewed.
- *
- * @return string
- * The name of the theme currently being previewed, or an empty string if the
- * logged in user does not have access to administer themes.
- */
- function _color_preview_theme() {
- if (user_access('administer themes')) {
- if (isset($_GET['preview'])) {
- $themes = list_themes();
- if (in_array($_GET['preview'], array_keys($themes))) {
- return $_GET['preview'];
- }
- }
- }
- return '';
- }
-
- * Form validation handler for color_scheme_form().
- *
- * @see color_scheme_form_submit()
- */
- function color_scheme_form_validate($form, &$form_state) {
-
- foreach ($form_state['values']['palette'] as $key => $color) {
- if (!color_valid_hexadecimal_string($color)) {
- form_set_error('palette][' . $key, t('You must enter a valid hexadecimal color value for %name.', array('%name' => $form['color']['palette'][$key]['#title'])));
- }
- }
- }
-
- * Form submission handler for color_scheme_form().
- *
- * @see color_scheme_form_validate()
- */
- function color_scheme_form_submit($form, &$form_state) {
-
- if (!isset($form_state['values']['info'])) {
- return;
- }
- $theme = $form_state['values']['theme'];
- $info = $form_state['values']['info'];
-
-
- unset($form_state['values']['info']);
-
-
- $palette = $form_state['values']['palette'];
- if ($form_state['values']['scheme'] != '') {
- foreach ($palette as $key => $color) {
- if (isset($info['schemes'][$form_state['values']['scheme']]['colors'][$key])) {
- $palette[$key] = $info['schemes'][$form_state['values']['scheme']]['colors'][$key];
- }
- }
- $palette += $info['schemes']['default']['colors'];
- }
-
-
- unset($form_state['values']['scheme']);
- unset($form_state['values']['palette']);
- unset($_SESSION['color']);
-
-
- $form_state['values']['color'] = color_save_configuration($theme, $info, $palette);
- }
-
- * Implements hook_flush_caches().
- */
- function color_flush_caches() {
-
- color_rebuild_settings();
- }
-
- * Rebuild color scheme info.
- */
- function color_rebuild_settings($theme_name = NULL) {
- $themes = array();
- if ($theme_name) {
- $themes = array($theme_name);
- }
- else {
- foreach (list_themes() as $key => $data) {
- if ($data->status) {
- $themes[] = $key;
- }
- }
- }
-
- foreach ($themes as $theme) {
- $theme_config_name = $theme . '.settings';
- $theme_config = config($theme_config_name);
- if ($theme_config && $new_color_config = $theme_config->get('color')) {
- $color_info = color_get_info($theme);
- if ($color_info) {
- $palette = isset($new_color_config['palette']) ? $new_color_config['palette'] : NULL;
- $new_color_info = color_save_configuration($theme, $color_info, $palette);
- $theme_config->set('color', $new_color_info);
- $theme_config->save();
- }
- }
- }
- }
-
- * Generates the necessary CSS and images based on a color palette.
- *
- * @param $theme_name
- * The theme machine name.
- * @param $theme_info
- * The theme info, as loaded by list_themes().
- * @param $palette
- * The color palette on which the images and CSS will be generated.
- *
- * @return array|NULL
- * Returns an array of values to be saved in the theme configuration. If no
- * color settings are necessary (such as when using the default color scheme),
- * NULL is returned.
- */
- function color_save_configuration($theme_name, $theme_info, $palette) {
-
- $files = theme_get_setting('color.files', $theme_name);
- if ($files) {
- foreach ($files as $file) {
- @backdrop_unlink($file);
- }
- }
- if (isset($file) && $file = dirname($file)) {
- @backdrop_rmdir($file);
- }
-
-
- if (empty($palette) || implode(',', color_get_palette($theme_name, TRUE)) == implode(',', $palette)) {
- return NULL;
- }
-
-
- $id = $theme_name . '-' . substr(hash('sha256', serialize($palette) . microtime()), 0, 8);
- $paths['color'] = 'public://color';
- $paths['target'] = $paths['color'] . '/' . $id;
- foreach ($paths as $path) {
- file_prepare_directory($path, FILE_CREATE_DIRECTORY);
- }
- $paths['target'] = $paths['target'] . '/';
- $paths['id'] = $id;
- $paths['source'] = backdrop_get_path('theme', $theme_name) . '/';
- $paths['files'] = $paths['map'] = array();
-
-
- $css = array();
- foreach ($theme_info['css'] as $stylesheet) {
-
- $files = array();
- $filename = _color_get_file_path($stylesheet, $theme_name);
- if (file_exists($filename)) {
- $files[] = $stylesheet;
- }
-
- foreach ($files as $file) {
-
-
-
- $filename = _color_get_file_path($file, $theme_name);
- $theme = _color_get_theme_from_file($file, $theme_name);
- $paths['source'] = backdrop_get_path('theme', $theme) . '/';
-
- $style = backdrop_load_stylesheet($filename, FALSE);
-
-
-
- $base = base_path() . dirname($filename) . '/';
- _backdrop_build_css_path(NULL, $base);
-
-
- $style = preg_replace_callback('/url\([\'"]?(?![a-z]+:|\/+)([^\'")]+)[\'"]?\)/i', '_backdrop_build_css_path', $style);
-
-
- $style = _color_rewrite_stylesheet($theme_name, $theme_info, $paths, $palette, $style);
- $base_file = backdrop_basename($file);
- $css[] = $paths['target'] . $base_file;
- _color_save_stylesheet($paths['target'] . $base_file, $style, $paths);
- }
- }
-
- return array(
- 'palette' => $palette,
- 'stylesheets' => $css,
- 'files' => $paths['files'],
- );
- }
-
- * Rewrites the stylesheet to match the colors in the palette.
- */
- function _color_rewrite_stylesheet($theme, &$info, &$paths, $palette, $style) {
-
- $conversion = $palette;
- foreach ($conversion as $k => $v) {
- $conversion[$k] = backdrop_strtolower($v);
- }
- $default = color_get_palette($theme, TRUE);
-
- $split = "Color Module: Don't touch";
- if (strpos($style, $split) !== FALSE) {
- list($style, $fixed) = explode($split, $style);
- }
-
-
- $style = preg_split('/(#[0-9a-f]{6}|#[0-9a-f]{3})/i', $style, -1, PREG_SPLIT_DELIM_CAPTURE);
- $is_color = FALSE;
- $output = '';
- $base = 'base';
-
-
- foreach ($style as $chunk) {
- if ($is_color) {
- $chunk = backdrop_strtolower($chunk);
-
- if (backdrop_strlen($chunk) == 4) {
- $chunk = '#' . $chunk[1] . $chunk[1] . $chunk[2] . $chunk[2] . $chunk[3] . $chunk[3];
- }
-
- if ($key = array_search($chunk, $default)) {
- $chunk = $conversion[$key];
- }
-
- else {
- if (isset($info['blend_target'])) {
- $chunk = _color_shift($palette[$base], $default[$base], $chunk, $info['blend_target']);
- }
- }
- }
- else {
-
-
-
- if (preg_match('@[^a-z0-9_-](a)[^a-z0-9_-][^/{]*{[^{]+$@i', $chunk)) {
- $base = 'link';
- }
-
- elseif (preg_match('/(?<!-)color[^{:]*:[^{#]*$/i', $chunk)) {
- $base = 'text';
- }
-
- else {
- $base = 'base';
- }
- }
- $output .= $chunk;
- $is_color = !$is_color;
- }
-
- if (isset($fixed)) {
- $output .= $fixed;
- }
-
-
- foreach ($paths['map'] as $before => $after) {
- $before = base_path() . $paths['source'] . $before;
- $before = preg_replace('`(^|/)(?!../)([^/]+)/../`', '$1', $before);
- $output = str_replace($before, $after, $output);
- }
-
- return $output;
- }
-
- * Saves the rewritten stylesheet to disk.
- */
- function _color_save_stylesheet($file, $style, &$paths) {
- $filepath = file_unmanaged_save_data($style, $file, FILE_EXISTS_REPLACE);
- $paths['files'][] = $filepath;
-
-
- backdrop_chmod($file);
- }
-
- * Finds the original file path of a CSS file from the color configuration.
- *
- * @param $filename
- * The file name that we are searching for.
- * @param $theme_name
- * The name of the theme that is being modified.
- *
- * @return string
- * Returns the original file path of the CSS file.
- */
- function _color_get_file_path($filename, $theme_name) {
- static $basenames = array();
-
- $themes = list_themes();
- $theme = $themes[$theme_name];
-
- $basename = backdrop_basename($filename);
-
- if (isset($theme->stylesheets)) {
- foreach ($theme->stylesheets as $group_name => $group) {
- foreach ($group as $file) {
- if (!isset($basenames[$theme_name][$group_name][$file])) {
- $basenames[$theme_name][$group_name][$file] = backdrop_basename($file);
- }
- if ($basename === $basenames[$theme_name][$group_name][$file]) {
- return $file;
- }
- }
- }
- }
-
- if (isset($theme->base_theme)) {
- return _color_get_file_path($filename, $theme->base_theme);
- }
- }
-
- * Finds which theme a CSS file came from.
- *
- * @param $filename
- * The file name that we are searching for.
- * @param $theme_name
- * The name of the theme that is being modified.
- *
- * @return string
- * Returns the name of the theme that the CSS file came from.
- */
- function _color_get_theme_from_file($filename, $theme_name) {
- $themes = list_themes();
- $theme = $themes[$theme_name];
-
- $basename = backdrop_basename($filename);
-
- if (isset($theme->stylesheets)) {
- foreach ($theme->stylesheets as $group_name => $group) {
- foreach ($group as $file) {
- if ($basename === backdrop_basename($file)) {
- return $theme_name;
- }
- }
- }
- }
-
- if (isset($theme->base_theme)) {
- return _color_get_theme_from_file($filename, $theme->base_theme);
- }
- }
-
- * Shifts a given color, using a reference pair and a target blend color.
- *
- * Note: this function is significantly different from the JS version, as it
- * is written to match the blended images perfectly.
- *
- * Constraint: if (ref2 == target + (ref1 - target) * delta) for some fraction
- * delta then (return == target + (given - target) * delta).
- *
- * Loose constraint: Preserve relative positions in saturation and luminance
- * space.
- */
- function _color_shift($given, $ref1, $ref2, $target) {
-
-
-
-
- $target = _color_unpack($target, TRUE);
- $ref1 = _color_unpack($ref1, TRUE);
- $ref2 = _color_unpack($ref2, TRUE);
- $numerator = 0;
- $denominator = 0;
- for ($i = 0; $i < 3; ++$i) {
- $numerator += ($ref2[$i] - $ref1[$i]) * ($ref2[$i] - $ref1[$i]);
- $denominator += ($target[$i] - $ref1[$i]) * ($target[$i] - $ref1[$i]);
- }
- $delta = ($denominator > 0) ? (1 - sqrt($numerator / $denominator)) : 0;
-
-
- for ($i = 0; $i < 3; ++$i) {
- $ref3[$i] = $target[$i] + ($ref1[$i] - $target[$i]) * $delta;
- }
-
-
-
- $ref2 = _color_rgb2hsl($ref2);
- $ref3 = _color_rgb2hsl($ref3);
- for ($i = 0; $i < 3; ++$i) {
- $shift[$i] = $ref2[$i] - $ref3[$i];
- }
-
-
- $given = _color_unpack($given, TRUE);
- for ($i = 0; $i < 3; ++$i) {
- $result[$i] = $target[$i] + ($given[$i] - $target[$i]) * $delta;
- }
-
-
-
- $result = _color_rgb2hsl($result);
- for ($i = 0; $i < 3; ++$i) {
- $result[$i] = min(1, max(0, $result[$i] + $shift[$i]));
- }
- $result = _color_hsl2rgb($result);
-
-
- return _color_pack($result, TRUE);
- }
-
- * Converts a hex color into an RGB triplet.
- */
- function _color_unpack($hex, $normalize = FALSE) {
- $hex = substr($hex, 1);
- if (strlen($hex) == 3) {
- $hex = $hex[0] . $hex[0] . $hex[1] . $hex[1] . $hex[2] . $hex[2];
- }
- $c = hexdec($hex);
- for ($i = 16; $i >= 0; $i -= 8) {
- $out[] = (($c >> $i) & 0xFF) / ($normalize ? 255 : 1);
- }
-
- return $out;
- }
-
- * Converts an RGB triplet to a hex color.
- */
- function _color_pack($rgb, $normalize = FALSE) {
- $out = 0;
- foreach ($rgb as $k => $v) {
- $out |= (((int) $v * ($normalize ? 255 : 1)) << (16 - $k * 8));
- }
-
- return '#' . str_pad(dechex($out), 6, 0, STR_PAD_LEFT);
- }
-
- * Converts an HSL triplet into RGB.
- */
- function _color_hsl2rgb($hsl) {
- $h = $hsl[0];
- $s = $hsl[1];
- $l = $hsl[2];
- $m2 = ($l <= 0.5) ? $l * ($s + 1) : $l + $s - $l*$s;
- $m1 = $l * 2 - $m2;
-
- return array(
- _color_hue2rgb($m1, $m2, $h + 0.33333),
- _color_hue2rgb($m1, $m2, $h),
- _color_hue2rgb($m1, $m2, $h - 0.33333),
- );
- }
-
- * Helper function for _color_hsl2rgb().
- */
- function _color_hue2rgb($m1, $m2, $h) {
- $h = ($h < 0) ? $h + 1 : (($h > 1) ? $h - 1 : $h);
- if ($h * 6 < 1) return $m1 + ($m2 - $m1) * $h * 6;
- if ($h * 2 < 1) return $m2;
- if ($h * 3 < 2) return $m1 + ($m2 - $m1) * (0.66666 - $h) * 6;
-
- return $m1;
- }
-
- * Converts an RGB triplet to HSL.
- */
- function _color_rgb2hsl($rgb) {
- $r = $rgb[0];
- $g = $rgb[1];
- $b = $rgb[2];
- $min = min($r, min($g, $b));
- $max = max($r, max($g, $b));
- $delta = $max - $min;
- $l = ($min + $max) / 2;
- $s = 0;
-
- if ($l > 0 && $l < 1) {
- $s = $delta / ($l < 0.5 ? (2 * $l) : (2 - 2 * $l));
- }
-
- $h = 0;
- if ($delta > 0) {
- if ($max == $r && $max != $g) $h += ($g - $b) / $delta;
- if ($max == $g && $max != $b) $h += (2 + ($b - $r) / $delta);
- if ($max == $b && $max != $r) $h += (4 + ($r - $g) / $delta);
- $h /= 6;
- }
-
- return array($h, $s, $l);
- }