In order to make font handling a bit more robust, I put together a prototype of how we could build and share a Fontconfig cache that is known to be compatible with a particular GNOME platform snap:
Cache provider
I’ve built this as an independent snap, but could probably be built into the platform snap directly. In essence, it does the following:
- include a private
fonts.conf
file in the snap that searches for fonts in/usr/share/fonts
and/usr/local/share/fonts
, and sets the cache dir to a location under$SNAP_COMMON
(hard coded as a/var/snap/...
path). - include a script that calls
fc-cache -s
using the binary and libraries from the platform snap. - Create a content interface slot to export the generated cache:
slots: fontconfig-cache-gnome-3-34-1804: interface: content read: - $SNAP_COMMON/cache/fontconfig
- symlink the cache generation script to act as a
configure
hook andprepare-slot
hook for the above slot.
The intent of the hooks is to try and ensure the cache is up to date with the fonts on the host system by refreshing it whenever the snap is updated or another snap tries to connect to the cache slot. We could probably also add install a systemd timer to regularly rebuild the cache on top of this, if needed.
And since the cache was built using the fontconfig and freetype libraries from the gnome-3-34-1804
snap, we know that it will be compatible with those libraries in the applications.
Use by applications
Other snaps can then access the cache using a matching plug:
plugs:
fontconfig-cache-gnome-3-34-1804:
interface: content
target: $SNAP_COMMON/cache/fontconfig
default-provider: fontconfig-cache-prototype
Ideally, we’d have the plug mount the cache directly to /var/cache/fontconfig
so the default fontconfig configuration will use it by default. However the content interface does not allow that. I tried working around this using layouts without success:
- If I use layouts to mount
$SNAP_COMMON/cache /fontconfig -> /var/cache/fontconfig
, this mount is performed before the content interface mount, leaving me with an empty directory. - the
desktop
interface tries to mount the host system/var/cache/fontconfig
to this location. One of these loses and tries to mount to/var/cache/fontconfig-2
, which in turn fails due to AppArmor restrictions.
For (1), I wonder if it would make sense to adjust the content interface to allow mounting to any location we allow layouts to bind mount to? If we’re only doing a single bind mount, then the ordering issue goes away.
For (2), the desktop interface currently includes a quirk to skip the /var/cache/fontconfig
mount on Fedora and Arch, where we’ve encountered cache incompatibilities in the past. Maybe it would make sense to extend this into a expose-font-cache
plug attribute so snaps can opt out of that mount on all systems?
If we can get around these issues, this all looks like logic that could be folded into the existing Snapcraft extensions once we update the corresponding platform snaps to build and share a compatible cache.