function cw_generate_css_sprites($tpl, &$smarty) { global $config, $app_dir; $global_map_stamp = 0; $maps_objects = array(); if (isset($smarty->_smarty_vars['sprites']) && is_array($smarty->_smarty_vars['sprites']) && count($smarty->_smarty_vars['sprites'])) { foreach ($smarty->_smarty_vars['sprites'] as $group => $sprites) { foreach ($sprites as $key => $src) { $num = $key + 1; $maps_objects[$group]['objects']['sprite' . $num] = $src; } $maps_objects[$group]['default_presets'] = '@whb'; $maps_objects[$group]['mapstamp'] = $global_map_stamp; } require_once $app_dir . '/core/include/lib/qpimg/qpimg.php'; foreach ($maps_objects as $group => $data) { $css_link = qpimg::get_css_source_link($group); $tpl = str_replace("</head>", "<link href='" . $css_link . "' rel='stylesheet' type='text/css' />\n</head>", $tpl); } } return $tpl; }
/** * Generate class values by incoming selector. Selector may be as: * - map_id.obj_id - generate "qpimg_map_class qpimg_obj_class" * - map_id - generate only "qpimg_map_class" * - .obj_id - try autodetect map_id and generate "qpimg_map_class qpimg_obj_class" * or empty string (if map not found) * * @param string $selector * * @return string class-value ( "qpimg_map_class" or "qpimg_map_class qpimg_obj_class" ) */ public static function get_obj_class($selector) { $selector = rtrim(trim($selector), '.'); $map_cfg = $map_id = $media_id = null; if ($selector) { list($map_id, $media_id) = explode('.', $selector); if ($map_id == '') { $map_id = null; $map_keys = qpimg_config::get_map_keys(); foreach ($map_keys as $onemap_id) { $onemap_cfg = qpimg_config::get_map($onemap_id); if (isset($onemap_cfg['objects']) === false) { continue; } if (isset($onemap_cfg['objects'][$media_id]) === true) { if ($map_id === null) { $map_id = $onemap_id; $map_cfg = $onemap_cfg; } else { $map_cfg = $map_id = $media_id = null; break; } } } // ToDo: maybe use here user-function } else { $map_cfg = qpimg_config::get_map($map_id); if ($map_cfg === false) { $map_cfg = $map_id = $media_id = null; } } } $classes = array(); if ($map_id) { $classes[] = qpimg::get_map_css_selector($map_id, $map_cfg); if ($media_id) { $classes[] = qpimg::get_obj_css_selector($map_id, $media_id, $map_cfg); } } return join(' ', $classes); }
/** * Generate css & sprite (image) for single map * * @param array $map_cfg map-config array * * @return bool status */ public static function pack($map_cfg) { //--------------------------------------------------------------------- // PreCheck incoming data if (is_array($map_cfg['objects']) === false) { $map_cfg['objects'] = array(); } //- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - if (isset($map_cfg['verbose_check']) === false) { $map_cfg['verbose_check'] = false; } $map_cfg['verbose_check'] = (bool) $map_cfg['verbose_check']; //- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - $map_cfg['save_format'] = strtolower($map_cfg['save_format']); if (in_array($map_cfg['save_format'], array('png', 'gif', 'jpg')) === false) { $map_cfg['save_format'] = 'png'; } //--------------------------------------------------------------------- self::prepare_media_items($map_cfg); if ($map_cfg['objects:dataURI_files_count'] == 0) { // if no dataURI media-items -> then no need proecee MODE_DATAURI_REJECT $process_modes = array(self::MODE_STANDARD); } else { $process_modes = array(self::MODE_STANDARD, self::MODE_DATAURI_REJECT); } foreach ($process_modes as $mode) { switch ($mode) { case self::MODE_STANDARD: $css_filename = qpimg_cache::gen_filename($map_cfg, 'css', qpimg::CSS_FILE_KEY_DEFAULT); $sprite_filename = qpimg_cache::gen_filename($map_cfg, $map_cfg['save_format'], qpimg::SPRITE_FILE_KEY_DEFAULT); $sprite_url = qpimg_cache::gen_filename($map_cfg, $map_cfg['save_format'], qpimg::SPRITE_FILE_KEY_DEFAULT, true); break; case self::MODE_DATAURI_REJECT: $css_filename = qpimg_cache::gen_filename($map_cfg, 'css', qpimg::CSS_FILE_KEY_DATAURI_REJECT); $sprite_filename = qpimg_cache::gen_filename($map_cfg, $map_cfg['save_format'], qpimg::SPRITE_FILE_KEY_DATAURI_REJECT); $sprite_url = qpimg_cache::gen_filename($map_cfg, $map_cfg['save_format'], qpimg::SPRITE_FILE_KEY_DATAURI_REJECT, true); break; } //--------------------------------------------------------------------- // Set positions of each media-item-element for sprite switch ($map_cfg['orientation']) { case 'static': default: $set_position_funcname = 'set_position_static'; $css_bg_repeat_style = 'no-repeat'; break; case 'repeat_x': $set_position_funcname = 'set_position_repeat_x'; $css_bg_repeat_style = 'repeat-x'; break; case 'repeat_y': $set_position_funcname = 'set_position_repeat_y'; $css_bg_repeat_style = 'repeat-y'; break; } list($pos_media_items, $img_width, $img_height) = self::$set_position_funcname($map_cfg, $mode); //--------------------------------------------------------------------- // Save CSS data (by mode) $css_data = array(); if (count($pos_media_items) > 0) { $css_data[':main_sprite']['background-image'] = "url('{$sprite_url}')"; $css_data[':main_sprite']['background-repeat'] = $css_bg_repeat_style; $css_data[':main_sprite'][':css-selector'] = array(); } // Generate crash rules foreach ($map_cfg['objects:items'] as $media_id => $media_item) { if ($media_item->is_crashed() === false) { continue; } $item_css_data = array(); $item_css_data['background-image'] = 'none !important'; $item_css_data['background-color'] = '#800000'; $css_data[qpimg::get_obj_css_selector($map_cfg['id'], $media_id, $map_cfg)] = $item_css_data; } // Generate items data foreach ($pos_media_items as $media_id => $media_item) { $item_css_data = array(); $item_css_data['background-position'] = -($media_item->get('left') + $media_item->get('space-left')) . "px " . -($media_item->get('top') + $media_item->get('space-top')) . "px"; self::prepare_item_css($item_css_data, $media_item); $css_data[':main_sprite'][':css-selector'] = array_merge($css_data[':main_sprite'][':css-selector'], $item_css_data[':css-selector']); $css_data[qpimg::get_obj_css_selector($map_cfg['id'], $media_id, $map_cfg)] = $item_css_data; } unset($item_css_data); // Generate data:URI content (for MODE_STANDARD) if ($mode == self::MODE_STANDARD) { if (is_array($map_cfg['objects:items']) === true) { foreach ($map_cfg['objects:items'] as $media_id => $media_item) { if ($media_item->is_crashed() === true) { continue; } if ($media_item->get('data:URI') === false) { continue; } $item_css_data = array(); self::prepare_item_css($item_css_data, $media_item); switch ($media_item->get('imagetype')) { case IMAGETYPE_GIF: $mimetype = 'image/gif'; break; case IMAGETYPE_JPEG: $mimetype = 'image/jpeg'; break; case IMAGETYPE_PNG: $mimetype = 'image/png'; break; } $item_css_data['background-image'] = "url(" . "data:{$mimetype};" . "base64," . base64_encode(@file_get_contents($media_item->get('source'))) . ")"; $css_data[qpimg::get_obj_css_selector($map_cfg['id'], $media_id, $map_cfg)] = $item_css_data; } } } $css_hf = @fopen($css_filename, 'w'); if (is_resource($css_hf) === false) { self::drop_temporary_media(); return false; } ksort($css_data); foreach ($css_data as $css_selector => $item_css_data) { if ($css_selector == ':main_sprite') { $css_selector = qpimg::get_map_css_selector($map_cfg['id'], $map_cfg); } fwrite($css_hf, ".{$css_selector}"); if (is_array($item_css_data[':css-selector']) === true) { foreach ($item_css_data[':css-selector'] as $sub_css_selector) { $sub_css_selector = trim($sub_css_selector); if ($sub_css_selector == '') { continue; } fwrite($css_hf, ", {$sub_css_selector}"); } } fwrite($css_hf, " { "); foreach ($item_css_data as $css_attr_key => $css_attr_value) { if ($css_attr_key[0] == ':') { continue; } fwrite($css_hf, "{$css_attr_key}: {$css_attr_value}; "); } fwrite($css_hf, "}\n"); } fclose($css_hf); //--------------------------------------------------------------------- // Make SPRITE (image) if (count($pos_media_items) > 0) { $sprite_img = @imagecreatetruecolor($img_width, $img_height); if (is_resource($sprite_img) === false) { self::drop_temporary_media(); return false; } imagealphablending($sprite_img, false); imagesavealpha($sprite_img, true); if (isset($map_cfg['bgcolor']) === true && $map_cfg['bgcolor']) { list($color_r, $color_g, $color_b) = qpimg_utils::color2rgb($map_cfg['bgcolor']); imagefill($sprite_img, 0, 0, imagecolorallocate($sprite_img, $color_r, $color_g, $color_b)); unset($color_r, $color_g, $color_b); } else { imagefill($sprite_img, 0, 0, imagecolorallocatealpha($sprite_img, 0, 0, 0, 127)); } //--------------------------------------------------------------------- if (isset($map_cfg['transparent_color']) === true) { list($color_r, $color_g, $color_b) = qpimg_utils::color2rgb($map_cfg['transparent_color']); imagecolortransparent($sprite_img, imagecolorallocate($sprite_img, $color_r, $color_g, $color_b)); unset($color_r, $color_g, $color_b); } //--------------------------------------------------------------------- // Copy images in sprite & save css attributes for each element foreach ($pos_media_items as $media_id => $media_item) { $safe_image_source = self::parse_media_source($media_item->get('source'), $map_cfg['id']); if ($safe_image_source === false) { continue; } //- - - - - - - - - - - - - - - - - - - - - - - - - - - - - switch ($media_item->get('imagetype')) { case IMAGETYPE_GIF: $tmp_img = @imagecreatefromgif($safe_image_source); break; case IMAGETYPE_JPEG: $tmp_img = @imagecreatefromjpeg($safe_image_source); break; case IMAGETYPE_PNG: $tmp_img = @imagecreatefrompng($safe_image_source); break; } if (is_resource($tmp_img) === false) { continue; } $src_x = 0; $src_y = 0; $src_w = $media_item->get('etalon-width'); $src_h = $media_item->get('etalon-height'); $dst_x = $media_item->get('left') + $media_item->get('space-left'); $dst_y = $media_item->get('top') + $media_item->get('space-top'); $dst_w = $media_item->get('scale-width'); $dst_h = $media_item->get('scale-height'); if ($media_item->get('bgcolor') !== false) { list($color_r, $color_g, $color_b) = qpimg_utils::color2rgb($media_item->get('bgcolor')); imagefilledrectangle($sprite_img, $media_item->get('left'), $media_item->get('top'), $media_item->get('left') + $media_item->get('full-width') - 1, $media_item->get('top') + $media_item->get('full-height') - 1, imagecolorallocate($sprite_img, $color_r, $color_g, $color_b)); unset($color_r, $color_g, $color_b); } if ($src_w == $dst_w && $src_h == $dst_h) { imagecopy($sprite_img, $tmp_img, $dst_x, $dst_y, $src_x, $src_y, $src_w, $src_h); } else { if ($media_item->get('scale-method') == 'resize') { imagecopyresized($sprite_img, $tmp_img, $dst_x, $dst_y, $src_x, $src_y, $dst_w, $dst_h, $src_w, $src_h); } elseif ($media_item->get('scale-method') == 'resample') { imagecopyresampled($sprite_img, $tmp_img, $dst_x, $dst_y, $src_x, $src_y, $dst_w, $dst_h, $src_w, $src_h); } elseif ($media_item->get('scale-method') == 'mosaic') { $mosaic_y = $dst_y; $mosaic_h = $dst_h; do { $mosaic_x = $dst_x; $mosaic_w = $dst_w; do { imagecopy($sprite_img, $tmp_img, $mosaic_x, $mosaic_y, 0, 0, min($mosaic_w, $src_w), min($mosaic_h, $src_h)); $mosaic_x += $src_w; $mosaic_w -= $src_w; } while ($mosaic_w > 0); $mosaic_y += $src_h; $mosaic_h -= $src_h; } while ($mosaic_h > 0); unset($mosaic_x, $mosaic_y, $mosaic_w, $mosaic_h); } else { qpimg_logger::write("QPIMG_WARNING: Undefined scale-method: " . $media_item->get('scale-method'), __FILE__, __LINE__); continue; } } unset($src_x, $src_y, $src_w, $src_h); unset($dst_x, $dst_y, $dst_w, $dst_h); imagedestroy($tmp_img); } //--------------------------------------------------------------------- // Save image-data switch ($map_cfg['save_format']) { case 'png': if (isset($map_cfg['save_quality']) === false) { $map_cfg['save_quality'] = 9; } $save_result = @imagepng($sprite_img, $sprite_filename, min(max($map_cfg['save_quality'], 0), 9)); break; case 'gif': $save_result = @imagegif($sprite_img, $sprite_filename); break; case 'jpg': if (isset($map_cfg['save_quality']) === false) { $map_cfg['save_quality'] = 95; } $save_result = @imagejpeg($sprite_img, $sprite_filename, min(max($map_cfg['save_quality'], 0), 100)); break; } if ($save_result === false) { qpimg_logger::write("QPIMG_ERROR: Failed on save result sprite '{$sprite_filename}'", __FILE__, __LINE__); } imagedestroy($sprite_img); } } //--------------------------------------------------------------------- // Save crc-hash [if set verbose_check mode] if ($map_cfg['verbose_check'] === true) { @file_put_contents(qpimg_cache::gen_filename($map_cfg, 'crc'), $map_cfg['hash'] . ':' . qpimg_cache::get_media_hash($map_cfg)); } self::drop_temporary_media(); return true; }