root/CS/trunk/mk/jam/icons.jam

Revision 34928, 12.6 KB (checked in by res2002, 21 months ago)

Also png2icns for ICNS generation, when available

  • Property svn:mime-type set to text/plain
  • Property svn:eol-style set to native
Line 
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#============================================================================
19if $(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}
132else
133{
134  rule IconsFromSVG { }
135}
136
137if $(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}
236else
237{
238  rule IconsMakeWin32ICO { }
239}
240
241if $(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}
408else
409{
410  rule IconsMakeMacICNS { }
411}
Note: See TracBrowser for help on using the browser.