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