From mboxrd@z Thu Jan 1 00:00:00 1970 Path: news.gmane.org!.POSTED!not-for-mail From: Kalman Reti Newsgroups: gmane.emacs.bugs Subject: bug#32744: There seems to be a bug in current-column in character mode Date: Mon, 17 Sep 2018 10:54:50 -0400 Message-ID: References: <83y3c1gyer.fsf@gnu.org> <83o9cwgp6x.fsf@gnu.org> NNTP-Posting-Host: blaine.gmane.org Mime-Version: 1.0 Content-Type: multipart/alternative; boundary="000000000000fae3780576125ad1" X-Trace: blaine.gmane.org 1537195989 20733 195.159.176.226 (17 Sep 2018 14:53:09 GMT) X-Complaints-To: usenet@blaine.gmane.org NNTP-Posting-Date: Mon, 17 Sep 2018 14:53:09 +0000 (UTC) Cc: 32744-done@debbugs.gnu.org To: Eli Zaretskii Original-X-From: bug-gnu-emacs-bounces+geb-bug-gnu-emacs=m.gmane.org@gnu.org Mon Sep 17 16:53:05 2018 Return-path: Envelope-to: geb-bug-gnu-emacs@m.gmane.org Original-Received: from lists.gnu.org ([208.118.235.17]) by blaine.gmane.org with esmtp (Exim 4.84_2) (envelope-from ) id 1g1utd-0005Ic-7c for geb-bug-gnu-emacs@m.gmane.org; Mon, 17 Sep 2018 16:53:05 +0200 Original-Received: from localhost ([::1]:35944 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1g1uvj-0003VP-N1 for geb-bug-gnu-emacs@m.gmane.org; Mon, 17 Sep 2018 10:55:15 -0400 Original-Received: from eggs.gnu.org ([2001:4830:134:3::10]:51672) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1g1uva-0003V7-AY for bug-gnu-emacs@gnu.org; Mon, 17 Sep 2018 10:55:08 -0400 Original-Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1g1uvW-0000Wq-Cv for bug-gnu-emacs@gnu.org; Mon, 17 Sep 2018 10:55:06 -0400 Original-Received: from debbugs.gnu.org ([208.118.235.43]:38998) by eggs.gnu.org with esmtps (TLS1.0:RSA_AES_128_CBC_SHA1:16) (Exim 4.71) (envelope-from ) id 1g1uvW-0000Vy-7G for bug-gnu-emacs@gnu.org; Mon, 17 Sep 2018 10:55:02 -0400 Original-Received: from Debian-debbugs by debbugs.gnu.org with local (Exim 4.84_2) (envelope-from ) id 1g1uvW-0006LA-1w for bug-gnu-emacs@gnu.org; Mon, 17 Sep 2018 10:55:02 -0400 X-Loop: help-debbugs@gnu.org Resent-From: Kalman Reti Original-Sender: "Debbugs-submit" Resent-CC: bug-gnu-emacs@gnu.org Resent-Date: Mon, 17 Sep 2018 14:55:01 +0000 Resent-Message-ID: Resent-Sender: help-debbugs@gnu.org X-GNU-PR-Message: followup 32744 X-GNU-PR-Package: emacs X-GNU-PR-Keywords: Original-Received: via spool by 32744-done@debbugs.gnu.org id=D32744.153719610024360 (code D ref 32744); Mon, 17 Sep 2018 14:55:01 +0000 Original-Received: (at 32744-done) by debbugs.gnu.org; 17 Sep 2018 14:55:00 +0000 Original-Received: from localhost ([127.0.0.1]:43256 helo=debbugs.gnu.org) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from ) id 1g1uvT-0006Kp-CG for submit@debbugs.gnu.org; Mon, 17 Sep 2018 10:55:00 -0400 Original-Received: from mail-ot1-f43.google.com ([209.85.210.43]:46280) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from ) id 1g1uvR-0006Kd-BF for 32744-done@debbugs.gnu.org; Mon, 17 Sep 2018 10:54:58 -0400 Original-Received: by mail-ot1-f43.google.com with SMTP id v44-v6so11575479ote.13 for <32744-done@debbugs.gnu.org>; Mon, 17 Sep 2018 07:54:57 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=mime-version:in-reply-to:references:from:date:message-id:subject:to :cc; bh=AIaX3nOMTmrjOOmV7yYKNboqdUBDptTt+gseX68gn4E=; b=Q9/wH7Xt911PNp7I3k0lbjyr/NTYOCTFZpPGaPXveaaRpBFVvhOvjK96tE4iUmuvlq fb1xkbgqFkp0xLal9hb4cFxk4LjoMUh3Fxfns+pCF5PN833Gc5n3PkVzxhUdpjFZegFA Fw7Z8nkEZj+lfyftGrx0MZ9NPSbSgEAHL9JGmJgu42KxOHp4VQ9V66fipUHsp05v/+TA cabk73NxUaLRXmvUbWXPY3TjQhe0T3ZT4ruc3u6Gy/ZjGWXQcE8rH5g+xN2iPQc1yWqy woPTSFyCvTK7/jCbbDJTxO6x21Kgo1nW/5WkKKrrH6tndWGQwn0/aJnSg3umJ1UEV749 X9bQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:mime-version:in-reply-to:references:from:date :message-id:subject:to:cc; bh=AIaX3nOMTmrjOOmV7yYKNboqdUBDptTt+gseX68gn4E=; b=i94OI7ZVWyymirRJcJaAmRW025R9ytTUjnwKCeGqWqwtW9uXMYz9qcEN2V5IuxhzgC 80tbfkaU/iKlQmmoLtDZC7r6biBWbSnWiOD6Dio9dA6vL0uXUQr/6JNENkAUk12PrU3F jdeEvsV/uv0Yr9mpXAlljkNM8Gn05+40ZUK1sVlLi75LE0/gK/6TU+wSz1bRbK3nuPUp wXEgaQmaxrjKf/WFoZWcLkEsJOOvRISn+Bk35kpZHI5dP08Jb9kQevBNvlO7Atg/h+s6 XPRnLvyMLpqZtg38juGowVz4CMVKrCyM/FEhM5lOqCqUyTSe+aZlc2zZCqBUuHwD5VOw 09JQ== X-Gm-Message-State: APzg51BWKKXd6fWjGCxgDbg0HphLm74BCWhGCpuIXVkBq/6BA3tF67nl uTesiYE1iYiHtMPhEwGDlHL5twgTxYUBegZ51uI= X-Google-Smtp-Source: ANB0VdYcImntaaDoeRGlA1MHna/AO3aI1cmtZVec3Dph/Y4zaU4X1GGpFtOU9K7zXjEayfSDoyNWMWbjwWvxHmN3TzI= X-Received: by 2002:a9d:ff5:: with SMTP id m50-v6mr12870724otd.276.1537196091432; Mon, 17 Sep 2018 07:54:51 -0700 (PDT) Original-Received: by 2002:ac9:604c:0:0:0:0:0 with HTTP; Mon, 17 Sep 2018 07:54:50 -0700 (PDT) Original-Received: by 2002:ac9:604c:0:0:0:0:0 with HTTP; Mon, 17 Sep 2018 07:54:50 -0700 (PDT) In-Reply-To: <83o9cwgp6x.fsf@gnu.org> X-BeenThere: debbugs-submit@debbugs.gnu.org X-Mailman-Version: 2.1.18 Precedence: list X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.2.x-3.x [generic] X-Received-From: 208.118.235.43 X-BeenThere: bug-gnu-emacs@gnu.org List-Id: "Bug reports for GNU Emacs, the Swiss army knife of text editors" List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: bug-gnu-emacs-bounces+geb-bug-gnu-emacs=m.gmane.org@gnu.org Original-Sender: "bug-gnu-emacs" Xref: news.gmane.org gmane.emacs.bugs:150370 Archived-At: --000000000000fae3780576125ad1 Content-Type: text/plain; charset="UTF-8" On Sep 17, 2018 10:43 AM, "Eli Zaretskii" wrote: > From: Kalman Reti > Date: Sun, 16 Sep 2018 19:44:33 -0400 > Cc: 32744@debbugs.gnu.org > > I get 8 in GUI frames as well. > > The display spec (space :width 7) means 7 times the width of the > default face's font. So if your default GUI font is monospaced, you > should get 8 in both GUI and text-mode frames. > > So I'm unsure how come you get 2 in GUI mode. Maybe you've omitted > some important detail in the reproducer. > > I apologize; you are correct, it gets 8 in gui mode as well. I must have been confused about which window > was running which version of emacs while I was experimenting. > > But is that the correct value? The bubbles game code clearly wants it to mean 'the number of forward-chars I > have to do from the beginning of the line to get here' not 'what column does it visually look like I'm on'. > > The doc string for the function doesn't clarify the intended meaning. I think the doc string for current column should be enhanced to say what it is returning. > > If you do m-x bubbles immediately followed by m-: (current-column) it returns 1 in the gui case but a number > larger than one (which depends upon the :width keyword of the wide-displaying space), but for the game to > work in the character case it needs to return 1. It's a bug in bubbles.el, now fixed on the emacs-26 branch. The patch is below, so you can apply it locally if you want. The existing bubbles code works for both gui and character mode in emacs 22, so I'd characterize it less as a bug in bubbles as an incompatibility introduced after emacs 22. Is there some other function that will give 'how many forward-chars necessary to go from beginning of line to here? Thanks for the patch. The patch does some cleanup, so it might not be easy to spot the crucial problem it fixes. The root cause of the bug was that bubbles--initialize had 2 code paths in it: one for GUI frames (which worked), and another for TTY frames (which didn't, and it seems to me that no one has ever tried it). The GUI part computed the offsets as lists, i.e. '(N), whereas the TTY part produced just N, a simple number. And the display property 'space' treats each of these differently: '(N) is treated as pixel width, while N is treated as a multiple of the default character width (your example only used the N form, so it produced 8 instead of 1 from current-column). Once we produce '(N) both in GUI and in TTY frames, the game works in both. Here's the patch I promised; I'm closing the bug report. diff --git a/lisp/play/bubbles.el b/lisp/play/bubbles.el index e30838d..ee2135b 100644 --- a/lisp/play/bubbles.el +++ b/lisp/play/bubbles.el @@ -250,10 +250,10 @@ bubbles--images-ok "Indicate whether images have been created successfully.") (defvar bubbles--col-offset 0 - "Horizontal offset for centering the bubbles grid.") + "Horizontal offset for centering the bubbles grid, in pixels.") (defvar bubbles--row-offset 0 - "Vertical offset for centering the bubbles grid.") + "Vertical offset for centering the bubbles grid, in pixels.") (defvar bubbles--save-data nil "List containing bubbles save data (SCORE BUFFERCONTENTS).") @@ -960,33 +960,26 @@ bubbles-quit (defun bubbles--compute-offsets () "Update horizontal and vertical offsets for centering the bubbles grid. Set `bubbles--col-offset' and `bubbles--row-offset'." - (cond ((and (display-images-p) - bubbles--images-ok - (not (eq bubbles-graphics-theme 'ascii)) - (fboundp 'window-inside-pixel-edges)) - ;; compute offset in units of pixels - (let ((bubbles--image-size - (car (image-size (car bubbles--images) t)))) - (setq bubbles--col-offset - (list - (max 0 (/ (- (nth 2 (window-inside-pixel-edges)) - (nth 0 (window-inside-pixel-edges)) - (* ( + bubbles--image-size 2) ;; margin - (bubbles--grid-width))) 2)))) - (setq bubbles--row-offset - (list - (max 0 (/ (- (nth 3 (window-inside-pixel-edges)) - (nth 1 (window-inside-pixel-edges)) - (* (+ bubbles--image-size 1) ;; margin - (bubbles--grid-height))) 2)))))) - (t - ;; compute offset in units of chars - (setq bubbles--col-offset - (max 0 (/ (- (window-width) - (bubbles--grid-width)) 2))) - (setq bubbles--row-offset - (max 0 (/ (- (window-height) - (bubbles--grid-height) 2) 2)))))) + (let* ((use-images-p (and (display-images-p) + bubbles--images-ok + (not (eq bubbles-graphics-theme 'ascii)))) + (bubbles--image-size + (if use-images-p (car (image-size (car bubbles--images) t)) 1)) + ;; In GUI mode, leave thin margins around the images. + (image-hor-size + (if use-images-p (+ bubbles--image-size 2) bubbles--image-size)) + (image-vert-size + (if use-images-p (1+ bubbles--image-size) bubbles--image-size))) + (setq bubbles--col-offset + (max 0 (/ (- (nth 2 (window-body-pixel-edges)) + (nth 0 (window-body-pixel-edges)) + (* image-hor-size (bubbles--grid-width))) + 2))) + (setq bubbles--row-offset + (max 0 (/ (- (nth 3 (window-body-pixel-edges)) + (nth 1 (window-body-pixel-edges)) + (* image-vert-size (bubbles--grid-height))) + 2))))) (defun bubbles--remove-overlays () "Remove all overlays." @@ -1007,7 +1000,8 @@ bubbles--initialize (insert " ") (put-text-property (point-min) (point) 'display - (cons 'space (list :height bubbles--row-offset))) + (cons 'space (list :height + (list bubbles--row-offset)))) (insert "\n") (let ((max-char (length (bubbles--colors)))) (dotimes (i (bubbles--grid-height)) @@ -1015,7 +1009,8 @@ bubbles--initialize (insert " ") (put-text-property p (point) 'display - (cons 'space (list :width bubbles--col-offset)))) + (cons 'space (list :width + (list bubbles--col-offset))))) (dotimes (j (bubbles--grid-width)) (let* ((index (random max-char)) (char (nth index bubbles-chars))) @@ -1025,7 +1020,8 @@ bubbles--initialize (insert "\n ") (put-text-property (1- (point)) (point) 'display - (cons 'space (list :width bubbles--col-offset)))) + (cons 'space (list :width + (list bubbles--col-offset))))) (put-text-property (point-min) (point-max) 'pointer 'arrow)) (bubbles-mode) (bubbles--reset-score) @@ -1177,7 +1173,7 @@ bubbles--show-scores (insert " ") (put-text-property (1- (point)) (point) 'display - (cons 'space (list :width bubbles--col-offset))) + (cons 'space (list :width (list bubbles--col-offset)))) (insert (format "Score: %4d" bubbles--score)) (put-text-property pos (point) 'status t)))) @@ -1197,7 +1193,7 @@ bubbles--game-over (insert "\n ") (put-text-property (1- (point)) (point) 'display - (cons 'space (list :width bubbles--col-offset))) + (cons 'space (list :width (list bubbles--col-offset)))) (insert "Game Over!")) ;; save score (gamegrid-add-score (format "bubbles-%s-%d-%d-%d-scores" --000000000000fae3780576125ad1 Content-Type: text/html; charset="UTF-8" Content-Transfer-Encoding: quoted-printable
On Sep 17, 2018 10:43 AM, "Eli Zaretskii" <eliz@gnu.org> wrote:
> From: Kalman Reti <kalman.reti@gmail.com>
> Date: Sun, 16 Sep 2018 19:44:33 -0400
> Cc: 32744@debbugs.gnu.org=
>
>=C2=A0 I get 8 in GUI frames as well.
>
>=C2=A0 The display spec (space :width 7) means 7 times the width of the=
>=C2=A0 default face's font.=C2=A0 So if your default GUI font is mo= nospaced, you
>=C2=A0 should get 8 in both GUI and text-mode frames.
>
>=C2=A0 So I'm unsure how come you get 2 in GUI mode.=C2=A0 Maybe yo= u've omitted
>=C2=A0 some important detail in the reproducer.
>
> I apologize; you are correct, it gets 8 in gui mode as well. I must ha= ve been confused about which window
> was running which version of emacs while I was experimenting.
>
> But is that the correct value? The bubbles game code clearly wants it = to mean 'the number of forward-chars I
> have to do from the beginning of the line to get here' not 'wh= at column does it visually look like I'm on'.
>
> The doc string for the function doesn't clarify the intended meani= ng.

