commit daec3e7b410cdb8deefbb241d056f8b42dfb40ac (HEAD, refs/remotes/origin/master) Author: Po Lu Date: Wed Jan 17 09:30:47 2024 +0800 Increase accuracy of IP instruction * src/sfnt.c (sfnt_interpret_ip): Avoid precision loss by retrieving original positions from the unscaled outline, whenever possible. diff --git a/src/sfnt.c b/src/sfnt.c index 2f0153b9a75..ca4c60e8e3a 100644 --- a/src/sfnt.c +++ b/src/sfnt.c @@ -9640,6 +9640,8 @@ sfnt_interpret_ip (struct sfnt_interpreter *interpreter) sfnt_f26dot6 new_distance; uint32_t p; sfnt_f26dot6 x, y, original_x, original_y; + struct sfnt_interpreter_zone *zone; + bool scale; /* First load both reference points. */ sfnt_address_zp0 (interpreter, interpreter->state.rp1, @@ -9649,6 +9651,57 @@ sfnt_interpret_ip (struct sfnt_interpreter *interpreter) &rp2x, &rp2y, &rp2_original_x, &rp2_original_y); + /* If RP1, RP2, and all arguments all fall within the glyph zone and + a simple glyph is loaded, replace their original coordinates as + loaded here with coordinates from the unscaled glyph outline. */ + + zone = interpreter->glyph_zone; + scale = false; + + if (zone && zone->simple + && interpreter->state.zp0 + && interpreter->state.zp1 + && interpreter->state.zp2) + { + p = interpreter->state.rp1; + + /* If P is a phantom point... */ + if (p >= zone->simple->number_of_points) + { + /* ...scale the phantom point to the size of the original + outline. */ + rp1_original_x = sfnt_div_fixed (rp1_original_x, + interpreter->scale); + rp1_original_y = sfnt_div_fixed (rp1_original_y, + interpreter->scale); + } + else + { + rp1_original_x = zone->simple->x_coordinates[p]; + rp1_original_y = zone->simple->y_coordinates[p]; + } + + p = interpreter->state.rp2; + + /* If P is a phantom point... */ + if (p >= zone->simple->number_of_points) + { + /* ...scale the phantom point to the size of the original + outline. */ + rp2_original_x = sfnt_div_fixed (rp2_original_x, + interpreter->scale); + rp2_original_y = sfnt_div_fixed (rp2_original_y, + interpreter->scale); + } + else + { + rp2_original_x = zone->simple->x_coordinates[p]; + rp2_original_y = zone->simple->y_coordinates[p]; + } + + scale = true; + } + /* Get the original distance between of RP1 and RP2 measured relative to the dual projection vector. */ range = sfnt_dual_project_vector (interpreter, @@ -9657,6 +9710,9 @@ sfnt_interpret_ip (struct sfnt_interpreter *interpreter) sfnt_sub (rp2_original_y, rp1_original_y)); + if (scale) + range = sfnt_mul_fixed_round (range, interpreter->scale); + /* Get the new distance. */ new_range = sfnt_dual_project_vector (interpreter, sfnt_sub (rp2x, rp1x), @@ -9670,6 +9726,25 @@ sfnt_interpret_ip (struct sfnt_interpreter *interpreter) sfnt_address_zp2 (interpreter, p, &x, &y, &original_x, &original_y); + if (scale) + { + /* If P is a phantom point... */ + if (p >= zone->simple->number_of_points) + { + /* ...scale the phantom point to the size of the original + outline. */ + original_x = sfnt_div_fixed (original_x, + interpreter->scale); + original_y = sfnt_div_fixed (original_y, + interpreter->scale); + } + else + { + original_x = zone->simple->x_coordinates[p]; + original_y = zone->simple->y_coordinates[p]; + } + } + /* Now compute the old distance from this point to rp1. */ org_distance = sfnt_dual_project_vector (interpreter, @@ -9678,6 +9753,10 @@ sfnt_interpret_ip (struct sfnt_interpreter *interpreter) sfnt_sub (original_y, rp1_original_y)); + if (scale) + org_distance = sfnt_mul_fixed_round (org_distance, + interpreter->scale); + /* And the current distance from this point to rp1, so how much to move can be determined. */ cur_distance @@ -11447,7 +11526,8 @@ sfnt_interpret_mirp (struct sfnt_interpreter *interpreter, coordinate from the font designer's intentions, either exaggerating or neutralizing the slant of the stem to which it belongs. - This behavior applies only to MDRP, which see. */ + This behavior applies only to MDRP (which see), although a similar + strategy is also applied while interpreting IP instructions. */ static sfnt_f26dot6 sfnt_project_zp1_zp0_org (struct sfnt_interpreter *interpreter, @@ -20715,8 +20795,8 @@ main (int argc, char **argv) return 1; } -#define FANCY_PPEM 16 -#define EASY_PPEM 16 +#define FANCY_PPEM 14 +#define EASY_PPEM 14 interpreter = NULL; head = sfnt_read_head_table (fd, font); commit f19f5604deb72c4d548702b2d9b8565805ffbca1 Author: Mattias EngdegÄrd Date: Mon Jan 15 14:58:43 2024 +0100 Update pdumper hashes for buffer and Lisp_Hash_Table * src/pdumper.c (dump_hash_table): Update for changes in recent hash-table patch suites (bug#68244). (dump_buffer): Update for case-fold-search changes (bug#66117). diff --git a/src/pdumper.c b/src/pdumper.c index 54f0f2bca13..4602931b63a 100644 --- a/src/pdumper.c +++ b/src/pdumper.c @@ -2752,7 +2752,7 @@ dump_hash_table_contents (struct dump_context *ctx, struct Lisp_Hash_Table *h) static dump_off dump_hash_table (struct dump_context *ctx, Lisp_Object object) { -#if CHECK_STRUCTS && !defined HASH_Lisp_Hash_Table_6D63EDB618 +#if CHECK_STRUCTS && !defined HASH_Lisp_Hash_Table_313A489F0A # error "Lisp_Hash_Table changed. See CHECK_STRUCTS comment in config.h." #endif const struct Lisp_Hash_Table *hash_in = XHASH_TABLE (object); @@ -2784,7 +2784,7 @@ dump_hash_table (struct dump_context *ctx, Lisp_Object object) static dump_off dump_buffer (struct dump_context *ctx, const struct buffer *in_buffer) { -#if CHECK_STRUCTS && !defined HASH_buffer_EB0A5191C5 +#if CHECK_STRUCTS && !defined HASH_buffer_EBBA38AEFA # error "buffer changed. See CHECK_STRUCTS comment in config.h." #endif struct buffer munged_buffer = *in_buffer; commit dc404c5d0caac798627751bfd77ed005629abd4e Author: Mattias EngdegÄrd Date: Mon Jan 15 10:58:59 2024 +0100 More efficient hash table thawing * src/fns.c (hash_table_thaw): Don't allocate anything for empty tables. Don't initialise the next vector twice. (maybe_resize_hash_table): Factor out min_size constant. diff --git a/src/fns.c b/src/fns.c index acfedbfa922..5bedf49ef36 100644 --- a/src/fns.c +++ b/src/fns.c @@ -4665,11 +4665,12 @@ maybe_resize_hash_table (struct Lisp_Hash_Table *h) if (h->next_free < 0) { ptrdiff_t old_size = HASH_TABLE_SIZE (h); - ptrdiff_t base_size = min (max (old_size, 8), PTRDIFF_MAX / 2); + ptrdiff_t min_size = 8; + ptrdiff_t base_size = min (max (old_size, min_size), PTRDIFF_MAX / 2); /* Grow aggressively at small sizes, then just double. */ ptrdiff_t new_size = old_size == 0 - ? 8 + ? min_size : (base_size <= 64 ? base_size * 4 : base_size * 2); /* Allocate all the new vectors before updating *H, to @@ -4754,30 +4755,39 @@ hash_table_thaw (Lisp_Object hash_table) h->test = hash_table_test_from_std (h->frozen_test); ptrdiff_t size = h->count; h->table_size = size; - ptrdiff_t index_size = hash_index_size (size); - h->index_size = index_size; h->next_free = -1; - h->hash = hash_table_alloc_bytes (size * sizeof *h->hash); + if (size == 0) + { + h->key_and_value = NULL; + h->hash = NULL; + h->next = NULL; + h->index_size = 1; + h->index = (hash_idx_t *)empty_hash_index_vector; + } + else + { + ptrdiff_t index_size = hash_index_size (size); + h->index_size = index_size; - h->next = hash_table_alloc_bytes (size * sizeof *h->next); - for (ptrdiff_t i = 0; i < size; i++) - h->next[i] = -1; + h->hash = hash_table_alloc_bytes (size * sizeof *h->hash); - h->index = hash_table_alloc_bytes (index_size * sizeof *h->index); - for (ptrdiff_t i = 0; i < index_size; i++) - h->index[i] = -1; + h->next = hash_table_alloc_bytes (size * sizeof *h->next); - /* Recompute the actual hash codes for each entry in the table. - Order is still invalid. */ - for (ptrdiff_t i = 0; i < size; i++) - { - Lisp_Object key = HASH_KEY (h, i); - hash_hash_t hash_code = hash_from_key (h, key); - ptrdiff_t start_of_bucket = hash_index_index (h, hash_code); - set_hash_hash_slot (h, i, hash_code); - set_hash_next_slot (h, i, HASH_INDEX (h, start_of_bucket)); - set_hash_index_slot (h, start_of_bucket, i); + h->index = hash_table_alloc_bytes (index_size * sizeof *h->index); + for (ptrdiff_t i = 0; i < index_size; i++) + h->index[i] = -1; + + /* Recompute the hash codes for each entry in the table. */ + for (ptrdiff_t i = 0; i < size; i++) + { + Lisp_Object key = HASH_KEY (h, i); + hash_hash_t hash_code = hash_from_key (h, key); + ptrdiff_t start_of_bucket = hash_index_index (h, hash_code); + set_hash_hash_slot (h, i, hash_code); + set_hash_next_slot (h, i, HASH_INDEX (h, start_of_bucket)); + set_hash_index_slot (h, start_of_bucket, i); + } } } commit 0b8fe3c73ce4e9a2a8f025655970e86e0d81a0aa Author: Eli Zaretskii Date: Tue Jan 16 19:14:09 2024 +0200 ; * etc/NEWS: Fix wording of recently-added entry. diff --git a/etc/NEWS b/etc/NEWS index 939caed14f6..735a05f6579 100644 --- a/etc/NEWS +++ b/etc/NEWS @@ -264,7 +264,7 @@ right-aligned to is controlled by the new user option ** Windows -*** New buffer display action alist entry 'post-command-select-window'. +*** New action alist entry 'post-command-select-window' for display-buffer. It specifies whether the window of the displayed buffer should be selected or deselected at the end of executing the current command. commit 6f75d0f36dd44fa794ed264042bb6edb4d897bec Author: Juri Linkov Date: Tue Jan 16 18:54:04 2024 +0200 New display action alist entry 'post-command-select-window' (bug#67993) * doc/lispref/windows.texi (Buffer Display Action Alists): Add 'post-command-select-window'. * lisp/window.el (display-buffer): Add 'post-command-select-window' to the docstring and handle at the end of function. diff --git a/doc/lispref/windows.texi b/doc/lispref/windows.texi index 93b25cbe67f..f14e74bc785 100644 --- a/doc/lispref/windows.texi +++ b/doc/lispref/windows.texi @@ -3344,6 +3344,16 @@ It is called @emph{after} the buffer is displayed, and @emph{before} the entries @code{window-height}, @code{window-width} and @code{preserve-size} are applied that could resize the window to fit it to the inserted contents. + +@vindex post-command-select-window@r{, a buffer display action alist entry} +@item post-command-select-window +If the value is non-@code{nil}, the buffer displayed by @code{display-buffer} +is selected after the current command is executed by running the hook +@code{post-command-hook} (@pxref{Command Overview}). +If the value is @code{nil}, the buffer selected by such functions as +@code{pop-to-buffer} is deselected, and the window that was selected +before calling this function will remain selected regardless of which +windows were selected afterwards within this command. @end table By convention, the entries @code{window-height}, @code{window-width} diff --git a/etc/NEWS b/etc/NEWS index 03b8c3b517a..939caed14f6 100644 --- a/etc/NEWS +++ b/etc/NEWS @@ -262,6 +262,12 @@ Anything following the symbol 'mode-line-format-right-align' in right-aligned to is controlled by the new user option 'mode-line-right-align-edge'. +** Windows + +*** New buffer display action alist entry 'post-command-select-window'. +It specifies whether the window of the displayed buffer should be +selected or deselected at the end of executing the current command. + ** Tab Bars and Tab Lines *** New user option 'tab-bar-tab-name-format-functions'. diff --git a/lisp/window.el b/lisp/window.el index 23977691f50..65651b2931b 100644 --- a/lisp/window.el +++ b/lisp/window.el @@ -7798,6 +7798,14 @@ Action alist entries are: and `preserve-size' are applied. The function is supposed to fill the window body with some contents that might depend on dimensions of the displayed window. + `post-command-select-window' -- A non-nil value means that after the + current command is executed and the hook `post-command-hook' is called, + the window displayed by this function will be selected. A nil value + means that if functions like `pop-to-buffer' selected another window, + at the end of this command that window will be deselected, and the + window that was selected before calling this function will remain + selected regardless of which windows were selected afterwards within + this command. The entries `window-height', `window-width', `window-size' and `preserve-size' are applied only when the window used for @@ -7853,6 +7861,17 @@ specified by the ACTION argument." (while (and functions (not window)) (setq window (funcall (car functions) buffer alist) functions (cdr functions))) + (when-let ((select (assq 'post-command-select-window alist))) + (letrec ((old-selected-window (selected-window)) + (postfun + (lambda () + (if (cdr select) + (when (window-live-p window) + (select-window window)) + (when (window-live-p old-selected-window) + (select-window old-selected-window))) + (remove-hook 'post-command-hook postfun)))) + (add-hook 'post-command-hook postfun))) (and (windowp window) window)))) (defun display-buffer-other-frame (buffer)