PmMemCreateMC()

Create a memory context

Synopsis:

#include <photon/PhRender.h>

PmMemoryContext_t * PmMemCreateMC(
                        PhImage_t *mc_image,
                        PhDim_t *dim,
                        PhPoint_t *translation );

Library:

ph

Description:

This function creates a memory context. A memory context is used to draw into a local memory image buffer. You must create a memory context before calling any other Photon Memory (Pm) functions. The memory context provides definition, control, and access to the memory image.

The parameters for this function are:

mc_image
The resulting image's type and dimensions. For more information, see below.
dim
A PhDim_t structure that defines the source size of the draw stream. If the image dimension is different from the source dimension, any drawing done to the memory context will be scaled as necessary to fit the source dimension exactly into the image dimension.
translation
A PhPoint_t structure that defines the amount by which the draw stream is translated when being rendered into the memory image buffer.

If the image member of the PhImage_t structure pointed to by mc_image (i.e. mc_image->image) is NULL, PmMemCreateMC() uses calloc() to allocate its own buffer. In this case, PmMemReleaseMC() frees the allocated image buffer.

If mc_image->image isn't NULL, PmMemCreateMC() uses it instead of allocating its own buffer. The size of the buffer depends on the type and dimensions specified for mc_image. In this case, PmMemReleaseMC() doesn't free the buffer.


Note: If you want the image to be in shared memory, allocate the shared space for the image data, instead of letting PmMemCreateMC() do it.

The mc_image->type member indicates the type of image that's generated. The type must be one of:

If the type member is Pg_IMAGE_PALETTE_BYTE or Pg_IMAGE_PALETTE_NIBBLE, the palette member is used to define the palette. If the palette member is NULL, the default palette is used.

The image member of the PhImage_t structure filled in by PmMemFlush() is a pointer to the mc_image->image buffer.

Returns:

A pointer to the new memory context, or NULL if there isn't enough memory to allocate one.

Examples:

/* pmmemtobutton.c

This demonstrates how to draw into an image.  This example
uses the PmMem*() functions to draw into a memory context.
When finished drawing, the memory context is then dumped
into an image. The image is then used as the image
displayed on a button.

To compile, you must link with the phrender library.
For example:

qcc -w3 -opmmemtobutton -lphrender -lph pmmemtobutton.c

*/

#include <stdlib.h>
#include <mem.h>
#include <photon/PhRender.h>
#include <Pt.h>

void
create_image( PhImage_t *image, PhDim_t *dim )
{
    PhPoint_t           translation = { 0, 0 }, center, radii;
    PmMemoryContext_t   *mc;

    mc = PmMemCreateMC( image, dim, &translation );

    PmMemStart( mc );
    // now all drawing goes into the memory context

    // draw whatever we want to appear in the image
    center.x = dim->w / 2;
    center.y = dim->h / 2;
    radii = center;
    PgSetFillColor( Pg_WHITE );
    PgSetStrokeColor( Pg_RED );
    PgDrawEllipse( &center, &radii, Pg_DRAW_FILL_STROKE );
    PgSetStrokeColor( Pg_GREEN );
    PgDrawILine( 0, 0, dim->w-1, dim->h-1 );

    PmMemFlush( mc, image ); // get the image
    PmMemStop( mc );
    // now all drawing goes to the default drawing context

    PmMemReleaseMC( mc );
}

int main( int argc, char *argv[] )
{
    PhArea_t    area = { {80, 20}, {80, 40} };
    PhDim_t     dim = { 240, 80 };
    PhImage_t   image;
    PtArg_t     args[3];
    PtWidget_t  *button, *window;
    short       bytes_per_pixel = 3;

    if (PtInit(NULL) == -1)
      exit(EXIT_FAILURE);

    PtSetArg( &args[0], Pt_ARG_WINDOW_TITLE,
              "Memory Context Sample", 0 );
    PtSetArg( &args[1], Pt_ARG_DIM, &dim, 0 );
    if ((window = PtCreateWidget(PtWindow, Pt_NO_PARENT,
                                 2, args)) == NULL)
      PtExit(EXIT_FAILURE);

  memset( &image, 0, sizeof(PhImage_t) );
  image.type = Pg_IMAGE_DIRECT_888; // 3 bytes per pixel
                                          // with this type

    // If we want the image to be in shared memory, we must
    // allocate the shared space for the image data, instead
    // of letting PmMemCreateMC() do it.

  image.size = dim;
  image.image = PgShmemCreate(
                      dim.w * dim.h * bytes_per_pixel,
                      NULL );

    create_image( &image, &area.size );

    PtSetArg( &args[0], Pt_ARG_LABEL_TYPE, Pt_IMAGE, 0 );
    PtSetArg( &args[1], Pt_ARG_AREA, &area, 0 );
    PtSetArg( &args[2], Pt_ARG_LABEL_IMAGE, &image, 0 );
    button = PtCreateWidget( PtButton, Pt_DEFAULT_PARENT,
                             3, args );

    PtRealizeWidget( window );
    PtMainLoop();

    // Shared memory for the image is cleaned up by an
    // internal function that's called when the program
    // exits.

    return (EXIT_SUCCESS);
}

Classification:

Photon

Safety:
Interrupt handler No
Signal handler No
Thread No

See also:

PgShmemCreate(), PgShmemDestroy(), PhDim_t, PhImage_t, PhPoint_t, PmMemFlush(), PmMemReleaseMC()

Flickerless animation in the Raw Drawing and Animation chapter of the Photon Programmer's Guide