#("思源黑体 Light" 0 10 (charset chinese-gbk)) 是什么结构

运行 (font-family-list) 出来一个 list,按理应该都是string,但是有些中文字体的名称是 #("思源黑体 Light" 0 10 (charset chinese-gbk)) 这样的。

请问这是什么结构?如何变成单纯的 "思源黑体 Light"?

可能这是一个gbk格式的字符串

1赞

通过 (decode-coding-string #("思源黑体 Light" 0 10 (charset chinese-gbk)) 'chinese-gbk)转回来了

有一个问题是,如果字体名称是gbk格式的,你转成utf8,字体可能就识别不了了

Windows系统,虽然coding-priority是utf-8,但是经过上述decode之后没有问题,可以用


我是用在一个函数里

(defun my-font-list-all-fonts ()
  "List all fonts."
  (interactive)
  (let ((str "The quick brown fox jumps over the lazy dog ´`''\"\"1lI|¦!Ø0Oo{[()]}.,:; 汉字显示")
        (font-families (cl-remove-duplicates
		                (sort (font-family-list)
			                  (lambda(x y) (string< (upcase x) (upcase y))))
		                :test 'string=)))
    (with-current-buffer (get-buffer-create "*font-list*")
      (dolist (ff font-families)
        ;; (setq ff (decode-coding-string ff 'chinese-gbk))
        (insert
         (propertize str 'font-lock-face `(:family ,ff))               " " ff "\n"
         (propertize str 'font-lock-face `(:family ,ff :slant italic)) " " ff "\n"))
      (font-lock-mode)
      (goto-char (point-min))))
  (display-buffer (get-buffer-create "*font-list*"))
  )

来显示所有字体的。结果里中文没有正确的font-lock,我以为是那个带"#"的字符串的问题。decode后还是没变化。可能是因为前边用过

(set-fontset-font nil charset
                                 (font-spec :family "微软雅黑 Light")
                                 frame)

所以汉字都是"微软雅黑 Light"显示的。

就是字符串,带property的字符串

(stringp #("思源黑体 Light" 0 10 (charset chinese-gbk)))
;; => t

可以用substring-no-properties去掉,不过你不去掉property也不影响这东西可以作为字符串使用

(substring-no-properties #("思源黑体 Light" 0 10 (charset chinese-gbk)))
;; => "思源黑体 Light"

内部字符串必定是UTF-8编码


https://www.gnu.org/software/emacs/manual/html_node/elisp/Text-Props-and-Strings.html

Elisp manual和Emacs manual都是好东西,还可以用内置的info阅读器阅读。

3赞