Author: miguel
Date: 2007-06-02 18:51:48 -0400 (Sat, 02 Jun 2007)
New Revision: 78482

Modified:
   trunk/moon/README
   trunk/moon/src/ChangeLog
   trunk/moon/src/demo.cpp
   trunk/moon/src/ffvideo.cpp
   trunk/moon/src/runtime.cpp
   trunk/moon/src/runtime.h
   trunk/moon/src/shape.cpp
Log:
2007-06-02  Miguel de Icaza  <[EMAIL PROTECTED]>

        Implement support for the render origin.
        
        * runtime.cpp (item_invalidate): add one to cope with the rouding
        from floats to ints (fixes some trailing junk).

        Item: redo the affine transformation setup to support both the
        render_transform_origin property and avoid recomputing all of this
        on each repaint request.



Modified: trunk/moon/README
===================================================================
--- trunk/moon/README   2007-06-02 22:30:41 UTC (rev 78481)
+++ trunk/moon/README   2007-06-02 22:51:48 UTC (rev 78482)
@@ -47,16 +47,10 @@
        items contain a bounding box (double x1, y1, x2, y2) which must
        be updated when the virtual method ->getbounds is called.
 
-       In addition each item can contain an affine transformation, the 
-       affine transformation is relative.  This means that the affine
-       is relative to the parent.  
-
-       I chose relative vs absolute for the items as changing an affine
-       in the managed world for a parent would have to change all the
-       affines for all the children contained.  With this approach,
-       we can change the affine for a parent, and all the children
-       will get the new affine transformation.
-
+       In addition each item can contain an affine transformation,
+       the code tracks the user set values as well as an absolute
+       affine transformation.
+       
        The encoding of the affine transformation is done with a
        "double *" which, if not-NULL should point to six doubles in 
        the format expected by cairo_matrix_t (and libart).
@@ -65,23 +59,6 @@
        this appers like that in the source code.  This was done in
        case we want to switch to AGG.
 
