Subject: 23.2; Mac OS X Dual Spacing Fonts Fix (Patch supplied)

From: Dragan Ivanovic <[email-masked]>
Date: Tue, 25 Jan 2011 12:14:01 +0100 (CET)

This bug report will be sent to the Free Software Foundation,
not to your local site managers!
Please write in English if possible, because the Emacs maintainers
usually do not have translators to read other languages for them.

Your bug report will be posted to the [email-masked] mailing list,
and to the gnu.emacs.bug news group.

Please describe exactly what actions triggered the bug
and the precise symptoms of the bug.  If you can, give
a recipe starting from `emacs -Q':

% ------------------------------------------------------------------

Emacs (v23.2 distro in my case) has a known problem with determining
pixel width of frames when using dual-space (Japanese) fonts.  It
arises because the maximum pixel width of characters in those fonts is
way bigger than (usually double the size of) the printable ASCII
characters.  Therefore, windows open twice as wide, and the
intelligent line wrapping (as in man or Mew, my favorite email reader)
gets the metrics wrong and forces the text to be wrapped to about one
third of the frame width.

Patches for X-Windows versions are known, and can be found on Ubuntu
mailing lists.  The same problem appears on NextSTEP, i.e., Mac OS
X/Cocoa version.  Below is the patch that solves the problem:

% ..................................................................

--- nsfont-old.m	2011-01-18 13:36:39.000000000 +0100
+++ nsfont.m	2011-01-18 13:36:17.000000000 +0100
@@ -885,9 +885,29 @@ nsfont_open (FRAME_PTR f, Lisp_Object fo
     font->ascent = lrint([sfont ascender]);
     font->descent = -lrint(floor([sfont descender]));
     font->min_width = ns_char_width(sfont, '|');
-    font->space_width = lrint (ns_char_width (sfont, ' '));
-    font->average_width = lrint (font_info->width);
-    font->max_width = lrint (font_info->max_bounds.width);
+    if([nsfont isFixedPitch]) {
+      /* This is a "dirty" fix to avoid problem with some (mostly
+	 Japanese) fonts that use dual spacing. Unlike in the patches
+	 to "ftfont.c" and "xftfont.c", in Cocoa we cannot rely on a
+	 flag (FC_DUAL) to tell us if a fixed width font uses dual
+	 spacing or not.
+
+	 To avoid some problems with spaces (e.g. inside the vebatim
+	 LaTeX environment when using AUCTeX), we measure the width of
+	 a "regular" character, e.g. M (the size of em-space). */
+      font->space_width = lrint (ns_char_width (sfont, 'M'));
+      /* We assume it is the average width. */
+      font->average_width = font->space_width;
+      /* We also assume it is the maximal width.  This may possibly
+	 cause some side effects, but I am not aware of any right
+	 now. */
+      font->max_width = font->space_width;
+    } else {
+      /* This is the normal v23.2 code */
+      font->space_width = lrint (ns_char_width (sfont, ' '));
+      font->average_width = lrint (font_info->width);
+      font->max_width = lrint (font_info->max_bounds.width);
+    }
     font->height = lrint (font_info->height);
     font->underline_position = lrint (font_info->underpos);
     font->underline_thickness = lrint (font_info->underwidth);

% ..................................................................

Best regards,

Dragan Ivanovic

% ------------------------------------------------------------------

If Emacs crashed, and you have the Emacs process in the gdb debugger,
please include the output from the following gdb commands:
    `bt full' and `xbacktrace'.
For information about debugging Emacs, please read the file
/Applications/Emacs.app/Contents/Resources/etc/DEBUG.

In GNU Emacs 23.2.1 (i386-apple-darwin10.6.0, NS apple-appkit-1038.35)
 of 2011-01-18 on dhcp-191.imdea
Windowing system distributor `Apple', version 10.3.1038
configured using `configure  '--with-ns''

Important settings:
  value of $LC_ALL: nil
  value of $LC_COLLATE: nil
  value of $LC_CTYPE: C
  value of $LC_MESSAGES: nil
  value of $LC_MONETARY: nil
  value of $LC_NUMERIC: nil
  value of $LC_TIME: nil
  value of $LANG: nil
  value of $XMODIFIERS: nil
  locale-coding-system: nil
  default enable-multibyte-characters: t

