| 1 | #============================================================================ |
|---|
| 2 | # Copyright (C)2006-2010 by Frank Richter |
|---|
| 3 | # |
|---|
| 4 | # This library is free software; you can redistribute it and/or modify it |
|---|
| 5 | # under the terms of the GNU Library General Public License as published by |
|---|
| 6 | # the Free Software Foundation; either version 2 of the License, or (at your |
|---|
| 7 | # option) any later version. |
|---|
| 8 | # |
|---|
| 9 | # This library is distributed in the hope that it will be useful, but |
|---|
| 10 | # WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY |
|---|
| 11 | # or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public |
|---|
| 12 | # License for more details. |
|---|
| 13 | # |
|---|
| 14 | # You should have received a copy of the GNU Library General Public License |
|---|
| 15 | # along with this library; if not, write to the Free Software Foundation, |
|---|
| 16 | # Inc., 675 Mass Ave, Cambridge, MA 02139, USA. |
|---|
| 17 | # |
|---|
| 18 | #============================================================================ |
|---|
| 19 | if $(CMD.RSVG) != "" |
|---|
| 20 | { |
|---|
| 21 | ## IconsFromSVG iconname |
|---|
| 22 | ## Generate multiple PNG images suitable for icon use from an SVG file. |
|---|
| 23 | ## The source SVG file is expected to have the name |
|---|
| 24 | ## icons-src/scalable/<iconname>.svg. The result files are named |
|---|
| 25 | ## the icons/<size>/<iconname>.png for multiple common icon sizes as |
|---|
| 26 | ## 'size'. These "common sizes" include suitable sizes for icons on Linux |
|---|
| 27 | ## desktops, Windows and MacOS/X. |
|---|
| 28 | ## Images for certain sizes can be specified as |
|---|
| 29 | ## icons-src/<size>/<iconname>.png files; these are preferred over the |
|---|
| 30 | ## automatically generated ones. |
|---|
| 31 | ## The actual conversion is done when the "generateicons" target is |
|---|
| 32 | ## invoked. |
|---|
| 33 | rule IconsFromSVG |
|---|
| 34 | { |
|---|
| 35 | local icon = $(1) ; |
|---|
| 36 | local iconfile = $(icon).svg ; |
|---|
| 37 | local svgscalabledir = [ ConcatDirs $(SUBDIR) icons-src scalable ] ; |
|---|
| 38 | local svgsource = $(iconfile:G=$(svgscalabledir)) ; |
|---|
| 39 | SEARCH on $(svgsource) = $(svgscalabledir) ; |
|---|
| 40 | |
|---|
| 41 | NotFile generateicons ; |
|---|
| 42 | |
|---|
| 43 | local size ; |
|---|
| 44 | # Icon sizes to generate/use: |
|---|
| 45 | # 16 - Windows small icon (Window menu, start menu) |
|---|
| 46 | # 22 - Small icon for KDE and GNOME menus |
|---|
| 47 | # 24 - Small icon for GNOME file lists(1) |
|---|
| 48 | # 32 - Normal icon for Windows |
|---|
| 49 | # 48 - Large icon for Windows XP |
|---|
| 50 | # 256 - Windows Vista icon(2) |
|---|
| 51 | # 512 - MacOS/X(3) |
|---|
| 52 | # |
|---|
| 53 | # (1) - Can be generated from 22x22 pics by adding a border. |
|---|
| 54 | # (2) - Cause icon files to be really large. Vista supports PNG compression |
|---|
| 55 | # in icons and uses it for the 256x256 versions. |
|---|
| 56 | # (3) - OS/X 10.5 and newer. Older versions used 128x128. |
|---|
| 57 | for size in 16 22 32 48 256 512 |
|---|
| 58 | { |
|---|
| 59 | local pngdir = [ ConcatDirs $(SUBDIR) icons $(size) ] ; |
|---|
| 60 | local pngfile = $(icon:G=$(pngdir)).png ; |
|---|
| 61 | MakeLocate $(pngfile) : $(pngdir) ; |
|---|
| 62 | |
|---|
| 63 | SIZE on $(pngfile) = $(size) ; |
|---|
| 64 | Depends $(pngfile) : $(svgsource) ; |
|---|
| 65 | CreateIcon $(pngfile) : $(svgsource) ; |
|---|
| 66 | |
|---|
| 67 | Depends generateicons : $(pngfile) ; |
|---|
| 68 | Always $(pngfile) ; |
|---|
| 69 | } |
|---|
| 70 | |
|---|
| 71 | # size 24 icons are a special case, see above |
|---|
| 72 | local pngdir = [ ConcatDirs $(SUBDIR) icons 24 ] ; |
|---|
| 73 | local pngfile = $(icon:G=$(pngdir)).png ; |
|---|
| 74 | if $(CMD.CONVERT) != "" |
|---|
| 75 | { |
|---|
| 76 | MakeLocate $(pngfile) : $(pngdir) ; |
|---|
| 77 | Depends $(pngfile) : $(svgsource) ; |
|---|
| 78 | CreateIcon24 $(pngfile) : $(svgsource) ; |
|---|
| 79 | |
|---|
| 80 | Depends generateicons : $(pngfile) ; |
|---|
| 81 | Always $(pngfile) ; |
|---|
| 82 | } |
|---|
| 83 | else |
|---|
| 84 | { |
|---|
| 85 | Echo "ImageMagick not available, $(pngfile) not regenerated" ; |
|---|
| 86 | } |
|---|
| 87 | } |
|---|
| 88 | |
|---|
| 89 | actions CreateIcon |
|---|
| 90 | { |
|---|
| 91 | SIZEDICONSSRC=`dirname $(>)`/../$(SIZE) |
|---|
| 92 | ICONBASE=`basename $(>) .svg` |
|---|
| 93 | if [ -e $SIZEDICONSSRC/$ICONBASE.png ] ; then |
|---|
| 94 | $(CP) $SIZEDICONSSRC/$ICONBASE.png $(<) |
|---|
| 95 | else |
|---|
| 96 | if [ -e $SIZEDICONSSRC/$ICONBASE.svg ] ; then |
|---|
| 97 | $(CMD.RSVG) -f png -w $(SIZE) -h $(SIZE) $SIZEDICONSSRC/$ICONBASE.svg $(<).tmp |
|---|
| 98 | else |
|---|
| 99 | $(CMD.RSVG) -f png -w $(SIZE) -h $(SIZE) $(>) $(<).tmp |
|---|
| 100 | fi |
|---|
| 101 | if [ -n "$(CMD.PNGCRUSH:E=)" ] ; then |
|---|
| 102 | $(CMD.PNGCRUSH) -rem text $(<).tmp $(<) |
|---|
| 103 | rm $(<).tmp |
|---|
| 104 | else |
|---|
| 105 | mv $(<).tmp $(<) |
|---|
| 106 | fi |
|---|
| 107 | fi |
|---|
| 108 | } |
|---|
| 109 | |
|---|
| 110 | actions CreateIcon24 |
|---|
| 111 | { |
|---|
| 112 | SIZEDICONSSRC=`dirname $(>)`/../24 |
|---|
| 113 | ICONBASE=`basename $(>) .svg` |
|---|
| 114 | GENSIZEDICONSSRC=`dirname $(<)`/../22 |
|---|
| 115 | if [ -e $SIZEDICONSSRC/$ICONBASE.png ] ; then |
|---|
| 116 | $(CP) $SIZEDICONSSRC/$ICONBASE.png $(<) |
|---|
| 117 | else |
|---|
| 118 | if [ -e $SIZEDICONSSRC/$ICONBASE.svg ] ; then |
|---|
| 119 | $(CMD.RSVG) -f png -w 24 -h 24 $SIZEDICONSSRC/$ICONBASE.svg $(<).tmp |
|---|
| 120 | else |
|---|
| 121 | $(CMD.CONVERT) -bordercolor Transparent -border 1x1 $GENSIZEDICONSSRC/$ICONBASE.png $(<).tmp |
|---|
| 122 | fi |
|---|
| 123 | if [ -n "$(CMD.PNGCRUSH:E=)" ] ; then |
|---|
| 124 | $(CMD.PNGCRUSH) -rem text $(<).tmp $(<) |
|---|
| 125 | rm $(<).tmp |
|---|
| 126 | else |
|---|
| 127 | mv $(<).tmp $(<) |
|---|
| 128 | fi |
|---|
| 129 | fi |
|---|
| 130 | } |
|---|
| 131 | } |
|---|
| 132 | else |
|---|
| 133 | { |
|---|
| 134 | rule IconsFromSVG { } |
|---|
| 135 | } |
|---|
| 136 | |
|---|
| 137 | if $(CMD.ICOTOOL) != "" |
|---|
| 138 | { |
|---|
| 139 | # Pad the given argument with zeroes on the left side to a length of 3 chars. |
|---|
| 140 | rule _ZeroPad |
|---|
| 141 | { |
|---|
| 142 | if [ Match ^([0-9][0-9])$ : $(<) ] |
|---|
| 143 | { |
|---|
| 144 | return 0$(<) ; |
|---|
| 145 | } |
|---|
| 146 | if [ Match ^([0-9])$ : $(<) ] |
|---|
| 147 | { |
|---|
| 148 | return 00$(<) ; |
|---|
| 149 | } |
|---|
| 150 | return $(<) ; |
|---|
| 151 | } |
|---|
| 152 | |
|---|
| 153 | ## IconsMakeWin32ICO filename : iconname [: sizes] |
|---|
| 154 | ## Generate a Win32 ICO file from multiple PNG images, such as those |
|---|
| 155 | ## produced by IconsFromSVG. |
|---|
| 156 | ## The source images are expected to have the names |
|---|
| 157 | ## icons-src/<size>/<iconname>.png or icons/<size>/<iconname>.png for the |
|---|
| 158 | ## sizes specified in `sizes'. Files in the `icons-src/' directory are |
|---|
| 159 | ## preferred over files in the `icons/' directory. |
|---|
| 160 | ## By default, a set of common sizes is used, currently 16, 32, 48 and 256. |
|---|
| 161 | ## The ICO will also include 256 color images that are generated from |
|---|
| 162 | ## the (presumably RGBA) source PNGs; however, such color-reduced images |
|---|
| 163 | ## can also be specified manually for certain sizes by saving them named |
|---|
| 164 | ## icons-src/<size>/<iconname>_8.png. These user-provided reduced versions |
|---|
| 165 | ## are preferred over the automatically reduced ones. |
|---|
| 166 | ## The actual conversion is done when the "generateicons" target is |
|---|
| 167 | ## invoked. |
|---|
| 168 | rule IconsMakeWin32ICO |
|---|
| 169 | { |
|---|
| 170 | local icofile = $(1) ; |
|---|
| 171 | local icon = $(2) ; |
|---|
| 172 | local sizes = $(3) ; |
|---|
| 173 | |
|---|
| 174 | if "$(sizes)" = "" { sizes = 16 32 48 256 ; } |
|---|
| 175 | |
|---|
| 176 | local size icons ; |
|---|
| 177 | for size in $(sizes) |
|---|
| 178 | { |
|---|
| 179 | local pngdir = [ ConcatDirs $(SUBDIR) icons $(size) ] ; |
|---|
| 180 | local pngtempdir = [ ConcatDirs $(BUILDTOP) out iconstmp $(SUBDIR) $(size) ] ; |
|---|
| 181 | local pngsrcdir = [ ConcatDirs $(SUBDIR) icons-src $(size) ] ; |
|---|
| 182 | local pngfile = $(icon:G=$(pngdir)).png ; |
|---|
| 183 | local lowfile = $(icon:G=$(pngtempdir))_8.png ; |
|---|
| 184 | NoCare $(pngfile) ; |
|---|
| 185 | # Prefer icons from `icons-src/' (presumably user-provided) over icons |
|---|
| 186 | # from `icons/' (presumably auto-generated). |
|---|
| 187 | SEARCH on $(pngfile) = $(pngsrcdir) $(pngdir) ; |
|---|
| 188 | # <= is a string comparison in Jam, hence the 0 padding |
|---|
| 189 | if [ _ZeroPad $(size) ] <= 128 |
|---|
| 190 | { |
|---|
| 191 | icons += "$(pngfile)" ; |
|---|
| 192 | if $(CMD.CONVERT) != "" |
|---|
| 193 | { |
|---|
| 194 | MakeLocate $(lowfile) : $(pngtempdir) ; |
|---|
| 195 | SIZE on $(lowfile) = $(size) ; |
|---|
| 196 | |
|---|
| 197 | ReduceColorDepth $(lowfile) : $(pngfile) ; |
|---|
| 198 | Depends $(lowfile) : $(pngfile) ; |
|---|
| 199 | icons += "$(lowfile)" ; |
|---|
| 200 | RmTemps generateicons : $(lowfile) ; |
|---|
| 201 | } |
|---|
| 202 | } |
|---|
| 203 | else |
|---|
| 204 | { |
|---|
| 205 | if "$(ICOTOOL.SUPPORTS_RAW)" = "yes" |
|---|
| 206 | { |
|---|
| 207 | # Special case, embed icon as PNG |
|---|
| 208 | RAW_ICONS on $(icofile) += "$(pngfile)" ; |
|---|
| 209 | } |
|---|
| 210 | } |
|---|
| 211 | } |
|---|
| 212 | |
|---|
| 213 | MakeLocate $(icofile) : $(SUBDIR) ; |
|---|
| 214 | Depends $(icofile) : $(icons) ; |
|---|
| 215 | IcoTool $(icofile) : $(icons) ; |
|---|
| 216 | Depends generateicons : $(icofile) ; |
|---|
| 217 | } |
|---|
| 218 | |
|---|
| 219 | actions ReduceColorDepth |
|---|
| 220 | { |
|---|
| 221 | ICONSSRC=`dirname $(>)`/../../icons-src/$(SIZE) |
|---|
| 222 | ICONBASE=`basename $(>) .png` |
|---|
| 223 | if [ -e $ICONSSRC/${ICONBASE}_8.png ] ; then |
|---|
| 224 | $(CP) $ICONSSRC/${ICONBASE}_8.png $(<) |
|---|
| 225 | else |
|---|
| 226 | # Makes transparency binary and reduces colors to 256 |
|---|
| 227 | $(CMD.CONVERT) $(>) \( +clone -fx a +matte -monochrome \) -compose CopyOpacity -composite -colors 256 +dither $(<) |
|---|
| 228 | fi |
|---|
| 229 | } |
|---|
| 230 | |
|---|
| 231 | actions IcoTool bind RAW_ICONS |
|---|
| 232 | { |
|---|
| 233 | $(CMD.ICOTOOL) -c -o $(<) $(>) $(RAW_ICONS) |
|---|
| 234 | } |
|---|
| 235 | } |
|---|
| 236 | else |
|---|
| 237 | { |
|---|
| 238 | rule IconsMakeWin32ICO { } |
|---|
| 239 | } |
|---|
| 240 | |
|---|
| 241 | if $(CMD.MAKEICNS) != "" || $(CMD.PNG2ICNS) != "" |
|---|
| 242 | { |
|---|
| 243 | # DownsampleImage target : source : size ; |
|---|
| 244 | # Returns file name of (temp) file with resampled imaged. |
|---|
| 245 | rule DownsampleImage |
|---|
| 246 | { |
|---|
| 247 | local target = $(1) ; |
|---|
| 248 | local source = $(2) ; |
|---|
| 249 | local size = $(3) ; |
|---|
| 250 | |
|---|
| 251 | local tempdir = [ ConcatDirs $(BUILDTOP) out iconstmp $(SUBDIR) $(size) ] ; |
|---|
| 252 | local outfile = $(source:G=$(tempdir)) ; |
|---|
| 253 | |
|---|
| 254 | MakeLocate $(outfile) : $(tempdir) ; |
|---|
| 255 | Depends $(outfile) : $(source) ; |
|---|
| 256 | SIZE on $(outfile) = $(size) ; |
|---|
| 257 | ConvertReduce $(outfile) : $(source) ; |
|---|
| 258 | RmTemps $(target) : $(outfile) ; |
|---|
| 259 | |
|---|
| 260 | return $(outfile) ; |
|---|
| 261 | } |
|---|
| 262 | |
|---|
| 263 | actions ConvertReduce |
|---|
| 264 | { |
|---|
| 265 | $(CMD.CONVERT) $(>) -resize $(SIZE)x$(SIZE) $(<) |
|---|
| 266 | } |
|---|
| 267 | |
|---|
| 268 | ## IconsMakeMacICNS filename : iconname [: sizes] |
|---|
| 269 | ## Generate a MacOS/X ICNS file from a PNG image such as produced by |
|---|
| 270 | ## IconsFromSVG. |
|---|
| 271 | ## `sizes' specify the available source image resolutions. Allowed sizes |
|---|
| 272 | ## are 128, 256 and 512. Note that a missing size is generated |
|---|
| 273 | ## automatically if a higher size is available. Thus, only specifying a |
|---|
| 274 | ## 512x512 is sufficient as the lower resolutions will be generated from |
|---|
| 275 | ## that. However, upscaling will not take place: e.g. only specifying a |
|---|
| 276 | ## size of 256 will result in an icon without a 512x512 image (forcing the |
|---|
| 277 | ## OS to upscale the lower resolution image). |
|---|
| 278 | ## The source images are expected to have the names |
|---|
| 279 | ## icons-src/<size>/<iconname>.png or icons/<size>/<iconname>.png for the |
|---|
| 280 | ## sizes specified in `sizes'. Files in the `icons-src/' directory are |
|---|
| 281 | ## preferred over files in the `icons/' directory. |
|---|
| 282 | ## For the conversion to happen a 3rd party tool, `makeicns' is required. |
|---|
| 283 | ## It can be obtained from http://www.amnoid.de/icns/makeicns.html . |
|---|
| 284 | ## The actual conversion is done when the "generateicons" target is |
|---|
| 285 | ## invoked. |
|---|
| 286 | rule IconsMakeMacICNS |
|---|
| 287 | { |
|---|
| 288 | local icnsfile = $(1) ; |
|---|
| 289 | local icon = $(2) ; |
|---|
| 290 | local in_sizes = $(3) ; |
|---|
| 291 | |
|---|
| 292 | # Default to the size used by Leopard and above. |
|---|
| 293 | if "$(in_sizes)" = "" { in_sizes = 512 ; } |
|---|
| 294 | # Filter out unsupported sizes (only certain sizes are allowed in ICNS |
|---|
| 295 | # icons, and we don't provide/care about images sized below 128x128) |
|---|
| 296 | local sizes ; |
|---|
| 297 | for i in $(in_sizes) |
|---|
| 298 | { |
|---|
| 299 | if [ IsElem $(i) : 128 256 512 ] |
|---|
| 300 | { |
|---|
| 301 | sizes += $(i) ; |
|---|
| 302 | } |
|---|
| 303 | } |
|---|
| 304 | if "$(sizes)" = "" |
|---|
| 305 | { |
|---|
| 306 | echo "IconsMakeMacICNS $(icnsfile): no valid size given, sizes must contain at least one of 128, 256 or 512" ; |
|---|
| 307 | } |
|---|
| 308 | else |
|---|
| 309 | { |
|---|
| 310 | local in_512 = "" ; |
|---|
| 311 | local in_256 = "" ; |
|---|
| 312 | local in_128 = "" ; |
|---|
| 313 | for size in $(sizes) |
|---|
| 314 | { |
|---|
| 315 | local pngdir = [ ConcatDirs $(SUBDIR) icons $(size) ] ; |
|---|
| 316 | local pngsrcdir = [ ConcatDirs $(SUBDIR) icons-src $(size) ] ; |
|---|
| 317 | local pngfile = $(icon:G=$(pngdir)).png ; |
|---|
| 318 | |
|---|
| 319 | SEARCH on $(pngfile) = $(pngsrcdir) $(pngdir) ; |
|---|
| 320 | NoCare $(pngfile) ; |
|---|
| 321 | Depends $(icnsfile) : $(pngfile) ; |
|---|
| 322 | in_$(size) = $(pngfile) ; |
|---|
| 323 | } |
|---|
| 324 | if $(CMD.MAKEICNS) != "" |
|---|
| 325 | { |
|---|
| 326 | # Generate ICNS using makeicns |
|---|
| 327 | |
|---|
| 328 | # If an image of a size is not available, default to the next larger size. |
|---|
| 329 | # Note that `makeicns' takes care of downsizing to the smaller size in |
|---|
| 330 | # that case. |
|---|
| 331 | if ! $(in_256) { in_256 = $(in_512) ; } |
|---|
| 332 | if ! $(in_128) { in_128 = $(in_256) ; } |
|---|
| 333 | INPUT_512 on $(icnsfile) = $(in_512) ; |
|---|
| 334 | INPUT_256 on $(icnsfile) = $(in_256) ; |
|---|
| 335 | INPUT_128 on $(icnsfile) = $(in_128) ; |
|---|
| 336 | MakeLocate $(icnsfile) : $(SUBDIR) ; |
|---|
| 337 | MakeIcns $(icnsfile) ; |
|---|
| 338 | Depends generateicons : $(icnsfile) ; |
|---|
| 339 | } |
|---|
| 340 | else |
|---|
| 341 | { |
|---|
| 342 | # Generate ICNS using png2icns |
|---|
| 343 | |
|---|
| 344 | if $(CMD.CONVERT) != "" |
|---|
| 345 | { |
|---|
| 346 | # png2icns doesn't handle resizing, so do it ourselves |
|---|
| 347 | if ! $(in_256) |
|---|
| 348 | { |
|---|
| 349 | if $(in_512) |
|---|
| 350 | { |
|---|
| 351 | in_256 = [ DownsampleImage generateicons : $(in_512) : 256 ] ; |
|---|
| 352 | Depends $(icnsfile) : $(in_256) ; |
|---|
| 353 | } |
|---|
| 354 | } |
|---|
| 355 | if ! $(in_128) |
|---|
| 356 | { |
|---|
| 357 | if $(in_256) |
|---|
| 358 | { |
|---|
| 359 | in_128 = [ DownsampleImage generateicons : $(in_256) : 128 ] ; |
|---|
| 360 | Depends $(icnsfile) : $(in_128) ; |
|---|
| 361 | } |
|---|
| 362 | } |
|---|
| 363 | } |
|---|
| 364 | else |
|---|
| 365 | { |
|---|
| 366 | # Make do with the images we have, but issue a warning |
|---|
| 367 | local need_resize ; |
|---|
| 368 | if $(in_512) |
|---|
| 369 | { |
|---|
| 370 | if ! $(in_256) || ! $(in_128) { need_resize = "yes" ; } |
|---|
| 371 | } |
|---|
| 372 | else if $(in_256) |
|---|
| 373 | { |
|---|
| 374 | if ! $(in_128) { need_resize = "yes" ; } |
|---|
| 375 | } |
|---|
| 376 | if $(need_resize) |
|---|
| 377 | { |
|---|
| 378 | Echo "ImageMagick not available, $(icnsfile) will be incomplete" ; |
|---|
| 379 | } |
|---|
| 380 | } |
|---|
| 381 | MakeLocate $(icnsfile) : $(SUBDIR) ; |
|---|
| 382 | Png2icns $(icnsfile) : $(in_128) $(in_256) $(in_512) ; |
|---|
| 383 | Depends generateicons : $(icnsfile) ; |
|---|
| 384 | } |
|---|
| 385 | } |
|---|
| 386 | } |
|---|
| 387 | |
|---|
| 388 | actions MakeIcns bind INPUT_128 INPUT_256 INPUT_512 |
|---|
| 389 | { |
|---|
| 390 | args= |
|---|
| 391 | if [ -n "$(INPUT_512)" ]; then |
|---|
| 392 | args="$args -512 $(INPUT_512)" |
|---|
| 393 | fi |
|---|
| 394 | if [ -n "$(INPUT_256)" ]; then |
|---|
| 395 | args="$args -256 $(INPUT_256)" |
|---|
| 396 | fi |
|---|
| 397 | if [ -n "$(INPUT_128)" ]; then |
|---|
| 398 | args="$args -128 $(INPUT_128)" |
|---|
| 399 | fi |
|---|
| 400 | $(CMD.MAKEICNS) $args -out $(<) |
|---|
| 401 | } |
|---|
| 402 | |
|---|
| 403 | actions Png2icns |
|---|
| 404 | { |
|---|
| 405 | $(CMD.PNG2ICNS) $(<) $(>) |
|---|
| 406 | } |
|---|
| 407 | } |
|---|
| 408 | else |
|---|
| 409 | { |
|---|
| 410 | rule IconsMakeMacICNS { } |
|---|
| 411 | } |
|---|