annotate modules/color/color.module @ 9:830c812b520f

added smtp module
author root <root@paio.local>
date Mon, 28 Oct 2013 15:34:27 +0000
parents ff03f76ab3fe
children
rev   line source
danielebarchiesi@0 1 <?php
danielebarchiesi@0 2 /**
danielebarchiesi@0 3 * @file
danielebarchiesi@0 4 * Allows users to change the color scheme of themes.
danielebarchiesi@0 5 */
danielebarchiesi@0 6
danielebarchiesi@0 7 /**
danielebarchiesi@0 8 * Implements hook_help().
danielebarchiesi@0 9 */
danielebarchiesi@0 10 function color_help($path, $arg) {
danielebarchiesi@0 11 switch ($path) {
danielebarchiesi@0 12 case 'admin/help#color':
danielebarchiesi@0 13 $output = '<h3>' . t('About') . '</h3>';
danielebarchiesi@0 14 $output .= '<p>' . t('The Color module allows users with the <em>Administer site configuration</em> permission to quickly and easily change the color scheme of themes that have been built to be compatible with it. For more information, see the online handbook entry for <a href="@color">Color module</a>.', array('@color' => 'http://drupal.org/documentation/modules/color')) . '</p>';
danielebarchiesi@0 15 $output .= '<h3>' . t('Uses') . '</h3>';
danielebarchiesi@0 16 $output .= '<dl>';
danielebarchiesi@0 17 $output .= '<dt>' . t('Changing colors') . '</dt>';
danielebarchiesi@0 18 $output .= '<dd>' . t("Using the Color module allows you to easily change the color of links, backgrounds, text, and other theme elements. To change the color settings for a compatible theme, select the <em>Settings</em> link for your theme on the <a href='@configure'>Themes administration page</a>. If you don't see a color picker on that page, then your theme is not compatible with the color module. If you are sure that the theme does indeed support the color module, but the color picker does not appear, then <a href='@troubleshoot'>follow these troubleshooting procedures</a>.", array('@configure' => url('admin/appearance'), '@troubleshoot' => 'http://drupal.org/node/109457')) . '</dd>';
danielebarchiesi@0 19 $output .= '<dd>' . t("The Color module saves a modified copy of the theme's specified stylesheets in the files directory. This means that if you make any manual changes to your theme's stylesheet, <em>you must save your color settings again, even if they haven't changed</em>. This step is required because the module stylesheets (in the files directory) need to be recreated to include your changes.") . '</dd>';
danielebarchiesi@0 20 $output .= '</dl>';
danielebarchiesi@0 21 return $output;
danielebarchiesi@0 22 }
danielebarchiesi@0 23 }
danielebarchiesi@0 24
danielebarchiesi@0 25 /**
danielebarchiesi@0 26 * Implements hook_theme().
danielebarchiesi@0 27 */
danielebarchiesi@0 28 function color_theme() {
danielebarchiesi@0 29 return array(
danielebarchiesi@0 30 'color_scheme_form' => array(
danielebarchiesi@0 31 'render element' => 'form',
danielebarchiesi@0 32 ),
danielebarchiesi@0 33 );
danielebarchiesi@0 34 }
danielebarchiesi@0 35
danielebarchiesi@0 36 /**
danielebarchiesi@0 37 * Implements hook_form_FORM_ID_alter().
danielebarchiesi@0 38 */
danielebarchiesi@0 39 function color_form_system_theme_settings_alter(&$form, &$form_state) {
danielebarchiesi@0 40 if (isset($form_state['build_info']['args'][0]) && ($theme = $form_state['build_info']['args'][0]) && color_get_info($theme) && function_exists('gd_info')) {
danielebarchiesi@0 41 $form['color'] = array(
danielebarchiesi@0 42 '#type' => 'fieldset',
danielebarchiesi@0 43 '#title' => t('Color scheme'),
danielebarchiesi@0 44 '#weight' => -1,
danielebarchiesi@0 45 '#attributes' => array('id' => 'color_scheme_form'),
danielebarchiesi@0 46 '#theme' => 'color_scheme_form',
danielebarchiesi@0 47 );
danielebarchiesi@0 48 $form['color'] += color_scheme_form($form, $form_state, $theme);
danielebarchiesi@0 49 $form['#validate'][] = 'color_scheme_form_validate';
danielebarchiesi@0 50 $form['#submit'][] = 'color_scheme_form_submit';
danielebarchiesi@0 51 }
danielebarchiesi@0 52 }
danielebarchiesi@0 53
danielebarchiesi@0 54 /**
danielebarchiesi@0 55 * Implements hook_form_FORM_ID_alter().
danielebarchiesi@0 56 */
danielebarchiesi@0 57 function color_form_system_themes_alter(&$form, &$form_state) {
danielebarchiesi@0 58 _color_theme_select_form_alter($form, $form_state);
danielebarchiesi@0 59 }
danielebarchiesi@0 60
danielebarchiesi@0 61 /**
danielebarchiesi@0 62 * Helper for hook_form_FORM_ID_alter() implementations.
danielebarchiesi@0 63 */
danielebarchiesi@0 64 function _color_theme_select_form_alter(&$form, &$form_state) {
danielebarchiesi@0 65 // Use the generated screenshot in the theme list.
danielebarchiesi@0 66 $themes = list_themes();
danielebarchiesi@0 67 foreach (element_children($form) as $theme) {
danielebarchiesi@0 68 if ($screenshot = variable_get('color_' . $theme . '_screenshot')) {
danielebarchiesi@0 69 if (isset($form[$theme]['screenshot'])) {
danielebarchiesi@0 70 $form[$theme]['screenshot']['#markup'] = theme('image', array('path' => $screenshot, 'title' => '', 'attributes' => array('class' => array('screenshot'))));
danielebarchiesi@0 71 }
danielebarchiesi@0 72 }
danielebarchiesi@0 73 }
danielebarchiesi@0 74 }
danielebarchiesi@0 75
danielebarchiesi@0 76 /**
danielebarchiesi@0 77 * Replaces style sheets with color-altered style sheets.
danielebarchiesi@0 78 *
danielebarchiesi@0 79 * A theme that supports the color module should call this function from its
danielebarchiesi@0 80 * THEME_process_html() function, so that the correct style sheets are
danielebarchiesi@0 81 * included when html.tpl.php is rendered.
danielebarchiesi@0 82 *
danielebarchiesi@0 83 * @see theme()
danielebarchiesi@0 84 */
danielebarchiesi@0 85 function _color_html_alter(&$vars) {
danielebarchiesi@0 86 global $theme_key;
danielebarchiesi@0 87 $themes = list_themes();
danielebarchiesi@0 88
danielebarchiesi@0 89 // Override stylesheets.
danielebarchiesi@0 90 $color_paths = variable_get('color_' . $theme_key . '_stylesheets', array());
danielebarchiesi@0 91 if (!empty($color_paths)) {
danielebarchiesi@0 92
danielebarchiesi@0 93 foreach ($themes[$theme_key]->stylesheets['all'] as $base_filename => $old_path) {
danielebarchiesi@0 94 // Loop over the path array with recolored CSS files to find matching
danielebarchiesi@0 95 // paths which could replace the non-recolored paths.
danielebarchiesi@0 96 foreach ($color_paths as $color_path) {
danielebarchiesi@0 97 // Color module currently requires unique file names to be used,
danielebarchiesi@0 98 // which allows us to compare different file paths.
danielebarchiesi@0 99 if (drupal_basename($old_path) == drupal_basename($color_path)) {
danielebarchiesi@0 100 // Replace the path to the new css file.
danielebarchiesi@0 101 // This keeps the order of the stylesheets intact.
danielebarchiesi@0 102 $vars['css'][$old_path]['data'] = $color_path;
danielebarchiesi@0 103 }
danielebarchiesi@0 104 }
danielebarchiesi@0 105 }
danielebarchiesi@0 106
danielebarchiesi@0 107 $vars['styles'] = drupal_get_css($vars['css']);
danielebarchiesi@0 108 }
danielebarchiesi@0 109 }
danielebarchiesi@0 110
danielebarchiesi@0 111 /**
danielebarchiesi@0 112 * Replaces the logo with a color-altered logo.
danielebarchiesi@0 113 *
danielebarchiesi@0 114 * A theme that supports the color module should call this function from its
danielebarchiesi@0 115 * THEME_process_page() function, so that the correct logo is included when
danielebarchiesi@0 116 * page.tpl.php is rendered.
danielebarchiesi@0 117 *
danielebarchiesi@0 118 * @see theme()
danielebarchiesi@0 119 */
danielebarchiesi@0 120 function _color_page_alter(&$vars) {
danielebarchiesi@0 121 global $theme_key;
danielebarchiesi@0 122
danielebarchiesi@0 123 // Override logo.
danielebarchiesi@0 124 $logo = variable_get('color_' . $theme_key . '_logo');
danielebarchiesi@0 125 if ($logo && $vars['logo'] && preg_match('!' . $theme_key . '/logo.png$!', $vars['logo'])) {
danielebarchiesi@0 126 $vars['logo'] = file_create_url($logo);
danielebarchiesi@0 127 }
danielebarchiesi@0 128 }
danielebarchiesi@0 129
danielebarchiesi@0 130 /**
danielebarchiesi@0 131 * Retrieves the Color module information for a particular theme.
danielebarchiesi@0 132 */
danielebarchiesi@0 133 function color_get_info($theme) {
danielebarchiesi@0 134 static $theme_info = array();
danielebarchiesi@0 135
danielebarchiesi@0 136 if (isset($theme_info[$theme])) {
danielebarchiesi@0 137 return $theme_info[$theme];
danielebarchiesi@0 138 }
danielebarchiesi@0 139
danielebarchiesi@0 140 $path = drupal_get_path('theme', $theme);
danielebarchiesi@0 141 $file = DRUPAL_ROOT . '/' . $path . '/color/color.inc';
danielebarchiesi@0 142 if ($path && file_exists($file)) {
danielebarchiesi@0 143 include $file;
danielebarchiesi@0 144 $theme_info[$theme] = $info;
danielebarchiesi@0 145 return $info;
danielebarchiesi@0 146 }
danielebarchiesi@0 147 }
danielebarchiesi@0 148
danielebarchiesi@0 149 /**
danielebarchiesi@0 150 * Retrieves the color palette for a particular theme.
danielebarchiesi@0 151 */
danielebarchiesi@0 152 function color_get_palette($theme, $default = FALSE) {
danielebarchiesi@0 153 // Fetch and expand default palette.
danielebarchiesi@0 154 $info = color_get_info($theme);
danielebarchiesi@0 155 $palette = $info['schemes']['default']['colors'];
danielebarchiesi@0 156
danielebarchiesi@0 157 // Load variable.
danielebarchiesi@0 158 return $default ? $palette : variable_get('color_' . $theme . '_palette', $palette);
danielebarchiesi@0 159 }
danielebarchiesi@0 160
danielebarchiesi@0 161 /**
danielebarchiesi@0 162 * Form constructor for the color configuration form for a particular theme.
danielebarchiesi@0 163 *
danielebarchiesi@0 164 * @param $theme
danielebarchiesi@0 165 * The machine name of the theme whose color settings are being configured.
danielebarchiesi@0 166 *
danielebarchiesi@0 167 * @see color_scheme_form_validate()
danielebarchiesi@0 168 * @see color_scheme_form_submit()
danielebarchiesi@0 169 * @ingroup forms
danielebarchiesi@0 170 */
danielebarchiesi@0 171 function color_scheme_form($complete_form, &$form_state, $theme) {
danielebarchiesi@0 172 $base = drupal_get_path('module', 'color');
danielebarchiesi@0 173 $info = color_get_info($theme);
danielebarchiesi@0 174
danielebarchiesi@0 175 $info['schemes'][''] = array('title' => t('Custom'), 'colors' => array());
danielebarchiesi@0 176 $color_sets = array();
danielebarchiesi@0 177 $schemes = array();
danielebarchiesi@0 178 foreach ($info['schemes'] as $key => $scheme) {
danielebarchiesi@0 179 $color_sets[$key] = $scheme['title'];
danielebarchiesi@0 180 $schemes[$key] = $scheme['colors'];
danielebarchiesi@0 181 $schemes[$key] += $info['schemes']['default']['colors'];
danielebarchiesi@0 182 }
danielebarchiesi@0 183
danielebarchiesi@0 184 // See if we're using a predefined scheme.
danielebarchiesi@0 185 // Note: we use the original theme when the default scheme is chosen.
danielebarchiesi@0 186 $current_scheme = variable_get('color_' . $theme . '_palette', array());
danielebarchiesi@0 187 foreach ($schemes as $key => $scheme) {
danielebarchiesi@0 188 if ($current_scheme == $scheme) {
danielebarchiesi@0 189 $scheme_name = $key;
danielebarchiesi@0 190 break;
danielebarchiesi@0 191 }
danielebarchiesi@0 192 }
danielebarchiesi@0 193 if (empty($scheme_name)) {
danielebarchiesi@0 194 if (empty($current_scheme)) {
danielebarchiesi@0 195 $scheme_name = 'default';
danielebarchiesi@0 196 }
danielebarchiesi@0 197 else {
danielebarchiesi@0 198 $scheme_name = '';
danielebarchiesi@0 199 }
danielebarchiesi@0 200 }
danielebarchiesi@0 201
danielebarchiesi@0 202 // Add scheme selector.
danielebarchiesi@0 203 $form['scheme'] = array(
danielebarchiesi@0 204 '#type' => 'select',
danielebarchiesi@0 205 '#title' => t('Color set'),
danielebarchiesi@0 206 '#options' => $color_sets,
danielebarchiesi@0 207 '#default_value' => $scheme_name,
danielebarchiesi@0 208 '#attached' => array(
danielebarchiesi@0 209 // Add Farbtastic color picker.
danielebarchiesi@0 210 'library' => array(
danielebarchiesi@0 211 array('system', 'farbtastic'),
danielebarchiesi@0 212 ),
danielebarchiesi@0 213 // Add custom CSS.
danielebarchiesi@0 214 'css' => array(
danielebarchiesi@0 215 $base . '/color.css' => array(),
danielebarchiesi@0 216 ),
danielebarchiesi@0 217 // Add custom JavaScript.
danielebarchiesi@0 218 'js' => array(
danielebarchiesi@0 219 $base . '/color.js',
danielebarchiesi@0 220 array(
danielebarchiesi@0 221 'data' => array(
danielebarchiesi@0 222 'color' => array(
danielebarchiesi@0 223 'reference' => color_get_palette($theme, TRUE),
danielebarchiesi@0 224 'schemes' => $schemes,
danielebarchiesi@0 225 ),
danielebarchiesi@0 226 'gradients' => $info['gradients'],
danielebarchiesi@0 227 ),
danielebarchiesi@0 228 'type' => 'setting',
danielebarchiesi@0 229 ),
danielebarchiesi@0 230 ),
danielebarchiesi@0 231 ),
danielebarchiesi@0 232 );
danielebarchiesi@0 233
danielebarchiesi@0 234 // Add palette fields.
danielebarchiesi@0 235 $palette = color_get_palette($theme);
danielebarchiesi@0 236 $names = $info['fields'];
danielebarchiesi@0 237 $form['palette']['#tree'] = TRUE;
danielebarchiesi@0 238 foreach ($palette as $name => $value) {
danielebarchiesi@0 239 if (isset($names[$name])) {
danielebarchiesi@0 240 $form['palette'][$name] = array(
danielebarchiesi@0 241 '#type' => 'textfield',
danielebarchiesi@0 242 '#title' => check_plain($names[$name]),
danielebarchiesi@0 243 '#default_value' => $value,
danielebarchiesi@0 244 '#size' => 8,
danielebarchiesi@0 245 );
danielebarchiesi@0 246 }
danielebarchiesi@0 247 }
danielebarchiesi@0 248 $form['theme'] = array('#type' => 'value', '#value' => $theme);
danielebarchiesi@0 249 $form['info'] = array('#type' => 'value', '#value' => $info);
danielebarchiesi@0 250
danielebarchiesi@0 251 return $form;
danielebarchiesi@0 252 }
danielebarchiesi@0 253
danielebarchiesi@0 254 /**
danielebarchiesi@0 255 * Returns HTML for a theme's color form.
danielebarchiesi@0 256 *
danielebarchiesi@0 257 * @param $variables
danielebarchiesi@0 258 * An associative array containing:
danielebarchiesi@0 259 * - form: A render element representing the form.
danielebarchiesi@0 260 *
danielebarchiesi@0 261 * @ingroup themeable
danielebarchiesi@0 262 */
danielebarchiesi@0 263 function theme_color_scheme_form($variables) {
danielebarchiesi@0 264 $form = $variables['form'];
danielebarchiesi@0 265
danielebarchiesi@0 266 $theme = $form['theme']['#value'];
danielebarchiesi@0 267 $info = $form['info']['#value'];
danielebarchiesi@0 268 $path = drupal_get_path('theme', $theme) . '/';
danielebarchiesi@0 269 drupal_add_css($path . $info['preview_css']);
danielebarchiesi@0 270
danielebarchiesi@0 271 $preview_js_path = isset($info['preview_js']) ? $path . $info['preview_js'] : drupal_get_path('module', 'color') . '/' . 'preview.js';
danielebarchiesi@0 272 // Add the JS at a weight below color.js.
danielebarchiesi@0 273 drupal_add_js($preview_js_path, array('weight' => -1));
danielebarchiesi@0 274
danielebarchiesi@0 275 $output = '';
danielebarchiesi@0 276 $output .= '<div class="color-form clearfix">';
danielebarchiesi@0 277 // Color schemes
danielebarchiesi@0 278 $output .= drupal_render($form['scheme']);
danielebarchiesi@0 279 // Palette
danielebarchiesi@0 280 $output .= '<div id="palette" class="clearfix">';
danielebarchiesi@0 281 foreach (element_children($form['palette']) as $name) {
danielebarchiesi@0 282 $output .= drupal_render($form['palette'][$name]);
danielebarchiesi@0 283 }
danielebarchiesi@0 284 $output .= '</div>';
danielebarchiesi@0 285 // Preview
danielebarchiesi@0 286 $output .= drupal_render_children($form);
danielebarchiesi@0 287 $output .= '<h2>' . t('Preview') . '</h2>';
danielebarchiesi@0 288 // Attempt to load preview HTML if the theme provides it.
danielebarchiesi@0 289 $preview_html_path = DRUPAL_ROOT . '/' . (isset($info['preview_html']) ? drupal_get_path('theme', $theme) . '/' . $info['preview_html'] : drupal_get_path('module', 'color') . '/preview.html');
danielebarchiesi@0 290 $output .= file_get_contents($preview_html_path);
danielebarchiesi@0 291 // Close the wrapper div.
danielebarchiesi@0 292 $output .= '</div>';
danielebarchiesi@0 293
danielebarchiesi@0 294 return $output;
danielebarchiesi@0 295 }
danielebarchiesi@0 296
danielebarchiesi@0 297 /**
danielebarchiesi@0 298 * Form validation handler for color_scheme_form().
danielebarchiesi@0 299 *
danielebarchiesi@0 300 * @see color_scheme_form_submit()
danielebarchiesi@0 301 */
danielebarchiesi@0 302 function color_scheme_form_validate($form, &$form_state) {
danielebarchiesi@0 303 // Only accept hexadecimal CSS color strings to avoid XSS upon use.
danielebarchiesi@0 304 foreach ($form_state['values']['palette'] as $key => $color) {
danielebarchiesi@0 305 if (!preg_match('/^#([a-f0-9]{3}){1,2}$/iD', $color)) {
danielebarchiesi@0 306 form_set_error('palette][' . $key, t('%name must be a valid hexadecimal CSS color value.', array('%name' => $form['color']['palette'][$key]['#title'])));
danielebarchiesi@0 307 }
danielebarchiesi@0 308 }
danielebarchiesi@0 309 }
danielebarchiesi@0 310
danielebarchiesi@0 311 /**
danielebarchiesi@0 312 * Form submission handler for color_scheme_form().
danielebarchiesi@0 313 *
danielebarchiesi@0 314 * @see color_scheme_form_validate()
danielebarchiesi@0 315 */
danielebarchiesi@0 316 function color_scheme_form_submit($form, &$form_state) {
danielebarchiesi@0 317 // Get theme coloring info.
danielebarchiesi@0 318 if (!isset($form_state['values']['info'])) {
danielebarchiesi@0 319 return;
danielebarchiesi@0 320 }
danielebarchiesi@0 321 $theme = $form_state['values']['theme'];
danielebarchiesi@0 322 $info = $form_state['values']['info'];
danielebarchiesi@0 323
danielebarchiesi@0 324 // Resolve palette.
danielebarchiesi@0 325 $palette = $form_state['values']['palette'];
danielebarchiesi@0 326 if ($form_state['values']['scheme'] != '') {
danielebarchiesi@0 327 foreach ($palette as $key => $color) {
danielebarchiesi@0 328 if (isset($info['schemes'][$form_state['values']['scheme']]['colors'][$key])) {
danielebarchiesi@0 329 $palette[$key] = $info['schemes'][$form_state['values']['scheme']]['colors'][$key];
danielebarchiesi@0 330 }
danielebarchiesi@0 331 }
danielebarchiesi@0 332 $palette += $info['schemes']['default']['colors'];
danielebarchiesi@0 333 }
danielebarchiesi@0 334
danielebarchiesi@0 335 // Make sure enough memory is available, if PHP's memory limit is compiled in.
danielebarchiesi@0 336 if (function_exists('memory_get_usage')) {
danielebarchiesi@0 337 // Fetch source image dimensions.
danielebarchiesi@0 338 $source = drupal_get_path('theme', $theme) . '/' . $info['base_image'];
danielebarchiesi@0 339 list($width, $height) = getimagesize($source);
danielebarchiesi@0 340
danielebarchiesi@0 341 // We need at least a copy of the source and a target buffer of the same
danielebarchiesi@0 342 // size (both at 32bpp).
danielebarchiesi@0 343 $required = $width * $height * 8;
danielebarchiesi@0 344 // We intend to prevent color scheme changes if there isn't enough memory
danielebarchiesi@0 345 // available. memory_get_usage(TRUE) returns a more accurate number than
danielebarchiesi@0 346 // memory_get_usage(), therefore we won't inadvertently reject a color
danielebarchiesi@0 347 // scheme change based on a faulty memory calculation.
danielebarchiesi@0 348 $usage = memory_get_usage(TRUE);
danielebarchiesi@0 349 $memory_limit = ini_get('memory_limit');
danielebarchiesi@0 350 $size = parse_size($memory_limit);
danielebarchiesi@0 351 if (!drupal_check_memory_limit($usage + $required, $memory_limit)) {
danielebarchiesi@0 352 drupal_set_message(t('There is not enough memory available to PHP to change this theme\'s color scheme. You need at least %size more. Check the <a href="@url">PHP documentation</a> for more information.', array('%size' => format_size($usage + $required - $size), '@url' => 'http://www.php.net/manual/ini.core.php#ini.sect.resource-limits')), 'error');
danielebarchiesi@0 353 return;
danielebarchiesi@0 354 }
danielebarchiesi@0 355 }
danielebarchiesi@0 356
danielebarchiesi@0 357 // Delete old files.
danielebarchiesi@0 358 foreach (variable_get('color_' . $theme . '_files', array()) as $file) {
danielebarchiesi@0 359 @drupal_unlink($file);
danielebarchiesi@0 360 }
danielebarchiesi@0 361 if (isset($file) && $file = dirname($file)) {
danielebarchiesi@0 362 @drupal_rmdir($file);
danielebarchiesi@0 363 }
danielebarchiesi@0 364
danielebarchiesi@0 365 // Don't render the default colorscheme, use the standard theme instead.
danielebarchiesi@0 366 if (implode(',', color_get_palette($theme, TRUE)) == implode(',', $palette)) {
danielebarchiesi@0 367 variable_del('color_' . $theme . '_palette');
danielebarchiesi@0 368 variable_del('color_' . $theme . '_stylesheets');
danielebarchiesi@0 369 variable_del('color_' . $theme . '_logo');
danielebarchiesi@0 370 variable_del('color_' . $theme . '_files');
danielebarchiesi@0 371 variable_del('color_' . $theme . '_screenshot');
danielebarchiesi@0 372 return;
danielebarchiesi@0 373 }
danielebarchiesi@0 374
danielebarchiesi@0 375 // Prepare target locations for generated files.
danielebarchiesi@0 376 $id = $theme . '-' . substr(hash('sha256', serialize($palette) . microtime()), 0, 8);
danielebarchiesi@0 377 $paths['color'] = 'public://color';
danielebarchiesi@0 378 $paths['target'] = $paths['color'] . '/' . $id;
danielebarchiesi@0 379 foreach ($paths as $path) {
danielebarchiesi@0 380 file_prepare_directory($path, FILE_CREATE_DIRECTORY);
danielebarchiesi@0 381 }
danielebarchiesi@0 382 $paths['target'] = $paths['target'] . '/';
danielebarchiesi@0 383 $paths['id'] = $id;
danielebarchiesi@0 384 $paths['source'] = drupal_get_path('theme', $theme) . '/';
danielebarchiesi@0 385 $paths['files'] = $paths['map'] = array();
danielebarchiesi@0 386
danielebarchiesi@0 387 // Save palette and logo location.
danielebarchiesi@0 388 variable_set('color_' . $theme . '_palette', $palette);
danielebarchiesi@0 389 variable_set('color_' . $theme . '_logo', $paths['target'] . 'logo.png');
danielebarchiesi@0 390
danielebarchiesi@0 391 // Copy over neutral images.
danielebarchiesi@0 392 foreach ($info['copy'] as $file) {
danielebarchiesi@0 393 $base = drupal_basename($file);
danielebarchiesi@0 394 $source = $paths['source'] . $file;
danielebarchiesi@0 395 $filepath = file_unmanaged_copy($source, $paths['target'] . $base);
danielebarchiesi@0 396 $paths['map'][$file] = $base;
danielebarchiesi@0 397 $paths['files'][] = $filepath;
danielebarchiesi@0 398 }
danielebarchiesi@0 399
danielebarchiesi@0 400 // Render new images, if image has been provided.
danielebarchiesi@0 401 if ($info['base_image']) {
danielebarchiesi@0 402 _color_render_images($theme, $info, $paths, $palette);
danielebarchiesi@0 403 }
danielebarchiesi@0 404
danielebarchiesi@0 405 // Rewrite theme stylesheets.
danielebarchiesi@0 406 $css = array();
danielebarchiesi@0 407 foreach ($info['css'] as $stylesheet) {
danielebarchiesi@0 408 // Build a temporary array with LTR and RTL files.
danielebarchiesi@0 409 $files = array();
danielebarchiesi@0 410 if (file_exists($paths['source'] . $stylesheet)) {
danielebarchiesi@0 411 $files[] = $stylesheet;
danielebarchiesi@0 412
danielebarchiesi@0 413 $rtl_file = str_replace('.css', '-rtl.css', $stylesheet);
danielebarchiesi@0 414 if (file_exists($paths['source'] . $rtl_file)) {
danielebarchiesi@0 415 $files[] = $rtl_file;
danielebarchiesi@0 416 }
danielebarchiesi@0 417 }
danielebarchiesi@0 418
danielebarchiesi@0 419 foreach ($files as $file) {
danielebarchiesi@0 420 // Aggregate @imports recursively for each configured top level CSS file
danielebarchiesi@0 421 // without optimization. Aggregation and optimization will be
danielebarchiesi@0 422 // handled by drupal_build_css_cache() only.
danielebarchiesi@0 423 $style = drupal_load_stylesheet($paths['source'] . $file, FALSE);
danielebarchiesi@0 424
danielebarchiesi@0 425 // Return the path to where this CSS file originated from, stripping
danielebarchiesi@0 426 // off the name of the file at the end of the path.
danielebarchiesi@0 427 $base = base_path() . dirname($paths['source'] . $file) . '/';
danielebarchiesi@0 428 _drupal_build_css_path(NULL, $base);
danielebarchiesi@0 429
danielebarchiesi@0 430 // Prefix all paths within this CSS file, ignoring absolute paths.
danielebarchiesi@0 431 $style = preg_replace_callback('/url\([\'"]?(?![a-z]+:|\/+)([^\'")]+)[\'"]?\)/i', '_drupal_build_css_path', $style);
danielebarchiesi@0 432
danielebarchiesi@0 433 // Rewrite stylesheet with new colors.
danielebarchiesi@0 434 $style = _color_rewrite_stylesheet($theme, $info, $paths, $palette, $style);
danielebarchiesi@0 435 $base_file = drupal_basename($file);
danielebarchiesi@0 436 $css[] = $paths['target'] . $base_file;
danielebarchiesi@0 437 _color_save_stylesheet($paths['target'] . $base_file, $style, $paths);
danielebarchiesi@0 438 }
danielebarchiesi@0 439 }
danielebarchiesi@0 440
danielebarchiesi@0 441 // Maintain list of files.
danielebarchiesi@0 442 variable_set('color_' . $theme . '_stylesheets', $css);
danielebarchiesi@0 443 variable_set('color_' . $theme . '_files', $paths['files']);
danielebarchiesi@0 444 }
danielebarchiesi@0 445
danielebarchiesi@0 446 /**
danielebarchiesi@0 447 * Rewrites the stylesheet to match the colors in the palette.
danielebarchiesi@0 448 */
danielebarchiesi@0 449 function _color_rewrite_stylesheet($theme, &$info, &$paths, $palette, $style) {
danielebarchiesi@0 450 $themes = list_themes();
danielebarchiesi@0 451 // Prepare color conversion table.
danielebarchiesi@0 452 $conversion = $palette;
danielebarchiesi@0 453 foreach ($conversion as $k => $v) {
danielebarchiesi@0 454 $conversion[$k] = drupal_strtolower($v);
danielebarchiesi@0 455 }
danielebarchiesi@0 456 $default = color_get_palette($theme, TRUE);
danielebarchiesi@0 457
danielebarchiesi@0 458 // Split off the "Don't touch" section of the stylesheet.
danielebarchiesi@0 459 $split = "Color Module: Don't touch";
danielebarchiesi@0 460 if (strpos($style, $split) !== FALSE) {
danielebarchiesi@0 461 list($style, $fixed) = explode($split, $style);
danielebarchiesi@0 462 }
danielebarchiesi@0 463
danielebarchiesi@0 464 // Find all colors in the stylesheet and the chunks in between.
danielebarchiesi@0 465 $style = preg_split('/(#[0-9a-f]{6}|#[0-9a-f]{3})/i', $style, -1, PREG_SPLIT_DELIM_CAPTURE);
danielebarchiesi@0 466 $is_color = FALSE;
danielebarchiesi@0 467 $output = '';
danielebarchiesi@0 468 $base = 'base';
danielebarchiesi@0 469
danielebarchiesi@0 470 // Iterate over all the parts.
danielebarchiesi@0 471 foreach ($style as $chunk) {
danielebarchiesi@0 472 if ($is_color) {
danielebarchiesi@0 473 $chunk = drupal_strtolower($chunk);
danielebarchiesi@0 474 // Check if this is one of the colors in the default palette.
danielebarchiesi@0 475 if ($key = array_search($chunk, $default)) {
danielebarchiesi@0 476 $chunk = $conversion[$key];
danielebarchiesi@0 477 }
danielebarchiesi@0 478 // Not a pre-set color. Extrapolate from the base.
danielebarchiesi@0 479 else {
danielebarchiesi@0 480 $chunk = _color_shift($palette[$base], $default[$base], $chunk, $info['blend_target']);
danielebarchiesi@0 481 }
danielebarchiesi@0 482 }
danielebarchiesi@0 483 else {
danielebarchiesi@0 484 // Determine the most suitable base color for the next color.
danielebarchiesi@0 485
danielebarchiesi@0 486 // 'a' declarations. Use link.
danielebarchiesi@0 487 if (preg_match('@[^a-z0-9_-](a)[^a-z0-9_-][^/{]*{[^{]+$@i', $chunk)) {
danielebarchiesi@0 488 $base = 'link';
danielebarchiesi@0 489 }
danielebarchiesi@0 490 // 'color:' styles. Use text.
danielebarchiesi@0 491 elseif (preg_match('/(?<!-)color[^{:]*:[^{#]*$/i', $chunk)) {
danielebarchiesi@0 492 $base = 'text';
danielebarchiesi@0 493 }
danielebarchiesi@0 494 // Reset back to base.
danielebarchiesi@0 495 else {
danielebarchiesi@0 496 $base = 'base';
danielebarchiesi@0 497 }
danielebarchiesi@0 498 }
danielebarchiesi@0 499 $output .= $chunk;
danielebarchiesi@0 500 $is_color = !$is_color;
danielebarchiesi@0 501 }
danielebarchiesi@0 502 // Append fixed colors segment.
danielebarchiesi@0 503 if (isset($fixed)) {
danielebarchiesi@0 504 $output .= $fixed;
danielebarchiesi@0 505 }
danielebarchiesi@0 506
danielebarchiesi@0 507 // Replace paths to images.
danielebarchiesi@0 508 foreach ($paths['map'] as $before => $after) {
danielebarchiesi@0 509 $before = base_path() . $paths['source'] . $before;
danielebarchiesi@0 510 $before = preg_replace('`(^|/)(?!../)([^/]+)/../`', '$1', $before);
danielebarchiesi@0 511 $output = str_replace($before, $after, $output);
danielebarchiesi@0 512 }
danielebarchiesi@0 513
danielebarchiesi@0 514 return $output;
danielebarchiesi@0 515 }
danielebarchiesi@0 516
danielebarchiesi@0 517 /**
danielebarchiesi@0 518 * Saves the rewritten stylesheet to disk.
danielebarchiesi@0 519 */
danielebarchiesi@0 520 function _color_save_stylesheet($file, $style, &$paths) {
danielebarchiesi@0 521 $filepath = file_unmanaged_save_data($style, $file, FILE_EXISTS_REPLACE);
danielebarchiesi@0 522 $paths['files'][] = $filepath;
danielebarchiesi@0 523
danielebarchiesi@0 524 // Set standard file permissions for webserver-generated files.
danielebarchiesi@0 525 drupal_chmod($file);
danielebarchiesi@0 526 }
danielebarchiesi@0 527
danielebarchiesi@0 528 /**
danielebarchiesi@0 529 * Renders images that match a given palette.
danielebarchiesi@0 530 */
danielebarchiesi@0 531 function _color_render_images($theme, &$info, &$paths, $palette) {
danielebarchiesi@0 532 // Prepare template image.
danielebarchiesi@0 533 $source = $paths['source'] . '/' . $info['base_image'];
danielebarchiesi@0 534 $source = imagecreatefrompng($source);
danielebarchiesi@0 535 $width = imagesx($source);
danielebarchiesi@0 536 $height = imagesy($source);
danielebarchiesi@0 537
danielebarchiesi@0 538 // Prepare target buffer.
danielebarchiesi@0 539 $target = imagecreatetruecolor($width, $height);
danielebarchiesi@0 540 imagealphablending($target, TRUE);
danielebarchiesi@0 541
danielebarchiesi@0 542 // Fill regions of solid color.
danielebarchiesi@0 543 foreach ($info['fill'] as $color => $fill) {
danielebarchiesi@0 544 imagefilledrectangle($target, $fill[0], $fill[1], $fill[0] + $fill[2], $fill[1] + $fill[3], _color_gd($target, $palette[$color]));
danielebarchiesi@0 545 }
danielebarchiesi@0 546
danielebarchiesi@0 547 // Render gradients.
danielebarchiesi@0 548 foreach ($info['gradients'] as $gradient) {
danielebarchiesi@0 549 // Get direction of the gradient.
danielebarchiesi@0 550 if (isset($gradient['direction']) && $gradient['direction'] == 'horizontal') {
danielebarchiesi@0 551 // Horizontal gradient.
danielebarchiesi@0 552 for ($x = 0; $x < $gradient['dimension'][2]; $x++) {
danielebarchiesi@0 553 $color = _color_blend($target, $palette[$gradient['colors'][0]], $palette[$gradient['colors'][1]], $x / ($gradient['dimension'][2] - 1));
danielebarchiesi@0 554 imagefilledrectangle($target, ($gradient['dimension'][0] + $x), $gradient['dimension'][1], ($gradient['dimension'][0] + $x + 1), ($gradient['dimension'][1] + $gradient['dimension'][3]), $color);
danielebarchiesi@0 555 }
danielebarchiesi@0 556 }
danielebarchiesi@0 557 else {
danielebarchiesi@0 558 // Vertical gradient.
danielebarchiesi@0 559 for ($y = 0; $y < $gradient['dimension'][3]; $y++) {
danielebarchiesi@0 560 $color = _color_blend($target, $palette[$gradient['colors'][0]], $palette[$gradient['colors'][1]], $y / ($gradient['dimension'][3] - 1));
danielebarchiesi@0 561 imagefilledrectangle($target, $gradient['dimension'][0], $gradient['dimension'][1] + $y, $gradient['dimension'][0] + $gradient['dimension'][2], $gradient['dimension'][1] + $y + 1, $color);
danielebarchiesi@0 562 }
danielebarchiesi@0 563 }
danielebarchiesi@0 564 }
danielebarchiesi@0 565
danielebarchiesi@0 566 // Blend over template.
danielebarchiesi@0 567 imagecopy($target, $source, 0, 0, 0, 0, $width, $height);
danielebarchiesi@0 568
danielebarchiesi@0 569 // Clean up template image.
danielebarchiesi@0 570 imagedestroy($source);
danielebarchiesi@0 571
danielebarchiesi@0 572 // Cut out slices.
danielebarchiesi@0 573 foreach ($info['slices'] as $file => $coord) {
danielebarchiesi@0 574 list($x, $y, $width, $height) = $coord;
danielebarchiesi@0 575 $base = drupal_basename($file);
danielebarchiesi@0 576 $image = drupal_realpath($paths['target'] . $base);
danielebarchiesi@0 577
danielebarchiesi@0 578 // Cut out slice.
danielebarchiesi@0 579 if ($file == 'screenshot.png') {
danielebarchiesi@0 580 $slice = imagecreatetruecolor(150, 90);
danielebarchiesi@0 581 imagecopyresampled($slice, $target, 0, 0, $x, $y, 150, 90, $width, $height);
danielebarchiesi@0 582 variable_set('color_' . $theme . '_screenshot', $image);
danielebarchiesi@0 583 }
danielebarchiesi@0 584 else {
danielebarchiesi@0 585 $slice = imagecreatetruecolor($width, $height);
danielebarchiesi@0 586 imagecopy($slice, $target, 0, 0, $x, $y, $width, $height);
danielebarchiesi@0 587 }
danielebarchiesi@0 588
danielebarchiesi@0 589 // Save image.
danielebarchiesi@0 590 imagepng($slice, $image);
danielebarchiesi@0 591 imagedestroy($slice);
danielebarchiesi@0 592 $paths['files'][] = $image;
danielebarchiesi@0 593
danielebarchiesi@0 594 // Set standard file permissions for webserver-generated files
danielebarchiesi@0 595 drupal_chmod($image);
danielebarchiesi@0 596
danielebarchiesi@0 597 // Build before/after map of image paths.
danielebarchiesi@0 598 $paths['map'][$file] = $base;
danielebarchiesi@0 599 }
danielebarchiesi@0 600
danielebarchiesi@0 601 // Clean up target buffer.
danielebarchiesi@0 602 imagedestroy($target);
danielebarchiesi@0 603 }
danielebarchiesi@0 604
danielebarchiesi@0 605 /**
danielebarchiesi@0 606 * Shifts a given color, using a reference pair and a target blend color.
danielebarchiesi@0 607 *
danielebarchiesi@0 608 * Note: this function is significantly different from the JS version, as it
danielebarchiesi@0 609 * is written to match the blended images perfectly.
danielebarchiesi@0 610 *
danielebarchiesi@0 611 * Constraint: if (ref2 == target + (ref1 - target) * delta) for some fraction
danielebarchiesi@0 612 * delta then (return == target + (given - target) * delta).
danielebarchiesi@0 613 *
danielebarchiesi@0 614 * Loose constraint: Preserve relative positions in saturation and luminance
danielebarchiesi@0 615 * space.
danielebarchiesi@0 616 */
danielebarchiesi@0 617 function _color_shift($given, $ref1, $ref2, $target) {
danielebarchiesi@0 618 // We assume that ref2 is a blend of ref1 and target and find
danielebarchiesi@0 619 // delta based on the length of the difference vectors.
danielebarchiesi@0 620
danielebarchiesi@0 621 // delta = 1 - |ref2 - ref1| / |white - ref1|
danielebarchiesi@0 622 $target = _color_unpack($target, TRUE);
danielebarchiesi@0 623 $ref1 = _color_unpack($ref1, TRUE);
danielebarchiesi@0 624 $ref2 = _color_unpack($ref2, TRUE);
danielebarchiesi@0 625 $numerator = 0;
danielebarchiesi@0 626 $denominator = 0;
danielebarchiesi@0 627 for ($i = 0; $i < 3; ++$i) {
danielebarchiesi@0 628 $numerator += ($ref2[$i] - $ref1[$i]) * ($ref2[$i] - $ref1[$i]);
danielebarchiesi@0 629 $denominator += ($target[$i] - $ref1[$i]) * ($target[$i] - $ref1[$i]);
danielebarchiesi@0 630 }
danielebarchiesi@0 631 $delta = ($denominator > 0) ? (1 - sqrt($numerator / $denominator)) : 0;
danielebarchiesi@0 632
danielebarchiesi@0 633 // Calculate the color that ref2 would be if the assumption was true.
danielebarchiesi@0 634 for ($i = 0; $i < 3; ++$i) {
danielebarchiesi@0 635 $ref3[$i] = $target[$i] + ($ref1[$i] - $target[$i]) * $delta;
danielebarchiesi@0 636 }
danielebarchiesi@0 637
danielebarchiesi@0 638 // If the assumption is not true, there is a difference between ref2 and ref3.
danielebarchiesi@0 639 // We measure this in HSL space. Notation: x' = hsl(x).
danielebarchiesi@0 640 $ref2 = _color_rgb2hsl($ref2);
danielebarchiesi@0 641 $ref3 = _color_rgb2hsl($ref3);
danielebarchiesi@0 642 for ($i = 0; $i < 3; ++$i) {
danielebarchiesi@0 643 $shift[$i] = $ref2[$i] - $ref3[$i];
danielebarchiesi@0 644 }
danielebarchiesi@0 645
danielebarchiesi@0 646 // Take the given color, and blend it towards the target.
danielebarchiesi@0 647 $given = _color_unpack($given, TRUE);
danielebarchiesi@0 648 for ($i = 0; $i < 3; ++$i) {
danielebarchiesi@0 649 $result[$i] = $target[$i] + ($given[$i] - $target[$i]) * $delta;
danielebarchiesi@0 650 }
danielebarchiesi@0 651
danielebarchiesi@0 652 // Finally, we apply the extra shift in HSL space.
danielebarchiesi@0 653 // Note: if ref2 is a pure blend of ref1 and target, then |shift| = 0.
danielebarchiesi@0 654 $result = _color_rgb2hsl($result);
danielebarchiesi@0 655 for ($i = 0; $i < 3; ++$i) {
danielebarchiesi@0 656 $result[$i] = min(1, max(0, $result[$i] + $shift[$i]));
danielebarchiesi@0 657 }
danielebarchiesi@0 658 $result = _color_hsl2rgb($result);
danielebarchiesi@0 659
danielebarchiesi@0 660 // Return hex color.
danielebarchiesi@0 661 return _color_pack($result, TRUE);
danielebarchiesi@0 662 }
danielebarchiesi@0 663
danielebarchiesi@0 664 /**
danielebarchiesi@0 665 * Converts a hex triplet into a GD color.
danielebarchiesi@0 666 */
danielebarchiesi@0 667 function _color_gd($img, $hex) {
danielebarchiesi@0 668 $c = array_merge(array($img), _color_unpack($hex));
danielebarchiesi@0 669 return call_user_func_array('imagecolorallocate', $c);
danielebarchiesi@0 670 }
danielebarchiesi@0 671
danielebarchiesi@0 672 /**
danielebarchiesi@0 673 * Blends two hex colors and returns the GD color.
danielebarchiesi@0 674 */
danielebarchiesi@0 675 function _color_blend($img, $hex1, $hex2, $alpha) {
danielebarchiesi@0 676 $in1 = _color_unpack($hex1);
danielebarchiesi@0 677 $in2 = _color_unpack($hex2);
danielebarchiesi@0 678 $out = array($img);
danielebarchiesi@0 679 for ($i = 0; $i < 3; ++$i) {
danielebarchiesi@0 680 $out[] = $in1[$i] + ($in2[$i] - $in1[$i]) * $alpha;
danielebarchiesi@0 681 }
danielebarchiesi@0 682
danielebarchiesi@0 683 return call_user_func_array('imagecolorallocate', $out);
danielebarchiesi@0 684 }
danielebarchiesi@0 685
danielebarchiesi@0 686 /**
danielebarchiesi@0 687 * Converts a hex color into an RGB triplet.
danielebarchiesi@0 688 */
danielebarchiesi@0 689 function _color_unpack($hex, $normalize = FALSE) {
danielebarchiesi@0 690 if (strlen($hex) == 4) {
danielebarchiesi@0 691 $hex = $hex[1] . $hex[1] . $hex[2] . $hex[2] . $hex[3] . $hex[3];
danielebarchiesi@0 692 }
danielebarchiesi@0 693 $c = hexdec($hex);
danielebarchiesi@0 694 for ($i = 16; $i >= 0; $i -= 8) {
danielebarchiesi@0 695 $out[] = (($c >> $i) & 0xFF) / ($normalize ? 255 : 1);
danielebarchiesi@0 696 }
danielebarchiesi@0 697
danielebarchiesi@0 698 return $out;
danielebarchiesi@0 699 }
danielebarchiesi@0 700
danielebarchiesi@0 701 /**
danielebarchiesi@0 702 * Converts an RGB triplet to a hex color.
danielebarchiesi@0 703 */
danielebarchiesi@0 704 function _color_pack($rgb, $normalize = FALSE) {
danielebarchiesi@0 705 $out = 0;
danielebarchiesi@0 706 foreach ($rgb as $k => $v) {
danielebarchiesi@0 707 $out |= (($v * ($normalize ? 255 : 1)) << (16 - $k * 8));
danielebarchiesi@0 708 }
danielebarchiesi@0 709
danielebarchiesi@0 710 return '#' . str_pad(dechex($out), 6, 0, STR_PAD_LEFT);
danielebarchiesi@0 711 }
danielebarchiesi@0 712
danielebarchiesi@0 713 /**
danielebarchiesi@0 714 * Converts an HSL triplet into RGB.
danielebarchiesi@0 715 */
danielebarchiesi@0 716 function _color_hsl2rgb($hsl) {
danielebarchiesi@0 717 $h = $hsl[0];
danielebarchiesi@0 718 $s = $hsl[1];
danielebarchiesi@0 719 $l = $hsl[2];
danielebarchiesi@0 720 $m2 = ($l <= 0.5) ? $l * ($s + 1) : $l + $s - $l*$s;
danielebarchiesi@0 721 $m1 = $l * 2 - $m2;
danielebarchiesi@0 722
danielebarchiesi@0 723 return array(
danielebarchiesi@0 724 _color_hue2rgb($m1, $m2, $h + 0.33333),
danielebarchiesi@0 725 _color_hue2rgb($m1, $m2, $h),
danielebarchiesi@0 726 _color_hue2rgb($m1, $m2, $h - 0.33333),
danielebarchiesi@0 727 );
danielebarchiesi@0 728 }
danielebarchiesi@0 729
danielebarchiesi@0 730 /**
danielebarchiesi@0 731 * Helper function for _color_hsl2rgb().
danielebarchiesi@0 732 */
danielebarchiesi@0 733 function _color_hue2rgb($m1, $m2, $h) {
danielebarchiesi@0 734 $h = ($h < 0) ? $h + 1 : (($h > 1) ? $h - 1 : $h);
danielebarchiesi@0 735 if ($h * 6 < 1) return $m1 + ($m2 - $m1) * $h * 6;
danielebarchiesi@0 736 if ($h * 2 < 1) return $m2;
danielebarchiesi@0 737 if ($h * 3 < 2) return $m1 + ($m2 - $m1) * (0.66666 - $h) * 6;
danielebarchiesi@0 738
danielebarchiesi@0 739 return $m1;
danielebarchiesi@0 740 }
danielebarchiesi@0 741
danielebarchiesi@0 742 /**
danielebarchiesi@0 743 * Converts an RGB triplet to HSL.
danielebarchiesi@0 744 */
danielebarchiesi@0 745 function _color_rgb2hsl($rgb) {
danielebarchiesi@0 746 $r = $rgb[0];
danielebarchiesi@0 747 $g = $rgb[1];
danielebarchiesi@0 748 $b = $rgb[2];
danielebarchiesi@0 749 $min = min($r, min($g, $b));
danielebarchiesi@0 750 $max = max($r, max($g, $b));
danielebarchiesi@0 751 $delta = $max - $min;
danielebarchiesi@0 752 $l = ($min + $max) / 2;
danielebarchiesi@0 753 $s = 0;
danielebarchiesi@0 754
danielebarchiesi@0 755 if ($l > 0 && $l < 1) {
danielebarchiesi@0 756 $s = $delta / ($l < 0.5 ? (2 * $l) : (2 - 2 * $l));
danielebarchiesi@0 757 }
danielebarchiesi@0 758
danielebarchiesi@0 759 $h = 0;
danielebarchiesi@0 760 if ($delta > 0) {
danielebarchiesi@0 761 if ($max == $r && $max != $g) $h += ($g - $b) / $delta;
danielebarchiesi@0 762 if ($max == $g && $max != $b) $h += (2 + ($b - $r) / $delta);
danielebarchiesi@0 763 if ($max == $b && $max != $r) $h += (4 + ($r - $g) / $delta);
danielebarchiesi@0 764 $h /= 6;
danielebarchiesi@0 765 }
danielebarchiesi@0 766
danielebarchiesi@0 767 return array($h, $s, $l);
danielebarchiesi@0 768 }