Major mode: Shell

Minor modes in effect:
  shell-dirtrack-mode: t
  diff-auto-refine-mode: t
  show-paren-mode: t
  global-hl-line-mode: t
  tooltip-mode: t
  mouse-wheel-mode: t
  menu-bar-mode: t
  file-name-shadow-mode: t
  global-font-lock-mode: t
  font-lock-mode: t
  blink-cursor-mode: t
  auto-encryption-mode: t
  auto-compression-mode: t
  column-number-mode: t
  line-number-mode: t
  transient-mark-mode: t

Recent input:
o <up> C-a C-y <up> <M-right> <up> C-a <M-right> C-e 
C-a <tab> <down> <down> <tab> <down> <tab> <up> <tab> 
<right> <tab> <tab> <tab> <tab> <down> <down> <down> 
<up> C-SPC <down> <down> C-w <up> <up> <return> C-x 
C-s <up> <up> <up> <up> <up> C-c C-t p <up> <up> <up> 
<up> <up> <up> <up> <up> <up> <down> <C-right> <C-left> 
<down> <down> <down> <down> <down> <down> <down> <down> 
<C-right> <C-right> <C-right> <backspace> <backspace> 
<backspace> <backspace> <backspace> <backspace> R - 
2 0 1 1 <up> <up> <up> <up> <up> <up> <up> <up> <up> 
<down> <C-left> <left> <left> <right> <right> <backspace> 
- <left> <left> <left> <left> <left> <S-left> C-_ <left> 
S C C . <backspace> 2 <backspace> - 2 0 1 0 <backspace> 
1 SPC C-a <right> <right> <right> C-c C-t p C-x C-s 
C-c a t <up> <up> <up> <up> <up> <up> <help-echo> <down-mouse-1> 
<mouse-1> t c N r N <up> <up> <up> <up> <up> <up> <down> 
<down> <down> <down> <down> <down> 4 r 4 0 0 r <help-echo> 
C-x 5 2 <help-echo> C-x C-f C-f ~ / i n s t / a c t 
i <tab> <return> <down> <down> <down> <down> <return> 
<down> <down> <down> <down> <down> <return> <down> 
<down> <down> <down> <down> <down> <down> <down> <down> 
<down> <down> <down> <down> <down> <down> <down> <down> 
<down> <down> <down> <down> <down> <down> <down> <down> 
<down> <down> <down> <down> <down> <down> <down> C-x 
k <return> <up> <up> <up> <up> <return> C-x k <return> 
<down> <down> <down> <down> <down> M-x e s h e l l 
<return> C-x k <return> M-x s h e l l <return> p w 
d <return> a n SPC <backspace> t SPC d e m o - s <backspace> 
<backspace> s <backspace> . s t a r t <return> <help-echo> 
M-x r e p o r <tab> b <tab> <return>

Recent messages:
Loading em-basic...done
Loading em-cmpl...done
Loading em-dirs...done
Loading em-glob...done
Loading em-hist...done
Loading em-ls...done
Loading em-prompt...done
Loading em-script...done
Loading em-term...done
Loading em-unix...done

