aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorAndrea Corallo2020-12-12 15:31:33 +0100
committerAndrea Corallo2020-12-12 15:31:33 +0100
commit0474fda62d79cb7eb250f34f19773c87f283c665 (patch)
treedf7418a6b22fbbfda725c56825ec0290f8e6be39 /src
parentbe907b0ba82c2a65e0468d50653cae8a7cf5f16b (diff)
parent4afef614cd6c93b4d4a57aa5bb211563649abc56 (diff)
downloademacs-0474fda62d79cb7eb250f34f19773c87f283c665.tar.gz
emacs-0474fda62d79cb7eb250f34f19773c87f283c665.zip
Merge remote-tracking branch 'savannah/master' into HEAD
Diffstat (limited to 'src')
-rw-r--r--src/charset.c4
-rw-r--r--src/chartab.c6
-rw-r--r--src/data.c5
-rw-r--r--src/emacs.c13
-rw-r--r--src/eval.c11
-rw-r--r--src/fileio.c7
-rw-r--r--src/fns.c78
-rw-r--r--src/frame.c12
-rw-r--r--src/image.c124
-rw-r--r--src/lisp.h33
-rw-r--r--src/nsterm.m10
-rw-r--r--src/regex-emacs.c17
-rw-r--r--src/w32gui.h1
-rw-r--r--src/w32term.c11
-rw-r--r--src/window.c56
-rw-r--r--src/xdisp.c40
16 files changed, 314 insertions, 114 deletions
diff --git a/src/charset.c b/src/charset.c
index 520dd3a9605..f6b5173fad4 100644
--- a/src/charset.c
+++ b/src/charset.c
@@ -800,7 +800,9 @@ RANGE is a cons (FROM . TO), where FROM and TO indicate a range of
800characters contained in CHARSET. 800characters contained in CHARSET.
801 801
802The optional 4th and 5th arguments FROM-CODE and TO-CODE specify the 802The optional 4th and 5th arguments FROM-CODE and TO-CODE specify the
803range of code points (in CHARSET) of target characters. */) 803range of code points (in CHARSET) of target characters. Note that
804these are not character codes, but code points in CHARSET; for the
805difference see `decode-char' and `list-charset-chars'. */)
804 (Lisp_Object function, Lisp_Object charset, Lisp_Object arg, Lisp_Object from_code, Lisp_Object to_code) 806 (Lisp_Object function, Lisp_Object charset, Lisp_Object arg, Lisp_Object from_code, Lisp_Object to_code)
805{ 807{
806 struct charset *cs; 808 struct charset *cs;
diff --git a/src/chartab.c b/src/chartab.c
index cb2ced568d9..331e8595ebe 100644
--- a/src/chartab.c
+++ b/src/chartab.c
@@ -1000,10 +1000,10 @@ map_sub_char_table_for_charset (void (*c_function) (Lisp_Object, Lisp_Object),
1000 "mapping table" or a "deunifier table" of a certain charset. 1000 "mapping table" or a "deunifier table" of a certain charset.
1001 1001
1002 If CHARSET is not NULL (this is the case that `map-charset-chars' 1002 If CHARSET is not NULL (this is the case that `map-charset-chars'
1003 is called with non-nil FROM-CODE and TO-CODE), it is a charset who 1003 is called with non-nil FROM-CODE and TO-CODE), it is a charset that
1004 owns TABLE, and the function is called only on a character in the 1004 owns TABLE, and the function is called only for characters in the
1005 range FROM and TO. FROM and TO are not character codes, but code 1005 range FROM and TO. FROM and TO are not character codes, but code
1006 points of a character in CHARSET. 1006 points of characters in CHARSET (see 'decode-char').
1007 1007
1008 This function is called in these two cases: 1008 This function is called in these two cases:
1009 1009
diff --git a/src/data.c b/src/data.c
index fea39867c99..544b20d50cc 100644
--- a/src/data.c
+++ b/src/data.c
@@ -1700,8 +1700,9 @@ default_value (Lisp_Object symbol)
1700 1700
1701DEFUN ("default-boundp", Fdefault_boundp, Sdefault_boundp, 1, 1, 0, 1701DEFUN ("default-boundp", Fdefault_boundp, Sdefault_boundp, 1, 1, 0,
1702 doc: /* Return t if SYMBOL has a non-void default value. 1702 doc: /* Return t if SYMBOL has a non-void default value.
1703This is the value that is seen in buffers that do not have their own values 1703A variable may have a buffer-local or a `let'-bound local value. This
1704for this variable. */) 1704function says whether the variable has a non-void value outside of the
1705current context. Also see `default-value'. */)
1705 (Lisp_Object symbol) 1706 (Lisp_Object symbol)
1706{ 1707{
1707 register Lisp_Object value; 1708 register Lisp_Object value;
diff --git a/src/emacs.c b/src/emacs.c
index afcdb667821..afdfcade777 100644
--- a/src/emacs.c
+++ b/src/emacs.c
@@ -2398,10 +2398,13 @@ all of which are called before Emacs is actually killed. */
2398 /* Fsignal calls emacs_abort () if it sees that waiting_for_input is 2398 /* Fsignal calls emacs_abort () if it sees that waiting_for_input is
2399 set. */ 2399 set. */
2400 waiting_for_input = 0; 2400 waiting_for_input = 0;
2401 if (noninteractive) 2401 if (!NILP (find_symbol_value (Qkill_emacs_hook)))
2402 safe_run_hooks (Qkill_emacs_hook); 2402 {
2403 else 2403 if (noninteractive)
2404 run_hook (Qkill_emacs_hook); 2404 safe_run_hooks (Qkill_emacs_hook);
2405 else
2406 call1 (Qrun_hook_query_error_with_timeout, Qkill_emacs_hook);
2407 }
2405 2408
2406#ifdef HAVE_X_WINDOWS 2409#ifdef HAVE_X_WINDOWS
2407 /* Transfer any clipboards we own to the clipboard manager. */ 2410 /* Transfer any clipboards we own to the clipboard manager. */
@@ -2927,6 +2930,8 @@ syms_of_emacs (void)
2927 DEFSYM (Qrisky_local_variable, "risky-local-variable"); 2930 DEFSYM (Qrisky_local_variable, "risky-local-variable");
2928 DEFSYM (Qkill_emacs, "kill-emacs"); 2931 DEFSYM (Qkill_emacs, "kill-emacs");
2929 DEFSYM (Qkill_emacs_hook, "kill-emacs-hook"); 2932 DEFSYM (Qkill_emacs_hook, "kill-emacs-hook");
2933 DEFSYM (Qrun_hook_query_error_with_timeout,
2934 "run-hook-query-error-with-timeout");
2930 2935
2931#ifdef HAVE_UNEXEC 2936#ifdef HAVE_UNEXEC
2932 defsubr (&Sdump_emacs); 2937 defsubr (&Sdump_emacs);
diff --git a/src/eval.c b/src/eval.c
index fb747c58838..2b31b91175b 100644
--- a/src/eval.c
+++ b/src/eval.c
@@ -1799,7 +1799,8 @@ signal_or_quit (Lisp_Object error_symbol, Lisp_Object data, bool keyboard_quit)
1799 debugging. Make sure to use `debug' unconditionally to not interfere with 1799 debugging. Make sure to use `debug' unconditionally to not interfere with
1800 ERT or other packages that install custom debuggers. */ 1800 ERT or other packages that install custom debuggers. */
1801 if (!debugger_called && !NILP (error_symbol) 1801 if (!debugger_called && !NILP (error_symbol)
1802 && (NILP (clause) || EQ (h->tag_or_ch, Qerror)) && noninteractive) 1802 && (NILP (clause) || EQ (h->tag_or_ch, Qerror)) && noninteractive
1803 && backtrace_on_error_noninteractive)
1803 { 1804 {
1804 ptrdiff_t count = SPECPDL_INDEX (); 1805 ptrdiff_t count = SPECPDL_INDEX ();
1805 specbind (Vdebugger, Qdebug); 1806 specbind (Vdebugger, Qdebug);
@@ -4344,6 +4345,14 @@ Note that `debug-on-error', `debug-on-quit' and friends
4344still determine whether to handle the particular condition. */); 4345still determine whether to handle the particular condition. */);
4345 Vdebug_on_signal = Qnil; 4346 Vdebug_on_signal = Qnil;
4346 4347
4348 DEFVAR_BOOL ("backtrace-on-error-noninteractive",
4349 backtrace_on_error_noninteractive,
4350 doc: /* Non-nil means print backtrace on error in batch mode.
4351If this is nil, errors in batch mode will just print the error
4352message upon encountering an unhandled error, without showing
4353the Lisp backtrace. */);
4354 backtrace_on_error_noninteractive = true;
4355
4347 /* The value of num_nonmacro_input_events as of the last time we 4356 /* The value of num_nonmacro_input_events as of the last time we
4348 started to enter the debugger. If we decide to enter the debugger 4357 started to enter the debugger. If we decide to enter the debugger
4349 again when this is still equal to num_nonmacro_input_events, then we 4358 again when this is still equal to num_nonmacro_input_events, then we
diff --git a/src/fileio.c b/src/fileio.c
index 283813ff89e..702c1438283 100644
--- a/src/fileio.c
+++ b/src/fileio.c
@@ -3757,9 +3757,10 @@ characters in the buffer. If VISIT is non-nil, BEG and END must be nil.
3757If optional fifth argument REPLACE is non-nil, replace the current 3757If optional fifth argument REPLACE is non-nil, replace the current
3758buffer contents (in the accessible portion) with the file contents. 3758buffer contents (in the accessible portion) with the file contents.
3759This is better than simply deleting and inserting the whole thing 3759This is better than simply deleting and inserting the whole thing
3760because (1) it preserves some marker positions and (2) it puts less data 3760because (1) it preserves some marker positions (in unchanged portions
3761in the undo list. When REPLACE is non-nil, the second return value is 3761at the start and end of the buffer) and (2) it puts less data in the
3762the number of characters that replace previous buffer contents. 3762undo list. When REPLACE is non-nil, the second return value is the
3763number of characters that replace previous buffer contents.
3763 3764
3764This function does code conversion according to the value of 3765This function does code conversion according to the value of
3765`coding-system-for-read' or `file-coding-system-alist', and sets the 3766`coding-system-for-read' or `file-coding-system-alist', and sets the
diff --git a/src/fns.c b/src/fns.c
index e4c9acc3163..f77092972ab 100644
--- a/src/fns.c
+++ b/src/fns.c
@@ -4525,18 +4525,40 @@ sweep_weak_table (struct Lisp_Hash_Table *h, bool remove_entries_p)
4525EMACS_UINT 4525EMACS_UINT
4526hash_string (char const *ptr, ptrdiff_t len) 4526hash_string (char const *ptr, ptrdiff_t len)
4527{ 4527{
4528 char const *p = ptr; 4528 if (len < 16)
4529 char const *end = p + len;
4530 unsigned char c;
4531 EMACS_UINT hash = 0;
4532
4533 while (p != end)
4534 { 4529 {
4535 c = *p++; 4530 char const *p = ptr;
4536 hash = sxhash_combine (hash, c); 4531 char const *end = p + len;
4532 EMACS_UINT hash = len;
4533
4534 while (p < end)
4535 {
4536 unsigned char c = *p++;
4537 hash = sxhash_combine (hash, c);
4538 }
4539
4540 return hash;
4537 } 4541 }
4542 else
4543 {
4544 EMACS_UINT const *p = (EMACS_UINT const *) ptr;
4545 EMACS_UINT const *end = (EMACS_UINT const *) (ptr + len);
4546 EMACS_UINT hash = len;
4547 /* At most 8 steps. We could reuse SXHASH_MAX_LEN, of course,
4548 * but dividing by 8 is cheaper. */
4549 ptrdiff_t step = max (1, (end - p) >> 3);
4550
4551 /* Beware: `end` might be unaligned, so `p < end` is not always the same
4552 * as `p <= end - 1`. */
4553 while (p <= end - 1)
4554 {
4555 EMACS_UINT c = *p;
4556 p += step;
4557 hash = sxhash_combine (hash, c);
4558 }
4538 4559
4539 return hash; 4560 return hash;
4561 }
4540} 4562}
4541 4563
4542/* Return a hash for string PTR which has length LEN. The hash 4564/* Return a hash for string PTR which has length LEN. The hash
@@ -5418,7 +5440,8 @@ disregarding any coding systems. If nil, use the current buffer.
5418 5440
5419This function is useful for comparing two buffers running in the same 5441This function is useful for comparing two buffers running in the same
5420Emacs, but is not guaranteed to return the same hash between different 5442Emacs, but is not guaranteed to return the same hash between different
5421Emacs versions. 5443Emacs versions. It should be somewhat more efficient on larger
5444buffers than `secure-hash' is, and should not allocate more memory.
5422 5445
5423It should not be used for anything security-related. See 5446It should not be used for anything security-related. See
5424`secure-hash' for these applications. */ ) 5447`secure-hash' for these applications. */ )
@@ -5551,6 +5574,40 @@ Case is always significant and text properties are ignored. */)
5551 5574
5552 return make_int (string_byte_to_char (haystack, res - SSDATA (haystack))); 5575 return make_int (string_byte_to_char (haystack, res - SSDATA (haystack)));
5553} 5576}
5577
5578static void
5579collect_interval (INTERVAL interval, Lisp_Object collector)
5580{
5581 nconc2 (collector,
5582 list1(list3 (make_fixnum (interval->position),
5583 make_fixnum (interval->position + LENGTH (interval)),
5584 interval->plist)));
5585}
5586
5587DEFUN ("object-intervals", Fobject_intervals, Sobject_intervals, 1, 1, 0,
5588 doc: /* Return a copy of the text properties of OBJECT.
5589OBJECT must be a buffer or a string.
5590
5591Altering this copy does not change the layout of the text properties
5592in OBJECT. */)
5593 (register Lisp_Object object)
5594{
5595 Lisp_Object collector = Fcons (Qnil, Qnil);
5596 INTERVAL intervals;
5597
5598 if (STRINGP (object))
5599 intervals = string_intervals (object);
5600 else if (BUFFERP (object))
5601 intervals = buffer_intervals (XBUFFER (object));
5602 else
5603 wrong_type_argument (Qbuffer_or_string_p, object);
5604
5605 if (! intervals)
5606 return Qnil;
5607
5608 traverse_intervals (intervals, 0, collect_interval, collector);
5609 return CDR (collector);
5610}
5554 5611
5555 5612
5556void 5613void
@@ -5592,6 +5649,7 @@ syms_of_fns (void)
5592 defsubr (&Smaphash); 5649 defsubr (&Smaphash);
5593 defsubr (&Sdefine_hash_table_test); 5650 defsubr (&Sdefine_hash_table_test);
5594 defsubr (&Sstring_search); 5651 defsubr (&Sstring_search);
5652 defsubr (&Sobject_intervals);
5595 5653
5596 /* Crypto and hashing stuff. */ 5654 /* Crypto and hashing stuff. */
5597 DEFSYM (Qiv_auto, "iv-auto"); 5655 DEFSYM (Qiv_auto, "iv-auto");
diff --git a/src/frame.c b/src/frame.c
index 17ec455d2d6..164c05cae85 100644
--- a/src/frame.c
+++ b/src/frame.c
@@ -3577,7 +3577,9 @@ window managers may refuse to honor a HEIGHT that is not an integer
3577multiple of the default frame font height. 3577multiple of the default frame font height.
3578 3578
3579When called interactively, HEIGHT is the numeric prefix and the 3579When called interactively, HEIGHT is the numeric prefix and the
3580currently selected frame will be set to this height. */) 3580currently selected frame will be set to this height.
3581
3582If FRAME is nil, it defaults to the selected frame. */)
3581 (Lisp_Object frame, Lisp_Object height, Lisp_Object pretend, Lisp_Object pixelwise) 3583 (Lisp_Object frame, Lisp_Object height, Lisp_Object pretend, Lisp_Object pixelwise)
3582{ 3584{
3583 struct frame *f = decode_live_frame (frame); 3585 struct frame *f = decode_live_frame (frame);
@@ -3600,7 +3602,9 @@ window managers may refuse to honor a WIDTH that is not an integer
3600multiple of the default frame font width. 3602multiple of the default frame font width.
3601 3603
3602When called interactively, WIDTH is the numeric prefix and the 3604When called interactively, WIDTH is the numeric prefix and the
3603currently selected frame will be set to this width. */) 3605currently selected frame will be set to this width.
3606
3607If FRAME is nil, it defaults to the selected frame. */)
3604 (Lisp_Object frame, Lisp_Object width, Lisp_Object pretend, Lisp_Object pixelwise) 3608 (Lisp_Object frame, Lisp_Object width, Lisp_Object pretend, Lisp_Object pixelwise)
3605{ 3609{
3606 struct frame *f = decode_live_frame (frame); 3610 struct frame *f = decode_live_frame (frame);
@@ -3616,7 +3620,9 @@ Optional argument PIXELWISE non-nil means to measure in pixels. Note:
3616When `frame-resize-pixelwise' is nil, some window managers may refuse to 3620When `frame-resize-pixelwise' is nil, some window managers may refuse to
3617honor a WIDTH that is not an integer multiple of the default frame font 3621honor a WIDTH that is not an integer multiple of the default frame font
3618width or a HEIGHT that is not an integer multiple of the default frame 3622width or a HEIGHT that is not an integer multiple of the default frame
3619font height. */) 3623font height.
3624
3625If FRAME is nil, it defaults to the selected frame. */)
3620 (Lisp_Object frame, Lisp_Object width, Lisp_Object height, Lisp_Object pixelwise) 3626 (Lisp_Object frame, Lisp_Object width, Lisp_Object height, Lisp_Object pixelwise)
3621{ 3627{
3622 struct frame *f = decode_live_frame (frame); 3628 struct frame *f = decode_live_frame (frame);
diff --git a/src/image.c b/src/image.c
index 5eb41322950..6b85ab78f61 100644
--- a/src/image.c
+++ b/src/image.c
@@ -1592,17 +1592,6 @@ make_image_cache (void)
1592 return c; 1592 return c;
1593} 1593}
1594 1594
1595/* Compare two lists (one of which must be proper), comparing each
1596 element with `eq'. */
1597static bool
1598equal_lists (Lisp_Object a, Lisp_Object b)
1599{
1600 while (CONSP (a) && CONSP (b) && EQ (XCAR (a), XCAR (b)))
1601 a = XCDR (a), b = XCDR (b);
1602
1603 return EQ (a, b);
1604}
1605
1606/* Find an image matching SPEC in the cache, and return it. If no 1595/* Find an image matching SPEC in the cache, and return it. If no
1607 image is found, return NULL. */ 1596 image is found, return NULL. */
1608static struct image * 1597static struct image *
@@ -1630,7 +1619,7 @@ search_image_cache (struct frame *f, Lisp_Object spec, EMACS_UINT hash,
1630 1619
1631 for (img = c->buckets[i]; img; img = img->next) 1620 for (img = c->buckets[i]; img; img = img->next)
1632 if (img->hash == hash 1621 if (img->hash == hash
1633 && equal_lists (img->spec, spec) 1622 && !NILP (Fequal (img->spec, spec))
1634 && (ignore_colors || (img->face_foreground == foreground 1623 && (ignore_colors || (img->face_foreground == foreground
1635 && img->face_background == background))) 1624 && img->face_background == background)))
1636 break; 1625 break;
@@ -1644,12 +1633,13 @@ static void
1644uncache_image (struct frame *f, Lisp_Object spec) 1633uncache_image (struct frame *f, Lisp_Object spec)
1645{ 1634{
1646 struct image *img; 1635 struct image *img;
1636 EMACS_UINT hash = sxhash (spec);
1647 1637
1648 /* Because the background colors are based on the current face, we 1638 /* Because the background colors are based on the current face, we
1649 can have multiple copies of an image with the same spec. We want 1639 can have multiple copies of an image with the same spec. We want
1650 to remove them all to ensure the user doesn't see an old version 1640 to remove them all to ensure the user doesn't see an old version
1651 of the image when the face changes. */ 1641 of the image when the face changes. */
1652 while ((img = search_image_cache (f, spec, sxhash (spec), 0, 0, true))) 1642 while ((img = search_image_cache (f, spec, hash, 0, 0, true)))
1653 { 1643 {
1654 free_image (f, img); 1644 free_image (f, img);
1655 /* As display glyphs may still be referring to the image ID, we 1645 /* As display glyphs may still be referring to the image ID, we
@@ -1802,6 +1792,55 @@ which is then usually a filename. */)
1802 return Qnil; 1792 return Qnil;
1803} 1793}
1804 1794
1795static size_t
1796image_frame_cache_size (struct frame *f)
1797{
1798 size_t total = 0;
1799#if defined USE_CAIRO
1800 struct image_cache *c = FRAME_IMAGE_CACHE (f);
1801
1802 if (!c)
1803 return 0;
1804
1805 for (ptrdiff_t i = 0; i < c->used; ++i)
1806 {
1807 struct image *img = c->images[i];
1808
1809 if (img && img->pixmap && img->pixmap != NO_PIXMAP)
1810 total += img->pixmap->width * img->pixmap->height *
1811 img->pixmap->bits_per_pixel / 8;
1812 }
1813#elif defined HAVE_NTGUI
1814 struct image_cache *c = FRAME_IMAGE_CACHE (f);
1815
1816 if (!c)
1817 return 0;
1818
1819 for (ptrdiff_t i = 0; i < c->used; ++i)
1820 {
1821 struct image *img = c->images[i];
1822
1823 if (img && img->pixmap && img->pixmap != NO_PIXMAP)
1824 total += w32_image_size (img);
1825 }
1826#endif
1827 return total;
1828}
1829
1830DEFUN ("image-cache-size", Fimage_cache_size, Simage_cache_size, 0, 0, 0,
1831 doc: /* Return the size of the image cache. */)
1832 (void)
1833{
1834 Lisp_Object tail, frame;
1835 size_t total = 0;
1836
1837 FOR_EACH_FRAME (tail, frame)
1838 if (FRAME_WINDOW_P (XFRAME (frame)))
1839 total += image_frame_cache_size (XFRAME (frame));
1840
1841 return make_int (total);
1842}
1843
1805 1844
1806DEFUN ("image-flush", Fimage_flush, Simage_flush, 1845DEFUN ("image-flush", Fimage_flush, Simage_flush,
1807 1, 2, 0, 1846 1, 2, 0,
@@ -9453,6 +9492,7 @@ enum svg_keyword_index
9453 SVG_TYPE, 9492 SVG_TYPE,
9454 SVG_DATA, 9493 SVG_DATA,
9455 SVG_FILE, 9494 SVG_FILE,
9495 SVG_BASE_URI,
9456 SVG_ASCENT, 9496 SVG_ASCENT,
9457 SVG_MARGIN, 9497 SVG_MARGIN,
9458 SVG_RELIEF, 9498 SVG_RELIEF,
@@ -9472,6 +9512,7 @@ static const struct image_keyword svg_format[SVG_LAST] =
9472 {":type", IMAGE_SYMBOL_VALUE, 1}, 9512 {":type", IMAGE_SYMBOL_VALUE, 1},
9473 {":data", IMAGE_STRING_VALUE, 0}, 9513 {":data", IMAGE_STRING_VALUE, 0},
9474 {":file", IMAGE_STRING_VALUE, 0}, 9514 {":file", IMAGE_STRING_VALUE, 0},
9515 {":base-uri", IMAGE_STRING_VALUE, 0},
9475 {":ascent", IMAGE_ASCENT_VALUE, 0}, 9516 {":ascent", IMAGE_ASCENT_VALUE, 0},
9476 {":margin", IMAGE_NON_NEGATIVE_INTEGER_VALUE_OR_PAIR, 0}, 9517 {":margin", IMAGE_NON_NEGATIVE_INTEGER_VALUE_OR_PAIR, 0},
9477 {":relief", IMAGE_INTEGER_VALUE, 0}, 9518 {":relief", IMAGE_INTEGER_VALUE, 0},
@@ -9544,6 +9585,9 @@ DEF_DLL_FN (gboolean, rsvg_handle_write,
9544DEF_DLL_FN (gboolean, rsvg_handle_close, (RsvgHandle *, GError **)); 9585DEF_DLL_FN (gboolean, rsvg_handle_close, (RsvgHandle *, GError **));
9545# endif 9586# endif
9546 9587
9588DEF_DLL_FN (void, rsvg_handle_set_dpi_x_y,
9589 (RsvgHandle * handle, double dpi_x, double dpi_y));
9590
9547# if LIBRSVG_CHECK_VERSION (2, 46, 0) 9591# if LIBRSVG_CHECK_VERSION (2, 46, 0)
9548DEF_DLL_FN (void, rsvg_handle_get_intrinsic_dimensions, 9592DEF_DLL_FN (void, rsvg_handle_get_intrinsic_dimensions,
9549 (RsvgHandle *, gboolean *, RsvgLength *, gboolean *, 9593 (RsvgHandle *, gboolean *, RsvgLength *, gboolean *,
@@ -9600,6 +9644,7 @@ init_svg_functions (void)
9600 LOAD_DLL_FN (library, rsvg_handle_write); 9644 LOAD_DLL_FN (library, rsvg_handle_write);
9601 LOAD_DLL_FN (library, rsvg_handle_close); 9645 LOAD_DLL_FN (library, rsvg_handle_close);
9602#endif 9646#endif
9647 LOAD_DLL_FN (library, rsvg_handle_set_dpi_x_y);
9603#if LIBRSVG_CHECK_VERSION (2, 46, 0) 9648#if LIBRSVG_CHECK_VERSION (2, 46, 0)
9604 LOAD_DLL_FN (library, rsvg_handle_get_intrinsic_dimensions); 9649 LOAD_DLL_FN (library, rsvg_handle_get_intrinsic_dimensions);
9605 LOAD_DLL_FN (library, rsvg_handle_get_geometry_for_layer); 9650 LOAD_DLL_FN (library, rsvg_handle_get_geometry_for_layer);
@@ -9655,6 +9700,7 @@ init_svg_functions (void)
9655# undef rsvg_handle_set_base_uri 9700# undef rsvg_handle_set_base_uri
9656# undef rsvg_handle_write 9701# undef rsvg_handle_write
9657# endif 9702# endif
9703# undef rsvg_handle_set_dpi_x_y
9658 9704
9659# define gdk_pixbuf_get_bits_per_sample fn_gdk_pixbuf_get_bits_per_sample 9705# define gdk_pixbuf_get_bits_per_sample fn_gdk_pixbuf_get_bits_per_sample
9660# define gdk_pixbuf_get_colorspace fn_gdk_pixbuf_get_colorspace 9706# define gdk_pixbuf_get_colorspace fn_gdk_pixbuf_get_colorspace
@@ -9688,6 +9734,7 @@ init_svg_functions (void)
9688# define rsvg_handle_set_base_uri fn_rsvg_handle_set_base_uri 9734# define rsvg_handle_set_base_uri fn_rsvg_handle_set_base_uri
9689# define rsvg_handle_write fn_rsvg_handle_write 9735# define rsvg_handle_write fn_rsvg_handle_write
9690# endif 9736# endif
9737# define rsvg_handle_set_dpi_x_y fn_rsvg_handle_set_dpi_x_y
9691 9738
9692# endif /* !WINDOWSNT */ 9739# endif /* !WINDOWSNT */
9693 9740
@@ -9698,10 +9745,11 @@ static bool
9698svg_load (struct frame *f, struct image *img) 9745svg_load (struct frame *f, struct image *img)
9699{ 9746{
9700 bool success_p = 0; 9747 bool success_p = 0;
9701 Lisp_Object file_name; 9748 Lisp_Object file_name, base_uri;
9702 9749
9703 /* If IMG->spec specifies a file name, create a non-file spec from it. */ 9750 /* If IMG->spec specifies a file name, create a non-file spec from it. */
9704 file_name = image_spec_value (img->spec, QCfile, NULL); 9751 file_name = image_spec_value (img->spec, QCfile, NULL);
9752 base_uri = image_spec_value (img->spec, QCbase_uri, NULL);
9705 if (STRINGP (file_name)) 9753 if (STRINGP (file_name))
9706 { 9754 {
9707 int fd; 9755 int fd;
@@ -9721,15 +9769,16 @@ svg_load (struct frame *f, struct image *img)
9721 return 0; 9769 return 0;
9722 } 9770 }
9723 /* If the file was slurped into memory properly, parse it. */ 9771 /* If the file was slurped into memory properly, parse it. */
9724 success_p = svg_load_image (f, img, contents, size, 9772 if (!STRINGP (base_uri))
9725 SSDATA (ENCODE_FILE (file))); 9773 base_uri = ENCODE_FILE (file);
9774 success_p = svg_load_image (f, img, contents, size, SSDATA (base_uri));
9726 xfree (contents); 9775 xfree (contents);
9727 } 9776 }
9728 /* Else it's not a file, it's a Lisp object. Load the image from a 9777 /* Else it's not a file, it's a Lisp object. Load the image from a
9729 Lisp object rather than a file. */ 9778 Lisp object rather than a file. */
9730 else 9779 else
9731 { 9780 {
9732 Lisp_Object data, original_filename; 9781 Lisp_Object data;
9733 9782
9734 data = image_spec_value (img->spec, QCdata, NULL); 9783 data = image_spec_value (img->spec, QCdata, NULL);
9735 if (!STRINGP (data)) 9784 if (!STRINGP (data))
@@ -9737,10 +9786,10 @@ svg_load (struct frame *f, struct image *img)
9737 image_error ("Invalid image data `%s'", data); 9786 image_error ("Invalid image data `%s'", data);
9738 return 0; 9787 return 0;
9739 } 9788 }
9740 original_filename = BVAR (current_buffer, filename); 9789 if (!STRINGP (base_uri))
9790 base_uri = BVAR (current_buffer, filename);
9741 success_p = svg_load_image (f, img, SSDATA (data), SBYTES (data), 9791 success_p = svg_load_image (f, img, SSDATA (data), SBYTES (data),
9742 (NILP (original_filename) ? NULL 9792 (NILP (base_uri) ? NULL : SSDATA (base_uri)));
9743 : SSDATA (original_filename)));
9744 } 9793 }
9745 9794
9746 return success_p; 9795 return success_p;
@@ -9748,11 +9797,8 @@ svg_load (struct frame *f, struct image *img)
9748 9797
9749#if LIBRSVG_CHECK_VERSION (2, 46, 0) 9798#if LIBRSVG_CHECK_VERSION (2, 46, 0)
9750static double 9799static double
9751svg_css_length_to_pixels (RsvgLength length) 9800svg_css_length_to_pixels (RsvgLength length, double dpi)
9752{ 9801{
9753 /* FIXME: 96 appears to be a pretty standard DPI but we should
9754 probably use the real DPI if we can get it. */
9755 double dpi = 96;
9756 double value = length.length; 9802 double value = length.length;
9757 9803
9758 switch (length.unit) 9804 switch (length.unit)
@@ -9826,6 +9872,9 @@ svg_load_image (struct frame *f, struct image *img, char *contents,
9826 rsvg_handle = rsvg_handle_new_from_stream_sync (input_stream, base_file, 9872 rsvg_handle = rsvg_handle_new_from_stream_sync (input_stream, base_file,
9827 RSVG_HANDLE_FLAGS_NONE, 9873 RSVG_HANDLE_FLAGS_NONE,
9828 NULL, &err); 9874 NULL, &err);
9875 rsvg_handle_set_dpi_x_y (rsvg_handle, FRAME_DISPLAY_INFO (f)->resx,
9876 FRAME_DISPLAY_INFO (f)->resy);
9877
9829 if (base_file) 9878 if (base_file)
9830 g_object_unref (base_file); 9879 g_object_unref (base_file);
9831 g_object_unref (input_stream); 9880 g_object_unref (input_stream);
@@ -9837,7 +9886,11 @@ svg_load_image (struct frame *f, struct image *img, char *contents,
9837 rsvg_handle = rsvg_handle_new (); 9886 rsvg_handle = rsvg_handle_new ();
9838 eassume (rsvg_handle); 9887 eassume (rsvg_handle);
9839 9888
9889 rsvg_handle_set_dpi_x_y (rsvg_handle, FRAME_DISPLAY_INFO (f)->resx,
9890 FRAME_DISPLAY_INFO (f)->resy);
9891
9840 /* Set base_uri for properly handling referenced images (via 'href'). 9892 /* Set base_uri for properly handling referenced images (via 'href').
9893 Can be explicitly specified using `:base_uri' image property.
9841 See rsvg bug 596114 - "image refs are relative to curdir, not .svg file" 9894 See rsvg bug 596114 - "image refs are relative to curdir, not .svg file"
9842 <https://gitlab.gnome.org/GNOME/librsvg/issues/33>. */ 9895 <https://gitlab.gnome.org/GNOME/librsvg/issues/33>. */
9843 if (filename) 9896 if (filename)
@@ -9860,6 +9913,7 @@ svg_load_image (struct frame *f, struct image *img, char *contents,
9860 /* Try the instrinsic dimensions first. */ 9913 /* Try the instrinsic dimensions first. */
9861 gboolean has_width, has_height, has_viewbox; 9914 gboolean has_width, has_height, has_viewbox;
9862 RsvgLength iwidth, iheight; 9915 RsvgLength iwidth, iheight;
9916 double dpi = FRAME_DISPLAY_INFO (f)->resx;
9863 9917
9864 rsvg_handle_get_intrinsic_dimensions (rsvg_handle, 9918 rsvg_handle_get_intrinsic_dimensions (rsvg_handle,
9865 &has_width, &iwidth, 9919 &has_width, &iwidth,
@@ -9869,19 +9923,19 @@ svg_load_image (struct frame *f, struct image *img, char *contents,
9869 if (has_width && has_height) 9923 if (has_width && has_height)
9870 { 9924 {
9871 /* Success! We can use these values directly. */ 9925 /* Success! We can use these values directly. */
9872 viewbox_width = svg_css_length_to_pixels (iwidth); 9926 viewbox_width = svg_css_length_to_pixels (iwidth, dpi);
9873 viewbox_height = svg_css_length_to_pixels (iheight); 9927 viewbox_height = svg_css_length_to_pixels (iheight, dpi);
9874 } 9928 }
9875 else if (has_width && has_viewbox) 9929 else if (has_width && has_viewbox)
9876 { 9930 {
9877 viewbox_width = svg_css_length_to_pixels (iwidth); 9931 viewbox_width = svg_css_length_to_pixels (iwidth, dpi);
9878 viewbox_height = svg_css_length_to_pixels (iwidth) 9932 viewbox_height = svg_css_length_to_pixels (iwidth, dpi)
9879 * viewbox.width / viewbox.height; 9933 * viewbox.width / viewbox.height;
9880 } 9934 }
9881 else if (has_height && has_viewbox) 9935 else if (has_height && has_viewbox)
9882 { 9936 {
9883 viewbox_height = svg_css_length_to_pixels (iheight); 9937 viewbox_height = svg_css_length_to_pixels (iheight, dpi);
9884 viewbox_width = svg_css_length_to_pixels (iheight) 9938 viewbox_width = svg_css_length_to_pixels (iheight, dpi)
9885 * viewbox.height / viewbox.width; 9939 * viewbox.height / viewbox.width;
9886 } 9940 }
9887 else if (has_viewbox) 9941 else if (has_viewbox)
@@ -9990,6 +10044,10 @@ svg_load_image (struct frame *f, struct image *img, char *contents,
9990 rsvg_handle = rsvg_handle_new_from_stream_sync (input_stream, base_file, 10044 rsvg_handle = rsvg_handle_new_from_stream_sync (input_stream, base_file,
9991 RSVG_HANDLE_FLAGS_NONE, 10045 RSVG_HANDLE_FLAGS_NONE,
9992 NULL, &err); 10046 NULL, &err);
10047
10048 rsvg_handle_set_dpi_x_y (rsvg_handle, FRAME_DISPLAY_INFO (f)->resx,
10049 FRAME_DISPLAY_INFO (f)->resy);
10050
9993 if (base_file) 10051 if (base_file)
9994 g_object_unref (base_file); 10052 g_object_unref (base_file);
9995 g_object_unref (input_stream); 10053 g_object_unref (input_stream);
@@ -10001,7 +10059,11 @@ svg_load_image (struct frame *f, struct image *img, char *contents,
10001 rsvg_handle = rsvg_handle_new (); 10059 rsvg_handle = rsvg_handle_new ();
10002 eassume (rsvg_handle); 10060 eassume (rsvg_handle);
10003 10061
10062 rsvg_handle_set_dpi_x_y (rsvg_handle, FRAME_DISPLAY_INFO (f)->resx,
10063 FRAME_DISPLAY_INFO (f)->resy);
10064
10004 /* Set base_uri for properly handling referenced images (via 'href'). 10065 /* Set base_uri for properly handling referenced images (via 'href').
10066 Can be explicitly specified using `:base_uri' image property.
10005 See rsvg bug 596114 - "image refs are relative to curdir, not .svg file" 10067 See rsvg bug 596114 - "image refs are relative to curdir, not .svg file"
10006 <https://gitlab.gnome.org/GNOME/librsvg/issues/33>. */ 10068 <https://gitlab.gnome.org/GNOME/librsvg/issues/33>. */
10007 if (filename) 10069 if (filename)
@@ -10684,6 +10746,7 @@ non-numeric, there is no explicit limit on the size of images. */);
10684 10746
10685#if defined (HAVE_RSVG) 10747#if defined (HAVE_RSVG)
10686 DEFSYM (Qsvg, "svg"); 10748 DEFSYM (Qsvg, "svg");
10749 DEFSYM (QCbase_uri, ":base-uri");
10687 add_image_type (Qsvg); 10750 add_image_type (Qsvg);
10688#ifdef HAVE_NTGUI 10751#ifdef HAVE_NTGUI
10689 /* Other libraries used directly by svg code. */ 10752 /* Other libraries used directly by svg code. */
@@ -10713,6 +10776,7 @@ non-numeric, there is no explicit limit on the size of images. */);
10713 defsubr (&Simage_size); 10776 defsubr (&Simage_size);
10714 defsubr (&Simage_mask_p); 10777 defsubr (&Simage_mask_p);
10715 defsubr (&Simage_metadata); 10778 defsubr (&Simage_metadata);
10779 defsubr (&Simage_cache_size);
10716 10780
10717#ifdef GLYPH_DEBUG 10781#ifdef GLYPH_DEBUG
10718 defsubr (&Simagep); 10782 defsubr (&Simagep);
diff --git a/src/lisp.h b/src/lisp.h
index a5a90cce1b4..5900b8d25e4 100644
--- a/src/lisp.h
+++ b/src/lisp.h
@@ -1900,16 +1900,17 @@ ASCII_CHAR_P (intmax_t c)
1900 return 0 <= c && c < 0x80; 1900 return 0 <= c && c < 0x80;
1901} 1901}
1902 1902
1903/* A char-table is a kind of vectorlike, with contents are like a 1903/* A char-table is a kind of vectorlike, with contents like a vector,
1904 vector but with a few other slots. For some purposes, it makes 1904 but with a few additional slots. For some purposes, it makes sense
1905 sense to handle a char-table with type struct Lisp_Vector. An 1905 to handle a char-table as type 'struct Lisp_Vector'. An element of
1906 element of a char table can be any Lisp objects, but if it is a sub 1906 a char-table can be any Lisp object, but if it is a sub-char-table,
1907 char-table, we treat it a table that contains information of a 1907 we treat it as a table that contains information of a specific
1908 specific range of characters. A sub char-table is like a vector but 1908 range of characters. A sub-char-table is like a vector, but with
1909 with two integer fields between the header and Lisp data, which means 1909 two integer fields between the header and Lisp data, which means
1910 that it has to be marked with some precautions (see mark_char_table 1910 that it has to be marked with some precautions (see mark_char_table
1911 in alloc.c). A sub char-table appears only in an element of a char-table, 1911 in alloc.c). A sub-char-table appears only in an element of a
1912 and there's no way to access it directly from Emacs Lisp program. */ 1912 char-table, and there's no way to access it directly from a Lisp
1913 program. */
1913 1914
1914enum CHARTAB_SIZE_BITS 1915enum CHARTAB_SIZE_BITS
1915 { 1916 {
@@ -1929,11 +1930,11 @@ struct Lisp_Char_Table
1929 contents, and extras slots. */ 1930 contents, and extras slots. */
1930 union vectorlike_header header; 1931 union vectorlike_header header;
1931 1932
1932 /* This holds a default value, 1933 /* This holds the default value, which is used whenever the value
1933 which is used whenever the value for a specific character is nil. */ 1934 for a specific character is nil. */
1934 Lisp_Object defalt; 1935 Lisp_Object defalt;
1935 1936
1936 /* This points to another char table, which we inherit from when the 1937 /* This points to another char table, from which we inherit when the
1937 value for a specific character is nil. The `defalt' slot takes 1938 value for a specific character is nil. The `defalt' slot takes
1938 precedence over this. */ 1939 precedence over this. */
1939 Lisp_Object parent; 1940 Lisp_Object parent;
@@ -1942,8 +1943,8 @@ struct Lisp_Char_Table
1942 meant for. */ 1943 meant for. */
1943 Lisp_Object purpose; 1944 Lisp_Object purpose;
1944 1945
1945 /* The bottom sub char-table for characters of the range 0..127. It 1946 /* The bottom sub char-table for characters in the range 0..127. It
1946 is nil if none of ASCII character has a specific value. */ 1947 is nil if no ASCII character has a specific value. */
1947 Lisp_Object ascii; 1948 Lisp_Object ascii;
1948 1949
1949 Lisp_Object contents[(1 << CHARTAB_SIZE_BITS_0)]; 1950 Lisp_Object contents[(1 << CHARTAB_SIZE_BITS_0)];
@@ -2018,7 +2019,7 @@ CHAR_TABLE_REF_ASCII (Lisp_Object ct, ptrdiff_t idx)
2018} 2019}
2019 2020
2020/* Almost equivalent to Faref (CT, IDX) with optimization for ASCII 2021/* Almost equivalent to Faref (CT, IDX) with optimization for ASCII
2021 characters. Do not check validity of CT. */ 2022 characters. Does not check validity of CT. */
2022INLINE Lisp_Object 2023INLINE Lisp_Object
2023CHAR_TABLE_REF (Lisp_Object ct, int idx) 2024CHAR_TABLE_REF (Lisp_Object ct, int idx)
2024{ 2025{
@@ -2028,7 +2029,7 @@ CHAR_TABLE_REF (Lisp_Object ct, int idx)
2028} 2029}
2029 2030
2030/* Equivalent to Faset (CT, IDX, VAL) with optimization for ASCII and 2031/* Equivalent to Faset (CT, IDX, VAL) with optimization for ASCII and
2031 8-bit European characters. Do not check validity of CT. */ 2032 8-bit European characters. Does not check validity of CT. */
2032INLINE void 2033INLINE void
2033CHAR_TABLE_SET (Lisp_Object ct, int idx, Lisp_Object val) 2034CHAR_TABLE_SET (Lisp_Object ct, int idx, Lisp_Object val)
2034{ 2035{
diff --git a/src/nsterm.m b/src/nsterm.m
index 0729c961bdf..7972fa4dabb 100644
--- a/src/nsterm.m
+++ b/src/nsterm.m
@@ -1166,7 +1166,6 @@ ns_update_end (struct frame *f)
1166 { 1166 {
1167#endif 1167#endif
1168 [NSGraphicsContext setCurrentContext:nil]; 1168 [NSGraphicsContext setCurrentContext:nil];
1169 [view setNeedsDisplay:YES];
1170#if MAC_OS_X_VERSION_MIN_REQUIRED < 101400 1169#if MAC_OS_X_VERSION_MIN_REQUIRED < 101400
1171 } 1170 }
1172 else 1171 else
@@ -3056,7 +3055,7 @@ ns_clear_under_internal_border (struct frame *f)
3056 if (!face) 3055 if (!face)
3057 return; 3056 return;
3058 3057
3059 ns_focus (f, &frame_rect, 1); 3058 ns_focus (f, NULL, 1);
3060 [ns_lookup_indexed_color (NS_FACE_BACKGROUND (face), f) set]; 3059 [ns_lookup_indexed_color (NS_FACE_BACKGROUND (face), f) set];
3061 for (int i = 0; i < 4 ; i++) 3060 for (int i = 0; i < 4 ; i++)
3062 { 3061 {
@@ -4987,8 +4986,8 @@ ns_set_vertical_scroll_bar (struct window *window,
4987 [bar removeFromSuperview]; 4986 [bar removeFromSuperview];
4988 wset_vertical_scroll_bar (window, Qnil); 4987 wset_vertical_scroll_bar (window, Qnil);
4989 [bar release]; 4988 [bar release];
4989 ns_clear_frame_area (f, left, top, width, height);
4990 } 4990 }
4991 ns_clear_frame_area (f, left, top, width, height);
4992 unblock_input (); 4991 unblock_input ();
4993 return; 4992 return;
4994 } 4993 }
@@ -5010,7 +5009,7 @@ ns_set_vertical_scroll_bar (struct window *window,
5010 r.size.width = oldRect.size.width; 5009 r.size.width = oldRect.size.width;
5011 if (FRAME_LIVE_P (f) && !NSEqualRects (oldRect, r)) 5010 if (FRAME_LIVE_P (f) && !NSEqualRects (oldRect, r))
5012 { 5011 {
5013 if (oldRect.origin.x != r.origin.x) 5012 if (! NSEqualRects (oldRect, r))
5014 ns_clear_frame_area (f, left, top, width, height); 5013 ns_clear_frame_area (f, left, top, width, height);
5015 [bar setFrame: r]; 5014 [bar setFrame: r];
5016 } 5015 }
@@ -5088,8 +5087,7 @@ ns_set_horizontal_scroll_bar (struct window *window,
5088 oldRect = [bar frame]; 5087 oldRect = [bar frame];
5089 if (FRAME_LIVE_P (f) && !NSEqualRects (oldRect, r)) 5088 if (FRAME_LIVE_P (f) && !NSEqualRects (oldRect, r))
5090 { 5089 {
5091 if (oldRect.origin.y != r.origin.y) 5090 ns_clear_frame_area (f, left, top, width, height);
5092 ns_clear_frame_area (f, left, top, width, height);
5093 [bar setFrame: r]; 5091 [bar setFrame: r];
5094 update_p = YES; 5092 update_p = YES;
5095 } 5093 }
diff --git a/src/regex-emacs.c b/src/regex-emacs.c
index 971a5f63749..904ca0c7b95 100644
--- a/src/regex-emacs.c
+++ b/src/regex-emacs.c
@@ -3575,9 +3575,11 @@ skip_noops (re_char *p, re_char *pend)
3575 opcode. When the function finishes, *PP will be advanced past that opcode. 3575 opcode. When the function finishes, *PP will be advanced past that opcode.
3576 C is character to test (possibly after translations) and CORIG is original 3576 C is character to test (possibly after translations) and CORIG is original
3577 character (i.e. without any translations). UNIBYTE denotes whether c is 3577 character (i.e. without any translations). UNIBYTE denotes whether c is
3578 unibyte or multibyte character. */ 3578 unibyte or multibyte character.
3579 CANON_TABLE is the canonicalisation table for case folding or Qnil. */
3579static bool 3580static bool
3580execute_charset (re_char **pp, int c, int corig, bool unibyte) 3581execute_charset (re_char **pp, int c, int corig, bool unibyte,
3582 Lisp_Object canon_table)
3581{ 3583{
3582 eassume (0 <= c && 0 <= corig); 3584 eassume (0 <= c && 0 <= corig);
3583 re_char *p = *pp, *rtp = NULL; 3585 re_char *p = *pp, *rtp = NULL;
@@ -3617,11 +3619,9 @@ execute_charset (re_char **pp, int c, int corig, bool unibyte)
3617 (class_bits & BIT_BLANK && ISBLANK (c)) || 3619 (class_bits & BIT_BLANK && ISBLANK (c)) ||
3618 (class_bits & BIT_WORD && ISWORD (c)) || 3620 (class_bits & BIT_WORD && ISWORD (c)) ||
3619 ((class_bits & BIT_UPPER) && 3621 ((class_bits & BIT_UPPER) &&
3620 (ISUPPER (c) || (corig != c && 3622 (ISUPPER (corig) || (!NILP (canon_table) && ISLOWER (corig)))) ||
3621 c == downcase (corig) && ISLOWER (c)))) ||
3622 ((class_bits & BIT_LOWER) && 3623 ((class_bits & BIT_LOWER) &&
3623 (ISLOWER (c) || (corig != c && 3624 (ISLOWER (corig) || (!NILP (canon_table) && ISUPPER (corig)))) ||
3624 c == upcase (corig) && ISUPPER(c)))) ||
3625 (class_bits & BIT_PUNCT && ISPUNCT (c)) || 3625 (class_bits & BIT_PUNCT && ISPUNCT (c)) ||
3626 (class_bits & BIT_GRAPH && ISGRAPH (c)) || 3626 (class_bits & BIT_GRAPH && ISGRAPH (c)) ||
3627 (class_bits & BIT_PRINT && ISPRINT (c))) 3627 (class_bits & BIT_PRINT && ISPRINT (c)))
@@ -3696,7 +3696,8 @@ mutually_exclusive_p (struct re_pattern_buffer *bufp, re_char *p1,
3696 else if ((re_opcode_t) *p1 == charset 3696 else if ((re_opcode_t) *p1 == charset
3697 || (re_opcode_t) *p1 == charset_not) 3697 || (re_opcode_t) *p1 == charset_not)
3698 { 3698 {
3699 if (!execute_charset (&p1, c, c, !multibyte || ASCII_CHAR_P (c))) 3699 if (!execute_charset (&p1, c, c, !multibyte || ASCII_CHAR_P (c),
3700 Qnil))
3700 { 3701 {
3701 DEBUG_PRINT (" No match => fast loop.\n"); 3702 DEBUG_PRINT (" No match => fast loop.\n");
3702 return true; 3703 return true;
@@ -4367,7 +4368,7 @@ re_match_2_internal (struct re_pattern_buffer *bufp,
4367 } 4368 }
4368 4369
4369 p -= 1; 4370 p -= 1;
4370 if (!execute_charset (&p, c, corig, unibyte_char)) 4371 if (!execute_charset (&p, c, corig, unibyte_char, translate))
4371 goto fail; 4372 goto fail;
4372 4373
4373 d += len; 4374 d += len;
diff --git a/src/w32gui.h b/src/w32gui.h
index dfec1f08617..fc8131130fb 100644
--- a/src/w32gui.h
+++ b/src/w32gui.h
@@ -46,6 +46,7 @@ extern int w32_load_image (struct frame *f, struct image *img,
46 Lisp_Object spec_file, Lisp_Object spec_data); 46 Lisp_Object spec_file, Lisp_Object spec_data);
47extern bool w32_can_use_native_image_api (Lisp_Object); 47extern bool w32_can_use_native_image_api (Lisp_Object);
48extern void w32_gdiplus_shutdown (void); 48extern void w32_gdiplus_shutdown (void);
49extern size_t w32_image_size (struct image *);
49 50
50#define FACE_DEFAULT (~0) 51#define FACE_DEFAULT (~0)
51 52
diff --git a/src/w32term.c b/src/w32term.c
index 23cb380040b..dc5cd1f6997 100644
--- a/src/w32term.c
+++ b/src/w32term.c
@@ -1991,6 +1991,17 @@ w32_draw_image_foreground (struct glyph_string *s)
1991 RestoreDC (s->hdc ,-1); 1991 RestoreDC (s->hdc ,-1);
1992} 1992}
1993 1993
1994size_t
1995w32_image_size (struct image *img)
1996{
1997 BITMAP bm_info;
1998 size_t rv = 0;
1999
2000 if (GetObject (img->pixmap, sizeof (BITMAP), &bm_info))
2001 rv = bm_info.bmWidth * bm_info.bmHeight * bm_info.bmBitsPixel / 8;
2002 return rv;
2003}
2004
1994 2005
1995/* Draw a relief around the image glyph string S. */ 2006/* Draw a relief around the image glyph string S. */
1996 2007
diff --git a/src/window.c b/src/window.c
index 6cd3122b43b..8e75e460b2b 100644
--- a/src/window.c
+++ b/src/window.c
@@ -5669,7 +5669,7 @@ window_scroll_pixel_based (Lisp_Object window, int n, bool whole, bool noerror)
5669 if (whole) 5669 if (whole)
5670 { 5670 {
5671 ptrdiff_t start_pos = IT_CHARPOS (it); 5671 ptrdiff_t start_pos = IT_CHARPOS (it);
5672 int dy = frame_line_height; 5672 int flh = frame_line_height;
5673 int ht = window_box_height (w); 5673 int ht = window_box_height (w);
5674 int nscls = sanitize_next_screen_context_lines (); 5674 int nscls = sanitize_next_screen_context_lines ();
5675 /* In the below we divide the window box height by the frame's 5675 /* In the below we divide the window box height by the frame's
@@ -5677,14 +5677,37 @@ window_scroll_pixel_based (Lisp_Object window, int n, bool whole, bool noerror)
5677 box is not an integral multiple of the line height. This is 5677 box is not an integral multiple of the line height. This is
5678 important to ensure we get back to the same position when 5678 important to ensure we get back to the same position when
5679 scrolling up, then down. */ 5679 scrolling up, then down. */
5680 dy = n * max (dy, (ht / dy - nscls) * dy); 5680 int dy = n * max (flh, (ht / flh - nscls) * flh);
5681 int goal_y;
5682 void *it_data;
5681 5683
5682 /* Note that move_it_vertically always moves the iterator to the 5684 /* Note that move_it_vertically always moves the iterator to the
5683 start of a line. So, if the last line doesn't have a newline, 5685 start of a line. So, if the last line doesn't have a newline,
5684 we would end up at the start of the line ending at ZV. */ 5686 we would end up at the start of the line ending at ZV. */
5685 if (dy <= 0) 5687 if (dy <= 0)
5686 { 5688 {
5689 goal_y = it.current_y - dy;
5687 move_it_vertically_backward (&it, -dy); 5690 move_it_vertically_backward (&it, -dy);
5691 /* Extra precision for people who want us to preserve the
5692 screen position of the cursor: effectively round DY to the
5693 nearest screen line, instead of rounding to zero; the latter
5694 causes point to move by one line after C-v followed by M-v,
5695 if the buffer has lines of different height. */
5696 if (!NILP (Vscroll_preserve_screen_position)
5697 && it.current_y - goal_y > 0.5 * flh)
5698 {
5699 it_data = bidi_shelve_cache ();
5700 struct it it2 = it;
5701
5702 move_it_by_lines (&it, -1);
5703 if (it.current_y < goal_y - 0.5 * flh)
5704 {
5705 it = it2;
5706 bidi_unshelve_cache (it_data, false);
5707 }
5708 else
5709 bidi_unshelve_cache (it_data, true);
5710 }
5688 /* Ensure we actually do move, e.g. in case we are currently 5711 /* Ensure we actually do move, e.g. in case we are currently
5689 looking at an image that is taller that the window height. */ 5712 looking at an image that is taller that the window height. */
5690 while (start_pos == IT_CHARPOS (it) 5713 while (start_pos == IT_CHARPOS (it)
@@ -5693,8 +5716,25 @@ window_scroll_pixel_based (Lisp_Object window, int n, bool whole, bool noerror)
5693 } 5716 }
5694 else if (dy > 0) 5717 else if (dy > 0)
5695 { 5718 {
5696 move_it_to (&it, ZV, -1, it.current_y + dy, -1, 5719 goal_y = it.current_y + dy;
5697 MOVE_TO_POS | MOVE_TO_Y); 5720 move_it_to (&it, ZV, -1, goal_y, -1, MOVE_TO_POS | MOVE_TO_Y);
5721 /* See the comment above, for the reasons of this
5722 extra-precision. */
5723 if (!NILP (Vscroll_preserve_screen_position)
5724 && goal_y - it.current_y > 0.5 * flh)
5725 {
5726 it_data = bidi_shelve_cache ();
5727 struct it it2 = it;
5728
5729 move_it_by_lines (&it, 1);
5730 if (it.current_y > goal_y + 0.5 * flh)
5731 {
5732 it = it2;
5733 bidi_unshelve_cache (it_data, false);
5734 }
5735 else
5736 bidi_unshelve_cache (it_data, true);
5737 }
5698 /* Ensure we actually do move, e.g. in case we are currently 5738 /* Ensure we actually do move, e.g. in case we are currently
5699 looking at an image that is taller that the window height. */ 5739 looking at an image that is taller that the window height. */
5700 while (start_pos == IT_CHARPOS (it) 5740 while (start_pos == IT_CHARPOS (it)
@@ -8206,11 +8246,17 @@ is displayed in the `mode-line' face. */);
8206 DEFVAR_LISP ("scroll-preserve-screen-position", 8246 DEFVAR_LISP ("scroll-preserve-screen-position",
8207 Vscroll_preserve_screen_position, 8247 Vscroll_preserve_screen_position,
8208 doc: /* Controls if scroll commands move point to keep its screen position unchanged. 8248 doc: /* Controls if scroll commands move point to keep its screen position unchanged.
8249
8209A value of nil means point does not keep its screen position except 8250A value of nil means point does not keep its screen position except
8210at the scroll margin or window boundary respectively. 8251at the scroll margin or window boundary respectively.
8252
8211A value of t means point keeps its screen position if the scroll 8253A value of t means point keeps its screen position if the scroll
8212command moved it vertically out of the window, e.g. when scrolling 8254command moved it vertically out of the window, e.g. when scrolling
8213by full screens. 8255by full screens. If point is within `next-screen-context-lines' lines
8256from the edges of the window, point will typically not keep its screen
8257position when doing commands like `scroll-up-command'/`scroll-down-command'
8258and the like.
8259
8214Any other value means point always keeps its screen position. 8260Any other value means point always keeps its screen position.
8215Scroll commands should have the `scroll-command' property 8261Scroll commands should have the `scroll-command' property
8216on their symbols to be controlled by this variable. */); 8262on their symbols to be controlled by this variable. */);
diff --git a/src/xdisp.c b/src/xdisp.c
index ed1d4761b95..689b87df421 100644
--- a/src/xdisp.c
+++ b/src/xdisp.c
@@ -1925,12 +1925,12 @@ pos_visible_p (struct window *w, ptrdiff_t charpos, int *x, int *y,
1925 /* If it3_moved stays false after the 'while' loop 1925 /* If it3_moved stays false after the 'while' loop
1926 below, that means we already were at a newline 1926 below, that means we already were at a newline
1927 before the loop (e.g., the display string begins 1927 before the loop (e.g., the display string begins
1928 with a newline), so we don't need to (and cannot) 1928 with a newline), so we don't need to return to
1929 inspect the glyphs of it3.glyph_row, because 1929 the last position before the display string,
1930 PRODUCE_GLYPHS will not produce anything for a 1930 because PRODUCE_GLYPHS will not produce anything
1931 newline, and thus it3.glyph_row stays at its 1931 for a newline. */
1932 stale content it got at top of the window. */
1933 bool it3_moved = false; 1932 bool it3_moved = false;
1933 int top_x_before_string = it3.current_x;
1934 /* Finally, advance the iterator until we hit the 1934 /* Finally, advance the iterator until we hit the
1935 first display element whose character position is 1935 first display element whose character position is
1936 CHARPOS, or until the first newline from the 1936 CHARPOS, or until the first newline from the
@@ -1938,6 +1938,8 @@ pos_visible_p (struct window *w, ptrdiff_t charpos, int *x, int *y,
1938 display line. */ 1938 display line. */
1939 while (get_next_display_element (&it3)) 1939 while (get_next_display_element (&it3))
1940 { 1940 {
1941 if (!EQ (it3.object, string))
1942 top_x_before_string = it3.current_x;
1941 PRODUCE_GLYPHS (&it3); 1943 PRODUCE_GLYPHS (&it3);
1942 if (IT_CHARPOS (it3) == charpos 1944 if (IT_CHARPOS (it3) == charpos
1943 || ITERATOR_AT_END_OF_LINE_P (&it3)) 1945 || ITERATOR_AT_END_OF_LINE_P (&it3))
@@ -1952,32 +1954,26 @@ pos_visible_p (struct window *w, ptrdiff_t charpos, int *x, int *y,
1952 if (!it3.line_number_produced_p) 1954 if (!it3.line_number_produced_p)
1953 { 1955 {
1954 if (it3.lnum_pixel_width > 0) 1956 if (it3.lnum_pixel_width > 0)
1955 top_x += it3.lnum_pixel_width; 1957 {
1958 top_x += it3.lnum_pixel_width;
1959 top_x_before_string += it3.lnum_pixel_width;
1960 }
1956 else if (it.line_number_produced_p) 1961 else if (it.line_number_produced_p)
1957 top_x += it.lnum_pixel_width; 1962 {
1963 top_x += it.lnum_pixel_width;
1964 top_x_before_string += it3.lnum_pixel_width;
1965 }
1958 } 1966 }
1959 /* Normally, we would exit the above loop because we 1967 /* Normally, we would exit the above loop because we
1960 found the display element whose character 1968 found the display element whose character
1961 position is CHARPOS. For the contingency that we 1969 position is CHARPOS. For the contingency that we
1962 didn't, and stopped at the first newline from the 1970 didn't, and stopped at the first newline from the
1963 display string, move back over the glyphs 1971 display string, reset top_x to the coordinate of
1964 produced from the string, until we find the 1972 the rightmost glyph not from the string. */
1965 rightmost glyph not from the string. */
1966 if (it3_moved 1973 if (it3_moved
1967 && newline_in_string 1974 && newline_in_string
1968 && IT_CHARPOS (it3) != charpos && EQ (it3.object, string)) 1975 && IT_CHARPOS (it3) != charpos && EQ (it3.object, string))
1969 { 1976 top_x = top_x_before_string;
1970 struct glyph *g = it3.glyph_row->glyphs[TEXT_AREA]
1971 + it3.glyph_row->used[TEXT_AREA];
1972
1973 while (EQ ((g - 1)->object, string))
1974 {
1975 --g;
1976 top_x -= g->pixel_width;
1977 }
1978 eassert (g < it3.glyph_row->glyphs[TEXT_AREA]
1979 + it3.glyph_row->used[TEXT_AREA]);
1980 }
1981 } 1977 }
1982 } 1978 }
1983 1979