diff --git a/headers/private/interface/PictureDataWriter.h b/headers/private/interface/PictureDataWriter.h index 4b7d6a0a88..a2672e0cf0 100644 --- a/headers/private/interface/PictureDataWriter.h +++ b/headers/private/interface/PictureDataWriter.h @@ -32,6 +32,8 @@ public: status_t WriteSetLineMode(const cap_mode &cap, const join_mode &join, const float &miterLimit); status_t WriteSetScale(const float &scale); status_t WriteSetPattern(const pattern &pat); + status_t WriteSetClipping(/*const */BRegion ®ion); + status_t WriteClearClipping(); status_t WritePushState(); status_t WritePopState(); diff --git a/src/kits/interface/PictureDataWriter.cpp b/src/kits/interface/PictureDataWriter.cpp index 67a17a73a6..ce2591c420 100644 --- a/src/kits/interface/PictureDataWriter.cpp +++ b/src/kits/interface/PictureDataWriter.cpp @@ -13,6 +13,7 @@ #include #include #include +#include #include @@ -163,6 +164,40 @@ PictureDataWriter::WriteSetPattern(const pattern &pat) } +status_t +PictureDataWriter::WriteSetClipping(/*const */BRegion ®ion) +{ + // TODO: I don't know if it's compatible with R5's BPicture version + try { + const int32 numRects = region.CountRects(); + if (numRects > 0 && region.Frame().IsValid()) { + BeginOp(B_PIC_SET_CLIPPING_RECTS); + Write(numRects); + for (int32 i = 0; i < numRects; i++) + Write(region.RectAt(i)); + EndOp(); + } else + WriteClearClipping(); + } catch (status_t &status) { + return status; + } + return B_OK; +} + + +status_t +PictureDataWriter::WriteClearClipping() +{ + try { + BeginOp(B_PIC_CLEAR_CLIPPING_RECTS); + EndOp(); + } catch (status_t &status) { + return status; + } + return B_OK; +} + + status_t PictureDataWriter::WriteSetHighColor(const rgb_color &color) { diff --git a/src/kits/interface/PicturePlayer.cpp b/src/kits/interface/PicturePlayer.cpp index d526a9626e..54e21fcaa0 100644 --- a/src/kits/interface/PicturePlayer.cpp +++ b/src/kits/interface/PicturePlayer.cpp @@ -35,7 +35,7 @@ typedef void (*fnc_f)(void*, float); typedef void (*fnc_Color)(void*, rgb_color); typedef void (*fnc_Pattern)(void*, pattern); typedef void (*fnc_ss)(void *, int16, int16); -typedef void (*fnc_PBRecti)(void*, const BRect*, int32); +typedef void (*fnc_PBRecti)(void*, const BRect*, uint32); typedef void (*fnc_DrawPixels)(void *, BRect, BRect, int32, int32, int32, int32, int32, const void *); typedef void (*fnc_DrawPicture)(void *, BPoint, int32); @@ -283,15 +283,18 @@ PicturePlayer::Play(void **callBackTable, int32 tableEntries, void *userData) case B_PIC_SET_CLIPPING_RECTS: { if (tableEntries <= 20) - break; - // TODO: Implement + break; + // TODO: Not sure if it's compatible with R5's BPicture version + ((fnc_PBRecti)callBackTable[20])(userData, + reinterpret_cast(data + sizeof(uint32)), + *reinterpret_cast(data)); break; } case B_PIC_CLEAR_CLIPPING_RECTS: { if (tableEntries <= 20) - break; + break; ((fnc_PBRecti)callBackTable[20])(userData, NULL, 0); break; } diff --git a/src/servers/app/ServerPicture.cpp b/src/servers/app/ServerPicture.cpp index e897cecb1e..7f931e92bc 100644 --- a/src/servers/app/ServerPicture.cpp +++ b/src/servers/app/ServerPicture.cpp @@ -437,7 +437,8 @@ draw_picture(ViewLayer *view, BPoint where, int32 token) static void set_clipping_rects(ViewLayer *view, const BRect *rects, uint32 numRects) { - // TODO: This is too slow, we should copy the rects directly to BRegion's internal data + // TODO: This might be too slow, we should copy the rects + // directly to BRegion's internal data BRegion region; for (uint32 c = 0; c < numRects; c++) region.Include(rects[c]); diff --git a/src/servers/app/ServerWindow.cpp b/src/servers/app/ServerWindow.cpp index fefe0716c0..a5971963be 100644 --- a/src/servers/app/ServerWindow.cpp +++ b/src/servers/app/ServerWindow.cpp @@ -2709,6 +2709,31 @@ ServerWindow::_DispatchPictureMessage(int32 code, BPrivate::LinkReceiver &link) break; } + case AS_LAYER_SET_CLIP_REGION: + { + int32 rectCount; + status_t status = link.Read(&rectCount); + // a negative count means no + // region for the current draw state, + // but an *empty* region is actually valid! + // even if it means no drawing is allowed + + if (status < B_OK) + break; + + if (rectCount >= 0) { + // we are supposed to set the clipping region + BRegion region; + if (rectCount > 0 && link.ReadRegion(®ion) < B_OK) + break; + picture->WriteSetClipping(region); + } else { + // we are supposed to clear the clipping region + picture->WriteClearClipping(); + } + + break; + } case AS_LAYER_BEGIN_PICTURE: { ServerPicture *newPicture = App()->CreatePicture();