Fix copying of overlapping bitmaps. The cases of copying within the

screen bitmap and within a single MEMBUF were broken when first source
line is before the first destination line and the sub-bitmaps overlap.

The fix just copies horizontal lines in reverse order when the first
source line is before the first destination line.  This switches
directions unnecessarily in some cases, but the switch is about as
fast as doing a precise detection of overlaps.  When the first lines
are the same, there can be undetected overlap in the horizontal
direction.  The old code already handles this mostly accidentally by
using bcopy() for MEMBUFs and by copying through a temporary buffer
for the screen bitmap although the latter is sub-optimal in direct
modes.
This commit is contained in:
Bruce Evans 2019-04-19 20:29:49 +00:00
parent bd48a01043
commit 1e4abf1d4c
Notes: svn2git 2020-12-20 02:59:44 +00:00
svn path=/head/; revision=346416

View File

@ -269,7 +269,7 @@ int
__VGLBitmapCopy(VGLBitmap *src, int srcx, int srcy,
VGLBitmap *dst, int dstx, int dsty, int width, int hight)
{
int srcline, dstline;
int srcline, dstline, yend, yextra, ystep;
if (srcx>src->VXsize || srcy>src->VYsize
|| dstx>dst->VXsize || dsty>dst->VYsize)
@ -296,8 +296,17 @@ __VGLBitmapCopy(VGLBitmap *src, int srcx, int srcy,
hight=dst->VYsize-dsty;
if (width < 0 || hight < 0)
return -1;
yend = srcy + hight;
yextra = 0;
ystep = 1;
if (src->Bitmap == dst->Bitmap && srcy < dsty) {
yend = srcy;
yextra = hight - 1;
ystep = -1;
}
if (src->Type == MEMBUF) {
for (srcline=srcy, dstline=dsty; srcline<srcy+hight; srcline++, dstline++) {
for (srcline = srcy + yextra, dstline = dsty + yextra; srcline != yend;
srcline += ystep, dstline += ystep) {
WriteVerticalLine(dst, dstx, dstline, width,
src->Bitmap+(srcline*src->VXsize+srcx)*dst->PixelBytes);
}
@ -319,7 +328,8 @@ __VGLBitmapCopy(VGLBitmap *src, int srcx, int srcy,
} else {
p = buffer;
}
for (srcline=srcy, dstline=dsty; srcline<srcy+hight; srcline++, dstline++) {
for (srcline = srcy + yextra, dstline = dsty + yextra; srcline != yend;
srcline += ystep, dstline += ystep) {
ReadVerticalLine(src, srcx, srcline, width, p);
WriteVerticalLine(dst, dstx, dstline, width, p);
}