diff lisp/w3/font.el @ 70:131b0175ea99 r20-0b30

Import from CVS: tag r20-0b30
author cvs
date Mon, 13 Aug 2007 09:02:59 +0200
parents 6a22abad6937
children 1ce6082ce73f
line wrap: on
line diff
--- a/lisp/w3/font.el	Mon Aug 13 09:00:04 2007 +0200
+++ b/lisp/w3/font.el	Mon Aug 13 09:02:59 2007 +0200
@@ -1,14 +1,13 @@
 ;;; font.el --- New font model
 ;; Author: wmperry
-;; Created: 1997/03/26 20:08:55
-;; Version: 1.40
+;; Created: 1996/08/11 16:40:36
+;; Version: 1.8
 ;; Keywords: faces
 
 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
 ;;; Copyright (c) 1995, 1996 by William M. Perry (wmperry@cs.indiana.edu)
-;;; Copyright (c) 1996, 1997 Free Software Foundation, Inc.
 ;;;
-;;; This file is part of GNU Emacs.
+;;; This file is not part of GNU Emacs, but the same permissions apply.
 ;;;
 ;;; GNU Emacs is free software; you can redistribute it and/or modify
 ;;; it under the terms of the GNU General Public License as published by
@@ -21,17 +20,15 @@
 ;;; GNU General Public License for more details.
 ;;;
 ;;; You should have received a copy of the GNU General Public License
