diff --git a/headers/private/servers/app/DisplayDriver.h b/headers/private/servers/app/DisplayDriver.h index 381e3c9e69..e531dd5a73 100644 --- a/headers/private/servers/app/DisplayDriver.h +++ b/headers/private/servers/app/DisplayDriver.h @@ -115,12 +115,9 @@ class DisplayDriver { virtual void Shutdown(); // Graphics calls implemented in DisplayDriver - virtual void CopyBits( const BRect &src, - const BRect &dest, - const DrawData *d) = 0; - - virtual void CopyRegion( BRegion *src, - const BPoint &lefttop) = 0; + virtual void CopyRegion( /*const*/ BRegion* region, + int32 xOffset, + int32 yOffset) = 0; virtual void CopyRegionList( BList* list, BList* pList, diff --git a/src/servers/app/ServerWindow.cpp b/src/servers/app/ServerWindow.cpp index 200cd5d96e..15e0ed1700 100644 --- a/src/servers/app/ServerWindow.cpp +++ b/src/servers/app/ServerWindow.cpp @@ -522,49 +522,57 @@ void ServerWindow::DispatchMessage(int32 code, LinkMsgReader &link) } case AS_LAYER_COPY_BITS: { - BRect src; - BRect dest; - - link.Read(&src); - link.Read(&dest); - // NOTE: The correct behaviour is this: // * The region that is copied is the // src rectangle, no matter if it fits - // into the dest rectangle. It is copied - // by the offset dest.LeftTop() - src.LeftTop() - // * The dest rectangle is used for invalidation: - // Any area in the dest rectangle that could + // into the dst rectangle. It is copied + // by the offset dst.LeftTop() - src.LeftTop() + // * The dst rectangle is used for invalidation: + // Any area in the dst rectangle that could // not be copied from src (because either the // src rectangle was not big enough, or because there // were parts cut off by the current layer clipping), // are triggering BView::Draw() to be called // and for these parts only. - // TODO: The DisplayDriver::CopyBits() call needs - // to get a BRegion and an offset by which to copy - // all the rects in that region. The region is calculated as - // * The src rectangle minus the currect clipping of the layer - // * minus the part of the region that is outside the layer - // when the region is translated by the offset! - // Then, an invalidation needs to be triggered for the - // following region: the dest rectangle minus the - // region we calculated in step one translated by the - // offset. - // By implementing it this way, we don't mix the update - // triggering with the actual graphical operation in - // DisplayDriver. I know that normally DisplayDriver takes - // care of the clipping, but this is different, because - // CopyBits() is the only drawing call that can trigger - // invalidation. - // TODO: In DisplayDriver, implement the described CopyBits() - // version. Also, the current implementation is wrong because it - // clips the source rectangle to the dest rectangle. + BRect src; + BRect dst; + + link.Read(&src); + link.Read(&dst); + + // TODO: Are origin and scale handled in this conversion? src = cl->ConvertToTop(src); - dest = cl->ConvertToTop(dest); + dst = cl->ConvertToTop(dst); + + int32 xOffset = (int32)(dst.left - src.left); + int32 yOffset = (int32)(dst.top - src.top); + + // the region that is going to be copied + BRegion copyRegion(src); + // apply the current clipping of the layer + copyRegion.IntersectWith(&cl->fVisible); + + // offset the region to the destination + // and apply the current clipping there as well + copyRegion.OffsetBy(xOffset, yOffset); + copyRegion.IntersectWith(&cl->fVisible); + + // the region at the destination that needs invalidation + BRegion invalidRegion(dst); + // exclude the region drawn by the copy operation + invalidRegion.Exclude(©Region); + // apply the current clipping as well + invalidRegion.IntersectWith(&cl->fVisible); + + // move the region back for the actual operation + copyRegion.OffsetBy(-xOffset, -yOffset); + + cl->fDriver->CopyRegion(©Region, xOffset, yOffset); + + // trigger the redraw + myRootLayer->GoRedraw(fWinBorder, invalidRegion); - cl->fDriver->CopyBits(src, dest, cl->fLayerData); - break; } case AS_SET_CURRENT_LAYER: diff --git a/src/servers/app/drawing/DisplayDriverPainter.cpp b/src/servers/app/drawing/DisplayDriverPainter.cpp index 1d736c7162..dfaf35bef6 100644 --- a/src/servers/app/drawing/DisplayDriverPainter.cpp +++ b/src/servers/app/drawing/DisplayDriverPainter.cpp @@ -26,6 +26,7 @@ //------------------------------------------------------------------------------ #include #include +#include #include "LayerData.h" #include "Painter.h" @@ -46,11 +47,6 @@ #include "DisplayDriverPainter.h" -// TODO: fix invalidation, what about pensize, scale, origin? -// Painter calls could return the bounding box arround all -// pixels touched by a drawing operation - - // constructor DisplayDriverPainter::DisplayDriverPainter() : DisplayDriver(), @@ -88,55 +84,229 @@ DisplayDriverPainter::Shutdown() DisplayDriver::Shutdown(); } -// CopyBits +// CopyRegion() does a topological sort of the rects in the +// region. The algorithm was suggested by Ingo Weinhold. +// It compares each rect with each rect and builds a tree +// of successors so we know the order in which they can be copied. +// For example, let's suppose these rects are in a BRegion: +// ************ +// * B * +// ************ +// ************* +// * * +// * A **************** +// * ** * +// ************** * +// * C * +// * * +// * * +// *************** +// When copying stuff from LEFT TO RIGHT, TOP TO BOTTOM, the +// result of the sort will be C, A, B. For this direction, we search +// for the rects that have no neighbors to their right and to their +// bottom, These can be copied without drawing into the area of +// rects yet to be copied. If you move from RIGHT TO LEFT, BOTTOM TO TOP, +// you go look for the ones that have no neighbors to their top and left. +// +// Here I draw some rays to illustrate LEFT TO RIGHT, TOP TO BOTTOM: +// ************ +// * B * +// ************ +// ************* +// * * +// * A ****************----------------- +// * ** * +// ************** * +// * C * +// * * +// * * +// *************** +// | +// | +// | +// | +// There are no rects in the area defined by the rays to the right +// and bottom of rect C, so that's the one we want to copy first +// (for positive x and y offsets). +// Since A is to the left of C and B is to the top of C, The "node" +// for C will point to the nodes of A and B as its "successors". Therefor, +// A and B will have an "indegree" of 1 for C pointing to them. C will +// have and "indegree" of 0, because there was no rect to which C +// was to the left or top of. When comparing A and B, neither is left +// or top from the other and in the sense that the algorithm cares about. + +// NOTE: comparisson of coordinates assumes that rects don't overlap +// and don't share the actual edge either (as is the case in BRegions). + +struct node { + node() + { + pointers = NULL; + } + node(const BRect& r, int32 maxPointers) + { + init(r, maxPointers); + } + ~node() + { + delete [] pointers; + } + + void init(const BRect& r, int32 maxPointers) + { + rect = r; + pointers = new node*[maxPointers]; + in_degree = 0; + next_pointer = 0; + } + + void push(node* node) + { + pointers[next_pointer] = node; + next_pointer++; + } + node* top() + { + return pointers[next_pointer]; + } + node* pop() + { + node* ret = top(); + next_pointer--; + return ret; + } + + BRect rect; + int32 in_degree; + node** pointers; + int32 next_pointer; +}; + +bool +is_left_of(const BRect& a, const BRect& b) +{ + return (a.right < b.left); +} +bool +is_above(const BRect& a, const BRect& b) +{ + return (a.bottom < b.top); +} + +// CopyRegion void -DisplayDriverPainter::CopyBits(const BRect &src, const BRect &dst, - const DrawData *d) +DisplayDriverPainter::CopyRegion(/*const*/ BRegion* region, + int32 xOffset, int32 yOffset) { if (Lock()) { - // TODO: handle clipping to d->clipreg here? + int32 count = region->CountRects(); - RenderingBuffer* backBuffer = fGraphicsCard->DrawingBuffer(); + // TODO: make this step unnecessary + // (by using different stack impl inside node) + node nodes[count]; + for (int32 i= 0; i < count; i++) { + nodes[i].init(region->RectAt(i), count); + } - BRect valid(0, 0, backBuffer->Width() - 1, backBuffer->Height() - 1); - if (valid.Intersects(src) && valid.Intersects(dst)) { + for (int32 i = 0; i < count; i++) { + BRect a = region->RectAt(i); + for (int32 k = i + 1; k < count; k++) { + BRect b = region->RectAt(k); + int cmp = 0; + // compare horizontally + if (xOffset > 0) { + if (is_left_of(a, b)) { + cmp -= 1; + } else if (is_left_of(b, a)) { + cmp += 1; + } + } else if (xOffset < 0) { + if (is_left_of(a, b)) { + cmp += 1; + } else if (is_left_of(b, a)) { + cmp -= 1; + } + } + // compare vertically + if (yOffset > 0) { + if (is_above(a, b)) { + cmp -= 1; + } else if (is_above(b, a)) { + cmp += 1; + } + } else if (yOffset < 0) { + if (is_above(a, b)) { + cmp += 1; + } else if (is_above(b, a)) { + cmp -= 1; + } + } + // add appropriate node as successor + if (cmp > 0) { + nodes[i].push(&nodes[k]); + nodes[k].in_degree++; + } else if (cmp < 0) { + nodes[k].push(&nodes[i]); + nodes[i].in_degree++; + } + } + } + // put all nodes onto a stack that have an "indegree" count of zero + stack inDegreeZeroNodes; + for (int32 i = 0; i < count; i++) { + if (nodes[i].in_degree == 0) { + inDegreeZeroNodes.push(&nodes[i]); + } + } + // pop the rects from the stack, do the actual copy operation + // and decrease the "indegree" count of the other rects not + // currently on the stack and to which the current rect pointed + // to. If their "indegree" count reaches zero, put them onto the + // stack as well. + while (!inDegreeZeroNodes.empty()) { + node* n = inDegreeZeroNodes.top(); + inDegreeZeroNodes.pop(); - // calculate offset before any clipping - int32 xOffset = (int32)(dst.left - src.left); - int32 yOffset = (int32)(dst.top - src.top); + BRect touched = _CopyRect(n->rect, xOffset, yOffset); + fGraphicsCard->Invalidate(touched); - // clip src and dest - BRect a = src & valid; - BRect b = dst & valid; - a = a & b.OffsetByCopy(BPoint(-xOffset, -yOffset)); - b = b & a.OffsetByCopy(BPoint(xOffset, yOffset)); - - uint8* bits = (uint8*)backBuffer->Bits(); - uint32 bpr = backBuffer->BytesPerRow(); - - uint32 width = a.IntegerWidth() + 1; - uint32 height = a.IntegerHeight() + 1; - - int32 left = (int32)a.left; - int32 top = (int32)a.top; - - // offset to left top of src rect - bits += top * bpr + left * 4; - - _MoveRect(bits, width, height, bpr, xOffset, yOffset); - - fGraphicsCard->Invalidate(dst); + for (int32 k = 0; k < n->next_pointer; k++) { + n->pointers[k]->in_degree--; + if (n->pointers[k]->in_degree == 0) + inDegreeZeroNodes.push(n->pointers[k]); + } } Unlock(); } } -// CopyRegion +// CopyRegionList +// +// * used to move windows arround on screen +// TODO: Since the regions are passed to CopyRegion() one by one, +// the case of different regions overlapping each other at source +// and/or dest locations is not handled. +// We also don't handle the case where multiple regions should have +// been combined into one larger region (with effectively the same +// rects), so that the sorting would compare them all at once. If +// this turns out to be a problem, we can easily rewrite the function +// here. In any case, to copy overlapping regions in app_server doesn't +// make much sense to me. void -DisplayDriverPainter::CopyRegion(BRegion *src, const BPoint &lefttop) +DisplayDriverPainter::CopyRegionList(BList* list, BList* pList, + int32 rCount, BRegion* clipReg) { -printf("DisplayDriverPainter::CopyRegion()\n"); + if (Lock()) { + + for (int32 i = 0; i < rCount; i++) { + BRegion* region = (BRegion*)list->ItemAt(i); + BPoint* offset = (BPoint*)pList->ItemAt(i); + CopyRegion(region, (int32)offset->x, (int32)offset->y); + } + + Unlock(); + } } // InvertRect @@ -174,299 +344,6 @@ DisplayDriverPainter::DrawBitmap(BRegion *region, ServerBitmap *bitmap, } } -/* -inline int -compare_left_right_top_bottom(BRect* a, BRect* b) -{ - if (b->right < a->left || b->bottom < a->top) - return 1; - else - return -1; - return 0; -} - -inline int -compare_right_left_top_bottom(BRect* a, BRect* b) -{ - if (b->right > a->left || b->bottom < a->top) - return 1; - else - return -1; - return 0; -} - -inline int -compare_left_right_bottom_top(BRect* a, BRect* b) -{ - if (b->right < a->left || b->bottom > a->top) - return 1; - else - return -1; - return 0; -} - -inline int -compare_right_left_bottom_top(BRect* a, BRect* b) -{ - if (b->right > a->left || b->bottom > a->top) - return 1; - else - return -1; - return 0; -} -*/ - -// TODO: the commented out code is completely broken -// what needs to be done is a topological sort of the rectangles -// in a given BRegion. -// For example, let's suppose these rects are in a BRegion: -// ************ -// * B * -// ************* ************ -// * * -// * A *************** -// * * * -// ************* * -// * C * -// * * -// * * -// *************** -// When moving stuff from LEFT TO RIGHT, TOP TO BOTTOM, the -// result of the sort should be C, B, A, ie, you take an unsorted -// list of rects, and you go look for the one that has no neighbors -// to the right and to the bottom, that's the first one you want -// to move. If you move from RIGHT TO LEFT, BOTTOM TO TOP, you -// go look for the one that has no neighbors to the top and left. -// -// Here I draw some rays to illustrate LEFT TO RIGHT, TOP TO BOTTOM: -// ************ -// * B * -// ************* ************ -// * * -// * A ***************----------------- -// * * * -// ************* * -// * C * -// * * -// * * -// *************** -// | -// | -// | -// | -// There are no rects in the area defined by the rays to the right -// and bottom of rect C, so that's the one we want to copy first -// (for positive x and y offsets). If the sorting of rects can -// be implemented, the speed-up of the CopyRegionList() function -// will be about 300% (I tested that) with "in-place" copying. -// -// Of course, the usage of the funcion is completely obscure to me. -// First of all, why is there a list of points? I checked and it -// is indeed always the same point (the same offset used for all rects). -// Second, if the Regions provided in the list somehow overlap, then -// an in-place copy cannot be performed, so this all makes no sense. -// However during my tests, the usage of the function -// (from Layer::move_to() btw) was only with a *single* BRegion in -// the list. Which makes most sense, but it doesn't make sense to pass -// a BList then. - -// used to move windows arround on screen -// -// CopyRegionList -void -DisplayDriverPainter::CopyRegionList(BList* list, BList* pList, - int32 rCount, BRegion* clipReg) -{ - if (!clipReg || !Lock()) - return; -/* -// This is the same implementation as in DisplayDriverImpl for now - -// since we're not using painter.... this won't do much good, will it? -// fPainter->ConstrainClipping(*clipReg); -//bigtime_t now = system_time(); - - BRect updateRect; - - RenderingBuffer* backBuffer = fGraphicsCard->DrawingBuffer(); - - uint8* bits = (uint8*)backBuffer->Bits(); - uint32 bpr = backBuffer->BytesPerRow(); - - // TODO: it's always the same point, no? - BPoint offset = *((BPoint*)pList->ItemAt(0)); - - // iterate over regions (and points) - for (int32 i = 0; i < rCount; i++) { - BRegion* region = (BRegion*)list->ItemAt(i); - - // copy rects into a list - int32 rectCount = region->CountRects(); - BList rects(rectCount); - for (int32 j = 0; j < rectCount; j++) { - BRect* r = new BRect(region->RectAt(j)); - rects.AddItem((void*)r); - } - // sort the rects according to offset - BRect** first = (BRect**)rects.Items(); - BRect** behindLast = (BRect**)rects.Items() + rects.CountItems(); - - int32 xOffset = (int32)offset.x; - int32 yOffset = (int32)offset.y; - - if (xOffset >= 0) { - if (yOffset >= 0) - sort(first, behindLast, compare_left_right_top_bottom); - else - sort(first, behindLast, compare_left_right_bottom_top); - } else { - if (yOffset >= 0) - sort(first, behindLast, compare_right_left_top_bottom); - else - sort(first, behindLast, compare_right_left_bottom_top); - } - - - // iterate over rects in region - for (int32 j = 0; j < rectCount; j++) { - BRect* r = (BRect*)rects.ItemAt(j); - - uint32 width = r->IntegerWidth() + 1; - uint32 height = r->IntegerHeight() + 1; - - int32 left = (int32)r->left; - int32 top = (int32)r->top; - -// TODO: out of bounds checking! -// BPoint offset = *((BPoint*)pList->ItemAt(j % rCount)); - // keep track of dirty rect - r->OffsetBy(offset); - updateRect = updateRect.IsValid() ? updateRect | *r : *r; - -printf("region: %ld, rect: %ld, offset(%ld, %ld)\n", i, j, xOffset, yOffset); - - // offset to left top of src rect - uint8* src = bits + top * bpr + left * 4; - - _MoveRect(src, width, height, bpr, xOffset, yOffset); - - delete r; - } - } - -*/ - RenderingBuffer* bmp = fGraphicsCard->DrawingBuffer(); - - uint32 bytesPerPixel = bmp->BytesPerRow() / bmp->Width(); - BList rectList; - int32 i, k; - uint8 *bitmapBits = (uint8*)bmp->Bits(); - int32 Bwidth = bmp->Width(); - int32 Bheight = bmp->Height(); - - BRect updateRect; - - for (k = 0; k < rCount; k++) { - BRegion* reg = (BRegion*)list->ItemAt(k); - - int32 rectCount = reg->CountRects(); - for(i=0; i < rectCount; i++) { - BRect r = reg->RectAt(i); - uint8 *rectCopy; - uint8 *srcAddress; - uint8 *destAddress; - int32 firstRow, lastRow; - int32 firstCol, lastCol; - int32 copyLength; - int32 copyRows; - - firstRow = (int32)(r.top < 0? 0: r.top); - lastRow = (int32)(r.bottom > (Bheight-1)? (Bheight-1): r.bottom); - firstCol = (int32)(r.left < 0? 0: r.left); - lastCol = (int32)(r.right > (Bwidth-1)? (Bwidth-1): r.right); - copyLength = (lastCol - firstCol + 1) < 0? 0: (lastCol - firstCol + 1); - copyRows = (lastRow - firstRow + 1) < 0? 0: (lastRow - firstRow + 1); - - rectCopy = (uint8*)malloc(copyLength * copyRows * bytesPerPixel); - - srcAddress = bitmapBits + (((firstRow) * Bwidth + firstCol) * bytesPerPixel); - destAddress = rectCopy; - - for (int32 j = 0; j < copyRows; j++) { - uint8 *destRowAddress = destAddress + (j * copyLength * bytesPerPixel); - uint8 *srcRowAddress = srcAddress + (j * Bwidth * bytesPerPixel); - memcpy(destRowAddress, srcRowAddress, copyLength * bytesPerPixel ); - } - - rectList.AddItem(rectCopy); - } - } - - int32 item = 0; - for(k = 0; k < rCount; k++) { - BRegion* reg = (BRegion*)list->ItemAt(k); - - int32 rectCount = reg->CountRects(); - for(i=0; i < rectCount; i++) - { - BRect r = reg->RectAt(i); - uint8 *rectCopy; - uint8 *srcAddress; - uint8 *destAddress; - int32 firstRow, lastRow; - int32 firstCol, lastCol; - int32 copyLength, copyLength2; - int32 copyRows, copyRows2; - - firstRow = (int32)(r.top < 0? 0: r.top); - lastRow = (int32)(r.bottom > (Bheight-1)? (Bheight-1): r.bottom); - firstCol = (int32)(r.left < 0? 0: r.left); - lastCol = (int32)(r.right > (Bwidth-1)? (Bwidth-1): r.right); - copyLength = (lastCol - firstCol + 1) < 0? 0: (lastCol - firstCol + 1); - copyRows = (lastRow - firstRow + 1) < 0? 0: (lastRow - firstRow + 1); - - rectCopy = (uint8*)rectList.ItemAt(item++); - - srcAddress = rectCopy; - - r.Set(firstCol, firstRow, lastCol, lastRow); - r.OffsetBy( *((BPoint*)pList->ItemAt(k%rCount)) ); - - // keep track of invalid area - updateRect = updateRect.IsValid() ? updateRect | r : r; - - firstRow = (int32)(r.top < 0? 0: r.top); - lastRow = (int32)(r.bottom > (Bheight-1)? (Bheight-1): r.bottom); - firstCol = (int32)(r.left < 0? 0: r.left); - lastCol = (int32)(r.right > (Bwidth-1)? (Bwidth-1): r.right); - copyLength2 = (lastCol - firstCol + 1) < 0? 0: (lastCol - firstCol + 1); - copyRows2 = (lastRow - firstRow + 1) < 0? 0: (lastRow - firstRow + 1); - - destAddress = bitmapBits + (((firstRow) * Bwidth + firstCol) * bytesPerPixel); - - int32 minLength = copyLength < copyLength2? copyLength: copyLength2; - int32 minRows = copyRows < copyRows2? copyRows: copyRows2; - - for (int32 j = 0; j < minRows; j++) - { - uint8 *destRowAddress = destAddress + (j * Bwidth * bytesPerPixel); - uint8 *srcRowAddress = srcAddress + (j * copyLength * bytesPerPixel); - memcpy(destRowAddress, srcRowAddress, minLength * bytesPerPixel ); - } - } - } - - int32 count = rectList.CountItems(); - for (i = 0; i < count; i++) { - if (void* rectCopy = rectList.ItemAt(i)) - free(rectCopy); - } - - fGraphicsCard->Invalidate(updateRect); - - Unlock(); -} - // FillArc void DisplayDriverPainter::FillArc(const BRect &r, const float &angle, @@ -1313,9 +1190,50 @@ void DisplayDriverPainter::ConstrainClippingRegion(BRegion *region) } } -// _MoveRect +// _CopyRect +BRect +DisplayDriverPainter::_CopyRect(BRect src, int32 xOffset, int32 yOffset) const +{ + BRect dst; + RenderingBuffer* buffer = fGraphicsCard->DrawingBuffer(); + if (buffer) { + + BRect clip(0, 0, buffer->Width() - 1, buffer->Height() - 1); + + dst = src; + dst.OffsetBy(xOffset, yOffset); + + if (clip.Intersects(src) && clip.Intersects(dst)) { + + uint32 bpr = buffer->BytesPerRow(); + uint8* bits = (uint8*)buffer->Bits(); + + // clip source rect + src = src & clip; + // clip dest rect + dst = dst & clip; + // move dest back over source and clip source to dest + dst.OffsetBy(-xOffset, -yOffset); + src = src & dst; + + // calc offset in buffer + bits += (int32)src.left * 4 + (int32)src.top * bpr; + + uint32 width = src.IntegerWidth() + 1; + uint32 height = src.IntegerHeight() + 1; + + _CopyRect(bits, width, height, bpr, xOffset, yOffset); + + // offset dest again, because it is return value + dst.OffsetBy(xOffset, yOffset); + } + } + return dst; +} + +// _CopyRect void -DisplayDriverPainter::_MoveRect(uint8* src, uint32 width, uint32 height, +DisplayDriverPainter::_CopyRect(uint8* src, uint32 width, uint32 height, uint32 bpr, int32 xOffset, int32 yOffset) const { int32 xIncrement; @@ -1324,7 +1242,7 @@ DisplayDriverPainter::_MoveRect(uint8* src, uint32 width, uint32 height, if (xOffset > 0) { // copy from right to left xIncrement = -1; - src += width * 4; + src += (width - 1) * 4; } else { // copy from left to right xIncrement = 1; @@ -1333,7 +1251,7 @@ DisplayDriverPainter::_MoveRect(uint8* src, uint32 width, uint32 height, if (yOffset > 0) { // copy from bottom to top yIncrement = -bpr; - src += height * bpr; + src += (height - 1) * bpr; } else { // copy from top to bottom yIncrement = bpr; diff --git a/src/servers/app/drawing/DisplayDriverPainter.h b/src/servers/app/drawing/DisplayDriverPainter.h index 5ff5817184..65045edcfd 100644 --- a/src/servers/app/drawing/DisplayDriverPainter.h +++ b/src/servers/app/drawing/DisplayDriverPainter.h @@ -46,12 +46,9 @@ class DisplayDriverPainter : public DisplayDriver { virtual void Shutdown(); // drawing functions - virtual void CopyBits( const BRect &src, - const BRect &dest, - const DrawData *d); - - virtual void CopyRegion( BRegion *src, - const BPoint &lefttop); + virtual void CopyRegion( /*const*/ BRegion* region, + int32 xOffset, + int32 yOffset); virtual void CopyRegionList( BList* list, BList* pList, @@ -281,7 +278,9 @@ class DisplayDriverPainter : public DisplayDriver { virtual void ConstrainClippingRegion(BRegion *reg); private: - void _MoveRect(uint8* bits, + BRect _CopyRect(BRect r, int32 xOffset, int32 yOffset) const; + + void _CopyRect(uint8* bits, uint32 width, uint32 height, uint32 bpr, int32 xOffset, int32 yOffset) const; diff --git a/src/servers/app/drawing/Painter/Painter.cpp b/src/servers/app/drawing/Painter/Painter.cpp index 57030ddfdd..b0e16dc548 100644 --- a/src/servers/app/drawing/Painter/Painter.cpp +++ b/src/servers/app/drawing/Painter/Painter.cpp @@ -90,7 +90,9 @@ Painter::~Painter() void Painter::AttachToBuffer(RenderingBuffer* buffer) { - if (buffer && buffer->InitCheck() >= B_OK) { + if (buffer && buffer->InitCheck() >= B_OK && + // TODO: implement drawing on B_RGB24, B_RGB15, B_RGB16, B_CMAP8 and B_GRAY8 :-[ + (buffer->ColorSpace() == B_RGBA32 || buffer->ColorSpace() == B_RGB32)) { // clean up previous stuff _MakeEmpty(); @@ -112,7 +114,6 @@ Painter::AttachToBuffer(RenderingBuffer* buffer) // These are the AGG renderes and rasterizes which // will be used for stroking paths -rgb_color color = fPatternHandler->HighColor().GetColor32(); #if ALIASED_DRAWING fOutlineRenderer = new outline_renderer_type(*fBaseRenderer); fOutlineRasterizer = new outline_rasterizer_type(*fOutlineRenderer);