emacs-devel
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: Miles' patch still fixes xfaces.c


From: Robert J. Chassell
Subject: Re: Miles' patch still fixes xfaces.c
Date: Sat, 31 May 2003 21:43:09 +0000 (UTC)

    Can you show me that fix?  Maybe we can change it not to crash.

Here it is:

------- Start of forwarded message -------
To: address@hidden
System-Type: i686-pc-linux-gnu
From: Miles Bader <address@hidden>
Date: 18 Dec 2002 19:01:01 +0900
In-Reply-To: <address@hidden>
MIME-Version: 1.0
Content-Type: multipart/mixed; boundary="=-=-="
cc: address@hidden
Subject: Re: Bold by moving pixels problem
Reply-To: Miles Bader <address@hidden>


- --=-=-=

Here's an updated version of my patch, that uses a list of functions:



- --=-=-=
Content-Type: text/x-patch
Content-Disposition: attachment;
  filename=realize-face-filter-20021218-0.patch
Content-Description: realize-face-filter-20021218-0.patch

2002-12-17  Miles Bader  <address@hidden>

        * xfaces.c (Vrealize_face_filter_functions): New variable.
        (realize_face): If Vrealize_face_filter_functions has a non-nil
        value, use it to filter the face attributes before realization.
        Use new calling conventions for realize_x_face, realize_tty_face,
        and load_face_font.
        (realize_x_face, realize_tty_face): Add new argument FACE, and
        change return type to void.  Use FACE instead of creating our own.
        (load_face_font): Add a new argument ATTRS, and use it instead of
        FACE->lface.
        (syms_of_xfaces): Initialize Vrealize_face_filter_functions.

Index: src/xfaces.c
===================================================================
RCS file: /cvsroot/emacs/emacs/src/xfaces.c,v
retrieving revision 1.266
diff -u -r1.266 xfaces.c
- --- src/xfaces.c      17 Nov 2002 23:51:19 -0000      1.266
+++ src/xfaces.c        18 Dec 2002 05:26:34 -0000
@@ -422,6 +422,13 @@
 
 Lisp_Object Vtty_defined_color_alist;
 
+/* A list of functions to perturb faces before final realization.
+   They are passed a lisp-vector containing all the attributes of the
+   fully-specified face, and can change any that they wish. */
+
+Lisp_Object Vrealize_face_filter_functions;
+
+
 /* Counter for calls to clear_face_cache.  If this counter reaches
    CLEAR_FONT_TABLE_COUNT, and a frame has more than
    CLEAR_FONT_TABLE_NFONTS load, unused fonts are freed.  */
@@ -481,7 +488,7 @@
 static unsigned char *xstrlwr P_ ((unsigned char *));
 static void signal_error P_ ((char *, Lisp_Object));
 static struct frame *frame_or_selected_frame P_ ((Lisp_Object, int));
- -static void load_face_font P_ ((struct frame *, struct face *, int));
+static void load_face_font P_ ((struct frame *, struct face *, Lisp_Object *, 
int));
 static void load_face_colors P_ ((struct frame *, struct face *, Lisp_Object 
*));
 static void free_face_colors P_ ((struct frame *, struct face *));
 static int face_color_gray_p P_ ((struct frame *, char *));
@@ -502,10 +509,10 @@
 static int cmp_font_names P_ ((const void *, const void *));
 static struct face *realize_face P_ ((struct face_cache *, Lisp_Object *, int,
                                      struct face *, int));
- -static struct face *realize_x_face P_ ((struct face_cache *,
- -                                     Lisp_Object *, int, struct face *));
- -static struct face *realize_tty_face P_ ((struct face_cache *,
- -                                       Lisp_Object *, int));
+static void realize_x_face P_ ((struct face *, struct face_cache *,
+                               Lisp_Object *, int, struct face *));
+static void realize_tty_face P_ ((struct face *, struct face_cache *,
+                                 Lisp_Object *, int));
 static int realize_basic_faces P_ ((struct frame *));
 static int realize_default_face P_ ((struct frame *));
 static void realize_named_face P_ ((struct frame *, Lisp_Object, int));
