--- ox-ascii.el.org	2021-03-26 09:28:44.000000000 +0900
+++ ox-ascii.el	2021-05-09 17:23:40.421912931 +0900
@@ -440,8 +440,11 @@
 ;; `org-ascii--describe-links' creates notes about links for
 ;; insertion at the end of a section.  It uses
 ;; `org-ascii--unique-links' to get the list of links to describe.
-;; Eventually, `org-ascii--translate' translates a string according
+;; `org-ascii--translate' translates a string according
 ;; to language and charset specification.
+;; `org-ascii--make-string' provides pixel width based `make-string' for
+;; better text alignment, by using `org-ascii--pixel-width' which returns
+;; actual pixel width of characters and strings.
 
 
 (defun org-ascii--fill-string (s text-width info &optional justify)
@@ -481,9 +484,19 @@
     (let ((fill-column text-width)
 	  ;; Disable `adaptive-fill-mode' so it doesn't prevent
 	  ;; filling lines matching `adaptive-fill-regexp'.
-	  (adaptive-fill-mode nil))
+	  (adaptive-fill-mode nil)
+          linestr pwidth)
       (while (< (point) (point-max))
-	(justify-current-line how)
+        (setq linestr (buffer-substring (point) (line-end-position))
+              pwidth (max (- (* (org-ascii--pixel-width ?\s) text-width)
+                             (org-ascii--pixel-width linestr))
+                          0))
+        (insert (org-ascii--make-string (pcase how
+                                          (`left 0)
+                                          (`center (/ pwidth 2))
+                                          (`right pwidth))
+                                        ?\s 0 (- text-width
+                                                 (string-width linestr))))
 	(forward-line)))
     (buffer-string)))
 
@@ -697,9 +710,8 @@
 			      (plist-get info :ascii-underline))))))
 	 (and under-char
 	      (concat "\n"
-		      (make-string (/ (string-width first-part)
-				      (char-width under-char))
-				   under-char))))))))
+		      (org-ascii--make-string
+                       (org-ascii--pixel-width first-part) under-char))))))))
 
 (defun org-ascii--has-caption-p (element _info)
   "Non-nil when ELEMENT has a caption affiliated keyword.
@@ -750,9 +762,9 @@
    (unless scope
      (let ((title (org-ascii--translate "Table of Contents" info)))
        (concat title "\n"
-	       (make-string
-		(string-width title)
-		(if (eq (plist-get info :ascii-charset) 'utf-8) ?─ ?_))
+               (org-ascii--make-string
+                (org-ascii--pixel-width title)
+                (if (eq (plist-get info :ascii-charset) 'utf-8) ?─ ?_))
 	       "\n\n")))
    (let ((text-width
 	  (if keyword (org-ascii--current-text-width keyword info)
@@ -779,8 +791,9 @@
   (let ((title (org-ascii--translate "List of Listings" info)))
     (concat
      title "\n"
-     (make-string (string-width title)
-		  (if (eq (plist-get info :ascii-charset) 'utf-8) ?─ ?_))
+     (org-ascii--make-string
+      (org-ascii--pixel-width title)
+      (if (eq (plist-get info :ascii-charset) 'utf-8) ?─ ?_))
      "\n\n"
      (let ((text-width
 	    (if keyword (org-ascii--current-text-width keyword info)
@@ -819,8 +832,9 @@
   (let ((title (org-ascii--translate "List of Tables" info)))
     (concat
      title "\n"
-     (make-string (string-width title)
-		  (if (eq (plist-get info :ascii-charset) 'utf-8) ?─ ?_))
+     (org-ascii--make-string
+      (org-ascii--pixel-width title)
+      (if (eq (plist-get info :ascii-charset) 'utf-8) ?─ ?_))
      "\n\n"
      (let ((text-width
 	    (if keyword (org-ascii--current-text-width keyword info)
@@ -1033,7 +1047,7 @@
 	     ;; Format TITLE.  It may be filled if it is too wide,
 	     ;; that is wider than the two thirds of the total width.
 	     (title-len (min (apply #'max
-				    (mapcar #'length
+				    (mapcar #'string-width
 					    (org-split-string
 					     (concat title "\n" subtitle) "\n")))
 			     (/ (* 2 text-width) 3)))
@@ -1041,12 +1055,19 @@
 	     (formatted-subtitle (when (org-string-nw-p subtitle)
 				   (org-ascii--fill-string subtitle title-len info)))
 	     (line
-	      (make-string
-	       (min (+ (max title-len
-			    (string-width (or author ""))
-			    (string-width (or email "")))
-		       2)
-		    text-width) (if utf8p ?━ ?_))))
+              (org-ascii--make-string
+               (apply #'max
+                      (mapcar #'org-ascii--pixel-width
+	                      (org-split-string
+		               (concat formatted-title "\n"
+                                       formatted-subtitle "\n"
+                                       (if author (concat author "\n") "")
+                                       (if email (concat email "\n") ""))
+                               "\n")))
+               (if utf8p ?━ ?_)
+               2 text-width)))
+        (message "%s" line)
+        (message "%s" formatted-title)
 	(org-ascii--justify-lines
 	 (concat line "\n"
 		 (unless utf8p "\n")
@@ -1082,9 +1103,9 @@
 	    (let ((title (org-ascii--translate "Footnotes" info)))
 	      (concat
 	       title "\n"
-	       (make-string
-		(string-width title)
-		(if (eq (plist-get info :ascii-charset) 'utf-8) ?─ ?_))))
+               (org-ascii--make-string
+                (org-ascii--pixel-width title)
+                (if (eq (plist-get info :ascii-charset) 'utf-8) ?─ ?_))))
 	    "\n\n"
 	    (let ((text-width (- (plist-get info :ascii-text-width)
 				 global-margin)))
@@ -1150,6 +1171,29 @@
   (let ((charset (intern (format ":%s" (plist-get info :ascii-charset)))))
     (org-export-translate s charset info)))
 
+(defun org-ascii--make-string (pwidth init &optional adjust limit)
+  "Return a newly created string of width PWIDTH, with INIT in each element.
+PWIDTH is in pixel and the actual width is a minimum longer than
+PWIDTH, unless either ADJUST or LIMIT is specified.  ADJUST is
+the number of characters added or removed from the string if the
+value is positive or negative integer.  LIMIT is the maximum
+allowed number of characters of the string."
+  (let* ((init-pwidth (org-ascii--pixel-width init))
+         (width (/ (+ pwidth (1- init-pwidth)) init-pwidth)))
+    (if (integerp adjust) (setq width (+ width adjust)))
+    (if (integerp limit) (setq width (min width (max limit 0))))
+    (make-string width init)))
+
+(defun org-ascii--pixel-width (obj)
+  "Return OBJ pixel width in display.
+OBJ is supposed to be a character or a string.  Returned pixel
+width is based on frame default font."
+  (with-temp-buffer
+    (insert obj)
+    (switch-to-buffer (current-buffer))
+    (car (window-text-pixel-size
+          nil 1 (1+ (if (sequencep obj) (length obj) 1))))))
+
 
 
 ;;; Transcode Functions
@@ -1960,7 +2004,9 @@
 					'identity info t)
 				      cell))
 			 lcorner)
-		       (make-string (+ 2 width) (string-to-char horiz))
+                       (org-ascii--make-string
+                        (* (+ 2 width) (org-ascii--pixel-width ?\s))
+                        (string-to-char horiz))
 		       (cond
 			((not (memq 'right borders)) nil)
 			((eq (car (last (org-element-contents table-row))) cell)
