rougier / svg-lib

Emacs SVG libraries for creatings tags, icons and bars
GNU General Public License v3.0
335 stars 30 forks source link

When run `svg-lib-button` gets error - "Debugger entered--Lisp error: (wrong-type-argument arrayp nil)" #2

Closed chenyanming closed 3 years ago

chenyanming commented 3 years ago

Run demo code:

(svg-lib-button "check-bold" "DONE" nil
                                                             :font-family "Roboto Mono"
                                                             :font-weight 500
                                                             :stroke 0 :background "#673AB7" :foreground "white")

But get me the following error

Debugger entered--Lisp error: (wrong-type-argument arrayp nil)
  aref(nil 8)
  (let* ((default svg-lib-style-default) (style (if style (apply #'svg-lib-style nil style) default)) (style (if args (apply #'svg-lib-style style args) style)) (collection (plist-get style :collection)) (root (svg-lib--icon-get-data collection icon)) (foreground (plist-get style :foreground)) (background (plist-get style :background)) (stroke (plist-get style :stroke)) (width (plist-get style :width)) (height (plist-get style :height)) (radius (plist-get style :radius)) (scale (plist-get style :scale)) (margin (plist-get style :margin)) (padding (plist-get style :padding)) (font-size (plist-get style :font-size)) (font-family (plist-get style :font-family)) (font-weight (plist-get style :font-weight)) (label-length (+ (length label) 2)) (txt-char-width (window-font-width)) (txt-char-height (window-font-height)) (box-width (* width txt-char-width)) (box-height (* height txt-char-height)) (font-info (font-info (format "%s:%d" font-family font-size))) (ascent (aref font-info 8)) (tag-char-width (aref font-info 11)) (tag-char-height (aref font-info 3)) (tag-width (* (+ label-length padding) txt-char-width)) (tag-height (* txt-char-height height)) (svg-width (+ tag-width (* margin txt-char-width))) (svg-height tag-height) (tag-x (/ (- svg-width tag-width) 2)) (text-x (+ tag-x (/ (- tag-width (* (length label) tag-char-width)) 2))) (text-x (+ text-x tag-char-width)) (text-y ascent) (viewbox (cdr (assq 'viewBox (xml-node-attributes (car root))))) (viewbox (mapcar 'string-to-number (split-string viewbox))) (icon-x (nth 0 viewbox)) (icon-y (nth 1 viewbox)) (icon-width (nth 2 viewbox)) (icon-height (nth 3 viewbox)) (scale (* scale (/ (float tag-height) (float icon-height)))) (icon-transform (format "translate(%f,%f) scale(%f) translate(%f,%f)" (- icon-x) (- icon-y) scale (- (/ (- text-x (* tag-char-width 1.25)) scale) (/ icon-width 2)) (- (/ svg-height 2 scale) (/ icon-height 2)))) (svg (svg-create svg-width svg-height))) (if (>= stroke 0.25) (svg-rectangle svg tag-x 0 tag-width tag-height :fill foreground :rx radius)) (svg-rectangle svg (+ tag-x (/ stroke 2.0)) (/ stroke 2.0) (- tag-width stroke) (- tag-height stroke) :fill background :rx (- radius (/ stroke 2.0))) (svg-text svg label :font-family font-family :font-weight font-weight :font-size font-size :fill foreground :x text-x :y text-y) (dolist (item (xml-get-children (car root) 'path)) (let* ((attrs (xml-node-attributes item)) (path (cdr (assoc 'd attrs))) (fill (or (cdr (assoc ... attrs)) foreground))) (svg-node svg 'path :d path :fill foreground :transform icon-transform))) (svg-image svg :scale 1 :ascent 'center))
  svg-lib-button("check-bold" "DONE" nil :font-family "Roboto Mono" :font-weight 500 :stroke 0 :background "#673AB7" :foreground "white")
  (progn (svg-lib-button "check-bold" "DONE" nil :font-family "Roboto Mono" :font-weight 500 :stroke 0 :background "#673AB7" :foreground "white"))
  eval((progn (svg-lib-button "check-bold" "DONE" nil :font-family "Roboto Mono" :font-weight 500 :stroke 0 :background "#673AB7" :foreground "white")) t)
  elisp--eval-last-sexp(nil)
  #f(compiled-function (eval-last-sexp-arg-internal) "Evaluate sexp before point; print value in the echo area.\nInteractively, with a non `-' prefix argument, print output into\ncurrent buffer.\n\nNormally, this function truncates long output according to the\nvalue of the variables `eval-expression-print-length' and\n`eval-expression-print-level'.  With a prefix argument of zero,\nhowever, there is no such truncation.\nInteger values are printed in several formats (decimal, octal,\nand hexadecimal).  When the prefix argument is -1 or the value\ndoesn't exceed `eval-expression-print-maximum-character', an\ninteger value is also printed as a character of that codepoint.\n\nIf `eval-expression-debug-on-error' is non-nil, which is the default,\nthis command arranges for all errors to enter the debugger." (interactive "P") #<bytecode 0x10d732b>)(nil)
  apply(#f(compiled-function (eval-last-sexp-arg-internal) "Evaluate sexp before point; print value in the echo area.\nInteractively, with a non `-' prefix argument, print output into\ncurrent buffer.\n\nNormally, this function truncates long output according to the\nvalue of the variables `eval-expression-print-length' and\n`eval-expression-print-level'.  With a prefix argument of zero,\nhowever, there is no such truncation.\nInteger values are printed in several formats (decimal, octal,\nand hexadecimal).  When the prefix argument is -1 or the value\ndoesn't exceed `eval-expression-print-maximum-character', an\ninteger value is also printed as a character of that codepoint.\n\nIf `eval-expression-debug-on-error' is non-nil, which is the default,\nthis command arranges for all errors to enter the debugger." (interactive "P") #<bytecode 0x10d732b>) nil)
  eval-last-sexp(nil)
  funcall-interactively(eval-last-sexp nil)
  call-interactively(eval-last-sexp nil nil)
  command-execute(eval-last-sexp)

And if just (svg-lib--icon-get-data "material" "check-bold") the result is nil.

Enviroment: Windows 10 msys2 + Emacs 27.1 x64

rougier commented 3 years ago

Do the other objects work as expected?

rougier commented 3 years ago

Oh wait, may you don't have the "Roboto Mono" font installed.

chenyanming commented 3 years ago

Oh wait, may you don't have the "Roboto Mono" font installed.

No, but I used another font. The svg-lib-tag and svg-lib-progress can work, but svg-lib-button and svg-lib-icon can not. I changed to another computer to test, which is also running emacs 27.1 on msys2, but it gives me another error:

Contacting host: raw.githubusercontent.com:443
if: Opening output file: No such file or directory, c:/Users/elecm/.emacs.d/.local/etc/url/cache/elecm/https/com/githubusercontent/raw/b132dc0c589078353deb11aa7c433d05
Contacting host: raw.githubusercontent.com:443
if: Opening output file: No such file or directory, c:/Users/elecm/.emacs.d/.local/etc/url/cache/elecm/https/com/githubusercontent/raw/b132dc0c589078353deb11aa7c433d05
Contacting host: raw.githubusercontent.com:443
if: Opening output file: No such file or directory, c:/Users/elecm/.emacs.d/.local/etc/url/cache/elecm/https/com/githubusercontent/raw/e8eb3b44e0671004a5b506d47a0bfd3e
Quit
Contacting host: raw.githubusercontent.com:443
if: Opening output file: No such file or directory, c:/Users/elecm/.emacs.d/.local/etc/url/cache/elecm/https/com/githubusercontent/raw/4052ef19a4033cb1bd842df012ea7ca1
Contacting host: raw.githubusercontent.com:443
if: Opening output file: No such file or directory, c:/Users/elecm/.emacs.d/.local/etc/url/cache/elecm/https/com/githubusercontent/raw/b132dc0c589078353deb11aa7c433d05

image

I also tested on macOS, no above issues. I guess the issues are on windows specific?

rougier commented 3 years ago

Maybe. When I retrieve an icon from an online library, it is supposed to be cached locally to avoir re-downloading it again. In you case, it seems that either the cache is corrupted or the library cannot reach the host. Can you try by hand to retrieve one of the file from your windows computer? For example, the url for the gnuemacsicon is https://raw.githubusercontent.com/simple-icons/simple-icons/develop/icons/gnuemacs.svg

son1112 commented 3 years ago

I see this is closed now, but only a few days ago...

I am currently seeing the same error Wrong type argument: arrayp, nil on MacOs. I installed roboto-mono with brew and confirmed it to be installed.

For what it's worth, if I change font-family to a non-existent font, I also get the same error. But... change to Andale Mono (also installed), the error is Invalid image type 'svg'

🎸 Super awesome package btw; super excited to make use of it for a presentation at the end of this month: https://www.meetup.com/402-Developers/events/278391286/

Follow up:

I also tried another example that does not specify a font-family and also received the error Invalid image type 'svg'

(dotimes (i 10)  (insert-image (svg-lib-progress (/ (+ i 1) 10.0) nil :width 5 :margin 1 :stroke 2 :padding 2)))

trace:

Debugger entered--Lisp error: (error "Invalid image type ‘svg’")
  signal(error ("Invalid image type ‘svg’"))
  error("Invalid image type `%s'" svg)
  image-type("<svg width=\"42\" height=\"12.6\" version=\"1.1\" xmlns=..." svg t)
  create-image("<svg width=\"42\" height=\"12.6\" version=\"1.1\" xmlns=..." svg t :scale 1 :ascent center)
  apply(create-image "<svg width=\"42\" height=\"12.6\" version=\"1.1\" xmlns=..." svg t (:scale 1 :ascent center))
  svg-image((svg ((width . 42) (height . 12.6) (version . "1.1") (xmlns . "http://www.w3.org/2000/svg") (xmlns:xlink . "http://www.w3.org/1999/xlink")) (rect ((width . 35) (height . 12.6) (x . 3) (y . 0) (rx . 3) (fill . "#f4ead5"))) (rect ((width . 33) (height . 10.6) (x . 4.0) (y . 1.0) (rx . 2.0) (fill . "#110f13"))) (rect ((width . -2.5) (height . 6.6) (x . 6.0) (y . 3.0) (rx . 2.0) (fill . "#f4ead5")))) :scale 1 :ascent center)
  (let* ((default svg-lib-style-default) (style (if style (apply #'svg-lib-style nil style) default)) (style (if args (apply #'svg-lib-style style args) style)) (foreground (plist-get style :foreground)) (background (plist-get style :background)) (stroke (plist-get style :stroke)) (width (plist-get style :width)) (height (plist-get style :height)) (radius (plist-get style :radius)) (scale (plist-get style :scale)) (margin (plist-get style :margin)) (padding (plist-get style :padding)) (font-size (plist-get style :font-size)) (font-family (plist-get style :font-family)) (font-weight (plist-get style :font-weight)) (txt-char-width (window-font-width)) (txt-char-height (window-font-height)) (font-info (font-info (format "%s:%d" font-family font-size))) (ascent (aref font-info 8)) (tag-char-width (aref font-info 11)) (tag-char-height (aref font-info 3)) (tag-width (* width txt-char-width)) (tag-height (* txt-char-height height)) (svg-width (+ tag-width (* margin txt-char-width))) (svg-height tag-height) (tag-x (/ (- svg-width tag-width) 2)) (svg (svg-create svg-width svg-height))) (if (>= stroke 0.25) (svg-rectangle svg tag-x 0 tag-width tag-height :fill foreground :rx radius)) (svg-rectangle svg (+ tag-x (/ stroke 2.0)) (/ stroke 2.0) (- tag-width stroke) (- tag-height stroke) :fill background :rx (- radius (/ stroke 2.0))) (svg-rectangle svg (+ tag-x (/ stroke 2.0) padding) (+ (/ stroke 2.0) padding) (- (* value tag-width) stroke (* 2 padding)) (- tag-height stroke (* 2 padding)) :fill foreground :rx (- radius (/ stroke 2.0))) (svg-image svg :scale 1 :ascent 'center))
  svg-lib-progress(0.1 nil :width 5 :margin 1 :stroke 2 :padding 2)
  (insert-image (svg-lib-progress (/ (+ i 1) 10.0) nil :width 5 :margin 1 :stroke 2 :padding 2))
  (while (< i --dotimes-limit--) (insert-image (svg-lib-progress (/ (+ i 1) 10.0) nil :width 5 :margin 1 :stroke 2 :padding 2)) (setq i (1+ i)))
  (let ((--dotimes-limit-- 10) (i 0)) (while (< i --dotimes-limit--) (insert-image (svg-lib-progress (/ (+ i 1) 10.0) nil :width 5 :margin 1 :stroke 2 :padding 2)) (setq i (1+ i))))
  eval((let ((--dotimes-limit-- 10) (i 0)) (while (< i --dotimes-limit--) (insert-image (svg-lib-progress (/ (+ i 1) 10.0) nil :width 5 :margin 1 :stroke 2 :padding 2)) (setq i (1+ i)))) nil)
  elisp--eval-last-sexp(nil)
  #f(compiled-function (eval-last-sexp-arg-internal) "Evaluate sexp before point; print value in the echo area.\nInteractively, with a non `-' prefix argument, print output into\ncurrent buffer.\n\nNormally, this function truncates long output according to the\nvalue of the variables `eval-expression-print-length' and\n`eval-expression-print-level'.  With a prefix argument of zero,\nhowever, there is no such truncation.\nInteger values are printed in several formats (decimal, octal,\nand hexadecimal).  When the prefix argument is -1 or the value\ndoesn't exceed `eval-expression-print-maximum-character', an\ninteger value is also printed as a character of that codepoint.\n\nIf `eval-expression-debug-on-error' is non-nil, which is the default,\nthis command arranges for all errors to enter the debugger." (interactive "P") #<bytecode 0x43b9c793>)(nil)
  #f(compiled-function (&rest _it) #<bytecode 0x1fe22a9b6c7d>)()
  eval-sexp-fu-flash-doit-simple(#f(compiled-function (&rest _it) #<bytecode 0x1fe22a9b6c7d>) #f(compiled-function (&rest args2) #<bytecode 0x1fe2327cc8f1>) #f(compiled-function (&rest args2) #<bytecode 0x1fe22be74195>))
  eval-sexp-fu-flash-doit(#f(compiled-function (&rest _it) #<bytecode 0x1fe22a9b6c7d>) #f(compiled-function (&rest args2) #<bytecode 0x1fe2327cc8f1>) #f(compiled-function (&rest args2) #<bytecode 0x1fe22be74195>))
  esf-flash-doit(#f(compiled-function (&rest _it) #<bytecode 0x1fe22a9b6c7d>) #f(compiled-function (&rest args2) #<bytecode 0x1fe2327cc8f1>) #f(compiled-function (&rest args2) #<bytecode 0x1fe22be74195>) #f(compiled-function (&rest args2) #<bytecode 0x1fe22be741b5>))
  ad-Advice-eval-last-sexp(#f(compiled-function (eval-last-sexp-arg-internal) "Evaluate sexp before point; print value in the echo area.\nInteractively, with a non `-' prefix argument, print output into\ncurrent buffer.\n\nNormally, this function truncates long output according to the\nvalue of the variables `eval-expression-print-length' and\n`eval-expression-print-level'.  With a prefix argument of zero,\nhowever, there is no such truncation.\nInteger values are printed in several formats (decimal, octal,\nand hexadecimal).  When the prefix argument is -1 or the value\ndoesn't exceed `eval-expression-print-maximum-character', an\ninteger value is also printed as a character of that codepoint.\n\nIf `eval-expression-debug-on-error' is non-nil, which is the default,\nthis command arranges for all errors to enter the debugger." (interactive "P") #<bytecode 0x43b9c793>) nil)
  apply(ad-Advice-eval-last-sexp #f(compiled-function (eval-last-sexp-arg-internal) "Evaluate sexp before point; print value in the echo area.\nInteractively, with a non `-' prefix argument, print output into\ncurrent buffer.\n\nNormally, this function truncates long output according to the\nvalue of the variables `eval-expression-print-length' and\n`eval-expression-print-level'.  With a prefix argument of zero,\nhowever, there is no such truncation.\nInteger values are printed in several formats (decimal, octal,\nand hexadecimal).  When the prefix argument is -1 or the value\ndoesn't exceed `eval-expression-print-maximum-character', an\ninteger value is also printed as a character of that codepoint.\n\nIf `eval-expression-debug-on-error' is non-nil, which is the default,\nthis command arranges for all errors to enter the debugger." (interactive "P") #<bytecode 0x43b9c793>) nil)
  eval-last-sexp(nil)
  funcall-interactively(eval-last-sexp nil)
  call-interactively(eval-last-sexp nil nil)
  command-execute(eval-last-sexp)

Perhaps there is additional emacs svg support I need to add?

It looks like it may require emacs to be built with svg support. https://github.com/hlissner/doom-emacs/issues/3046

rougier commented 3 years ago

Yes, you need support for svg in order to be able to build the svg. I think emacs is usign rsvg library that is sent the svg to be transformed into an image. Maybe this would require a specific lien in the README. And of course, I don't know how to check if svg is supported from within emacs.

I hope we'll get this fixed before your talk!

son1112 commented 3 years ago

Thanks @rougier! Yeah, it looks like my current build is without svg, so I will attempt a rebuild and see if I can get this cooking!

chenyanming commented 3 years ago

Check https://emacs.stackexchange.com/questions/10908/detecting-availability-of-svg

rougier commented 3 years ago

@chenyanming Thanks. Answer is thus (image-type-available-p 'svg)