@@ -1245,14 +1252,15 @@
 
 #ifdef HAVE_WINDOW_SYSTEM
 
- -/* Load font of face FACE which is used on frame F to display
- -   character C.  The name of the font to load is determined by lface
- -   and fontset of FACE.  */
+/* Load font of face FACE with attributes ATTRS which is used on frame F to
+   display character C.  The name of the font to load is determined by
+   lface and fontset of FACE.  */
 
 static void
- -load_face_font (f, face, c)
+load_face_font (f, face, attrs, c)
      struct frame *f;
      struct face *face;
+     Lisp_Object *attrs;
      int c;
 {
   struct font_info *font_info = NULL;
@@ -1262,7 +1270,7 @@
   face->font_info_id = -1;
   face->font = NULL;
 
- -  font_name = choose_face_font (f, face->lface, face->fontset, c,
+  font_name = choose_face_font (f, attrs, face->fontset, c,
                                &needs_overstrike);
   if (!font_name)
     return;
@@ -6678,6 +6686,11 @@
      int former_face_id;
 {
   struct face *face;
+  /* The set of attributes this face is know by to the user, as opposed to
+     the set actually used to render the face.  They're usually the same
+     as, but may be different if some attribute is changed by
+     realize-face-filter.  */
+  Lisp_Object *orig_attrs = attrs;
 
   /* LFACE must be fully specified.  */
   xassert (cache != NULL);
@@ -6691,41 +6704,70 @@
       free_realized_face (cache->f, former_face);
     }
 
+  if (CONSP (Vrealize_face_filter_functions))
+    {
+      /* Call these user-defined functions to perturb the face attributes
+        before realization.  */
+      Lisp_Object filters, cycle_check;
+      Lisp_Object lface = Fmake_vector (make_number (LFACE_VECTOR_SIZE),
+                                       Qunspecified);
+
+      bcopy (attrs, XVECTOR (lface)->contents,
+            LFACE_VECTOR_SIZE * (sizeof *attrs));
+
+      cycle_check = Qnil;
+      for (filters = Vrealize_face_filter_functions;
+          CONSP (filters);
+          filters = XCDR (filters))
+       {
+         safe_call1 (XCAR (filters), lface);
+         cycle_check = CYCLE_CHECK (cycle_check, filters, 50);
+         if (NILP (cycle_check))
+           break;              /* cycle detected */
+       }
+
+      attrs = XVECTOR (lface)->contents;
+    }      
+
+  /* Allocate a new realized face.  */
+  face = make_realized_face (orig_attrs);
+
+  /* Fill it in.  */
   if (FRAME_WINDOW_P (cache->f))
- -    face = realize_x_face (cache, attrs, c, base_face);
+    realize_x_face (face, cache, attrs, c, base_face);
   else if (FRAME_TERMCAP_P (cache->f) || FRAME_MSDOS_P (cache->f))
- -    face = realize_tty_face (cache, attrs, c);
+    realize_tty_face (face, cache, attrs, c);
   else
     abort ();
 
   /* Insert the new face.  */
- -  cache_face (cache, face, lface_hash (attrs));
+  cache_face (cache, face, lface_hash (orig_attrs));
 #ifdef HAVE_WINDOW_SYSTEM
   if (FRAME_WINDOW_P (cache->f) && face->font == NULL)
- -    load_face_font (cache->f, face, c);
+    load_face_font (cache->f, face, attrs, c);
 #endif  /* HAVE_WINDOW_SYSTEM */
   return face;
 }
 
 
- -/* Realize the fully-specified face with attributes ATTRS in face
- -   cache CACHE for character C.  Do it for X frame CACHE->f.  If C is
- -   a multibyte character, BASE_FACE is a face that has the same
- -   attributes.  Otherwise, BASE_FACE is ignored.  If the new face
- -   doesn't share font with the default face, a fontname is allocated
- -   from the heap and set in `font_name' of the new face, but it is not
- -   yet loaded here.  Value is a pointer to the newly created realized
- -   face.  */
+/* Realize into FACE the fully-specified face with attributes ATTRS in face
+   cache CACHE for character C.  Do it for X frame CACHE->f.  If C is a
+   multibyte character, BASE_FACE is a face that has the same attributes.
+   Otherwise, BASE_FACE is ignored.  If the new face doesn't share font
+   with the default face, a fontname is allocated from the heap and set in
+   `font_name' of the new face, but it is not yet loaded here.  Value is a
+   pointer to the newly created realized face.  */
 
- -static struct face *
- -realize_x_face (cache, attrs, c, base_face)
+static void
+realize_x_face (face, cache, attrs, c, base_face)
+     struct face *face;
      struct face_cache *cache;
      Lisp_Object *attrs;
      int c;
      struct face *base_face;
 {
 #ifdef HAVE_WINDOW_SYSTEM
- -  struct face *face, *default_face;
+  struct face *default_face;
   struct frame *f;
   Lisp_Object stipple, overline, strike_through, box;
 
@@ -6733,9 +6775,6 @@
   xassert (SINGLE_BYTE_CHAR_P (c)
           || base_face);
 
- -  /* Allocate a new realized face.  */
- -  face = make_realized_face (attrs);
- -
   f = cache->f;
 
   /* If C is a multibyte character, we share all face attirbutes with
@@ -6751,7 +6790,7 @@
 
       /* to force realize_face to load font */
       face->font = NULL;
- -      return face;
+      return;
     }
 
   /* Now we are realizing a face for ASCII (and unibyte) characters.  */
@@ -6921,7 +6960,6 @@
     face->stipple = load_pixmap (f, stipple, &face->pixmap_w, &face->pixmap_h);
 
   xassert (FACE_SUITABLE_FOR_CHAR_P (face, c));
- -  return face;
 #endif /* HAVE_WINDOW_SYSTEM */
 }
 