Load-path shadows:
~/elisp/emacs-w3m/octet hides ~/elisp/octet
~/elisp/emacs-w3m/mime-w3m hides ~/elisp/mime-w3m
~/elisp/emacs-w3m/mew-w3m hides ~/elisp/mew-w3m
~/elisp/remember/remember hides /Applications/Emacs.app/Contents/Resources/lisp/textmodes/remember
~/elisp/org-mode/lisp/org hides /Applications/Emacs.app/Contents/Resources/lisp/org/org
~/elisp/org-mode/lisp/org-xoxo hides /Applications/Emacs.app/Contents/Resources/lisp/org/org-xoxo
~/elisp/org-mode/lisp/org-wl hides /Applications/Emacs.app/Contents/Resources/lisp/org/org-wl
~/elisp/org-mode/lisp/org-w3m hides /Applications/Emacs.app/Contents/Resources/lisp/org/org-w3m
~/elisp/org-mode/lisp/org-vm hides /Applications/Emacs.app/Contents/Resources/lisp/org/org-vm
~/elisp/org-mode/lisp/org-timer hides /Applications/Emacs.app/Contents/Resources/lisp/org/org-timer
~/elisp/org-mode/lisp/org-table hides /Applications/Emacs.app/Contents/Resources/lisp/org/org-table
~/elisp/org-mode/lisp/org-src hides /Applications/Emacs.app/Contents/Resources/lisp/org/org-src
~/elisp/org-mode/lisp/org-rmail hides /Applications/Emacs.app/Contents/Resources/lisp/org/org-rmail
~/elisp/org-mode/lisp/org-remember hides /Applications/Emacs.app/Contents/Resources/lisp/org/org-remember
~/elisp/org-mode/lisp/org-publish hides /Applications/Emacs.app/Contents/Resources/lisp/org/org-publish
~/elisp/org-mode/lisp/org-protocol hides /Applications/Emacs.app/Contents/Resources/lisp/org/org-protocol
~/elisp/org-mode/lisp/org-plot hides /Applications/Emacs.app/Contents/Resources/lisp/org/org-plot
~/elisp/org-mode/lisp/org-mouse hides /Applications/Emacs.app/Contents/Resources/lisp/org/org-mouse
~/elisp/org-mode/lisp/org-mobile hides /Applications/Emacs.app/Contents/Resources/lisp/org/org-mobile
~/elisp/org-mode/lisp/org-mhe hides /Applications/Emacs.app/Contents/Resources/lisp/org/org-mhe
~/elisp/org-mode/lisp/org-mew hides /Applications/Emacs.app/Contents/Resources/lisp/org/org-mew
~/elisp/org-mode/lisp/org-macs hides /Applications/Emacs.app/Contents/Resources/lisp/org/org-macs
~/elisp/org-mode/lisp/org-mac-message hides /Applications/Emacs.app/Contents/Resources/lisp/org/org-mac-message
~/elisp/org-mode/lisp/org-list hides /Applications/Emacs.app/Contents/Resources/lisp/org/org-list
~/elisp/org-mode/lisp/org-latex hides /Applications/Emacs.app/Contents/Resources/lisp/org/org-latex
~/elisp/org-mode/lisp/org-jsinfo hides /Applications/Emacs.app/Contents/Resources/lisp/org/org-jsinfo
~/elisp/org-mode/lisp/org-irc hides /Applications/Emacs.app/Contents/Resources/lisp/org/org-irc
~/elisp/org-mode/lisp/org-install hides /Applications/Emacs.app/Contents/Resources/lisp/org/org-install
~/elisp/org-mode/lisp/org-inlinetask hides /Applications/Emacs.app/Contents/Resources/lisp/org/org-inlinetask
~/elisp/org-mode/lisp/org-info hides /Applications/Emacs.app/Contents/Resources/lisp/org/org-info
~/elisp/org-mode/lisp/org-indent hides /Applications/Emacs.app/Contents/Resources/lisp/org/org-indent
~/elisp/org-mode/lisp/org-id hides /Applications/Emacs.app/Contents/Resources/lisp/org/org-id
~/elisp/org-mode/lisp/org-icalendar hides /Applications/Emacs.app/Contents/Resources/lisp/org/org-icalendar
~/elisp/org-mode/lisp/org-html hides /Applications/Emacs.app/Contents/Resources/lisp/org/org-html
~/elisp/org-mode/lisp/org-habit hides /Applications/Emacs.app/Contents/Resources/lisp/org/org-habit
~/elisp/org-mode/lisp/org-gnus hides /Applications/Emacs.app/Contents/Resources/lisp/org/org-gnus
~/elisp/org-mode/lisp/org-freemind hides /Applications/Emacs.app/Contents/Resources/lisp/org/org-freemind
~/elisp/org-mode/lisp/org-footnote hides /Applications/Emacs.app/Contents/Resources/lisp/org/org-footnote
~/elisp/org-mode/lisp/org-feed hides /Applications/Emacs.app/Contents/Resources/lisp/org/org-feed
~/elisp/org-mode/lisp/org-faces hides /Applications/Emacs.app/Contents/Resources/lisp/org/org-faces
~/elisp/org-mode/lisp/org-exp hides /Applications/Emacs.app/Contents/Resources/lisp/org/org-exp
~/elisp/org-mode/lisp/org-exp-blocks hides /Applications/Emacs.app/Contents/Resources/lisp/org/org-exp-blocks
~/elisp/org-mode/lisp/org-docbook hides /Applications/Emacs.app/Contents/Resources/lisp/org/org-docbook
~/elisp/org-mode/lisp/org-datetree hides /Applications/Emacs.app/Contents/Resources/lisp/org/org-datetree
~/elisp/org-mode/lisp/org-crypt hides /Applications/Emacs.app/Contents/Resources/lisp/org/org-crypt
~/elisp/org-mode/lisp/org-compat hides /Applications/Emacs.app/Contents/Resources/lisp/org/org-compat
~/elisp/org-mode/lisp/org-colview hides /Applications/Emacs.app/Contents/Resources/lisp/org/org-colview
~/elisp/org-mode/lisp/org-clock hides /Applications/Emacs.app/Contents/Resources/lisp/org/org-clock
~/elisp/org-mode/lisp/org-bibtex hides /Applications/Emacs.app/Contents/Resources/lisp/org/org-bibtex
~/elisp/org-mode/lisp/org-bbdb hides /Applications/Emacs.app/Contents/Resources/lisp/org/org-bbdb
~/elisp/org-mode/lisp/org-attach hides /Applications/Emacs.app/Contents/Resources/lisp/org/org-attach
~/elisp/org-mode/lisp/org-ascii hides /Applications/Emacs.app/Contents/Resources/lisp/org/org-ascii
~/elisp/org-mode/lisp/org-archive hides /Applications/Emacs.app/Contents/Resources/lisp/org/org-archive
~/elisp/org-mode/lisp/org-agenda hides /Applications/Emacs.app/Contents/Resources/lisp/org/org-agenda
~/elisp/xsd-regexp hides /Applications/Emacs.app/Contents/Resources/lisp/nxml/xsd-regexp
~/elisp/xmltok hides /Applications/Emacs.app/Contents/Resources/lisp/nxml/xmltok
~/elisp/rng-xsd hides /Applications/Emacs.app/Contents/Resources/lisp/nxml/rng-xsd
~/elisp/rng-valid hides /Applications/Emacs.app/Contents/Resources/lisp/nxml/rng-valid
~/elisp/rng-util hides /Applications/Emacs.app/Contents/Resources/lisp/nxml/rng-util
~/elisp/rng-uri hides /Applications/Emacs.app/Contents/Resources/lisp/nxml/rng-uri
~/elisp/rng-pttrn hides /Applications/Emacs.app/Contents/Resources/lisp/nxml/rng-pttrn
~/elisp/rng-parse hides /Applications/Emacs.app/Contents/Resources/lisp/nxml/rng-parse
~/elisp/rng-nxml hides /Applications/Emacs.app/Contents/Resources/lisp/nxml/rng-nxml
~/elisp/rng-match hides /Applications/Emacs.app/Contents/Resources/lisp/nxml/rng-match
~/elisp/rng-maint hides /Applications/Emacs.app/Contents/Resources/lisp/nxml/rng-maint
~/elisp/rng-loc hides /Applications/Emacs.app/Contents/Resources/lisp/nxml/rng-loc
~/elisp/rng-dt hides /Applications/Emacs.app/Contents/Resources/lisp/nxml/rng-dt
~/elisp/rng-cmpct hides /Applications/Emacs.app/Contents/Resources/lisp/nxml/rng-cmpct

