Function: artist-flood-fill

artist-flood-fill is a byte-compiled function defined in artist.el.gz.

Signature

(artist-flood-fill X1 Y1)

Documentation

Flood-fill starting at X1, Y1. Fill with the char in artist-fill-char.

Source Code

;; Defined in /usr/src/emacs/lisp/textmodes/artist.el.gz
(defun artist-flood-fill (x1 y1)
  "Flood-fill starting at X1, Y1.  Fill with the char in `artist-fill-char'."
  (let ((stack nil)
	;; We are flood-filling the area that has this character.
	(c     (artist-get-char-at-xy-conv x1 y1))
        (artist-fill-char (if artist-fill-char-set
                              artist-fill-char
                            artist-default-fill-char)))

    ;; Fill only if the fill-char is not the same as the character whose
    ;; area we are about to fill, or, in other words, don't fill if we
    ;; needn't.
    (if (not (= c artist-fill-char))
	(push (artist-new-coord x1 y1) stack))

    (while (not (null stack))
      (let* ((coord (pop stack))
	     (x (artist-coord-get-x coord))
	     (y (artist-coord-get-y coord))

	     ;; Here we keep track of the leftmost and rightmost position
	     ;; for this run
	     (x-leftmost 0)
	     (x-rightmost 0)
	     (last-x 0)

	     ;; Remember if line above and below are accessible
	     ;; Lines below the last one, and prior to the first-one
	     ;; are not accessible.
	     (lines-above nil)
	     (lines-below nil)

	     ;; Remember char for position on line above and below, so we
	     ;; can find the rightmost positions on the runs.
	     (last-c-above -1)
	     (last-c-below -1))

	(setq x-rightmost (artist-ff-get-rightmost-from-xy x y))
	(setq lines-above (not (artist-ff-is-topmost-line x y)))
	(setq lines-below (not (artist-ff-is-bottommost-line x y)))
	(setq last-x x-rightmost)
	(setq x x-rightmost)

	;; Search line above, push rightmost positions of runs for that line
	(while (and (>= x 0) (= c (artist-get-char-at-xy-conv x y)))
	  (if lines-above
	      (let ((c-above (artist-get-char-at-xy-conv x (- y 1))))
		(if (and (= c-above c) (/= c-above last-c-above))
		    (push (artist-new-coord x (- y 1)) stack))
		(setq last-c-above c-above)))
	  (setq last-x x)
	  (setq x (- x 1)))

	;; Remember the left-most position on this run
	(setq x-leftmost last-x)

	;; Search line below, push rightmost positions of runs for that line
	(setq x x-rightmost)
	(while (>= x x-leftmost)
	  (if lines-below
	      (let ((c-below (artist-get-char-at-xy-conv x (1+ y))))
		(if (and (= c-below c) (/= c-below last-c-below))
		    (push (artist-new-coord x (1+ y)) stack))
		(setq last-c-below c-below)))
	  (setq x (- x 1)))

	(artist-move-to-xy x-leftmost y)
	(artist-replace-chars artist-fill-char (1+ (- x-rightmost x-leftmost)))

	;; If we are to show incrementally, we have to remove any pending
	;; input from the input queue, because processing of pending input
	;; always has priority over display updates (although this input
	;; won't be processed until we are done). Later on we will queue
	;; the input on the input queue again.
	(if artist-flood-fill-show-incrementally
	    (progn
	      (if (input-pending-p)
		  (discard-input))
	      (artist-update-display)))))))