PgmCanvas

PgmCanvas — A virtual positioning class for drawables.

Synopsis


#include <pgm/pgm.h>

                    PgmCanvas;
PgmCanvas *         pgm_canvas_new                      (void);
PgmError            pgm_canvas_set_size                 (PgmCanvas *canvas,
                                                         gfloat width,
                                                         gfloat height);
PgmError            pgm_canvas_get_size                 (PgmCanvas *canvas,
                                                         gfloat *width,
                                                         gfloat *height);
PgmError            pgm_canvas_add                      (PgmCanvas *canvas,
                                                         PgmDrawableLayer layer,
                                                         PgmDrawable *drawable);
PgmError            pgm_canvas_remove                   (PgmCanvas *canvas,
                                                         PgmDrawable *drawable);
PgmError            pgm_canvas_add_many                 (PgmCanvas *canvas,
                                                         PgmDrawableLayer layer,
                                                         PgmDrawable *drawable_1,
                                                         ...);
PgmError            pgm_canvas_remove_many              (PgmCanvas *canvas,
                                                         PgmDrawable *drawable_1,
                                                         ...);
PgmError            pgm_canvas_set_order                (PgmCanvas *canvas,
                                                         PgmDrawable *drawable,
                                                         gint order);
PgmError            pgm_canvas_get_order                (PgmCanvas *canvas,
                                                         PgmDrawable *drawable,
                                                         PgmDrawableLayer *layer,
                                                         gint *order);
PgmError            pgm_canvas_get_layer_count          (PgmCanvas *canvas,
                                                         PgmDrawableLayer layer,
                                                         gint *count);
PgmError            pgm_canvas_regenerate               (PgmCanvas *canvas);
PgmError            pgm_canvas_get_pixel_formats        (PgmCanvas *canvas,
                                                         gulong *pixel_formats);
PgmError            pgm_canvas_get_pixel_offsets        (PgmCanvas *canvas,
                                                         gfloat *x,
                                                         gfloat *y);

Object Hierarchy

  GObject
   +----GstObject
         +----PgmCanvas

Signals

  "drawable-added"                                 : Run First
  "drawable-removed"                               : Run First
  "drawable-reordered"                             : Run First
  "regenerated"                                    : Run First
  "size-changed"                                   : Run First

Description

Canvas coordinates

A PgmCanvas object is used as a virtual positioning system for the PgmDrawable. It provides Pigment users (application developers using the library) a very simple and flexible way to build their user interface without having to worry about visual rendering problems such as non square pixels, aspect ratio of images or videos, keeping proportional alignment or spacing between objects when resizing, etc.

The origin of the canvas coordinate system corresponds to the upper-left corner. A canvas can only understand canvas coordinates, and those coordinates have nothing to do with pixels. This is why the methods you can call on a canvas always use coordinates with floating numbers. Let's say you want to draw a user interface with an aspect ratio of 16:9 (which is nice to do on most wide screen TV of the market). In that case you would for example set the canvas size to width 16.0 and height 9.0. Every coordinate and size of the drawables you are going to put on the canvas will use the same coordinate system. So, if you wanted to put an image in the middle of the user interface you would compute its position so that its center is at (8.0, 4.5) on the canvas. You would also define the size of that image using values of the same scale. For example, the width of the image could be 1.0 and its height 1.0 thus making appear as a square.

A canvas is never drawn directly which is why you can use abstract coordinates to place objects on it. Also, since it is using floating numbers there is no limit in precision. At some point we still need to have a visual representation of what is on the canvas, this is what PgmViewport does. A canvas can be projected on 0 to n viewport.

It is entirely the application's responsibility to decide how many drawables are going to be drawn on the canvas and their size. Using the viewport information the application can decide which aspect ratio to use and how many drawables can fit on the canvas while still being easily readable. If for example the end user (user interface user) steps away from the monitor and cannot read the text the application can just make the drawables bigger on the canvas which will automatically get reprojected onto the viewport.

