From ce27f9612e78bbb58c62bdc54c02bfc0e5172681 Mon Sep 17 00:00:00 2001 From: Stefano Ceccherini Date: Sat, 5 Sep 2015 20:59:06 +0200 Subject: [PATCH] Implement ClipToPicture inside a BPicture. Not working yet. BView::ClipToPicture doesn't work anymore, when nested inside a BPicture, This happened when its implementation was moved server-side. --- headers/private/interface/PictureDataWriter.h | 2 ++ headers/private/interface/PicturePlayer.h | 2 +- src/kits/interface/PictureDataWriter.cpp | 19 +++++++++++++++ src/kits/interface/PicturePlayer.cpp | 14 +++++++++-- src/servers/app/ServerPicture.cpp | 19 ++++++++++++--- src/servers/app/ServerWindow.cpp | 24 +++++++++++++++++++ 6 files changed, 74 insertions(+), 6 deletions(-) diff --git a/headers/private/interface/PictureDataWriter.h b/headers/private/interface/PictureDataWriter.h index 4af9187f24..ea3fe9e7c8 100644 --- a/headers/private/interface/PictureDataWriter.h +++ b/headers/private/interface/PictureDataWriter.h @@ -40,6 +40,8 @@ public: status_t WriteSetScale(const float& scale); status_t WriteSetTransform(BAffineTransform transform); status_t WriteSetPattern(const ::pattern& pattern); + status_t WriteClipToPicture(int32 pictureToken, + const BPoint& origin, bool inverse); status_t WriteSetClipping(const BRegion& region); status_t WriteClearClipping(); diff --git a/headers/private/interface/PicturePlayer.h b/headers/private/interface/PicturePlayer.h index bd714b74b5..f21b3ff4c5 100644 --- a/headers/private/interface/PicturePlayer.h +++ b/headers/private/interface/PicturePlayer.h @@ -51,7 +51,7 @@ struct picture_player_callbacks { void (*draw_picture)(void* userData, const BPoint& where, int32 token); void (*set_clipping_rects)(void* userData, size_t numRects, const BRect rects[]); - void (*clip_to_picture)(void* userData, const BPicture& picture, + void (*clip_to_picture)(void* userData, int32 token, const BPoint& where, bool clipToInverse); void (*push_state)(void* userData); void (*pop_state)(void* userData); diff --git a/src/kits/interface/PictureDataWriter.cpp b/src/kits/interface/PictureDataWriter.cpp index 3f9f5c911c..8dabc494fe 100644 --- a/src/kits/interface/PictureDataWriter.cpp +++ b/src/kits/interface/PictureDataWriter.cpp @@ -197,6 +197,25 @@ PictureDataWriter::WriteSetPattern(const ::pattern& pattern) } +status_t +PictureDataWriter::WriteClipToPicture(int32 pictureToken, + const BPoint& origin, bool inverse) +{ + // TODO: I don't know if it's compatible with R5's BPicture version + try { + BeginOp(B_PIC_CLIP_TO_PICTURE); + Write(pictureToken); + Write(origin); + Write(inverse); + EndOp(); + } catch (status_t& status) { + return status; + } + + return B_OK; +} + + status_t PictureDataWriter::WriteSetClipping(const BRegion& region) { diff --git a/src/kits/interface/PicturePlayer.cpp b/src/kits/interface/PicturePlayer.cpp index 4b32428a4a..980810bd59 100644 --- a/src/kits/interface/PicturePlayer.cpp +++ b/src/kits/interface/PicturePlayer.cpp @@ -215,9 +215,12 @@ set_clipping_rects(void* _context, size_t numRects, const BRect _rects[]) static void -clip_to_picture(void* context, const BPicture& picture, const BPoint& origin, +clip_to_picture(void* _context, int32 token, const BPoint& origin, bool clipToInverse) { + adapter_context* context = reinterpret_cast(_context); + ((void (*)(void*, int32, BPoint, bool))context->function_table[21])( + context->user_data, token, origin, clipToInverse); } @@ -930,7 +933,14 @@ PicturePlayer::_Play(const picture_player_callbacks& callbacks, void* userData, case B_PIC_CLIP_TO_PICTURE: { - // TODO: Implement + const int32* token; + const BPoint* where; + const bool* inverse; + if (callbacks.clip_to_picture == NULL || !reader.Get(token) + || !reader.Get(where) || !reader.Get(inverse)) + break; + + callbacks.clip_to_picture(userData, *token, *where, *inverse); break; } diff --git a/src/servers/app/ServerPicture.cpp b/src/servers/app/ServerPicture.cpp index d370663e14..8df669b09b 100644 --- a/src/servers/app/ServerPicture.cpp +++ b/src/servers/app/ServerPicture.cpp @@ -14,6 +14,7 @@ #include #include +#include "AlphaMask.h" #include "DrawingEngine.h" #include "DrawState.h" #include "FontManager.h" @@ -466,11 +467,23 @@ set_clipping_rects(void* _context, size_t numRects, const BRect rects[]) static void -clip_to_picture(void* context, const BPicture& picture, const BPoint& pt, +clip_to_picture(void* _context, int32 pictureToken, const BPoint& where, bool clipToInverse) { - printf("ClipToPicture(picture, BPoint(%.2f, %.2f), %s)\n", - pt.x, pt.y, clipToInverse ? "inverse" : ""); + DrawingContext* context = reinterpret_cast(_context); + + ServerPicture* picture = context->GetPicture(pictureToken); + if (picture == NULL) + return; + + AlphaMask* mask = new(std::nothrow) AlphaMask( + picture, clipToInverse, where, *context->CurrentState()); + context->SetAlphaMask(mask); + context->UpdateCurrentDrawingRegion(); + if (mask != NULL) + mask->ReleaseReference(); + + picture->ReleaseReference(); } diff --git a/src/servers/app/ServerWindow.cpp b/src/servers/app/ServerWindow.cpp index fef86d05c6..2ec9d90c7c 100644 --- a/src/servers/app/ServerWindow.cpp +++ b/src/servers/app/ServerWindow.cpp @@ -3346,6 +3346,30 @@ ServerWindow::_DispatchPictureMessage(int32 code, BPrivate::LinkReceiver& link) break; } + case AS_VIEW_CLIP_TO_PICTURE: + { + int32 pictureToken; + BPoint where; + bool inverse = false; + + link.Read(&pictureToken); + if (pictureToken < 0) + break; + + link.Read(&where); + if (link.Read(&inverse) != B_OK) + break; + + ServerPicture* picture = fServerApp->GetPicture(pictureToken); + if (picture == NULL) + break; + + picture->WriteClipToPicture(picture->Token(), where, inverse); + + picture->ReleaseReference(); + break; + } + case AS_VIEW_BEGIN_PICTURE: { ServerPicture* newPicture = App()->CreatePicture();