@@ -7012,17 +7050,16 @@
 }
 
 
- -/* Realize the fully-specified face with attributes ATTRS in face
- -   cache CACHE for character C.  Do it for TTY frame CACHE->f.  Value is a
- -   pointer to the newly created realized face.  */
+/* Realize into FACE the fully-specified face with attributes ATTRS in face
+   cache CACHE for character C.  Do it for TTY frame CACHE->f.  */
 
- -static struct face *
- -realize_tty_face (cache, attrs, c)
+static void
+realize_tty_face (face, cache, attrs, c)
+     struct face *face;
      struct face_cache *cache;
      Lisp_Object *attrs;
      int c;
 {
- -  struct face *face;
   int weight, slant;
   int face_colors_defaulted = 0;
   struct frame *f = cache->f;
@@ -7030,8 +7067,6 @@
   /* Frame must be a termcap frame.  */
   xassert (FRAME_TERMCAP_P (cache->f) || FRAME_MSDOS_P (cache->f));
 
- -  /* Allocate a new realized face.  */
- -  face = make_realized_face (attrs);
   face->font_name = FRAME_MSDOS_P (cache->f) ? "ms-dos" : "tty";
 
   /* Map face attributes to TTY appearances.  We map slant to
@@ -7068,8 +7103,6 @@
       && face->background == FACE_TTY_DEFAULT_FG_COLOR
       && face->foreground == FACE_TTY_DEFAULT_BG_COLOR)
     face->tty_bold_p = 0;
- -
- -  return face;
 }
 
 
@@ -7670,6 +7703,14 @@
 Each element is a regular expression that matches names of fonts to
 ignore.  */);
   Vface_ignored_fonts = Qnil;
