Inspectcode scrolls, has the correct window title (#2222)
* Inspectcode scrolls, has the correct window title * Add promptwindo so M-f search strings are locally visible * Fix FILETYPE for LLDISPLAY * MEDLEYFONTFORMAT More efficient store and read of numeric Interlisp arrays
This commit is contained in:
914
sources/MEDLEYFONTFORMAT
Normal file
914
sources/MEDLEYFONTFORMAT
Normal file
@@ -0,0 +1,914 @@
|
||||
(DEFINE-FILE-INFO PACKAGE "INTERLISP" READTABLE "INTERLISP" BASE 10)
|
||||
|
||||
(FILECREATED "27-Jul-2025 22:22:23" {WMEDLEY}<sources>MEDLEYFONTFORMAT.;218 57699
|
||||
|
||||
:EDIT-BY rmk
|
||||
|
||||
:CHANGES-TO (FNS MEDLEYFONT.READ.ITEM)
|
||||
|
||||
:PREVIOUS-DATE "24-Jul-2025 22:07:35" {WMEDLEY}<sources>MEDLEYFONTFORMAT.;217)
|
||||
|
||||
|
||||
(PRETTYCOMPRINT MEDLEYFONTFORMATCOMS)
|
||||
|
||||
(RPAQQ MEDLEYFONTFORMATCOMS
|
||||
[
|
||||
(* ;; "Eventually, MEDLEYFONT should be a package")
|
||||
|
||||
|
||||
(* ;; "Main public entries")
|
||||
|
||||
(FNS MEDLEYFONT.WRITE.FONT MEDLEYFONT.GETCHARSET MEDLEYFONT.CHARSET? MEDLEYFONT.GETFILEPROP
|
||||
MEDLEYFONT.FILEP)
|
||||
|
||||
(* ;; "Reading")
|
||||
|
||||
(FNS MEDLEYFONT.READ.FONT MEDLEYFONT.READ.CHARSET MEDLEYFONT.READ.ITEM MEDLEYFONT.PEEK.ITEM
|
||||
MEDLEYFONT.READ.FONTPROPS MEDLEYFONT.READ.VERIFIEDFONT)
|
||||
|
||||
(* ;; "Writing")
|
||||
|
||||
(FNS MEDLEYFONT.WRITE.CHARSET MEDLEYFONT.WRITE.ITEM MEDLEYFONT.WRITE.FONTPROPS
|
||||
MEDLEYFONT.WRITE.HEADER)
|
||||
(FNS MEDLEYFONT.FILENAME)
|
||||
(ADDVARS (DISPLAYFONTEXTENSIONS MEDLEYDISPLAYFONT)
|
||||
(DISPLAYCHARSETFNS (MEDLEYFONT MEDLEYFONT.FILEP MEDLEYFONT.GETCHARSET))
|
||||
(INTERPRESSFONTEXTENSIONS MEDLEYINTERPRESSFONT))
|
||||
(DECLARE%: EVAL@COMPILE DONTCOPY (CONSTANTS (PRINTDATA 0)
|
||||
(SMALLPDATA 1)
|
||||
(BITMAPDATA 2)
|
||||
(WORDBLOCKDATA 3)
|
||||
(CLARRAYDATA 4)
|
||||
(FIXPDATA 5)
|
||||
(ILPOINTERARRAY 6)
|
||||
(ILNUMBERARRAY 11)
|
||||
(HPRINTDATA 7)
|
||||
(ALISTDATA 8)
|
||||
(PLISTDATA 9)
|
||||
(LISTDATA 10])
|
||||
|
||||
|
||||
|
||||
(* ;; "Eventually, MEDLEYFONT should be a package")
|
||||
|
||||
|
||||
|
||||
|
||||
(* ;; "Main public entries")
|
||||
|
||||
(DEFINEQ
|
||||
|
||||
(MEDLEYFONT.WRITE.FONT
|
||||
[LAMBDA (FONT FILE CHARSETNOS OTHERFONTPROPS NOINDIRECTS) (* ; "Edited 15-Jul-2025 16:43 by rmk")
|
||||
(* ; "Edited 9-Jul-2025 09:32 by rmk")
|
||||
(* ; "Edited 19-Jun-2025 10:59 by rmk")
|
||||
(* ; "Edited 9-Jun-2025 12:17 by rmk")
|
||||
(* ; "Edited 25-May-2025 20:48 by rmk")
|
||||
(* ; "Edited 23-May-2025 14:59 by rmk")
|
||||
(* ; "Edited 22-May-2025 09:58 by rmk")
|
||||
(* ; "Edited 16-May-2025 20:17 by rmk")
|
||||
(* ; "Edited 14-May-2025 17:45 by rmk")
|
||||
(SETQ FONT (FONTCREATE FONT))
|
||||
(CL:UNLESS FILE
|
||||
(SETQ FILE (MEDLEYFONT.FILENAME FONT CHARSETNOS)))
|
||||
(SETQ CHARSETNOS (SORT (MKLIST CHARSETNOS)))
|
||||
(CL:WITH-OPEN-FILE (STREAM FILE :DIRECTION :OUTPUT :IF-EXISTS :NEW-VERSION)
|
||||
(MEDLEYFONT.WRITE.HEADER STREAM OTHERFONTPROPS)
|
||||
(LET ((CHARSETLOCS (CL:MAKE-ARRAY 256 :INITIAL-ELEMENT 0))
|
||||
(FONTCHARENCODING (FONTPROP FONT 'CHARENCODING))
|
||||
(*READTABLE* (FIND-READTABLE "INTERLISP"))
|
||||
CSVECTORPTRLOC CSVECTORLOC FILECHARSETS)
|
||||
|
||||
(* ;; "Figure out the actual non empty/sluggish charsets that will be wrtitten.")
|
||||
|
||||
(SETQ FILECHARSETS (for CSNO CSINFO from 0 to \MAXCHARSET
|
||||
when (OR (NULL CHARSETNOS)
|
||||
(MEMB CSNO CHARSETNOS))
|
||||
when (SETQ CSINFO (\XGETCHARSETINFO FONT CSNO))
|
||||
unless (fetch (CHARSETINFO CSSLUGP) of CSINFO) collect CSNO))
|
||||
(CL:UNLESS FILECHARSETS (ERROR "No character sets to write" FONT))
|
||||
|
||||
(* ;; "Right after the header, leave 4 bytes for the pointer to the charset dispatch vector. If writing a single charset, we store the negative of the byte location so we can still easily skip the font properties without writing the whole vector. The byte in front of the single charset holds its number.")
|
||||
|
||||
(* ;; "")
|
||||
|
||||
(SETQ CSVECTORPTRLOC (GETFILEPTR STREAM)) (* ;
|
||||
"Ptr is before fontproperties, vector is after")
|
||||
(\FIXPOUT STREAM 0)
|
||||
(MEDLEYFONT.WRITE.FONTPROPS STREAM FONT)
|
||||
(if (CDR FILECHARSETS)
|
||||
then (PRINTOUT STREAM "CHARSET LOCATIONS" T)
|
||||
(* ;
|
||||
"Allocate the vector space if multiple")
|
||||
(SETQ CSVECTORLOC (GETFILEPTR STREAM))
|
||||
(for I from 0 to \MAXCHARSET do (\FIXPOUT STREAM 0))
|
||||
(TERPRI STREAM)
|
||||
(for CSNO in FILECHARSETS do
|
||||
|
||||
(* ;;
|
||||
"LOC remains zero for missing charsets, slug properties are determined by font-level properties.")
|
||||
|
||||
(CL:SETF (CL:SVREF CHARSETLOCS CSNO)
|
||||
(GETFILEPTR STREAM))
|
||||
(MEDLEYFONT.WRITE.CHARSET FONT CSNO STREAM
|
||||
NOINDIRECTS))
|
||||
(SETFILEPTR STREAM CSVECTORLOC)
|
||||
(for CSNO from 0 to \MAXCHARSET do (\FIXPOUT STREAM (CL:SVREF CHARSETLOCS
|
||||
CSNO)))
|
||||
else
|
||||
(* ;; "Only one. The %"vector%" is the charset byte immediately before the charset, the sign bit tells the tale.")
|
||||
|
||||
(SETQ CSVECTORLOC (IMINUS (GETFILEPTR STREAM)))
|
||||
(BOUT STREAM (CAR FILECHARSETS))
|
||||
(MEDLEYFONT.WRITE.CHARSET FONT (CAR FILECHARSETS)
|
||||
STREAM NOINDIRECTS))
|
||||
(SETFILEPTR STREAM CSVECTORPTRLOC)
|
||||
(\FIXPOUT STREAM CSVECTORLOC) (* ;
|
||||
"Pointer to the charset dispatch vector--or negative of actual location for a singleton")
|
||||
(FULLNAME STREAM])
|
||||
|
||||
(MEDLEYFONT.GETCHARSET
|
||||
[LAMBDA (STREAM CHARSET) (* ; "Edited 15-Jul-2025 17:09 by rmk")
|
||||
(* ; "Edited 9-Jul-2025 15:45 by rmk")
|
||||
(* ; "Edited 14-May-2025 17:46 by rmk")
|
||||
|
||||
(* ;; "If open, assume its a medleyfont stream, that the initial Me etc. has been checked, and we are positioned after the header information")
|
||||
|
||||
(CL:UNLESS (<= 0 CHARSET \MAXCHARSET)
|
||||
(\ILLEGAL.ARG CHARSET))
|
||||
(RESETLST
|
||||
(CL:UNLESS (\GETSTREAM STREAM 'INPUT T)
|
||||
[RESETSAVE (SETQ STREAM (OPENSTREAM STREAM 'INPUT))
|
||||
`(PROGN (CLOSEF? OLDVALUE]
|
||||
(CL:UNLESS (MEDLEYFONT.FILEP STREAM) (* ;
|
||||
"Checks and positions, if reopening.")
|
||||
(ERROR "NOT A MEDLEYFONT FILE" (FULLNAME STREAM))))
|
||||
(LET ((CSVECTORLOC (\FIXPIN STREAM))
|
||||
CSLOC)
|
||||
|
||||
(* ;; "We know now that this file has information about the requested charset, including NIL entries for empty/slugglish ones in the middle of populated ones. A file that would have contain a single empty/sluggish charset cannot be created--the caller would recognize the case of a missing file and provide either NIL or a slug-vector.")
|
||||
|
||||
(CL:WHEN (if (ILESSP CSVECTORLOC 0)
|
||||
then
|
||||
(* ;; "File contains only one charset. Is it the one we want? If the intended charset is empty/sluggish, the file would not have been constructed and we wouldn't be here.")
|
||||
|
||||
(SETFILEPTR STREAM (IMINUS CSVECTORLOC))
|
||||
(EQ CHARSET (BIN STREAM))
|
||||
else
|
||||
(* ;; "The vector-entry points to the one we want. Is it there?")
|
||||
|
||||
(SETFILEPTR STREAM (IPLUS CSVECTORLOC (UNFOLD CHARSET BYTESPERCELL)))
|
||||
(CL:UNLESS (EQ 0 (SETQ CSLOC (\FIXPIN STREAM)))
|
||||
(SETFILEPTR STREAM CSLOC)))
|
||||
(MEDLEYFONT.READ.CHARSET STREAM CHARSET))))])
|
||||
|
||||
(MEDLEYFONT.CHARSET?
|
||||
[LAMBDA (FILE CHARSET) (* ; "Edited 15-Jul-2025 15:21 by rmk")
|
||||
(* ; "Edited 25-May-2025 20:53 by rmk")
|
||||
(* ; "Edited 21-May-2025 11:35 by rmk")
|
||||
(* ; "Edited 17-May-2025 11:29 by rmk")
|
||||
(* ; "Edited 14-May-2025 17:46 by rmk")
|
||||
|
||||
(* ;; "If CHARSET, returns CHARSET if FILE contains a non-slug entry for CHARSET. If not CHARSET, returns the list of non-slug charsets in FILE.")
|
||||
|
||||
(CL:WITH-OPEN-FILE (STREAM FILE :DIRECTION :INPUT)
|
||||
(CL:UNLESS (MEDLEYFONT.FILEP STREAM)
|
||||
(ERROR "Not a MEDLEYFONT file" FILE))
|
||||
(LET ((CSVECTORLOC (\FIXPIN STREAM)))
|
||||
(CL:WHEN (if (ILESSP CSVECTORLOC 0)
|
||||
then
|
||||
(* ;; "File contains only one charse, is it the one we want? ")
|
||||
|
||||
(SETFILEPTR STREAM (IMINUS CSVECTORLOC))
|
||||
(EQ CHARSET (BIN STREAM))
|
||||
else (SETFILEPTR STREAM (IPLUS CSVECTORLOC (UNFOLD CHARSET BYTESPERCELL)))
|
||||
(NEQ 0 (\FIXPIN STREAM)))
|
||||
CHARSET])
|
||||
|
||||
(MEDLEYFONT.GETFILEPROP
|
||||
[LAMBDA (FILE PROP) (* ; "Edited 15-Jul-2025 20:21 by rmk")
|
||||
(* ; "Edited 10-Jul-2025 17:50 by rmk")
|
||||
(* ; "Edited 25-May-2025 20:53 by rmk")
|
||||
(* ; "Edited 21-May-2025 11:36 by rmk")
|
||||
(* ; "Edited 17-May-2025 19:07 by rmk")
|
||||
(* ; "Edited 14-May-2025 17:46 by rmk")
|
||||
(CL:UNLESS (OR (LITATOM FILE)
|
||||
(STRINGP FILE))
|
||||
[SETQ FILE (CAR (APPLY (FUNCTION FONTFILES)
|
||||
(FONTPROP (FONTCREATE FILE)
|
||||
'SPEC])
|
||||
(CL:WITH-OPEN-FILE (STREAM FILE :DIRECTION :INPUT)
|
||||
(LET (HEADERPROPS CSVECTORLOC)
|
||||
(CL:UNLESS (SETQ HEADERPROPS (MEDLEYFONT.FILEP STREAM))
|
||||
(ERROR "Not a MEDLEYFONT file" (FULLNAME STREAM)))
|
||||
(SETQ CSVECTORLOC (\FIXPIN STREAM))
|
||||
(SELECTQ PROP
|
||||
(OTHERPROPS (CDDR HEADERPROPS))
|
||||
(DATE (CADR HEADERPROPS))
|
||||
(FONTPROPS (MEDLEYFONT.READ.FONTPROPS STREAM))
|
||||
(CHARSETS (if (ILESSP CSVECTORLOC 0)
|
||||
then
|
||||
(* ;; "File contains only one charset ")
|
||||
|
||||
(SETFILEPTR STREAM (IMINUS CSVECTORLOC))
|
||||
(CONS (BIN STREAM))
|
||||
else (SETFILEPTR STREAM CSVECTORLOC)
|
||||
(for CS from 0 to \MAXCHARSET unless (EQ 0 (\FIXPIN STREAM))
|
||||
collect CS)))
|
||||
(ERROR "Unknown MEDLEYFONT property"])
|
||||
|
||||
(MEDLEYFONT.FILEP
|
||||
[LAMBDA (FILE) (* ; "Edited 6-Jul-2025 11:44 by rmk")
|
||||
(* ; "Edited 10-Jun-2025 18:19 by rmk")
|
||||
(* ; "Edited 8-Jun-2025 22:55 by rmk")
|
||||
(* ; "Edited 25-May-2025 20:54 by rmk")
|
||||
(* ; "Edited 21-May-2025 11:37 by rmk")
|
||||
(* ; "Edited 16-May-2025 21:58 by rmk")
|
||||
(* ; "Edited 14-May-2025 17:00 by rmk")
|
||||
|
||||
(* ;; "Me in first 2 bytes distinguishes MEDLEYFONT format from others. This may be called after the first 2 bytes have been read to verify the %"Me%", if not we skip over it here.")
|
||||
|
||||
(* ;; "For a valid file, returns (fullname date)")
|
||||
|
||||
(* ;; "If FILE is an open stream, it is left open. Otherwise it is opened and closed.")
|
||||
|
||||
(RESETLST
|
||||
[LET (STREAM VERSION DATE)
|
||||
[if (\GETSTREAM FILE 'INPUT T)
|
||||
then (SETQ STREAM FILE)
|
||||
else (RESETSAVE (SETQ STREAM (OPENSTREAM FILE 'INPUT))
|
||||
`(PROGN (CLOSEF? OLDVALUE]
|
||||
(CL:UNLESS (ZEROP (GETFILEPTR STREAM))
|
||||
(SETFILEPTR STREAM 0))
|
||||
(CL:WHEN (for C in (CONSTANT (CHCON "Medley font")) always (EQ C (READCCODE STREAM)))
|
||||
[CAR (NLSETQ [CL:WHEN (EQ 0 (SETQ VERSION (MEDLEYFONT.READ.ITEM STREAM 'VERSION]
|
||||
`(,(FULLNAME STREAM)
|
||||
,(MEDLEYFONT.READ.ITEM STREAM 'DATE)
|
||||
,VERSION
|
||||
,@(MEDLEYFONT.READ.ITEM STREAM 'OTHERFONTPROPS])])])
|
||||
)
|
||||
|
||||
|
||||
|
||||
(* ;; "Reading")
|
||||
|
||||
(DEFINEQ
|
||||
|
||||
(MEDLEYFONT.READ.FONT
|
||||
[LAMBDA (FILE CHARSETNOS FONT) (* ; "Edited 15-Jul-2025 20:20 by rmk")
|
||||
(* ; "Edited 9-Jul-2025 00:06 by rmk")
|
||||
(* ; "Edited 6-Jul-2025 11:45 by rmk")
|
||||
(CL:UNLESS FILE (SETQ FILE FONT))
|
||||
(CL:WHEN (OR (type? FONTDESCRIPTOR FILE)
|
||||
(LISTP FILE))
|
||||
(SETQ FILE (MEDLEYFONT.FILENAME FILE)))
|
||||
(SETQ CHARSETNOS (SORT (MKLIST CHARSETNOS)))
|
||||
(CL:WITH-OPEN-FILE (STREAM FILE :DIRECTION :INPUT)
|
||||
(CL:UNLESS (MEDLEYFONT.FILEP STREAM)
|
||||
(ERROR "NOT A MEDLEYFONT FILE" (FULLNAME STREAM)))
|
||||
(LET ((*READTABLE* (FIND-READTABLE "INTERLISP"))
|
||||
FONTCHARSETVECTOR CSVECTORLOC NOTFOUND SINGLECS)
|
||||
(SETQ CSVECTORLOC (\FIXPIN STREAM)) (* ;
|
||||
"Byte location of the charset dispatch vector")
|
||||
|
||||
(* ;; "We know now that this file has information about all requested charsets, including NIL entries for empty/slugglish ones in the middle of populated ones. A file that would have contain a single empty/sluggish charset cannot be created--the caller would recognize the case of a missing file and provide either NIL or a slug-vector.")
|
||||
|
||||
(SETQ FONT (MEDLEYFONT.READ.VERIFIEDFONT STREAM FONT))
|
||||
(SETQ FONTCHARSETVECTOR (fetch (FONTDESCRIPTOR FONTCHARSETVECTOR) of FONT))
|
||||
(CL:UNLESS (EQ CSVECTORLOC 0) (* ; "Not empty")
|
||||
[if (ILESSP CSVECTORLOC 0)
|
||||
then
|
||||
(* ;;
|
||||
"File contains only one charset and it's the one we want. Its CHARSET number is in the first byte.")
|
||||
|
||||
(* ;; "If the intended charset is empty/sluggish, the file would not have been constructed and we wouldn't be here.")
|
||||
|
||||
(SETFILEPTR STREAM (IMINUS CSVECTORLOC))
|
||||
(SETQ SINGLECS (BIN STREAM))
|
||||
(CL:WHEN CHARSETNOS
|
||||
(CL:UNLESS (AND (EQ SINGLECS (CAR CHARSETNOS))
|
||||
(NULL (CDR CHARSETNOS)))
|
||||
(ERROR (CONCAT FILE
|
||||
" does not contain information for charsets ÿ4ÿ | ||||