Mercurial > hg > xemacs-beta
diff lisp/w3/font.el @ 80:1ce6082ce73f r20-0b90
Import from CVS: tag r20-0b90
author | cvs |
---|---|
date | Mon, 13 Aug 2007 09:06:37 +0200 |
parents | 131b0175ea99 |
children | 6a378aca36af |
line wrap: on
line diff
--- a/lisp/w3/font.el Mon Aug 13 09:05:44 2007 +0200 +++ b/lisp/w3/font.el Mon Aug 13 09:06:37 2007 +0200 @@ -1,13 +1,14 @@ ;;; font.el --- New font model ;; Author: wmperry -;; Created: 1996/08/11 16:40:36 -;; Version: 1.8 +;; Created: 1997/01/03 16:43:49 +;; Version: 1.22 ;; Keywords: faces ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;; Copyright (c) 1995, 1996 by William M. Perry (wmperry@cs.indiana.edu) +;;; Copyright (c) 1996 Free Software Foundation, Inc. ;;; -;;; This file is not part of GNU Emacs, but the same permissions apply. +;;; This file is part of GNU Emacs. ;;; ;;; 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 @@ -20,15 +21,16 @@ ;;; 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, 675 Mass Ave, Cambridge, MA 02139, USA. +;;; 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. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;; The emacsen compatibility package - load it up before anything else ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; (eval-and-compile - (load-library "w3-sysdp") + (require 'w3-sysdp) (require 'cl)) (require 'disp-table) @@ -142,10 +144,54 @@ (defkeyword :registry "Keyword specifying the registry of a FONTOBJ.") (defkeyword :encoding "Keyword specifying the encoding of a FONTOBJ.") +(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)) + +(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)) + (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." @@ -156,17 +202,18 @@ (, (intern (format "font-%s-mask" attr))))) t nil)) - (defun (, (intern (format "font-set-%s-p" attr))) (fontobj val) + (defun (, (intern (format "set-font-%s-p" attr))) (fontobj val) (, (format "Set whether FONTOBJ will be renderd in `%s' or not." 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))))))) + (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)))))))) )))) (let ((mask 0)) @@ -205,6 +252,25 @@ ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;; Utility functions ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +(defsubst set-font-style-by-keywords (fontobj styles) + (make-local-variable 'font-func) + (declare (special font-func)) + (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)))) + +(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)) @@ -228,8 +294,8 @@ w2)))) (defun font-spatial-to-canonical (spec &optional device) - "Convert SPEC (in inches, millimeters, points, or picas) into pixels" - ;; 1 in = 25.4 mm = 72 pt = 6 pa + "Convert SPEC (in inches, millimeters, points, or picas) into points" + ;; 1 in = 6 pa = 25.4 mm = 72 pt (if (numberp spec) spec (let ((num nil) @@ -260,28 +326,19 @@ (setq num (string-to-number spec)) (cond ((member type '("pixel" "px" "pix")) - (setq retval num - num nil)) + (setq retval (* num (/ pix-width mm-width) (/ 25.4 72.0)))) ((member type '("point" "pt")) - (setq retval (+ (* (/ pix-width mm-width) - (/ 25.4 72.0) - num)))) + (setq retval num)) ((member type '("pica" "pa")) - (setq retval (* (/ pix-width mm-width) - (/ 25.4 6.0) - num))) + (setq retval (* num 12.0))) ((member type '("inch" "in")) - (setq retval (* (/ pix-width mm-width) - (/ 25.4 1.0) - num))) + (setq retval (* num 72.0))) ((string= type "mm") - (setq retval (* (/ pix-width mm-width) - num))) + (setq retval (* num (/ 72.0 25.4)))) ((string= type "cm") - (setq retval (* (/ pix-width mm-width) - 10 - num))) - (t (setq retval num)) + (setq retval (* num 10 (/ 72.0 25.4)))) + (t + (setq retval num)) ) retval))) @@ -291,57 +348,21 @@ ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; (defun make-font (&rest args) (vector :family - (if (stringp (nth 1 (memq :family args))) - (list (nth 1 (memq :family args))) - (nth 1 (memq :family args))) + (if (stringp (plist-get args :family)) + (list (plist-get args :family)) + (plist-get args :family)) :weight - (nth 1 (memq :weight args)) + (plist-get args :weight) :style - (if (numberp (nth 1 (memq :style args))) - (nth 1 (memq :style args)) + (if (numberp (plist-get args :style)) + (plist-get args :style) 0) :size - (nth 1 (memq :size args)) + (plist-get args :size) :registry - (nth 1 (memq :registry args)) + (plist-get args :registry) :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)) + (plist-get args :encoding))) (defun font-create-name (fontobj &optional device) (let* ((type (device-type device)) @@ -400,7 +421,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)) @@ -463,28 +484,28 @@ ) (if (not (string-match x-font-regexp-foundry-and-family fontname)) nil - (setq family (list (match-string 1 fontname)))) + (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 (format "%dpt" (/ (string-to-int ptsize) 10)))) + (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 adstyle)))) + (setq family (append family (list (downcase adstyle))))) (setq retval (make-font :family family :weight weight :size size)) - (font-set-bold-p retval (eq :bold weight)) + (set-font-bold-p retval (eq :bold weight)) (cond ((null slant) nil) ((member slant '("i" "I")) - (font-set-italic-p retval t)) + (set-font-italic-p retval t)) ((member slant '("o" "O")) - (font-set-oblique-p retval t))) + (set-font-oblique-p retval t))) retval))) (defun x-font-families-for-device (&optional device no-resetp) @@ -513,8 +534,11 @@ (font-truename (make-font-specifier (face-font-name 'default device))) - (cdr-safe (assq 'font (frame-parameters 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)))) + (defun font-default-object-for-device (&optional device) (let ((font (font-default-font-for-device device))) (or (cdr-safe @@ -543,7 +567,8 @@ (font-registry fontobj) (font-encoding fontobj))) (not (font-bold-p fontobj)) - (not (font-italic-p fontobj))) + (not (font-italic-p fontobj)) + (not (font-oblique-p fontobj))) (face-font 'default) (or device (setq device (selected-device))) (let ((family (or (font-family fontobj) @@ -584,16 +609,22 @@ (if (= ?- (aref cur-family (1- x))) (aset cur-family (1- x) ? )) (setq x (1- x)))) - (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)))) + ;; 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)))))) (if done font-name))))) @@ -604,16 +635,17 @@ ;; 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))) - (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))))) + (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)))))) (defun ns-font-create-name (fontobj &optional device) (let ((family (or (font-family fontobj) @@ -626,7 +658,7 @@ ;; Create a font, wow! (if (stringp family) (setq family (list family))) - (if (symbolp style) + (if (or (symbolp style) (numberp style)) (setq style (list style))) (setq weight (font-higher-weight weight (car-safe (memq :bold style)))) (if (stringp size) @@ -655,6 +687,33 @@ (if done font-name)))) +;;; Cache building code +(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. @@ -922,14 +981,14 @@ The variable x-library-search-path is use to locate the rgb.txt file." (let ((case-fold-search t)) (cond - ((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))) + ((and (font-rgb-color-p color) (floatp (aref color 1))) (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))) @@ -1001,13 +1060,13 @@ is returned." (cond ((eq (device-type device) 'x) - (apply 'format "#%04x%04x%04x" (font-color-rgb-components color))) + (apply 'format "#%02x%02x%02x" (font-color-rgb-components color))) ((eq (device-type device) 'tty) (apply 'font-tty-find-closest-color (font-color-rgb-components color))) ((eq (device-type device) 'ns) (let ((vals (mapcar (function (lambda (x) (>> x 8))) (font-color-rgb-components color)))) - (apply 'format "RGB%02x%02x%02ff" vals))) + (apply 'format "RGB%02x%02x%02xff" vals))) (t "black"))) (defun font-set-face-background (&optional face color &rest args)