Skip to content

Commit

Permalink
contour & flood-fill
Browse files Browse the repository at this point in the history
  • Loading branch information
c committed Dec 2, 2024
1 parent f9177e8 commit d8f9ba9
Show file tree
Hide file tree
Showing 10 changed files with 603 additions and 23 deletions.
82 changes: 81 additions & 1 deletion README.org
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
#+TITLE: Uniline
#+OPTIONS: ^:{} authors:Thierry Banel, toc:nil

*New*: one-liner Hydra hints (see below "Text menus (Hydra)")
*New*: trace contour & flood-fill shapes

* Pure UNICODΕ text diagrams in Emacs
Draw diagrams like those:
Expand Down Expand Up @@ -392,6 +392,86 @@ move surrounding characters.
and killed rectangles, =killed-rectangle=. So, a rectangle can be killed
one way, and yanked another way.

* Tracing a contour

[[file:images/contour-tracing.png]]

#+begin_example
╭──────────────╮
╭─╯A.written.text╰────────╮
│outlined by the.`contour'│
╰─╮function.gets╶┬────────╯
╰╮a.surrounding╰───────╮
╰─╮line.in.the.current│
╰─╮brush.style╭─────╯
╰───────────╯
#+end_example

Choose or change the brush style with any of =-,+,=_,#,<delete>_=. Put
the cursor anywhere on the shape or outside but touching it. Then
type:

=<insert> c=

A contour line is traced (or erased if brush style is =<delete>=)
around the contiguous shape close to the cursor.

When hitting capital letter: =<insert> C= the contour is
overwritten. This means that if there was already a different style of
line on the contour path, it is overwritten.

The shape is distinguished because it floats in a blank characters
ocean. For the shake of the contour function, blank characters are
those containing lines as drawn by Uniline (including true blank
characters). Locations outside the buffer are also considered blank.

The algorithm has an upper limit of 10000 steps. This avoids an
infinite loop in which the algorithm may end up in some rare
cases. One of those cases is when the contour crosses a new-page
character, displayed by Emacs as =^L=. 10000 steps require a fraction of
a second to run. For shapes really huge, you may launch the contour
command once again, at the point where the previous run ended.

* Flood-fill

[[file:images/flood-fill.png]]

#+begin_example

this.text.surrounds this.text.surrounds
. / .▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒/
. //╶───▷╴.▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒//
... //// ...▒▒▒▒▒▒▒▒▒▒▒▒////
...a.hole///// ...a.hole/////

#+end_example

A hollow shape is a contiguous region of identical characters (not
necessarily blank), surrounded by a boundary of different
characters. The end of the buffer in any direction is also considered
a boundary.

Put the cursor anywhere in the hole. Then type:

=<insert> i=

Answer by giving a character to fill the hole.

If instead of a character, =SPC= or =DEL= is typed, then a shade of grey
character is picked. =SPC= selects a darker grey than the one the point
is on, while =DEL= selects a lighter. There are 5 shades of grey in the
UNICODE standard: =" ░▒▓█"=. Those grey characters are well supported
by the suggested fonts.

=C-y= is also an option. The first character in the top of the kill
ring will be chosen as the filling character. The kill ring is filled
by functions like =C-k= or =M-w=, which remove text from the buffer.

Typing =RET= aborts the filling operation.

There is no limit on the area to fill. Therefore, the filling
operation may flood the entire buffer (but no more).

* Text direction
Usually, inserting text in a buffer moves the cursor to the right. (And
sometimes to the left for some locales). Any of the 4 directions can be
Expand Down
Binary file added images/contour-tracing.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added images/flood-fill.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
40 changes: 40 additions & 0 deletions tests/bench12.el
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
;;; uniline.el --- Draw lines, boxes, & arrows with the keyboard -*- coding:utf-8; lexical-binding: t; -*-

;; Copyright (C) 2024 Thierry Banel

;; Author: Thierry Banel tbanelwebmin at free dot fr
;; Version: 1.0
;; URL: https://github.com/tbanel/uniline

;; Uniline is free software: you can redistribute it and/or modify
;; it under the terms of the GNU General Public License as published by
;; the Free Software Foundation, either version 3 of the License, or
;; (at your option) any later version.

;; Uniline is distributed in the hope that it will be useful,
;; but WITHOUT ANY WARRANTY; without even the implied warranty of
;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
;; GNU General Public License for more details.

;; You should have received a copy of the GNU General Public License
;; along with this program. If not, see <http://www.gnu.org/licenses/>.

(uniline-bench
"<return> <down> <down> <down> <right> <right> <right> <right> <right> S-<down> S-<down> S-<down> S-<down> S-<down> S-<down> S-<right> S-<right> S-<right> S-<right> S-<right> S-<right> S-<right> S-<right> S-<right> S-<right> S-<right> <insert> i SPC <return> <down> <down> <down> <right> <right> <right> <right> <right> <right> <right> <down> S-<down> S-<down> S-<down> S-<down> S-<down> S-<down> S-<right> S-<right> S-<right> S-<right> S-<right> S-<right> S-<right> S-<right> <insert> i y <return> <up> <up> S-<left> S-<left> S-<left> S-<left> S-<left> S-<up> <insert> i SPC <return>"
"\
░░░░░░░░░░░
░░▒▒▒▒▒░░░░
░░▒▒▒▒▒░░░░
░░░░░░░░░░░
░░░░░░░yyyyyyyy
░░░░░░░yyyyyyyy
░░░░░░░yyyyyyyy
yyyyyyyy
yyyyyyyy
yyyyyyyy
yyyyyyyy
")
36 changes: 36 additions & 0 deletions tests/bench6.el
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
;;; uniline.el --- Draw lines, boxes, & arrows with the keyboard -*- coding:utf-8; lexical-binding: t; -*-

;; Copyright (C) 2024 Thierry Banel

;; Author: Thierry Banel tbanelwebmin at free dot fr
;; Version: 1.0
;; URL: https://github.com/tbanel/uniline

;; Uniline is free software: you can redistribute it and/or modify
;; it under the terms of the GNU General Public License as published by
;; the Free Software Foundation, either version 3 of the License, or
;; (at your option) any later version.

;; Uniline is distributed in the hope that it will be useful,
;; but WITHOUT ANY WARRANTY; without even the implied warranty of
;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
;; GNU General Public License for more details.

;; You should have received a copy of the GNU General Public License
;; along with this program. If not, see <http://www.gnu.org/licenses/>.

(uniline-bench
"<return> <down> <down> <right> <right> <right> <right> <right> m ù q <down> v <down> h u <down> <left> u <down> <left> u <down> <left> u <left> <left> u <left> <left> u <left> <left> u <down> <left> u <left> <left> u <left> <left> u <left> <left> u <up> <left> u <left> <left> a <up> <left> é <up> <left> <left> 1 <up> <left> 2 i i <down> <up> i <up> <up> <left> <left> <left> <left> C-SPC <down> <down> <down> <down> <down> <down> <right> <right> <right> <right> <right> <right> <right> <right> <right> <insert> c <up> <right> <right> <right> <up> <up> <up> <up> y <return> <left> <left> <left> <left> <left> <left> <insert> <return> <kp-subtract> <insert> c <return> <right> <right> <right> <right> <right> <right> <right> j <down> <left> j <down> <down> <insert> i SPC"
"\
╭───╮
│mùq╰╮
╭──┴─┬╮v╰─╮ jmùq
│2iii│╰╮hu│ j░░░v
│1╶┬─╯ ╰╮u│ 2iii░░░hu
╰╮é╰╮╭──╯u│ 1░░░░░░░u
│au╰╯uuuu│ é░░░░░░u
╰╮uuuu╭──╯ au░░uuuu
╰────╯ uuuu
")
36 changes: 36 additions & 0 deletions tests/bench7.el
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
;;; uniline.el --- Draw lines, boxes, & arrows with the keyboard -*- coding:utf-8; lexical-binding: t; -*-

;; Copyright (C) 2024 Thierry Banel

;; Author: Thierry Banel tbanelwebmin at free dot fr
;; Version: 1.0
;; URL: https://github.com/tbanel/uniline

;; Uniline is free software: you can redistribute it and/or modify
;; it under the terms of the GNU General Public License as published by
;; the Free Software Foundation, either version 3 of the License, or
;; (at your option) any later version.

;; Uniline is distributed in the hope that it will be useful,
;; but WITHOUT ANY WARRANTY; without even the implied warranty of
;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
;; GNU General Public License for more details.

;; You should have received a copy of the GNU General Public License
;; along with this program. If not, see <http://www.gnu.org/licenses/>.

(uniline-bench
"a a <return> <right> a a <left> <left> <left> a <right> <down> a <down> <left> a <down> <left> a a a a a a <up> <left> a <up> <left> a <up> <left> a a a a a <down> <left> <left> <home> <down> <up> a <down> <left> a <down> <left> a <down> <left> a <down> <left> a a a a <down> <left> a <down> <left> a <down> <left> a <left> <left> a <left> <left> a <left> <left> a <down> <left> a <left> <kp-subtract> <insert> c"
"\
aaaaa╷ ╷aaaaa╷
a╭─╮a│ │a╭───╯
a│ │a╰──╯a│
a│ │aaaaaa│
a╰─┴┬─────╯
aaaa│
╶─╮a│
╶─╯a│
aaaa│
a╭──╯
╶╯
")
44 changes: 44 additions & 0 deletions tests/bench8.el
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
;;; uniline.el --- Draw lines, boxes, & arrows with the keyboard -*- coding:utf-8; lexical-binding: t; -*-

;; Copyright (C) 2024 Thierry Banel

;; Author: Thierry Banel tbanelwebmin at free dot fr
;; Version: 1.0
;; URL: https://github.com/tbanel/uniline

;; Uniline is free software: you can redistribute it and/or modify
;; it under the terms of the GNU General Public License as published by
;; the Free Software Foundation, either version 3 of the License, or
;; (at your option) any later version.

;; Uniline is distributed in the hope that it will be useful,
;; but WITHOUT ANY WARRANTY; without even the implied warranty of
;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
;; GNU General Public License for more details.

;; You should have received a copy of the GNU General Public License
;; along with this program. If not, see <http://www.gnu.org/licenses/>.

(uniline-bench
"<return> a <left> <down> a <left> <down> a <left> <up> <up> <right> a a a <left> <kp-add> <insert> c <return> <right> <right> <right> <right> <right> <right> h h h h <left> <down> h <left> <left> h <left> <down> h h h h h h h h h <left> <up> h <left> <up> h h h h <left> <left> <left> <down> h <left> <down> h <left> + <insert> c <return> <home> <down> <down> <down> <down> <down> g g g g <left> <down> g <left> <down> g <left> <down> g <left> <down> g <left> <down> g <left> <left> g <left> <left> g <left> <left> g <left> <down> g g g g <left> <down> g <left> <down> g <left> <down> g <left> <down> g <left> <left> g <left> <left> g <left> <left> g <left> <kp-subtract> <insert> c <return> <up> <up> <up> <up> <up> <up> <up> <up> <up> <up> <right> <right> <right> <right> <right> <right> <right> <right> o o o o o o o o <left> <down> <right> o <left> <down> o <left> <down> o <left> <down> o <left> <down> o <left> <down> o <left> <down> o <left> <down> o <left> <left> <down> o <left> <left> o <left> <left> o <left> <left> o <left> <left> o <left> <up> <left> o <left> <up> <left> o <left> <up> <left> o <left> <up> <left> o <left> <up> o <left> <up> o <left> <up> o <left> <up> o <left> <kp-subtract> <insert> c <return> <down> <right> <right> <insert> i * <return> <up> <up> <kp-subtract> <insert> c"
"\
aaaa╻ ╻hhhh╻ ╻hhhh╻
a┏━━┛ ┗━┓hh┗━━━━┛hh┏━┛
a┃ ┃hhhhhhhhhh┃
╺┛ ┗━━━━━━━━━━┛
╶───╮ ╭────────╮
gggg│ ╭╯oooooooo╰╮
╶─╮g│ │o╭──────╮o│
│g│ │o│******│o│
│g│ │o│******│o│
╶─╯g│ │o│******│o│
gggg│ │o╰╮*****│o│
gggg│ ╰╮o╰╮****│o│
╶─╮g│ ╰╮o╰╮***│o│
│g│ ╰╮o╰───╯o│
╶─╯g│ ╰╮ooooo╭╯
gggg│ ╰─────╯
╶───╯
")
37 changes: 37 additions & 0 deletions tests/bench9.el
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
;;; uniline.el --- Draw lines, boxes, & arrows with the keyboard -*- coding:utf-8; lexical-binding: t; -*-

;; Copyright (C) 2024 Thierry Banel

;; Author: Thierry Banel tbanelwebmin at free dot fr
;; Version: 1.0
;; URL: https://github.com/tbanel/uniline

;; Uniline is free software: you can redistribute it and/or modify
;; it under the terms of the GNU General Public License as published by
;; the Free Software Foundation, either version 3 of the License, or
;; (at your option) any later version.

;; Uniline is distributed in the hope that it will be useful,
;; but WITHOUT ANY WARRANTY; without even the implied warranty of
;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
;; GNU General Public License for more details.

;; You should have received a copy of the GNU General Public License
;; along with this program. If not, see <http://www.gnu.org/licenses/>.

(uniline-bench
"<return> <down> <down> <down> <down> <down> <down> <down> <down> <down> <down> g <left> <up> g g g g <left> <up> g <left> <up> g g <left> <up> g <left> <left> g <left> <left> g <left> <left> g <left> <left> g <left> <up> g <left> <up> g g g g g g g <left> <up> g <left> <up> g <left> <up> g <left> <left> g <left> <left> g <left> <left> g <left> <left> g <left> <left> g <left> <left> g <left> <up> g g g g g g g g g g g <left> <down> g <left> <down> g g g g g g g g g g <left> <up> g <left> <up> g <left> <left> <left> <left> <left> <left> g <left> <down> <right> <up> g <left> <up> <right> <right> <right> <right> <right> g g g g <left> <down> <down> <down> <down> <down> <down> <left> <left> <left> <left> <left> <left> <left> <left> <left> <left> <left> <left> <left> <up> <up> <left> <left> p p p p p p <left> <down> p <left> p <left> <left> p <left> <left> p <left> <left> p <left> <left> p <left> <left> p <left> <up> <left> <left> <left> <left> <kp-subtract> <insert> c"
"\
ggggggggggg╷ gg ╷ggggg╷
ggggggg╭─╮g╰──────╯g╭───╯
╶────╮g│ │gggggggggg│
╶────╯g│ ╰──────────╯
ggggggg│pppppp
g╶───┬─╯pppppp
ggggg│
╶─╮gg│
╶─╯g╭╯
gggg│
g╭──╯
╶╯
")
24 changes: 16 additions & 8 deletions tests/uniline-bench.el
Original file line number Diff line number Diff line change
Expand Up @@ -113,19 +113,27 @@ Stops on the first error, presenting two buffers,
with points on the first difference.
If there are no errors, a summary buffer is presented."
(interactive)
(let ((buf (current-buffer)))
(let ((buf (current-buffer))
(nbpassed 0)
(nbfailed 0))
(cl-loop
for file in (directory-files "." nil "\\.el$")
unless (equal "uniline-bench.el" file)
do
(load (format "%s%s" default-directory file) nil nil t)
while uniline-bench-result)
(if (not uniline-bench-result)
(message "at least one bench FAILED")
(switch-to-buffer buf)
(message "all benches PASSED"))))

(uniline-bench-run)
(if uniline-bench-result
(cl-incf nbpassed)
(cl-incf nbfailed)
(message "%s FAILED" file)))
(switch-to-buffer buf)
(message "%s PASSED / %s FAILED" nbpassed nbfailed)))

(if t
(uniline-bench-run)
(profiler-start 'cpu+mem)
(uniline-bench-run)
(profiler-stop)
(profiler-report))

(provide 'uniline-bench)
;;; uniline-bench.el ends here
Loading

0 comments on commit d8f9ba9

Please sign in to comment.