Author: spouliot
Date: 2007-06-18 11:56:09 -0400 (Mon, 18 Jun 2007)
New Revision: 80014

Modified:
   trunk/moon/src/ChangeLog
   trunk/moon/src/brush.cpp
   trunk/moon/src/media.cpp
   trunk/moon/src/media.h
Log:
2007-06-18  Sebastien Pouliot  <[EMAIL PROTECTED]>
        * brush.cpp: Refactor the pattern creation to allow caching.
        * media.cpp|h: Add caching of cairo_pattern_t to Image.



Modified: trunk/moon/src/ChangeLog
===================================================================
--- trunk/moon/src/ChangeLog    2007-06-18 15:42:14 UTC (rev 80013)
+++ trunk/moon/src/ChangeLog    2007-06-18 15:56:09 UTC (rev 80014)
@@ -1,4 +1,8 @@
+2007-06-18  Sebastien Pouliot  <[EMAIL PROTECTED]>
 
+       * brush.cpp: Refactor the pattern creation to allow caching.
+       * media.cpp|h: Add caching of cairo_pattern_t to Image.
+
 Mon Jun 18 17:53:03 CEST 2007 Paolo Molaro <[EMAIL PROTECTED]>
 
        * runtime.cpp: use motion hints for smoother motion event handling.

Modified: trunk/moon/src/brush.cpp
===================================================================
--- trunk/moon/src/brush.cpp    2007-06-18 15:42:14 UTC (rev 80013)
+++ trunk/moon/src/brush.cpp    2007-06-18 15:56:09 UTC (rev 80014)
@@ -861,10 +861,9 @@
                TileBrush::OnPropertyChanged (prop);
 }
 
-// ripped apart to be reusable for Image class
-void
-image_brush_set_surface_as_pattern (cairo_t *cairo, cairo_surface_t *surface, 
double width, double height, int sw, int sh, 
-       double opacity, Stretch stretch, AlignmentX align_x, AlignmentY 
align_y, Transform *transform)
+// ripped apart to be reusable for Image and VideoBrush classes
+cairo_pattern_t*
+image_brush_create_pattern (cairo_t *cairo, cairo_surface_t *surface, int sw, 
int sh, double opacity)
 {
        cairo_pattern_t *pattern;
 
@@ -882,8 +881,13 @@
                pattern = cairo_pattern_create_for_surface (surface);
        }
 
-       cairo_matrix_t matrix;
+       return pattern;
+}
 
+void
+image_brush_compute_pattern_matrix (cairo_matrix_t *matrix, double width, 
double height, int sw, int sh, 
+       Stretch stretch, AlignmentX align_x, AlignmentY align_y, Transform 
*transform)
+{
        // scale required to "fit" for both axes
        double sx = sw / width;
        double sy = sh / height;
@@ -891,11 +895,8 @@
        // Fill is the simplest case because AlignementX and AlignmentY don't 
matter in this case
        if (stretch == StretchFill) {
                // fill extents in both axes
-               cairo_matrix_init_scale (&matrix, sx, sy);
+               cairo_matrix_init_scale (matrix, sx, sy);
        } else {
-               bool fit_horz = (sw <= width);
-               bool fit_vert = (sh <= height);
-
                double scale = 1.0;
                double dx = 0.0;
                double dy = 0.0;
@@ -916,18 +917,15 @@
                        break;
                }
 
-               double actual_height = scale * height;
-               double actual_width = scale * width;
-
                switch (align_x) {
                case AlignmentXLeft:
                        dx = 0.0;
                        break;
                case AlignmentXCenter:
-                       dx = (sw - actual_width) / 2;
+                       dx = (sw - (scale * width)) / 2;
                        break;
                case AlignmentXRight:
-                       dx = (sw - actual_width);
+                       dx = (sw - (scale * width));
                        break;
                }
 
@@ -936,19 +934,19 @@
                        dy = 0.0;
                        break;
                case AlignmentYCenter:
-                       dy = (sh - actual_height) / 2;
+                       dy = (sh - (scale * height)) / 2;
                        break;
                case AlignmentYBottom:
-                       dy = (sh - actual_height);
+                       dy = (sh - (scale * height));
                        break;
                }
 
                if (stretch == StretchNone) {
                        // no strech, no scale
-                       cairo_matrix_init_translate (&matrix, dx, dy);
+                       cairo_matrix_init_translate (matrix, dx, dy);
                } else {
                        // otherwise there's both a scale and translation to be 
done
-                       cairo_matrix_init (&matrix, scale, 0, 0, scale, dx, dy);
+                       cairo_matrix_init (matrix, scale, 0, 0, scale, dx, dy);
                }
        }
 
@@ -956,12 +954,8 @@
                cairo_matrix_t tm;
                transform_get_transform (transform, &tm);
                cairo_matrix_invert (&tm);
-               cairo_matrix_multiply (&matrix, &tm, &matrix);
+               cairo_matrix_multiply (matrix, &tm, matrix);
        }
-       cairo_pattern_set_matrix (pattern, &matrix);
-
-       cairo_set_source (cairo, pattern);
-       cairo_pattern_destroy (pattern);
 }
 
 void
@@ -997,8 +991,14 @@
                width = fabs (x2 - x1);
        }
        
