unofficial mirror of emacs-devel@gnu.org 
 help / color / mirror / code / Atom feed
* [Patch] Basic WYSIWYG printing in GNU Emacs
@ 2021-08-10  9:29 Anand Tamariya
  2021-08-10 12:31 ` Eli Zaretskii
  0 siblings, 1 reply; 13+ messages in thread
From: Anand Tamariya @ 2021-08-10  9:29 UTC (permalink / raw)
  To: emacs-devel


[-- Attachment #1.1: Type: text/plain, Size: 615 bytes --]

Here's a patch for basic WYSIWYG printing in GNU Emacs. This should enable
following print  features in Emacs:

   - Size and colour variation in text
   - Unicode text (including Hindi, script for Eastern European
   languages, logographic scripts like Chinese, Japanese and Korean (CJK),
   right to left (RTL) scripts like Arabic and Hebrew, and music symbols)
   - Fancy fonts
   - Tables
   - Images
   - Zero font setup (Tip: Use Truetype fonts in your system)

*Screenshots:*
https://lifeofpenguin.blogspot.com/2021/06/basic-wysiwyg-printing-in-gnu-emacs.html

*Note:* This disables ps-mule.el for printing.

[-- Attachment #1.2: Type: text/html, Size: 931 bytes --]

[-- Attachment #2: patch.txt --]
[-- Type: text/plain, Size: 34554 bytes --]

diff --git a/etc/ps-prin1.ps b/etc/ps-prin1.ps
index f68174b991..0db2f2f182 100644
--- a/etc/ps-prin1.ps
+++ b/etc/ps-prin1.ps
@@ -76,6 +76,22 @@ StandardEncoding 46 82 getinterval aload pop
 256 packedarray def
 }ifelse
 
+/DefMetrics{
+    /FontHeight Ascent Descent sub def	% use `sub' because descent < 0
+
+    % Define these in case they're not in the FontInfo
+    % (also, here they're easier to get to).
+    /UnderlinePosition  Descent 0.20 mul def
+    /OverlinePosition   Descent UnderlinePosition sub Ascent add def
+    /StrikeoutPosition  Ascent 0.30 mul def
+    /LineThickness      FontHeight 0.02 mul def
+    /Xshadow            FontHeight  0.08 mul def
+    /Yshadow            FontHeight -0.09 mul def
+    /SpaceBackground    Descent neg UnderlinePosition add def
+    /XBox               Descent neg def
+    /YBox               LineThickness 0.7 mul def
+}def
+
 /reencodeFontISO{ %def
   dup
   length 12 add dict	% Make a new font (a new dict the same size
@@ -115,19 +131,7 @@ StandardEncoding 46 82 getinterval aload pop
      PrimaryFont/FontMatrix get transform/Ascent exch def pop
      PrimaryFont/FontMatrix get transform/Descent exch def pop}ifelse
 
-    /FontHeight Ascent Descent sub def	% use `sub' because descent < 0
-
-    % Define these in case they're not in the FontInfo
-    % (also, here they're easier to get to).
-    /UnderlinePosition  Descent 0.70 mul def
-    /OverlinePosition   Descent UnderlinePosition sub Ascent add def
-    /StrikeoutPosition  Ascent 0.30 mul def
-    /LineThickness      FontHeight 0.05 mul def
-    /Xshadow            FontHeight  0.08 mul def
-    /Yshadow            FontHeight -0.09 mul def
-    /SpaceBackground    Descent neg UnderlinePosition add def
-    /XBox               Descent neg def
-    /YBox               LineThickness 0.7 mul def
+    DefMetrics
 
     currentdict		% Leave the new font on the stack
     end			% Stop using the font as the current dictionary.
@@ -138,6 +142,17 @@ StandardEncoding 46 82 getinterval aload pop
 % Font definition
 /DefFont{findfont exch scalefont reencodeFontISO}def
 
+/DeriveFont {	% newname charstring encoding fontname  |  font
+    findfont dup length dict begin
+	{ 1 index /FID ne { def } { pop pop } ifelse } forall
+        /Encoding exch def
+        /CharStrings exch def
+	currentdict
+    end
+    definefont
+    pop
+} bind def
+
 % Font selection
 /F{
   findfont
@@ -153,9 +168,25 @@ StandardEncoding 46 82 getinterval aload pop
   dup/SpaceBackground   get/SpaceBackground   exch def
   dup/XBox              get/XBox              exch def
   dup/YBox              get/YBox              exch def
+  % /LineHeight FontHeight def
   setfont
 }def
 
+/FS {
+    exch findfont exch scalefont setfont
+
+    currentfont/FontType get 0 ne
+    {/PrimaryFont currentfont def}
+    {/PrimaryFont currentfont /FDepVector get 0 get def}
+    ifelse
+
+    PrimaryFont/FontBBox get aload pop
+    PrimaryFont/FontMatrix get transform/Ascent exch def pop
+    PrimaryFont/FontMatrix get transform/Descent exch def pop
+
+    DefMetrics
+}def
+
 /FG/setrgbcolor load def
 
 /bg false def
@@ -196,9 +227,9 @@ StandardEncoding 46 82 getinterval aload pop
   dobackground
 }def
 
-/LineHS LineHeight LineSpacing add def
+/LineHS{ LineHeight LineSpacing add }def
 /ParagraphHS LineHeight ParagraphSpacing add def
-/PSL{/h exch def bg{eolbg}if  0  currentpoint exch pop h sub  moveto}def
+/PSL{currentpoint pop neg LineHS neg rmoveto}def
 /PLN{PrintLineNumber{doLineNumber}if}def
 
 /SL{LineHS PSL isLineStep pop}def	% Soft Linefeed
@@ -211,12 +242,12 @@ StandardEncoding 46 82 getinterval aload pop
 /dp{print 2 copy  exch 40 string cvs print(, )print =}def
 
 /W{
-  ( )stringwidth	% Get the width of a space in the current font.
+  (n)stringwidth	% Get the en width in the current font.
   pop			% Discard the Y component.
   mul			% Multiply the width of a space
 			% by the number of spaces to plot
   bg{dup dobackground}if
-  0 rmoveto
+  currentpoint exch pop moveto
 }def
 
 /Effect          0 def
@@ -266,6 +297,13 @@ StandardEncoding 46 82 getinterval aload pop
   EffectOverline {OverlinePosition  Hline}if	% overline
 }bind def
 
+% stack:  string yposition  |-  --
+/yS {
+	/y exch def
+	0 y rmoveto S
+	0 y neg rmoveto
+} def
+
 % stack:  position  |-  --
 /Hline{
   currentpoint exch pop add dup
diff --git a/lisp/descr-text.el b/lisp/descr-text.el
index 1dbbd42148..9817accad9 100644
--- a/lisp/descr-text.el
+++ b/lisp/descr-text.el
@@ -842,6 +842,48 @@ describe-char
           (if text-props-desc (insert text-props-desc))
           (setq buffer-read-only t))))))
 
+(defun composite-char-p (pos)
+  "Returns non-nil if POS is a non-composite char.
+ If point is after a composite char on a non-composite char,
+ `find-composition' returns non-nil. This function is useful in
+ such cases."
+  (let ((composition (find-composition pos)))
+  (when composition
+        ;; When the composition is trivial (i.e. composed only with the
+        ;; current character itself without any alternate characters),
+        ;; we don't show the composition information.  Otherwise, store
+        ;; two descriptive strings in the first two elements of
+        ;; COMPOSITION.
+        (or (catch 'tag
+              (let ((from (car composition))
+                    (to (nth 1 composition))
+                    (components (nth 2 composition))
+                    )
+                (if (and (vectorp components) (vectorp (aref components 0)))
+                    (let ((idx (- pos from))
+                          (nglyphs (lgstring-glyph-len components))
+                          (i 0) j glyph glyph-from)
+                      ;; COMPONENTS is a gstring.  Find a grapheme
+                      ;; cluster containing the current character.
+                      (while (and (< i nglyphs)
+                                  (setq glyph (lgstring-glyph components i))
+                                  (< (lglyph-to glyph) idx))
+                        (setq i (1+ i)))
+                      (if (or (not glyph) (= i nglyphs))
+                          ;; The composition is broken.
+                          (throw 'tag nil))
+                      (setq glyph-from (lglyph-from glyph)
+                            to (+ from (lglyph-to glyph) 1)
+                            from (+ from glyph-from)
+                            j i)
+                      (while (and (< j nglyphs)
+                                  (setq glyph (lgstring-glyph components j))
+                                  (= (lglyph-from glyph) glyph-from))
+                        (setq j (1+ j)))
+                      (nconc composition (list i (1- j))))
+                  )))
+            (setq composition nil)))))
+
 ;;; Describe-Char-ElDoc
 
 (defun describe-char-eldoc--truncate (name width)
diff --git a/lisp/ps-def.el b/lisp/ps-def.el
index 49d72d3be5..ccb70e838a 100644
--- a/lisp/ps-def.el
+++ b/lisp/ps-def.el
@@ -28,6 +28,7 @@
 ;; See ps-print.el for documentation.
 
 ;;; Code:
+(require 'descr-text)
 
 (declare-function ps-plot-with-face "ps-print" (from to face))
 (declare-function ps-plot-string    "ps-print" (string))
@@ -103,6 +104,20 @@ ps-color-format
 (defvar ps-float-format "%0.3f ")
 
 
+(defun ps-font-name (font)
+  "PS font name for FONT object."
+  (let* ((info (font-info font))
+         (file (aref info 12)))
+    (or (font-get font :postscriptname)
+        (file-name-base file))))
+
+(defvar ps--cmap nil
+  "Char table containing (FONT CODE (GLYPH INDICES)) for a
+  character. Glyph indices are indices in PS font.")
+
+(defvar ps--adjustment nil
+  "X adjustment for composite glyphs.")
+
 (defun ps-generate-postscript-with-faces1 (from to)
   ;; Generate some PostScript.
   (let ((face 'default)
@@ -110,31 +125,166 @@ ps-generate-postscript-with-faces1
 	;; Emacs
 	(property-change from)
 	(overlay-change from)
-	before-string after-string)
-    (while (< from to)
+        (font-change from)
+        family char-info glyph glyphs chars
+        fonts font-index font-glyphs font-chars
+        pos next ltr
+        components
+        )
+    ;; Generate a map containing font-family and a list of (font index (glyph indices))
+    ;; from that family used in the doc for unicode char
+    (goto-char from)
+    (setq ps--cmap (make-char-table 'cmap))
+    (setq ps--adjustment (make-char-table 'adjustment))
+    (while (and (not (eobp))
+                (or (> (char-after) 255)
+                    (and (re-search-forward "[^[:ascii:]]" to t)
+                         (goto-char (match-beginning 0))))
+                )
+      (if (composite-char-p (point))
+          (progn
+            (setq char-info (find-composition (point))
+                  pos (nth 0 char-info)
+                  next (nth 1 char-info)
+                  components (nth 2 char-info)
+                  family (ps-font-name (lgstring-font components)))
+            )
+        (setq char-info (internal-char-font (point))
+              pos (point)
+              next (1+ (point))
+              components nil
+              glyph (cdr char-info)
+              family (ps-font-name (car char-info))))
+
+      (unless (assoc family fonts)
+        (setq font-index (length fonts))
+        (push (list family font-index (aref char-script-table (char-after))) fonts)
+        (push (cons font-index nil) font-chars)
+        (push (cons font-index nil) font-glyphs))
+      (setq font-index (nth 1 (assoc family fonts)))
+
+      (setq chars  nil)
+      (setq glyphs (cdr (assoc font-index font-glyphs)))
+      (if components
+          ;; Loop for composites
+          (dotimes (i (lgstring-glyph-len components))
+            (setq glyph (lglyph-code (lgstring-glyph components i)))
+            (unless (memq glyph glyphs)
+              (push glyph glyphs))
+            (push (1- (length (memq glyph glyphs))) chars)
+            (if (= i 0)
+                (aset ps--adjustment pos
+                      (lglyph-adjustment (lgstring-glyph components i))))
+            )
+        ;; For non-composites
+        (unless (memq glyph glyphs)
+          (push glyph glyphs))
+        (push (1- (length (memq glyph glyphs))) chars))
+      (setcdr (assoc font-index font-glyphs) glyphs)
+
+      ;; (message "%s %s" pos (reverse chars))
+      (aset ps--cmap pos (cons font-index (reverse chars)))
+      ;; (message "%s" char-info)
+      (goto-char next)
+      )
+    ;; (pp fonts)
+    ;; (pp font-chars)
+    ;; (pp font-glyphs)
+
+    ;; Use font-glyphs to generate new PS font
+    (dolist (e font-glyphs)
+      (let* ((font-index (car e))
+             (font (pop fonts))
+             (script (nth 2 font))
+             (encoding-str nil)
+             (map-str nil)
+             (cmap-str nil)
+             (i 0)
+             (glyphs (cdr e)))
+        (when (memq script '(han kana))
+          ;; CIDFont for CJK script
+          (mapc (lambda (k)
+                  (setq cmap-str (concat cmap-str
+                                         (format "<%02x> <%02x> %d\n" i i k))
+                        i (1+ i)))
+                (nreverse glyphs))
+          (setq i (1- i))
+          (ps-output (format "
+/CIDInit /ProcSet findresource begin
+12 dict begin
+begincmap /CIDSystemInfo <<
+/Registry (Adobe) /Ordering (Identity) /Supplement 0 >> def
+/CMapName /CM def
+/CMapType 1 def
+1 begincodespacerange
+<%02x> <%02x>
+endcodespacerange
+
+%d begincidrange
+%s
+endcidrange
+endcmap CMapName currentdict /CMap defineresource
+pop end end
+/F%d /CM [/%s] composefont pop
+"
+                             0 i (1+ i) cmap-str font-index (car font))))
+
+        (unless (memq script '(han kana))
+          ;; Type42 font
+          (mapc (lambda (k)
+                  (setq encoding-str (concat encoding-str (format "/g%d " k))
+                        map-str (concat map-str (format "/g%d %d\n" k k))))
+                (nreverse glyphs))
+          ;; (pp encoding-str)
+          ;; (pp map-str)
+          (ps-output (format "/E [%s] def\n" encoding-str))
+          (ps-output (format "/C <<%s>> def\n" map-str))
+          (ps-output (format "/F%d C E /%s DeriveFont\n" font-index (car font)))
+          )))
+
+    (while (and (goto-char from)
+                (char-after)
+                (< from to))
+
       (and (< property-change to)  ; Don't search for property change
 					; unless previous search succeeded.
 	   (setq property-change (next-property-change from nil to)))
       (and (< overlay-change to)   ; Don't search for overlay change
 					; unless previous search succeeded.
-	   (setq overlay-change (min (next-overlay-change from)
-				     to)))
-      (setq position (min property-change overlay-change)
-	    before-string nil
-	    after-string nil)
+	   (setq overlay-change (next-overlay-change from)))
+      (and (or (null font-change) (< font-change to))  ; Don't search for property change
+					; unless previous search succeeded.
+           ;; Range of characters sharing same font
+           ;; Whitespace uses default font usually in between mixed font families.
+           ;; Hence must be treated separately.
+           (setq font-change (or (if (= (syntax-class (syntax-after from)) 0)
+                                     (+ from (skip-chars-forward "[ \t\n]")))
+                                 (when (eq (char-charset (char-after)) 'ascii)
+                                   (and (re-search-forward "[[:multibyte:][:blank:]]" nil t)
+                                        (1- (point))))
+                                 (when (eq (char-charset (char-after)) 'unicode)
+                                   (and (re-search-forward "[[:ascii:][:blank:]]" nil t)
+                                        (1- (point))))
+                                 ))
+           )
+      (setq position
+            (if (null font-change)
+                (min property-change overlay-change)
+              (min property-change overlay-change font-change))
+            ltr (get-char-code-property (char-after from) 'bidi-class)
+            )
+      (if (composite-char-p from)
+          (setq char-info (find-composition from)
+                position (nth 1 char-info)))
+      ;; (message "%s %s %s %s %s" from property-change overlay-change font-change ltr)
       (setq face
 	    (cond ((invisible-p from)
 		   'emacs--invisible--face)
 		  ((get-char-property from 'face))
 		  (t 'default)))
-      ;; Plot up to this record.
-      (and before-string
-	   (ps-plot-string before-string))
-      (ps-plot-with-face from position face)
-      (and after-string
-	   (ps-plot-string after-string))
-      (setq from position))
-    (ps-plot-with-face from to face)))
+      (ps-plot-with-face from position face (not (memq ltr '(R AL))))
+      (setq from position)
+      )))
 
 \f
 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
diff --git a/lisp/ps-print.el b/lisp/ps-print.el
index ace3001781..8c7b87cee3 100644
--- a/lisp/ps-print.el
+++ b/lisp/ps-print.el
@@ -1452,6 +1452,7 @@ ps-print-version
 
 
 (require 'lpr)
+(require 'image-converter)
 
 ;; Load Emacs definitions
 (require 'ps-def)
@@ -2828,10 +2829,10 @@ ps-font-info-database
   :version "20"
   :group 'ps-print-font)
 
-(defcustom ps-font-family 'Courier
+(defcustom ps-font-family nil
   "Font family name for ordinary text, when generating PostScript."
   :type 'symbol
-  :version "20"
+  :version "28"
   :group 'ps-print-font)
 
 (defcustom ps-font-size   '(7 . 8.5)
@@ -3180,7 +3181,7 @@ ps-underlined-faces
   :version "20"
   :group 'ps-print-face)
 
-(defcustom ps-use-face-background nil
+(defcustom ps-use-face-background t
   "Specify if face background should be used.
 
 Valid values are:
@@ -3399,7 +3400,7 @@ ps-paragraph-spacing
   :version "21.1"
   :group 'ps-print-miscellany)
 
-(defcustom ps-paragraph-regexp "[ \t]*$"
+(defcustom ps-paragraph-regexp nil
   "Specify paragraph delimiter.
 
 It should be a regexp or nil.
@@ -3408,7 +3409,7 @@ ps-paragraph-regexp
   :type '(choice :menu-tag "Paragraph Delimiter"
 		 (const :tag "No Delimiter" nil)
 		 (regexp :tag "Delimiter Regexp"))
-  :version "21.1"
+  :version "28"
   :group 'ps-print-miscellany)
 
 (defcustom ps-begin-cut-regexp nil
@@ -3924,6 +3925,7 @@ ps-default-foreground
 (defvar ps-default-background nil)
 (defvar ps-default-color nil)
 (defvar ps-current-color nil)
+(defvar ps-current-height nil)
 (defvar ps-current-bg nil)
 (defvar ps-foreground-list nil)
 
@@ -4349,8 +4351,62 @@ ps-nb-pages
 (defmacro ps-lookup (key) `(cdr (assq ,key font-entry)))
 (defmacro ps-size-scale (key) `(/ (* (ps-lookup ,key) font-size) size))
 
+(defun ps-find-font (&optional font-family)
+  "Populate `ps-font-info-database' with default font
+info. Default font is used for displaying ASCII characters."
+  (or (assq font-family ps-font-info-database)
+      ;; Every document might have a different default font
+      ;;ps-font-family
+      (let (font types name size line-height space-width avg-char-width
+                 info prop old-prop pos empty)
+        (when (zerop (buffer-size))
+          ;; Need atleast one char for analysis
+          (insert " ")
+          (setq empty t))
+
+        (save-excursion
+          (goto-char (point-min))
+          (unless (< (char-after) 255)
+            (re-search-forward "[:ascii:]" (point-max) t))
+
+          (setq pos (point)
+                prop (get-text-property pos 'face)
+                old-prop (if (listp prop) prop (list prop))))
+        (dolist (type '(default bold italic bold-italic))
+          (setq prop (append old-prop
+                             (if (eq type 'bold) '(:weight bold))
+                             (if (eq type 'italic) '(:slant oblique))
+                             (if (eq type 'bold-italic) '(:weight bold :slant oblique))
+                             ))
+          (put-text-property pos (1+ pos) 'face prop)
+
+          (setq info (font-info (font-at pos))
+                name (ps-font-name (font-at pos))
+                size (aref info 2)
+                line-height (aref info 3)
+                space-width (aref info 10)
+                avg-char-width (aref info 11))
+          (when (eq type 'default)
+            (setq font-family (intern name)
+                  ps-font-family font-family))
+          (push (cons type name) types))
+
+        ;; Restore buffer state
+        (put-text-property pos (1+ pos) 'face old-prop)
+        (when empty (erase-buffer))
+
+        (setq font (cons font-family `((fonts . ,(nreverse types))
+                                       (size . ,size)
+                                       (line-height . ,line-height)
+	                               (space-width . ,space-width)
+	                               (avg-char-width . ,avg-char-width)))
+              ps-font-size-internal size)
+        (unless (assq font-family ps-font-info-database)
+          (push font ps-font-info-database))
+        font)))
+
 (defun ps-select-font (font-family sym font-size title-font-size)
-  (let ((font-entry (cdr (assq font-family ps-font-info-database))))
+  (let* ((font-entry (cdr (ps-find-font font-family))))
     (or font-entry
 	(error "Don't have data to scale font %s.  Known fonts families are %s"
 	       font-family
@@ -4374,7 +4430,7 @@ ps-get-page-dimensions
       (error "The number of columns %d should be positive"
 	     ps-number-of-columns)))
 
-    (ps-select-font ps-font-family 'ps-font-for-text
+    (ps-select-font nil 'ps-font-for-text
 		    ps-font-size-internal ps-font-size-internal)
     (ps-select-font ps-header-font-family 'ps-font-for-header
 		    ps-header-font-size-internal
@@ -4581,9 +4637,7 @@ ps-string-escape-codes
 (defsubst ps-output-string-prim (string)
   (insert "(")				;insert start-string delimiter
   (save-excursion			;insert string
-    (insert (if (multibyte-string-p string)
-                (encode-coding-string string 'utf-8)
-              string)))
+    (insert string))
   ;; Find and quote special characters as necessary for PS
   ;; This skips everything except control chars, non-ASCII chars, (, ) and \.
   (while (progn (skip-chars-forward " -'*-[]-~") (not (eobp)))
@@ -5895,9 +5949,8 @@ ps-begin-page
     (ps-output (format "%d SetFooterLines\n" ps-footer-lines)))
 
   (ps-output (number-to-string ps-lines-printed) " BeginPage\n")
-  (ps-set-font  ps-current-font)
-  (ps-set-bg    ps-current-bg)
-  (ps-set-color ps-current-color))
+  (ps-output (format "PrintWidth %f div dup scale\n"
+                     (window-body-width nil t))))
 
 (defsubst ps-skip-newline (limit)
   (setq ps-showline-count (1+ ps-showline-count)
@@ -5946,15 +5999,15 @@ ps-basic-plot-str
     wrappoint))
 
 (defun ps-basic-plot-string (from to &optional _bg-color)
-  (let* ((wrappoint (ps-find-wrappoint from to
-				       (ps-avg-char-width 'ps-font-for-text)))
-	 (to (car wrappoint))
-	 (string (buffer-substring-no-properties from to)))
+  (let* ((string (buffer-substring-no-properties from to)))
     (ps-output-string string)
     (ps-output " S\n")
-    wrappoint))
+    (cons to (* (ps-space-width 'ps-font-for-text) (- to from)))
+    ))
 
 (defun ps-basic-plot-whitespace (from to &optional _bg-color)
+  "Used for drawing TAB position.
+Since space width may be narrower than char width, use en width."
   (let* ((wrappoint (ps-find-wrappoint from to
 				       (ps-space-width 'ps-font-for-text)))
 	 (to (car wrappoint)))
@@ -6001,6 +6054,10 @@ ps-set-color
 		     (nth 1 ps-current-color) (nth 2 ps-current-color))
 	     " FG\n"))
 
+(defun ps-change-font (family size)
+  "Use this function when font or size is different from default."
+  (setq ps-last-font nil)
+  (ps-output (format "/%s %d FS\n" family size)))
 
 (defsubst ps-plot-string (string)
   (ps-plot 'ps-basic-plot-str 0 (length string) string))
@@ -6022,10 +6079,48 @@ ps-print-translation-table
 The default value is a table that translates non-Latin-1 Latin characters
 to the equivalent Latin-1 characters.")
 
-(defun ps-plot-region (from to font &optional fg-color bg-color effects)
-  (or (equal font ps-current-font)
-      (ps-set-font font))
+(defun ps-plot-effects (face)
+  (let* ((face-bit   (ps-face-attribute-list face))
+	 (effect     (aref face-bit 0))
+	 (foreground (aref face-bit 1))
+	 (background (ps-face-background face (aref face-bit 2)))
+	 (fg-color (if (and ps-color-p foreground)
+		       (ps-color-scale foreground)
+		     ps-default-color))
+	 (fg (or fg-color ps-default-foreground))
+         (effects (ash effect -2))
+         (bg-color (and ps-color-p background
+			(ps-color-scale background))))
+
+    ;; Specify a foreground color only if:
+    ;;    one's specified,
+    ;;    it's different from the background (if `ps-fg-validate-p' is non-nil)
+    ;;    and it's different from the current.
+    (if ps-fg-validate-p
+	(let ((bg (or bg-color ps-default-background))
+	      (el ps-foreground-list))
+	  (while (and el (equal fg bg))
+	    (setq fg (car el)
+		  el (cdr el)))))
+    (or (equal fg ps-current-color)
+	(ps-set-color fg))
+
+    (or (equal bg-color ps-current-bg)
+      (if (equal bg-color ps-default-background)
+          (if ps-current-bg (ps-set-bg nil))
+        (ps-set-bg bg-color)))
 
+    ;; Specify effects (underline, overline, box, etc.)
+    (cond
+     ((not (integerp effects))
+      (ps-output "0 EF\n")
+      (setq ps-current-effect 0))
+     ((/= effects ps-current-effect)
+      (ps-output (number-to-string effects) " EF\n")
+      (setq ps-current-effect effects)))
+    ))
+
+(defun ps-plot-region (from to _font &optional fg-color bg-color effects)
   ;; Specify a foreground color only if:
   ;;    one's specified,
   ;;    it's different from the background (if `ps-fg-validate-p' is non-nil)
@@ -6041,7 +6136,9 @@ ps-plot-region
 	(ps-set-color fg)))
 
   (or (equal bg-color ps-current-bg)
-      (ps-set-bg bg-color))
+      (if (equal bg-color ps-default-background)
+          (if ps-current-bg (ps-set-bg nil))
+        (ps-set-bg bg-color)))
 
   ;; Specify effects (underline, overline, box, etc.)
   (cond
@@ -6080,9 +6177,10 @@ ps-plot-region
 	      (let ((linestart (line-beginning-position)))
 		(forward-char -1)
 		(setq from (+ linestart (current-column)))
-		(when (re-search-forward "[ \t]+" to t)
+		(when (re-search-forward "[\t]+" to t)
 		  (ps-plot 'ps-basic-plot-whitespace
-			   from (+ linestart (current-column))
+                           ;; Tab stops are fixed
+                           0 (current-column)
 			   bg-color))))
 
 	     ((= match ?\n)		; newline
@@ -6093,7 +6191,7 @@ ps-plot-region
 		    (ps-next-page))
 		;; \n\f\n     ==>> it'll be handled by form feed
 		;; \ntext\n   ==>> next line
-		(ps-next-line)))
+		(ps-plot-with-face (1- (point)) (point) 'default)))
 
 	     ((= match ?\f)		; form feed
 	      ;; do not skip page if previous character is NEWLINE and
@@ -6189,11 +6287,19 @@ ps-face-attributes
 			 (cons new-face ps-print-face-alist)))
 	       new-face))))
    ((ps-face-foreground-color-p (car face))
-    (vector 0 (ps-face-extract-color face) nil))
+    (vector 0 (ps-face-extract-color face) nil nil))
    ((ps-face-background-color-p (car face))
-    (vector 0 nil (ps-face-extract-color face)))
+    (vector 0 nil (ps-face-extract-color face) nil))
    (t
-    (vector 0 nil nil))))
+    (vector (if (and (eq 'bold (faces--attribute-at-point :weight))
+                             (eq 'oblique (faces--attribute-at-point :slant)))
+                        3
+                      (if (eq 'bold (faces--attribute-at-point :weight))
+                          1
+                        (if (eq 'oblique (faces--attribute-at-point :slant))
+                            2
+                          0)))
+            nil nil nil))))
 
 
 (defun ps-face-background (face background)
@@ -6231,12 +6337,16 @@ ps-face-attribute-list
     (vector 0 nil (ps-face-extract-color face-or-list)))
    ;; Anonymous face.
    ((keywordp (car face-or-list))
-    (vector 0 (plist-get face-or-list :foreground)
-	    (plist-get face-or-list :background)))
+    (vector (logior (if (eq 'bold (plist-get face-or-list :weight)) 1 0)
+                    (if (eq 'oblique (plist-get face-or-list :slant)) 2 0))
+            (plist-get face-or-list :foreground)
+	    (plist-get face-or-list :background)
+            (if (plist-get face-or-list :height)
+                (/ (plist-get face-or-list :height) 10.0) 0)))
    ;; list of faces
    (t
     (let ((effects 0)
-	  foreground background face-attr face)
+	  foreground background height face-attr face)
       (while face-or-list
 	(setq face         (car face-or-list)
 	      face-or-list (cdr face-or-list)
@@ -6244,28 +6354,156 @@ ps-face-attribute-list
 	      effects      (logior effects (aref face-attr 0)))
 	(or foreground (setq foreground (aref face-attr 1)))
 	(or background
-	    (setq background (ps-face-background face (aref face-attr 2)))))
-      (vector effects foreground background)))))
+	    (setq background (ps-face-background face (aref face-attr 2))))
+        (or height (setq height (aref face-attr 3))))
+      (vector effects foreground background height)))))
 
 
 (defconst ps-font-type (vector nil 'bold 'italic 'bold-italic))
 
 
-(defun ps-plot-with-face (from to face)
+(defun ps-plot-with-face (from to face &optional ltr)
+  (goto-char from)
   (cond
    ((null face)				; print text with null face
     (ps-plot-region from to 0))
    ((eq face 'emacs--invisible--face))	; skip invisible text!!!
+   ((eolp)
+    ;; New line doesn't need font change. However, line height must be
+    ;; restored for next line.
+    (ps-output (format "/LineHeight %0.3f def\n"
+                       (save-excursion
+                         (let ((h (line-pixel-height)))
+                           (forward-line)
+                           ;; This is required for image. However, breaks tables.
+                           ;; (+ (/ h 2.0) (line-pixel-height))
+                           (line-pixel-height)
+                           ;; (* (/ (/ (display-mm-width) 25.4) (display-pixel-width))
+                           ;;    72.0 (+ (/ h 2.0) (line-pixel-height)))
+                           ))))
+    (ps-next-line)
+    (when (> to (1+ from))
+      (goto-char (1+ from))
+      (ps-plot-with-face (1+ from) to face ltr)))
+   ((eq 'space (car (get-text-property from 'display)))
+    (let* ((size (posn-object-width-height (posn-at-point from)))
+           (w (car size)))
+      (ps-output (format "%d 0 rmoveto\n" w))))
+   ((aref ps--cmap (point))
+    ;; Plot unicode characters sharing same font
+    (ps-plot-effects face)
+    (let (family size str data pos tfamily)
+      (setq data (aref ps--cmap (point))
+            size (font-get (font-at (point)) :size)
+            family (car data))
+      (ps-change-font (format "F%d" family) size)
+      (unless ltr
+        (save-excursion
+          (goto-char (1- to))
+          (if (eolp) (forward-char -1))
+          (ps-output (format "currentpoint %d exch moveto pop\n"
+                             (car (posn-x-y (posn-at-point)))))
+          ))
+      (let ((i 0)
+            (end (- to from)))
+        (while (< i end)
+          (setq pos (if ltr (+ from i) (- to i 1))
+                i (1+ i))
+          (goto-char pos)
+          (setq data (aref ps--cmap (point))
+                tfamily (or (car data) family))
+        (cond ((/= family tfamily)
+               (setq i (if ltr to from)))
+              (t
+               (setq data (aref ps--cmap pos)
+                     str (concat str
+                                 (mapconcat
+                                  (lambda (a)
+                                    (format "\\%003o" a))
+                                  (if ltr (cdr data) (reverse (cdr data))) ""))
+                     )))))
+      (cond
+       ((and (aref ps--adjustment from)
+             (eq (get-char-code-property (char-after from) 'bidi-class) 'R))
+        ;; For Hebrew
+        (ps-output (format "(%s)%s xshow\n" str (aref ps--adjustment from))))
+       ((plist-get (get-text-property from 'display) 'raise)
+        (ps-output (format "(%s) %0.3f yS\n" str
+                           (* size
+                              (plist-get (get-text-property from 'display)
+                                         'raise)
+                              ))))
+       ((not (string-empty-p str))
+        (ps-output (format "(%s) S\n" str))))
+
+      (if (/= family tfamily)
+          ;; Mixed family - might be from different scripts
+          (ps-plot-with-face pos to face ltr))
+      ))
+   ((plist-get (get-text-property from 'display) 'image)
+    (let* ((image (get-text-property from 'display))
+           (size (image-size image t))
+           (data (plist-get (cdr (image-convert
+                                  (append image '(:data-p image/mjpeg))))
+                            :data))
+           (w (car size))
+           (h (cdr size)))
+      (ps-output (concat (format "
+/w %d def
+/h %d def
+" w h)
+"
+currentpoint h 2 div add
+gsave
+
+translate
+% 0 700 translate   % set lower left of image at (0, 700)
+w h scale           % size of rendered image is w points by h points
+w                   % number of columns per row
+h                   % number of rows
+8                   % bits per color channel (1, 2, 4, or 8)
+[w 0 0 h neg 0 0]   % maps unit square to image space
+% (splash.jpg) (r) file /DCTDecode filter % opens the file and filters the image data
+% {currentfile picstr readhexstring pop}
+{<"
+     (mapconcat (lambda (ch) (format "%02x" ch)) data "")
+">}
+/DCTDecode filter
+false               % pull channels from separate sources
+3                   % 3 color channels (RGB)
+colorimage
+
+grestore
+w 0 rmoveto
+/LineHeight h def
+"
+                 ))))
    (t					; otherwise, text has a valid face
     (let* ((face-bit   (ps-face-attribute-list face))
 	   (effect     (aref face-bit 0))
 	   (foreground (aref face-bit 1))
 	   (background (ps-face-background face (aref face-bit 2)))
+	   (size       nil)
+           (family     nil)
+           (same       nil)
+           (font (ps-font-number 'ps-font-for-text
+		                 (or (aref ps-font-type (logand effect 3))
+			             face)))
 	   (fg-color (if (and ps-color-p foreground)
 			 (ps-color-scale foreground)
 		       ps-default-color))
 	   (bg-color (and ps-color-p background
 			  (ps-color-scale background))))
+      (unless (eobp)
+        (setq family (intern (ps-font-name (font-at (point))))
+              size (font-get (font-at (point)) :size)
+              same (and (eq family ps-font-family)
+                        (= size ps-font-size-internal)))
+
+        (if same
+            (or (and ps-last-font (equal font ps-current-font))
+                (ps-set-font font))
+          (ps-change-font family size)))
       (ps-plot-region
        from to
        (ps-font-number 'ps-font-for-text
@@ -6312,7 +6550,8 @@ ps-map-face
 	(let ((face-bit (cdr face-map)))
 	  (aset ps-face-bit 0 (logior (aref ps-face-bit 0) (aref face-bit 0)))
 	  (or (aref ps-face-bit 1) (aset ps-face-bit 1 (aref face-bit 1)))
-	  (or (aref ps-face-bit 2) (aset ps-face-bit 2 (aref face-bit 2))))
+	  (or (aref ps-face-bit 2) (aset ps-face-bit 2 (aref face-bit 2)))
+          (or (aref ps-face-bit 3) (aset ps-face-bit 3 (aref face-bit 3))))
       ;; if face does not exist, insert it
       (setq ps-print-face-alist (cons face-map ps-print-face-alist)))
     face-map))
@@ -6327,7 +6566,10 @@ ps-screen-to-bit-face
 			(if (ps-face-overline-p face)  16 0)  ; overline
 			(if (ps-face-box-p face)       64 0)) ; box
 		(ps-face-foreground-name face)
-		(ps-face-background-name face))))
+		(ps-face-background-name face)
+                (face-attribute-specified-or
+                 (face-attribute face :height)
+		 nil))))
 
 
 (declare-function jit-lock-fontify-now "jit-lock" (&optional start end))
@@ -6410,13 +6652,14 @@ ps-generate
 		    (ps-begin-job genfunc)
 		    (when needs-begin-file
 		      (ps-begin-file)
-		      (ps-mule-initialize))
-		    (ps-mule-begin-job from to)
+		      ;; (ps-mule-initialize)
+                      )
+		    ;; (ps-mule-begin-job from to)
 		    (ps-selected-pages)))
 		(ps-begin-page)
 		(funcall genfunc from to)
 		(ps-end-page)
-		(ps-mule-end-job)
+		;; (ps-mule-end-job)
 		(ps-end-job needs-begin-file)
 
 		;; Setting this variable tells the unwind form that the

[-- Attachment #3: psname.txt --]
[-- Type: text/plain, Size: 3476 bytes --]

diff --git a/src/font.c b/src/font.c
index 0c9e752e08..2031cc8eca 100644
--- a/src/font.c
+++ b/src/font.c
@@ -665,6 +665,7 @@ font_prop_validate_otf (Lisp_Object prop, Lisp_Object val)
     /* The order of the above entries must match with enum
        font_property_index.  */
     { SYMBOL_INDEX (QClang), font_prop_validate_symbol },
+    { SYMBOL_INDEX (QCpostscriptname), font_prop_validate_symbol },
     { SYMBOL_INDEX (QCscript), font_prop_validate_symbol },
     { SYMBOL_INDEX (QCotf), font_prop_validate_otf }
   };
@@ -4129,6 +4130,10 @@ DEFUN ("font-get", Ffont_get, Sfont_get, 2, 2, 0,
 	  if (fontp->driver->combining_capability)
 	    val = fontp->driver->combining_capability (fontp);
 	}
+      else if (EQ (key, QCpostscriptname)) {
+	  if (fontp->driver->postscriptname)
+	    val = fontp->driver->postscriptname (fontp);
+      }
     }
   else
     val = Fcdr (val);
@@ -5376,6 +5381,7 @@ syms_of_font (void)
   DEFSYM (QCavgwidth, ":avgwidth");
   DEFSYM (QCfont_entity, ":font-entity");
   DEFSYM (QCcombining_capability, ":combining-capability");
+  DEFSYM (QCpostscriptname, ":postscriptname");
 
   /* Symbols representing values of font spacing property.  */
   DEFSYM (Qc, "c");
diff --git a/src/font.h b/src/font.h
index 8614e7fa10..5e15ef4457 100644
--- a/src/font.h
+++ b/src/font.h
@@ -692,6 +692,7 @@ #define FONT_INVALID_CODE 0xFFFFFFFF
      GSUB and GPOS are lists of the form
      ((SCRIPT (LANGSYS FEATURE ...) ...) ...)  */
   Lisp_Object (*otf_capability) (struct font *font);
+  Lisp_Object (*postscriptname) (struct font *font);
 
   /* Optional.
      Apply FONT's OTF-FEATURES to the glyph string.
@@ -893,6 +894,7 @@ valid_font_driver (struct font_driver const *d)
 
 #ifdef HAVE_HARFBUZZ
 extern Lisp_Object hbfont_otf_capability (struct font *);
+extern Lisp_Object hbfont_postscriptname (struct font *);
 extern Lisp_Object hbfont_shape (Lisp_Object, Lisp_Object);
 extern Lisp_Object hbfont_combining_capability (struct font *);
 #endif
diff --git a/src/ftcrfont.c b/src/ftcrfont.c
index a0e18e13cf..365671b036 100644
--- a/src/ftcrfont.c
+++ b/src/ftcrfont.c
@@ -621,6 +621,7 @@ syms_of_ftcrfont_for_pdumper (void)
   ftcrhbfont_driver.list = ftcrhbfont_list;
   ftcrhbfont_driver.match = ftcrhbfont_match;
   ftcrhbfont_driver.otf_capability = hbfont_otf_capability;
+  ftcrhbfont_driver.postscriptname = hbfont_postscriptname;
   ftcrhbfont_driver.shape = hbfont_shape;
   ftcrhbfont_driver.combining_capability = hbfont_combining_capability;
   ftcrhbfont_driver.begin_hb_font = ftcrhbfont_begin_hb_font;
diff --git a/src/hbfont.c b/src/hbfont.c
index 576c5fe7f6..7587d933cc 100644
--- a/src/hbfont.c
+++ b/src/hbfont.c
@@ -212,6 +212,31 @@ hbfont_otf_features (hb_face_t *face, hb_tag_t table_tag)
   return scripts;
 }
 
+Lisp_Object
+hbfont_postscriptname (struct font *font)
+{
+  double position_unit;
+  hb_font_t *hb_font
+    = font->driver->begin_hb_font
+    ? font->driver->begin_hb_font (font, &position_unit)
+    : NULL;
+  if (!hb_font)
+    return Qnil;
+
+  hb_face_t *face = hb_font_get_face (hb_font);
+
+  // Postscript name
+  unsigned int text_size = 127;
+  char *text = xmalloc (text_size * sizeof (char));
+  hb_ot_name_get_utf8 (face, 6, NULL, &text_size, text);
+  Lisp_Object psname = make_unibyte_string (text, text_size);
+
+  if (font->driver->end_hb_font)
+    font->driver->end_hb_font (font, hb_font);
+
+  return psname;
+}
+
 Lisp_Object
 hbfont_otf_capability (struct font *font)
 {

^ permalink raw reply related	[flat|nested] 13+ messages in thread

* Re: [Patch] Basic WYSIWYG printing in GNU Emacs
  2021-08-10  9:29 [Patch] Basic WYSIWYG printing in GNU Emacs Anand Tamariya
@ 2021-08-10 12:31 ` Eli Zaretskii
  2021-08-10 18:12   ` Pankaj Jangid
  2021-08-11  4:32   ` Anand Tamariya
  0 siblings, 2 replies; 13+ messages in thread
From: Eli Zaretskii @ 2021-08-10 12:31 UTC (permalink / raw)
  To: Anand Tamariya; +Cc: emacs-devel

> From: Anand Tamariya <atamariya@gmail.com>
> Date: Tue, 10 Aug 2021 14:59:46 +0530
> 
> Here's a patch for basic WYSIWYG printing in GNU Emacs. This should enable following print  features in
> Emacs:
> 
> * Size and colour variation in text
> * Unicode text (including Hindi, script for Eastern European
>  languages, logographic scripts like Chinese, Japanese and Korean (CJK), right to left (RTL) scripts like
>  Arabic and Hebrew, and music symbols)
> * Fancy fonts
> * Tables
> * Images
> * Zero font setup (Tip: Use Truetype fonts in your system)

Thanks, but can you tell a few words about the prerequisites and
limitations?  For example, it sounds like this requires a Cairo build
and the use of the ftcrhb font backend -- is this a requirement, or
should it be possible to make it work with other font backends as
well?  Also, are there any assumptions or requirements regarding the
fonts installed on the system?



^ permalink raw reply	[flat|nested] 13+ messages in thread

* Re: [Patch] Basic WYSIWYG printing in GNU Emacs
  2021-08-10 12:31 ` Eli Zaretskii
@ 2021-08-10 18:12   ` Pankaj Jangid
  2021-08-11  3:39     ` Anand Tamariya
  2021-08-11  4:32   ` Anand Tamariya
  1 sibling, 1 reply; 13+ messages in thread
From: Pankaj Jangid @ 2021-08-10 18:12 UTC (permalink / raw)
  To: Eli Zaretskii; +Cc: emacs-devel, Anand Tamariya

Eli Zaretskii <eliz@gnu.org> writes:

>> From: Anand Tamariya <atamariya@gmail.com>
>> Date: Tue, 10 Aug 2021 14:59:46 +0530
>> 
>> Here's a patch for basic WYSIWYG printing in GNU Emacs.

> Thanks, but can you tell a few words about the prerequisites and
> limitations?  For example, it sounds like this requires a Cairo build
> and the use of the ftcrhb font backend -- is this a requirement, or
> should it be possible to make it work with other font backends as
> well?  Also, are there any assumptions or requirements regarding the
> fonts installed on the system?

Thanks Anand, for this work. I am interested in knowing if there are any
OS specific requirements for this to work.



^ permalink raw reply	[flat|nested] 13+ messages in thread

* Re: [Patch] Basic WYSIWYG printing in GNU Emacs
  2021-08-10 18:12   ` Pankaj Jangid
@ 2021-08-11  3:39     ` Anand Tamariya
  0 siblings, 0 replies; 13+ messages in thread
From: Anand Tamariya @ 2021-08-11  3:39 UTC (permalink / raw)
  To: Eli Zaretskii, Anand Tamariya, emacs-devel

[-- Attachment #1: Type: text/plain, Size: 237 bytes --]

> Thanks Anand, for this work. I am interested in knowing if there are any
> OS specific requirements for this to work.
>
Emacs uses Ghostscript for printing infrastructure. So if your OS supports
Ghostview or a clone, this should work.

[-- Attachment #2: Type: text/html, Size: 445 bytes --]

^ permalink raw reply	[flat|nested] 13+ messages in thread

* Re: [Patch] Basic WYSIWYG printing in GNU Emacs
  2021-08-10 12:31 ` Eli Zaretskii
  2021-08-10 18:12   ` Pankaj Jangid
@ 2021-08-11  4:32   ` Anand Tamariya
  2021-08-11 11:41     ` Eli Zaretskii
  1 sibling, 1 reply; 13+ messages in thread
From: Anand Tamariya @ 2021-08-11  4:32 UTC (permalink / raw)
  To: Eli Zaretskii; +Cc: emacs-devel

[-- Attachment #1: Type: text/plain, Size: 1023 bytes --]

> Thanks, but can you tell a few words about the prerequisites and
> limitations?  For example, it sounds like this requires a Cairo build
> and the use of the ftcrhb font backend -- is this a requirement, or
> should it be possible to make it work with other font backends as
> well?  Also, are there any assumptions or requirements regarding the
> fonts installed on the system?
>
Printers use "postscriptname" defined in a font file while searching for
fonts. psname.txt provides a sample of how to read that information from a
font backend. It is not mandatory - but its presence will prevent nasty
surprises. In its absence, Lisp code uses font file base name. If the file
name doesn't match postscriptname, printing might fail - "might" because
printer will try its best to substitute a suitable font.
Theoretically, there's no dependency except Ghostscript which does most of
the heavy lifting for printing in Emacs. Fonts other than Truetype might
require additional configuration as defined in Ghostscript manual.

[-- Attachment #2: Type: text/html, Size: 1285 bytes --]

^ permalink raw reply	[flat|nested] 13+ messages in thread

* Re: [Patch] Basic WYSIWYG printing in GNU Emacs
  2021-08-11  4:32   ` Anand Tamariya
@ 2021-08-11 11:41     ` Eli Zaretskii
  2021-08-11 15:49       ` Anand Tamariya
  0 siblings, 1 reply; 13+ messages in thread
From: Eli Zaretskii @ 2021-08-11 11:41 UTC (permalink / raw)
  To: Anand Tamariya; +Cc: emacs-devel

> From: Anand Tamariya <atamariya@gmail.com>
> Date: Wed, 11 Aug 2021 10:02:03 +0530
> Cc: emacs-devel@gnu.org
> 
> Printers use "postscriptname" defined in a font file while searching for fonts. psname.txt provides a sample
> of how to read that information from a font backend. It is not mandatory - but its presence will prevent nasty
> surprises. In its absence, Lisp code uses font file base name. If the file name doesn't match
> postscriptname, printing might fail - "might" because printer will try its best to substitute a suitable font.
> Theoretically, there's no dependency except Ghostscript which does most of the heavy lifting for printing in
> Emacs. Fonts other than Truetype might require additional configuration as defined in Ghostscript manual.

Could you please point to the code which uses or requires Ghostscript,
I don't think I see it in the patch you sent.  And since you seem to
be using the HarfBuzz rendering, why do we need Ghostscript at all?

Thanks.



^ permalink raw reply	[flat|nested] 13+ messages in thread

* Re: [Patch] Basic WYSIWYG printing in GNU Emacs
  2021-08-11 11:41     ` Eli Zaretskii
@ 2021-08-11 15:49       ` Anand Tamariya
  2021-08-11 16:51         ` Eli Zaretskii
  0 siblings, 1 reply; 13+ messages in thread
From: Anand Tamariya @ 2021-08-11 15:49 UTC (permalink / raw)
  To: Eli Zaretskii; +Cc: emacs-devel

[-- Attachment #1: Type: text/plain, Size: 1257 bytes --]

On Wed, Aug 11, 2021 at 5:11 PM Eli Zaretskii <eliz@gnu.org> wrote:

> > From: Anand Tamariya <atamariya@gmail.com>
> > Date: Wed, 11 Aug 2021 10:02:03 +0530
> > Cc: emacs-devel@gnu.org
> >
> > Printers use "postscriptname" defined in a font file while searching for
> fonts. psname.txt provides a sample
> > of how to read that information from a font backend. It is not mandatory
> - but its presence will prevent nasty
> > surprises. In its absence, Lisp code uses font file base name. If the
> file name doesn't match
> > postscriptname, printing might fail - "might" because printer will try
> its best to substitute a suitable font.
> > Theoretically, there's no dependency except Ghostscript which does most
> of the heavy lifting for printing in
> > Emacs. Fonts other than Truetype might require additional configuration
> as defined in Ghostscript manual.
>
> Could you please point to the code which uses or requires Ghostscript,
> I don't think I see it in the patch you sent.  And since you seem to
> be using the HarfBuzz rendering, why do we need Ghostscript at all?
>
> Thanks.
>
Correction is in order - the screenshot/ rendering within Emacs requires
Ghostscript. Printing to printer would use OS specific print commands e.g.
lpr on *nix.

[-- Attachment #2: Type: text/html, Size: 1788 bytes --]

^ permalink raw reply	[flat|nested] 13+ messages in thread

* Re: [Patch] Basic WYSIWYG printing in GNU Emacs
  2021-08-11 15:49       ` Anand Tamariya
@ 2021-08-11 16:51         ` Eli Zaretskii
  2021-08-11 16:58           ` Eli Zaretskii
  2021-08-12  5:34           ` Anand Tamariya
  0 siblings, 2 replies; 13+ messages in thread
From: Eli Zaretskii @ 2021-08-11 16:51 UTC (permalink / raw)
  To: Anand Tamariya; +Cc: emacs-devel

> From: Anand Tamariya <atamariya@gmail.com>
> Date: Wed, 11 Aug 2021 21:19:14 +0530
> Cc: emacs-devel@gnu.org
> 
>  > Theoretically, there's no dependency except Ghostscript which does most of the heavy lifting for
>  printing in
>  > Emacs. Fonts other than Truetype might require additional configuration as defined in Ghostscript
>  manual.
> 
>  Could you please point to the code which uses or requires Ghostscript,
>  I don't think I see it in the patch you sent.  And since you seem to
>  be using the HarfBuzz rendering, why do we need Ghostscript at all?
> 
>  Thanks.
> 
> Correction is in order - the screenshot/ rendering within Emacs requires Ghostscript. Printing to printer
> would use OS specific print commands e.g. lpr on *nix.

Now I'm even more confused.  How does one "render within Emacs with
Ghostscript"?  Emacs display rendering uses our display engine, which
doesn't need Ghostscript, and AFAIK cannot use it.  I guess I'm
misunderstanding something very basic here...



^ permalink raw reply	[flat|nested] 13+ messages in thread

* Re: [Patch] Basic WYSIWYG printing in GNU Emacs
  2021-08-11 16:51         ` Eli Zaretskii
@ 2021-08-11 16:58           ` Eli Zaretskii
  2021-08-12  5:34           ` Anand Tamariya
  1 sibling, 0 replies; 13+ messages in thread
From: Eli Zaretskii @ 2021-08-11 16:58 UTC (permalink / raw)
  To: atamariya; +Cc: emacs-devel

> Date: Wed, 11 Aug 2021 19:51:46 +0300
> From: Eli Zaretskii <eliz@gnu.org>
> Cc: emacs-devel@gnu.org
> 
> > From: Anand Tamariya <atamariya@gmail.com>
> > Date: Wed, 11 Aug 2021 21:19:14 +0530
> > Cc: emacs-devel@gnu.org
> > 
> >  > Theoretically, there's no dependency except Ghostscript which does most of the heavy lifting for
> >  printing in
> >  > Emacs. Fonts other than Truetype might require additional configuration as defined in Ghostscript
> >  manual.
> > 
> >  Could you please point to the code which uses or requires Ghostscript,
> >  I don't think I see it in the patch you sent.  And since you seem to
> >  be using the HarfBuzz rendering, why do we need Ghostscript at all?
> > 
> >  Thanks.
> > 
> > Correction is in order - the screenshot/ rendering within Emacs requires Ghostscript. Printing to printer
> > would use OS specific print commands e.g. lpr on *nix.
> 
> Now I'm even more confused.  How does one "render within Emacs with
> Ghostscript"?  Emacs display rendering uses our display engine, which
> doesn't need Ghostscript, and AFAIK cannot use it.  I guess I'm
> misunderstanding something very basic here...

To make sure I'm not too confused: you are talking about the code
which you posted here in the form of two patches, right?  Because
that's the only code I looked at, so if you are talking about some
other code, I can easily understand why I'm confused.



^ permalink raw reply	[flat|nested] 13+ messages in thread

* Re: [Patch] Basic WYSIWYG printing in GNU Emacs
  2021-08-11 16:51         ` Eli Zaretskii
  2021-08-11 16:58           ` Eli Zaretskii
@ 2021-08-12  5:34           ` Anand Tamariya
  2021-08-12  6:11             ` Eli Zaretskii
  1 sibling, 1 reply; 13+ messages in thread
From: Anand Tamariya @ 2021-08-12  5:34 UTC (permalink / raw)
  To: Eli Zaretskii; +Cc: emacs-devel

[-- Attachment #1: Type: text/plain, Size: 664 bytes --]

> > Correction is in order - the screenshot/ rendering within Emacs requires
> Ghostscript. Printing to printer
> > would use OS specific print commands e.g. lpr on *nix.
>
> Now I'm even more confused.  How does one "render within Emacs with
> Ghostscript"?  Emacs display rendering uses our display engine, which
> doesn't need Ghostscript, and AFAIK cannot use it.  I guess I'm
> misunderstanding something very basic here...
>
The screenshots linked in OP shows split windows - one with original text
and another with PS file. The PS file section is actually a PNG image
generated with Ghostscript from the PS file. The PS file itself is
generated by my code.

[-- Attachment #2: Type: text/html, Size: 920 bytes --]

^ permalink raw reply	[flat|nested] 13+ messages in thread

* Re: [Patch] Basic WYSIWYG printing in GNU Emacs
  2021-08-12  5:34           ` Anand Tamariya
@ 2021-08-12  6:11             ` Eli Zaretskii
  2021-08-12  6:45               ` Anand Tamariya
  0 siblings, 1 reply; 13+ messages in thread
From: Eli Zaretskii @ 2021-08-12  6:11 UTC (permalink / raw)
  To: Anand Tamariya; +Cc: emacs-devel

> From: Anand Tamariya <atamariya@gmail.com>
> Date: Thu, 12 Aug 2021 11:04:39 +0530
> Cc: emacs-devel@gnu.org
> 
>  > Correction is in order - the screenshot/ rendering within Emacs requires Ghostscript. Printing to
>  printer
>  > would use OS specific print commands e.g. lpr on *nix.
> 
>  Now I'm even more confused.  How does one "render within Emacs with
>  Ghostscript"?  Emacs display rendering uses our display engine, which
>  doesn't need Ghostscript, and AFAIK cannot use it.  I guess I'm
>  misunderstanding something very basic here...
> 
> The screenshots linked in OP shows split windows - one with original text and another with PS file. The PS
> file section is actually a PNG image generated with Ghostscript from the PS file. The PS file itself is
> generated by my code. 

OK, that takes care of my confusion, thanks.

But the original question still stands: where do you make use of
Ghostscript in your code which generates the PS file?  Or maybe you
don't use Ghostscript for that (which would be good news), and I just
misunderstood you did?  IOW, is Ghostscript a prerequisite for using
your WYSIWYG printing code to produce the PS stuff (as opposed to
sending the PS to the printer)?



^ permalink raw reply	[flat|nested] 13+ messages in thread

* Re: [Patch] Basic WYSIWYG printing in GNU Emacs
  2021-08-12  6:11             ` Eli Zaretskii
@ 2021-08-12  6:45               ` Anand Tamariya
  2021-08-12  8:08                 ` Eli Zaretskii
  0 siblings, 1 reply; 13+ messages in thread
From: Anand Tamariya @ 2021-08-12  6:45 UTC (permalink / raw)
  To: Eli Zaretskii; +Cc: emacs-devel

[-- Attachment #1: Type: text/plain, Size: 1571 bytes --]

On Thu, Aug 12, 2021 at 11:41 AM Eli Zaretskii <eliz@gnu.org> wrote:

> > From: Anand Tamariya <atamariya@gmail.com>
> > Date: Thu, 12 Aug 2021 11:04:39 +0530
> > Cc: emacs-devel@gnu.org
> >
> >  > Correction is in order - the screenshot/ rendering within Emacs
> requires Ghostscript. Printing to
> >  printer
> >  > would use OS specific print commands e.g. lpr on *nix.
> >
> >  Now I'm even more confused.  How does one "render within Emacs with
> >  Ghostscript"?  Emacs display rendering uses our display engine, which
> >  doesn't need Ghostscript, and AFAIK cannot use it.  I guess I'm
> >  misunderstanding something very basic here...
> >
> > The screenshots linked in OP shows split windows - one with original
> text and another with PS file. The PS
> > file section is actually a PNG image generated with Ghostscript from the
> PS file. The PS file itself is
> > generated by my code.
>
> OK, that takes care of my confusion, thanks.
>
> But the original question still stands: where do you make use of
> Ghostscript in your code which generates the PS file?

I don't.

>   Or maybe you
> don't use Ghostscript for that (which would be good news), and I just
> misunderstood you did?  IOW, is Ghostscript a prerequisite for using
> your WYSIWYG printing code to produce the PS stuff (as opposed to
> sending the PS to the printer)?
>
It's not. It is only required if one wants to visualize (print preview) it
within Emacs. Of course, for development and testing, it's irreplaceable
unless you want to waste reams of paper. Hence, I count it as a dependency.

[-- Attachment #2: Type: text/html, Size: 2323 bytes --]

^ permalink raw reply	[flat|nested] 13+ messages in thread

* Re: [Patch] Basic WYSIWYG printing in GNU Emacs
  2021-08-12  6:45               ` Anand Tamariya
@ 2021-08-12  8:08                 ` Eli Zaretskii
  0 siblings, 0 replies; 13+ messages in thread
From: Eli Zaretskii @ 2021-08-12  8:08 UTC (permalink / raw)
  To: Anand Tamariya; +Cc: emacs-devel

> From: Anand Tamariya <atamariya@gmail.com>
> Date: Thu, 12 Aug 2021 12:15:53 +0530
> Cc: emacs-devel@gnu.org
> 
>  But the original question still stands: where do you make use of
>  Ghostscript in your code which generates the PS file?
> 
> I don't. 
> 
>    Or maybe you
>  don't use Ghostscript for that (which would be good news), and I just
>  misunderstood you did?  IOW, is Ghostscript a prerequisite for using
>  your WYSIWYG printing code to produce the PS stuff (as opposed to
>  sending the PS to the printer)?
> 
> It's not. It is only required if one wants to visualize (print preview) it within Emacs. Of course, for
> development and testing, it's irreplaceable unless you want to waste reams of paper. Hence, I count it as a
> dependency.

Thanks, and sorry for my confusion about this aspect.



^ permalink raw reply	[flat|nested] 13+ messages in thread

end of thread, other threads:[~2021-08-12  8:08 UTC | newest]

Thread overview: 13+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2021-08-10  9:29 [Patch] Basic WYSIWYG printing in GNU Emacs Anand Tamariya
2021-08-10 12:31 ` Eli Zaretskii
2021-08-10 18:12   ` Pankaj Jangid
2021-08-11  3:39     ` Anand Tamariya
2021-08-11  4:32   ` Anand Tamariya
2021-08-11 11:41     ` Eli Zaretskii
2021-08-11 15:49       ` Anand Tamariya
2021-08-11 16:51         ` Eli Zaretskii
2021-08-11 16:58           ` Eli Zaretskii
2021-08-12  5:34           ` Anand Tamariya
2021-08-12  6:11             ` Eli Zaretskii
2021-08-12  6:45               ` Anand Tamariya
2021-08-12  8:08                 ` Eli Zaretskii

Code repositories for project(s) associated with this public inbox

	https://git.savannah.gnu.org/cgit/emacs.git

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).