-;;; along with GNU Emacs; see the file COPYING.  If not, write to the
-;;; Free Software Foundation, Inc., 59 Temple Place - Suite 330,
-;;; Boston, MA 02111-1307, USA.
+;;; along with GNU Emacs; see the file COPYING.  If not, write to
+;;; the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
 
 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
 ;;; The emacsen compatibility package - load it up before anything else
 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
 (eval-and-compile
-  (unless (string-match "XEmacs" emacs-version)
-    (require 'w3-sysdp))
+  (load-library "w3-sysdp")
   (require 'cl))
 
 (require 'disp-table)
@@ -49,20 +46,13 @@
 (defconst font-running-xemacs (string-match "XEmacs" (emacs-version))
   "Whether we are running in XEmacs or not.")
 
-(defmacro define-font-keywords (&rest keys)
-  (`
-   (eval-and-compile
-     (let ((keywords (quote (, keys))))
-       (while keywords
-	 (or (boundp (car keywords))
-	     (set (car keywords) (car keywords)))
-	 (setq keywords (cdr keywords)))))))  
+(defmacro defkeyword (keyword &optional docstring)
+  (list 'defconst keyword (list 'quote keyword)
+	(or docstring "A keyword")))
 
 (defconst font-window-system-mappings
   '((x        . (x-font-create-name x-font-create-object))
     (ns       . (ns-font-create-name ns-font-create-object))
-    (win32    . (x-font-create-name x-font-create-object))
-    (pm       . (x-font-create-name x-font-create-object)) ; Change? FIXME
     (tty      . (tty-font-create-plist tty-font-create-object)))
   "An assoc list mapping device types to the function used to create
 a font name from a font structure.")
@@ -135,60 +125,27 @@
     )
   "A list of font family mappings.")
 
-(define-font-keywords :family :style :size :registry :encoding)
-
-(define-font-keywords
-  :weight :extra-light :light :demi-light :medium :normal :demi-bold
-  :bold :extra-bold)
-
-(defvar font-style-keywords nil)
-
-(defsubst set-font-family (fontobj family)
-  (aset fontobj 1 family))
-
-(defsubst set-font-weight (fontobj weight)
-  (aset fontobj 3 weight))
-
-(defsubst set-font-style (fontobj style)
-  (aset fontobj 5 style))
-
-(defsubst set-font-size (fontobj size)
-  (aset fontobj 7 size))
+(defkeyword :family "Keyword specifying the font family of a FONTOBJ.")
 
-(defsubst set-font-registry (fontobj reg)
-  (aset fontobj 9 reg))
-
-(defsubst set-font-encoding (fontobj enc)
-  (aset fontobj 11 enc))
-
-(defsubst font-family (fontobj)
-  (aref fontobj 1))
-
-(defsubst font-weight (fontobj)
-  (aref fontobj 3))
+(defkeyword :weight "Keyword specifying the font weight of a FONTOBJ.")
+ (defkeyword :extra-light)
+ (defkeyword :light)
+ (defkeyword :demi-light)
+ (defkeyword :medium)
+ (defkeyword :normal)
+ (defkeyword :demi-bold)
+ (defkeyword :bold)
+ (defkeyword :extra-bold)
 
-(defsubst font-style (fontobj)
-  (aref fontobj 5))
-
-(defsubst font-size (fontobj)
-  (aref fontobj 7))
-
-(defsubst font-registry (fontobj)
-  (aref fontobj 9))
-
-(defsubst font-encoding (fontobj)
-  (aref fontobj 11))
+(defkeyword :style "Keyword specifying the font style of a FONTOBJ.")
+(defkeyword :size "Keyword specifying the font size of a FONTOBJ.")
+(defkeyword :registry "Keyword specifying the registry of a FONTOBJ.")
+(defkeyword :encoding "Keyword specifying the encoding of a FONTOBJ.")
 
 (eval-when-compile
   (defmacro define-new-mask (attr mask)
     (`
      (progn
-       (setq font-style-keywords
-	     (cons (cons (quote (, attr))
-			 (cons
-			  (quote (, (intern (format "set-font-%s-p" attr))))
-			  (quote (, (intern (format "font-%s-p" attr))))))
-		   font-style-keywords))
        (defconst (, (intern (format "font-%s-mask" attr))) (<< 1 (, mask))
 	 (, (format
 	     "Bitmask for whether a font is to be rendered in %s or not."
@@ -199,18 +156,17 @@
 		      (, (intern (format "font-%s-mask" attr)))))
 	     t
 	   nil))
-       (defun (, (intern (format "set-font-%s-p" attr))) (fontobj val)
+       (defun (, (intern (format "font-set-%s-p" attr))) (fontobj val)
 	 (, (format "Set whether FONTOBJ will be renderd in `%s' or not."
 		    attr))
-	 (cond
-	  (val
-	   (set-font-style fontobj (| (font-style fontobj)
-				      (, (intern
-					  (format "font-%s-mask" attr))))))
-	  (((, (intern (format "font-%s-p" attr))) fontobj)
-	   (set-font-style fontobj (- (font-style fontobj)
-				      (, (intern
-					  (format "font-%s-mask" attr))))))))
+	 (if val
+	     (set-font-style fontobj (| (font-style fontobj)
+					(, (intern
+					    (format "font-%s-mask" attr)))))
+	   (set-font-style fontobj (logxor (font-style fontobj)
+					   (, (intern
+					       (format "font-%s-mask"
+						       attr)))))))
        ))))
 
 (let ((mask 0))
@@ -249,28 +205,6 @@
 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
 ;;; Utility functions
 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
-(defsubst set-font-style-by-keywords (fontobj styles)
-  (make-local-variable 'font-func)
-  (declare (special font-func))
-  (if (listp styles)
-      (while styles
-	(setq font-func (car-safe (cdr-safe (assq (car styles) font-style-keywords)))
-	      styles (cdr styles))
-	(and (fboundp font-func) (funcall font-func fontobj t)))
-    (setq font-func (car-safe (cdr-safe (assq styles font-style-keywords))))
-    (and (fboundp font-func) (funcall font-func fontobj t))))
-
-(defsubst font-properties-from-style (fontobj)
-  (let ((style (font-style fontobj))
-	(todo font-style-keywords)
-	type func retval)
-    (while todo
-      (setq func (cdr (cdr (car todo)))
-	    type (car (pop todo)))
-      (if (funcall func fontobj)
-	  (setq retval (cons type retval))))
-    retval))
-
 (defun unique (list)
   (let ((retval)
 	(cur))
@@ -294,14 +228,10 @@
       w2))))
 
 (defun font-spatial-to-canonical (spec &optional device)
-  "Convert SPEC (in inches, millimeters, points, or picas) into points"
-  ;; 1 in = 6 pa = 25.4 mm = 72 pt
-  (cond
-   ((numberp spec)
-    spec)
-   ((null spec)
-    nil)
-   (t
+  "Convert SPEC (in inches, millimeters, points, or picas) into pixels"
+  ;; 1 in = 25.4 mm = 72 pt = 6 pa
+  (if (numberp spec)
+      spec
     (let ((num nil)
 	  (type nil)
 	  ;; If for any reason we get null for any of this, default
@@ -330,21 +260,30 @@
       (setq num (string-to-number spec))
       (cond
        ((member type '("pixel" "px" "pix"))
-	(setq retval (* num (/ pix-width mm-width) (/ 25.4 72.0))))
+	(setq retval num
+	      num nil))
        ((member type '("point" "pt"))
-	(setq retval num))
+	(setq retval (+ (* (/ pix-width mm-width)
+			   (/ 25.4 72.0)
+			   num))))
        ((member type '("pica" "pa"))
-	(setq retval (* num 12.0)))
+	(setq retval (* (/ pix-width mm-width)
+			(/ 25.4 6.0)
+			num)))
        ((member type '("inch" "in"))
-	(setq retval (* num 72.0)))
+	(setq retval (* (/ pix-width mm-width)
+			(/ 25.4 1.0)
+			num)))
        ((string= type "mm")
-	(setq retval (* num (/ 72.0 25.4))))
+	(setq retval (* (/ pix-width mm-width)
+			num)))
        ((string= type "cm")
-	(setq retval (* num 10 (/ 72.0 25.4))))
-       (t
-	(setq retval num))
+	(setq retval (* (/ pix-width mm-width)
+			10
+			num)))
+       (t (setq retval num))
        )
-      retval))))
+      retval)))
 
 
 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
