+/*
+ * A face's background pixmap will override the face's
+ * background color. But the background pixmap of the
+ * default face should not override the background color of
+ * a face if the background color has been specified or
+ * inherited.
+ *
+ * To accomplish this we remove the background pixmap of the
+ * cachel and mark it as having been specified so that cachel
+ * merging won't override it later.
+ */
+#define MAYBE_UNFROB_BACKGROUND_PIXMAP \
+do \
+{ \
+ if (! default_face \
+ && cachel->background_specified \
+ && ! cachel->background_pixmap_specified) \
+ { \
+ cachel->background_pixmap = Qunbound; \
+ cachel->background_pixmap_specified = 1; \
+ } \
+} while (0)
+
+
+/* Add a cachel for the given face to the given window's cache. */
+
+static void
+add_face_cachel (struct window *w, Lisp_Object face)
+{
+ int must_finish_frobbing = ! WINDOW_FACE_CACHEL (w, DEFAULT_INDEX);
+ struct face_cachel new_cachel;
+ Lisp_Object domain;
+
+ reset_face_cachel (&new_cachel);
+ XSETWINDOW (domain, w);
+ update_face_cachel_data (&new_cachel, domain, face);
+ Dynarr_add (w->face_cachels, new_cachel);
+
+ /* The face's background pixmap have not yet been frobbed (see comment
+ int update_face_cachel_data), so we have to do it now */
+ if (must_finish_frobbing)
+ {
+ int default_face = EQ (face, Vdefault_face);
+ struct face_cachel *cachel
+ = Dynarr_atp (w->face_cachels, Dynarr_length (w->face_cachels) - 1);
+
+ FROB (background_pixmap);
+ MAYBE_UNFROB_BACKGROUND_PIXMAP;
+ }
+}
+
+/* Called when the updated flag has been cleared on a cachel.
+ This function returns 1 if the caller must finish the update (see comment
+ below), 0 otherwise.
+*/
+
+void
+update_face_cachel_data (struct face_cachel *cachel,
+ Lisp_Object domain,
+ Lisp_Object face)
+{
+ if (XFACE (face)->dirty || UNBOUNDP (cachel->face))
+ {
+ int default_face = EQ (face, Vdefault_face);
+ cachel->face = face;
+
+ /* We normally only set the _specified flags if the value was
+ actually bound. The exception is for the default face where
+ we always set it since it is the ultimate fallback. */
+