I think the doc string for current column should be enhanced= to say what it is returning.
>
> If you do m-x bubbles immediately followed by m-: (current-column) it = returns 1 in the gui case but a number
> larger than one (which depends upon the :width keyword of the wide-dis= playing space), but for the game to
> work in the character case it needs to return 1.

It's a bug in bubbles.el, now fixed on the emacs-26 branch.=C2=A0= The patch
is below, so you can apply it locally if you want.

The existing bubble= s code works for both gui and character mode in emacs 22, so I'd charac= terize it less as a bug in bubbles as an incompatibility introduced after e= macs 22.

Is there some o= ther function that will give 'how many forward-chars necessary to go fr= om beginning of line to here?

Thanks for the patch.


The patch does some cleanup, so it might not be easy to spot the
crucial problem it fixes.=C2=A0 The root cause of the bug was that
bubbles--initialize had 2 code paths in it: one for GUI frames (which
worked), and another for TTY frames (which didn't, and it seems to me that no one has ever tried it).=C2=A0 The GUI part computed the offsets as<= br> lists, i.e. '(N), whereas the TTY part produced just N, a simple
number.=C2=A0 And the display property 'space' treats each of these=
differently: '(N) is treated as pixel width, while N is treated as a multiple of the default character width (your example only used the N
form, so it produced 8 instead of 1 from current-column).=C2=A0 Once we
produce '(N) both in GUI and in TTY frames, the game works in both.