@@ -352,28 +291,63 @@
 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
 (defun make-font (&rest args)
   (vector :family
-	  (if (stringp (plist-get args :family))
-	      (list (plist-get args :family))
-	    (plist-get args :family))
+	  (if (stringp (nth 1 (memq :family args)))
+	      (list (nth 1 (memq :family args)))
+	    (nth 1 (memq :family args)))
 	  :weight
-	  (plist-get args :weight)
+	  (nth 1 (memq :weight args))
 	  :style
-	  (if (numberp (plist-get args :style))
-	      (plist-get args :style)
+	  (if (numberp (nth 1 (memq :style args)))
+	      (nth 1 (memq :style args))
 	    0)
 	  :size
-	  (plist-get args :size)
+	  (nth 1 (memq :size args))
 	  :registry
-	  (plist-get args :registry)
+	  (nth 1 (memq :registry args))
 	  :encoding
-	  (plist-get args :encoding)))
+	  (nth 1 (memq :encoding args))))
+
+(defsubst set-font-family (fontobj family)
+  (aset fontobj 1 family))
+
+(defsubst set-font-weight (fontobj weight)
+  (aset fontobj 3 weight))
+
+(defsubst set-font-style (fontobj style)
+  (aset fontobj 5 style))
+
+(defsubst set-font-size (fontobj size)
+  (aset fontobj 7 size))
+
+(defsubst set-font-registry (fontobj reg)
+  (aset fontobj 9 reg))
+
+(defsubst set-font-encoding (fontobj enc)
+  (aset fontobj 11 enc))
+
+(defsubst font-family (fontobj)
+  (aref fontobj 1))
+
+(defsubst font-weight (fontobj)
+  (aref fontobj 3))
+
+(defsubst font-style (fontobj)
+  (aref fontobj 5))
+
+(defsubst font-size (fontobj)
+  (aref fontobj 7))
+
+(defsubst font-registry (fontobj)
+  (aref fontobj 9))
+
+(defsubst font-encoding (fontobj)
+  (aref fontobj 11))
 
 (defun font-create-name (fontobj &optional device)
   (let* ((type (device-type device))
 	 (func (car (cdr-safe (assq type font-window-system-mappings)))))
     (and func (fboundp func) (funcall func fontobj device))))
 
