> My guess is, that the dirty region tracking code gets messed up by
> the Hline.
Confirmed the GGI_X_CLEAN-Macro contains a bug (I think, it is pretty
had to understand) Diff attached, please validate before I commit.
Rationale for the changes:
Old code was:
#define GGI_X_CLEAN(vis, _x, _y, _w, _h) do { \
if (priv->dirtytl.x >= _x && priv->dirtybr.x <= _x + _w-1) { \
### If the to be cleaned region is at least as wide as the dirty region,
### it can possibly be used to clip the region down.
if (priv->dirtytl.y >= _y && priv->dirtybr.y <= _y + _h-1) { \
### If it completely conceals the dirty region, turn off the dirty region.
### further processing can be stopped here.
priv->dirtytl.x = 1; priv->dirtybr.x = 0; break; } \
if ((priv->dirtybr.y < _y) || (priv->dirtytl.y > _y + _h-1)) break; \
### If the region is completely outside of the dirty region (i.e. starts
### below it or stops above it, nothing happens. Stop processing.
if ((priv->dirtybr.y < _y + _h-1) && (priv->dirtytl.y > _y)) break; \
### Now here is the first bug. I think this is supposed to check, if
### the cleaned reagion is completely within the dirty region, in which
### case nothing can be done (it would split the region in two
### However it does check, that the cleaned region contains the dirty
### one. Correct code would IMHO be:
++if ((priv->dirtybr.y > _y + _h-1) && (priv->dirtytl.y < _y)) break; \
### Mind the reversed comparisions.
if (priv->dirtytl.y < _y) priv->dirtybr.y = _y; \
### Now we want o check, if it overlaps at the top or the bottom.
### This is inaccurate IMHO. The line y is cleared, so we can set y-1.
++if (priv->dirtytl.y < _y) priv->dirtybr.y = _y-1;
if (priv->dirtybr.y > _y + _h-1) priv->dirtytl.y = _y + _h-1; \
### Same here. y+h-1 is the last line that is cleaned, so we can start
### one line below, i.e.
++if (priv->dirtybr.y > _y + _h-1) priv->dirtytl.y = _y + _h;
break; \
### is redundant here. We are in while(0), so we will autobreak anyway.
} else if (priv->dirtytl.x >= _x && priv->dirtybr.x <= _x + _w-1) { \
### Uh - ouch. Next bug I think. I suppose this section is supposed
### to check the same but snipping off at left and right. For that to
### work, we should check the y parameters. I.e.
++ } else if (priv->dirtytl.y >= _y && priv->dirtybr.y <= _y + _h-1) { \
if (priv->dirtytl.x >= _x && priv->dirtybr.x <= _x + _w-1) { \
priv->dirtytl.x = 1; priv->dirtybr.x = 0; break; } \
### This is redundant, as the check in the area above would have catched it.
if ((priv->dirtybr.x < _x) || (priv->dirtytl.x > _x + _w-1)) break; \
### Check cleans left/right of dirty region.
if ((priv->dirtybr.x < _x + _w-1) && (priv->dirtytl.x > _x)) break; \
# Check for completely contained region. Wrong like above.
++if ((priv->dirtybr.x > _x + _w-1) && (priv->dirtytl.x < _x)) break;
if (priv->dirtytl.x < _x) priv->dirtybr.x = _x; \
if (priv->dirtybr.x > _x + _w-1) priv->dirtytl.x = _x + _w-1; \
# Comments like above leading to
++if (priv->dirtytl.x < _x) priv->dirtybr.x = _x-1; \
++if (priv->dirtybr.x > _x + _w-1) priv->dirtytl.x = _x + _w; \
break; \
# redundant.
}} while (0)
I spent quite a while thinking this code through, and suppose I got it
right. I am not quite sure about the last two ifs in each chain. I think one
could use greater/less-or-equal in the comparisions as well, thus correctly
handling regions that just touch the borders.
I have tested these changes with my application, and it fixes the problems
I reported.
Could you please go over the code and my comments and have a look, if the
fix is right? That stuff is pretty complex to think into, so I am not
absolutely positive I didn't mis anything.
If a few people confirm my thought, I will commit.
CU, Andy
--
= Andreas Beck | Email : <[EMAIL PROTECTED]> =
? bla
Index: include/ggi/display/x.h
===================================================================
RCS file: /cvsroot/ggi/ggi-core/libggi/include/ggi/display/x.h,v
retrieving revision 1.3
diff -u -r1.3 x.h
--- include/ggi/display/x.h 12 Jun 2002 03:53:59 -0000 1.3
+++ include/ggi/display/x.h 14 Dec 2002 15:01:25 -0000
@@ -208,18 +208,14 @@
if (priv->dirtytl.y >= _y && priv->dirtybr.y <= _y + _h-1) { \
priv->dirtytl.x = 1; priv->dirtybr.x = 0; break; } \
if ((priv->dirtybr.y < _y) || (priv->dirtytl.y > _y + _h-1)) break; \
- if ((priv->dirtybr.y < _y + _h-1) && (priv->dirtytl.y > _y)) break; \
- if (priv->dirtytl.y < _y) priv->dirtybr.y = _y; \
- if (priv->dirtybr.y > _y + _h-1) priv->dirtytl.y = _y + _h-1; \
- break; \
-} else if (priv->dirtytl.x >= _x && priv->dirtybr.x <= _x + _w-1) { \
- if (priv->dirtytl.x >= _x && priv->dirtybr.x <= _x + _w-1) { \
- priv->dirtytl.x = 1; priv->dirtybr.x = 0; break; } \
+ if ((priv->dirtybr.y > _y + _h-1) && (priv->dirtytl.y < _y)) break; \
+ if (priv->dirtytl.y < _y) priv->dirtybr.y = _y-1; \
+ if (priv->dirtybr.y > _y + _h-1) priv->dirtytl.y = _y + _h; \
+} else if (priv->dirtytl.y >= _y && priv->dirtybr.y <= _y + _h-1) { \
if ((priv->dirtybr.x < _x) || (priv->dirtytl.x > _x + _w-1)) break; \
- if ((priv->dirtybr.x < _x + _w-1) && (priv->dirtytl.x > _x)) break; \
- if (priv->dirtytl.x < _x) priv->dirtybr.x = _x; \
- if (priv->dirtybr.x > _x + _w-1) priv->dirtytl.x = _x + _w-1; \
- break; \
+ if ((priv->dirtybr.x > _x + _w-1) && (priv->dirtytl.x < _x)) break; \
+ if (priv->dirtytl.x < _x) priv->dirtybr.x = _x-1; \
+ if (priv->dirtybr.x > _x + _w-1) priv->dirtytl.x = _x + _w; \
}} while (0)
#define GGI_X_SYNC(_vis) XFlush(GGIX_PRIV(_vis)->disp);
#define GGI_X_MAYBE_SYNC(_vis) \