aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorRichard M. Stallman1997-12-25 18:33:52 +0000
committerRichard M. Stallman1997-12-25 18:33:52 +0000
commit857686a6d3eb18738ede4b7152332f7ef2d98e5b (patch)
treef75f23cafe0e2194c9f1114943ef11f08b9d1581
parent99783bde1243b07e22ff4a9ab03dd984ace15c2c (diff)
downloademacs-857686a6d3eb18738ede4b7152332f7ef2d98e5b.tar.gz
emacs-857686a6d3eb18738ede4b7152332f7ef2d98e5b.zip
Some comment, doc and bug fixes.
(ps-print-version): New version number (3.05.3) and doc fix. (ps-output-string-prim, ps-begin-job, ps-control-character) (ps-plot-region): Bug fix. (ps-print-control-characters): New custom var. (ps-string-escape-codes, ps-string-control-codes): New var. (ps-color-device, ps-font-lock-face-attributes, ps-eval-switch) (ps-flatten-list, ps-flatten-list-1): New fn. (ps-setup): Update current setup. (ps-begin-file): Adjust PostScript header file. (ps-plot, ps-face-attribute-list): Little programming improvement. (ps-print-prologue-1): Replace NumberOfZebra by ZebraHeight. (ps-print-without-faces, ps-print-with-faces): Little reprogramming. (ps-plot-with-face): Get color only on color screen device. (ps-build-reference-face-lists): Handle obsolete font-lock-face-attributes. (ps-print-ensure-fontified): Little programming setting. (ps-generate-postscript-with-faces): Adjust initializations, get color only on color screen device. (ps-generate): Replace (if A B) by (and A B). (ps-do-despool): Dynamic evaluation for ps-lpr-switches, Replace (if A B) by (and A B). (color-instance-rgb-components, ps-color-values): Replace pixel-components by color-instance-rgb-components. (ps-xemacs-face-kind-p): Replace face-font by face-font-instance, replace x-font-properties by font-instance-properties.
-rw-r--r--lisp/ps-print.el366
1 files changed, 272 insertions, 94 deletions
diff --git a/lisp/ps-print.el b/lisp/ps-print.el
index 1f777073f20..4af13e94238 100644
--- a/lisp/ps-print.el
+++ b/lisp/ps-print.el
@@ -4,13 +4,14 @@
4 4
5;; Author: Jim Thompson (was <thompson@wg2.waii.com>) 5;; Author: Jim Thompson (was <thompson@wg2.waii.com>)
6;; Author: Jacques Duthen <duthen@cegelec-red.fr> 6;; Author: Jacques Duthen <duthen@cegelec-red.fr>
7;; Author: Vinicius Jose Latorre <vinicius@cpqd.com.br>
7;; Maintainer: Vinicius Jose Latorre <vinicius@cpqd.com.br> 8;; Maintainer: Vinicius Jose Latorre <vinicius@cpqd.com.br>
8;; Keywords: print, PostScript 9;; Keywords: print, PostScript
9;; Time-stamp: <97/08/28 22:35:25 vinicius> 10;; Time-stamp: <97/11/21 22:12:47 vinicius>
10;; Version: 3.05.2 11;; Version: 3.05.3
11 12
12(defconst ps-print-version "3.05.2" 13(defconst ps-print-version "3.05.3"
13 "ps-print.el, v 3.05.2 <97/08/28 vinicius> 14 "ps-print.el, v 3.05.3 <97/11/21 vinicius>
14 15
15Vinicius's last change version -- this file may have been edited as part of 16Vinicius's last change version -- this file may have been edited as part of
16Emacs without changes to the version number. When reporting bugs, 17Emacs without changes to the version number. When reporting bugs,
@@ -362,6 +363,30 @@ Please send all bug fixes and enhancements to
362;; for your printer. 363;; for your printer.
363;; 364;;
364;; 365;;
366;; Control And 8-bit Characters
367;; ----------------------------
368;;
369;; The variable `ps-print-control-characters' specifies whether you want to see
370;; a printable form for control and 8-bit characters, that is, instead of
371;; sending, for example, a ^D (\005) to printer, it is sent the string "^D".
372;;
373;; Valid values for `ps-print-control-characters' are:
374;;
375;; '8-bit printable form for control and 8-bit characters
376;; (characters from \000 to \037 and \177 to \377).
377;; 'control-8-bit printable form for control and *control* 8-bit characters
378;; (characters from \000 to \037 and \177 to \237).
379;; 'control printable form for control character
380;; (characters from \000 to \037 and \177).
381;; nil raw character (no printable form).
382;;
383;; Any other value is treated as nil.
384;;
385;; The default is 'control-8-bit.
386;;
387;; Characters TAB, NEWLINE and FORMFEED are always treated by ps-print engine.
388;;
389;;
365;; Line Number 390;; Line Number
366;; ----------- 391;; -----------
367;; 392;;
@@ -497,15 +522,16 @@ Please send all bug fixes and enhancements to
497;; always right. For example, you might want to map colors into faces 522;; always right. For example, you might want to map colors into faces
498;; so that blue faces print in bold, and red faces in italic. 523;; so that blue faces print in bold, and red faces in italic.
499;; 524;;
500;; It is possible to force ps-print to consider specific faces bold or 525;; It is possible to force ps-print to consider specific faces bold,
501;; italic, no matter what font they are displayed in, by setting the 526;; italic or underline, no matter what font they are displayed in, by setting
502;; variables `ps-bold-faces' and `ps-italic-faces'. These variables 527;; the variables `ps-bold-faces', `ps-italic-faces' and `ps-underlined-faces'.
503;; contain lists of faces that ps-print should consider bold or 528;; These variables contain lists of faces that ps-print should consider bold,
504;; italic; to set them, put code like the following into your .emacs 529;; italic or underline; to set them, put code like the following into your
505;; file: 530;; .emacs file:
506;; 531;;
507;; (setq ps-bold-faces '(my-blue-face)) 532;; (setq ps-bold-faces '(my-blue-face))
508;; (setq ps-italic-faces '(my-red-face)) 533;; (setq ps-italic-faces '(my-red-face))
534;; (setq ps-underlined-faces '(my-green-face))
509;; 535;;
510;; Faces like bold-italic that are both bold and italic should go in 536;; Faces like bold-italic that are both bold and italic should go in
511;; *both* lists. 537;; *both* lists.
@@ -519,7 +545,9 @@ Please send all bug fixes and enhancements to
519;; get out of sync, if a face changes, or if new faces are added. To 545;; get out of sync, if a face changes, or if new faces are added. To
520;; get the lists back in sync, you can set the variable 546;; get the lists back in sync, you can set the variable
521;; `ps-build-face-reference' to t, and the lists will be rebuilt the 547;; `ps-build-face-reference' to t, and the lists will be rebuilt the
522;; next time ps-print is invoked. 548;; next time ps-print is invoked. If you need that the lists always be
549;; rebuilt when ps-print is invoked, set the variable
550;; `ps-always-build-face-reference' to t.
523;; 551;;
524;; 552;;
525;; How Ps-Print Deals With Color 553;; How Ps-Print Deals With Color
@@ -649,7 +677,7 @@ Please send all bug fixes and enhancements to
649;; New since version 2.8 677;; New since version 2.8
650;; --------------------- 678;; ---------------------
651;; 679;;
652;; [vinicius] 970809 Vinicius Jose Latorre <vinicius@cpqd.br> 680;; [vinicius] 971121 Vinicius Jose Latorre <vinicius@cpqd.com.br>
653;; 681;;
654;; Handle control characters. 682;; Handle control characters.
655;; Face remapping. 683;; Face remapping.
@@ -678,12 +706,12 @@ Please send all bug fixes and enhancements to
678;; Automatic font-attribute detection doesn't work well, especially 706;; Automatic font-attribute detection doesn't work well, especially
679;; with hilit19 and older versions of get-create-face. Users having 707;; with hilit19 and older versions of get-create-face. Users having
680;; problems with auto-font detection should use the lists 708;; problems with auto-font detection should use the lists
681;; `ps-italic-faces' and `ps-bold-faces' and/or turn off automatic 709;; `ps-italic-faces', `ps-bold-faces' and `ps-underlined-faces' and/or
682;; detection by setting `ps-auto-font-detect' to nil. 710;; turn off automatic detection by setting `ps-auto-font-detect' to nil.
683;; 711;;
684;; Automatic font-attribute detection doesn't work with XEmacs 19.12 712;; Automatic font-attribute detection doesn't work with XEmacs 19.12
685;; in tty mode; use the lists `ps-italic-faces' and `ps-bold-faces' 713;; in tty mode; use the lists `ps-italic-faces', `ps-bold-faces' and
686;; instead. 714;; `ps-underlined-faces' instead.
687;; 715;;
688;; Still too slow; could use some hand-optimization. 716;; Still too slow; could use some hand-optimization.
689;; 717;;
@@ -713,6 +741,9 @@ Please send all bug fixes and enhancements to
713;; 741;;
714;; Acknowledgements 742;; Acknowledgements
715;; ---------------- 743;; ----------------
744;; Thanks to Jacques Duthen <duthen@cegelec-red.fr> (Jack) for the 3.4 version
745;; I started from. [vinicius]
746;;
716;; Thanks to Jim Thompson <?@?> for the 2.8 version I started from. 747;; Thanks to Jim Thompson <?@?> for the 2.8 version I started from.
717;; [jack] 748;; [jack]
718;; 749;;
@@ -846,6 +877,7 @@ see `ps-paper-type'."
846 (number :tag "Height"))) 877 (number :tag "Height")))
847 :group 'ps-print) 878 :group 'ps-print)
848 879
880;;;###autoload
849(defcustom ps-paper-type 'letter 881(defcustom ps-paper-type 'letter
850 "*Specifies the size of paper to format for. 882 "*Specifies the size of paper to format for.
851Should be one of the paper types defined in `ps-page-dimensions-database', for 883Should be one of the paper types defined in `ps-page-dimensions-database', for
@@ -863,6 +895,20 @@ example `letter', `legal' or `a4'."
863 :type 'boolean 895 :type 'boolean
864 :group 'ps-print) 896 :group 'ps-print)
865 897
898(defcustom ps-print-control-characters 'control-8-bit
899 "*Specifies the printable form for control and 8-bit characters.
900Valid values are:
901 '8-bit printable form for control and 8-bit characters
902 (characters from \000 to \037 and \177 to \377).
903 'control-8-bit printable form for control and *control* 8-bit characters
904 (characters from \000 to \037 and \177 to \237).
905 'control printable form for control character
906 (characters from \000 to \037 and \177).
907 nil raw character (no printable form).
908Any other value is treated as nil."
909 :type '(choice (const 8-bit) (const control-8-bit) (const control) (const nil))
910 :group 'ps-print)
911
866(defcustom ps-number-of-columns (if ps-landscape-mode 2 1) 912(defcustom ps-number-of-columns (if ps-landscape-mode 2 1)
867 "*Specifies the number of columns" 913 "*Specifies the number of columns"
868 :type 'number 914 :type 'number
@@ -1182,7 +1228,8 @@ when generating PostScript."
1182 1228
1183;; Printing color requires x-color-values. 1229;; Printing color requires x-color-values.
1184(defcustom ps-print-color-p (or (fboundp 'x-color-values) ; Emacs 1230(defcustom ps-print-color-p (or (fboundp 'x-color-values) ; Emacs
1185 (fboundp 'pixel-components)) ; XEmacs 1231 (fboundp 'color-instance-rgb-components))
1232 ; XEmacs
1186 "*If non-nil, print the buffer's text in color." 1233 "*If non-nil, print the buffer's text in color."
1187 :type 'boolean 1234 :type 'boolean
1188 :group 'ps-print-color) 1235 :group 'ps-print-color)
@@ -1451,6 +1498,8 @@ The table depends on the current ps-print setup."
1451 ps-zebra-stripe-height %s 1498 ps-zebra-stripe-height %s
1452 ps-line-number %s 1499 ps-line-number %s
1453 1500
1501 ps-print-control-characters %s
1502
1454 ps-print-background-image %s 1503 ps-print-background-image %s
1455 1504
1456 ps-print-background-text %s 1505 ps-print-background-text %s
@@ -1483,6 +1532,7 @@ The table depends on the current ps-print setup."
1483 ps-zebra-stripes 1532 ps-zebra-stripes
1484 ps-zebra-stripe-height 1533 ps-zebra-stripe-height
1485 ps-line-number 1534 ps-line-number
1535 ps-print-control-characters
1486 ps-print-background-image 1536 ps-print-background-image
1487 ps-print-background-text 1537 ps-print-background-text
1488 ps-left-margin 1538 ps-left-margin
@@ -1519,6 +1569,15 @@ The table depends on the current ps-print setup."
1519 (require 'faces)) ; face-font, face-underline-p, 1569 (require 'faces)) ; face-font, face-underline-p,
1520 ; x-font-regexp 1570 ; x-font-regexp
1521 1571
1572;; Return t if the device (which can be changed during an emacs session)
1573;; can handle colors.
1574;; This is function is not yet implemented for GNU emacs.
1575(defun ps-color-device ()
1576 (if (and (eq ps-print-emacs-type 'xemacs)
1577 (>= emacs-minor-version 12))
1578 (eq (device-class) 'color)
1579 t))
1580
1522(require 'time-stamp) 1581(require 'time-stamp)
1523 1582
1524(defvar ps-font nil 1583(defvar ps-font nil
@@ -1864,7 +1923,7 @@ StandardEncoding 46 82 getinterval aload pop
1864/printZebra { 1923/printZebra {
1865 gsave 1924 gsave
1866 0.985 setgray 1925 0.985 setgray
1867 /double-zebra NumberOfZebra NumberOfZebra add def 1926 /double-zebra ZebraHeight ZebraHeight add def
1868 /yiter double-zebra LineHeight mul neg def 1927 /yiter double-zebra LineHeight mul neg def
1869 /xiter PrintWidth InterColumn add def 1928 /xiter PrintWidth InterColumn add def
1870 NumberOfColumns {LinesPerColumn doColumnZebra xiter 0 rmoveto}repeat 1929 NumberOfColumns {LinesPerColumn doColumnZebra xiter 0 rmoveto}repeat
@@ -1874,9 +1933,9 @@ StandardEncoding 46 82 getinterval aload pop
1874% stack: lines-per-column |- -- 1933% stack: lines-per-column |- --
1875/doColumnZebra { 1934/doColumnZebra {
1876 gsave 1935 gsave
1877 dup double-zebra idiv {NumberOfZebra doZebra 0 yiter rmoveto}repeat 1936 dup double-zebra idiv {ZebraHeight doZebra 0 yiter rmoveto}repeat
1878 double-zebra mod 1937 double-zebra mod
1879 dup 0 le {pop}{dup NumberOfZebra gt {pop NumberOfZebra}if doZebra}ifelse 1938 dup 0 le {pop}{dup ZebraHeight gt {pop ZebraHeight}if doZebra}ifelse
1880 grestore 1939 grestore
1881} def 1940} def
1882 1941
@@ -2173,6 +2232,8 @@ StandardEncoding 46 82 getinterval aload pop
2173(defvar ps-page-count 0) 2232(defvar ps-page-count 0)
2174(defvar ps-showline-count 1) 2233(defvar ps-showline-count 1)
2175 2234
2235(defvar ps-control-or-escape-regexp nil)
2236
2176(defvar ps-background-pages nil) 2237(defvar ps-background-pages nil)
2177(defvar ps-background-all-pages nil) 2238(defvar ps-background-all-pages nil)
2178(defvar ps-background-text-count 0) 2239(defvar ps-background-text-count 0)
@@ -2350,12 +2411,50 @@ If EXTENSION is any other symbol, it is ignored."
2350 2411
2351 2412
2352;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 2413;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
2414;; Adapted from font-lock:
2415;; Originally face attributes were specified via `font-lock-face-attributes'.
2416;; Users then changed the default face attributes by setting that variable.
2417;; However, we try and be back-compatible and respect its value if set except
2418;; for faces where M-x customize has been used to save changes for the face.
2419
2420(defun ps-font-lock-face-attributes ()
2421 (and (boundp 'font-lock-mode) (symbol-value 'font-lock-mode)
2422 (boundp 'font-lock-face-attributes)
2423 (let ((face-attributes font-lock-face-attributes))
2424 (while face-attributes
2425 (let* ((face-attribute (pop face-attributes))
2426 (face (car face-attribute)))
2427 ;; Rustle up a `defface' SPEC from a
2428 ;; `font-lock-face-attributes' entry.
2429 (unless (get face 'saved-face)
2430 (let ((foreground (nth 1 face-attribute))
2431 (background (nth 2 face-attribute))
2432 (bold-p (nth 3 face-attribute))
2433 (italic-p (nth 4 face-attribute))
2434 (underline-p (nth 5 face-attribute))
2435 face-spec)
2436 (when foreground
2437 (setq face-spec (cons ':foreground
2438 (cons foreground face-spec))))
2439 (when background
2440 (setq face-spec (cons ':background
2441 (cons background face-spec))))
2442 (when bold-p
2443 (setq face-spec (append '(:bold t) face-spec)))
2444 (when italic-p
2445 (setq face-spec (append '(:italic t) face-spec)))
2446 (when underline-p
2447 (setq face-spec (append '(:underline t) face-spec)))
2448 (custom-declare-face face (list (list t face-spec)) nil)
2449 )))))))
2450
2451
2452;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
2353;; Internal functions and variables 2453;; Internal functions and variables
2354 2454
2355 2455
2356(defun ps-print-without-faces (from to &optional filename region-p) 2456(defun ps-print-without-faces (from to &optional filename region-p)
2357 (ps-printing-region region-p) 2457 (ps-spool-without-faces from to region-p)
2358 (ps-generate (current-buffer) from to 'ps-generate-postscript)
2359 (ps-do-despool filename)) 2458 (ps-do-despool filename))
2360 2459
2361 2460
@@ -2365,8 +2464,7 @@ If EXTENSION is any other symbol, it is ignored."
2365 2464
2366 2465
2367(defun ps-print-with-faces (from to &optional filename region-p) 2466(defun ps-print-with-faces (from to &optional filename region-p)
2368 (ps-printing-region region-p) 2467 (ps-spool-with-faces from to region-p)
2369 (ps-generate (current-buffer) from to 'ps-generate-postscript-with-faces)
2370 (ps-do-despool filename)) 2468 (ps-do-despool filename))
2371 2469
2372 2470
@@ -2377,8 +2475,9 @@ If EXTENSION is any other symbol, it is ignored."
2377 2475
2378(defsubst ps-count-lines (from to) 2476(defsubst ps-count-lines (from to)
2379 (+ (count-lines from to) 2477 (+ (count-lines from to)
2380 (save-excursion (goto-char to) 2478 (save-excursion
2381 (if (= (current-column) 0) 1 0)))) 2479 (goto-char to)
2480 (if (= (current-column) 0) 1 0))))
2382 2481
2383 2482
2384(defvar ps-printing-region nil 2483(defvar ps-printing-region nil
@@ -2636,19 +2735,47 @@ page-height == bm + print-height + tm - ho - hh
2636 2735
2637;; The following functions implement a simple list-buffering scheme so 2736;; The following functions implement a simple list-buffering scheme so
2638;; that ps-print doesn't have to repeatedly switch between buffers 2737;; that ps-print doesn't have to repeatedly switch between buffers
2639;; while spooling. The functions ps-output and ps-output-string build 2738;; while spooling. The functions `ps-output' and `ps-output-string' build
2640;; up the lists; the function ps-flush-output takes the lists and 2739;; up the lists; the function `ps-flush-output' takes the lists and
2641;; insert its contents into the spool buffer (*PostScript*). 2740;; insert its contents into the spool buffer (*PostScript*).
2642 2741
2742(defvar ps-string-escape-codes
2743 (let ((table (make-vector 256 nil))
2744 (char ?\000))
2745 ;; control characters
2746 (while (<= char ?\037)
2747 (aset table char (format "\\%03o" char))
2748 (setq char (1+ char)))
2749 ;; printable characters
2750 (while (< char ?\177)
2751 (aset table char (format "%c" char))
2752 (setq char (1+ char)))
2753 ;; DEL and 8-bit characters
2754 (while (<= char ?\377)
2755 (aset table char (format "\\%o" char))
2756 (setq char (1+ char)))
2757 ;; Override ASCII formatting characters with named escape code:
2758 (aset table ?\n "\\n") ; [NL] linefeed
2759 (aset table ?\r "\\r") ; [CR] carriage return
2760 (aset table ?\t "\\t") ; [HT] horizontal tab
2761 (aset table ?\b "\\b") ; [BS] backspace
2762 (aset table ?\f "\\f") ; [NP] form feed
2763 ;; Escape PostScript escape and string delimiter characters:
2764 (aset table ?\\ "\\\\")
2765 (aset table ?\( "\\(")
2766 (aset table ?\) "\\)")
2767 table)
2768 "Vector used to map characters to PostScript string escape codes.")
2769
2643(defun ps-output-string-prim (string) 2770(defun ps-output-string-prim (string)
2644 (insert "(") ;insert start-string delimiter 2771 (insert "(") ;insert start-string delimiter
2645 (save-excursion ;insert string 2772 (save-excursion ;insert string
2646 (insert string)) 2773 (insert string))
2647 ;; Find and quote special characters as necessary for PS 2774 ;; Find and quote special characters as necessary for PS
2648 (while (re-search-forward "[()\\]" nil t) 2775 (while (re-search-forward "[\000-\037\177-\377()\\]" nil t)
2649 (save-excursion 2776 (let ((special (preceding-char)))
2650 (forward-char -1) 2777 (delete-char -1)
2651 (insert "\\"))) 2778 (insert (aref ps-string-escape-codes special))))
2652 (goto-char (point-max)) 2779 (goto-char (point-max))
2653 (insert ")")) ;insert end-string delimiter 2780 (insert ")")) ;insert end-string delimiter
2654 2781
@@ -2870,7 +2997,8 @@ page-height == bm + print-height + tm - ho - hh
2870 "%%Title: " (buffer-name) ; Take job name from name of 2997 "%%Title: " (buffer-name) ; Take job name from name of
2871 ; first buffer printed 2998 ; first buffer printed
2872 "\n%%Creator: " (user-full-name) 2999 "\n%%Creator: " (user-full-name)
2873 "\n%%CreationDate: " 3000 " (using ps-print v" ps-print-version
3001 ")\n%%CreationDate: "
2874 (time-stamp-hh:mm:ss) " " (time-stamp-mon-dd-yyyy) 3002 (time-stamp-hh:mm:ss) " " (time-stamp-mon-dd-yyyy)
2875 "\n%%Orientation: " 3003 "\n%%Orientation: "
2876 (if ps-landscape-mode "Landscape" "Portrait") 3004 (if ps-landscape-mode "Landscape" "Portrait")
@@ -2914,7 +3042,7 @@ page-height == bm + print-height + tm - ho - hh
2914 3042
2915 (ps-output-boolean "Zebra" ps-zebra-stripes) 3043 (ps-output-boolean "Zebra" ps-zebra-stripes)
2916 (ps-output-boolean "PrintLineNumber" ps-line-number) 3044 (ps-output-boolean "PrintLineNumber" ps-line-number)
2917 (ps-output (format "/NumberOfZebra %d def\n" ps-zebra-stripe-height) 3045 (ps-output (format "/ZebraHeight %d def\n" ps-zebra-stripe-height)
2918 (format "/Lines %d def\n" 3046 (format "/Lines %d def\n"
2919 (if ps-printing-region 3047 (if ps-printing-region
2920 (cdr ps-printing-region) 3048 (cdr ps-printing-region)
@@ -2973,7 +3101,12 @@ page-height == bm + print-height + tm - ho - hh
2973 (and (buffer-modified-p) " (unsaved)"))))) 3101 (and (buffer-modified-p) " (unsaved)")))))
2974 3102
2975(defun ps-begin-job () 3103(defun ps-begin-job ()
2976 (setq ps-page-count 0)) 3104 (setq ps-page-count 0
3105 ps-control-or-escape-regexp
3106 (cond ((eq ps-print-control-characters '8-bit) "[\000-\037\177-\377]")
3107 ((eq ps-print-control-characters 'control-8-bit) "[\000-\037\177-\237]")
3108 ((eq ps-print-control-characters 'control) "[\000-\037\177]")
3109 (t "[\t\n\f]"))))
2977 3110
2978(defun ps-end-file () 3111(defun ps-end-file ()
2979 (ps-output "\nEndDoc\n\n%%Trailer\n%%Pages: " 3112 (ps-output "\nEndDoc\n\n%%Trailer\n%%Pages: "
@@ -3076,7 +3209,7 @@ EndDSCPage\n"))
3076 (let* ((q-todo (- (point-max) (point-min))) 3209 (let* ((q-todo (- (point-max) (point-min)))
3077 (q-done (- (point) (point-min))) 3210 (q-done (- (point) (point-min)))
3078 (chunkfrac (/ q-todo 8)) 3211 (chunkfrac (/ q-todo 8))
3079 (chunksize (if (> chunkfrac 1000) 1000 chunkfrac))) 3212 (chunksize (min chunkfrac 1000)))
3080 (if (> (- q-done ps-razchunk) chunksize) 3213 (if (> (- q-done ps-razchunk) chunksize)
3081 (progn 3214 (progn
3082 (setq ps-razchunk q-done) 3215 (setq ps-razchunk q-done)
@@ -3135,44 +3268,55 @@ EndDSCPage\n"))
3135 ;; ...break the region up into chunks separated by tabs, linefeeds, 3268 ;; ...break the region up into chunks separated by tabs, linefeeds,
3136 ;; pagefeeds, control characters, and plot each chunk. 3269 ;; pagefeeds, control characters, and plot each chunk.
3137 (while (< from to) 3270 (while (< from to)
3138 (if (re-search-forward "[\000-\037\177-\377]" to t) 3271 (if (re-search-forward ps-control-or-escape-regexp to t)
3139 ;; region with some control characters 3272 ;; region with some control characters
3140 (let ((match (char-after (match-beginning 0)))) 3273 (let ((match (char-after (match-beginning 0))))
3141 (if (= match ?\t) ; tab 3274 (ps-plot 'ps-basic-plot-string from (1- (point)) bg-color)
3142 (let ((linestart 3275 (cond
3143 (save-excursion (beginning-of-line) (point)))) 3276 ((= match ?\t) ; tab
3144 (ps-plot 'ps-basic-plot-string from (1- (point)) 3277 (let ((linestart (save-excursion (beginning-of-line) (point))))
3145 bg-color) 3278 (forward-char -1)
3146 (forward-char -1) 3279 (setq from (+ linestart (current-column)))
3147 (setq from (+ linestart (current-column))) 3280 (if (re-search-forward "[ \t]+" to t)
3148 (if (re-search-forward "[ \t]+" to t) 3281 (ps-plot 'ps-basic-plot-whitespace
3149 (ps-plot 'ps-basic-plot-whitespace 3282 from (+ linestart (current-column))
3150 from (+ linestart (current-column)) 3283 bg-color))))
3151 bg-color))) 3284
3152 ;; any other control character except tab 3285 ((= match ?\n) ; newline
3153 (ps-plot 'ps-basic-plot-string from (1- (point)) bg-color) 3286 (ps-next-line))
3154 (cond 3287
3155 ((= match ?\n) ; newline 3288 ((= match ?\f) ; form feed
3156 (ps-next-line)) 3289 (ps-next-page))
3157 3290 ; characters from ^@ to ^_ and
3158 ((= match ?\f) ; form feed 3291 (t ; characters from 127 to 255
3159 (ps-next-page)) 3292 (ps-control-character match)))
3160
3161 ((<= match ?\037) ; characters from ^@ to ^_
3162 (ps-control-character (format "^%c" (+ match ?@))))
3163
3164 ((= match ?\177) ; del (127) is printed ^?
3165 (ps-control-character "^?"))
3166
3167 (t ; characters from 128 to 255
3168 (ps-control-character (format "\\%o" match)))))
3169 (setq from (point))) 3293 (setq from (point)))
3170 ;; region without control characters 3294 ;; region without control characters
3171 (ps-plot 'ps-basic-plot-string from to bg-color) 3295 (ps-plot 'ps-basic-plot-string from to bg-color)
3172 (setq from to))))) 3296 (setq from to)))))
3173 3297
3174(defun ps-control-character (str) 3298(defvar ps-string-control-codes
3175 (let* ((from (1- (point))) 3299 (let ((table (make-vector 256 nil))
3300 (char ?\000))
3301 ;; control character
3302 (while (<= char ?\037)
3303 (aset table char (format "^%c" (+ char ?@)))
3304 (setq char (1+ char)))
3305 ;; printable character
3306 (while (< char ?\177)
3307 (aset table char (format "%c" char))
3308 (setq char (1+ char)))
3309 ;; DEL
3310 (aset table char "^?")
3311 ;; 8-bit character
3312 (while (<= (setq char (1+ char)) ?\377)
3313 (aset table char (format "\\%o" char)))
3314 table)
3315 "Vector used to map characters to a printable string.")
3316
3317(defun ps-control-character (char)
3318 (let* ((str (aref ps-string-control-codes char))
3319 (from (1- (point)))
3176 (len (length str)) 3320 (len (length str))
3177 (to (+ from len)) 3321 (to (+ from len))
3178 (wrappoint (ps-find-wrappoint from to ps-avg-char-width))) 3322 (wrappoint (ps-find-wrappoint from to ps-avg-char-width)))
@@ -3189,8 +3333,16 @@ EndDSCPage\n"))
3189(defun ps-color-values (x-color) 3333(defun ps-color-values (x-color)
3190 (cond ((fboundp 'x-color-values) 3334 (cond ((fboundp 'x-color-values)
3191 (x-color-values x-color)) 3335 (x-color-values x-color))
3192 ((fboundp 'pixel-components) 3336 ((fboundp 'color-instance-rgb-components)
3193 (pixel-components x-color)) 3337 (if (ps-color-device)
3338 (color-instance-rgb-components
3339 (if (color-instance-p x-color)
3340 x-color
3341 (make-color-instance
3342 (if (color-specifier-p x-color)
3343 (color-name x-color)
3344 x-color))))
3345 (error "No available function to determine X color values.")))
3194 (t (error "No available function to determine X color values.")))) 3346 (t (error "No available function to determine X color values."))))
3195 3347
3196 3348
@@ -3215,10 +3367,10 @@ If FACE is not a valid face name, it is used default face."
3215(defun ps-face-attribute-list (face-or-list) 3367(defun ps-face-attribute-list (face-or-list)
3216 (if (listp face-or-list) 3368 (if (listp face-or-list)
3217 ;; list of faces 3369 ;; list of faces
3218 (let ((effects 0) foreground background face-attr face) 3370 (let ((effects 0)
3371 foreground background face-attr)
3219 (while face-or-list 3372 (while face-or-list
3220 (setq face (car face-or-list) 3373 (setq face-attr (ps-face-attributes (car face-or-list))
3221 face-attr (ps-face-attributes face)
3222 effects (logior effects (aref face-attr 0))) 3374 effects (logior effects (aref face-attr 0)))
3223 (or foreground (setq foreground (aref face-attr 1))) 3375 (or foreground (setq foreground (aref face-attr 1)))
3224 (or background (setq background (aref face-attr 2))) 3376 (or background (setq background (aref face-attr 2)))
@@ -3234,11 +3386,11 @@ If FACE is not a valid face name, it is used default face."
3234 (effect (aref face-bit 0)) 3386 (effect (aref face-bit 0))
3235 (foreground (aref face-bit 1)) 3387 (foreground (aref face-bit 1))
3236 (background (aref face-bit 2)) 3388 (background (aref face-bit 2))
3237 (fg-color (if (and ps-print-color-p foreground) 3389 (fg-color (if (and ps-print-color-p foreground (ps-color-device))
3238 (mapcar 'ps-color-value 3390 (mapcar 'ps-color-value
3239 (ps-color-values foreground)) 3391 (ps-color-values foreground))
3240 ps-default-color)) 3392 ps-default-color))
3241 (bg-color (and ps-print-color-p background 3393 (bg-color (and ps-print-color-p background (ps-color-device)
3242 (mapcar 'ps-color-value 3394 (mapcar 'ps-color-value
3243 (ps-color-values background))))) 3395 (ps-color-values background)))))
3244 (ps-plot-region from to (logand effect 3) 3396 (ps-plot-region from to (logand effect 3)
@@ -3248,8 +3400,10 @@ If FACE is not a valid face name, it is used default face."
3248 3400
3249 3401
3250(defun ps-xemacs-face-kind-p (face kind kind-regex kind-list) 3402(defun ps-xemacs-face-kind-p (face kind kind-regex kind-list)
3251 (let* ((frame-font (or (face-font face) (face-font 'default))) 3403 (let* ((frame-font (or (face-font-instance face)
3252 (kind-cons (assq kind (x-font-properties frame-font))) 3404 (face-font-instance 'default)))
3405 (kind-cons (and frame-font
3406 (assq kind (font-instance-properties frame-font))))
3253 (kind-spec (cdr-safe kind-cons)) 3407 (kind-spec (cdr-safe kind-cons))
3254 (case-fold-search t)) 3408 (case-fold-search t))
3255 (or (and kind-spec (string-match kind-regex kind-spec)) 3409 (or (and kind-spec (string-match kind-regex kind-spec))
@@ -3279,6 +3433,10 @@ If FACE is not a valid face name, it is used default face."
3279 3433
3280 3434
3281(defun ps-build-reference-face-lists () 3435(defun ps-build-reference-face-lists ()
3436 ;; Ensure that face database is updated with faces on
3437 ;; `font-lock-face-attributes' (obsolete stuff)
3438 (ps-font-lock-face-attributes)
3439 ;; Now, rebuild reference face lists
3282 (setq ps-print-face-alist nil) 3440 (setq ps-print-face-alist nil)
3283 (if ps-auto-font-detect 3441 (if ps-auto-font-detect
3284 (mapcar 'ps-map-face (face-list)) 3442 (mapcar 'ps-map-face (face-list))
@@ -3335,15 +3493,14 @@ If FACE is not a valid face name, it is used default face."
3335 (< (extent-priority a) (extent-priority b))) 3493 (< (extent-priority a) (extent-priority b)))
3336 3494
3337(defun ps-print-ensure-fontified (start end) 3495(defun ps-print-ensure-fontified (start end)
3338 (and (boundp 'lazy-lock-mode) lazy-lock-mode 3496 (and (boundp 'lazy-lock-mode) (symbol-value 'lazy-lock-mode)
3339 (if (fboundp 'lazy-lock-fontify-region) 3497 (if (fboundp 'lazy-lock-fontify-region)
3340 (lazy-lock-fontify-region start end) ; the new 3498 (lazy-lock-fontify-region start end) ; the new
3341 (lazy-lock-fontify-buffer)))) ; the old 3499 (lazy-lock-fontify-buffer)))) ; the old
3342 3500
3343(defun ps-generate-postscript-with-faces (from to) 3501(defun ps-generate-postscript-with-faces (from to)
3344 ;; Some initialization... 3502 ;; Some initialization...
3345 (setq ps-current-effect 0 3503 (setq ps-current-effect 0)
3346 ps-print-face-alist nil)
3347 3504
3348 ;; Build the reference lists of faces if necessary. 3505 ;; Build the reference lists of faces if necessary.
3349 (if (or ps-always-build-face-reference 3506 (if (or ps-always-build-face-reference
@@ -3355,7 +3512,7 @@ If FACE is not a valid face name, it is used default face."
3355 ;; that ps-print can be dumped into emacs. This expression can't be 3512 ;; that ps-print can be dumped into emacs. This expression can't be
3356 ;; evaluated at dump-time because X isn't initialized. 3513 ;; evaluated at dump-time because X isn't initialized.
3357 (setq ps-print-color-scale 3514 (setq ps-print-color-scale
3358 (if ps-print-color-p 3515 (if (and ps-print-color-p (ps-color-device))
3359 (float (car (ps-color-values "white"))) 3516 (float (car (ps-color-values "white")))
3360 1.0)) 3517 1.0))
3361 ;; Generate some PostScript. 3518 ;; Generate some PostScript.
@@ -3482,8 +3639,8 @@ If FACE is not a valid face name, it is used default face."
3482 (inhibit-read-only t)) 3639 (inhibit-read-only t))
3483 (save-restriction 3640 (save-restriction
3484 (narrow-to-region from to) 3641 (narrow-to-region from to)
3485 (if ps-razzle-dazzle 3642 (and ps-razzle-dazzle
3486 (message "Formatting...%3d%%" (setq ps-razchunk 0))) 3643 (message "Formatting...%3d%%" (setq ps-razchunk 0)))
3487 (set-buffer buffer) 3644 (set-buffer buffer)
3488 (setq ps-source-buffer buffer 3645 (setq ps-source-buffer buffer
3489 ps-spool-buffer (get-buffer-create ps-spool-buffer-name)) 3646 ps-spool-buffer (get-buffer-create ps-spool-buffer-name))
@@ -3535,9 +3692,9 @@ If FACE is not a valid face name, it is used default face."
3535 (set-buffer ps-spool-buffer) 3692 (set-buffer ps-spool-buffer)
3536 (delete-region (marker-position safe-marker) (point-max)))))) 3693 (delete-region (marker-position safe-marker) (point-max))))))
3537 3694
3538 (if ps-razzle-dazzle 3695 (and ps-razzle-dazzle (message "Formatting...done"))))))
3539 (message "Formatting...done"))))))
3540 3696
3697;; Permit dynamic evaluation at print time of `ps-lpr-switches'.
3541(defun ps-do-despool (filename) 3698(defun ps-do-despool (filename)
3542 (if (or (not (boundp 'ps-spool-buffer)) 3699 (if (or (not (boundp 'ps-spool-buffer))
3543 (not (symbol-value 'ps-spool-buffer))) 3700 (not (symbol-value 'ps-spool-buffer)))
@@ -3546,16 +3703,13 @@ If FACE is not a valid face name, it is used default face."
3546 (ps-flush-output) 3703 (ps-flush-output)
3547 (if filename 3704 (if filename
3548 (save-excursion 3705 (save-excursion
3549 (if ps-razzle-dazzle 3706 (and ps-razzle-dazzle (message "Saving..."))
3550 (message "Saving..."))
3551 (set-buffer ps-spool-buffer) 3707 (set-buffer ps-spool-buffer)
3552 (setq filename (expand-file-name filename)) 3708 (setq filename (expand-file-name filename))
3553 (write-region (point-min) (point-max) filename) 3709 (write-region (point-min) (point-max) filename)
3554 (if ps-razzle-dazzle 3710 (and ps-razzle-dazzle (message "Wrote %s" filename)))
3555 (message "Wrote %s" filename)))
3556 ;; Else, spool to the printer 3711 ;; Else, spool to the printer
3557 (if ps-razzle-dazzle 3712 (and ps-razzle-dazzle (message "Printing..."))
3558 (message "Printing..."))
3559 (save-excursion 3713 (save-excursion
3560 (set-buffer ps-spool-buffer) 3714 (set-buffer ps-spool-buffer)
3561 (if (and (eq system-type 'ms-dos) 3715 (if (and (eq system-type 'ms-dos)
@@ -3565,13 +3719,37 @@ If FACE is not a valid face name, it is used default face."
3565 (let ((binary-process-input t)) ; for MS-DOS 3719 (let ((binary-process-input t)) ; for MS-DOS
3566 (apply 'call-process-region 3720 (apply 'call-process-region
3567 (point-min) (point-max) ps-lpr-command nil 3721 (point-min) (point-max) ps-lpr-command nil
3568 (if (fboundp 'start-process) 0 nil) 3722 (and (fboundp 'start-process) 0)
3569 nil 3723 nil
3570 ps-lpr-switches)))) 3724 (ps-flatten-list ; dynamic evaluation
3571 (if ps-razzle-dazzle 3725 (mapcar 'ps-eval-switch ps-lpr-switches))))))
3572 (message "Printing...done"))) 3726 (and ps-razzle-dazzle (message "Printing...done")))
3573 (kill-buffer ps-spool-buffer))) 3727 (kill-buffer ps-spool-buffer)))
3574 3728
3729;; Dynamic evaluation
3730(defun ps-eval-switch (arg)
3731 (cond ((stringp arg) arg)
3732 ((functionp arg) (apply arg nil))
3733 ((symbolp arg) (symbol-value arg))
3734 ((consp arg) (apply (car arg) (cdr arg)))
3735 (t nil)))
3736
3737;; `ps-flatten-list' is defined here (copied from "message.el" and
3738;; enhanced to handle dotted pairs as well) until we can get some
3739;; sensible autoloads, or `flatten-list' gets put somewhere decent.
3740
3741;; (ps-flatten-list '((a . b) c (d . e) (f g h) i . j))
3742;; => (a b c d e f g h i j)
3743
3744(defun ps-flatten-list (&rest list)
3745 (ps-flatten-list-1 list))
3746
3747(defun ps-flatten-list-1 (list)
3748 (cond ((null list) nil)
3749 ((consp list) (append (ps-flatten-list-1 (car list))
3750 (ps-flatten-list-1 (cdr list))))
3751 (t (list list))))
3752
3575(defun ps-kill-emacs-check () 3753(defun ps-kill-emacs-check ()
3576 (let (ps-buffer) 3754 (let (ps-buffer)
3577 (and (setq ps-buffer (get-buffer ps-spool-buffer-name)) 3755 (and (setq ps-buffer (get-buffer ps-spool-buffer-name))