-;;;###autoload
 (defun font-create-object (fontname &optional device)
   (let* ((type (device-type device))
 	 (func (car (cdr (cdr-safe (assq type font-window-system-mappings))))))
@@ -426,7 +400,7 @@
 ;;; The window-system dependent code (TTY-style)
 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
 (defun tty-font-create-object (fontname &optional device)
-  (make-font :size "12pt"))
+  )
 
 (defun tty-font-create-plist (fontobj &optional device)
   (let ((styles (font-style fontobj))
@@ -472,47 +446,46 @@
 	   ))))
 
 (defun x-font-create-object (fontname &optional device)
-  (let ((case-fold-search t))
-    (if (or (not (stringp fontname))
-	    (not (string-match font-x-font-regexp fontname)))
-	(make-font)
-      (let ((family nil)
-	    (style nil)
-	    (size nil)
-	    (weight  (match-string 1 fontname))
-	    (slant   (match-string 2 fontname))
-	    (swidth  (match-string 3 fontname))
-	    (adstyle (match-string 4 fontname))
-	    (pxsize  (match-string 5 fontname))
-	    (ptsize  (match-string 6 fontname))
-	    (retval nil)
-	    (case-fold-search t)
-	    )
-	(if (not (string-match x-font-regexp-foundry-and-family fontname))
-	    nil
-	  (setq family (list (downcase (match-string 1 fontname)))))
-	(if (string= "*" weight)  (setq weight  nil))
-	(if (string= "*" slant)   (setq slant   nil))
-	(if (string= "*" swidth)  (setq swidth  nil))
-	(if (string= "*" adstyle) (setq adstyle nil))
-	(if (string= "*" pxsize)  (setq pxsize  nil))
-	(if (string= "*" ptsize)  (setq ptsize  nil))
-	(if ptsize (setq size (/ (string-to-int ptsize) 10)))
-	(if (and (not size) pxsize) (setq size (concat pxsize "px")))
-	(if weight (setq weight (intern-soft (concat ":" (downcase weight)))))
-	(if (and adstyle (not (equal adstyle "")))
-	    (setq family (append family (list (downcase adstyle)))))
-	(setq retval (make-font :family family
-				:weight weight
-				:size size))
-	(set-font-bold-p retval (eq :bold weight))
-	(cond
-	 ((null slant) nil)
-	 ((member slant '("i" "I"))
-	  (set-font-italic-p retval t))
-	 ((member slant '("o" "O"))
-	  (set-font-oblique-p retval t)))
-	retval))))
+  (if (or (not (stringp fontname))
+	  (not (string-match font-x-font-regexp fontname)))
+      (make-font)
+    (let ((family nil)
+	  (style nil)
+	  (size nil)
+	  (weight  (match-string 1 fontname))
+	  (slant   (match-string 2 fontname))
+	  (swidth  (match-string 3 fontname))
+	  (adstyle (match-string 4 fontname))
+	  (pxsize  (match-string 5 fontname))
+	  (ptsize  (match-string 6 fontname))
+	  (retval nil)
+	  (case-fold-search t)
+	  )
+      (if (not (string-match x-font-regexp-foundry-and-family fontname))
+	  nil
+	(setq family (list (match-string 1 fontname))))
+      (if (string= "*" weight)  (setq weight  nil))
+      (if (string= "*" slant)   (setq slant   nil))
+      (if (string= "*" swidth)  (setq swidth  nil))
+      (if (string= "*" adstyle) (setq adstyle nil))
+      (if (string= "*" pxsize)  (setq pxsize  nil))
+      (if (string= "*" ptsize)  (setq ptsize  nil))
+      (if ptsize (setq size (format "%dpt" (/ (string-to-int ptsize) 10))))
+      (if (and (not size) pxsize) (setq size (concat pxsize "px")))
+      (if weight (setq weight (intern-soft (concat ":" (downcase weight)))))
+      (if (and adstyle (not (equal adstyle "")))
+	  (setq family (append family (list adstyle))))
+      (setq retval (make-font :family family
+			      :weight weight
+			      :size size))
+      (font-set-bold-p retval (eq :bold weight))
+      (cond
+       ((null slant) nil)
+       ((member slant '("i" "I"))
+	(font-set-italic-p retval t))
+       ((member slant '("o" "O"))
+	(font-set-oblique-p retval t)))
+      retval)))
 
 (defun x-font-families-for-device (&optional device no-resetp)
   (condition-case ()
@@ -530,23 +503,18 @@
 		(normal (mapcar (function (lambda (x) (if x (aref x 0))))
 				(aref menu 1))))
 	    (sort (unique (nconc scaled normal)) 'string-lessp))))
-    (cons "monospace" (mapcar 'car font-family-mappings))))
+    (mapcar 'car font-family-mappings)))
 
 (defvar font-default-cache nil)
 
-;;;###autoload
 (defun font-default-font-for-device (&optional device)
   (or device (setq device (selected-device)))
   (if font-running-xemacs
       (font-truename
        (make-font-specifier
 	(face-font-name 'default device)))
-    (let ((font (cdr-safe (assq 'font (frame-parameters device)))))
-      (if (and (fboundp 'fontsetp) (fontsetp font))
-	  (aref (get-font-info (aref (cdr (get-fontset-info font)) 0)) 2)
-	font))))
-	  
-;;;###autoload
+    (cdr-safe (assq 'font (frame-parameters device)))))
+
 (defun font-default-object-for-device (&optional device)
   (let ((font (font-default-font-for-device device)))
     (or (cdr-safe 
@@ -557,26 +525,25 @@
 					 font-default-cache))
 	  (cdr-safe (assoc font font-default-cache))))))
 
-;;;###autoload
 (defun font-default-family-for-device (&optional device)
   (or device (setq device (selected-device)))
   (font-family (font-default-object-for-device device)))
 
-;;;###autoload
 (defun font-default-size-for-device (&optional device)
   (or device (setq device (selected-device)))
   ;; face-height isn't the right thing (always 1 pixel too high?)
   ;; (if font-running-xemacs
   ;;    (format "%dpx" (face-height 'default device))
   (font-size (font-default-object-for-device device)))
-
+       
 (defun x-font-create-name (fontobj &optional device)
   (if (and (not (or (font-family fontobj)
 		    (font-weight fontobj)
 		    (font-size fontobj)
 		    (font-registry fontobj)
 		    (font-encoding fontobj)))
-	   (= (font-style fontobj) 0))
+	   (not (font-bold-p fontobj))
+	   (not (font-italic-p fontobj)))
       (face-font 'default)
     (or device (setq device (selected-device)))
     (let ((family (or (font-family fontobj)
@@ -584,9 +551,7 @@
 		      (x-font-families-for-device device)))
 	  (weight (or (font-weight fontobj) :medium))
 	  (style (font-style fontobj))
-	  (size (or (if font-running-xemacs
-			(font-size fontobj))
-		    (font-default-size-for-device device)))
+	  (size (or (font-size fontobj) (font-default-size-for-device device)))
 	  (registry (or (font-registry fontobj) "*"))
 	  (encoding (or (font-encoding fontobj) "*")))
       (if (stringp family)
@@ -619,22 +584,16 @@
 		(if (= ?- (aref cur-family (1- x)))
 		    (aset cur-family (1- x) ? ))
 		(setq x (1- x))))
-	    ;; We treat oblique and italic as equivalent.  Don't ask.
-	    (let ((slants '("o" "i")))
-	      (while (and slants (not done))
-		(setq font-name (format "-*-%s-%s-%s-*-*-*-%s-*-*-*-*-%s-%s"
-					cur-family weight
-					(if (or (font-italic-p fontobj)
-						(font-oblique-p fontobj))
-					    (car slants)
-					  "r")
-					(if size
-					    (int-to-string (* 10 size)) "*")
-					registry
-					encoding
-					)
-		      slants (cdr slants)
-		      done (try-font-name font-name device))))))
+	    (setq font-name (format "-*-%s-%s-%s-*-*-%s-*-*-*-*-*-%s-%s"
+				    cur-family weight
+				    (if (font-italic-p fontobj)
+					"i"
+				      "r")
+				    (if size (int-to-string size) "*")
+				    registry
+				    encoding
+				    )
+		  done (try-font-name font-name device))))
 	(if done font-name)))))
 
 
@@ -645,17 +604,16 @@
   ;; For right now, assume we are going to have the same storage for
   ;; device fonts for NS as we do for X.  Is this a valid assumption?
   (or device (setq device (selected-device)))
-  (if (boundp 'device-fonts-cache)
-      (let ((menu (or (cdr-safe (assq device device-fonts-cache)))))
-	(if (and (not menu) (not no-resetp))
-	    (progn
-	      (reset-device-font-menus device)
-	      (ns-font-families-for-device device t))
-	  (let ((scaled (mapcar (function (lambda (x) (if x (aref x 0))))
-				(aref menu 0)))
-		(normal (mapcar (function (lambda (x) (if x (aref x 0))))
-				(aref menu 1))))
-	    (sort (unique (nconc scaled normal)) 'string-lessp))))))
+  (let ((menu (or (cdr-safe (assq device device-fonts-cache)))))
+    (if (and (not menu) (not no-resetp))
+	(progn
+	  (reset-device-font-menus device)
+	  (ns-font-families-for-device device t))
+      (let ((scaled (mapcar (function (lambda (x) (if x (aref x 0))))
+			    (aref menu 0)))
+	    (normal (mapcar (function (lambda (x) (if x (aref x 0))))
+			    (aref menu 1))))
+	(sort (unique (nconc scaled normal)) 'string-lessp)))))
 
 (defun ns-font-create-name (fontobj &optional device)
   (let ((family (or (font-family fontobj)
@@ -668,7 +626,7 @@
     ;; Create a font, wow!
     (if (stringp family)
 	(setq family (list family)))
-    (if (or (symbolp style) (numberp style))
+    (if (symbolp style)
 	(setq style (list style)))
     (setq weight (font-higher-weight weight (car-safe (memq :bold style))))
     (if (stringp size)
@@ -697,78 +655,51 @@
       (if done font-name))))
 
 
-;;; Cache building code
-;;;###autoload
-(defun x-font-build-cache (&optional device)
-  (let ((hashtable (make-hash-table :test 'equal :size 15))
-	(fonts (mapcar 'x-font-create-object
-		       (x-list-fonts "-*-*-*-*-*-*-*-*-*-*-*-*-*-*")))
-	(plist nil)
-	(cur nil))
-    (while fonts
-      (setq cur (car fonts)
-	    fonts (cdr fonts)
-	    plist (cl-gethash (car (font-family cur)) hashtable))
-      (if (not (memq (font-weight cur) (plist-get plist 'weights)))
-	  (setq plist (plist-put plist 'weights (cons (font-weight cur)
-						      (plist-get plist 'weights)))))
-      (if (not (member (font-size cur) (plist-get plist 'sizes)))
-	  (setq plist (plist-put plist 'sizes (cons (font-size cur)
-						    (plist-get plist 'sizes)))))
-      (if (and (font-oblique-p cur)
-	       (not (memq 'oblique (plist-get plist 'styles))))
-	  (setq plist (plist-put plist 'styles (cons 'oblique (plist-get plist 'styles)))))
-      (if (and (font-italic-p cur)
-	       (not (memq 'italic (plist-get plist 'styles))))
-	  (setq plist (plist-put plist 'styles (cons 'italic (plist-get plist 'styles)))))
-      (cl-puthash (car (font-family cur)) plist hashtable))
-    hashtable))
-
-
 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
 ;;; Now overwrite the original copy of set-face-font with our own copy that
 ;;; can deal with either syntax.
 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
-;;; ###autoload
 (defun font-set-face-font (&optional face font &rest args)
-  (cond
-   ((and (vectorp font) (= (length font) 12))
-    (let ((font-name (font-create-name font)))
-      (set-face-property face 'font-specification font)
-      (cond
-       ((null font-name)		; No matching font!
-	nil)
-       ((listp font-name)		; For TTYs
-	(let (cur)
-	  (while font-name
-	    (setq cur (car font-name)
-		  font-name (cdr font-name))
-	    (apply 'set-face-property face (car cur) (cdr cur) args))))
-       (font-running-xemacs
-	(apply 'set-face-font face font-name args)
-	(apply 'set-face-underline-p face (font-underline-p font) args)
-	(if (and (or (font-smallcaps-p font) (font-bigcaps-p font))
-		 (fboundp 'set-face-display-table))
-	    (apply 'set-face-display-table
-		   face font-caps-display-table args))
-	(apply 'set-face-property face 'strikethru (or
-						    (font-linethrough-p font)
-						    (font-strikethru-p font))
-	       args))
-       (t
-	(condition-case nil
-	    (apply 'set-face-font face font-name args)
-	  (error
-	   (let ((args (car-safe args)))
-	     (and (or (font-bold-p font)
-		      (memq (font-weight font) '(:bold :demi-bold)))
-		  (make-face-bold face args t))
-	     (and (font-italic-p font) (make-face-italic face args t)))))
-	(apply 'set-face-underline-p face (font-underline-p font) args)))))
-   (t
-    ;; Let the original set-face-font signal any errors
-    (set-face-property face 'font-specification nil)
-    (apply 'set-face-font face font args))))
+  (if (interactive-p)
+      (call-interactively 'font-original-set-face-font)
+    (cond
+     ((and (vectorp font) (= (length font) 12))
+      (let ((font-name (font-create-name font)))
+	(set-face-property face 'font-specification font)
+	(cond
+	 ((null font-name)		; No matching font!
+	  nil)
+	 ((listp font-name)		; For TTYs
+	  (let (cur)
+	    (while font-name
+	      (setq cur (car font-name)
+		    font-name (cdr font-name))
+	      (apply 'set-face-property face (car cur) (cdr cur) args))))
+	 (font-running-xemacs
+	  (apply 'font-original-set-face-font face font-name args)
+	  (apply 'set-face-underline-p face (font-underline-p font) args)
+	  (if (and (or (font-smallcaps-p font) (font-bigcaps-p font))
+		   (fboundp 'set-face-display-table))
+	      (apply 'set-face-display-table
+		     face font-caps-display-table args))
+	  (apply 'set-face-property face 'strikethru (or
+						      (font-linethrough-p font)
+						      (font-strikethru-p font))
+		 args))
+	 (t
+	  (condition-case nil
+	      (apply 'font-original-set-face-font face font-name args)
+	    (error
+	     (let ((args (car-safe args)))
+	       (and (or (font-bold-p font)
+			(memq (font-weight font) '(:bold :demi-bold)))
+		    (make-face-bold face args t))
+	       (and (font-italic-p font) (make-face-italic face args t)))))
+	  (apply 'set-face-underline-p face (font-underline-p font) args)))))
+     (t
+      ;; Let the original set-face-font signal any errors
+      (set-face-property face 'font-specification nil)
+      (apply 'font-original-set-face-font face font args)))))
 
 
 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
@@ -974,9 +905,9 @@
   (list r g b) ))
 
 (defsubst font-rgb-color-p (obj)
-  (or (and (vectorp obj)
-	   (= (length obj) 4)
-	   (eq (aref obj 0) 'rgb))))
+  (and (vectorp obj)
+       (= (length obj) 4)
+       (eq (aref obj 0) 'rgb)))
 
 (defsubst font-rgb-color-red (obj) (aref obj 1))
 (defsubst font-rgb-color-green (obj) (aref obj 2))
@@ -991,14 +922,14 @@
 The variable x-library-search-path is use to locate the rgb.txt file."
   (let ((case-fold-search t))
     (cond
-     ((and (font-rgb-color-p color) (floatp (aref color 1)))
+     ((font-rgb-color-p color)
+      (list (* 65535 (font-rgb-color-red color))
+	    (* 65535 (font-rgb-color-green color))
+	    (* 65535 (font-rgb-color-blue color))))
+     ((and (vectorp color) (= 3 (length color)) (floatp (aref color 0)))
       (list (* 65535 (aref color 0))
  	    (* 65535 (aref color 1))
  	    (* 65535 (aref color 2))))
-     ((font-rgb-color-p color)
-      (list (font-rgb-color-red color)
-	    (font-rgb-color-green color)
-	    (font-rgb-color-blue color)))
      ((and (vectorp color) (= 3 (length color)))
       (list (aref color 0) (aref color 1) (aref color 2)))
      ((and (listp color) (= 3 (length color)) (floatp (car color)))
@@ -1068,44 +999,55 @@
 (defun font-normalize-color (color &optional device)
   "Return an RGB tuple, given any form of input.  If an error occurs, black
 is returned."
-  (case (device-type device)
-   ((x pm)
-    (apply 'format "#%02x%02x%02x" (font-color-rgb-components color)))
-   (win32
-    (let* ((rgb (font-color-rgb-components color))
-	   (color (apply 'format "#%02x%02x%02x" rgb)))
-      (win32-define-rgb-color (nth 0 rgb) (nth 1 rgb) (nth 2 rgb) color)
-      color))
-   (tty
+  (cond
+   ((eq (device-type device) 'x)
+    (apply 'format "#%04x%04x%04x" (font-color-rgb-components color)))
+   ((eq (device-type device) 'tty)
     (apply 'font-tty-find-closest-color (font-color-rgb-components color)))
-   (ns
+   ((eq (device-type device) 'ns)
     (let ((vals (mapcar (function (lambda (x) (>> x 8)))
 			(font-color-rgb-components color))))
-      (apply 'format "RGB%02x%02x%02xff" vals)))
-   (otherwise
-    color)))
+      (apply 'format "RGB%02x%02x%02ff" vals)))
+   (t "black")))
 
 (defun font-set-face-background (&optional face color &rest args)
   (interactive)
-  (condition-case nil
-      (cond
-       ((or (font-rgb-color-p color)
-	    (string-match "^#[0-9a-fA-F]+$" color))
-	(apply 'set-face-background face
-	       (font-normalize-color color) args))
-       (t
-	(apply 'set-face-background face color args)))
-    (error nil)))
+  (if (interactive-p)
+      (call-interactively 'font-original-set-face-background)
+    (cond
+     ((font-rgb-color-p color)
+      (apply 'font-original-set-face-background face
+	     (font-normalize-color color) args))
+     (t
+      (apply 'font-original-set-face-background face color args)))))
 
 (defun font-set-face-foreground (&optional face color &rest args)
   (interactive)
-  (condition-case nil
-      (cond
-       ((or (font-rgb-color-p color)
-	    (string-match "^#[0-9a-fA-F]+$" color))
-	(apply 'set-face-foreground face (font-normalize-color color) args))
-       (t
-	(apply 'set-face-foreground face color args)))
-    (error nil)))
+  (if (interactive-p)
+      (call-interactively 'font-original-set-face-foreground)
+    (cond
+     ((font-rgb-color-p color)
+      (apply 'font-original-set-face-foreground face
+	     (font-normalize-color color) args))
+     (t
+      (apply 'font-original-set-face-foreground face color args)))))
+
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+;;; Do the actual overwriting of some functions
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+(defmacro font-overwrite-fn (func)
+  (` (let ((our-func (intern (format "font-%s" (, func))))
+	   (new-func (intern (format "font-original-%s" (, func))))
+	   (old-func (and (fboundp (, func)) (symbol-function (, func)))))
+       (if (not (fboundp new-func))
+	   (progn
+	     (if old-func
+		 (fset new-func old-func)
+	       (fset new-func 'ignore))
+	     (fset (, func) our-func))))))
+
+(font-overwrite-fn 'set-face-foreground)
+(font-overwrite-fn 'set-face-background)
+(font-overwrite-fn 'set-face-font)
 
 (provide 'font)