Features:
(shadow emacsbug em-unix em-term term disp-table em-script em-prompt
em-ls em-hist em-pred em-glob em-dirs em-cmpl em-basic esh-opt
em-banner em-alias esh-var esh-io esh-cmd esh-ext esh-proc esh-arg
eldoc esh-groups eshell esh-module esh-mode esh-util conf-mode
newcomment help-mode bookmark mule-util cal-move view cal-china lunar
solar cal-dst cal-bahai cal-islam cal-hebrew holidays hol-loaddefs
diary-lib diary-loaddefs cal-iso org-wl org-w3m org-vm org-rmail
org-mhe org-mew org-irc org-jsinfo org-infojs org-html org-exp ob-exp
org-exp-blocks org-info org-gnus org-docview org-bibtex org-bbdb
org-agenda ehelp electric dired-aux mew-varsx mew-w3m w3m doc-view
jka-compr image-mode timezone w3m-hist w3m-fb w3m-ems w3m-ccl ccl
w3m-favicon w3m-image w3m-proc w3m-util mew-auth mew-config mew-imap2
mew-imap mew-nntp2 mew-nntp mew-pop mew-smtp mew-ssl mew-ssh mew-net
mew-highlight mew-sort mew-fib mew-ext mew-refile mew-demo mew-attach
mew-draft mew-message mew-thread mew-virtual mew-summary4 mew-summary3
mew-summary2 mew-summary mew-search mew-pick mew-passwd mew-scan
mew-syntax mew-bq mew-smime mew-pgp mew-header mew-exec mew-mark
mew-mime mew-edit mew-decode mew-encode mew-cache mew-minibuf
mew-complete mew-addrbook mew-local mew-darwin mew-vars3 mew-vars2
mew-vars mew-env mew-mule3 mew-mule mew-gemacs mew-key mew-func
mew-blvs mew-const mew coffee-mode windmove framemove ensime
ensime-undo ensime-refactor ensime-builder ensime-debug ensime-inf
ensime-sbt ensime-auto-complete ensime-config auto-complete popup
hideshow fortress-mode ansi-color scala-mode-auto pure-mode
org-remember org-datetree org-clock org ob-emacs-lisp ob-keys
ob-comint ob-tangle ob-ref ob-lob ob-table ob org-footnote org-src
org-list org-faces org-compat org-entities org-macs noutline outline
org-install ahg grep ewoc maxima maxima-font-lock teyjus magit
parse-time tex-site tramp-imap tramp-gw tramp-fish tramp-smb
tramp-cache tramp-ftp tramp-cmds tramp auth-source gnus-util netrc
time-date password-cache format-spec tramp-compat trampver ess-toolbar
ess-mous mouseme compile thingatpt browse-url ess-menu speedbar
sb-image ezimage dframe assoc ess-swv ess-noweb noweb-font-lock-mode
essl-bugs essd-omg essl-omg essd-els essd-sas essl-sas essa-sas
executable shell essd-arc essd-vst essd-xls essl-lsp essd-sta essl-sta
cc-vars cc-defs make-regexp essd-sp6 essd-sp5 essd-sp3 essd-r
essd-r-args essl-s ess-inf ess-utils ess-mode noweb-mode ess ess-cust
ess-emcs ess-site proof-site proof-autoloads pg-vars comint
remember-planner remember planner-multi crm planner cal-menu calendar
cal-loaddefs sort muse-html muse-xml-common muse-colors pcomplete
cus-edit muse-publish muse-project muse-protocols info muse-regexps
muse muse-nested-tags muse-mode server ido psvn byte-opt bytecomp
byte-compile advice help-fns advice-preload derived edmacro kmacro
wid-edit cl cl-19 log-edit ring pcvs-util add-log diff-mode easy-mmode
pp elp ediff-merg ediff-diff ediff-wind ediff-mult ediff-help
ediff-init ediff-util dired regexp-opt paren hl-line cus-start
cus-load tooltip ediff-hook vc-hooks lisp-float-type mwheel ns-win
easymenu tool-bar dnd fontset image fringe lisp-mode register page
menu-bar rfn-eshadow timer select scroll-bar mldrag mouse jit-lock
font-lock syntax facemenu font-core frame cham georgian utf-8-lang
misc-lang vietnamese tibetan thai tai-viet lao korean japanese hebrew
greek romanian slovak czech european ethiopic indian cyrillic chinese
case-table epa-hook jka-cmpr-hook help simple abbrev loaddefs button
minibuffer faces cus-face files text-properties overlay md5 base64
format env code-pages mule custom widget hashtable-print-readable
backquote make-network-process ns multi-tty emacs)