summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDavid Reveman <davidr@novell.com>2004-05-10 14:34:28 +0000
committerDavid Reveman <davidr@novell.com>2004-05-10 14:34:28 +0000
commit4828fcb4995de0ce6d36db046c260a212d2235a9 (patch)
tree191b6dc5ae8202c66a2369dbcbc4f78b1c62cbc5
parentbc0caac12d0bdc52bae20c22c54ad29e80d4622f (diff)
Fixed simultaneous transform and repeat
-rw-r--r--ChangeLog13
-rw-r--r--TODO2
-rw-r--r--src/glitz.c257
-rw-r--r--src/glitz_trap.c3
-rw-r--r--src/glitz_tri.c6
5 files changed, 175 insertions, 106 deletions
diff --git a/ChangeLog b/ChangeLog
index 07fe7cd..aba4522 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,16 @@
+2004-05-10 David Reveman <c99drn@cs.umu.se>
+
+ * TODO: Fixed simultaneous transform and repeat.
+
+ * src/glitz_tri.c (glitz_int_composite_triangles): Use ARGB32 format
+ for mask surface.
+
+ * src/glitz_trap.c (glitz_composite_trapezoids): Use ARGB32 format
+ for mask surface.
+
+ * src/glitz.c: Added glitz_repeat_direction_t type.
+ (glitz_composite): Fixed simultaneous transform and repeat.
+
2004-05-09 David Reveman <c99drn@cs.umu.se>
* TODO: Added library cleanup functions.
diff --git a/TODO b/TODO
index 9cadb3c..7e8b55a 100644
--- a/TODO
+++ b/TODO
@@ -3,8 +3,6 @@
* Copy area operation.
-* Support simultaneous transform and repeat.
-
* Alpha scaling of source surface with polygon rendering.
* Text support. Glyph set management, glyph and string compositing
diff --git a/src/glitz.c b/src/glitz.c
index 9a11ec8..4ff7693 100644
--- a/src/glitz.c
+++ b/src/glitz.c
@@ -395,6 +395,14 @@ glitz_mask_bounds (glitz_surface_t *src,
}
}
+typedef enum {
+ GLITZ_REPEAT_NONE = 0,
+ GLITZ_REPEAT_SOUTHEAST,
+ GLITZ_REPEAT_SOUTHWEST,
+ GLITZ_REPEAT_NORTHEAST,
+ GLITZ_REPEAT_NORTHWEST
+} glitz_repeat_direction_t;
+
void
glitz_composite (glitz_operator_t op,
glitz_surface_t *src,
@@ -639,117 +647,168 @@ glitz_composite (glitz_operator_t op,
} else {
/* CASE 2: Either none power of two sized texture or
transformation is set. */
- double save_tlx, save_trx, save_blx, save_brx;
+ glitz_point_t base_tl, base_bl, base_br, base_tr;
+ int x_dir, y_dir, continue_y, continue_x, x_is_ok, y_is_ok,
+ in_destination_area;
+ double save_base_x1, save_base_x2;
+ glitz_repeat_direction_t repeat_direction;
glitz_texture_ensure_repeat (gl, texture, 0);
- bl.x = tl.x = 0;
- tr.y = tl.y = 0;
- tr.x = br.x = src->width;
- bl.y = br.y = src->height;
+ base_bl.x = base_tl.x = 0;
+ base_tr.y = base_tl.y = 0;
+ base_tr.x = base_br.x = src->width;
+ base_bl.y = base_br.y = src->height;
+
+ /* Start repeating in southeast direction */
+ repeat_direction = GLITZ_REPEAT_SOUTHEAST;
+ x_dir = y_dir = 1;
- if (src->transform) {
+ if (src->transform)
glitz_texture_ensure_filter (gl, texture, src->filter);
- glitz_matrix_transform_point (src->transform, &tl);
- glitz_matrix_transform_point (src->transform, &bl);
- glitz_matrix_transform_point (src->transform, &tr);
- glitz_matrix_transform_point (src->transform, &br);
- } else
+ else
glitz_texture_ensure_filter (gl, texture, GLITZ_FILTER_NEAREST);
-
- /* Shift all coordinates with destination offset */
- if (x_dst) {
- tl.x += x_dst;
- bl.x += x_dst;
- tr.x += x_dst;
- br.x += x_dst;
- }
- if (y_dst) {
- tl.y += y_dst;
- bl.y += y_dst;
- tr.y += y_dst;
- br.y += y_dst;
- }
-
- /* Shift all coordinates with source offset */
- if (x_src) {
- x_src = abs (x_src);
- if (SURFACE_REPEAT (src))
- x_src = (x_src % src->width);
- tl.x -= x_src;
- bl.x -= x_src;
- tr.x -= x_src;
- br.x -= x_src;
- }
- if (y_src) {
- y_src = abs (y_src);
- if (SURFACE_REPEAT (src))
- y_src = (y_src % src->height);
- tl.y -= y_src;
- bl.y -= y_src;
- tr.y -= y_src;
- br.y -= y_src;
- }
- save_tlx = tl.x;
- save_blx = bl.x;
- save_trx = tr.x;
- save_brx = br.x;
-
- do {
+ while (repeat_direction) {
+ save_base_x1 = base_tl.x;
+ save_base_x2 = base_tr.x;
+
do {
- /* Clip to original source area if repeat and transform are both
- used. */
- if (src->transform && SURFACE_REPEAT (src)) {
- glitz_region_box_t src_clip, intersect_clip;
-
- src_clip.x1 = tl.x;
- src_clip.y1 = tl.y;
- src_clip.x2 = src_clip.x1 + src->width;
- src_clip.y2 = src_clip.y1 + src->height;
-
- glitz_intersect_region (&clip, &src_clip, &intersect_clip);
-
- gl->scissor (intersect_clip.x1,
- dst->height - (intersect_clip.y1 +
- (intersect_clip.y2 - intersect_clip.y1)),
- intersect_clip.x2 - intersect_clip.x1,
- intersect_clip.y2 - intersect_clip.y1);
- }
+ continue_y = continue_x = in_destination_area = 0;
+ do {
+ bl = base_bl;
+ br = base_br;
+ tl = base_tl;
+ tr = base_tr;
+
+ if (src->transform) {
+ glitz_matrix_transform_point (src->transform, &tl);
+ glitz_matrix_transform_point (src->transform, &bl);
+ glitz_matrix_transform_point (src->transform, &tr);
+ glitz_matrix_transform_point (src->transform, &br);
+ }
+
+ /* Shift all coordinates with destination offset */
+ if (x_dst) {
+ tl.x += x_dst;
+ bl.x += x_dst;
+ tr.x += x_dst;
+ br.x += x_dst;
+ }
+ if (y_dst) {
+ tl.y += y_dst;
+ bl.y += y_dst;
+ tr.y += y_dst;
+ br.y += y_dst;
+ }
+
+ /* Shift all coordinates with source offset */
+ if (x_src) {
+ x_src = abs (x_src);
+ if (SURFACE_REPEAT (src))
+ x_src = (x_src % src->width);
+ tl.x -= x_src;
+ bl.x -= x_src;
+ tr.x -= x_src;
+ br.x -= x_src;
+ }
+ if (y_src) {
+ y_src = abs (y_src);
+ if (SURFACE_REPEAT (src))
+ y_src = (y_src % src->height);
+ tl.y -= y_src;
+ bl.y -= y_src;
+ tr.y -= y_src;
+ br.y -= y_src;
+ }
+
+ if ((tl.x > (x_dst + width) && bl.x > (x_dst + width)) ||
+ (tr.x < x_dst && br.x < x_dst))
+ x_is_ok = 0;
+ else
+ x_is_ok = 1;
+
+ if ((tl.y > (y_dst + height) && tr.y > (y_dst + height)) ||
+ (bl.y < y_dst && br.y < y_dst))
+ y_is_ok = 0;
+ else
+ y_is_ok = 1;
- gl->begin (GLITZ_GL_QUADS);
- gl->tex_coord_2d (0.0, texture->texcoord_height);
- gl->vertex_2d (tl.x, tl.y);
- gl->tex_coord_2d (texture->texcoord_width, texture->texcoord_height);
- gl->vertex_2d (tr.x, tr.y);
- gl->tex_coord_2d (texture->texcoord_width, 0.0);
- gl->vertex_2d (br.x, br.y);
- gl->tex_coord_2d (0.0, 0.0);
- gl->vertex_2d (bl.x, bl.y);
- gl->end ();
+ if (x_is_ok && y_is_ok) {
+ gl->begin (GLITZ_GL_QUADS);
+ gl->tex_coord_2d (0.0, texture->texcoord_height);
+ gl->vertex_2d (tl.x, tl.y);
+ gl->tex_coord_2d (texture->texcoord_width,
+ texture->texcoord_height);
+ gl->vertex_2d (tr.x, tr.y);
+ gl->tex_coord_2d (texture->texcoord_width, 0.0);
+ gl->vertex_2d (br.x, br.y);
+ gl->tex_coord_2d (0.0, 0.0);
+ gl->vertex_2d (bl.x, bl.y);
+ gl->end ();
+ in_destination_area = 1;
+ }
+
+ if (SURFACE_REPEAT (src)) {
+ base_bl.x += src->width * x_dir;
+ base_tl.x += src->width * x_dir;
+ base_tr.x += src->width * x_dir;
+ base_br.x += src->width * x_dir;
+
+ if (y_is_ok)
+ continue_y = 1;
+
+ if (in_destination_area)
+ continue_x = (x_is_ok && y_is_ok);
+ else
+ continue_x = (x_is_ok || y_is_ok);
+ }
+ } while (SURFACE_REPEAT (src) && continue_x);
if (SURFACE_REPEAT (src)) {
- bl.x += src->width;
- tl.x += src->width;
- tr.x += src->width;
- br.x += src->width;
+ base_bl.y += src->height * y_dir;
+ base_tl.y += src->height * y_dir;
+ base_tr.y += src->height * y_dir;
+ base_br.y += src->height * y_dir;
+
+ base_tl.x = base_bl.x = save_base_x1;
+ base_tr.x = base_br.x = save_base_x2;
}
-
- } while (SURFACE_REPEAT (src) && (tl.x < (x_dst + width)));
-
- if (SURFACE_REPEAT (src)) {
- bl.y += src->height;
- tl.y += src->height;
- tr.y += src->height;
- br.y += src->height;
-
- tl.x = save_tlx;
- bl.x = save_blx;
- tr.x = save_trx;
- br.x = save_brx;
- }
-
- } while (SURFACE_REPEAT (src) && (tl.y < (y_dst + height)));
+ } while (SURFACE_REPEAT (src) && continue_y);
+
+ if (src->transform && SURFACE_REPEAT (src)) {
+ switch (repeat_direction) {
+ case GLITZ_REPEAT_SOUTHEAST:
+ y_dir = -1;
+ base_tl.y = base_tr.y = -src->height;
+ base_bl.y = base_br.y = 0.0;
+ repeat_direction = GLITZ_REPEAT_SOUTHWEST;
+ break;
+ case GLITZ_REPEAT_SOUTHWEST:
+ x_dir = -1;
+ base_tl.y = base_tr.y = -src->height;
+ base_bl.y = base_br.y = 0.0;
+ base_tl.x = base_bl.x = -src->width;
+ base_tr.x = base_br.x = 0.0;
+ repeat_direction = GLITZ_REPEAT_NORTHEAST;
+ break;
+ case GLITZ_REPEAT_NORTHEAST:
+ y_dir = 1;
+ base_tl.y = base_tr.y = 0.0;
+ base_bl.y = base_br.y = src->height;
+ base_tl.x = base_bl.x = -src->width;
+ base_tr.x = base_br.x = 0.0;
+ repeat_direction = GLITZ_REPEAT_NORTHWEST;
+ break;
+ case GLITZ_REPEAT_NORTHWEST:
+ repeat_direction = GLITZ_REPEAT_NONE;
+ break;
+ case GLITZ_REPEAT_NONE:
+ break;
+ }
+ } else
+ repeat_direction = GLITZ_REPEAT_NONE;
+ }
}
if (src->convolution || SURFACE_PROGRAMMATIC (src))
diff --git a/src/glitz_trap.c b/src/glitz_trap.c
index 613acdb..265f251 100644
--- a/src/glitz_trap.c
+++ b/src/glitz_trap.c
@@ -217,8 +217,7 @@ glitz_composite_trapezoids (glitz_operator_t op,
if ((bounds.x2 - bounds.x1) <= 0 || (bounds.y2 - bounds.y1) <= 0)
return;
- mask = glitz_int_surface_create_similar (dst, GLITZ_STANDARD_A8,
- 1,
+ mask = glitz_int_surface_create_similar (dst, GLITZ_STANDARD_ARGB32, 1,
bounds.x2 - bounds.x1,
bounds.y2 - bounds.y1);
diff --git a/src/glitz_tri.c b/src/glitz_tri.c
index bd0303f..e39d215 100644
--- a/src/glitz_tri.c
+++ b/src/glitz_tri.c
@@ -180,8 +180,7 @@ glitz_int_composite_triangles (glitz_operator_t op,
if ((bounds.x2 - bounds.x1) <= 0 || (bounds.y2 - bounds.y1) <= 0)
return;
- mask = glitz_int_surface_create_similar (dst, GLITZ_STANDARD_A8,
- 1,
+ mask = glitz_int_surface_create_similar (dst, GLITZ_STANDARD_ARGB32, 1,
bounds.x2 - bounds.x1,
bounds.y2 - bounds.y1);
@@ -192,7 +191,8 @@ glitz_int_composite_triangles (glitz_operator_t op,
mask->hint_mask |= GLITZ_INT_HINT_IMPLICIT_MASK_MASK;
- if (!glitz_surface_push_current (mask, GLITZ_CN_SURFACE_DRAWABLE_CURRENT)) {
+ if (!glitz_surface_push_current (mask,
+ GLITZ_CN_SURFACE_DRAWABLE_CURRENT)) {
glitz_surface_pop_current (mask);
return;
}