commit 1be132731d31c3752b275735e5dbe1f60d1988c3 (HEAD, refs/remotes/origin/master) Author: Po Lu Date: Mon Dec 25 15:38:15 2023 +0800 Apply TTF advance width rounding to uninstructed glyphs * src/sfnt.c (sfnt_scale_metrics): * src/sfntfont.c (sfntfont_get_glyph_outline): Round advance and floor lbearing scaling glyph metrics. (sfntfont_measure_pcm): Don't round or truncate metrics which have already been. diff --git a/src/sfnt.c b/src/sfnt.c index d945342c264..b67377ad064 100644 --- a/src/sfnt.c +++ b/src/sfnt.c @@ -5656,18 +5656,21 @@ sfnt_lookup_glyph_metrics (sfnt_glyph glyph, int pixel_size, return 0; } -/* Scale the specified glyph metrics by FACTOR. - Set METRICS->lbearing and METRICS->advance to their current - values times factor. */ +/* Scale the specified glyph metrics by FACTOR. Set METRICS->lbearing + and METRICS->advance to their current values times factor; take the + floor of the left bearing and round the advance width. */ MAYBE_UNUSED TEST_STATIC void sfnt_scale_metrics (struct sfnt_glyph_metrics *metrics, sfnt_fixed factor) { - metrics->lbearing - = sfnt_mul_fixed (metrics->lbearing * 65536, factor); - metrics->advance - = sfnt_mul_fixed (metrics->advance * 65536, factor); + sfnt_fixed lbearing, advance; + + lbearing = sfnt_mul_fixed (metrics->lbearing * 65536, factor); + advance = sfnt_mul_fixed (metrics->advance * 65536, factor); + + metrics->lbearing = sfnt_floor_fixed (lbearing); + metrics->advance = sfnt_round_fixed (advance); } /* Calculate the factor used to convert em space to device space for a diff --git a/src/sfntfont.c b/src/sfntfont.c index 078fe6083a6..c626e76b52b 100644 --- a/src/sfntfont.c +++ b/src/sfntfont.c @@ -2304,7 +2304,8 @@ sfntfont_get_glyph_outline (sfnt_glyph glyph_code, instruction code or glyph variation. The left side bearing is the distance from the origin point to the left most point on the X axis. */ - temp.lbearing = outline->xmin - outline->origin; + temp.lbearing + = SFNT_FLOOR_FIXED (outline->xmin - outline->origin); } } } @@ -3497,12 +3498,12 @@ sfntfont_measure_pcm (struct sfnt_font_info *font, sfnt_glyph glyph, if (!outline) return 1; - /* Round the left side bearing down. */ - pcm->lbearing = SFNT_FLOOR_FIXED (metrics.lbearing) / 65536; + /* The left side bearing has already been floored. */ + pcm->lbearing = metrics.lbearing / 65536; pcm->rbearing = SFNT_CEIL_FIXED (outline->xmax) / 65536; - /* Round the advance, ascent and descent upwards. */ - pcm->width = SFNT_CEIL_FIXED (metrics.advance) / 65536; + /* The advance is already rounded; ceil the ascent and descent. */ + pcm->width = metrics.advance / 65536; pcm->ascent = SFNT_CEIL_FIXED (outline->ymax) / 65536; pcm->descent = SFNT_CEIL_FIXED (-outline->ymin) / 65536; commit 995dd36da1df70c55ef2e72d4ff5b2641cc83292 Author: Po Lu Date: Mon Dec 25 11:21:15 2023 +0800 Optimize font edge filling loop * src/sfnt.c (sfnt_fedge_sort): Delete function. (sfnt_poly_edges_exact): Don't sort edges, iterate through each instead. (main): Adjust tests. diff --git a/src/sfnt.c b/src/sfnt.c index 553b828a2db..d945342c264 100644 --- a/src/sfnt.c +++ b/src/sfnt.c @@ -4946,36 +4946,6 @@ sfnt_insert_raster_step (struct sfnt_step_raster *raster, step->coverage += coverage; } -/* Sort an array of SIZE edges to increase by bottom Y position, in - preparation for building spans. - - Insertion sort is used because there are usually not very many - edges, and anything larger would bloat up the code. */ - -static void -sfnt_fedge_sort (struct sfnt_fedge *edges, size_t size) -{ - ssize_t i, j; - struct sfnt_fedge edge; - - for (i = 1; i < size; ++i) - { - edge = edges[i]; - j = i - 1; - - /* Comparing truncated values yields a faint speedup, for not as - many edges must be moved as would be otherwise. */ - while (j >= 0 && ((int) edges[j].bottom - > (int) edge.bottom)) - { - edges[j + 1] = edges[j]; - j--; - } - - edges[j + 1] = edge; - } -} - /* Draw EDGES, an unsorted array of polygon edges of size NEDGES. Transform EDGES into an array of steps representing a raster with @@ -4993,23 +4963,19 @@ sfnt_poly_edges_exact (struct sfnt_fedge *edges, size_t nedges, sfnt_step_raster_proc proc, void *dcontext) { int y; - size_t size, e; - struct sfnt_fedge *active, **prev, *a; + size_t size, e, edges_processed; + struct sfnt_fedge *active, **prev, *a, sentinel; struct sfnt_step_raster raster; struct sfnt_step_chunk *next, *last; if (!height) return; - /* Sort edges to ascend by Y-order. Once again, remember: cartesian - coordinates. */ - sfnt_fedge_sort (edges, nedges); - /* Step down line by line. Find active edges. */ y = sfnt_floor_fixed (MAX (0, edges[0].bottom)); - e = 0; - active = NULL; + e = edges_processed = 0; + active = &sentinel; /* Allocate the array of edges. */ @@ -5023,20 +4989,28 @@ sfnt_poly_edges_exact (struct sfnt_fedge *edges, size_t nedges, for (; y != height; y += 1) { - /* Add in new edges keeping them sorted. */ - for (; e < nedges && edges[e].bottom < y + 1; ++e) + /* Run over the whole array on each iteration of this loop; + experiments demonstrate this is faster for the majority of + glyphs. */ + for (e = 0; e < nedges; ++e) { - if (edges[e].top > y) + /* Although edges is unsorted, edges which have already been + processed will see their next fields set, and can thus be + disregarded. */ + if (!edges[e].next + && (edges[e].bottom < y + 1) + && (edges[e].top > y)) { - /* Find where to place this edge. */ - for (prev = &active; (a = *prev); prev = &(a->next)) - { - if (a->x > edges[e].x) - break; - } - - edges[e].next = *prev; - *prev = &edges[e]; + /* As steps generated from each edge are sorted at the + time of their insertion, sorting the list of active + edges itself is redundant. */ + edges[e].next = active; + active = &edges[e]; + + /* Increment the counter recording the number of edges + processed, which is used to terminate this loop early + once all have been processed. */ + edges_processed++; } } @@ -5044,7 +5018,7 @@ sfnt_poly_edges_exact (struct sfnt_fedge *edges, size_t nedges, removing it if it does not overlap with the next scanline. */ - for (prev = &active; (a = *prev);) + for (prev = &active; (a = *prev) != &sentinel;) { float x_top, x_bot, x_min, x_max; float y_top, y_bot; @@ -5371,11 +5345,15 @@ #define TRIANGLE_AREA(width, height) \ if (a->top < y + 1) *prev = a->next; else + /* This edge doesn't intersect with the next scanline; + remove it from the list. After the edge at hand is so + deleted from the list, its next field remains set, + excluding it from future consideration. */ prev = &a->next; } /* Break if all is done. */ - if (!active && e == nedges) + if (active == &sentinel && edges_processed == nedges) break; } @@ -21139,7 +21117,7 @@ #define EASY_PPEM 12 clock_gettime (CLOCK_THREAD_CPUTIME_ID, &start); - for (i = 0; i < 800; ++i) + for (i = 0; i < 12800; ++i) { xfree (raster); raster = (*test_raster_glyph_outline) (outline); @@ -21265,7 +21243,8 @@ #define RB outline->xmax - outline->origin printf ("time spent building edges: %lld sec %ld nsec\n", (long long) sub1.tv_sec, sub1.tv_nsec); printf ("time spent rasterizing: %lld sec %ld nsec\n", - (long long) sub2.tv_sec / 800, sub2.tv_nsec / 800); + (long long) sub2.tv_sec / 12800, + sub2.tv_nsec / 12800); xfree (outline); } commit 62f2c4386259f998442e8098d8a368835a36fb65 Author: Vincent Belaïche Date: Sun Dec 24 13:02:14 2023 +0100 Fix ses-formula-record * lisp/ses.el (ses-is-cell-sym-p): Tighten test with checking argument is a local variable. (ses-formula-record): Fix definition. (ses-rename-cell): Loosen test on new-name, conversely to 'ses-is-cell-sym-p' tightening. diff --git a/lisp/ses.el b/lisp/ses.el index c86871fa83f..881fe92a940 100644 --- a/lisp/ses.el +++ b/lisp/ses.el @@ -556,13 +556,15 @@ ses-col-printer (defun ses-is-cell-sym-p (sym) "Check whether SYM point at a cell of this spread sheet." - (let ((rowcol (get sym 'ses-cell))) - (and rowcol - (if (eq rowcol :ses-named) - (and ses--named-cell-hashmap (gethash sym ses--named-cell-hashmap)) - (and (< (car rowcol) ses--numrows) - (< (cdr rowcol) ses--numcols) - (eq (ses-cell-symbol (car rowcol) (cdr rowcol)) sym)))))) + (and (symbolp sym) + (local-variable-p sym) + (let ((rowcol (get sym 'ses-cell))) + (and rowcol + (if (eq rowcol :ses-named) + (and ses--named-cell-hashmap (gethash sym ses--named-cell-hashmap)) + (and (< (car rowcol) ses--numrows) + (< (cdr rowcol) ses--numcols) + (eq (ses-cell-symbol (car rowcol) (cdr rowcol)) sym))))))) (defun ses--cell (sym value formula printer references) "Load a cell SYM from the spreadsheet file. @@ -735,10 +737,8 @@ ses-printer-record (defun ses-formula-record (formula) "If FORMULA is of the form \\='SYMBOL, add it to the list of symbolic formulas for this spreadsheet." - (when (and (eq (car-safe formula) 'quote) - (symbolp (cadr formula))) - (add-to-list 'ses--symbolic-formulas - (list (symbol-name (cadr formula)))))) + (and (ses-is-cell-sym-p formula) + (cl-pushnew (symbol-name formula) ses--symbolic-formulas :test #'string=))) (defun ses-column-letter (col) "Return the alphabetic name of column number COL. @@ -3677,9 +3677,8 @@ ses-rename-cell "Rename current cell." (interactive "*SEnter new name: ") (or - (and (local-variable-p new-name) - (ses-is-cell-sym-p new-name) - (error "Already a cell name")) + (and (ses-is-cell-sym-p new-name) + (error "Already a cell name")) (and (boundp new-name) (null (yes-or-no-p (format-message commit a11d34b53e5c32dfc7b8a6eb0c64c087b9b046ba Author: Vincent Belaïche Date: Sun Dec 24 22:05:54 2023 +0100 Fix test about need for explicit printing inserted lines * lisp/ses.el (ses--blank-line-needs-printing-p): New function. Does not consider that printer `nil' produces a non empty string, as `ses-print-cell' removes nil printer by oring to fallback. (ses-insert-row): Replace the complex and erroneous test about blank newline needing printing by a call to 'ses--blank-line-needs-printing-p'. diff --git a/lisp/ses.el b/lisp/ses.el index 23018403cda..c86871fa83f 100644 --- a/lisp/ses.el +++ b/lisp/ses.el @@ -2762,6 +2762,18 @@ ses-read-default-printer ;;---------------------------------------------------------------------------- ;; Spreadsheet size adjustments ;;---------------------------------------------------------------------------- +(defun ses--blank-line-needs-printing-p () + "Returns `t' when blank new line print-out needs to be initialised +by calling the printers on it, `nil' otherwise." + (let (ret + printer + (printers (append ses--col-printers (list ses--default-printer)))) + (while printers + (if (and (setq printer (pop printers)) + (null (string= "" (ses-call-printer printer)))) + (setq ret t + printers nil))) + ret)) (defun ses-insert-row (count) "Insert a new row before the current one. @@ -2794,15 +2806,13 @@ ses-insert-row (ses-goto-data row 0) (insert (make-string (* (1+ ses--numcols) count) ?\n)) (ses-relocate-all row 0 count 0) - ;;If any cell printers insert constant text, insert that text - ;;into the line. - (let ((cols (mapconcat #'ses-call-printer ses--col-printers nil)) - (global (ses-call-printer ses--default-printer))) - (if (or (> (length cols) 0) (> (length global) 0)) - (dotimes (x count) - (dotimes (col ses--numcols) - ;;These cells are always nil, only constant formatting printed - (1value (ses-print-cell (+ x row) col)))))) + ;;If any cell printers insert constant text, insert that text into + ;;the line. + (if (ses--blank-line-needs-printing-p) + (dotimes (x count) + (dotimes (col ses--numcols) + ;;These cells are always nil, only constant formatting printed + (1value (ses-print-cell (+ x row) col))))) (when (> ses--header-row row) ;;Inserting before header (ses-set-parameter 'ses--header-row (+ ses--header-row count)) commit 44676555f9f5cf268104ccdd8eca1666336853ad Author: Vincent Belaïche Date: Sat Dec 23 19:38:56 2023 +0100 More doc on ses+ and argument order * doc/misc/ses.texi (Standard formula functions): Indicate that 'ses+' reverses argument order. diff --git a/doc/misc/ses.texi b/doc/misc/ses.texi index cfca9c25ebb..2949ecd50bd 100644 --- a/doc/misc/ses.texi +++ b/doc/misc/ses.texi @@ -195,6 +195,11 @@ Quick Tutorial (apply '+ (ses-range A2 A5 !)) @end lisp +Actually, both options are not exactly equivalent as the former makes +the summing in reversed order of argument, and the latter in the same +order. You can also reverse the order of arguments returned by +@code{ses-range} with the @code{<} modifier. + @c =================================================================== @node The Basics @@ -1018,7 +1023,7 @@ Standard formula functions @end lisp @item (ses+ &rest @var{args}) -Sum of non-blank arguments. +Sum of non-blank arguments taken in reverse order. @item (ses-average @var{list}) Average of non-blank elements in @var{list}. Here the list is passed commit ba3d3c699e12e2b236a353aa4dbfd1937d47f080 Author: Stefan Monnier Date: Sun Dec 24 10:13:22 2023 -0500 * src/eval.c (signal_or_quit): Fix naming inconsistency with docs The var's docstring and etc/NEWS refer to "*Redisplay-trace*", so better use that (which is also more in line with usual practice of Emacs buffer names). diff --git a/src/eval.c b/src/eval.c index 5ae56292c75..e13bf2103e1 100644 --- a/src/eval.c +++ b/src/eval.c @@ -1841,7 +1841,7 @@ signal_or_quit (Lisp_Object error_symbol, Lisp_Object data, bool keyboard_quit) { max_ensure_room (&max_lisp_eval_depth, lisp_eval_depth, 100); specpdl_ref count = SPECPDL_INDEX (); - AUTO_STRING (redisplay_trace, "*Redisplay_trace*"); + AUTO_STRING (redisplay_trace, "*Redisplay-trace*"); Lisp_Object redisplay_trace_buffer; AUTO_STRING (gap, "\n\n\n\n"); /* Separates things in *Redisplay-trace* */ Lisp_Object delayed_warning; @@ -1857,7 +1857,7 @@ signal_or_quit (Lisp_Object error_symbol, Lisp_Object data, bool keyboard_quit) call_debugger (list2 (Qerror, Fcons (error_symbol, data))); unbind_to (count, Qnil); delayed_warning = make_string - ("Error in a redisplay Lisp hook. See buffer *Redisplay_trace*", 61); + ("Error in a redisplay Lisp hook. See buffer *Redisplay-trace*", 61); Vdelayed_warnings_list = Fcons (list2 (Qerror, delayed_warning), Vdelayed_warnings_list); commit 13e46e2c1d33a3a48ecdcb56b745dbc53a4a3831 Author: Stefan Kangas Date: Sun Dec 24 14:27:48 2023 +0100 checkdoc: Avoid false positive for keybinding in docstring * lisp/emacs-lisp/checkdoc.el (checkdoc-this-string-valid-engine): Avoid false positive when a variable contains a keybinding (for example, "C-g"). (Bug#68002) * test/lisp/emacs-lisp/checkdoc-tests.el (checkdoc-docstring-avoid-false-positive-ok): New test. diff --git a/lisp/emacs-lisp/checkdoc.el b/lisp/emacs-lisp/checkdoc.el index 471a2fbdf48..dd7cfd82b1d 100644 --- a/lisp/emacs-lisp/checkdoc.el +++ b/lisp/emacs-lisp/checkdoc.el @@ -1611,8 +1611,11 @@ checkdoc-this-string-valid-engine (let ((f nil) (m nil) (start (point)) ;; Ignore the "A-" modifier: it is uncommon in practice, ;; and leads to false positives in regexp ranges. - (re "[^`‘A-Za-z0-9_]\\([CMs]-[a-zA-Z]\\|\\(\\([CMs]-\\)?\ -mouse-[0-3]\\)\\)\\>")) + (re (rx (not (any "0-9A-Za-z_`‘-")) + (group (or (seq (any "CMs") "-" (any "A-Za-z")) + (group (opt (group (any "CMs") "-")) + "mouse-" (any "0-3")))) + eow))) ;; Find the first key sequence not in a sample (while (and (not f) (setq m (re-search-forward re e t))) (setq f (not (checkdoc-in-sample-code-p start e)))) diff --git a/test/lisp/emacs-lisp/checkdoc-tests.el b/test/lisp/emacs-lisp/checkdoc-tests.el index 57694bd424b..242e41c7f08 100644 --- a/test/lisp/emacs-lisp/checkdoc-tests.el +++ b/test/lisp/emacs-lisp/checkdoc-tests.el @@ -37,6 +37,15 @@ checkdoc-tests--bug-24998 (insert "(defun foo())") (should-error (checkdoc-defun) :type 'user-error))) +(ert-deftest checkdoc-docstring-avoid-false-positive-ok () + "Check that Bug#68002 is fixed." + (with-temp-buffer + (emacs-lisp-mode) + (insert "(defvar org-element--cache-interrupt-C-g-count 0 + \"Current number of `org-element--cache-sync' calls. +See `org-element--cache-interrupt-C-g'.\")") + (checkdoc-defun))) + (ert-deftest checkdoc-cl-defmethod-ok () "Checkdoc should be happy with a simple correct cl-defmethod." (with-temp-buffer commit 2a1a7a8524c0307c09c91e89816b2b2b8bfb85bc Author: Michael Albinus Date: Sun Dec 24 11:35:16 2023 +0100 Make stty settings configurable in Tramp's make-process * lisp/net/tramp-sh.el (tramp-pipe-stty-settings): New defcustom. (tramp-sh-handle-make-process): Use it. (Bug#62093) diff --git a/lisp/net/tramp-sh.el b/lisp/net/tramp-sh.el index 064045584ae..1777e2f1ed8 100644 --- a/lisp/net/tramp-sh.el +++ b/lisp/net/tramp-sh.el @@ -2877,7 +2877,16 @@ tramp-sh-handle-expand-file-name (tramp-run-real-handler #'expand-file-name (list localname)))))))))) -;;; Remote commands: +;;; Remote processes: + +(defcustom tramp-pipe-stty-settings "-icanon min 1 time 0" + "How to prevent blocking read in pipeline processes. +This is used in `make-process' with `connection-type' `pipe'." + :group 'tramp + :version "29.3" + :type '(choice (const :tag "Use size limit" "-icanon min 1 time 0") + (const :tag "Use timeout" "-icanon min 0 time 1") + string)) ;; We use BUFFER also as connection buffer during setup. Because of ;; this, its original contents must be saved, and restored once @@ -3089,12 +3098,21 @@ tramp-sh-handle-make-process ;; otherwise strings larger than 4096 ;; bytes, sent by the process, could ;; block, see termios(3) and Bug#61341. + ;; In order to prevent blocking read + ;; from pipe processes, "stty -icanon" + ;; is used. By default, it expects at + ;; least one character to read. When a + ;; process does not read from stdin, + ;; like magit, it should set a timeout + ;; instead. See`tramp-pipe-stty-settings'. + ;; (Bug#62093) ;; FIXME: Shall we rather use "stty raw"? - (if (tramp-check-remote-uname v "Darwin") - (tramp-send-command - v "stty -icanon min 1 time 0") - (tramp-send-command - v "stty -icrnl -icanon min 1 time 0"))) + (tramp-send-command + v (format + "stty %s %s" + (if (tramp-check-remote-uname v "Darwin") + "" "-icrnl") + tramp-pipe-stty-settings))) ;; `tramp-maybe-open-connection' and ;; `tramp-send-command-and-read' could ;; have trashed the connection buffer. commit 9b8e0a54318fe909f321a9d437875c99f1bd4451 Author: Eli Zaretskii Date: Sun Dec 24 10:32:45 2023 +0200 Fix toolbar for Log Edit mode * lisp/vc/log-edit.el (log-edit-tool-bar-map): Fix buttons and help messages. * etc/images/README (Files): Fix whitespace. diff --git a/etc/images/README b/etc/images/README index 71115540344..dafabaf7354 100644 --- a/etc/images/README +++ b/etc/images/README @@ -67,7 +67,7 @@ Emacs images and their source in the GNOME icons stock/ directory: attach.xpm document/stock_attach bookmark_add.xpm actions/bookmark_add cancel.xpm slightly modified generic/stock_stop - commit.xpm code/stock_run + commit.xpm code/stock_run connect-to-url.xpm net/stock_connect-to-url connect.xpm net/stock_connect contact.xpm net/stock_contact @@ -76,9 +76,9 @@ Emacs images and their source in the GNOME icons stock/ directory: describe.xpm generic/stock_properties disconnect.xpm net/stock_disconnect exit.xpm generic/stock_exit - gen-changelog.xpm text/stock_autoformat - ins-changelog.xpm form/stock_show-form-dialog - load-changelog.xpm text/stock_insert_endnote + gen-changelog.xpm text/stock_autoformat + ins-changelog.xpm form/stock_show-form-dialog + load-changelog.xpm text/stock_insert_endnote lock-broken.xpm data/stock_lock-broken lock-ok.xpm data/stock_lock-ok lock.xpm data/stock_lock @@ -93,7 +93,7 @@ Emacs images and their source in the GNOME icons stock/ directory: sort-criteria.xpm data/stock_sort-criteria sort-descending.xpm slightly modified data/stock_sort-descending sort-row-ascending.xpm data/stock_sort-row-ascending - view-diff.xpm text/stock_list_enum-restart + view-diff.xpm text/stock_list_enum-restart zoom-in.xpm navigation/stock_zoom-in zoom-out.xpm navigation/stock_zoom-out diff --git a/lisp/vc/log-edit.el b/lisp/vc/log-edit.el index c2665c802f6..2b63419cc53 100644 --- a/lisp/vc/log-edit.el +++ b/lisp/vc/log-edit.el @@ -109,39 +109,34 @@ log-edit-tool-bar-map (tool-bar-local-item-from-menu 'log-edit-done "commit" map log-edit-mode-map :vert-only t :help - "Complete the actual action") + "Exit log buffer and commit the changes") (define-key-after map [separator-2] menu-bar-separator) - (tool-bar-local-item-from-menu 'log-edit-insert-changelog - "ins-changelog" - map log-edit-mode-map :vert-only t - :help - "Complete the actual action") (tool-bar-local-item-from-menu 'log-edit-insert-changelog "load-changelog" map log-edit-mode-map :vert-only t :help - "Insert log message from ChangeLog file") + "Produce log message from ChangeLog file") (tool-bar-local-item-from-menu 'log-edit-generate-changelog-from-diff "gen-changelog" map log-edit-mode-map :vert-only t :help - "Generate a log message from diff") + "Generate log message skeleton from diffs") (tool-bar-local-item-from-menu 'log-edit-add-to-changelog "ins-changelog" map log-edit-mode-map :vert-only t :help - "Insert this log message into the ChangeLog") + "Insert this log message into ChangeLog file") (define-key-after map [separator-3] menu-bar-separator) (tool-bar-local-item-from-menu 'log-edit-show-diff "view-diff" map log-edit-mode-map :vert-only t :help - "View the diff for the files to be committed") + "View diffs for the files to be committed") (tool-bar-local-item-from-menu 'log-edit-show-files "info" map log-edit-mode-map :vert-only t :help - "View the list of files to be committed") + "View list of files to be committed") (define-key-after map [separator-4] menu-bar-separator) (tool-bar-local-item-from-menu 'undo "undo" map nil) (define-key-after map [separator-5] menu-bar-separator)