12.6 Pixmaps

A pixmap can be thought of as an "off-screen window", that is, a medium that can be used for graphical output, but is not visible on any display device. Pixmaps are provided to allow a programmer to generate a piece of output associated with some display device that can then be rapidly drawn on a real display device. For example, an electrical CAD system might generate a pixmap that corresponds to a complex, frequently used part in a VLSI schematic, and then use copy-from-pixmap to draw the part as needed. [annotate]

The exact representation of a pixmap is explicitly unspecified. There is no interaction between the pixmap operations and output recording, that is, displaying a pixmap on a sheet or medium is a pure drawing operation that affects only the display, not the output history. Some mediums may not support pixmaps; in this case, an error will be signalled. [annotate]

allocate-pixmap  medium width height [Generic Function]
          

Allocates and returns a pixmap object that can be used on any medium that shares the same characteristics as medium. (The exact definition of "shared characteristics" will vary from host to host.) medium can be a medium, a sheet, or a stream. [annotate]

The resulting pixmap will be at least width units wide, height units high, and as deep as is necessary to store the information for the medium. The exact representation of pixmaps is explicitly unspecified. [annotate]

The returned value is the pixmap. [annotate]

[annotate]

Note: To play nice with general designs, we should specify that pixmaps are initially filled with transparent black. [edit]-- Gilbert Baumann 2005-03-06 23:39Z
 
Note:

We might want to be able to specify whether the pixmap has a color channel, an alpha channel, or just a one-bit alpha channel.

Cairo e.g. has a `content' argument to `cairo_surface_create_similar' specifying which channels you want.

[edit]-- Gilbert Baumann 2023-04-22 19:48Z
 

deallocate-pixmap  pixmap [Generic Function]
          

Deallocates the pixmap pixmap. [annotate]

[annotate]

Note: I think it ought to be specified that a pixmap object which becomes garbage will eventually be deallocated, for the sake of recovering from unexpected failures/bugs and for throwaway programs. If not specifically that, then the spec still ought to say how the presence of this this explicit deallocation interacts with GC. [edit]-- Kevin Reid 2009-05-10 14:08Z
 
Note:

@Kevin:

A pixmap is an external resource. This is the reason, why the programmer must explicitly deallocate it. Although it might be possible in some Common Lisp implementations to use weak pointers to detect, that a pixmap became garbage -- which in the case of the X11 protocol is not all too trivial -- I do not believe any programmer should rely on that, nor should that be part of a CLIM specification.

[edit]-- Gilbert Baumann 2009-05-13 18:51Z
 

pixmap-width  pixmap [Generic Function]
pixmap-height  pixmap [Generic Function]
pixmap-depth  pixmap [Generic Function]
          

These functions return, respectively, the width, height, and depth of the pixmap pixmap. These values may be different from the programmer-specified values, since some window systems need to allocate pixmaps only of particular sizes. [annotate]

[annotate]

Note: /depth/ wasn't intially specified by the programmer, so I wonder what significance it would have. [edit]-- Gilbert Baumann 2005-03-06 23:41Z
 

copy-to-pixmap  medium medium-x medium-y width height &optional pixmap (pixmap-x 0) (pixmap-y 0) [Function]
          

Copies the pixels from the medium medium starting at the position specified by (medium-x,medium-y) into the pixmap pixmap at the position specified by (pixmap-x,pixmap-y). A rectangle whose width and height is specified by width and height is copied. medium-x and medium-y are specified in user coordinates. (If medium is a medium or a stream, then medium-x and medium-y are transformed by the user transformation.) The copying must be done by medium-copy-copy. [annotate]

Note: There is no medium-copy-copy but medium-copy-area [edit]-- Gilbert Baumann 2005-03-06 20:03Z
 

If pixmap is not supplied, a new pixmap will be allocated. Otherwise, pixmap must be an object returned by allocate-pixmap that has the appropriate characteristics for medium. [annotate]

The returned value is the pixmap. [annotate]

[annotate]

copy-from-pixmap  pixmap pixmap-x pixmap-y width height medium medium-x medium-y [Function]
          

Copies the pixels from the pixmap pixmap starting at the position specified by (pixmap-x,pixmap-y) into the medium medium at the position (medium-x,medium-y). A rectangle whose width and height is specified by width and height is copied. medium-x and medium-y are specified in user coordinates. (If medium is a medium or a stream, then medium-x and medium-y are transformed by the user transformation.) The copying must be done by medium-copy-copy. [annotate]

Note: There is no medium-copy-copy but medium-copy-area [edit]-- Gilbert Baumann 2005-03-06 20:03Z
 

pixmap must be an object returned by allocate-pixmap that has the appropriate characteristics for medium. [annotate]

The returned value is the pixmap. [annotate]

[annotate]

copy-area  medium from-x from-y width height to-x to-y [Generic Function]
          