-       image_brush_set_surface_as_pattern (cairo, surface, width, height, 
image->GetWidth (), image->GetHeight (), 
-               opacity, stretch, ax, ay, transform);
+       cairo_pattern_t *pattern = image_brush_create_pattern (cairo, surface, 
image->GetWidth (), image->GetHeight (), opacity);
+
+       cairo_matrix_t matrix;
+       image_brush_compute_pattern_matrix (&matrix, width, height, 
image->GetWidth (), image->GetHeight (), stretch, ax, ay, transform);
+       cairo_pattern_set_matrix (pattern, &matrix);
+
+       cairo_set_source (cairo, pattern);
+       cairo_pattern_destroy (pattern);
 }
 
 //
@@ -1065,9 +1065,15 @@
                opacity = 1.0;
        }
        
-       image_brush_set_surface_as_pattern (cairo, surface, width, height,
-                                           mplayer->width, mplayer->height,
-                                           opacity, stretch, ax, ay, 
transform);
+       cairo_pattern_t *pattern = image_brush_create_pattern (cairo, surface, 
mplayer->width, mplayer->height, opacity);
+
+       cairo_matrix_t matrix;
+       image_brush_compute_pattern_matrix (&matrix, width, height, 
mplayer->width, mplayer->height, stretch, ax, ay, transform);
+       cairo_pattern_set_matrix (pattern, &matrix);
+
+       cairo_set_source (cairo, pattern);
+       cairo_pattern_destroy (pattern);
+
 }
 
 void

Modified: trunk/moon/src/media.cpp
===================================================================
--- trunk/moon/src/media.cpp    2007-06-18 15:42:14 UTC (rev 80013)
+++ trunk/moon/src/media.cpp    2007-06-18 15:56:09 UTC (rev 80014)
@@ -432,7 +432,9 @@
     downloader (NULL),
     surface (NULL),
     brush (NULL),
-    render_progressive (false)
+    render_progressive (false),
+    pattern (NULL),
+    pattern_opacity (1.0)
 {
 }
 
@@ -456,7 +458,18 @@
        }
 }
 
+
 void
+Image::CleanupPattern ()
+{
+       if (pattern) {
+               cairo_pattern_destroy (pattern);
+               pattern = NULL;
+       }
+       pattern_opacity = 1.0;
+}
+
+void
 Image::CleanupSurface ()
 {
        if (pixbuf) {
@@ -464,13 +477,15 @@
                pixbuf = NULL;
        }
 
+       CleanupPattern ();
+
        if (surface) {
                cairo_surface_destroy (surface);
                surface = NULL;
        }
 
        pixbuf_width =
-         pixbuf_height = 0;
+       pixbuf_height = 0;
 }
 
 void
@@ -580,6 +595,8 @@
                return;
        }
 
+       CleanupPattern ();
+
        pixbuf = gdk_pixbuf_loader_get_pixbuf (loader);
        if (!pixbuf)
                return;
@@ -711,10 +728,10 @@
        ((Image*)data)->LoaderAreaUpdated (x, y, width, height);
 }
 
-// that's too ugly to be exposed in the header files ;-)
-void
-image_brush_set_surface_as_pattern (cairo_t *cairo, cairo_surface_t *surface, 
double width, double height, int sw, int sh, 
-       double opacity, Stretch stretch, AlignmentX align_x, AlignmentY 
align_y, Transform *transform);
+// still too ugly to be exposed in the header files ;-)
+cairo_pattern_t* image_brush_create_pattern (cairo_t *cairo, cairo_surface_t 
*surface, int sw, int sh, double opacity);
+void image_brush_compute_pattern_matrix (cairo_matrix_t *matrix, double width, 
double height, int sw, int sh, 
+       Stretch stretch, AlignmentX align_x, AlignmentY align_y, Transform 
*transform);
 
 void
 Image::render (Surface *s, int x, int y, int width, int height)
@@ -731,9 +748,20 @@
        double w = framework_element_get_width (this);
        double h = framework_element_get_height (this);
 
-       image_brush_set_surface_as_pattern (s->cairo, surface, w, h, 
pixbuf_width, pixbuf_height, GetTotalOpacity (), 
-               stretch, AlignmentXCenter, AlignmentYCenter, NULL);
+       double opacity = GetTotalOpacity ();
+       if (!pattern || (pattern_opacity != opacity)) {
+               pattern = image_brush_create_pattern (s->cairo, surface, 
pixbuf_width, pixbuf_height, opacity);
+               pattern_opacity = opacity;
+       }
 
+       cairo_matrix_t matrix;
+       image_brush_compute_pattern_matrix (&matrix, w, h, pixbuf_width, 
pixbuf_height, stretch, 
+               AlignmentXCenter, AlignmentYCenter, NULL);
+       cairo_pattern_set_matrix (pattern, &matrix);
+
+       cairo_set_source (s->cairo, pattern);
+
+       cairo_new_path (s->cairo);
        cairo_rectangle (s->cairo, 0, 0, w, h);
        cairo_fill (s->cairo);
        cairo_restore (s->cairo);

Modified: trunk/moon/src/media.h
===================================================================
--- trunk/moon/src/media.h      2007-06-18 15:42:14 UTC (rev 80013)
+++ trunk/moon/src/media.h      2007-06-18 15:56:09 UTC (rev 80014)
@@ -67,6 +67,7 @@
  private:
        void CreateSurface ();
        void CleanupSurface ();
+       void CleanupPattern ();
        void StopLoader ();
 
        // downloader callbacks
@@ -92,6 +93,10 @@
        cairo_surface_t *surface;
        int pixbuf_width;
        int pixbuf_height;
+
+       // pattern caching
+       cairo_pattern_t *pattern;
+       double pattern_opacity;
 };
 
 Image *image_new (void);

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

Reply via email to