Article View: comp.sys.ti.explorer
Article #278Re: X11M (Monochrome X11 server)
From: James Rice
Date: Mon, 26 Nov 1990 19:58
Date: Mon, 26 Nov 1990 19:58
611 lines
26271 bytes
26271 bytes
>> * Has anyone got the code for the documented(!)
>> function X11:COMPILE-X11-FONT (appendix B of "SLE X
>> Window System Programmer's Reference"), which is said
>> to make a font usable by X11M out of a BDF file. The
>> stuff in jwz's archive just makes a screen font,
>> without the necessary X11 font info.
A quick grep revealed that this function is in
x11:x11m.utilities;font-compiler.lisp
Rice;
;-------------------------------------------------------------------------------
;;; -*- Mode:Common-Lisp; Package:USER; Base:10; Fonts:(CPTFONT CPTFONTB CPTFONTBI) -*-
#|
This program allows one to read in characters from X11 font files and convert
them to Explorer font objects. The font files are located in the directory
tilde:/lagoon.u1/X11-beta.1/fonts/bdf/. This program reads the font
information in a manner similar to the fc program in
tilde:/lagoon.u1/X11-beta.1/fonts/compiler/fc.c.
To run the program, call the function read-font, and pass a pathname for the
font file. The read-font function returns the symbol whose value is the font
object. These symbols are prefixed with `X11-' to distinguish them from
Explorer fonts which may have the same name.
|#
;;; Change history:
;;;
;;; Date Author Description
;;; -------------------------------------------------------------------------------------
;;; 12/06/88 LGO Ensure font name is all caps.
;;; 11/14/88 LGO Get font height and baseline from ascent and descent when FontBoundingBox is bad.
;;; 11/09/88 LGO Get font height and baseline from the FontBoundingBox.
;;; These font attributes cannot be derived from ascent and descent.
;;; 11/08/88 LGO Correctly skip characters with negative encoding
;;; 11/08/88 LGO Correctly left-justify font bitmaps
;;; 11/08/88 LGO Gather font properties correctly.
;;; 11/08/88 LGO Adjust FED:FD-SPACE-WIDTH and FED:FD-BLINKER-WIDTH for fixed width fonts
;;; 10/27/88 TWE Changed the inner data collection loop index start-row to never
;;; start below the index of 0.
;;; 9/14/88 LGO Use Y-RESOLUTION instead of explorer pixel-resolution
;;; when computing character sizes.
;;; 9/13/88 LGO Fix READ-A-LINE to work on unix files
;;; 9/13/88 LGO Add compile-x11-font function which dumps x11-font-info
;;; in the same file as the font.
;;; 9/13/88 LGO Set char-width to x-width instead of bounding-box-width
;;; 9/13/88 LGO Pad the top of char bitmaps to make the baselines line up.
;;; The prefix for font pathnames and font objects is the same.
(DEFCONSTANT X-FONT-OBJECT-PREFIX "X11-")
(DEFCONSTANT GOLDEN-RATIO (/ (1+ (SQRT 5)) 2))
(DEFCONSTANT MAX-ENCODING (EXPT 2 16)
"Largest number of characters in a font that can be supported")
(DEFCONSTANT VERSION-STRING "STARTFONT 2.1")
(DEFCONSTANT X-FONT-OBJECT-PREFIX "X11-")
(DEFPARAMETER LINE-NUMBER 0
"Number of the line read from a font file. Used for error reporting.")
;;; Simpler version of the read-from-string function, which more easily handles
;;; keywords. This version is less general than the read-from-string function,
;;; but sufices here.
(DEFUN READ-FROM-STRING-FIX (STRING &KEY (START 0))
(READ-FROM-STRING STRING T NIL :START START))
;;; The following defparameters are located here instead of being inside of a LET in read-font
;;; because release 2.1 doesn't allow one to put a large number of locals inside of a function.
;;; Data line read from the font file.
(DEFPARAMETER LINE NIL)
;;; Determines the name of the font. This may be a filename, which means
;;; that the font name needs to be extracted.
(DEFPARAMETER FAMILY NIL)
;;; Resolution of the font in the X direction.
(DEFPARAMETER X-RESOLUTION NIL)
;;; Resolution of the font in the Y direction.
(DEFPARAMETER Y-RESOLUTION NIL)
;;; Symbol which is the font's name. Has the X11- prefix.
(DEFPARAMETER FONT-SYMBOL NIL)
;;; The number of glyphs in this font.
(DEFPARAMETER NUMBER-CHARACTERS NIL)
;;; The lowest character in the font.
(DEFPARAMETER LOWEST-ENCODING MOST-POSITIVE-FIXNUM)
;;; The highest character in the font.
(DEFPARAMETER LARGEST-ENCODING 0)
;;; The next 4 deal with 2-D fonts.
(DEFPARAMETER FI.FIRST-ROW MOST-POSITIVE-FIXNUM)
(DEFPARAMETER FI.LAST-ROW 0)
(DEFPARAMETER FI.CH-FIRST MOST-POSITIVE-FIXNUM)
(DEFPARAMETER FI.CH-LAST 0)
(DEFPARAMETER REAL-PROPERTY-COUNTER 0
"Number of properties for this font.")
(DEFPARAMETER PROPERTIES NIL)
;;; Total font height
(defparameter font-height nil)
;;; Font baseline
(defparameter font-baseline nil)
(defparameter font-y nil)
;;; Maximum length of ascenders for the font.
(DEFPARAMETER FONT-ASCENT NIL)
;;; Maximum length of descenders for the font.
(DEFPARAMETER FONT-DESCENT NIL)
;;; Maximums and minimums for components of x-char-info.
(DEFPARAMETER MAX-LEFT-SIDE-BEARING NIL)
(DEFPARAMETER MAX-RIGHT-SIDE-BEARING NIL)
(DEFPARAMETER MAX-CHARACTER-WIDTH NIL)
(DEFPARAMETER MAX-FONT-ASCENT NIL)
(DEFPARAMETER MAX-FONT-DESCENT NIL)
(DEFPARAMETER MIN-LEFT-SIDE-BEARING NIL)
(DEFPARAMETER MIN-RIGHT-SIDE-BEARING NIL)
(DEFPARAMETER MIN-CHARACTER-WIDTH NIL)
(DEFPARAMETER MIN-FONT-ASCENT NIL)
(DEFPARAMETER MIN-FONT-DESCENT NIL)
;;; Default character property for the font.
(DEFPARAMETER DEFAULT-CHARACTER NIL)
(DEFPARAMETER ALL-CHARS-EXIST NIL)
(DEFPARAMETER CONSTANT-METRICS NIL)
;;; Point size for the font.
(DEFPARAMETER POINT-SIZE NIL)
;;; Family name property of the font. Not used for anything yet.
(DEFPARAMETER FAMILY-NAME NIL)
;;; Resolution property of the font. I'm not sure how this differs from
;;; the values of x-resolution and y-resolution, which are supposed to
;;; have the same value (i.e. X resolution = Y resolution).
(DEFPARAMETER RESOLUTION NIL)
;;; Height of the font.
(DEFPARAMETER X-HEIGHT NIL)
;;; Weight property of the font.
(DEFPARAMETER WEIGHT NIL)
;;; Quad width property of the font.
(DEFPARAMETER QUAD-WIDTH NIL)
;;; The FED font descriptor
(defparameter font-desc nil)
(DEFUN READ-FONT (PATHNAME &AUX (x11-metrics (make-array 256)))
"Read an X11 bdf font file and generate Explorer font object.
PATHNAME is the pathname where the .bdf information exists.
X11 font descriptor informations is put on the :X11-FONT-INFO
roperty of the font name symbol."
(WITH-OPEN-FILE (FONT-STREAM PATHNAME :DIRECTION :INPUT)
(SETQ ALL-CHARS-EXIST T
X-HEIGHT NIL
FONT-HEIGHT NIL
FONT-ASCENT NIL
FONT-DESCENT NIL
LARGEST-ENCODING 0;;; Maximum length of ascenders for the font.
LINE-NUMBER 0
LOWEST-ENCODING MOST-POSITIVE-FIXNUM
MAX-CHARACTER-WIDTH 0
MAX-FONT-ASCENT 0
MAX-FONT-DESCENT 0
MAX-LEFT-SIDE-BEARING 0
MAX-RIGHT-SIDE-BEARING 0
MIN-CHARACTER-WIDTH MOST-POSITIVE-FIXNUM
MIN-FONT-ASCENT MOST-POSITIVE-FIXNUM
MIN-FONT-DESCENT MOST-POSITIVE-FIXNUM
MIN-LEFT-SIDE-BEARING MOST-POSITIVE-FIXNUM
MIN-RIGHT-SIDE-BEARING MOST-POSITIVE-FIXNUM
PROPERTIES NIL)
;; The validate-string function compares the first few characters of LINE
;; to those characters in STRING. If they are not the same (case doesn't count)
;; then an error message is generated.
(FLET ((VALIDATE-STRING (STRING &OPTIONAL MESSAGE)
(IF (NOT (STRING-EQUAL (SETQ LINE (READ-A-LINE FONT-STREAM))
STRING
:end1 (LENGTH STRING)))
(FERROR NIL "Missing font ~A on line ~D, got ~A instead."
(OR MESSAGE (STRING-TRIM " " STRING))
LINE-NUMBER LINE)
;;ELSE
(nsubstring LINE (LENGTH STRING)))))
;; Parse the header stuff for the font.
(VALIDATE-STRING VERSION-STRING "file, or incorrect version")
(SETQ FAMILY (VALIDATE-STRING "FONT " "family line"))
;; Form a font name from the family string. The family can be one of
;; several things: a simple string, a simple filename with an
;; extension, or a fully specified pathname with an optional extension.
;; It is assumed that the characters of the filename component of a
;; pathname contain only alphabetic, numeric, - or _ characters.
(SETQ FONT-SYMBOL (INTERN
(CONCATENATE
'SIMPLE-STRING "X11-"
;; make the font name the same as the file name. This
;; makes it much easier to deal with fonts, since
;; X uses the file system to locate fonts.
(string-upcase (PATHNAME-NAME FONT-STREAM)))
'FONTS))
;; Read in the point size, x resolution and y resolution.
(LET ((RESOLUTIONS-STRING (VALIDATE-STRING "SIZE " "size line")))
(MULTIPLE-VALUE-BIND (VALUE X-RESOLUTION-POSITION)
(READ-FROM-STRING-FIX RESOLUTIONS-STRING)
(SETQ POINT-SIZE VALUE)
(MULTIPLE-VALUE-BIND (VALUE Y-RESOLUTION-POSITION)
(READ-FROM-STRING-FIX RESOLUTIONS-STRING :START X-RESOLUTION-POSITION)
(SETQ X-RESOLUTION VALUE
Y-RESOLUTION (READ-FROM-STRING-FIX RESOLUTIONS-STRING
:START Y-RESOLUTION-POSITION))))
(WHEN (NOT (= X-RESOLUTION Y-RESOLUTION))
(FERROR NIL "X and Y resolution must be equal, but are ~D and ~D"
X-RESOLUTION Y-RESOLUTION)))
(let ((BOUNDING-BOX-STRING (VALIDATE-STRING "FONTBOUNDINGBOX ")))
(MULTIPLE-VALUE-BIND (VALUE HEIGHT-POSITION)
(READ-FROM-STRING BOUNDING-BOX-STRING)
value ;; Ignore font bounding-box width
(MULTIPLE-VALUE-BIND (VALUE LEFT-POSITION)
(READ-FROM-STRING-FIX BOUNDING-BOX-STRING :START HEIGHT-POSITION)
(SETQ font-height VALUE)
(MULTIPLE-VALUE-BIND (VALUE BOTTOM-POSITION)
(READ-FROM-STRING-FIX BOUNDING-BOX-STRING :START LEFT-POSITION)
value ;; Ignore font bounding-box X
(SETQ value (READ-FROM-STRING-FIX
BOUNDING-BOX-STRING
:START BOTTOM-POSITION))
(setq font-y (- value))))))
(SETQ REAL-PROPERTY-COUNTER 0)
;; Read in the properties of the font.
(LOOP WITH NUMBER-OF-PROPERTIES = (READ-FROM-STRING (VALIDATE-STRING "STARTPROPERTIES "
"properties"))
FOR PROPERTY-COUNTER FROM 1 BY 1
WHILE (>= NUMBER-OF-PROPERTIES PROPERTY-COUNTER)
FOR LINE = (READ-A-LINE FONT-STREAM)
DO (MULTIPLE-VALUE-BIND (NAME VALUE-INDEX)
(let ((*package* *keyword-package*))
(READ-FROM-STRING LINE))
(LET ((VALUE (READ-FROM-STRING-FIX LINE :START VALUE-INDEX)))
(unless (numberp value)
(setq value (intern (string value) 'keyword)))
(case name ;; These properties are used, and DON'T go on the property list
(:font_ascent (setq font-ascent value))
(:font_descent (setq font-descent value))
(:default_char (setq default-character value))
(otherwise
(setq properties (list* name value properties))
(incf real-property-counter)
(case name ;; These properties are used and DO go on the property list
(:point_size (setq point-size value))
#+comment ;; what is this property anyway??? - LGO
(:x_height (setq x-height value))))))))
(VALIDATE-STRING "ENDPROPERTIES" "terminator for font properties")
(WHEN (OR (NULL FONT-ASCENT) (NULL FONT-DESCENT))
(FERROR NIL "Must have FONT_ASCENT and FONT_DESCENT properties"))
;; We shouldn't have to do this, but some fonts have incorrect fontboundingbox
;; specifications (probably because bdftosnf donesn't use it)
(setq font-height (max font-height (+ font-ascent font-descent))
font-baseline (- font-height (max font-y font-descent)))
(SETQ NUMBER-CHARACTERS (READ-FROM-STRING (VALIDATE-STRING "CHARS " "character count")))
(unless x-height
(setq x-height
(if (and font-ascent font-descent)
(+ font-ascent font-descent)
(ROUND (*
POINT-SIZE
;; Convert points to inches
(/ 1 72.27)
;; Convert inches to pixels
Y-RESOLUTION)))))
(unless FONT-ASCENT
(setq font-ascent
(if font-descent
(- font-height font-descent)
;; Assume that the ascender covers about 80% of a character.
(* FONT-HEIGHT 0.8))))
(setq font-desc
(FED:MAKE-FONT-DESCRIPTOR
:MAKE-ARRAY (:LENGTH (MAX NUMBER-CHARACTERS 256.))
FED:FD-FILL-POINTER (MAX NUMBER-CHARACTERS 256.)
FED:FD-NAME FONT-SYMBOL
FED:FD-SPACE-WIDTH (ROUND (*
;; Convert height to width
(/ POINT-SIZE GOLDEN-RATIO)
;; Convert points to inches
(/ 1 72.27)
;; Convert inches to pixels
Y-RESOLUTION))
FED:FD-LINE-SPACING (+ FONT-ASCENT FONT-DESCENT)
FED:FD-BASELINE FONT-BASELINE
FED:FD-BLINKER-WIDTH (ROUND (*
;; Convert height to width
(/ POINT-SIZE GOLDEN-RATIO)
;; Convert points to inches
(/ 1 72.27)
;; Convert inches to pixels
Y-RESOLUTION))
FED:FD-BLINKER-HEIGHT FONT-HEIGHT))
;; Loop through each character in this font.
(LOOP WITH BOUNDING-BOX-WIDTH = NIL
WITH BOUNDING-BOX-HEIGHT = NIL
WITH BOUNDING-BOX-LEFT = NIL
WITH BOUNDING-BOX-BOTTOM = NIL
FOR CHARACTER-COUNTER FROM 0 BELOW NUMBER-CHARACTERS
;; 1234567890
WHILE (string= (SETQ LINE (READ-A-LINE FONT-STREAM)) "STARTCHAR " :end1 10)
FOR CHARACTER-NAME = (SUBSEQ LINE 10)
FOR LAST-ENCODING = NIL THEN ENCODING
FOR ENCODING = (LET ((ENCODING (VALIDATE-STRING "encoding ")))
(MULTIPLE-VALUE-BIND (VALUE END-POSITION)
(READ-FROM-STRING ENCODING)
(WHEN (AND (NOT (= END-POSITION (LENGTH ENCODING)))
(= VALUE -1))
;; We have two values. Get the second one since the
;; first one looks kind of trashy (I don't know what
;; the real meaning is behind the -1 value).
(SETQ VALUE (READ-FROM-STRING-FIX ENCODING
:START END-POSITION)))
(WHEN (= VALUE -1)
#+comment
(FORMAT T "~%Character ~A with encoding = -1 ignored at line ~D"
CHARACTER-NAME LINE-NUMBER)
(LOOP FOR LINE = (READ-A-LINE FONT-STREAM)
UNTIL (EQUAL LINE "ENDCHAR")))
(WHEN (> VALUE MAX-ENCODING)
(FERROR NIL "Character `~A' has encoding(=~D) ~
which is too large"
CHARACTER-NAME VALUE))
(SETQ LARGEST-ENCODING (MAX VALUE LARGEST-ENCODING))
VALUE))
unless (minusp encoding) do
;; The following three things are unused, but are calculated in
;; the C program, so we do this here in case we need them later.
(let* ((CHARACTER-ROW (LOGAND (ASH ENCODING -8) #xFF))
(CHARACTER-COLUMN (LET ((COLUMN (LOGAND ENCODING #xFF)))
(SETQ FI.FIRST-ROW (MIN FI.FIRST-ROW CHARACTER-ROW)
FI.LAST-ROW (MAX FI.LAST-ROW CHARACTER-ROW)
FI.CH-FIRST (MIN FI.CH-FIRST COLUMN)
FI.CH-LAST (MAX FI.CH-LAST COLUMN))
COLUMN))
(SWIDTH (VALIDATE-STRING "SWIDTH "))
;; X component of width
(X-WIDTH (READ-FROM-STRING (VALIDATE-STRING "DWIDTH ")))
(BOUNDING-BOX-STRING (VALIDATE-STRING "BBX" "bounding box"))
(ATTRIBUTES 0))
swidth character-column ;; not used
;; Decode the components of the bounding box.
(MULTIPLE-VALUE-BIND (VALUE HEIGHT-POSITION)
(READ-FROM-STRING BOUNDING-BOX-STRING)
(SETQ BOUNDING-BOX-WIDTH VALUE)
(MULTIPLE-VALUE-BIND (VALUE LEFT-POSITION)
(READ-FROM-STRING-FIX BOUNDING-BOX-STRING :START HEIGHT-POSITION)
(SETQ BOUNDING-BOX-HEIGHT VALUE)
(MULTIPLE-VALUE-BIND (VALUE BOTTOM-POSITION)
(READ-FROM-STRING-FIX BOUNDING-BOX-STRING :START LEFT-POSITION)
(SETQ BOUNDING-BOX-LEFT VALUE
BOUNDING-BOX-BOTTOM (READ-FROM-STRING-FIX
BOUNDING-BOX-STRING
:START BOTTOM-POSITION)))))
(WHEN (OR (ZEROP BOUNDING-BOX-WIDTH) (ZEROP BOUNDING-BOX-HEIGHT))
;; The character has zero size. Make sure that the left and
;; bottom dimensions don't affect the minimum/maximum
;; calculations.
(SETQ BOUNDING-BOX-WIDTH 0
BOUNDING-BOX-HEIGHT 0
BOUNDING-BOX-LEFT MIN-LEFT-SIDE-BEARING
BOUNDING-BOX-BOTTOM (- MIN-FONT-DESCENT)))
(SETQ LINE (READ-A-LINE FONT-STREAM))
;; 12345678901
(WHEN (STRING-EQUAL (SUBSEQ LINE 0 11) "ATTRIBUTES ")
;; The attributes line is optional.
(SETQ ATTRIBUTES (READ-FROM-STRING-FIX
(CONCATENATE 'SIMPLE-STRING "#\x" LINE)
:START 11))
(SETQ LINE (READ-A-LINE FONT-STREAM)))
(SETQ LOWEST-ENCODING (MIN LOWEST-ENCODING ENCODING))
;; Write information out regarding this character.
(setf (aref x11-metrics encoding)
(X11:MAKE-X-CHAR-INFO
:LEFT-SIDE-BEARING BOUNDING-BOX-LEFT
:RIGHT-SIDE-BEARING (+ BOUNDING-BOX-LEFT BOUNDING-BOX-WIDTH)
:CHARACTER-WIDTH X-WIDTH
:ASCENT (+ BOUNDING-BOX-HEIGHT BOUNDING-BOX-BOTTOM)
:DESCENT (- BOUNDING-BOX-BOTTOM)
:ATTRIBUTES ATTRIBUTES))
(SETQ MAX-LEFT-SIDE-BEARING (MAX MAX-LEFT-SIDE-BEARING BOUNDING-BOX-LEFT)
MAX-RIGHT-SIDE-BEARING (MAX MAX-RIGHT-SIDE-BEARING
(+ BOUNDING-BOX-LEFT BOUNDING-BOX-WIDTH))
MAX-CHARACTER-WIDTH (MAX MAX-CHARACTER-WIDTH X-WIDTH)
MAX-FONT-ASCENT (MAX MAX-FONT-ASCENT
(+ BOUNDING-BOX-HEIGHT BOUNDING-BOX-BOTTOM))
MAX-FONT-DESCENT (MAX MAX-FONT-DESCENT (- BOUNDING-BOX-BOTTOM))
MIN-LEFT-SIDE-BEARING (MIN MIN-LEFT-SIDE-BEARING BOUNDING-BOX-LEFT)
MIN-RIGHT-SIDE-BEARING (MIN MIN-RIGHT-SIDE-BEARING
(+ BOUNDING-BOX-LEFT BOUNDING-BOX-WIDTH))
MIN-CHARACTER-WIDTH (MIN MIN-CHARACTER-WIDTH X-WIDTH)
MIN-FONT-ASCENT (MIN MIN-FONT-ASCENT
(+ BOUNDING-BOX-HEIGHT BOUNDING-BOX-BOTTOM))
MIN-FONT-DESCENT (MIN MIN-FONT-DESCENT (- BOUNDING-BOX-BOTTOM)))
;; Can't use validate-string here because the attributes line
;; is optional.
(WHEN (NOT (STRING-EQUAL LINE "BITMAP"))
(FERROR NIL "Missing font bitmap on line ~D, got ~A instead."
LINE LINE-NUMBER))
;; Loop collecting each row of the character.
(LOOP with start-row = (- font-baseline (+ BOUNDING-BOX-HEIGHT BOUNDING-BOX-BOTTOM))
#+comment
(min (max (- font-ascent (+ BOUNDING-BOX-HEIGHT BOUNDING-BOX-BOTTOM))
0)
(1- font-height)) ; These min/maxes are a kludge... do better someday
WITH CHAR-DESC = (FED:MAKE-CHAR-DESCRIPTOR
:MAKE-ARRAY (:element-type 'BIT
:LENGTH (LIST font-height
BOUNDING-BOX-WIDTH))
FED:CD-CHAR-WIDTH X-WIDTH
FED:CD-CHAR-LEFT-KERN 0)
FOR ROW FROM start-row ;;(+ start-row fudge)
FOR RAW-DATA = (READ-A-LINE FONT-STREAM)
WHILE (NOT (EQUAL RAW-DATA "ENDCHAR"))
;; Loop through all of the bits of this row.
;; The data comes in left justified, so we need
;; to shift it to make it right justified.
DO (LOOP with DATA = (parse-integer raw-data :radix 16.)
WITH SHIFTED-DATA = (ASH DATA
(- BOUNDING-BOX-WIDTH
(* 4 (LENGTH RAW-DATA))))
FOR COLUMN FROM (1- BOUNDING-BOX-WIDTH) DOWNTO 0
DO (PROGN
(SETF (AREF CHAR-DESC ROW COLUMN) (LOGAND SHIFTED-DATA 1))
(SETQ SHIFTED-DATA (ASH SHIFTED-DATA -1))))
FINALLY (SETF (AREF FONT-DESC ENCODING) CHAR-DESC))))
(progn ;; WHEN OUTPUT-PATHNAME
(SETQ CONSTANT-METRICS
(AND (= MIN-LEFT-SIDE-BEARING MAX-LEFT-SIDE-BEARING)
(= MIN-RIGHT-SIDE-BEARING MAX-RIGHT-SIDE-BEARING)
(= MIN-CHARACTER-WIDTH MAX-CHARACTER-WIDTH)
(= MIN-FONT-ASCENT MAX-FONT-ASCENT)
(= MIN-FONT-DESCENT MAX-FONT-DESCENT)))
;; Ensure correct space and blinker width for constant-metric fonts
(when constant-metrics
(setf (FED:FD-SPACE-WIDTH font-desc) max-character-width
(FED:FD-BLINKER-WIDTH font-desc) max-character-width))
;; Adjust the size of the font to only have those characters it defines.
(SETF (FILL-POINTER FONT-DESC) (1+ LARGEST-ENCODING))
(ADJUST-ARRAY FONT-DESC (1+ LARGEST-ENCODING))
(FED:FONT-NAME-SET-FONT-AND-DESCRIPTOR
FONT-SYMBOL
FONT-DESC)
;; Canonicalize metrics vector
(unless constant-metrics
(loop with metrics = (make-array (1+ (- largest-encoding lowest-encoding)))
for i from lowest-encoding to largest-encoding
for j upfrom 0
do (setf (aref metrics j) (aref x11-metrics i))
finally (setq x11-metrics metrics)))
;; Calculate all-chars-exists
(setq all-chars-exist t)
(dotimes (i (1+ (- largest-encoding lowest-encoding)))
(unless (aref x11-metrics i)
(return (setq all-chars-exist nil))))
;; Setup the font-info-record
(setf (get font-symbol :x11-font-info)
(X11:MAKE-FONT-INFO-RECORD
:VERSION VERSION-STRING
:ALL-EXIST ALL-CHARS-EXIST
:DRAW-DIRECTION X11:LEFT-TO-RIGHT-FONT
:NO-OVERLAP 0 ; HUH?
:CONSTANT-METRICS (if constant-metrics 1 0)
:TERMINAL-FONT (IF (AND CONSTANT-METRICS
(ZEROP MAX-LEFT-SIDE-BEARING))
1 0)
:LINEAR T
:FIRST-COL LOWEST-ENCODING
:LAST-COL LARGEST-ENCODING
:FIRST-ROW 0
:LAST-ROW 0
:N-PROPS REAL-PROPERTY-COUNTER
:PROPERTIES PROPERTIES
:LEN-STRINGS 0 ; WHAT IS THIS?
;; Try a bunch of default characters, starting with `?' and ending with
;; the first character in the font.
:CH-DEFAULT (LOOP FOR CHAR IN `(#\? #\! #\@ #\# #\$ #\% #\& ,LOWEST-ENCODING)
WHEN (PLUSP (AREF (W:FONT-CHARS-EXIST-TABLE
(symbol-value FONT-SYMBOL))
(CHAR-INT CHAR)))
RETURN (CHAR-INT CHAR))
:FONT-DESCENT FONT-DESCENT
:FONT-ASCENT FONT-ASCENT
:MIN-BOUNDS (X11:MAKE-X-CHAR-INFO
:LEFT-SIDE-BEARING MIN-LEFT-SIDE-BEARING
:RIGHT-SIDE-BEARING MIN-RIGHT-SIDE-BEARING
:CHARACTER-WIDTH MIN-CHARACTER-WIDTH
:ASCENT MIN-FONT-ASCENT
:DESCENT MIN-FONT-DESCENT
:ATTRIBUTES 0)
:MAX-BOUNDS (X11:MAKE-X-CHAR-INFO
:LEFT-SIDE-BEARING MAX-LEFT-SIDE-BEARING
:RIGHT-SIDE-BEARING MAX-RIGHT-SIDE-BEARING
:CHARACTER-WIDTH MAX-CHARACTER-WIDTH
:ASCENT MAX-FONT-ASCENT
:DESCENT MAX-FONT-DESCENT
:ATTRIBUTES 0)
:PIX-DEPTH 1
:GLYPH-SETS NUMBER-CHARACTERS
:VERSION2 VERSION-STRING
;; Metrics NIL when constant
:metrics (and (not constant-metrics) x11-metrics))))))
FONT-SYMBOL)
(DEFUN READ-A-LINE (STREAM)
"Reads a line from a font file."
;; Loop through each line read, skipping over special case lines.
(LOOP FOR STRING = (MAKE-ARRAY 20 :ELEMENT-TYPE :STRING-CHAR :FILL-POINTER 0)
with char do
;; Skip newline and formfeed
(loop while (or (CHAR= (setq char (read-char stream))
'#.(INT-CHAR (LOGAND (CHAR-INT #\NEWLINE) #O177)))
(CHAR= CHAR #\NEWLINE)
(char= char #\linefeed)))
;; Read into string until a newline or formfeed
(LOOP DO (VECTOR-PUSH-EXTEND CHAR STRING)
(setq CHAR (READ-CHAR STREAM))
UNTIL (or (CHAR= CHAR '#.(INT-CHAR (LOGAND (CHAR-INT #\NEWLINE) #O177)))
(CHAR= CHAR #\NEWLINE)
(char= char #\linefeed)))
;; Skip over comment, empty and dot lines.
WHILE (OR (STRING-EQUAL (SUBSEQ STRING 0 7) "COMMENT") ; For apl-s25 font
(ZEROP (LENGTH STRING)) ; For cartoon font in crturz.bdf
(STRING-EQUAL STRING (STRING #\CENTER-DOT))) ; For cursor font
FINALLY (RETURN STRING)))
(defun compile-x11-font (bdf-pathname &optional (xld-pathname ""))
(let ((font-symbol (read-font bdf-pathname)))
(setq bdf-pathname (parse-namestring bdf-pathname))
(compiler:DUMP-FORMS-TO-FILE
(merge-pathnames (string-downcase
(CONCATENATE 'SIMPLE-STRING X-FONT-OBJECT-PREFIX
(PATHNAME-NAME bdf-pathname)
"." (string (si::local-binary-file-type))))
xld-pathname)
;; Take font-symbol from the file name, to allow aliasing
`((setq ,font-symbol ',(symbol-value font-symbol))
(setf (get ',font-symbol :x11-font-info) ',(get font-symbol :x11-font-info))
(let ((symbol (and si:fdefine-file-pathname
(intern (string-upcase (pathname-name si:fdefine-file-pathname)) 'fonts))))
(when symbol
(setf (symbol-value symbol) ,font-symbol)
(setf (get symbol :x11-font-info) (get ',font-symbol :x11-font-info)))))
`(:FONT-SYMBOL ,FONT-SYMBOL :PACKAGE :USER))))
(defun update-all-x-fonts (from to)
(let ((files (directory (make-pathname :defaults from :type "BDF" :name :wild))))
(dolist (file files)
(format t "~%~a " (pathname-name file))
;; Skip 16b fonts (not handled yet)
(unless (member (pathname-name file) '("K14")
:test #'string-equal)
(princ
(compile-x11-font file to))))))
#|
(update-all-x-fonts "stroke:/u1/XV11R3/fonts/bdf/" "tan:/u1/oren/fonts/")
;; Andrew fonts
(let ((fudge -1)) ;; The .bdf files in this directory are incorrect, so compensate
(update-all-x-fonts "tan:/u1/oren/andyfont/" "tan:/u1/oren/fonts/"))
(update-all-x-fonts "tan:/u1/oren/andysrc/" "tan:/u1/oren/fonts/")
(update-all-x-fonts "stroke:/u1/XV11R3/fonts/bdf/75dpi/" "tan:/u1/oren/fonts/")
(update-all-x-fonts "stroke:/u1/XV11R3/fonts/bdf/misc/" "tan:/u1/oren/fonts/")
|#
#|
(update-all-x-fonts "x11m:fonts.100dpi;" "x11m:fonts.100dpi;")
(update-all-x-fonts "x11m:fonts.75dpi;" "x11m:fonts.75dpi;")
(update-all-x-fonts "x11m:fonts.misc;" "x11m:fonts.misc;")
(update-all-x-fonts "x11m:fonts.rel2;" "x11m:fonts.rel2;")
|#
Technical Details
Message-ID:
<2868638304-5851514@KSL-EXP-35>Path:
arc1-ca.pugleaf.net!utzoo!utgpu!news-server.csri.toronto.edu!cs.utexas.edu!usc!ucsd!ucbvax!SUMEX-AIM.STANFORD.EDU!RiceReferences:
<Bjorn.Victor@docs.uu.se>Show Full Headers
Complete Article Headers
Path: arc1-ca.pugleaf.net!utzoo!utgpu!news-server.csri.toronto.edu!cs.utexas.edu!usc!ucsd!ucbvax!SUMEX-AIM.STANFORD.EDU!Rice From: Rice@SUMEX-AIM.STANFORD.EDU (James Rice) Newsgroups: comp.sys.ti.explorer Subject: Re: X11M (Monochrome X11 server) Message-ID: <2868638304-5851514@KSL-EXP-35> Date: 26 Nov 90 19:58:24 GMT References: <Bjorn.Victor@docs.uu.se> Sender: daemon@ucbvax.BERKELEY.EDU Distribution: inet Organization: The Internet Lines: 611