aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorBenjamin Herrenschmidt <benh@kernel.crashing.org>2006-12-03 16:24:28 +1100
committerBenjamin Herrenschmidt <benh@kernel.crashing.org>2006-12-03 16:24:28 +1100
commit1ef6eaa1c4c6f895546fe9ad42d40e572be4a8aa (patch)
tree9a5ca3da3f4f7baa18e54ddbbad6aae712b86e6b
parent223adfae7caab8603c22159db00af7c08da9023c (diff)
downloadlibtwin-1ef6eaa1c4c6f895546fe9ad42d40e572be4a8aa.tar.gz
Rework clip handling. The clip rectangle and the origin of drawing
are now two different things, so that you can clip drawing within changing your coordinate system. Signed-off-by: Benjamin Herrenschmidt <benh@kernel.crashing.org>
-rw-r--r--twin.h30
-rw-r--r--twin_box.c6
-rw-r--r--twin_draw.c36
-rw-r--r--twin_pixmap.c70
-rw-r--r--twin_poly.c13
-rw-r--r--twin_window.c12
6 files changed, 138 insertions, 29 deletions
diff --git a/twin.h b/twin.h
index c2603c6..2e13fe0 100644
--- a/twin.h
+++ b/twin.h
@@ -117,9 +117,13 @@ typedef struct _twin_pixmap {
/*
* Clipping - a single rectangle in pixmap coordinates.
- * Drawing is done relative to this rectangle
+ * Drawing is done clipped by this rectangle and relative
+ * to origin_x, origin_y
*/
twin_rect_t clip;
+ twin_coord_t origin_x;
+ twin_coord_t origin_y;
+
/*
* Pixels
*/
@@ -955,15 +959,35 @@ void
twin_pixmap_disable_update (twin_pixmap_t *pixmap);
void
-twin_pixmap_clip (twin_pixmap_t *pixmap,
+twin_pixmap_get_origin (twin_pixmap_t *pixmap,
+ twin_coord_t *ox, twin_coord_t *oy);
+
+void
+twin_pixmap_set_origin (twin_pixmap_t *pixmap,
+ twin_coord_t ox, twin_coord_t oy);
+
+void
+twin_pixmap_origin_to_clip (twin_pixmap_t *pixmap);
+
+void
+twin_pixmap_offset (twin_pixmap_t *pixmap,
+ twin_coord_t offx, twin_coord_t offy);
+
+
+void
+twin_pixmap_clip (twin_pixmap_t *pixmap,
twin_coord_t left, twin_coord_t top,
twin_coord_t right, twin_coord_t bottom);
void
twin_pixmap_set_clip (twin_pixmap_t *pixmap, twin_rect_t clip);
+
+twin_rect_t
+twin_pixmap_get_clip (twin_pixmap_t *pixmap);
+
twin_rect_t
-twin_pixmap_current_clip (twin_pixmap_t *pixmap);
+twin_pixmap_save_clip (twin_pixmap_t *pixmap);
void
twin_pixmap_restore_clip (twin_pixmap_t *pixmap, twin_rect_t rect);
diff --git a/twin_box.c b/twin_box.c
index b1aa299..72ed5e1 100644
--- a/twin_box.c
+++ b/twin_box.c
@@ -230,17 +230,21 @@ _twin_box_dispatch (twin_widget_t *widget, twin_event_t *event)
if (child->paint)
{
twin_pixmap_t *pixmap = box->widget.window->pixmap;
- twin_rect_t clip = twin_pixmap_current_clip (pixmap);
+ twin_rect_t clip = twin_pixmap_save_clip (pixmap);
+ twin_coord_t ox, oy;
+ twin_pixmap_get_origin (pixmap, &ox, &oy);
if (child->shape != TwinShapeRectangle)
twin_fill (child->window->pixmap,
widget->background, TWIN_SOURCE,
child->extents.left, child->extents.top,
child->extents.right, child->extents.bottom);
twin_pixmap_set_clip (pixmap, child->extents);
+ twin_pixmap_origin_to_clip (pixmap);
child->paint = TWIN_FALSE;
(*child->dispatch) (child, event);
twin_pixmap_restore_clip (pixmap, clip);
+ twin_pixmap_set_origin (pixmap, ox, oy);
}
break;
default:
diff --git a/twin_draw.c b/twin_draw.c
index 3045cea..48a9da6 100644
--- a/twin_draw.c
+++ b/twin_draw.c
@@ -276,8 +276,8 @@ static void _twin_composite_simple (twin_pixmap_t *dst,
twin_coord_t sdx, sdy;
twin_source_u s;
- dst_x += dst->clip.left;
- dst_y += dst->clip.top;
+ dst_x += dst->origin_x;
+ dst_y += dst->origin_y;
left = dst_x;
top = dst_y;
right = dst_x + width;
@@ -296,7 +296,10 @@ static void _twin_composite_simple (twin_pixmap_t *dst,
if (left >= right || top >= bottom)
return;
- if (src->source_kind != TWIN_PIXMAP)
+ if (src->source_kind == TWIN_PIXMAP) {
+ src_x += src->u.pixmap->origin_x;
+ src_y += src->u.pixmap->origin_y;
+ } else
s.c = src->u.argb;
sdx = src_x - dst_x;
@@ -307,7 +310,10 @@ static void _twin_composite_simple (twin_pixmap_t *dst,
twin_source_u m;
twin_coord_t mdx, mdy;
- if (msk->source_kind != TWIN_PIXMAP)
+ if (msk->source_kind == TWIN_PIXMAP) {
+ msk_x += msk->u.pixmap->origin_x;
+ msk_y += msk->u.pixmap->origin_y;
+ } else
m.c = msk->u.argb;
mdx = msk_x - dst_x;
@@ -533,8 +539,8 @@ static void _twin_composite_xform (twin_pixmap_t *dst,
twin_xform_t *sxform = NULL, *mxform = NULL;
twin_source_u s;
- dst_x += dst->clip.left;
- dst_y += dst->clip.top;
+ dst_x += dst->origin_x;
+ dst_y += dst->origin_y;
left = dst_x;
top = dst_y;
right = dst_x + width;
@@ -556,7 +562,9 @@ static void _twin_composite_xform (twin_pixmap_t *dst,
width = right - left;
height = bottom - top;
- if (src->source_kind == TWIN_PIXMAP) {
+ if (src->source_kind == TWIN_PIXMAP) {
+ src_x += src->u.pixmap->origin_x;
+ src_y += src->u.pixmap->origin_y;
sxform = twin_pixmap_init_xform(src->u.pixmap, left, width,
src_x, src_y);
if (sxform == NULL)
@@ -570,6 +578,8 @@ static void _twin_composite_xform (twin_pixmap_t *dst,
twin_source_u m;
if (msk->source_kind == TWIN_PIXMAP) {
+ msk_x += msk->u.pixmap->origin_x;
+ msk_y += msk->u.pixmap->origin_y;
mxform = twin_pixmap_init_xform(msk->u.pixmap, left, width,
msk_x, msk_y);
if (mxform == NULL)
@@ -660,11 +670,13 @@ twin_fill (twin_pixmap_t *dst,
twin_src_op op;
twin_source_u src;
twin_coord_t iy;
-
- left += dst->clip.left;
- right += dst->clip.left;
- top += dst->clip.top;
- bottom += dst->clip.top;
+
+ /* offset */
+ left += dst->origin_x;
+ top += dst->origin_y;
+ right += dst->origin_x;
+ bottom += dst->origin_y;
+
/* clip */
if (left < dst->clip.left)
left = dst->clip.left;
diff --git a/twin_pixmap.c b/twin_pixmap.c
index b390ad6..e056093 100644
--- a/twin_pixmap.c
+++ b/twin_pixmap.c
@@ -43,6 +43,7 @@ twin_pixmap_create (twin_format_t format,
pixmap->clip.left = pixmap->clip.top = 0;
pixmap->clip.right = pixmap->width;
pixmap->clip.bottom = pixmap->height;
+ pixmap->origin_x = pixmap->origin_y = 0;
pixmap->stride = stride;
pixmap->disable = 0;
pixmap->p.v = pixmap + 1;
@@ -71,6 +72,7 @@ twin_pixmap_create_const (twin_format_t format,
pixmap->clip.left = pixmap->clip.top = 0;
pixmap->clip.right = pixmap->width;
pixmap->clip.bottom = pixmap->height;
+ pixmap->origin_x = pixmap->origin_y = 0;
pixmap->stride = stride;
pixmap->disable = 0;
pixmap->p = pixels;
@@ -184,32 +186,90 @@ twin_pixmap_disable_update (twin_pixmap_t *pixmap)
}
void
+twin_pixmap_set_origin (twin_pixmap_t *pixmap,
+ twin_coord_t ox, twin_coord_t oy)
+{
+ pixmap->origin_x = ox;
+ pixmap->origin_y = oy;
+}
+
+void
+twin_pixmap_offset (twin_pixmap_t *pixmap,
+ twin_coord_t offx, twin_coord_t offy)
+{
+ pixmap->origin_x += offx;
+ pixmap->origin_y += offy;
+}
+
+void
+twin_pixmap_get_origin (twin_pixmap_t *pixmap,
+ twin_coord_t *ox, twin_coord_t *oy)
+{
+ *ox = pixmap->origin_x;
+ *oy = pixmap->origin_y;
+}
+
+void
+twin_pixmap_origin_to_clip (twin_pixmap_t *pixmap)
+{
+ pixmap->origin_x = pixmap->clip.left;
+ pixmap->origin_y = pixmap->clip.top;
+}
+
+void
twin_pixmap_clip (twin_pixmap_t *pixmap,
twin_coord_t left, twin_coord_t top,
twin_coord_t right, twin_coord_t bottom)
{
+ left += pixmap->origin_x;
+ right += pixmap->origin_x;
+ top += pixmap->origin_y;
+ bottom += pixmap->origin_y;
+
if (left > pixmap->clip.left) pixmap->clip.left = left;
if (top > pixmap->clip.top) pixmap->clip.top = top;
if (right < pixmap->clip.right) pixmap->clip.right = right;
if (bottom < pixmap->clip.bottom) pixmap->clip.bottom = bottom;
+
if (pixmap->clip.left >= pixmap->clip.right)
pixmap->clip.right = pixmap->clip.left = 0;
if (pixmap->clip.top >= pixmap->clip.bottom)
pixmap->clip.bottom = pixmap->clip.top = 0;
+
+ if (pixmap->clip.left < 0)
+ pixmap->clip.left = 0;
+ if (pixmap->clip.top < 0)
+ pixmap->clip.top = 0;
+ if (pixmap->clip.right > pixmap->width)
+ pixmap->clip.right = pixmap->width;
+ if (pixmap->clip.bottom > pixmap->height)
+ pixmap->clip.bottom = pixmap->height;
}
void
twin_pixmap_set_clip (twin_pixmap_t *pixmap, twin_rect_t clip)
{
twin_pixmap_clip (pixmap,
- clip.left + pixmap->clip.left,
- clip.top + pixmap->clip.top,
- clip.right + pixmap->clip.left,
- clip.bottom+ pixmap->clip.top);
+ clip.left, clip.top,
+ clip.right, clip.bottom);
+}
+
+
+twin_rect_t
+twin_pixmap_get_clip (twin_pixmap_t *pixmap)
+{
+ twin_rect_t clip = pixmap->clip;
+
+ clip.left -= pixmap->origin_x;
+ clip.right -= pixmap->origin_x;
+ clip.top -= pixmap->origin_y;
+ clip.bottom -= pixmap->origin_y;
+
+ return clip;
}
twin_rect_t
-twin_pixmap_current_clip (twin_pixmap_t *pixmap)
+twin_pixmap_save_clip (twin_pixmap_t *pixmap)
{
return pixmap->clip;
}
diff --git a/twin_poly.c b/twin_poly.c
index 16c2b1f..71e5578 100644
--- a/twin_poly.c
+++ b/twin_poly.c
@@ -206,8 +206,8 @@ _span_fill (twin_pixmap_t *pixmap,
if (left < twin_int_to_sfixed (pixmap->clip.left))
left = twin_int_to_sfixed (pixmap->clip.left);
- if (right > twin_int_to_sfixed (pixmap->width))
- right = twin_int_to_sfixed (pixmap->width);
+ if (right > twin_int_to_sfixed (pixmap->clip.right))
+ right = twin_int_to_sfixed (pixmap->clip.right);
/* convert to sample grid */
left = _twin_sfixed_grid_ceil (left) >> TWIN_POLY_FIXED_SHIFT;
@@ -353,15 +353,13 @@ twin_fill_path (twin_pixmap_t *pixmap, twin_path_t *path,
int nalloc;
int s;
int p;
- twin_sfixed_t sdx = twin_int_to_sfixed (dx);
- twin_sfixed_t sdy = twin_int_to_sfixed (dy);
+ twin_sfixed_t sdx = twin_int_to_sfixed (dx + pixmap->origin_x);
+ twin_sfixed_t sdy = twin_int_to_sfixed (dy + pixmap->origin_y);
nalloc = path->npoints + path->nsublen + 1;
edges = malloc (sizeof (twin_edge_t) * nalloc);
p = 0;
nedges = 0;
- dx += twin_int_to_sfixed (pixmap->clip.left);
- dy += twin_int_to_sfixed (pixmap->clip.top);
for (s = 0; s <= path->nsublen; s++)
{
int sublen;
@@ -375,7 +373,8 @@ twin_fill_path (twin_pixmap_t *pixmap, twin_path_t *path,
if (npoints > 1)
{
n = _twin_edge_build (path->points + p, npoints, edges + nedges,
- sdx, sdy, twin_int_to_sfixed (pixmap->clip.top));
+ sdx, sdy,
+ twin_int_to_sfixed (pixmap->clip.top));
p = sublen;
nedges += n;
}
diff --git a/twin_window.c b/twin_window.c
index d4c69c7..ff2862f 100644
--- a/twin_window.c
+++ b/twin_window.c
@@ -70,6 +70,7 @@ twin_window_create (twin_screen_t *screen,
twin_pixmap_clip (window->pixmap,
window->client.left, window->client.top,
window->client.right, window->client.bottom);
+ twin_pixmap_origin_to_clip (window->pixmap);
window->pixmap->window = window;
twin_pixmap_move (window->pixmap, x, y);
window->damage.left = window->damage.right = 0;
@@ -136,9 +137,11 @@ twin_window_configure (twin_window_t *window,
for (i = 0; i < old->disable; i++)
twin_pixmap_disable_update (window->pixmap);
twin_pixmap_destroy (old);
+ twin_pixmap_reset_clip (window->pixmap);
twin_pixmap_clip (window->pixmap,
window->client.left, window->client.top,
window->client.right, window->client.bottom);
+ twin_pixmap_origin_to_clip (window->pixmap);
}
if (x != window->pixmap->x || y != window->pixmap->y)
twin_pixmap_move (window->pixmap, x, y);
@@ -207,6 +210,7 @@ twin_window_frame (twin_window_t *window)
const char *name;
twin_pixmap_reset_clip (pixmap);
+ twin_pixmap_origin_to_clip (pixmap);
twin_fill (pixmap, 0x00000000, TWIN_SOURCE,
0, 0, pixmap->width, window->client.top);
@@ -264,12 +268,14 @@ twin_window_frame (twin_window_t *window)
0,
twin_fixed_to_int (twin_fixed_ceil (c_right - t_arc_2)),
window->client.top);
-
+ twin_pixmap_origin_to_clip (pixmap);
+
twin_path_move (path, text_x - twin_fixed_floor (menu_x), text_y);
twin_path_utf8 (path, window->name);
twin_paint_path (pixmap, TWIN_FRAME_TEXT, path);
twin_pixmap_reset_clip (pixmap);
+ twin_pixmap_origin_to_clip (pixmap);
/* widgets */
@@ -307,12 +313,16 @@ twin_window_frame (twin_window_t *window)
twin_pixmap_clip (pixmap,
window->client.left, window->client.top,
window->client.right, window->client.bottom);
+ twin_pixmap_origin_to_clip (pixmap);
+
twin_path_destroy (path);
}
void
twin_window_draw (twin_window_t *window)
{
+ twin_pixmap_t *pixmap = window->pixmap;
+
switch (window->style) {
case TwinWindowPlain:
default: