gtk-css-engine r115 - in trunk: . libccd/ccd
- From: robsta svn gnome org
- To: svn-commits-list gnome org
- Subject: gtk-css-engine r115 - in trunk: . libccd/ccd
- Date: Thu, 18 Sep 2008 16:27:30 +0000 (UTC)
Author: robsta
Date: Thu Sep 18 16:27:30 2008
New Revision: 115
URL: http://svn.gnome.org/viewvc/gtk-css-engine?rev=115&view=rev
Log:
* libccd/ccd/ccd-background.c:
* libccd/ccd/ccd-position.c:
* libccd/ccd/ccd-position.h:
Background tile creation. Not hooked up yet.
Modified:
trunk/ (props changed)
trunk/ChangeLog
trunk/libccd/ccd/ccd-background.c
trunk/libccd/ccd/ccd-position.c
trunk/libccd/ccd/ccd-position.h
Modified: trunk/libccd/ccd/ccd-background.c
==============================================================================
--- trunk/libccd/ccd/ccd-background.c (original)
+++ trunk/libccd/ccd/ccd-background.c Thu Sep 18 16:27:30 2008
@@ -232,10 +232,37 @@
if (0 == strcmp ("background", property)) {
- /* TODO: also support `background-size' here. */
- ret |= bg_color_parse (&self->bg_color, &values);
- ret |= bg_image_parse (&self->bg_image, &values);
- return ret;
+ /* TODO: also support `background-size' here, but let's stick
+ * to CSS2 for now. */
+ ret = bg_color_parse (&self->bg_color, &values);
+ if (ret && values == NULL)
+ return true;
+ else if (!ret)
+ return false;
+
+ ret = bg_image_parse (&self->bg_image, &values);
+ if (ret && values == NULL)
+ return true;
+ else if (!ret)
+ return false;
+
+ ret = bg_repeat_parse (&self->bg_repeat, &values);
+ if (ret && values == NULL)
+ return true;
+ else if (!ret)
+ return false;
+
+ ret = bg_attachment_parse (&self->bg_attachment, &values);
+ if (ret && values == NULL)
+ return true;
+ else if (!ret)
+ return false;
+
+ ret = bg_position_parse (&self->bg_position, &values);
+ if (ret && values == NULL)
+ return true;
+ else if (!ret)
+ return false;
}
if (0 == strcmp ("background-attachment", property)) {
@@ -271,6 +298,118 @@
return false;
}
+#if 0
+/*
+ * x, y are relative to the previous tile.
+ */
+static void
+draw_tile (cairo_t *cr,
+ double x,
+ double y)
+{
+ cairo_translate (cr, x, y);
+ cairo_fill (cr);
+}
+
+/*
+ * y translation must already be set up when calling this.
+ */
+static void
+repeat_x (cairo_t *cr,
+ double x,
+ double width,
+ double tile_width)
+{
+ cairo_translate (cr, x - tile_width, 0);
+ for (double xoff = 0; xoff < width; xoff += tile_width) {
+ draw_tile (cr, tile_width, 0);
+ }
+}
+/*
+ * x translation must already be set up when calling this.
+ */
+static void
+repeat_y (cairo_t *cr,
+ double y,
+ double height,
+ double tile_height)
+{
+ cairo_translate (cr, 0, y - tile_height);
+ for (double yoff = 0; yoff < height; yoff += tile_height) {
+ draw_tile (cr, 0, tile_height);
+ }
+}
+#endif
+
+/*
+ * TODO: find out whether liberal use of cairo_create()/cairo_destroy()
+ * causes performance problems.
+ */
+static cairo_pattern_t *
+create_pattern (ccd_background_image_t const *bg_image,
+ ccd_background_size_t const *bg_size,
+ double width,
+ double height)
+{
+ cairo_t *cr;
+ cairo_pattern_t *tile;
+ cairo_surface_t *surface;
+ double intrinsic_width;
+ double intrinsic_height;
+ double tile_width;
+ double tile_height;
+ double dx;
+ double dy;
+ cairo_pattern_t *pattern;
+
+ /* Create a single tile of appropriate size. */
+ intrinsic_width = cairo_image_surface_get_width (bg_image->image.surface);
+ intrinsic_height = cairo_image_surface_get_height (bg_image->image.surface);
+ tile_width = ccd_position_get_horizontal (&bg_size->width,
+ width, height,
+ intrinsic_width,
+ intrinsic_height);
+ tile_height = ccd_position_get_horizontal (&bg_size->height,
+ width, height,
+ intrinsic_width,
+ intrinsic_height);
+ surface = cairo_surface_create_similar (bg_image->image.surface,
+ CAIRO_CONTENT_COLOR_ALPHA,
+ tile_width, tile_height);
+ cr = cairo_create (surface);
+ cairo_surface_destroy (surface), surface = NULL;
+
+ dx = tile_width / intrinsic_width;
+ dy = tile_height / intrinsic_height;
+ cairo_scale (cr, dx, dy);
+ cairo_set_source_surface (cr, bg_image->image.surface, 0, 0);
+ tile = cairo_get_source (cr);
+ cairo_pattern_set_extend (tile, CAIRO_EXTEND_PAD);
+ cairo_paint (cr);
+ cairo_pattern_reference (tile);
+ cairo_destroy (cr), cr = NULL;
+
+ /* Shortcut if we only want a single tile anyways. */
+ if (tile_width >= width && tile_height >= height)
+ return tile;
+
+ /* Create pattern. */
+ surface = cairo_surface_create_similar (bg_image->image.surface,
+ CAIRO_CONTENT_COLOR_ALPHA,
+ width, height);
+ cr = cairo_create (surface);
+ cairo_surface_destroy (surface), surface = NULL;
+ cairo_pattern_set_extend (tile, CAIRO_EXTEND_REPEAT);
+ cairo_set_source (cr, tile);
+ cairo_pattern_destroy (tile), tile = NULL;
+ cairo_paint (cr);
+ pattern = cairo_get_source (cr);
+ cairo_pattern_reference (pattern);
+ cairo_destroy (cr), cr = NULL;
+
+ return pattern;
+}
+
/**
* ccd_background_fill:
*
Modified: trunk/libccd/ccd/ccd-position.c
==============================================================================
--- trunk/libccd/ccd/ccd-position.c (original)
+++ trunk/libccd/ccd/ccd-position.c Thu Sep 18 16:27:30 2008
@@ -21,7 +21,7 @@
static const struct {
char const *name;
- ccd_position_flags_t match;
+ ccd_position_type_t type;
const double percentage;
} _position_map[] = {
{ "left", CCD_POSITION_LEFT, 0 },
@@ -45,24 +45,29 @@
switch ((*value)->type) {
case TERM_IDENT:
name = (char const *) cr_string_peek_raw_str ((*value)->content.str);
- for (int i = 0; i < G_N_ELEMENTS (_position_map); i++) {
- if (_position_map[i].match & flags &&
+ for (unsigned int i = 0; i < G_N_ELEMENTS (_position_map); i++) {
+ if (_position_map[i].type & flags &&
0 == g_ascii_strcasecmp (_position_map[i].name, name)) {
- self->type = CCD_POSITION_PERCENTAGE;
- self->value = _position_map[i].percentage;
- *value = (*value)->next;
+ if (_position_map[i].percentage > -1) {
+ self->type = CCD_POSITION_PERCENTAGE;
+ self->value = _position_map[i].percentage;
+ *value = (*value)->next;
+ } else {
+ self->type = _position_map[i].type;
+ self->value = -1;
+ }
return true;
}
}
break;
case TERM_NUMBER:
- if (CCD_POSITION_FLAG_PERCENTAGE & flags &&
+ if (CCD_POSITION_PERCENTAGE & flags &&
NUM_PERCENTAGE == (*value)->content.num->type) {
self->type = CCD_POSITION_PERCENTAGE;
self->value = (*value)->content.num->val;
*value = (*value)->next;
return true;
- } else if (CCD_POSITION_FLAG_LENGTH & flags &&
+ } else if (CCD_POSITION_LENGTH & flags &&
NUM_GENERIC == (*value)->content.num->type) {
self->type = CCD_POSITION_LENGTH;
self->value = (*value)->content.num->val;
@@ -81,30 +86,108 @@
return false;
}
-double
-ccd_position_get_offset (ccd_position_t *self,
- double extent,
- double size)
+static void
+contain (double extent_x,
+ double extent_y,
+ double width,
+ double height,
+ double *x,
+ double *y)
{
- double ret;
+ /* Try to use full width. */
+ *y = extent_x * height / width;
+ if (*y <= extent_y) {
+ *x = width;
+ return;
+ }
+
+ /* Use full height. */
+ *x = extent_y * width / height;
+ *y = height;
+}
+
+static void
+cover (double extent_x,
+ double extent_y,
+ double width,
+ double height,
+ double *x,
+ double *y)
+{
+ /* Try to use full width. */
+ *y = extent_x * height / width;
+ if (*y >= extent_y) {
+ *x = width;
+ return;
+ }
- g_return_val_if_fail (self, 0);
+ /* Use full height. */
+ *x = extent_y * width / height;
+ *y = height;
+}
+
+double
+ccd_position_get_horizontal (ccd_position_t const *self,
+ double extent_x,
+ double extent_y,
+ double width,
+ double height)
+{
+ double x;
+ double y;
- ret = 0;
switch (self->type) {
+ case CCD_POSITION_LENGTH:
+ return self->value;
case CCD_POSITION_PERCENTAGE:
- ret = (extent - size) * self->value / 100.;
- break;
+ return self->value * extent_x / 100.;
+ case CCD_POSITION_CONTAIN:
+ contain (extent_x, extent_y, width, height, &x, &y);
+ return x;
+ case CCD_POSITION_COVER:
+ cover (extent_x, extent_y, width, height, &x, &y);
+ return x;
+ case CCD_POSITION_AUTO:
+ return width;
+ default:
+ g_assert_not_reached ();
+ /* Need some code here when building w/o assertions. */
+ return 0;
+ }
+
+ return 0;
+}
+
+double
+ccd_position_get_vertical (ccd_position_t const *self,
+ double extent_x,
+ double extent_y,
+ double width,
+ double height)
+{
+ double x;
+ double y;
+
+ switch (self->type) {
case CCD_POSITION_LENGTH:
- ret = size;
- break;
+ return self->value;
+ case CCD_POSITION_PERCENTAGE:
+ return self->value * extent_y / 100.;
+ case CCD_POSITION_CONTAIN:
+ contain (extent_x, extent_y, width, height, &x, &y);
+ return y;
+ case CCD_POSITION_COVER:
+ cover (extent_x, extent_y, width, height, &x, &y);
+ return y;
+ case CCD_POSITION_AUTO:
+ return height;
default:
g_assert_not_reached ();
/* Need some code here when building w/o assertions. */
return 0;
}
- return ret;
+ return 0;
}
#ifdef CCD_DEBUG
Modified: trunk/libccd/ccd/ccd-position.h
==============================================================================
--- trunk/libccd/ccd/ccd-position.h (original)
+++ trunk/libccd/ccd/ccd-position.h Thu Sep 18 16:27:30 2008
@@ -31,11 +31,11 @@
typedef enum {
/* Remember to revisit all locations where a mask is used when it's
* being extended. */
- CCD_POSITION_FLAG_LENGTH = 1 << 0,
- CCD_POSITION_FLAG_PERCENTAGE = 1 << 1,
+ CCD_POSITION_LENGTH = 1 << 0,
+ CCD_POSITION_PERCENTAGE = 1 << 1,
- CCD_POSITION_MASK_NUMERIC = CCD_POSITION_FLAG_LENGTH |
- CCD_POSITION_FLAG_PERCENTAGE,
+ CCD_POSITION_MASK_NUMERIC = CCD_POSITION_LENGTH |
+ CCD_POSITION_PERCENTAGE,
CCD_POSITION_LEFT = 1 << 2,
CCD_POSITION_TOP = 1 << 3,
@@ -57,11 +57,6 @@
CCD_POSITION_MASK_AUTO = CCD_POSITION_AUTO |
CCD_POSITION_CONTAIN |
CCD_POSITION_COVER
-} ccd_position_flags_t;
-
-typedef enum {
- CCD_POSITION_PERCENTAGE = 0,
- CCD_POSITION_LENGTH
} ccd_position_type_t;
typedef struct {
@@ -69,10 +64,16 @@
double value;
} ccd_position_t;
-bool ccd_position_parse (ccd_position_t *self, uint32_t flags, CRTerm const **value);
+bool ccd_position_parse (ccd_position_t *self, uint32_t flags,
+ CRTerm const **value);
-double ccd_position_get_offset (ccd_position_t *self,
- double extent, double size);
+double ccd_position_get_horizontal (ccd_position_t const *self,
+ double extent_x, double extent_y,
+ double width, double height);
+
+double ccd_position_get_vertical (ccd_position_t const *self,
+ double extent_x, double extent_y,
+ double width, double height);
#ifdef CCD_DEBUG
void ccd_position_dump (ccd_position_t const *self);
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]