Author: miguel
Date: 2007-05-26 20:24:00 -0400 (Sat, 26 May 2007)
New Revision: 77996

Modified:
   trunk/moon/README
   trunk/moon/src/ChangeLog
   trunk/moon/src/Makefile.am
   trunk/moon/src/demo.cpp
   trunk/moon/src/runtime.cpp
   trunk/moon/src/runtime.h
Log:
Some refactoring

Modified: trunk/moon/README
===================================================================
--- trunk/moon/README   2007-05-27 00:14:33 UTC (rev 77995)
+++ trunk/moon/README   2007-05-27 00:24:00 UTC (rev 77996)
@@ -66,6 +66,15 @@
 
        And then `use_affine' is used. 
 
+* Class Hierarchy
+
+       I tried to simplify the class hierarchy from the one found in:
+
+               www.mono-project.com/WPFNotes
+
+       We will likely have to introudce some of the same classes to mirror
+       the hierarchy as my over-simplification left a few things out.
+
 * Rendering in Items
 
        Rendering currently passes the parent affine, but it might be possible 
to

Modified: trunk/moon/src/ChangeLog
===================================================================
--- trunk/moon/src/ChangeLog    2007-05-27 00:14:33 UTC (rev 77995)
+++ trunk/moon/src/ChangeLog    2007-05-27 00:24:00 UTC (rev 77996)
@@ -0,0 +1,12 @@
+2007-05-26  Miguel de Icaza  <[EMAIL PROTECTED]>
+
+       * runtime.cpp (Brush, SolidBrush): Introduce brushes. 
+
+       (Shape): introduce reusable drawing framework for shapes, not
+       complete. 
+       
+       (Line): introduce second user besides rectangles. 
+
+       Remove agg test code.
+
+       (Group::getbounds): implement.
\ No newline at end of file

Modified: trunk/moon/src/Makefile.am
===================================================================
--- trunk/moon/src/Makefile.am  2007-05-27 00:14:33 UTC (rev 77995)
+++ trunk/moon/src/Makefile.am  2007-05-27 00:24:00 UTC (rev 77996)
@@ -2,7 +2,8 @@
 
 lib_LTLIBRARIES = libmoon.la
 
-libmoon_la_SOURCES = \
+libmoon_la_SOURCES =   \
+       brush.cpp       \
        runtime.cpp     \
        runtime.h       \
        video.cpp       \

Modified: trunk/moon/src/demo.cpp
===================================================================
--- trunk/moon/src/demo.cpp     2007-05-27 00:14:33 UTC (rev 77995)
+++ trunk/moon/src/demo.cpp     2007-05-27 00:24:00 UTC (rev 77996)
@@ -1,4 +1,4 @@
-#define VIDEO_DEMO
+//#define VIDEO_DEMO
 #include <string.h>
 #include <gtk/gtk.h>
 #include <malloc.h>
@@ -7,7 +7,8 @@
 
 #include "runtime.h"
 
-static Item *r, *v;
+static Item *v;
+static Rectangle *r;
 
 gboolean
 expose_event_callback (GtkWidget *widget, GdkEventExpose *event, gpointer data)
@@ -72,6 +73,7 @@
        Surface *t = surface_new (600, 600);
        t->data = w;
        r = rectangle_new (100, 100, 100, 100);
+       shape_set_stroke (r, new SolidColorBrush (Color (1.0, 0.0, 0.5, 0.5)));
        cairo_matrix_init_rotate (&trans, 0.4);
        item_transform_set (r, (double *) (&trans));
        surface_repaint (t, 0, 0, 300, 300);

Modified: trunk/moon/src/runtime.cpp
===================================================================
--- trunk/moon/src/runtime.cpp  2007-05-27 00:14:33 UTC (rev 77995)
+++ trunk/moon/src/runtime.cpp  2007-05-27 00:24:00 UTC (rev 77996)
@@ -171,6 +171,18 @@
        item_invalidate (item);
 }
 
+Surface *
+item_surface_get (Item *item)
+{
+       if (item->flags & Video::IS_SURFACE)
+               return (Surface *) item;
+
+       if (item->parent != NULL)
+               return item_surface_get (item->parent);
+
+       return NULL;
+}
+
 void
 Group::render (Surface *s, double *affine, int x, int y, int width, int height)
 {
@@ -188,7 +200,36 @@
 void
 Group::getbounds ()
 {
-       
+       bool first = TRUE;
+       GSList *il;
+
+       for (il = items; il != NULL; il = il->next){
+               Item *item = (Item *) il->data;
+
+               item->getbounds ();
+               if (first){
+                       x1 = item->x1;
+                       x2 = item->x2;
+                       y1 = item->y1;
+                       y2 = item->y2;
+                       first = FALSE;
+                       continue;
+               } 
+
+               if (item->x1 < x1)
+                       x1 = item->x1;
+               if (item->x2 > x2)
+                       x2 = item->x2;
+               if (item->y1 < y1)
+                       y1 = item->y1;
+               if (item->y2 > y2)
+                       y2 = item->y2;
+       }
+
+       // If we found nothing.
+       if (first){
+               x1 = y1 = x2 = y2 = 0;
+       }
 }
 
 void 
@@ -200,75 +241,80 @@
        item->getbounds ();
 }
 
-static void
-rectangle_draw (Rectangle *r, Surface *s, double *affine)
+void 
+Shape::DoDraw (Surface *s, bool do_op)
 {
+       if (fill){
+               //fill->SetupBrush (s->cairo);
+               Draw (s);
+               if (do_op)
+                       cairo_fill (s->cairo);
+       }
+
+       if (stroke){
+               stroke->SetupBrush (s->cairo);
+               Draw (s);
+               if (do_op)
+                       cairo_stroke (s->cairo);
+       }
+
+}
+
+void
+Shape::render (Surface *s, double *affine, int x, int y, int width, int height)
+{
        double result [6];
-       double *matrix = item_get_affine (affine, r->xform, result);
+       double *matrix = item_get_affine (affine, xform, result);
 
        cairo_save (s->cairo);
        if (matrix != NULL)
                cairo_set_matrix (s->cairo, (cairo_matrix_t *) matrix);
 
-       cairo_rectangle (s->cairo, r->x, r->y, r->w, r->h);
+       DoDraw (s, TRUE);
+
        cairo_restore (s->cairo);
 }
 
-Surface *
-item_surface_get (Item *item)
+void 
+Shape::getbounds ()
 {
-       if (item->flags & Video::IS_SURFACE)
-               return (Surface *) item;
+       double res [6];
+       double *affine = item_affine_get_absolute (this, res);
 
-       if (item->parent != NULL)
-               return item_surface_get (item->parent);
+       Surface *s = item_surface_get (this);
+       if (s == NULL){
+               // not yet attached
+               return;
+       }
 
-       return NULL;
+       DoDraw (s, FALSE);
+       cairo_stroke_extents (s->cairo, &x1, &y1, &x2, &y2);
+       cairo_new_path (s->cairo);
 }
 
 void 
-Rectangle::render (Surface *s, double *affine, int x, int y, int width, int 
height)
+shape_set_fill (Shape *shape, Brush *fill)
 {
-#if CAIRO
-       rectangle_draw (this, s, affine);
-       cairo_stroke (s->cairo);
-#else
-       Rectangle *r = (Rectangle *) item;
-       Agg2D *g = s->priv->graphics;
+       if (shape->fill != NULL)
+               brush_unref (shape->fill);
 
-       double result[6];
-       double *matrix = item_get_affine (affine, item->xform, result);
+       shape->fill = brush_ref (fill);
+}
 
-       if (matrix != NULL){
-               Agg2D::Affine a (matrix [0], matrix [1], matrix [2], matrix 
[3], matrix [4], matrix [5]);
-               
-               g->affine (a);
-       }
-        g->lineColor (0, 0, 0);
-        g->noFill ();
-        g->rectangle (r->x, r->y, r->x + r->w, r->y + r->h);
-       if (matrix != NULL)
-               g->resetTransformations ();
-#endif
+void 
+shape_set_stroke (Shape *shape, Brush *stroke)
+{
+       if (shape->stroke != NULL)
+               brush_unref (shape->stroke);
+
+       shape->stroke = brush_ref (stroke);
 }
 
 void
-Rectangle::getbounds ()
+Rectangle::Draw (Surface *s)
 {
-       double res [6];
-       double *affine = item_affine_get_absolute (this, res);
-
-       Surface *s = item_surface_get (this);
-       if (s == NULL){
-               // not yet attached
-               return;
-       }
-#if CAIRO
-       rectangle_draw (this, s, affine);
-       cairo_stroke_extents (s->cairo, &x1, &y1, &x2, &y2);
-       cairo_new_path (s->cairo);
-#else
-#endif
+       printf ("here\n");
+       cairo_rectangle (s->cairo, x, y, w, h);
 }
 
 Rectangle *
@@ -279,6 +325,19 @@
        return rect;
 }
 
+void
+Line::Draw (Surface *s)
+{
+       cairo_move_to (s->cairo, line_x1, line_x2);
+       cairo_line_to (s->cairo, line_x2, line_y2);
+}
+
+Line *
+line_new (double x1, double y1, double x2, double y2)
+{
+       return new Line (x1, y1, x2, y2);
+}
+
 void 
 surface_clear (Surface *s, int x, int y, int width, int height)
 {
@@ -321,29 +380,13 @@
        s->buffer = (unsigned char *) malloc (size);
        surface_clear_all (s);
        
-       //
-       // Hook up our surfaces
-       //
-
        s->pixbuf = gdk_pixbuf_new_from_data (s->buffer, GDK_COLORSPACE_RGB, 
TRUE, 8, 
                                              s->width, s->height, s->width * 
4, NULL, NULL);
 
-#if AGG
-       s->priv = g_new0 (SurfacePrivate, 1);
-       s->priv->rbuf =  agg::rendering_buffer ();
-       s->priv->rbuf.attach  (s->buffer, s->width, s->height, s->width * 4);
-       s->priv->graphics = new Agg2D();
-       s->priv->graphics->attach (s->buffer, s->width, s->height, s->width * 
4);
-       s->priv->graphics->viewport (0, 0, s->width, s->height, 0, 0, s->width, 
s->height, Agg2D::XMidYMid);
-#else
+       s->cairo_surface = cairo_image_surface_create_for_data (
+               s->buffer, CAIRO_FORMAT_ARGB32, s->width, s->height, s->width * 
4);
 
-       s->cairo_surface = cairo_image_surface_create_for_data (s->buffer, 
CAIRO_FORMAT_ARGB32, s->width, s->height, s->width * 4);
        s->cairo = cairo_create (s->cairo_surface);
-       //cairo_set_operator (s->cairo, CAIRO_OPERATOR_SOURCE);
-       //cairo_paint (s->cairo);
-       //cairo_set_operator (s->cairo, CAIRO_OPERATOR_SOURCE);
-       //cairo_set_source_rgb (s->cairo, 0, 1, 0);
-#endif
 }
 
 void 

Modified: trunk/moon/src/runtime.h
===================================================================
--- trunk/moon/src/runtime.h    2007-05-27 00:14:33 UTC (rev 77995)
+++ trunk/moon/src/runtime.h    2007-05-27 00:24:00 UTC (rev 77996)
@@ -1,19 +1,66 @@
-#ifdef __cplusplus
-extern "C" {
-#endif
+G_BEGIN_DECLS
        
 #include <cairo.h>
 
 class Surface;
+class Brush;
        
-typedef struct {
+typedef void (*BrushChangedNotify)(Brush *brush, void *data);
+
+struct Color {
+       double r, g, b, a;
+ public:
+       Color () : r(0), g(0), b(0), a(0) {}
+       
+       Color (double r, double g, double b, double a)
+       {
+               this->r = r;
+               this->g = g;
+               this->b = b;
+               this->a = a;
+       };
+};
+
+class Brush {
+       GSList *listeners;
+ public:
+       int refcount;
+       Brush () : opacity(0), relative_transform(NULL), transform(NULL), 
listeners(NULL), refcount(1) {}
+       
        double opacity;
        double *relative_transform;
        double *transform;
 
-       GList *listeners;
-} Brush;
+       void *AddListener    (BrushChangedNotify notify, void *data);
+       void  RemoveListener (void *key);
 
+       virtual void SetupBrush (cairo_t *cairo) = 0;
+};
+
+Brush *brush_ref   (Brush *brush);
+void   brush_unref (Brush *brush);
+       
+class SolidColorBrush : public Brush {
+       Color color;
+ public:
+       SolidColorBrush (Color c) { color; } 
+
+       virtual void SetupBrush (cairo_t *cairo);
+};
+
+class GradientBrush : public Brush {
+ public:
+       GradientBrush ();
+       // ColorInterpolationMode{ScRgbLinearInterpolation, 
SRgbLinearInterpolation} mode;
+       // GradientStopCollection stops
+       // BrushMappingMode{Absolute,RelativeToBoundingBox} MappingMode
+       // GradientSpreadMethod{Pad, Reflect, Repeat} SpreadMethod
+       virtual void SetupBrush (cairo_t *cairo);
+};
+
+//
+// Item class
+//
 class Item {
  public:
        Item () : parent(NULL), flags (0), xform (NULL), x1 (0), y1(0), x2(0), 
y2(0) {}
@@ -59,6 +106,9 @@
 Surface *item_surface_get   (Item *item);
 double  *item_affine_get_absolute (Item *item, double *result);
 
+//
+// Group Class
+//
 class Group : public Item {
  public:
        GSList *items;
@@ -68,28 +118,71 @@
        virtual void render (Surface *s, double *affine, int x, int y, int 
width, int height);
        virtual void getbounds ();
 };
-
 void group_item_add (Group *group, Item *item);
 
+//
+// Shape class 
+// 
 class Shape : public Item {
-       // Brush: Fill, Stroke
+       void DoDraw (Surface *s, bool do_op);
+ public: 
+       Brush *fill, *stroke;
+
+       Shape () : fill (NULL), stroke (NULL) {}
+
+       //
+       // Overrides from Item.
+       //
+       virtual void render (Surface *s, double *affine, int x, int y, int 
width, int height);
+       virtual void getbounds ();
+
+       //
+       // new virtual methods for shapes
+       //
+       
+       //
+       // Draw: draws the Shape on the surface (affine transforms are set 
before this
+       // is called). 
+       //
+       // This is called multiple times: one for fills, one for strokes
+       // if they are both set.   It will also be called to compute the 
bounding box.
+       //
+       virtual void Draw (Surface *s) = 0;
 };
 
+void shape_set_fill   (Shape *shape, Brush *brush);
+void shape_set_stroke (Shape *shape, Brush *brush);
+
+//
+// Rectangle class 
+// 
 class Rectangle : public Shape {
  public:
        double x, y, w, h;
 
        Rectangle (double ix, double iy, double iw, double ih) : x(ix), y(iy), 
w(iw), h(ih) {};
        Rectangle () : x(0), y(0), w(0), h(0) {};
+
+       void Draw (Surface *s);
+};
+Rectangle *rectangle_new  (double x, double y, double w, double h);
+
+//
+// Line class 
+// 
+class Line : public Shape {
+ public:
+       double line_x1, line_y1, line_x2, line_y2;
+
+       Line (double px1, double py1, double px2, double py2) :
+               line_x1(px1), line_y1(py1), line_x2(px2), line_y2(py2) {};
        
-       virtual void render (Surface *s, double *affine, int x, int y, int 
width, int height);
-       virtual void getbounds ();
+       void Draw (Surface *s);
 };
+Line *line_new  (double x1, double y1, double x2, double y2);
 
-Rectangle *rectangle_new  (double x, double y, double w, double h);
 
-typedef struct _VideoPrivate VideoPrivate;
-       
+
 // A video is an Item
 class Video : public Item {
        enum { VIDEO_OK, VIDEO_ERROR_OPEN, VIDEO_ERROR_STREAM_INFO } VideoError;
@@ -140,6 +233,4 @@
 void     surface_destroy   (Surface *s);
 void     surface_repaint   (Surface *s, int x, int y, int width, int height);
 
-#ifdef __cplusplus
-};
-#endif
+G_END_DECLS

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

Reply via email to