When adding a drawable to a canvas you have to choose a PgmDrawableLayer in which that drawable will be stored. The three layers are used to handle a first control on the drawing order. The first layer drawn is the PGM_DRAWABLE_FAR one, all the drawables inside this layer will appear behind the two others. The second layer drawn is the PGM_DRAWABLE_MIDDLE one, the drawables inside this layer will be drawn over the PGM_DRAWABLE_FAR layer and behind the PGM_DRAWABLE_NEAR layer. The third layer drawn is the PGM_DRAWABLE_NEAR one, all the drawables inside this layer will be drawn over the two others. This is useful to make sure that dialog is shown on top of all the other objects for example or to make sure that no object is going to go behind the background. Drawables inside a layer are automatically ordered by Pigment depending on their z coordinate set through pgm_drawable_set_position(). Pigment also provides a way to reorder drawables inside a layer that have the same z coordinate thanks to the pgm_canvas_set_order() function.

When a drawable is created it has a floating reference, when you add it to the canvas, the canvas takes a reference to that drawable and sink the object reference. That means that the canvas now owns the drawable reference and you do not need to unref the drawable when cleaning up your objects. Just unrefing the canvas is going to cleanup all the drawables that were added to it. Here is an example:

Example 3. Create a canvas, add drawables, unref the canvas

PgmCanvas *canvas = pgm_canvas_new ();
PgmDrawable *drb1 = pgm_text_new ("hello world");
PgmDrawable *drb2 = pgm_image_new_from_fd (fd, 1024);
PgmDrawable *drb3 = pgm_image_new_from_image (drb2);
 
pgm_canvas_add_many (canvas, PGM_DRAWABLE_MIDDLE, drb1, drb2, drb3, NULL);
gst_object_unref (canvas); // Unref canvas, drb1, drb2 and drb3


The drawable-added signal is fired whenever a new drawable is added to the canvas. Likewise the drawable-removed signal is fired whenever an drawable is removed from the canvas. The drawable-reordered signal is fired whenever a drawable is reordered inside the canvas.

Last reviewed on 2007-08-03 (0.3.0)

Details

PgmCanvas

typedef struct {
  /* Layer lists */
  GList *far_layer;
  GList *middle_layer;
  GList *near_layer;

  /* Canvas size */
  gfloat width, height;

  /* Pixel offsets */
  gfloat pixel_offset_x, pixel_offset_y;

  /* Mask of supported formats */
  gulong pixel_formats;
} PgmCanvas;

The PgmCanvas structure.

GList *far_layer;

the list of PgmDrawable in the PGM_DRAWABLE_FAR layer.

GList *middle_layer;

the list of PgmDrawable in the PGM_DRAWABLE_MIDDLE layer.

GList *near_layer;

the list of PgmDrawable in the PGM_DRAWABLE_NEAR layer.

gfloat width;

the canvas width.

gfloat height;

the canvas height.

gfloat pixel_offset_x;

the pixel offset on x.

gfloat pixel_offset_y;

the pixel offset on y.

gulong pixel_formats;

the pixel formats mask.

pgm_canvas_new ()

PgmCanvas *         pgm_canvas_new                      (void);

Creates a new PgmCanvas instance.

MT safe.

Returns :

a new PgmCanvas instance.

pgm_canvas_set_size ()

PgmError            pgm_canvas_set_size                 (PgmCanvas *canvas,
                                                         gfloat width,
                                                         gfloat height);

Sets the width and height size of canvas. These values are not supposed to be pixels. You are strongly encouraged to use abstract coordinates such as 16.0x9.0 for a 16:9 interface or 4.0x3.0 for a 4:3 one, etc.

MT safe.

canvas :

a PgmCanvas object.

width :

the canvas width.

height :

the canvas height.

Returns :

a PgmError indicating success/failure.

pgm_canvas_get_size ()

PgmError            pgm_canvas_get_size                 (PgmCanvas *canvas,
                                                         gfloat *width,
                                                         gfloat *height);