-       A method to obtain the actual affine that applies to this object is:
-
-       double  *item_get_affine    (double *container, double *affine, double 
*result);
-
-       The "container" should be the affine passed by the parent, the "affine" 
is the
-       item affine (either one can be null) and the compound affine transform 
is
-       left in "result".
-
-       The "result" has to be allocated by the parent, if both container and 
affine
-       are null, the NULL value is returned from item_get_affine, so a common
-       code pattern used is:
-
-       double actual [6];
-       double *use_affine = item_get_affine (affine, item->xform, actual);
-
-       And then `use_affine' is used. 
-
 * Class Hierarchy
 
        I tried to simplify the class hierarchy from the one found in:

Modified: trunk/moon/src/ChangeLog
===================================================================
--- trunk/moon/src/ChangeLog    2007-06-02 22:30:41 UTC (rev 78481)
+++ trunk/moon/src/ChangeLog    2007-06-02 22:51:48 UTC (rev 78482)
@@ -1,5 +1,14 @@
 2007-06-02  Miguel de Icaza  <[EMAIL PROTECTED]>
 
+       Implement support for the render origin.
+       
+       * runtime.cpp (item_invalidate): add one to cope with the rouding
+       from floats to ints (fixes some trailing junk).
+
+       Item: redo the affine transformation setup to support both the
+       render_transform_origin property and avoid recomputing all of this
+       on each repaint request.
+
        * ffvideo.cpp: Changed the code to do the actual video decoding on
        the main thread so we can put all the video and audio in the
        queues before we start rendering.

Modified: trunk/moon/src/demo.cpp
===================================================================
--- trunk/moon/src/demo.cpp     2007-06-02 22:30:41 UTC (rev 78481)
+++ trunk/moon/src/demo.cpp     2007-06-02 22:51:48 UTC (rev 78482)
@@ -12,7 +12,7 @@
 static Rectangle *r;
 
 static gboolean
-repaint (gpointer data)
+animate (gpointer data)
 {
        static double degree = 0;
        static double degree2 = 0;
@@ -23,11 +23,11 @@
        degree += 0.01;
 
        if (v != NULL)
-               item_transform_set (v, (double *) trans);
+               item_set_transform (v, (double *) trans);
 
        cairo_matrix_init_rotate ((cairo_matrix_t *)&trans2, degree2);
        degree2 -= 0.1;
-       item_transform_set (r, (double *) trans2);
+       item_set_transform (r, (double *) trans2);
 
        return TRUE;
 }
@@ -35,45 +35,41 @@
 int
 main (int argc, char *argv [])
 {
-       GtkWidget *w, *box, *button;
+       GtkWidget *w, *w2, *box, *button;
        cairo_matrix_t trans;
 
        gtk_init (&argc, &argv);
        g_thread_init (NULL);
        gdk_threads_init ();
        
+
        w = gtk_window_new (GTK_WINDOW_TOPLEVEL);
 
-       box = gtk_hbox_new (FALSE, 0);
-       button = gtk_button_new_with_label ("dingus");
-       gtk_container_add (GTK_CONTAINER (box), button);
-       gtk_widget_show_all (box);
-       //gtk_container_add (GTK_CONTAINER (w), box);
-
        // Create our objects
        Surface *t = surface_new (600, 600);
        gtk_container_add (GTK_CONTAINER(w), t->drawing_area);
 
-       r = rectangle_new (50, 50, 100, 100);
+       r = rectangle_new (50, 50, 50, 50);
        Color c = Color (1.0, 0.0, 0.5, 0.5);
        shape_set_stroke (r, new SolidColorBrush (c));
-       cairo_matrix_init_rotate (&trans, 0.4);
-       item_transform_set (r, (double *) (&trans));
-       surface_repaint (t, 0, 0, 300, 300);
-       
-#ifdef VIDEO_DEMO1
+
+       Rectangle *r2 = new Rectangle (50, 50, 50, 50);
+       shape_set_stroke (r2, new SolidColorBrush (c));
+       panel_child_add (t, r2);
+
+#ifdef VIDEO_DEMO
        v = video_new ("BoxerSmacksdownInhoffe.wmv", 0, 0);
-       //printf ("Got %d\n", v);
-       item_transform_set (v, (double *) (&trans));
+       item_set_transform_origin (v, Point (1, 1));
+       printf ("Got %d\n", v);
        panel_child_add (t, v);
 #endif
 
        panel_child_add (t, r);
 
 #ifdef VIDEO_DEMO
-       UIElement *v2 = video_new 
("file:///tmp/Countdown-Colbert-BestNailings.wmv", 100, 100);
+       //UIElement *v2 = video_new 
("file:///tmp/Countdown-Colbert-BestNailings.wmv", 100, 100);
        //UIElement *v2 = video_new ("file:///tmp/red.wmv", 100, 100);
-       //UIElement *v2 = video_new ("file:///tmp/BoxerSmacksdownInhoffe.wmv", 
100, 100);
+       UIElement *v2 = video_new ("file:///tmp/BoxerSmacksdownInhoffe.wmv", 
100, 100);
        panel_child_add (t, v2);
 #endif
 
@@ -81,9 +77,9 @@
        gtk_widget_set_usize (w, 600, 400);
        printf ("show\n");
        gtk_widget_show_all (w);
-       gtk_timeout_add (60, repaint, w);
+       gtk_timeout_add (60, animate, NULL);
        printf ("timeout set\n");
-       //g_idle_add (repaint, w);
+       //g_idle_add (animate, w);
        printf ("entering main\n");
        gtk_main ();
 }

Modified: trunk/moon/src/ffvideo.cpp
===================================================================
--- trunk/moon/src/ffvideo.cpp  2007-06-02 22:30:41 UTC (rev 78481)
+++ trunk/moon/src/ffvideo.cpp  2007-06-02 22:51:48 UTC (rev 78482)
@@ -60,9 +60,9 @@
 
        // Virtual method overrides
        void getbounds ();
-       void render (Surface *s, double *affine, int x, int y, int width, int 
height);
+       void render (Surface *s, int x, int y, int width, int height);
+       virtual Point getxformorigin ();
 
-
        GThread    *decode_thread_id;
        int         pipes [2];
        GIOChannel *pipe_channel;
@@ -124,10 +124,9 @@
 VideoFfmpeg::getbounds ()
 {
        double res [6];
-       double *affine = item_affine_get_absolute (this, res);
        AVCodecContext *cc;
        
-       Surface *s = item_surface_get (this);
+       Surface *s = item_get_surface (this);
        if (s == NULL){
                // not yet attached
                return;
@@ -141,8 +140,8 @@
        cc = video_stream->codec;
 
        cairo_save (s->cairo);
-       if (affine != NULL)
-               cairo_set_matrix (s->cairo, (cairo_matrix_t *) affine);
+       if (absolute_xform != NULL)
+               cairo_set_matrix (s->cairo, (cairo_matrix_t *) absolute_xform);
 
        cairo_rectangle (s->cairo, x, y, cc->width, cc->height);
        cairo_fill_extents (s->cairo, &x1, &y1, &x2, &y2);
@@ -234,7 +233,8 @@
                        audio_stream_idx = video->audio_stream_idx;
 
                        cc = video->audio_stream->codec;
-                       n = snd_pcm_open (&video->pcm, "default", 
SND_PCM_STREAM_PLAYBACK, 0);
+                       n = -1;
+                       //snd_pcm_open (&video->pcm, "default", 
SND_PCM_STREAM_PLAYBACK, 0);
                        if (n < 0)
                                printf ("Error, can not initialize audio %d\n", 
video->pcm);
                        else {
@@ -299,7 +299,7 @@
 
                frame++;
                g_mutex_lock (video->video_mutex);
-               if (pkt->stream_index == audio_stream_idx){
+               if (video->pcm != NULL && pkt->stream_index == 
audio_stream_idx){
                        int frame_size_ptr = sizeof (video->audio_buffer);
                        int decoded_bytes;
 
@@ -405,11 +405,11 @@
                                printf ("Frame PTS=%ld\n", frame->pts);
                                printf ("Target PTS=%ld\n", target_pts);
                                printf ("frame size=%d\n", video->frame_size);
-#endif
+
                                printf ("discarding packet at time=%g seconds 
because it is late\n", 
                                        (pkt_pts - 
video->video_stream->start_time) *
                                        av_q2d 
(video->video_stream->time_base));
-
+#endif
                                // Remove this to discard
                                av_free (frame);
                                frame = NULL;
@@ -493,23 +493,26 @@
 }
 
 void
-VideoFfmpeg::render (Surface *s, double *affine, int x, int y, int width, int 
height)
+VideoFfmpeg::render (Surface *s, int x, int y, int width, int height)
 {
-       double actual [6];
-       double *use_affine = item_get_affine (affine, xform, actual);
        cairo_pattern_t *pattern, *old_pattern;
 
        // If we are not initialized yet, return.
        if (video_cairo_surface == NULL)
                return;
 
+       if (video_stream == NULL || video_stream->codec == NULL){
+               // FIXME: Draw something, some black box or something
+               return;
+       }
        cairo_save (s->cairo);
-       if (use_affine != NULL)
-               cairo_set_matrix (s->cairo, (cairo_matrix_t *) use_affine);
+       if (absolute_xform != NULL)
+               cairo_set_matrix (s->cairo, (cairo_matrix_t *) absolute_xform);
+   
+       cairo_set_source_surface (s->cairo, video_cairo_surface, this->x, 
this->y);
 
-       cairo_translate (s->cairo, this->x, this->y);
-       cairo_set_source_surface (s->cairo, video_cairo_surface, 0, 0);
-       cairo_paint (s->cairo);
+       cairo_rectangle (s->cairo, this->x, this->y, this->w, this->h);
+       cairo_fill (s->cairo);
 
        cairo_restore (s->cairo);
 }
@@ -550,6 +553,7 @@
        video_scale_context = NULL;
        av_format_context = NULL;
        
+       w = h = 0;
        timeout_handle = 0;
        initial_pts = 0;
        play_start_time = 0;
@@ -568,6 +572,12 @@
        decode_thread_id = g_thread_create (decoder, this, TRUE, NULL);
 }
 
+Point
+VideoFfmpeg::getxformorigin ()
+{
+       return Point (x + user_xform_origin.x * w, y + user_xform_origin.y * h);
+}
+
 VideoFfmpeg::~VideoFfmpeg ()
 {
        // TODO:

Modified: trunk/moon/src/runtime.cpp
===================================================================
--- trunk/moon/src/runtime.cpp  2007-06-02 22:30:41 UTC (rev 78481)
+++ trunk/moon/src/runtime.cpp  2007-06-02 22:51:48 UTC (rev 78482)
@@ -74,79 +74,19 @@
        }
 }
 
-/*
- * item_get_affine:
- * @container: the affine transform from the container
- * @affine: the affine transform for this item
- * @result: a place that can contain 6 doubles where the data is saved
- * 
- * Composites the container affine transformation with the item affine
- * transformation.
- *
- * Returns the pointer to result if the caller must apply affine
- * transformations, or NULL if the affine should not be used.
- */
-double *
-item_get_affine (double *container, double *affine, double *result)
+UIElement::~UIElement ()
 {
-       int i;
-
-       if (container == NULL){
-               if (affine == NULL)
-                       return FALSE;
-               for (i = 0; i < 6; i++)
-                       result [i] = affine [i];
-               return result;
-       } 
-       if (affine == NULL){
-               for (i = 0; i < 6; i++)
-                       result [i] = container [i];
-               return result;
-       }
-       
-       result [0] = container [0] * affine [0] + container [1] * affine [2];
-       result [1] = container [0] * affine [1] + container [1] * affine [3];
-       result [2] = container [2] * affine [0] + container [3] * affine [2];
-       result [3] = container [2] * affine [1] + container [3] * affine [3];
-       result [4] = container [4] * affine [0] + container [5] * affine [2] + 
affine [4];
-       result [5] = container [4] * affine [1] + container [5] * affine [3] + 
affine [5];
-       
-       return result;
+       if (absolute_xform)
+               g_free (absolute_xform);
+       if (user_xform)
+               g_free (user_xform);
 }
 
 void 
-item_destroy (UIElement *item)
-{
-       if (item->xform)
-               free (item->xform);
-}
-
-//
-// item_affine_get_absolute:
-//
-//   Returns the absolute affine transformation for this given item
-//   (composing the full chain from the top to this item)
-//
-double *
-item_affine_get_absolute (UIElement *item, double *result)
-{
-       double res [6];
-       double *ret;
-
-       if (item->parent == NULL){
-               return item_get_affine (NULL, item->xform, result);
-       }
-
-       ret = item_affine_get_absolute (item->parent, res);
-       return item_get_affine (ret, item->xform, result);
-}
-
-void 
 item_invalidate (UIElement *item)
 {
        double res [6];
-       double *affine = item_affine_get_absolute (item, res);
-       Surface *s = item_surface_get (item);
+       Surface *s = item_get_surface (item);
 
        if (s == NULL)
                return;
@@ -162,64 +102,128 @@
        //
        gtk_widget_queue_draw_area ((GtkWidget *)s->drawing_area, 
                                    (int) item->x1, (int)item->y1, 
-                                   (int)(item->x2-item->x1), 
(int)(item->y2-item->y1));
+                                   (int)(item->x2-item->x1+1), 
(int)(item->y2-item->y1+1));
 }
 
 void
-item_transform_set (UIElement *item, double *transform)
+item_set_transform (UIElement *item, double *transform)
 {
-       double *d;
-
        item_invalidate (item);
 
-       if (item->xform)
-               free (item->xform);
-
-       if (transform == NULL)
-               item->xform = transform;
-       else {
-               d = (double *) malloc (sizeof (double) * 6);
+       if (transform == NULL){
+               if (item->user_xform)
+                       free (item->user_xform);
+               item->user_xform = NULL;
+       } else {
+               if (item->user_xform == NULL)
+                       item->user_xform = g_new (double, 6);
                
-               d [0] = transform [0];
-               d [1] = transform [1];
-               d [2] = transform [2];
-               d [3] = transform [3];
-               d [4] = transform [4];
-               d [5] = transform [5];
-               
-               item->xform = d;
+               memcpy (item->user_xform, transform, sizeof (double) * 6);
        }
+
+       item->update_xform ();
+
        item->getbounds ();
        item_invalidate (item);
 }
 
+void 
+item_set_transform_origin (UIElement *item, Point p)
+{
+       item_invalidate (item);
+       
+       item->user_xform_origin = p;
+
+       item->update_xform ();
+       item->getbounds ();
+
+       item_invalidate (item);
+}
+
+void
+UIElement::update_xform ()
+{
+       cairo_matrix_t *cairo_mat;
+
+       if (parent == NULL || parent->absolute_xform == NULL) {
+               if (user_xform == NULL){
+                       if (absolute_xform != NULL){
+                               g_free (absolute_xform);
+                               absolute_xform = NULL;
+                       }
+               } else {
+                       //
+                       // If there is a rotation, we need the transform origin
+                       //
+                       if (absolute_xform == NULL)
+                               absolute_xform = g_new (double, 6);
+
+                       cairo_mat = (cairo_matrix_t *) absolute_xform;
+
+                       if (user_xform [1] != 0 || user_xform [2] != 0){
+                               Point p = getxformorigin ();
+
+                               cairo_matrix_init_translate (cairo_mat, p.x, 
p.y);
+                               cairo_matrix_multiply (cairo_mat, 
(cairo_matrix_t *) user_xform, cairo_mat);
+                               cairo_matrix_translate (cairo_mat, -p.x, -p.y);
+                       } else {
+                               memcpy (absolute_xform, user_xform, sizeof 
(double) * 6);
+                       }
+               }
+       } else {
+               // parent has an absolute xform
+
+               if (absolute_xform == NULL)
+                       absolute_xform = g_new (double, 6);
+               cairo_mat = (cairo_matrix_t *) absolute_xform;
+
+               memcpy (absolute_xform, parent->absolute_xform, sizeof (double) 
* 6);
+               Point p = getxformorigin ();
+               cairo_matrix_translate (cairo_mat, p.x, p.y);
+               cairo_matrix_multiply (cairo_mat, (cairo_matrix_t *) 
user_xform, cairo_mat);
+               cairo_matrix_translate (cairo_mat, -p.x, -p.y);
+       }
+}
+
 Surface *
-item_surface_get (UIElement *item)
+item_get_surface (UIElement *item)
 {
        if (item->flags & Video::IS_SURFACE)
                return (Surface *) item;
 
        if (item->parent != NULL)
-               return item_surface_get (item->parent);
+               return item_get_surface (item->parent);
 
        return NULL;
 }
 
 void
-Panel::render (Surface *s, double *affine, int x, int y, int width, int height)
+Panel::render (Surface *s, int x, int y, int width, int height)
 {
        GSList *il;
        double actual [6];
-       double *use_affine = item_get_affine (affine, xform, actual);
        
        for (il = children; il != NULL; il = il->next){
                UIElement *item = (UIElement *) il->data;
 
-               item->render (s, use_affine, x, y, width, height);
+               item->render (s, x, y, width, height);
        }
 }
 
 void
+Panel::update_xform ()
+{
+       UIElement::update_xform ();
+       GSList *il;
+
+       for (il = children; il != NULL; il = il->next){
+               UIElement *item = (UIElement *) il->data;
+
+               item->update_xform ();
+       }
+}
+
+void
 Panel::getbounds ()
 {
        bool first = TRUE;
@@ -266,6 +270,8 @@
 void 
 surface_clear (Surface *s, int x, int y, int width, int height)
 {
+       static unsigned char n;
+
        if (x < 0){
                width -= x;
                x = 0;
@@ -282,7 +288,7 @@
        unsigned char *dest = s->buffer + (y * stride) + (x * 4);
 
        while (height--){
-               memset (dest, 14, width * 4);
+               memset (dest, 70, width * 4);
                dest += stride;
        }
 }
@@ -290,7 +296,7 @@
 void
 surface_clear_all (Surface *s)
 {
-       memset (s->buffer, 14, s->width * s->height * 4);
+       memset (s->buffer, 0, s->width * s->height * 4);
 }
 
 static void
@@ -329,7 +335,6 @@
        if (event->area.x > s->width || event->area.y > s->height)
                return TRUE;
 
-       
        //
        // BIG DEBUG BLOB
        // 
@@ -338,7 +343,9 @@
                        cairo_status_to_string (cairo_status (s->cairo)));
        }
 
-       //printf ("Got a request to repaint at %d %d %d %d\n", event->area.x, 
event->area.y, event->area.width, event->area.height);
+#ifdef DEBUG_INVALIDATE
+       printf ("Got a request to repaint at %d %d %d %d\n", event->area.x, 
event->area.y, event->area.width, event->area.height);
+#endif
        surface_repaint (s, event->area.x, event->area.y, event->area.width, 
event->area.height);
        gdk_draw_pixbuf (widget->window,
                         NULL, 
@@ -377,6 +384,6 @@
 surface_repaint (Surface *s, int x, int y, int width, int height)
 {
        surface_clear (s, x, y, width, height);
-       s->render (s, NULL, x, y, width, height);
+       s->render (s, x, y, width, height);
 }
 

Modified: trunk/moon/src/runtime.h
===================================================================
--- trunk/moon/src/runtime.h    2007-06-02 22:30:41 UTC (rev 78481)
+++ trunk/moon/src/runtime.h    2007-06-02 22:51:48 UTC (rev 78482)
@@ -8,6 +8,19 @@
        
 typedef void (*BrushChangedNotify)(Brush *brush, void *data);
 
+struct Point {
+public:
+       double x, y;
+
+       Point () : x(0), y(0) {}
+
+       Point (double x, double y)
+       {
+               this->x = x;
+               this->y = y;
+       }
+};
+
 struct Color {
        double r, g, b, a;
  public:
@@ -74,7 +87,13 @@
 //
 class UIElement {
  public:
-       UIElement () : parent(NULL), flags (0), xform (NULL), x1 (0), y1(0), 
x2(0), y2(0) {}
+       UIElement () :
+               parent(NULL), flags (0),
+               absolute_xform (NULL),
+               user_xform (NULL),
+               user_xform_origin(0,0),
+               x1 (0), y1(0), x2(0), y2(0)
+               {}
        
        UIElement *parent;
 
@@ -87,15 +106,27 @@
        // The computed bounding box
        double x1, y1, x2, y2;
 
-       // If null, identity, otherwise affine transformation.
-       double *xform;
+       //
+       // Affine transformations:
+       // 
+       Point   user_xform_origin;      // transformation origin, user set
+       double *user_xform;             // If null, identity, otherwise affine 
xform, user set
 
+       // Absolute affine transform
+       double *absolute_xform;
+
        //
+       // update_xform:
+       //   Updates the absolute_xform for this item
+       //
+       virtual void update_xform ();
+       
+       //
        // render: 
-       //   Renders the given @item on the @surface.  The parent affine 
transformation is in
-       //   @affine, and the area that is exposed is delimited by x, y, width, 
height
+       //   Renders the given @item on the @surface.  the area that is
+       //   exposed is delimited by x, y, width, height
        //
-       virtual void render (Surface *surface, double *affine, int x, int y, 
int width, int height) = 0;
+       virtual void render (Surface *surface, int x, int y, int width, int 
height) = 0;
 
        // 
        // getbounds:
@@ -106,17 +137,24 @@
        //   the item->x1,y1,x2,y2 values are updated.
        // 
        virtual void getbounds () = 0;
+
+       //
+       // gencenter:
+       //   Returns the transformation origin based on  of the item and the
+       //   xform_origin
+       virtual Point getxformorigin () {
+               return Point (0, 0);
+       }
+
+       ~UIElement ();
 };
 
-Surface *item_surface_get   (UIElement *item);
-void     item_destroy       (UIElement *item);
-void     item_invalidate    (UIElement *item);
-void     item_update_bounds (UIElement *item);
-void     item_transform_set (UIElement *item, double *transform);
-double  *item_get_affine    (double *container, double *affine, double 
*result);
-Surface *item_surface_get   (UIElement *item);
-double  *item_affine_get_absolute (UIElement *item, double *result);
-
+Surface *item_get_surface          (UIElement *item);
+void     item_destroy              (UIElement *item);
+void     item_invalidate           (UIElement *item);
+void     item_update_bounds        (UIElement *item);
+void     item_set_transform        (UIElement *item, double *transform);
+void     item_set_transform_origin (UIElement *item, Point p);
 //
 // Panel Class
 //
@@ -126,8 +164,9 @@
 
        Panel () : children (NULL) {}
        
-       virtual void render (Surface *s, double *affine, int x, int y, int 
width, int height);
+       virtual void render (Surface *s, int x, int y, int width, int height);
        virtual void getbounds ();
+       virtual void update_xform ();
 };
 
 void panel_child_add (Panel *group, UIElement *item);
@@ -137,13 +176,16 @@
 // children can use
 //
 class Canvas : public Panel {
+ public:
+       virtual Point getxformorigin () { return Point (0, 0); } 
+       
 };
 
 //
 // Shape class 
 // 
 class Shape : public UIElement {
-       void DoDraw (Surface *s, double *affine, bool do_op);
+       void DoDraw (Surface *s, bool do_op);
  public: 
        Brush *fill, *stroke;
 
@@ -152,7 +194,7 @@
        //
        // Overrides from UIElement.
        //
-       virtual void render (Surface *s, double *affine, int x, int y, int 
width, int height);
+       virtual void render (Surface *s, int x, int y, int width, int height);
        virtual void getbounds ();
 
        //
@@ -183,6 +225,8 @@
        Rectangle () : x(0), y(0), w(0), h(0) {};
 
        void Draw (Surface *s);
+
+       virtual Point getxformorigin ();
 };
 Rectangle *rectangle_new  (double x, double y, double w, double h);
 
@@ -197,6 +241,8 @@
                line_x1(px1), line_y1(py1), line_x2(px2), line_y2(py2) {};
        
        void Draw (Surface *s);
+
+       virtual Point getxformorigin ();
 };
 Line *line_new  (double x1, double y1, double x2, double y2);
 
@@ -210,6 +256,8 @@
        char  *filename;
        int    error;
 
+       virtual Point getxformorigin () = 0;
+       
        Video (const char *filename, double x, double y);
        ~Video ();
 };

Modified: trunk/moon/src/shape.cpp
===================================================================
--- trunk/moon/src/shape.cpp    2007-06-02 22:30:41 UTC (rev 78481)
+++ trunk/moon/src/shape.cpp    2007-06-02 22:51:48 UTC (rev 78482)
@@ -22,14 +22,11 @@
 // to either get the bounding box from cairo, or to paint it
 //
 void 
-Shape::DoDraw (Surface *s, double *affine, bool do_op)
+Shape::DoDraw (Surface *s, bool do_op)
 {
-       double result [6];
-       double *matrix = item_get_affine (affine, xform, result);
-
        cairo_save (s->cairo);
-       if (matrix != NULL)
-               //cairo_set_matrix (s->cairo, (cairo_matrix_t *) matrix);
+       if (absolute_xform != NULL)
+               cairo_set_matrix (s->cairo, (cairo_matrix_t *) absolute_xform);
 
        if (fill){
                fill->SetupBrush (s->cairo);
@@ -48,25 +45,25 @@
 }
 
 void
-Shape::render (Surface *s, double *affine, int x, int y, int width, int height)
+Shape::render (Surface *s, int x, int y, int width, int height)
 {
-       DoDraw (s, affine, TRUE);
+       DoDraw (s, TRUE);
 }
 
 void 
 Shape::getbounds ()
 {
        double res [6];
-       double *affine = item_affine_get_absolute (this, res);
 
-       Surface *s = item_surface_get (this);
+       Surface *s = item_get_surface (this);
 
        // not yet attached
        if (s == NULL)
                return;
 
-       DoDraw (s, affine, FALSE);
+       DoDraw (s, FALSE);
        cairo_stroke_extents (s->cairo, &x1, &y1, &x2, &y2);
+
        cairo_new_path (s->cairo);
 }
 
@@ -98,6 +95,12 @@
        cairo_rectangle (s->cairo, x, y, w, h);
 }
 
+Point
+Rectangle::getxformorigin ()
+{
+       return Point (x + w * user_xform_origin.x, y + h * user_xform_origin.y);
+}
+
 Rectangle *
 rectangle_new (double x, double y, double w, double h)
 {
@@ -113,6 +116,13 @@
        cairo_line_to (s->cairo, line_x2, line_y2);
 }
 
+Point
+Line::getxformorigin ()
+{
+       return Point (line_x1 + (line_x2-line_x1) * user_xform_origin.x, 
+                     line_y1 + (line_y2-line_y1) * user_xform_origin.y);
+}
+
 Line *
 line_new (double x1, double y1, double x2, double y2)
 {

_______________________________________________
Mono-patches maillist  -  [email protected]
http://lists.ximian.com/mailman/listinfo/mono-patches

Reply via email to