FYI,
I'm adding some examples to the lispref documentation, on how to
display graphics in a buffer. Here is my current draft. Before I
submit patches, I'd like to get some comments.
[ Although the following is a formatted info node, I am doing all of the
changes in texinfo. ]
--
Darryl Okahata
darrylo(a)soco.agilent.com
DISCLAIMER: this message is the author's personal opinion and does not
constitute the support, opinion, or policy of Agilent Technologies, or
of the little green men that have been following him all day.
===============================================================================
File: lispref.info, Node: Glyph Examples, Prev: Subwindows, Up: Glyphs
Glyph Examples
==============
For many applications, displaying graphics is a simple process: you
create a glyph, and then you insert it into the 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. *Note
Image Specifiers::, for more information.
*Caution*: In order for XEmacs to read a particular graphics file
format, support for that format must have been compiled into
XEmacs. It's possible, although somewhat unlikely, for XEmacs to
have been compiled without support for any of the various graphics
file formats. To see what graphics formats your particular
version of XEmacs supports, use `M-x describe-installation'.
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).
;; 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:
* Glyphs are displayed by attaching them to extents (see *Note
Extents::), either to the beginning or the end of extents.
* Glyphs are often displayed inside the text area (alongside text).
This is the default.
Although glyphs can also be displayed in the margins, how to do
this will not be described here. For more information on this, see
*Note Annotation Basics:: (look for information on "layout types")
and *Note Extent Properties:: (look for `begin-glyph-layout' and
`end-glyph-layout').
* The easiest way to insert a glyph into text is to create a
zero-length extent at the point where you want the glyph to appear.
* It's often a good idea to assign a unique property to the
newly-created extent, in case you later want to locate it, and
replace any existing glyph with a different one (or just delete
the existing one). In the above example, we are using "myimage"
as our unique property name.
* Glyphs are displayed by assigning then to the `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).
* If you happen to insert two glyphs, side-by-side, note that the
example `insert-glyph' function will have trouble, if it's again
used at the same point (it can only locate one of the two
extents). 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. *Note Mapping
Over Extents::, for more information.
* Among other things, glyphs provide a way of displaying graphics
alongside text. Note, however, that glyphs only provide a way of
displaying graphics; glyphs are not actually part of the text, and
are only displayed alongside the text. The low-level glyph code
does not provide a way of saving graphics with the text. If you
need to save graphics and text, you have to write your own code to
do this, and this topic is outside the scope of this discussion.