Retrieves width and height size of canvas in width and height.

MT safe.

canvas :

a PgmCanvas object.

width :

a pointer to a gfloat where the canvas width is going to be stored.

height :

a pointer to a gfloat where the canvas height is going to be stored.

Returns :

a PgmError indicating success/failure.

pgm_canvas_add ()

PgmError            pgm_canvas_add                      (PgmCanvas *canvas,
                                                         PgmDrawableLayer layer,
                                                         PgmDrawable *drawable);

Adds drawable to canvas in layer. Both canvas and drawable reference counts will be increased by one as they are linking to each other. drawable reference will be sink as well so if the object reference was floating it now belongs to canvas and you don't have to unref drawable when cleaning up your objects.

MT safe.

canvas :

a PgmCanvas object.

layer :

a PgmDrawableLayer to add drawable into.

drawable :

the PgmDrawable object to add.

Returns :

a PgmError indicating success/failure.

pgm_canvas_remove ()

PgmError            pgm_canvas_remove                   (PgmCanvas *canvas,
                                                         PgmDrawable *drawable);

Removes drawable from canvas. Both canvas and drawable reference counts will be decreased by one as they were referencing each other. In most cases that means that drawable is going to be destroyed because canvas owned the only reference to it. If you want to reuse drawable in another canvas or in another layer you need to take a reference to it before removing it from canvas.

MT safe.

canvas :

a PgmCanvas object.

drawable :

the PgmDrawable object to remove.

Returns :

a PgmError indicating success/failure.

pgm_canvas_add_many ()

PgmError            pgm_canvas_add_many                 (PgmCanvas *canvas,
                                                         PgmDrawableLayer layer,
                                                         PgmDrawable *drawable_1,
                                                         ...);

Adds a NULL-terminated list of drawables to canvas. This function is equivalent to calling pgm_canvas_add() for each member of the list.

MT safe.

canvas :

a PgmCanvas object.

layer :

a PgmDrawableLayer to add the drawables into.

drawable_1 :

the PgmDrawable object to add.

... :

additional PgmDrawable objects to add.

Returns :

a PgmError indicating success/failure.

pgm_canvas_remove_many ()

PgmError            pgm_canvas_remove_many              (PgmCanvas *canvas,
                                                         PgmDrawable *drawable_1,
                                                         ...);

Removes a NULL-terminated list of drawables from canvas. This function is equivalent to calling pgm_canvas_remove() for each member of the list.

MT safe.

canvas :

a PgmCanvas object.

drawable_1 :

the PgmDrawable object to remove.

... :

additional PgmDrawable objects to remove.

Returns :

a PgmError indicating success/failure.

pgm_canvas_set_order ()

PgmError            pgm_canvas_set_order                (PgmCanvas *canvas,
                                                         PgmDrawable *drawable,
                                                         gint order);

Defines the ordering of drawable in its layer at position order. Since drawables are ordered function of their z coordinate, set through pgm_drawable_set_position(), this function is only useful if you want to reorder drawables at the same z coordinate. If you try to reorder a drawable inside a layer at an order where the current drawable doesn't have the same z coordinate, the function will do nothing and return an error.

MT safe.

canvas :

a PgmCanvas object.

drawable :

the PgmDrawable to reorder.

order :

the new position of drawable.

Returns :

a PgmError indicating success/failure.

pgm_canvas_get_order ()

PgmError            pgm_canvas_get_order                (PgmCanvas *canvas,
                                                         PgmDrawable *drawable,
                                                         PgmDrawableLayer *layer,
                                                         gint *order);

Retrieves the layering of drawable.

MT safe.

canvas :

a PgmCanvas object.

drawable :

the PgmDrawable to retrieve the layering.

layer :

a pointer to a PgmDrawableLayer in which drawable layer is going to be stored.

order :

a pointer to a gint in which the position of drawable in the layer is going to be stored.

Returns :

a PgmError indicating success/failure.

pgm_canvas_get_layer_count ()

