commit 1b3fd89b1c19cdd3203f16584abba38f1c1c722f (HEAD, refs/remotes/origin/master) Author: Glenn Morris Date: Tue May 26 23:42:59 2015 -0700 No longer set dired-directory in eshell. (Bug#16477) * lisp/eshell/esh-mode.el (eshell-mode): * lisp/eshell/em-dirs.el (eshell/cd): No longer set dired-directory. diff --git a/lisp/eshell/em-dirs.el b/lisp/eshell/em-dirs.el index 84d46dc..e9458cc 100644 --- a/lisp/eshell/em-dirs.el +++ b/lisp/eshell/em-dirs.el @@ -348,8 +348,6 @@ in the minibuffer: index (1+ index))))) oldpath)) -(defvar dired-directory) - (defun eshell/cd (&rest args) ; all but first ignored "Alias to extend the behavior of `cd'." (setq args (eshell-flatten-list args)) @@ -394,11 +392,11 @@ in the minibuffer: (path (setq path (eshell-expand-multiple-dots path)))) (unless handled - (setq dired-directory (or path "~")) - (let ((curdir (eshell/pwd))) - (unless (equal curdir dired-directory) + (let ((curdir (eshell/pwd)) + (newdir (or path "~"))) + (unless (equal curdir newdir) (eshell-add-to-dir-ring curdir)) - (let ((result (cd dired-directory))) + (let ((result (cd newdir))) (and eshell-cd-shows-directory (eshell-printn result))) (run-hooks 'eshell-directory-change-hook) diff --git a/lisp/eshell/esh-mode.el b/lisp/eshell/esh-mode.el index 0dac478..22ccf4e 100644 --- a/lisp/eshell/esh-mode.el +++ b/lisp/eshell/esh-mode.el @@ -344,7 +344,6 @@ and the hook `eshell-exit-hook'." (setq local-abbrev-table eshell-mode-abbrev-table) - (set (make-local-variable 'dired-directory) default-directory) (set (make-local-variable 'list-buffers-directory) (expand-file-name default-directory)) commit b38bc40d692f39d00477d5691acaa1046c74623c Author: Glenn Morris Date: Tue May 26 23:29:51 2015 -0700 * lisp/mail/sendmail.el (mail-position-on-field): Doc fix. diff --git a/lisp/mail/sendmail.el b/lisp/mail/sendmail.el index ddd8697..2b9d8fa 100644 --- a/lisp/mail/sendmail.el +++ b/lisp/mail/sendmail.el @@ -1500,9 +1500,10 @@ just append to the file, in Babyl format if necessary." (insert "\nMail-Followup-To: ")))) (defun mail-position-on-field (field &optional soft) - "Move to the start of the contents of header field FIELD. -If there is none, insert one, unless SOFT is non-nil. -If there are multiple FIELD fields, this goes to the first." + "Move to the end of the contents of header field FIELD. +If there is no such header, insert one, unless SOFT is non-nil. +If there are multiple FIELD fields, this goes to the first. +Returns non-nil if FIELD was originally present." (let (end (case-fold-search t)) (setq end (mail-header-end)) commit ce32fb872b3ae1037be1106afa92410f0c349385 Author: Glenn Morris Date: Tue May 26 23:29:25 2015 -0700 Make c-submit-bug-report file reports at debbugs.gnu.org. (Bug#15784) * lisp/progmodes/cc-mode.el (c-mode-help-address): Change to submit@debbugs. (c-mode-bug-package): New constant. (mail-position-on-field): Declare. (c-submit-bug-report): Insert X-Debbugs-Package header. * doc/misc/cc-mode.texi (Mailing Lists and Bug Reports): Mention debbugs.gnu.org. diff --git a/doc/misc/cc-mode.texi b/doc/misc/cc-mode.texi index 5ad29cd..c90a7db 100644 --- a/doc/misc/cc-mode.texi +++ b/doc/misc/cc-mode.texi @@ -7173,11 +7173,12 @@ configuration. In that case, we'd appreciate it if you isolate the Emacs Lisp code that triggers the bug and include it in your report. @cindex bug report mailing list -Bug reports should be sent to @email{bug-cc-mode@@gnu.org}. You can -also send other questions and suggestions (kudos?@: @t{;-)} to that -address. It's a mailing list which you can join or browse an archive -of; see the web site at @uref{http://cc-mode.sourceforge.net/} for -further details. +Reporting a bug using @code{c-submit-bug-report} files it in +the GNU Bug Tracker at @url{http://debbugs.gnu.org}, then sends it on +to @email{bug-cc-mode@@gnu.org}. You can also send reports, other +questions, and suggestions (kudos?@: @t{;-)} to that address. It's a +mailing list which you can join or browse an archive of; see the web site at +@uref{http://cc-mode.sourceforge.net/} for further details. @cindex announcement mailing list If you want to get announcements of new @ccmode{} releases, send the diff --git a/lisp/progmodes/cc-mode.el b/lisp/progmodes/cc-mode.el index 3c1aec4..8365702 100644 --- a/lisp/progmodes/cc-mode.el +++ b/lisp/progmodes/cc-mode.el @@ -1823,7 +1823,7 @@ Key bindings: ;; bug reporting (defconst c-mode-help-address - "bug-cc-mode@gnu.org" + "submit@debbugs.gnu.org" "Address(es) for CC Mode bug reports.") (defun c-version () @@ -1840,6 +1840,13 @@ Key bindings: (defvar reporter-prompt-for-summary-p) (defvar reporter-dont-compact-list) +;; This could be "emacs,cc-mode" in the version included in Emacs. +(defconst c-mode-bug-package "cc-mode" + "The package to use in the bug submission.") + +;; reporter-submit-bug-report requires sendmail. +(declare-function mail-position-on-field "sendmail" (field &optional soft)) + (defun c-submit-bug-report () "Submit via mail a bug report on CC Mode." (interactive) @@ -1903,6 +1910,9 @@ Key bindings: vars) (lambda () (run-hooks 'c-prepare-bug-report-hook) + (save-excursion + (or (mail-position-on-field "X-Debbugs-Package") + (insert c-mode-bug-package))) (insert (format "Buffer Style: %s\nc-emacs-features: %s\n" style c-features))))))) commit d3155315c85212f224fc5df0239182dafdfd6284 Author: Glenn Morris Date: Tue May 26 21:04:19 2015 -0400 * lisp/mail/rmailsum.el: Commas no longer separate regexps. (Bug#19026) (rmail-summary-by-recipients, rmail-summary-by-topic) (rmail-summary-by-senders): No longer use mail-comma-list-regexp. * doc/emacs/rmail.texi (Rmail Make Summary): Update for this change. ; * etc/NEWS: Mention this. diff --git a/doc/emacs/rmail.texi b/doc/emacs/rmail.texi index 82ac99f..6cad280 100644 --- a/doc/emacs/rmail.texi +++ b/doc/emacs/rmail.texi @@ -926,8 +926,7 @@ commas. @findex rmail-summary-by-recipients @kbd{C-M-r @var{rcpts} @key{RET}} (@code{rmail-summary-by-recipients}) makes a partial summary mentioning only the messages that have one or -more recipients matching the regular expression @var{rcpts}. You can -use commas to separate multiple regular expressions. These are matched +more recipients matching the regular expression @var{rcpts}. This is matched against the @samp{To}, @samp{From}, and @samp{CC} headers (supply a prefix argument to exclude this header). @@ -935,9 +934,8 @@ argument to exclude this header). @findex rmail-summary-by-topic @kbd{C-M-t @var{topic} @key{RET}} (@code{rmail-summary-by-topic}) makes a partial summary mentioning only the messages whose subjects have -a match for the regular expression @var{topic}. You can use commas to -separate multiple regular expressions. With a prefix argument, the -match is against the whole message, not just the subject. +a match for the regular expression @var{topic}. With a prefix argument, +the match is against the whole message, not just the subject. @kindex C-M-s @r{(Rmail)} @findex rmail-summary-by-regexp @@ -950,8 +948,7 @@ expression @var{regexp}. @findex rmail-summary-by-senders @kbd{C-M-f @var{senders} @key{RET}} (@code{rmail-summary-by-senders}) makes a partial summary that mentions only the messages whose @samp{From} -fields match the regular expression @var{senders}. You can use commas to -separate multiple regular expressions. +fields match the regular expression @var{senders}. Note that there is only one summary buffer for any Rmail buffer; making any kind of summary discards any previous summary. diff --git a/etc/NEWS b/etc/NEWS index 1cccc31..24f6d58 100644 --- a/etc/NEWS +++ b/etc/NEWS @@ -520,16 +520,21 @@ alternatives to currently visited manuals. --- ** ntlm.el has support for NTLM2. ---- -** The Rmail commands d, C-d and u now handle repeat counts to delete or +** Rmail + +*** The Rmail commands d, C-d and u take optional repeat counts to delete or undelete multiple messages. -** Rmail can now render HTML mail messages if your Emacs was built with +*** Rmail can now render HTML mail messages if your Emacs was built with libxml2 or if you have the Lynx browser installed. By default, Rmail will display the HTML version of a mail message that has both HTML and plain text parts, if display of HTML email is possible; customize the `rmail-mime-prefer-html' option to `nil' if you don't want that. ++++ +*** In the commands that make summaries by subject, recipients, or senders, +you can no longer use commas to separate regular expressions. + ** SES now supports local printer functions; see `ses-define-local-printer'. ** In sh-mode, you can now use `sh-shell' as a file-local variable to @@ -875,9 +880,6 @@ permissions set to temporary values (e.g., for creating private files). ** You can access the slots of structures using `cl-struct-slot-value'. -** Functions `rmail-delete-forward' and `rmail-delete-backward' take an -optional repeat-count argument. - ** Function `sort' can deal with vectors. ** Function `system-name' now returns an updated value if the current diff --git a/lisp/mail/rmailsum.el b/lisp/mail/rmailsum.el index 7097fef..ed4d58c 100644 --- a/lisp/mail/rmailsum.el +++ b/lisp/mail/rmailsum.el @@ -287,23 +287,20 @@ LABELS should be a string containing the desired labels, separated by commas." (mail-comma-list-regexp labels) "\\)\\(,\\|\\'\\)"))) -;; FIXME "a string of regexps separated by commas" makes no sense because: -;; i) it's pointless (you can just use \\|) -;; ii) it's broken (you can't specify a literal comma) -;; rmail-summary-by-topic and rmail-summary-by-senders have the same issue. ;;;###autoload (defun rmail-summary-by-recipients (recipients &optional primary-only) "Display a summary of all messages with the given RECIPIENTS. Normally checks the To, From and Cc fields of headers; but if PRIMARY-ONLY is non-nil (prefix arg given), only look in the To and From fields. -RECIPIENTS is a string of regexps separated by commas." +RECIPIENTS is a regular expression." (interactive "sRecipients to summarize by: \nP") (rmail-new-summary (concat "recipients " recipients) (list 'rmail-summary-by-recipients recipients primary-only) 'rmail-message-recipients-p - (mail-comma-list-regexp recipients) primary-only)) + (replace-regexp-in-string "\\`[ \t]*\\(.*?\\)[ \t]*\\'" "\\1" recipients) + primary-only)) (defun rmail-message-recipients-p (msg recipients &optional primary-only) (rmail-apply-in-message msg 'rmail-message-recipients-p-1 @@ -370,7 +367,7 @@ Emacs will list the message in the summary." "Display a summary of all messages with the given SUBJECT. Normally checks just the Subject field of headers; but with prefix argument WHOLE-MESSAGE is non-nil, looks in the whole message. -SUBJECT is a string of regexps separated by commas." +SUBJECT is a regular expression." (interactive ;; We quote the default subject, because if it contains regexp ;; special characters (eg "?"), it can fail to match itself. (Bug#2333) @@ -383,7 +380,8 @@ SUBJECT is a string of regexps separated by commas." (concat "about " subject) (list 'rmail-summary-by-topic subject whole-message) 'rmail-message-subject-p - (mail-comma-list-regexp subject) whole-message)) + (replace-regexp-in-string "\\`[ \t]*\\(.*?\\)[ \t]*\\'" "\\1" subject) + whole-message)) (defun rmail-message-subject-p (msg subject &optional whole-message) (if whole-message @@ -395,13 +393,13 @@ SUBJECT is a string of regexps separated by commas." ;;;###autoload (defun rmail-summary-by-senders (senders) "Display a summary of all messages whose \"From\" field matches SENDERS. -SENDERS is a string of regexps separated by commas." +SENDERS is a regular expression." (interactive "sSenders to summarize by: ") (rmail-new-summary (concat "senders " senders) (list 'rmail-summary-by-senders senders) 'rmail-message-senders-p - (mail-comma-list-regexp senders))) + (replace-regexp-in-string "\\`[ \t]*\\(.*?\\)[ \t]*\\'" "\\1" senders))) (defun rmail-message-senders-p (msg senders) (string-match senders (or (rmail-get-header "From" msg) ""))) commit 5e9756e4c68a199f051c2b9998c07a683ff479ff Author: Paul Eggert Date: Tue May 26 12:29:38 2015 -0700 Handle curved quotes in info files * lisp/calc/calc-help.el (calc-describe-thing): * lisp/info.el (Info-find-index-name) (Info-try-follow-nearest-node, Info-fontify-node): * lisp/vc/ediff-help.el (ediff-help-for-quick-help): In info files, process quotes ‘like this’ the same way we process quotes `like this'. This catches a few places we missed earlier. diff --git a/lisp/calc/calc-help.el b/lisp/calc/calc-help.el index 17e5b0f..aace2a9 100644 --- a/lisp/calc/calc-help.el +++ b/lisp/calc/calc-help.el @@ -365,21 +365,23 @@ C-w Describe how there is no warranty for Calc." (let (Info-history) (Info-goto-node (buffer-substring (match-beginning 1) (match-end 1)))) (or (let ((case-fold-search nil)) - (or (re-search-forward (format "\\[`%s'\\]\\|(`%s')\\|\\" makeinfo can append @@ -3894,7 +3894,7 @@ If FORK is non-nil, it is passed to `Info-goto-node'." (let (node) (cond ((setq node (Info-get-token (point) "[hf]t?tps?://" - "\\([hf]t?tps?://[^ \t\n\"`({<>})']+\\)")) + "\\([hf]t?tps?://[^ \t\n\"`‘({<>})’']+\\)")) (browse-url node) (setq node t)) ((setq node (Info-get-token (point) "\\*note[ \n\t]+" @@ -4979,7 +4979,7 @@ first line or header line, and for breadcrumb links.") ;; Fontify http and ftp references (goto-char (point-min)) (when not-fontified-p - (while (re-search-forward "\\(https?\\|ftp\\)://[^ \t\n\"`({<>})']+" + (while (re-search-forward "\\(https?\\|ftp\\)://[^ \t\n\"`‘({<>})’']+" nil t) (add-text-properties (match-beginning 0) (match-end 0) '(font-lock-face info-xref diff --git a/lisp/vc/ediff-help.el b/lisp/vc/ediff-help.el index c981d89..67acc66 100644 --- a/lisp/vc/ediff-help.el +++ b/lisp/vc/ediff-help.el @@ -195,47 +195,47 @@ the value of this variable and the variables `ediff-help-message-*' in (ediff-documentation "Quick Help Commands") (let (case-fold-search) - (cond ((string= cmd "?") (re-search-forward "^`\\?'")) - ((string= cmd "G") (re-search-forward "^`G'")) - ((string= cmd "E") (re-search-forward "^`E'")) - ((string= cmd "wd") (re-search-forward "^`wd'")) - ((string= cmd "wx") (re-search-forward "^`wa'")) - ((string= cmd "a/b") (re-search-forward "^`a'")) - ((string= cmd "x") (re-search-forward "^`a'")) - ((string= cmd "xy") (re-search-forward "^`ab'")) - ((string= cmd "p,DEL") (re-search-forward "^`p'")) - ((string= cmd "n,SPC") (re-search-forward "^`n'")) - ((string= cmd "j") (re-search-forward "^`j'")) - ((string= cmd "gx") (re-search-forward "^`ga'")) - ((string= cmd "!") (re-search-forward "^`!'")) - ((string= cmd "*") (re-search-forward "^`\\*'")) - ((string= cmd "m") (re-search-forward "^`m'")) - ((string= cmd "|") (re-search-forward "^`|'")) - ((string= cmd "@") (re-search-forward "^`@'")) - ((string= cmd "h") (re-search-forward "^`h'")) - ((string= cmd "r") (re-search-forward "^`r'")) - ((string= cmd "rx") (re-search-forward "^`ra'")) - ((string= cmd "##") (re-search-forward "^`##'")) - ((string= cmd "#c") (re-search-forward "^`#c'")) - ((string= cmd "#f/#h") (re-search-forward "^`#f'")) - ((string= cmd "X") (re-search-forward "^`A'")) - ((string= cmd "v/V") (re-search-forward "^`v'")) - ((string= cmd "") (re-search-forward "^`<'")) - ((string= cmd "~") (re-search-forward "^`~'")) - ((string= cmd "i") (re-search-forward "^`i'")) - ((string= cmd "D") (re-search-forward "^`D'")) - ((string= cmd "R") (re-search-forward "^`R'")) - ((string= cmd "M") (re-search-forward "^`M'")) - ((string= cmd "z/q") (re-search-forward "^`z'")) - ((string= cmd "%") (re-search-forward "^`%'")) - ((string= cmd "C-l") (re-search-forward "^`C-l'")) - ((string= cmd "$$") (re-search-forward "^`\\$\\$'")) - ((string= cmd "$*") (re-search-forward "^`\\$\\*'")) - ((string= cmd "/") (re-search-forward "^`/'")) - ((string= cmd "&") (re-search-forward "^`&'")) - ((string= cmd "s") (re-search-forward "^`s'")) - ((string= cmd "+") (re-search-forward "^`\\+'")) - ((string= cmd "=") (re-search-forward "^`='")) + (cond ((string= cmd "?") (re-search-forward "^[`‘]\\?['’]")) + ((string= cmd "G") (re-search-forward "^[`‘]G['’]")) + ((string= cmd "E") (re-search-forward "^[`‘]E['’]")) + ((string= cmd "wd") (re-search-forward "^[`‘]wd['’]")) + ((string= cmd "wx") (re-search-forward "^[`‘]wa['’]")) + ((string= cmd "a/b") (re-search-forward "^[`‘]a['’]")) + ((string= cmd "x") (re-search-forward "^[`‘]a['’]")) + ((string= cmd "xy") (re-search-forward "^[`‘]ab['’]")) + ((string= cmd "p,DEL") (re-search-forward "^[`‘]p['’]")) + ((string= cmd "n,SPC") (re-search-forward "^[`‘]n['’]")) + ((string= cmd "j") (re-search-forward "^[`‘]j['’]")) + ((string= cmd "gx") (re-search-forward "^[`‘]ga['’]")) + ((string= cmd "!") (re-search-forward "^[`‘]!['’]")) + ((string= cmd "*") (re-search-forward "^[`‘]\\*['’]")) + ((string= cmd "m") (re-search-forward "^[`‘]m['’]")) + ((string= cmd "|") (re-search-forward "^[`‘]|['’]")) + ((string= cmd "@") (re-search-forward "^[`‘]@['’]")) + ((string= cmd "h") (re-search-forward "^[`‘]h['’]")) + ((string= cmd "r") (re-search-forward "^[`‘]r['’]")) + ((string= cmd "rx") (re-search-forward "^[`‘]ra['’]")) + ((string= cmd "##") (re-search-forward "^[`‘]##['’]")) + ((string= cmd "#c") (re-search-forward "^[`‘]#c['’]")) + ((string= cmd "#f/#h") (re-search-forward "^[`‘]#f['’]")) + ((string= cmd "X") (re-search-forward "^[`‘]A['’]")) + ((string= cmd "v/V") (re-search-forward "^[`‘]v['’]")) + ((string= cmd "") (re-search-forward "^[`‘]<['’]")) + ((string= cmd "~") (re-search-forward "^[`‘]~['’]")) + ((string= cmd "i") (re-search-forward "^[`‘]i['’]")) + ((string= cmd "D") (re-search-forward "^[`‘]D['’]")) + ((string= cmd "R") (re-search-forward "^[`‘]R['’]")) + ((string= cmd "M") (re-search-forward "^[`‘]M['’]")) + ((string= cmd "z/q") (re-search-forward "^[`‘]z['’]")) + ((string= cmd "%") (re-search-forward "^[`‘]%['’]")) + ((string= cmd "C-l") (re-search-forward "^[`‘]C-l['’]")) + ((string= cmd "$$") (re-search-forward "^[`‘]\\$\\$['’]")) + ((string= cmd "$*") (re-search-forward "^[`‘]\\$\\*['’]")) + ((string= cmd "/") (re-search-forward "^[`‘]/['’]")) + ((string= cmd "&") (re-search-forward "^[`‘]&['’]")) + ((string= cmd "s") (re-search-forward "^[`‘]s['’]")) + ((string= cmd "+") (re-search-forward "^[`‘]\\+['’]")) + ((string= cmd "=") (re-search-forward "^[`‘]=['’]")) (t (error "Undocumented command! Type `G' in Ediff Control Panel to drop a note to the Ediff maintainer"))) ) ; let case-fold-search )) commit d86ef9fc4a45bd1f3c79c4814b9e1e545ce0a07c Author: Dmitry Gutov Date: Tue May 26 19:28:38 2015 +0300 xref-prompt-for-identifier: Use a list value * lisp/progmodes/xref.el (xref-prompt-for-identifier): Allow list value, to be interpreted as a list of commands. (xref--prompt-p): New function. (xref--read-identifier): Use it. diff --git a/lisp/progmodes/xref.el b/lisp/progmodes/xref.el index 3bb4fde..c9bffc6 100644 --- a/lisp/progmodes/xref.el +++ b/lisp/progmodes/xref.el @@ -283,13 +283,25 @@ backward." :type 'integer :version "25.1") -(defcustom xref-prompt-for-identifier nil - "When non-nil, always prompt for the identifier name. +(defcustom xref-prompt-for-identifier '(not xref-find-definitions + xref-find-definitions-other-window + xref-find-definitions-other-frame) + "When t, always prompt for the identifier name. -Otherwise, only prompt when there's no value at point we can use, -or when the command has been called with the prefix argument." +When nil, prompt only when there's no value at point we can use, +or when the command has been called with the prefix argument. + +Otherwise, it's a list of xref commands which will prompt +anyway (the value at point, if any, will be used as the default). + +If the list starts with `not', the meaning of the rest of the +elements is negated." :type '(choice (const :tag "always" t) - (const :tag "auto" nil)) + (const :tag "auto" nil) + (set :menu-tag "command specific" :tag "commands" + :value (not) + (const :tag "Except" not) + (repeat :inline t (symbol :tag "command")))) :version "25.1") (defcustom xref-pulse-on-jump t @@ -621,10 +633,18 @@ Return an alist of the form ((FILENAME . (XREF ...)) ...)." `((window . ,window) (temporary-buffers . ,tb))))))) +(defun xref--prompt-p (command) + (or (eq xref-prompt-for-identifier t) + (if (eq (car xref-prompt-for-identifier) 'not) + (not (memq command (cdr xref-prompt-for-identifier))) + (memq command xref-prompt-for-identifier)))) + (defun xref--read-identifier (prompt) "Return the identifier at point or read it from the minibuffer." (let ((id (funcall xref-identifier-at-point-function))) - (cond ((or current-prefix-arg xref-prompt-for-identifier (not id)) + (cond ((or current-prefix-arg + (not id) + (xref--prompt-p this-command)) (completing-read prompt (funcall xref-identifier-completion-table-function) nil nil nil @@ -667,6 +687,7 @@ With prefix argument, prompt for the identifier." ;;;###autoload (defun xref-find-regexp (regexp) "Find all matches for REGEXP." + ;; FIXME: Prompt for directory. (interactive (list (xref--read-identifier "Find regexp: "))) (xref--show-xrefs regexp 'matches regexp nil)) @@ -736,6 +757,9 @@ details on which tools are used, and when." (cl-assert (directory-name-p dir)) (when (null kind) (setq input (regexp-quote input))) + ;; FIXME: When regexp, search in all files, except + ;; `grep-find-ignored-directories' and `grep-find-ignored-files', + ;; like `rgrep' does. (let* ((default-directory dir) (semantic-symref-tool 'detect) (res (if (eq kind 'symbol) commit 53bedd3a8eb7169b734ee8925c76712c68d9c4fc Author: Eli Zaretskii Date: Tue May 26 18:29:40 2015 +0300 Teach MS-Windows font back-end return per-glyph ascent/descent * src/w32font.h (struct w32_metric_cache): Add ascent and descent values. * src/w32font.c (w32font_text_extents): Compute, cache, and accumulate per-glyph ascent and descent values, instead of copying global values from the font. If the values are not available from the font data, i.e., non-TTF fonts, fall back on font-global values. (compute_metrics): Compute and return per-glyph ascent and descent values, if returned by GetGlyphOutlineW, falling back on font-global values. (Bug#20628) * src/w32term.c (w32_draw_rectangle): Add 1 pixel to width and height of rectangle to be drawn, to be compatible with XDrawRectangle. Fixes glyphless-char display as hex codes in a box, when per-glyph ascent/descent values are used. diff --git a/src/w32font.c b/src/w32font.c index 7799459..6306a84 100644 --- a/src/w32font.c +++ b/src/w32font.c @@ -439,14 +439,13 @@ w32font_text_extents (struct font *font, unsigned *code, int total_width = 0; WORD *wcode; SIZE size; + bool first; struct w32font_info *w32_font = (struct w32font_info *) font; memset (metrics, 0, sizeof (struct font_metrics)); - metrics->ascent = font->ascent; - metrics->descent = font->descent; - for (i = 0; i < nglyphs; i++) + for (i = 0, first = true; i < nglyphs; i++) { struct w32_metric_cache *char_metric; int block = *(code + i) / CACHE_BLOCKSIZE; @@ -495,11 +494,24 @@ w32font_text_extents (struct font *font, unsigned *code, if (char_metric->status == W32METRIC_SUCCESS) { - metrics->lbearing = min (metrics->lbearing, - metrics->width + char_metric->lbearing); - metrics->rbearing = max (metrics->rbearing, - metrics->width + char_metric->rbearing); + if (first) + { + metrics->lbearing = char_metric->lbearing; + metrics->rbearing = char_metric->rbearing; + metrics->width = 0; + metrics->ascent = char_metric->ascent; + metrics->descent = char_metric->descent; + first = false; + } + if (metrics->lbearing > char_metric->lbearing) + metrics->lbearing = char_metric->lbearing; + if (metrics->rbearing < char_metric->rbearing) + metrics->rbearing = char_metric->rbearing; metrics->width += char_metric->width; + if (metrics->ascent < char_metric->ascent) + metrics->ascent = char_metric->ascent; + if (metrics->descent < char_metric->descent) + metrics->descent = char_metric->descent; } else /* If we couldn't get metrics for a char, @@ -574,6 +586,8 @@ w32font_text_extents (struct font *font, unsigned *code, metrics->width = total_width - w32_font->metrics.tmOverhang; metrics->lbearing = 0; metrics->rbearing = total_width; + metrics->ascent = font->ascent; + metrics->descent = font->descent; /* Restore state and release DC. */ SelectObject (dc, old_font); @@ -2415,6 +2429,8 @@ compute_metrics (HDC dc, struct w32font_info *w32_font, unsigned int code, metrics->lbearing = gm.gmptGlyphOrigin.x; metrics->rbearing = gm.gmptGlyphOrigin.x + gm.gmBlackBoxX; metrics->width = gm.gmCellIncX; + metrics->ascent = gm.gmptGlyphOrigin.y; + metrics->descent = gm.gmBlackBoxY - gm.gmptGlyphOrigin.y; metrics->status = W32METRIC_SUCCESS; } else if (get_char_width_32_w (dc, code, code, &width) != 0) @@ -2422,6 +2438,8 @@ compute_metrics (HDC dc, struct w32font_info *w32_font, unsigned int code, metrics->lbearing = 0; metrics->rbearing = width; metrics->width = width; + metrics->ascent = w32_font->font.ascent; + metrics->descent = w32_font->font.descent; metrics->status = W32METRIC_SUCCESS; } else diff --git a/src/w32font.h b/src/w32font.h index 0ad0125..6365cb3 100644 --- a/src/w32font.h +++ b/src/w32font.h @@ -37,7 +37,7 @@ along with GNU Emacs. If not, see . */ struct w32_metric_cache { - short lbearing, rbearing, width; + short lbearing, rbearing, width, ascent, descent; unsigned char status; }; diff --git a/src/w32term.c b/src/w32term.c index 089c43c..0bc2e98 100644 --- a/src/w32term.c +++ b/src/w32term.c @@ -401,7 +401,13 @@ w32_draw_rectangle (HDC hdc, XGCValues *gc, int x, int y, oldhb = SelectObject (hdc, hb); oldhp = SelectObject (hdc, hp); - Rectangle (hdc, x, y, x + width, y + height); + /* We enlarge WIDTH and HEIGHT by 1 to be bug-compatible to the + brain-dead design of XDrawRectangle, which draws a rectangle that + is 1 pixel wider and higher than its arguments WIDTH and HEIGHT. + This allows us to keep the code that calls this function similar + to the corresponding code in xterm.c. For the details, see + http://lists.gnu.org/archives/html/emacs-devel/2014-10/msg00546.html. */ + Rectangle (hdc, x, y, x + width + 1, y + height + 1); SelectObject (hdc, oldhb); SelectObject (hdc, oldhp);