+
+  DEFVAR_LISP ("realize-face-filter-functions",
+              &Vrealize_face_filter_functions,
+              doc:/* A list of functions to perturb faces before final 
realization.
+They are passed a lisp-vector containing all the attributes of the
+fully-specified face, and can change any that they wish. */);
+  Vrealize_face_filter_functions = Qnil;
+
 
 #ifdef HAVE_WINDOW_SYSTEM
   defsubr (&Sbitmap_spec_p);

- --=-=-=



Also, here's a lisp file that implements some filters:



- --=-=-=
Content-Type: application/emacs-lisp
Content-Disposition: attachment; filename=relfilt.el
Content-Description: Some filters for face-realization

(defun lface-emulate-bold-with-color (lface)
  (if (memq (aref lface 4)
            '(bold heavy extra-bold semi-bold ultra-bold))
      (let ((fg-vals (color-values (aref lface 8))))
        ;; unboldify
        (aset lface 4 'normal)
        ;; Tweak the fg color to indicate bold.
        (cond ((equal fg-vals '(65535 65535 65535))
               (aset lface 8 "khaki"))
              ((equal fg-vals '(0 0 0))
               (aset lface 8 "orange4"))
              (t
               ;; intensify the color
               (aset lface 8 (highlight-color (aref lface 8) 2 5000)))))))

(defun lface-replace-italic-with-underline (lface)
  (if (not (eq (aref lface 5) 'normal))
      (progn
        ;; remove italics
        (aset lface 5 'normal)
        ;; underline (we preserve an existing value, in case it's colored)
        (if (null (aref lface 6))
            (aset lface 6 t)))))

(push 'lface-emulate-bold-with-color realize-face-filter-functions)
(push 'lface-replace-italic-with-underline realize-face-filter-functions)
(clear-face-cache)

;;; highlight-color function
(defconst highlight-color-dark-boost-limit 48000)
(defun highlight-color (color factor &optional delta)
 "Return a color which is lighter or darker than COLOR by FACTOR and DELTA."
 (let* ((old-rgb (if (stringp color) (color-values color) color))
        (red (car old-rgb))
        (green (cadr old-rgb))
        (blue (nth 2 old-rgb))
        (bright (/ (+ (* red 2) (* green 3) blue) 6)))
   (setq red (min 65535 (* red factor)))
   (setq green (min 65535 (* green factor)))
   (setq blue (min 65535 (* blue factor)))
   (when (and (< bright highlight-color-dark-boost-limit) delta)
     ;; Make an additive adjustment to NEW, because it's dark enough so
     ;; that scaling by FACTOR alone isn't enough.
     (let* ((dimness
             ;; How far below the limit this color is (0 - 1, 1 being darker).
             (- 1 (/ (float bright) highlight-color-dark-boost-limit)))
            (min-delta
             ;; The additive adjustment.
             (* delta dimness factor 0.5)))
       (cond ((< factor 1)
              (setq red (max 0 (- red min-delta)))
              (setq green (max 0 (- green min-delta)))
              (setq blue (max 0 (- blue min-delta))))
             (t
              (setq red (min 65535 (+ red min-delta)))
              (setq green (min 65535 (+ green min-delta)))
              (setq blue (min 65535 (+ blue min-delta)))))))
   (format "#%04X%04X%04X" red green blue)))

- --=-=-=



- -Miles
- -- 
I'm beginning to think that life is just one long Yoko Ono album; no rhyme
or reason, just a lot of incoherent shrieks and then it's over.  --Ian Wolff

- --=-=-=
Content-Type: text/plain; charset="us-ascii"
MIME-Version: 1.0
Content-Transfer-Encoding: 7bit

_______________________________________________
Emacs-devel mailing list
address@hidden
http://mail.gnu.org/mailman/listinfo/emacs-devel

- --=-=-=--
------- End of forwarded message -------




reply via email to

[Prev in Thread] Current Thread [Next in Thread]