Previous: Manipulating Glyphs, Up: Glyphs [Contents][Index]
For many applications, displaying graphics is a simple process: you create a glyph, and then you insert it into a buffer.
The easiest way to create a glyph is to use a file that contains a graphical image, such as a JPEG, TIFF, or PNG file:
;; Create a glyph from a JPEG file: (setq foo (make-glyph [jpeg :file "/tmp/file1.jpg"]))
;; Create a glyph from a XPM file: (setq foo (make-glyph [xpm :file "/tmp/file2.xpm"]))
;; Create a glyph from a PNG file: (setq foo (make-glyph [png :file "/tmp/file3.png"]))
;; Create a glyph from a TIFF file: (setq foo (make-glyph [tiff :file "/tmp/file4.tiff"]))
The parameters passed to make-glyph
are called "Image
Specifiers", and can handle more image types than those shown above.
You can also put the raw image data into a string (e.g., if you put the
contents of a JPEG file into a string), and use that to create a glyph.
See Image Specifiers, for more information.
Caution: In order for SXEmacs to read a particular graphics file format, support for that format must have been compiled into SXEmacs. It’s possible, although somewhat unlikely, for SXEmacs to have been compiled without support for any of the various graphics file formats. To see what graphics formats your particular version of SXEmacs supports, use M-x describe-installation.
To programmatically query whether or not a particular file format is supported, you can use the
featurep
function, with one of:gif
,tiff
,jpeg
,xpm
,xbm
,png
, orxface
. For an up-to-date list, Image Specifiers. Example:;; Returns `t' if TIFF is supported: (featurep 'tiff)Another example is:
;; Returns a list of `t' or `nil', depending on whether or not the ;; corresponding feature is supported: (mapcar #'(lambda (format-symbol) (featurep format-symbol)) '(gif tiff jpeg xpm png))
Once you have a glyph, you can then insert it into a buffer. Example:
;; Use this function to insert a glyph at the left edge of point in the ;; current buffer. Any existing glyph at this location is replaced. (defun insert-glyph (gl) "Insert a glyph at the left edge of point." (let ( (prop 'myimage) ;; myimage is an arbitrary name, chosen ;; to (hopefully) not conflict with any ;; other properties. Change it if ;; necessary. extent ) ;; First, check to see if one of our extents already exists at ;; point. For ease-of-programming, we are creating and using our ;; own extents (multiple extents are allowed to exist/overlap at the ;; same point, and it's quite possible for other applications to ;; embed extents in the current buffer without your knowledge). ;; Basically, if an extent, with the property stored in "prop", ;; exists at point, we assume that it is one of ours, and we re-use ;; it (this is why it is important for the property stored in "prop" ;; to be unique, and only used by us). (if (not (setq extent (extent-at (point) (current-buffer) prop))) (progn ;; If an extent does not already exist, create a zero-length ;; extent, and give it our special property. (setq extent (make-extent (point) (point) (current-buffer))) (set-extent-property extent prop t) )) ;; Display the glyph by storing it as the extent's "begin-glyph". (set-extent-property extent 'begin-glyph gl) )) ;; You can then use this function like: (insert-glyph (make-glyph [jpeg :file "/tmp/file1.jpg"])) ;; This will insert the glyph at point. ;; Here's an example of how to insert two glyphs side-by-side, at point ;; (using the above code): (progn (insert-glyph (make-glyph [jpeg :file "/tmp/file1.jpg"])) ;; Create a new extent at point. We can't simply call "insert-glyph", ;; as "insert-glyph" will simply replace the first glyph with the ;; second. (setq extent (make-extent (point) (point) (current-buffer))) ;; Here, we're only setting the 'myimage property in case we need ;; to later identify/locate/reuse this particular extent. (set-extent-property extent 'myimage t) (set-extent-property extent 'begin-glyph (make-glyph [jpeg :file "/tmp/file2.jpg"])) )
Here are the gory details:
Note that extents can be used for many things, and not just for displaying images (although, in the above example, we are creating our own extent for the sole purpose of displaying an image). Also, note that multiple extents are allowed to exist at the same position, and they can overlap.
Although glyphs can also be displayed in the margins, how to do this
will not be described here. For more information on this, see
Annotation Basics (look for information on "layout types") and
Extent Properties (look for begin-glyph-layout
and
end-glyph-layout
).
Note that zero-length extents are attached to the character to the right of the extent; deleting this character will also delete the extent.
If you need to locate all of the extents, you’ll have to use functions
like extent-list
or next-extent
, or provide additional
parameters to the extent-at
function. Assigning a unique
property to the extent makes it easy to locate your extents; for
example, extent-list
can return only those extents with a
particular property. See Finding Extents, and Mapping Over Extents, for more information.
begin-glyph
or
end-glyph
property of the extent. For zero-length extents, it
doesn’t really matter if you assign the glyph to the begin-glyph
or end-glyph
property, as they are both at the same location;
however, for non-zero-length extents (extents that cover one or more
characters of text), it does matter which one you use.
Assigning nil
to the begin-glyph
or end-glyph
property will delete any existing glyph. In this case, you may also
want to delete the extent, assuming that the extent is used for no other
purpose.
insert-glyph
function will have trouble, if it’s again used at
the same point (it can only locate one of the two extents).
See Finding Extents, and Mapping Over Extents, for more
information on locating extents in a buffer.
Previous: Manipulating Glyphs, Up: Glyphs [Contents][Index]