Copies the pixels from the medium medium starting at the position specified by (from-x,from-y) to the position (to-x,to-y) on the same medium. A rectangle whose width and height is specified by width and height is copied. from-x, from-y, to-x, and to-y are specified in user coordinates. (If medium is a medium or a stream, then the x and y values are transformed by the user transformation.) The copying must be done by medium-copy-copy. [annotate]

Note: Again, there is no medium-copy-copy but medium-copy-area [edit]-- Gilbert Baumann 2005-03-06 20:05Z
 

[annotate]

medium-copy-area  from-drawable from-x from-y width height to-drawable to-x to-y [Generic Function]
          

Copies the pixels from the source drawable from-drawable at the position (from-x,from-y) to the destination drawable to-drawable at the position (to-x,to-y). A rectangle whose width and height is specified by width and height is copied. from-x, from-y, to-x, and to-y are specified in user coordinates. The x and y are transformed by the user transformation. [annotate]

Note: It says "The x and y are transformed [...]". If really so, shouldn't we transform /width/ and /height/ also? And then if we would make it so: Are /width/ and /height/ transformed according to /from-drawable/ or according to /to-drawable/? Hence, if you ask me: The signature is broken. [edit]-- Gilbert Baumann 2005-03-06 23:44Z
 

This is intended to specialize on both the from-drawable and to-drawable arguments. from-drawable and to-drawable may be either mediums or pixmaps. [annotate]

[annotate]

with-output-to-pixmap  (medium-var medium &key width height) &body body [Macro]
          

Binds medium-var to a "pixmap medium", that is, a medium that does output to a pixmap with the characteristics appropriate to the medium medium, and then evaluates body in that context. All the output done to the medium designated by medium-var inside of body is drawn on the pixmap stream. The pixmap medium must support the medium output protocol, including all of the graphics function. CLIM implementations are permitted, but not required, to have pixmap mediums support the stream output protocol (write-char and write-string). [annotate]

width and height are integers that give the width and height of the pixmap. If they are unsupplied, the result pixmap will be large enough to contain all of the output done by body. [annotate]

Note:

Hmm, what about

(with-output-to-pixmap (m m) (draw-line* -100 -100 -200 -200))

The spec says /large enough to contain _all_ of the output/. In the above case output is at negative coordinates. So the question is: Can we have such pixmaps? Is that intended? Should the output be moved so that output becomes visible? I doubt the latter.

-- Gilbert Baumann 2018-03-24 21:02Z

@Gilbert

I do not see an issue here- I suppose for completeness it would be nice to store a pixmap-origin-x and pixmap-origin-y to note this offset, which could be then utilized by copy-from-pixmap to offset said pixmap. After all (0,0) merely indicates the *origin*.

[edit]-- Matt 2020-01-30 19:23Z
 
Note: Not so fast -- pixmap is an off-screen mirror, who said that it is a class with arbitrary slots? You /could/ store the origin in a hash table, but that'd be yuck. [edit]-- DK 2020-11-13 15:22Z
 
Note:

@DK

Who says that CLIM objects cannot have slots? And a CLIM pixmap is not the very same object as the potentional mirror used for implementing it in the same way as a sheet is not an XLIB:WINDOW.

In fact, under the hood with FreeCLIM, each pixmap medium has a device transformation and device-region just like sheets have.

As you cannot get at the pixel array of a pixmap, there is no reason why CLIM cannot do that. And with vector media like PostScript, PDF, or SVG, there even is no pixel array at all and a pixmap might as well be a display list.

Further, to be clear, CLIM does not speak about physical pixels anywhere. It is perfectly fine if the coordinates do not address physical pixels. Which is something you cannot do with vector-oriented media anyway.

In this regard it would be perfectly fine for copy-from-pixmap to accept negative pixmap-x and pixmap-y arguments.

I believe that it would be better if pixmaps would mirror sheets here. One could view pixmaps as off-screen sheets with the output protocol only.

[edit]-- Gilbert Baumann 2022-07-23 13:45Z
 
Note:

Back to the original issue.

It is said the pixmap should be /large enough to contain _all_ of the output/.

When we don't allow for pixmaps having negative coordinates, this will have the effect that this could only be accomplished by shifting the output so that coordinates turn out positive. I do not like that.

I would rather like that

(copy-from-pixmap
  (with-output-to-pixmap (medium medium)
    (... some drawing to medium ...))
  x1 y1 (- x2 x1) (- y2 y1)
  medium
  x2 y2)

has the same effect as

(with-translation (medium x2 y2)
  (with-drawing-options (medium :clipping-region (make-rectangle* x1 y1 x2 y2))
    (... same drawing to medium ...)))

[edit]-- Gilbert Baumann 2022-07-23 14:02Z
 

medium-var must be a symbol; it is not evaluated. [annotate]

The returned value is a pixmap that can be drawn onto medium using copy-from-pixmap. [annotate]

[annotate]

Note: What is the background of the pixmap? As we now have pixmaps with an alpha channel or mask, I would prefer transparent black. See also allocate-pixmap. [edit]-- Gilbert Baumann 2018-03-24 21:05Z