1<?php
2/**
3 * This script generates a sprite from the unprocessed pagetool icons by combining them
4 * and overlaying a color layer for the active state.
5 *
6 * This script requires a current libGD to be available.
7 *
8 * The color for the active state is read from the style.ini's __link__ replacement
9 *
10 * The final sprite is optimized with optipng if available.
11 *
12 * @author Andreas Gohr <andi@splitbrain.org>
13 * @todo   Maybe add some more error checking
14 */
15$GAMMA = 0.8;
16$OPTIPNG = '/usr/bin/optipng';
17
18if('cli' != php_sapi_name()) die('please run from commandline');
19
20// load input images
21$input = glob('pagetools/*.png');
22sort($input);
23$cnt   = count($input);
24if(!$cnt){
25    die("No input images found. This script needs to be called from within the image directory!\n");
26}
27
28// create destination image
29$DST = imagecreatetruecolor(30,$cnt*45*2);
30imagesavealpha($DST, true);
31$C_trans = imagecolorallocatealpha($DST, 0, 0, 0, 127);
32imagefill($DST, 0, 0, $C_trans);
33
34// load highlight color from style.ini
35$ini = parse_ini_file('../style.ini',true);
36$COLOR = hex2rgb($ini['replacements']['__link__']);
37$C_active = imagecolorallocate($DST, $COLOR['r'],$COLOR['g'],$COLOR['b']);
38
39// add all the icons to the sprite image
40for($i=0; $i<$cnt; $i++){
41    $base = $i*90;
42
43    $IN = imagecreatefrompng($input[$i]);
44    imagesavealpha($IN, true);
45    imagecolorscale($IN,$GAMMA);
46    imagecopy($DST,$IN, 0,$base, 0,0, 30,30);
47    imagedestroy($IN);
48
49    $IN = imagecreatefrompng($input[$i]);
50    imagesavealpha($IN, true);
51    imagecolorscale($IN,$GAMMA);
52    imagecopy($DST,$IN, 0,$base+45, 0,0, 30,30);
53    imagedestroy($IN);
54
55    imagelayereffect($DST, IMG_EFFECT_OVERLAY);
56    imagefilledrectangle($DST, 0,$base+45, 30,$base+45+30, $C_active);
57    imagelayereffect($DST, IMG_EFFECT_NORMAL);
58}
59
60// output sprite
61imagepng($DST,'pagetools-sprite.png');
62imagedestroy($DST);
63
64// optimize if possible
65if(is_executable($OPTIPNG)){
66    system("$OPTIPNG -o5 'pagetools-sprite.png'");
67}
68
69/**
70 * Convert a hex color code to an rgb array
71 */
72function hex2rgb($hex) {
73    // strip hash
74    $hex = str_replace('#', '', $hex);
75
76    // normalize short codes
77    if(strlen($hex) == 3){
78        $hex = substr($hex,0,1).
79               substr($hex,0,1).
80               substr($hex,1,1).
81               substr($hex,1,1).
82               substr($hex,2,1).
83               substr($hex,2,1);
84    }
85
86    // calc rgb
87    return array(
88       'r' => hexdec(substr($hex, 0, 2)),
89       'g' => hexdec(substr($hex, 2, 2)),
90       'b' => hexdec(substr($hex, 4, 2))
91    );
92}
93
94/**
95 * Scale (darken/lighten) a given image
96 *
97 * @param resource $img    The truetype GD image to work on
98 * @param float     $scale  Scale the colors by this value ( <1 darkens, >1 lightens)
99 */
100function imagecolorscale(&$img, $scale){
101    $w = imagesx($img);
102    $h = imagesy($img);
103
104    imagealphablending($img, false);
105    for($x = 0; $x < $w; $x++){
106        for($y = 0; $y < $h; $y++){
107            $rgba   = imagecolorat($img, $x, $y);
108            $a = ($rgba >> 24) & 0xFF;
109            $r = ($rgba >> 16) & 0xFF;
110            $g = ($rgba >> 8) & 0xFF;
111            $b = $rgba & 0xFF;
112
113            $r = max(min(round($r*$scale),255),0);
114            $g = max(min(round($g*$scale),255),0);
115            $b = max(min(round($b*$scale),255),0);
116
117            $color = imagecolorallocatealpha($img, $r, $g, $b, $a);
118            imagesetpixel($img, $x, $y, $color);
119        }
120    }
121    imagealphablending($img, true);
122}
123
124