PgmError            pgm_canvas_get_layer_count          (PgmCanvas *canvas,
                                                         PgmDrawableLayer layer,
                                                         gint *count);

Retrieves the number of drawables in layer.

MT safe.

canvas :

a PgmCanvas object.

layer :

the PgmDrawableLayer to retrieve the size.

count :

a pointer to a gint in which the number of drawables in layer is going to be stored.

Returns :

a PgmError indicating success/failure.

pgm_canvas_regenerate ()

PgmError            pgm_canvas_regenerate               (PgmCanvas *canvas);

Affects all the drawables of the canvas which need to be displayed at a fixed size. It regenerates those rasterized pixmaps which have been affected by the canvas projection.

MT safe.

canvas :

a PgmCanvas object.

Returns :

a PgmError indicating success/failure.

pgm_canvas_get_pixel_formats ()

PgmError            pgm_canvas_get_pixel_formats        (PgmCanvas *canvas,
                                                         gulong *pixel_formats);

Gets the list of the supported pixel formats by canvas. This is the intersection of the pixel formats supported by the viewports to which canvas is bound.

MT safe.

canvas :

a PgmCanvas object.

pixel_formats :

a pointer to a gulong where the mask of supported PgmImagePixelFormat is going to be stored.

Returns :

a PgmError indicating success/failure.

pgm_canvas_get_pixel_offsets ()

PgmError            pgm_canvas_get_pixel_offsets        (PgmCanvas *canvas,
                                                         gfloat *x,
                                                         gfloat *y);

Gets the x and y ratios corresponding to the offsets in canvas coordinates between two pixels at z=0.

canvas :

a PgmCanvas object.

x :

a pointer to a gfloat where the x pixel offset is going to be stored.

y :

a pointer to a gfloat where the y pixel offset is going to be stored.

Returns :

a PgmError indicating success/failure.

Signal Details

The "drawable-added" signal

void                user_function                      (PgmCanvas       *canvas,
                                                        PgmDrawable     *drawable,
                                                        PgmDrawableLayer layer,
                                                        gint             order,
                                                        gpointer         user_data)      : Run First

Will be emitted after drawable was added to canvas.

canvas :

the PgmCanvas

drawable :

the PgmDrawable that was added to canvas

layer :

the PgmDrawableLayer in which drawable was added

order :

the order in layer in which drawable was added

user_data :

user data set when the signal handler was connected.

The "drawable-removed" signal

void                user_function                      (PgmCanvas       *canvas,
                                                        PgmDrawable     *drawable,
                                                        PgmDrawableLayer layer,
                                                        gpointer         user_data)      : Run First

Will be emitted after drawable was removed from canvas.

canvas :

the PgmCanvas

drawable :

the PgmDrawable that was removed from canvas

layer :

the PgmDrawableLayer from which drawable was removed

user_data :

user data set when the signal handler was connected.

The "drawable-reordered" signal

void                user_function                      (PgmCanvas       *canvas,
                                                        PgmDrawable     *drawable,
                                                        PgmDrawableLayer layer,
                                                        gint             order,
                                                        gpointer         user_data)      : Run First

Will be emitted after drawable was reordered in canvas.

canvas :

the PgmCanvas

drawable :

the PgmDrawable that was reordered in canvas

layer :

the PgmDrawableLayer in which drawable was reordered

order :

the new order of drawable

user_data :

user data set when the signal handler was connected.

The "regenerated" signal

void                user_function                      (PgmCanvas *canvas,
                                                        gpointer   user_data)      : Run First

Will be emitted after canvas received a regeneration request.

canvas :

the PgmCanvas

user_data :

user data set when the signal handler was connected.

The "size-changed" signal

void                user_function                      (PgmCanvas *canvas,
                                                        gpointer   user_data)      : Run First

Will be emitted after canvas size was changed.

canvas :

the PgmCanvas

user_data :

user data set when the signal handler was connected.

See Also

#PgmViewport, PgmDrawable.