1#!@shell@
2
3export PATH=@PATH@:$PATH
4
5export FONTCONFIG_FILE="@FONTCONFIG_FILE@"
6ENCODINGSDIR="@ENCODINGSDIR@"
7FC_LOCKFILE=""
8
9# Are we caching system fonts or user fonts?
10system=0
11
12# Are we including OSX font dirs ({/,~/,/System/}Library/Fonts)
13osxfonts=1
14
15# Do we want to force a recache?
16force=0
17
18# How noisy are we?
19verbose=0
20
21# Check if the data in the given directory is newer than its cache
22check_dirty() {
23 local dir=$1
24 local fontfiles=""
25 local retval=1
26
27 # If the dir does not exist, we just exit
28 if [[ ! -d "${dir}" ]]; then
29 return 1
30 fi
31
32 # Create a list of all files in the dir
33 # Filter out config / cache files. Ugly... counting down the day until
34 # xfs finally goes away
35 fontfiles="$(find ${dir}/ -maxdepth 1 -type f | awk '$0 !~ /fonts\..*$|^.*\.dir$/ {print}')"
36
37 # Fonts were deleted (or never there). Kill off the caches
38 if [[ -z "${fontfiles}" ]] ; then
39 local f
40 for f in "${dir}"/fonts.* "${dir}"/encodings.dir; do
41 if [[ -f ${f} ]] ; then
42 rm -f "${f}"
43 fi
44 done
45 return 1
46 fi
47
48 # Force a recache
49 if [[ ${force} == 1 ]] ; then
50 retval=0
51 fi
52
53 # If we don't have our caches, we are dirty
54 if [[ ! -f "${dir}/fonts.list" || ! -f "${dir}/fonts.dir" || ! -f "${dir}/encodings.dir" ]]; then
55 retval=0
56 fi
57
58 # Check that no files were added or removed....
59 if [[ "${retval}" -ne 0 && "$(cat ${dir}/fonts.list)" != "${fontfiles}" ]] ; then
60 retval=0
61 fi
62
63 # Check that no files were updated....
64 if [[ "${retval}" -ne 0 ]] ; then
65 local changed="$(find ${dir}/ -type f -cnewer ${dir}/fonts.dir | awk '$0 !~ /fonts\..*$|^.*\.dir$/ {print}')"
66
67 if [[ -n "${changed}" ]] ; then
68 retval=0
69 fi
70 fi
71
72 # Recreate fonts.list since something changed
73 if [[ "${retval}" == 0 ]] ; then
74 echo "${fontfiles}" > "${dir}"/fonts.list
75 fi
76
77 return ${retval}
78}
79
80get_fontdirs() {
81 local d
82 if [[ $system == 1 ]] ; then
83 if [[ $osxfonts == 1 ]] ; then
84 find {/System/,/}Library/Fonts -type d
85 fi
86 else
87 if [[ $osxfonts == 1 && -d "${HOME}/Library/Fonts" ]] ; then
88 find "${HOME}/Library/Fonts" -type d
89 fi
90
91 if [[ -d "${HOME}/.fonts" ]] ; then
92 find "${HOME}/.fonts" -type d
93 fi
94 fi
95}
96
97setup_fontdirs() {
98 local x=""
99 local fontdirs=""
100 local changed="no"
101
102 umask 022
103
104 if [[ $system == 1 ]] ; then
105 echo "font_cache: Scanning system font directories to generate X11 font caches"
106 else
107 echo "font_cache: Scanning user font directories to generate X11 font caches"
108 fi
109
110 OIFS=$IFS
111 IFS='
112'
113 for x in $(get_fontdirs) ; do
114 if [[ -d "${x}" ]] && check_dirty "${x}" ; then
115 if [[ -z "${fontdirs}" ]] ; then
116 fontdirs="${x}"
117 else
118 fontdirs="${fontdirs}${IFS}${x}"
119 fi
120 fi
121 done
122
123 if [[ -n "${fontdirs}" ]] ; then
124 echo "font_cache: Making fonts.dir for updated directories."
125 for x in ${fontdirs} ; do
126 if [[ $verbose == 1 ]] ; then
127 echo "font_cache: ${x}"
128 fi
129
130 # First, generate fonts.scale for scaleable fonts that might be there
131 @MKFONTSCALE@ \
132 -a $ENCODINGSDIR/encodings.dir \
133 -a $ENCODINGSDIR/large/encodings.dir \
134 -- ${x}
135
136 # Next, generate fonts.dir
137 if [[ $verbose == 1 ]] ; then
138 @MKFONTDIR@ \
139 -e $ENCODINGSDIR \
140 -e $ENCODINGSDIR/large \
141 -- ${x}
142 else
143 @MKFONTDIR@ \
144 -e $ENCODINGSDIR \
145 -e $ENCODINGSDIR/large \
146 -- ${x} > /dev/null
147 fi
148 done
149 fi
150 IFS=$OIFS
151
152 # Finally, update fontconfig's cache
153 echo "font_cache: Updating FC cache"
154 if [[ $system == 1 ]] ; then
155 @FC_CACHE@ -s \
156 $([[ $force == 1 ]] && echo "-f -r") \
157 $([[ $verbose == 1 ]] && echo "-v")
158 else
159 @FC_CACHE@ \
160 $([[ $force == 1 ]] && echo "-f -r") \
161 $([[ $verbose == 1 ]] && echo "-v")
162 fi
163 echo "font_cache: Done"
164}
165
166do_usage() {
167 echo "font_cache [options]"
168 echo " -f, --force : Force cache recreation"
169 echo " -n, --no-osxfonts : Just cache X11 font directories"
170 echo " (-n just pertains to XFont cache, not fontconfig)"
171 echo " -s, --system : Cache system font dirs instead of user dirs"
172 echo " -v, --verbose : Verbose Output"
173}
174
175cleanup() {
176 [[ -r "${FC_LOCKFILE}" ]] && rm -f "${FC_LOCKFILE}"
177 exit 1
178}
179
180while [[ $# -gt 0 ]] ; do
181 case $1 in
182 -s|--system) system=1 ;;
183 -f|--force) force=1 ;;
184 -v|--verbose) verbose=1 ;;
185 -n|--no-osxfonts) osxfonts=0 ;;
186 --help) do_usage ; exit 0 ;;
187 *) do_usage ; exit 1 ;;
188 esac
189 shift
190done
191
192if [[ $system == 1 ]] ; then
193 FC_LOCKFILE="/tmp/font_cache.$UID.lock"
194elif [[ -w "${TMPDIR}" ]] ; then
195 FC_LOCKFILE="${TMPDIR}/font_cache.lock"
196elif [[ -w "/tmp" ]] ; then
197 FC_LOCKFILE="/tmp/font_cache.$UID.lock"
198else
199 FC_LOCKFILE="${HOME}/.font_cache.lock"
200fi
201
202if [[ -x /usr/bin/lockfile ]] ; then
203 if /usr/bin/lockfile -r 0 -l 240 -s 4 -! "${FC_LOCKFILE}" ; then
204 echo "font_cache is already running." >&2
205 echo "If you believe this to be erroneous, please remove ${FC_LOCKFILE}." >&2
206 exit 1
207 fi
208else
209 if [[ -r "${FC_LOCKFILE}" ]] ; then
210 read OLD_PID < "${FC_LOCKFILE}"
211 if kill -0 ${OLD_PID} >& /dev/null ; then
212 echo "font_cache is already running with PID ${OLD_PID}." >&2
213 echo "If you believe this to be erroneous, please remove ${FC_LOCKFILE}." >&2
214 exit 1
215 fi
216
217 echo "Removing stale ${FC_LOCKFILE}" >&2
218 rm -f "${FC_LOCKFILE}"
219 fi
220
221 echo $$ > "${FC_LOCKFILE}"
222
223 if [[ ! -r "${FC_LOCKFILE}" ]] ; then
224 echo "Unable to write to ${FC_LOCKFILE}." >&2
225 exit 1
226 fi
227
228 # Now make sure we didn't collide mid-air
229 read OLD_PID < "${FC_LOCKFILE}"
230 if [[ $$ != ${OLD_PID} ]] ; then
231 echo "font_cache is already running with PID ${OLD_PID}." >&2
232 exit 1
233 fi
234fi
235
236trap cleanup SIGINT SIGQUIT SIGABRT SIGTERM
237
238setup_fontdirs
239
240rm -f "${FC_LOCKFILE}"