Function: window-largest-empty-rectangle

window-largest-empty-rectangle is a byte-compiled function defined in window.el.gz.

Signature

(window-largest-empty-rectangle &optional WINDOW COUNT MIN-WIDTH MIN-HEIGHT POSITIONS LEFT)

Documentation

Return dimensions of largest empty rectangle in WINDOW.

WINDOW must be a live window and defaults to the selected one.

The return value is a triple of the width and the start and end Y-coordinates of the largest rectangle that can be inscribed into the empty space (the space not displaying any text) of WINDOW's text area. The return value is nil if the current glyph matrix of WINDOW is not up-to-date.

Optional argument COUNT, if non-nil, specifies the maximum number of rectangles to return. This means that the return value is a list of triples specifying rectangles with the largest rectangle first. COUNT can be also a cons cell whose car specifies the number of rectangles to return and whose cdr, if non-nil, states that all rectangles returned must be disjoint.

Note that the right edge of any rectangle returned by this function is the right edge of WINDOW (the left edge if its buffer displays RTL text).

Optional arguments MIN-WIDTH and MIN-HEIGHT, if non-nil, specify the minimum width and height of any rectangle returned.

Optional argument POSITIONS, if non-nil, is a cons cell whose car specifies the uppermost and whose cdr specifies the lowermost pixel position that must be covered by any rectangle returned. Note that positions are counted from the start of the text area of WINDOW.

Optional argument LEFT, if non-nil, means to return values suitable for buffers displaying right to left text.

View in manual

Probably introduced at or before Emacs version 26.1.

Source Code

;; Defined in /usr/src/emacs/lisp/window.el.gz
(defun window-largest-empty-rectangle (&optional window count min-width min-height positions left)
  "Return dimensions of largest empty rectangle in WINDOW.
WINDOW must be a live window and defaults to the selected one.

The return value is a triple of the width and the start and end
Y-coordinates of the largest rectangle that can be inscribed into
the empty space (the space not displaying any text) of WINDOW's
text area.  The return value is nil if the current glyph matrix
of WINDOW is not up-to-date.

Optional argument COUNT, if non-nil, specifies the maximum number
of rectangles to return.  This means that the return value is a
list of triples specifying rectangles with the largest rectangle
first.  COUNT can be also a cons cell whose car specifies the
number of rectangles to return and whose cdr, if non-nil, states
that all rectangles returned must be disjoint.

Note that the right edge of any rectangle returned by this
function is the right edge of WINDOW (the left edge if its buffer
displays RTL text).

Optional arguments MIN-WIDTH and MIN-HEIGHT, if non-nil, specify
the minimum width and height of any rectangle returned.

Optional argument POSITIONS, if non-nil, is a cons cell whose car
specifies the uppermost and whose cdr specifies the lowermost
pixel position that must be covered by any rectangle returned.
Note that positions are counted from the start of the text area
of WINDOW.

Optional argument LEFT, if non-nil, means to return values suitable for
buffers displaying right to left text."
  ;; Process lines as returned by ‘window-lines-pixel-dimensions’.
  ;; STACK is a stack that contains rows that have yet to be processed.
  (let* ((window (window-normalize-window window t))
	 (disjoint (and (consp count) (cdr count)))
	 (count (or (and (numberp count) count)
		    (and (consp count) (numberp (car count)) (car count))))
	 (rows (window-lines-pixel-dimensions window nil nil t t left))
	 (rows-at 0)
	 (max-size 0)
	 row stack stack-at stack-to
	 top top-width top-at top-to top-size
	 max-width max-at max-to maximums)
    ;; ROWS-AT is the position where the first element of ROWS starts.
    ;; STACK-AT is the position where the first element of STACK starts.
    (while rows
      (setq row (car rows))
      (if (or (not stack) (>= (car row) (caar stack)))
	  (progn
	    (unless stack
	      (setq stack-at rows-at))
	    (setq stack (cons row stack))
	    ;; Set ROWS-AT to where the first element of ROWS ends
	    ;; which, after popping ROW, makes it the start position of
	    ;; the next ROW.
	    (setq rows-at (cdr row))
	    (setq rows (cdr rows)))
	(setq top (car stack))
	(setq stack (cdr stack))
	(setq top-width (car top))
	(setq top-at (if stack (cdar stack) stack-at))
	(setq top-to (cdr top))
	(setq top-size (* top-width (- top-to top-at)))
	(unless (or (and min-width (< top-width min-width))
		    (and min-height (< (- top-to top-at) min-height))
		    (and positions
			 (or (> top-at (car positions))
			     (< top-to (cdr positions)))))
	  (if count
	      (if disjoint
		  (setq maximums (cons (list top-size top-width top-at top-to)
				       maximums))
		(setq maximums (window-largest-empty-rectangle--maximums
				(list top-size top-width top-at top-to)
				maximums count)))
	    (when (> top-size max-size)
	      (setq max-size top-size)
	      (setq max-width top-width)
	      (setq max-at top-at)
	      (setq max-to top-to))))
	(if (and stack (> (caar stack) (car row)))
	    ;; Have new top element of stack include old top.
	    (setq stack (cons (cons (caar stack) (cdr top)) (cdr stack)))
	  ;; Move rows-at backwards to top-at.
	  (setq rows-at top-at))))

    (when stack
      ;; STACK-TO is the position where the stack ends.
      (setq stack-to (cdar stack))
      (while stack
	(setq top (car stack))
	(setq stack (cdr stack))
	(setq top-width (car top))
	(setq top-at (if stack (cdar stack) stack-at))
	(setq top-size (* top-width (- stack-to top-at)))
	(unless (or (and min-width (< top-width min-width))
		    (and min-height (< (- stack-to top-at) min-height))
		    (and positions
			 (or (> top-at (car positions))
			     (< stack-to (cdr positions)))))
	  (if count
	      (if disjoint
		  (setq maximums (cons (list top-size top-width top-at stack-to)
				       maximums))
		(setq maximums (window-largest-empty-rectangle--maximums
				(list top-size top-width top-at stack-to)
				maximums count)))
	    (when (> top-size max-size)
	      (setq max-size top-size)
	      (setq max-width top-width)
	      (setq max-at top-at)
	      (setq max-to stack-to))))))

    (cond
     (maximums
      (if disjoint
	  (window-largest-empty-rectangle--disjoint-maximums maximums count)
	maximums))
     ((> max-size 0)
      (list max-width max-at max-to)))))