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