summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorEli Zaretskii <eliz@gnu.org>2019-01-28 17:24:04 +0200
committerEli Zaretskii <eliz@gnu.org>2019-01-28 17:24:04 +0200
commitcd06d173a602bf0aa8a227ff1626dc70013fe480 (patch)
tree054908e08e1f1adcc8aace9b10e872e05e592b6a
parentfa7a841124578c00872d8a5aa834f6bbe57400ff (diff)
downloademacs-cd06d173a602bf0aa8a227ff1626dc70013fe480.tar.gz
Fix bug with face-id after restoring from pdump
* src/xfaces.c (init_xfaces): New function. * src/emacs.c (main) [HAVE_PDUMPER]: If dumped with pdumper, call init_xfaces. (Bug#34226) * src/lisp.h (init_xfaces) [HAVE_PDUMPER]: Add prototype. * test/lisp/faces-tests.el (faces--test-face-id): New test for bug#34226.
-rw-r--r--src/emacs.c5
-rw-r--r--src/lisp.h3
-rw-r--r--src/xfaces.c40
-rw-r--r--test/lisp/faces-tests.el9
4 files changed, 57 insertions, 0 deletions
diff --git a/src/emacs.c b/src/emacs.c
index 2acee8e6fea..d6b8a87c723 100644
--- a/src/emacs.c
+++ b/src/emacs.c
@@ -1484,6 +1484,11 @@ Using an Emacs configured with --with-x-toolkit=lucid does not have this problem
running_asynch_code = 0;
init_random ();
+#ifdef HAVE_PDUMPER
+ if (dumped_with_pdumper_p ())
+ init_xfaces ();
+#endif
+
#if defined HAVE_JSON && !defined WINDOWSNT
init_json ();
#endif
diff --git a/src/lisp.h b/src/lisp.h
index c5631e28453..5159f050a49 100644
--- a/src/lisp.h
+++ b/src/lisp.h
@@ -4606,6 +4606,9 @@ extern void syms_of_w32cygwinx (void);
extern Lisp_Object Vface_alternative_font_family_alist;
extern Lisp_Object Vface_alternative_font_registry_alist;
extern void syms_of_xfaces (void);
+#ifdef HAVE_PDUMPER
+extern void init_xfaces (void);
+#endif
#ifdef HAVE_X_WINDOWS
/* Defined in xfns.c. */
diff --git a/src/xfaces.c b/src/xfaces.c
index cffa89e1f39..7facb13b76c 100644
--- a/src/xfaces.c
+++ b/src/xfaces.c
@@ -6507,6 +6507,46 @@ DEFUN ("show-face-resources", Fshow_face_resources, Sshow_face_resources,
Initialization
***********************************************************************/
+#ifdef HAVE_PDUMPER
+/* All the faces defined during loadup are recorded in
+ face-new-frame-defaults, with the last face first in the list. We
+ need to set next_lface_id to the next face ID number, so that any
+ new faces defined in this session will have face IDs different from
+ those defined during loadup. We also need to set up the
+ lface_id_to_name[] array for the faces that were defined during
+ loadup. */
+void
+init_xfaces (void)
+{
+ if (CONSP (Vface_new_frame_defaults))
+ {
+ Lisp_Object lface = XCAR (Vface_new_frame_defaults);
+ if (CONSP (lface))
+ {
+ /* The first face in the list is the last face defined
+ during loadup. Compute how many faces are there, and
+ allocate the lface_id_to_name[] array. */
+ Lisp_Object lface_id = Fget (XCAR (lface), Qface);
+ lface_id_to_name_size = next_lface_id = XFIXNAT (lface_id) + 1;
+ lface_id_to_name = xnmalloc (next_lface_id, sizeof *lface_id_to_name);
+ /* Store the last face. */
+ lface_id_to_name[next_lface_id - 1] = lface;
+
+ /* Store the rest of the faces. */
+ Lisp_Object tail;
+ for (tail = XCDR (Vface_new_frame_defaults); CONSP (tail);
+ tail = XCDR (tail))
+ {
+ lface = XCAR (tail);
+ int face_id = XFIXNAT (Fget (XCAR (lface), Qface));
+ eassert (face_id < lface_id_to_name_size);
+ lface_id_to_name[face_id] = lface;
+ }
+ }
+ }
+}
+#endif
+
void
syms_of_xfaces (void)
{
diff --git a/test/lisp/faces-tests.el b/test/lisp/faces-tests.el
index 4447dd7b309..f00c93cedcb 100644
--- a/test/lisp/faces-tests.el
+++ b/test/lisp/faces-tests.el
@@ -60,5 +60,14 @@
(should (equal (background-color-at-point) "black"))
(should (equal (foreground-color-at-point) "black"))))
+(ert-deftest faces--test-face-id ()
+ ;; Face ID of 0 is the 'default' face; no face should have the same ID.
+ (should (> (face-id 'faces--test1) 0))
+ ;; 'tooltip' is the last face defined by preloaded packages, so any
+ ;; face we define in Emacs should have a face ID greater than that,
+ ;; since the ID of a face is just its index in the array that maps
+ ;; face IDs to faces.
+ (should (> (face-id 'faces--test1) (face-id 'tooltip))))
+
(provide 'faces-tests)
;;; faces-tests.el ends here