summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--doc/lispref/display.texi22
-rw-r--r--lisp/svg.el42
2 files changed, 53 insertions, 11 deletions
diff --git a/doc/lispref/display.texi b/doc/lispref/display.texi
index 575cad89f83..b7a6b570eb0 100644
--- a/doc/lispref/display.texi
+++ b/doc/lispref/display.texi
@@ -5350,6 +5350,24 @@ that describe the outer circumference of the polygon.
@end lisp
@end defun
+@defun svg-text svg text &rest args
+Add a text to @var{svg}.
+
+@lisp
+(svg-text
+ svg "This is a text"
+ :font-size "40"
+ :font-weight "bold"
+ :stroke "black"
+ :fill "white"
+ :font-family "impact"
+ :letter-spacing "4pt"
+ :x 300
+ :y 400
+ :stroke-width 1)
+@end lisp
+@end defun
+
@defun svg-embed svg image image-type datap &rest args
Add an embedded (raster) image to @var{svg}. If @var{datap} is
@code{nil}, @var{IMAGE} should be a file name; if not, it should be a
@@ -5363,6 +5381,10 @@ binary string containing the image data. @var{image-type} should be a
@end lisp
@end defun
+@defun svg-remove svg id
+Remove the element with identifier @code{id} from the @code{svg}.
+@end defun
+
Finally, the @code{svg-image} takes an SVG object as its parameter and
returns an image object suitable for use in functions like
@code{insert-image}. Here's a complete example that creates and
diff --git a/lisp/svg.el b/lisp/svg.el
index c33b0923c26..a92c6dfb610 100644
--- a/lisp/svg.el
+++ b/lisp/svg.el
@@ -27,6 +27,7 @@
(require 'cl-lib)
(require 'xml)
(require 'dom)
+(require 'subr-x)
(defun svg-create (width height &rest args)
"Create a new, empty SVG image with dimensions WIDTHxHEIGHT.
@@ -149,13 +150,22 @@ otherwise. IMAGE-TYPE should be a MIME image type, like
`((xlink:href . ,(svg--image-data image image-type datap))
,@(svg--arguments svg args)))))
+(defun svg-text (svg text &rest args)
+ "Add TEXT to SVG."
+ (svg--append
+ svg
+ (dom-node
+ 'text
+ `(,@(svg--arguments svg args))
+ text)))
+
(defun svg--append (svg node)
(let ((old (and (dom-attr node 'id)
(dom-by-id svg
(concat "\\`" (regexp-quote (dom-attr node 'id))
"\\'")))))
(if old
- (dom-set-attributes old (dom-attributes node))
+ (setcdr (car old) (cdr node))
(dom-append-child svg node)))
(svg-possibly-update-image svg))
@@ -237,16 +247,26 @@ If the SVG is later changed, the image will also be updated."
(defun svg-print (dom)
"Convert DOM into a string containing the xml representation."
- (insert (format "<%s" (car dom)))
- (dolist (attr (nth 1 dom))
- ;; Ignore attributes that start with a colon.
- (unless (= (aref (format "%s" (car attr)) 0) ?:)
- (insert (format " %s=\"%s\"" (car attr) (cdr attr)))))
- (insert ">")
- (dolist (elem (nthcdr 2 dom))
- (insert " ")
- (svg-print elem))
- (insert (format "</%s>" (car dom))))
+ (if (stringp dom)
+ (insert dom)
+ (insert (format "<%s" (car dom)))
+ (dolist (attr (nth 1 dom))
+ ;; Ignore attributes that start with a colon.
+ (unless (= (aref (format "%s" (car attr)) 0) ?:)
+ (insert (format " %s=\"%s\"" (car attr) (cdr attr)))))
+ (insert ">")
+ (dolist (elem (nthcdr 2 dom))
+ (insert " ")
+ (svg-print elem))
+ (insert (format "</%s>" (car dom)))))
+
+(defun svg-remove (svg id)
+ "Remove the element identified by ID from SVG."
+ (when-let ((node (car (dom-by-id
+ svg
+ (concat "\\`" (regexp-quote id)
+ "\\'")))))
+ (dom-remove-node svg node)))
(provide 'svg)