Switch to upstream source from tarball ‘comixcursors_0.7.orig.tar.bz2’.
[debian_comixcursors.git] / bin / render-cursor-image
blobe56e3b87f2bbfbb6deb3c0891b89a6753743327e
1 #! /bin/bash
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.
24 # Required tools:
25 # ImageMagick: http://www.imagemagick.org/
26 # librsvg: http://librsvg.sourceforge.net/
28 function show_usage_message {
29 cat <<_EOT_
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.
38 Options:
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.
45 _EOT_
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
54 CURSORTRANS=0
56 # source the theme config file
57 source "${configfile}"
59 # some initialisation before argument processing
60 orientation="RightHanded"
61 frame=0
63 # parse argument list
64 while [ "${1::1}" == "-" ]; do
65 case "$1" in
66 --help)
67 show_usage_message
68 exit
70 --orientation)
71 shift
72 orientation="$1"
74 --frame)
75 shift
76 frame=$1
78 --duration)
79 shift
80 duration=$1
82 --background)
83 shift
84 background_image="$1"
87 printf "Unexpected option: %q\n" "$1" >&2
88 show_usage_message
89 exit 2
91 esac
92 shift
93 done
95 if [ $# -lt 3 ]; then
96 show_usage_message
97 exit 2
100 NAME="$1"
101 infile="$2"
102 outfile="$3"
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..."
119 else
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}"
128 else
129 hotspot_name="$NAME"
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}"
145 else
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"
155 function svg2png {
156 # Convert a single SVG image to PNG.
157 local infile="$1"
158 local outfile="$2"
159 local size=$3
161 rsvg --format png \
162 --dpi-x 72 --dpi-y 72 \
163 --width $size --height $size \
164 "$infile" "$outfile"
167 function make_shadow_image {
168 # Make the shadow image from a bare image and a silhouette.
169 local infile="$1"
170 local silhouette_image="$2"
171 local shadow_image="$3"
173 convert \
174 -extract ${SHADOWSIZE}x${SHADOWSIZE}+${LEFT}+${LEFT} \
175 -resize ${TMPSIZE}x${TMPSIZE} \
176 "$bare_image" "$silhouette_image"
178 convert -modulate 0 \
179 -fill "$SHADOWCOLOR" \
180 -colorize 100 \
181 -channel Alpha \
182 -fx \'a-$SHADOWTRANS\' \
183 "$silhouette_image" "$shadow_image"
185 mogrify -channel Alpha \
186 -blur ${SCALEBLUR}x${SCALEBLUR} \
187 -resize 50% \
188 "$shadow_image"
190 mogrify -roll +${XMOVE}+${YMOVE} \
191 "$shadow_image"
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"