3 # bin/render-cursor-image
4 # Part of ComixCursors, a desktop cursor theme.
6 # Copyright © 2010 Ben Finney <ben+gnome@benfinney.id.au>
7 # Copyright © 2006–2010 Jens Luetkens <j.luetkens@hamburg.de>
9 # This work is free software: you can redistribute it and/or modify it
10 # under the terms of the GNU General Public License as published by
11 # the Free Software Foundation, either version 3 of the License, or
12 # (at your option) any later version.
14 # This work is distributed in the hope that it will be useful, but
15 # WITHOUT ANY WARRANTY; without even the implied warranty of
16 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
17 # General Public License for more details.
19 # You should have received a copy of the GNU General Public License
20 # along with this work. If not, see <http://www.gnu.org/licenses/>.
22 # Generate a PNG cursor image from SVG source.
25 # ImageMagick: http://www.imagemagick.org/
26 # librsvg: http://librsvg.sourceforge.net/
28 function show_usage_message
{
30 Usage: $0 [options] <in name> <in file> <out file>
32 Generate a PNG cursor image from SVG source.
34 Take a simple SVG file, export it to PNG, do some image magic,
35 generate a shadow, composite with a background image, scale and merge
36 it to a single PNG image.
39 --help Show this help text, then exit.
40 --orientation <facing> Specify the orientation of this cursor.
41 --frame <frame num> Specify frame number of animated cursor.
42 --duration <duration> Duration (in milliseconds) for this frame.
43 --background <file> Background image file for compositing.
48 THEMENAME
="${THEMENAME:-custom}"
50 configfile
="ComixCursorsConfigs/${THEMENAME}.CONFIG"
52 # don't do transparency post-processing by default
53 # used for ComixCursors but not for flatbedcursors
56 # source the theme config file
57 source "${configfile}"
59 # some initialisation before argument processing
60 orientation
="RightHanded"
64 while [ "${1::1}" == "-" ]; do
87 printf "Unexpected option: %q\n" "$1" >&2
104 TMPSIZE
=$
(echo "$SIZE * $TMPSCALE" |
bc)
106 XMOVE
=$
(echo "$XOFFSET * $TMPSCALE" |
bc)
107 YMOVE
=$
(echo "$YOFFSET * $TMPSCALE" |
bc)
109 SCALEBLUR
=$
(echo "$BLUR * $TMPSCALE" |
bc)
110 SCALESIZE
=$
(echo "$SIZE * $TMPSCALE" |
bc)
112 # Scaling the shadow from the cursor image.
113 SHADOWSIZE
=$
(echo "$TMPSIZE * $SHADOWSCALE" |
bc)
114 RIGHT
=$
(echo "$TMPSIZE / $SHADOWSCALE" |
bc)
115 LEFT
=$
(echo "$TMPSIZE - $RIGHT" |
bc)
117 if [ "$frame" -lt 1 ]; then
118 echo "processing $NAME..."
120 echo "processing $NAME frame $frame..."
123 # write the hotspot config file
124 hotspots_file
="$(dirname $infile)/HOTSPOTS"
125 if [ "$background_image" ] ; then
126 background_filename
="$(basename $background_image)"
127 hotspot_name
="${background_filename%.png}"
131 hotspot
=( $
(grep "^$hotspot_name" "$hotspots_file") )
133 hotx
=$
(echo "${hotspot[1]} * $SIZE / 500" |
bc)
134 hoty
=$
(echo "${hotspot[2]} * $SIZE / 500" |
bc)
136 xcursor_config
="$(dirname $outfile)/${NAME}.conf"
137 if [ "$frame" -lt 2 ] ; then
138 if [ -e "${xcursor_config}" ]; then
139 rm "${xcursor_config}"
143 if [ "$frame" -gt 0 ] ; then
144 echo "$SIZE $hotx $hoty $outfile $duration" >> "${xcursor_config}"
146 echo "$SIZE $hotx $hoty $outfile" >> "${xcursor_config}"
149 image_name
="${outfile%.png}"
150 bare_image
="${image_name}.bare.png"
151 shadow_name
="${image_name%.frame*}"
152 shadow_image
="${shadow_name}.${orientation}.${SIZE}.${SHADOWCOLOR}.${SHADOWTRANS}.shadow.png"
153 silhouette_image
="${image_name}.silhouette.png"
156 # Convert a single SVG image to PNG.
162 --dpi-x 72 --dpi-y 72 \
163 --width $size --height $size \
167 function make_shadow_image
{
168 # Make the shadow image from a bare image and a silhouette.
170 local silhouette_image
="$2"
171 local shadow_image
="$3"
174 -extract ${SHADOWSIZE}x${SHADOWSIZE}+${LEFT}+${LEFT} \
175 -resize ${TMPSIZE}x
${TMPSIZE} \
176 "$bare_image" "$silhouette_image"
178 convert
-modulate 0 \
179 -fill "$SHADOWCOLOR" \
182 -fx \'a-
$SHADOWTRANS\' \
183 "$silhouette_image" "$shadow_image"
185 mogrify
-channel Alpha \
186 -blur ${SCALEBLUR}x
${SCALEBLUR} \
190 mogrify
-roll +${XMOVE}+${YMOVE} \
195 # Render the bare cursor image.
196 svg2png
"$infile" "$bare_image" $TMPSIZE
198 # Check whether the shadow image is cached.
199 if [ ! -f "$shadow_image" ] ; then
200 # Make the shadow image.
201 make_shadow_image
"$bare_image" "$silhouette_image" "$shadow_image"
204 # Apply alpha-channel opacity to the bare image.
205 if [ $
(echo "$CURSORTRANS > 0" |
bc) -gt 0 ]; then
206 convert
-channel Alpha
-fx \'a-
$CURSORTRANS\' "$bare_image" "$bare_image"
209 # Compose the final image.
210 composite
-geometry ${SIZE}x
${SIZE} "$bare_image" "$shadow_image" "$outfile"
212 if [ "$background_image" ]; then
213 composite
"$outfile" "$background_image" "$outfile"