Here's the patch I promised; I'm closing the bug report.

diff --git a/lisp/play/bubbles.el b/lisp/play/bubbles.el
index e30838d..ee2135b 100644
--- a/lisp/play/bubbles.el
+++ b/lisp/play/bubbles.el
@@ -250,10 +250,10 @@ bubbles--images-ok
=C2=A0 =C2=A0"Indicate whether images have been created successfully.&= quot;)

=C2=A0(defvar bubbles--col-offset 0
-=C2=A0 "Horizontal offset for centering the bubbles grid.")
+=C2=A0 "Horizontal offset for centering the bubbles grid, in pixels.&= quot;)

=C2=A0(defvar bubbles--row-offset 0
-=C2=A0 "Vertical offset for centering the bubbles grid.")
+=C2=A0 "Vertical offset for centering the bubbles grid, in pixels.&qu= ot;)

=C2=A0(defvar bubbles--save-data nil
=C2=A0 =C2=A0"List containing bubbles save data (SCORE BUFFERCONTENTS)= .")
@@ -960,33 +960,26 @@ bubbles-quit
=C2=A0(defun bubbles--compute-offsets ()
=C2=A0 =C2=A0"Update horizontal and vertical offsets for centering the= bubbles grid.
=C2=A0Set `bubbles--col-offset' and `bubbles--row-offset'." -=C2=A0 (cond ((and (display-images-p)
-=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 bubbles--images-ok
-=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 (not (eq bubbles-graphics= -theme 'ascii))
-=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 (fboundp 'window-insi= de-pixel-edges))
-=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0;; compute offset in units of pixels
-=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0(let ((bubbles--image-size
-=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 (car (image-size (= car bubbles--images) t))))
-=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0(setq bubbles--col-offset
-=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0(list
-=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 (max 0 (/ (= - (nth 2 (window-inside-pixel-edges))
-=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0(nth 0 (window-inside-pixel-edges)) -=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0(* ( + bubbles--image-size 2) ;; marg= in
-=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 (bubbles--grid-width))) 2))))=
-=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0(setq bubbles--row-offset
-=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0(list
-=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 (max 0 (/ (= - (nth 3 (window-inside-pixel-edges))
-=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0(nth 1 (window-inside-pixel-edges)) -=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0(* (+ bubbles--image-size 1) ;; margi= n
-=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 (bubbles--grid-height))) 2)))= )))
-=C2=A0 =C2=A0 =C2=A0 =C2=A0 (t
-=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0;; compute offset in units of chars
-=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0(setq bubbles--col-offset
-=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0(max 0 (/ (- (windo= w-width)
-=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0 =C2=A0 =C2=A0 (bubbles--grid-width)) 2)))
-=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0(setq bubbles--row-offset
-=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0(max 0 (/ (- (windo= w-height)
-=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0 =C2=A0 =C2=A0 (bubbles--grid-height) 2) 2))))))
+=C2=A0 (let* ((use-images-p (and (display-images-p)
+=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0 =C2=A0 =C2=A0 bubbles--images-ok
+=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0 =C2=A0 =C2=A0 (not (eq bubbles-graphics-theme 'ascii))))
+=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0(bubbles--image-size
+=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 (if use-images-p (car (image-size (car = bubbles--images) t)) 1))
+=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0;; In GUI mode, leave thin margins aroun= d the images.
+=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0(image-hor-size
+=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 (if use-images-p (+ bubbles--image-size= 2) bubbles--image-size))
+=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0(image-vert-size
+=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 (if use-images-p (1+ bubbles--image-siz= e) bubbles--image-size)))
+=C2=A0 =C2=A0 (setq bubbles--col-offset
+=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 (max 0 (/ (- (nth 2 (window-body-pixel-= edges))
+=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0(nth 0 (window-body-pixel-edges))
+=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0(* image-hor-size (bubbles--grid-width)))
+=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 2)))=
+=C2=A0 =C2=A0 (setq bubbles--row-offset
+=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 (max 0 (/ (- (nth 3 (window-body-pixel-= edges))
+=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0(nth 1 (window-body-pixel-edges))
+=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0(* image-vert-size (bubbles--grid-height)))
+=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 2)))= ))

=C2=A0(defun bubbles--remove-overlays ()
=C2=A0 =C2=A0"Remove all overlays."
@@ -1007,7 +1000,8 @@ bubbles--initialize
=C2=A0 =C2=A0 =C2=A0(insert " ")
=C2=A0 =C2=A0 =C2=A0(put-text-property (point-min) (point)
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0 'display
-=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0(cons 'space (list :height bubbles--row-offset)))
+=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0(cons 'space (list :height
+=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 (= list bubbles--row-offset))))
=C2=A0 =C2=A0 =C2=A0(insert "\n")
=C2=A0 =C2=A0 =C2=A0(let ((max-char (length (bubbles--colors))))
=C2=A0 =C2=A0 =C2=A0 =C2=A0(dotimes (i (bubbles--grid-height))
@@ -1015,7 +1009,8 @@ bubbles--initialize
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0(insert " ")
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0(put-text-property p (point)
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 'display
-=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0(cons 'space (list :width bubbles--col-o= ffset))))
+=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0(cons 'space (list :width
+=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 = =C2=A0 =C2=A0 =C2=A0 (list bubbles--col-offset)))))
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0(dotimes (j (bubbles--grid-width))
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0(let* ((index (random max-char)) =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 (char (nth i= ndex bubbles-chars)))
@@ -1025,7 +1020,8 @@ bubbles--initialize
=C2=A0 =C2=A0 =C2=A0 =C2=A0(insert "\n ")
=C2=A0 =C2=A0 =C2=A0 =C2=A0(put-text-property (1- (point)) (point)
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0 =C2=A0 'display
-=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0 =C2=A0(cons 'space (list :width bubbles--col-offset))))
+=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0 =C2=A0(cons 'space (list :width
+=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 = =C2=A0 (list bubbles--col-offset)))))
=C2=A0 =C2=A0 =C2=A0(put-text-property (point-min) (point-max) 'pointer= 'arrow))
=C2=A0 =C2=A0(bubbles-mode)
=C2=A0 =C2=A0(bubbles--reset-score)
@@ -1177,7 +1173,7 @@ bubbles--show-scores
=C2=A0 =C2=A0 =C2=A0 =C2=A0(insert " ")
=C2=A0 =C2=A0 =C2=A0 =C2=A0(put-text-property (1- (point)) (point)
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0 =C2=A0 'display
-=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0 =C2=A0(cons 'space (list :width bubbles--col-offset)))
+=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0 =C2=A0(cons 'space (list :width (list bubbles--col-offset)))= )
=C2=A0 =C2=A0 =C2=A0 =C2=A0(insert (format "Score:=C2=A0 =C2=A0 %4d&qu= ot; bubbles--score))
=C2=A0 =C2=A0 =C2=A0 =C2=A0(put-text-property pos (point) 'status t))))=

@@ -1197,7 +1193,7 @@ bubbles--game-over
=C2=A0 =C2=A0 =C2=A0(insert "\n ")
=C2=A0 =C2=A0 =C2=A0(put-text-property (1- (point)) (point)
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0 'display
-=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0(cons 'space (list :width bubbles--col-offset)))
+=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0(cons 'space (list :width (list bubbles--col-offset))))
=C2=A0 =C2=A0 =C2=A0(insert "Game Over!"))
=C2=A0 =C2=A0;; save score
=C2=A0 =C2=A0(gamegrid-add-score (format "bubbles-%s-%d-%d-%d-scores&q= uot;

--000000000000fae3780576125ad1--