Function: org-string-width

org-string-width is a byte-compiled function defined in org-macs.el.gz.

Signature

(org-string-width STRING &optional PIXELS DEFAULT-FACE)

Documentation

Return width of STRING when displayed in the current buffer.

Return width in pixels when PIXELS is non-nil. When PIXELS is nil, DEFAULT-FACE is the face used to calculate relative STRING width. When REFERENCE-FACE is nil, default face is used.

Source Code

;; Defined in /usr/src/emacs/lisp/org/org-macs.el.gz
(defun org-string-width (string &optional pixels default-face)
  "Return width of STRING when displayed in the current buffer.
Return width in pixels when PIXELS is non-nil.
When PIXELS is nil, DEFAULT-FACE is the face used to calculate relative
STRING width.  When REFERENCE-FACE is nil, `default' face is used."
  (if (and (version< emacs-version "28") (not pixels))
      ;; FIXME: Fallback to old limited version, because
      ;; `window-pixel-width' is buggy in older Emacs.
      (org--string-width-1 string)
    ;; Wrap/line prefix will make `window-text-pixel-size' return too
    ;; large value including the prefix.
    (remove-text-properties 0 (length string)
                            '(wrap-prefix t line-prefix t)
                            string)
    ;; Face should be removed to make sure that all the string symbols
    ;; are using default face with constant width.  Constant char width
    ;; is critical to get right string width from pixel width (not needed
    ;; when PIXELS are requested though).
    (unless pixels
      (put-text-property 0 (length string) 'face (or default-face 'default) string))
    (let (;; We need to remove the folds to make sure that folded table
          ;; alignment is not messed up.
          (current-invisibility-spec
           (or (and (not (listp buffer-invisibility-spec))
                    buffer-invisibility-spec)
               (let (result)
                 (dolist (el buffer-invisibility-spec)
                   (unless (or (memq el
                                     '(org-fold-drawer
                                       org-fold-block
                                       org-fold-outline))
                               (and (listp el)
                                    (memq (car el)
                                          '(org-fold-drawer
                                            org-fold-block
                                            org-fold-outline))))
                     (push el result)))
                 result)))
          (current-char-property-alias-alist char-property-alias-alist))
      (with-current-buffer (get-buffer-create " *Org string width*")
        (setq-local display-line-numbers nil)
        (setq-local line-prefix nil)
        (setq-local wrap-prefix nil)
        (setq-local buffer-invisibility-spec
                    (if (listp current-invisibility-spec)
                        (mapcar (lambda (el)
                                  ;; Consider ellipsis to have 0 width.
                                  ;; It is what Emacs 28+ does, but we have
                                  ;; to force it in earlier Emacs versions.
                                  (if (and (consp el) (cdr el))
                                      (list (car el))
                                    el))
                                current-invisibility-spec)
                      current-invisibility-spec))
        (setq-local char-property-alias-alist
                    current-char-property-alias-alist)
        (let (pixel-width symbol-width)
          (with-silent-modifications
            (erase-buffer)
            (insert string)
            (setq pixel-width (org-buffer-text-pixel-width))
            (unless pixels
              (erase-buffer)
              (insert (propertize "a" 'face (or default-face 'default)))
              (setq symbol-width (org-buffer-text-pixel-width))))
          (if pixels
              pixel-width
            (ceiling pixel-width symbol-width)))))))