PATCH: PatBlt() with negative width or height draws in wrong
place
Adam Gundy
arg at cyberscience.com
Wed Mar 5 08:50:24 CST 2003
Hi. PatBlt() seems to behave differently with negative widths and height
to StretchBlt() - it does not invert the pattern etc. This caused 'lines'
drawn so that their ends touched (and appeared to be a single line) to have
gaps in them. Fixing this to behave like 'real' Windows caused the drawing
of window borders to break - they were (incorrectly) being drawn with negative
widths and heights.
Cyberscience disclaims all copyright and responsibility... ;-)
Changelog:
* graphics/x11drv/bitblt.c: Adam Gundy <arg at cyberscience.com>
BITBLT_InternalStretchBlt() was adding 1 to the source or
destination if the widths or heights were negative.
This doesn't seem to match the way Windows behaves for operations
without a source - it appears to re-order the points so that the
width/height are positive. Code in graphics.c already does this
re-ordering. Fixing this shows up a problem in window border drawing
(see changelog entry for windows/nonclient.c below).
* windows/nonclient.c: Adam Gundy <arg at cyberscience.com>
NC_DrawFrame95() was passing negative widths and heights
to PatBlt() for the right and bottom edges of the frame,
causing them to draw in the wrong place. This was masked by
the above bug in the X11 driver.
diff -u -r wine-20030219/graphics/x11drv/bitblt.c wine-20030219-new/graphics/x11drv/bitblt.c
--- wine-20030219/graphics/x11drv/bitblt.c Thu Jan 9 05:59:47 2003
+++ wine-20030219-new/graphics/x11drv/bitblt.c Wed Mar 5 14:42:34 2003
@@ -1228,16 +1228,6 @@
DC *dcSrc = physDevSrc ? physDevSrc->dc : NULL;
DC *dcDst = physDevDst->dc;
- /* compensate for off-by-one shifting for negative widths and heights */
- if (widthDst < 0)
- ++xDst;
- if (heightDst < 0)
- ++yDst;
- if (widthSrc < 0)
- ++xSrc;
- if (heightSrc < 0)
- ++ySrc;
-
usePat = (((rop >> 4) & 0x0f0000) != (rop & 0x0f0000));
useSrc = (((rop >> 2) & 0x330000) != (rop & 0x330000));
useDst = (((rop >> 1) & 0x550000) != (rop & 0x550000));
@@ -1245,11 +1235,36 @@
/* Map the coordinates to device coords */
+ if ( useSrc )
+ {
+ /* compensate for off-by-one shifting for negative widths and heights */
+ if (widthDst < 0)
+ ++xDst;
+ if (heightDst < 0)
+ ++yDst;
+ if (widthSrc < 0)
+ ++xSrc;
+ if (heightSrc < 0)
+ ++ySrc;
+ }
+
pts[0].x = xDst;
pts[0].y = yDst;
pts[1].x = xDst + widthDst;
pts[1].y = yDst + heightDst;
LPtoDP(physDevDst->hdc, pts, 2);
+
+ if ((pts[0].x == pts[1].x) || (pts[0].y == pts[1].y)) return TRUE;
+
+ if ( !useSrc )
+ {
+ /* OPs without a source use absolute width and height - make
+ * sure the width and height are positive
+ */
+ if (pts[1].x < pts[0].x) { INT tmp = pts[1].x; pts[1].x = pts[0].x; pts[0].x = tmp; }
+ if (pts[1].y < pts[0].y) { INT tmp = pts[1].y; pts[1].y = pts[0].y; pts[0].y = tmp; }
+ }
+
xDst = pts[0].x;
yDst = pts[0].y;
widthDst = pts[1].x - pts[0].x;
@@ -1271,6 +1286,7 @@
pts[1].x = xSrc + widthSrc;
pts[1].y = ySrc + heightSrc;
LPtoDP(physDevSrc->hdc, pts, 2);
+
xSrc = pts[0].x;
ySrc = pts[0].y;
widthSrc = pts[1].x - pts[0].x;
diff -u -r wine-20030219/windows/nonclient.c wine-20030219-new/windows/nonclient.c
--- wine-20030219/windows/nonclient.c Tue Feb 18 23:24:57 2003
+++ wine-20030219-new/windows/nonclient.c Wed Mar 5 10:30:27 2003
@@ -1188,9 +1188,9 @@
PatBlt( hdc, rect->left, rect->top,
width, rect->bottom - rect->top, PATCOPY );
PatBlt( hdc, rect->left, rect->bottom - 1,
- rect->right - rect->left, -height, PATCOPY );
+ rect->right - rect->left, height, PATCOPY );
PatBlt( hdc, rect->right - 1, rect->top,
- -width, rect->bottom - rect->top, PATCOPY );
+ width, rect->bottom - rect->top, PATCOPY );
InflateRect( rect, -width, -height );
}
@@ -1219,9 +1219,9 @@
PatBlt( hdc, rect->left, rect->top,
width, rect->bottom - rect->top, PATCOPY );
PatBlt( hdc, rect->left, rect->bottom - 1,
- rect->right - rect->left, -height, PATCOPY );
+ rect->right - rect->left, height, PATCOPY );
PatBlt( hdc, rect->right - 1, rect->top,
- -width, rect->bottom - rect->top, PATCOPY );
+ width, rect->bottom - rect->top, PATCOPY );
InflateRect( rect, -width, -height );
}
Seeya,
Adam
--
Real Programmers don't comment their code. If it was hard to write,
it should be hard to read, and even harder to modify.
These are all my own opinions.
More information about the wine-patches
mailing list