Function: indent-bars--stipple

indent-bars--stipple is a natively compiled function defined in indent-bars.el.

Signature

(indent-bars--stipple W H ROT &optional STYLE WIDTH-FRAC PAD-FRAC PATTERN ZIGZAG)

Documentation

Calculate stipple bitmap pattern for char width W and height H.

ROT is the number of bits to rotate the pattern around to the right (with wrap).

Uses configuration variables indent-bars-width-frac, indent-bars-pad-frac, indent-bars-pattern, and indent-bars-zigzag, unless PAD-FRAC, WIDTH-FRAC, PATTERN, and/or ZIGZAG are set (the latter overriding the config variables, which see). If STYLE is set, use config variables appropriate for that style.

Source Code

;; Defined in /nix/store/zkcdcnmcj3605fj09x584bf58d85brax-emacs-packages-deps/share/emacs/site-lisp/elpa/indent-bars-1.0.1/indent-bars.el
;; ** Notes on the stipples:
;;
;; indent-bars by default uses a selectively-revealed stipple pattern
;; with a width equivalent to the (presumed fixed) width of individual
;; characters to efficiently draw bars.  A stipple pattern is drawn as
;; a fixed repeating bit pattern, with its lowest bits and earlier
;; bytes leftmost.  It is drawn with respect to the *entire frame*,
;; with its first bit aligned with the first (leftmost) frame pixel.
;;
;; Turning on :stipple for a character merely "opens a window" on that
;; frame-filling, repeating stipple pattern.  Since the pattern starts
;; outside the body (in literally the first frame pixel, typically
;; within the fringe), you must consider the shift between the first
;; pixel of a window character and the first pixel of the repeating
;; stipple block at that pixel position or above:
;;
;;     |<-frame edge |<---buffer/window edge
;;     |<--w-->|<--w-->|<--w-->|     w = pattern width
;;     | marg+fringe |<-chr->|     chr = character width = w
;;             |<-g->|               g = gutter offset of chr start, g<w
;;
;; Or, when the character width exceeds the margin/fringe offset:
;;
;;     |<-frame edge |<---buffer/window edge
;;     |<--------w-------->|<---------w-------->|
;;     | marg+fringe |<-------chr------->|
;;     |<-----g----->|
;;
;; So g = (mod marg+fringe w).
;;
;; When the block/zigzag/whatever stipple pattern is made, to align
;; with characters, it must be shifted up (= right) by g bits, with
;; carry over (wrap) around w=space-width bits (i.e the width of the
;; bitmap in pixels).  The byte/bit pattern is first-lowest-leftmost.
;;
;; Note that different windows may have different g values
;; (e.g. left/right), which means the same bitmap cannot work for the
;; buffer in both windows.  In practice that means that all stipple
;; face attributes must be set via filtered face remaps, with the
;; filter set to match the pattern size (width and height) as well as
;; gutter offset "rot" value in that window, which we combine into a
;; single integer.
;;
;; Note: a bug in Emacs <29 means `face-remapping-alist' is
;; unintentionally shared between indirect and master buffers.  Fixed
;; in Emacs 29.

(defun indent-bars--stipple (w h rot &optional style
			       width-frac pad-frac pattern zigzag)
  "Calculate stipple bitmap pattern for char width W and height H.
ROT is the number of bits to rotate the pattern around to the
right (with wrap).

Uses configuration variables `indent-bars-width-frac',
`indent-bars-pad-frac', `indent-bars-pattern', and
`indent-bars-zigzag', unless PAD-FRAC, WIDTH-FRAC, PATTERN,
and/or ZIGZAG are set (the latter overriding the config
variables, which see).  If STYLE is set, use config variables
appropriate for that style."
  (unless (or (not (display-graphic-p)) indent-bars-prefer-character)
    (let* ((rowbytes (/ (+ w 7) 8))
	   (pattern (or pattern (indent-bars--style style "pattern")))
	   (pat (if (< h (length pattern)) (substring pattern 0 h) pattern))
	   (plen (max (length pat) 1))
	   (chunk (/ (float h) plen))
	   (small (floor chunk))
	   (large (ceiling chunk))
	   (pad-frac (or pad-frac (indent-bars--style style "pad-frac")))
	   (pad (round (* w pad-frac)))
	   (zigzag (or zigzag (indent-bars--style style "zigzag")))
	   (zz (if zigzag (round (* w zigzag)) 0))
	   (zeroes (make-string rowbytes ?\0))
	   (width-frac (or width-frac (indent-bars--style style "width-frac")))
	   (dlist (if (and (= plen 1) (not (string= pat " "))) ; solid bar
		      (list (indent-bars--row-data w pad rot width-frac)) ; one row
		    (cl-loop for last-fill-char = nil then x
			     for x across pat
			     for n = small then (if (and (/= x ?\s) (= n small))
						    large
						  small)
			     for zoff = zz then (if (and last-fill-char
							 (/= x ?\s)
							 (/= x last-fill-char))
						    (- zoff) zoff)
			     for row = (if (= x ?\s) zeroes
					 (indent-bars--row-data w (+ pad zoff)
								rot width-frac))
			     append (cl-loop repeat n collect row)))))
      (list w (length dlist) (string-join dlist)))))