From 4399ec510de9714e2440cdae346d00c286d69906 Mon Sep 17 00:00:00 2001 From: X512 Date: Wed, 10 Jun 2020 15:40:14 +0900 Subject: [PATCH] BPicture: add fill rule support Change-Id: I068e1c2e8659f7b90c6d7c7331a8bb25ae343fe9 Reviewed-on: https://review.haiku-os.org/c/haiku/+/2922 Reviewed-by: Adrien Destugues --- headers/private/interface/PictureDataWriter.h | 1 + headers/private/interface/PicturePlayer.h | 1 + headers/private/interface/PictureProtocol.h | 3 ++- src/kits/interface/PictureDataWriter.cpp | 15 ++++++++++++ src/kits/interface/PicturePlayer.cpp | 24 ++++++++++++++++++- src/servers/app/ServerPicture.cpp | 12 +++++++++- src/servers/app/ServerWindow.cpp | 13 ++++++++++ 7 files changed, 66 insertions(+), 3 deletions(-) diff --git a/headers/private/interface/PictureDataWriter.h b/headers/private/interface/PictureDataWriter.h index 5d75abe7c5..42ccd8941b 100644 --- a/headers/private/interface/PictureDataWriter.h +++ b/headers/private/interface/PictureDataWriter.h @@ -41,6 +41,7 @@ public: status_t WriteSetLineMode(const cap_mode& cap, const join_mode& join, const float& miterLimit); + status_t WriteSetFillRule(int32 fillRule); status_t WriteSetScale(const float& scale); status_t WriteSetTransform(BAffineTransform transform); status_t WriteTranslateBy(double x, double y); diff --git a/headers/private/interface/PicturePlayer.h b/headers/private/interface/PicturePlayer.h index 308829e873..748999356d 100644 --- a/headers/private/interface/PicturePlayer.h +++ b/headers/private/interface/PicturePlayer.h @@ -102,6 +102,7 @@ struct picture_player_callbacks { void (*draw_ellipse_gradient)(void* userData, const BRect& rect, BGradient& gradient, bool fill); void (*draw_polygon_gradient)(void* userData, size_t numPoints, const BPoint points[], bool isClosed, BGradient& gradient, bool fill); void (*draw_shape_gradient)(void* userData, const BShape& shape, BGradient& gradient, bool fill); + void (*set_fill_rule)(void* userData, int32 fillRule); }; diff --git a/headers/private/interface/PictureProtocol.h b/headers/private/interface/PictureProtocol.h index b83bb22701..25e14cf568 100644 --- a/headers/private/interface/PictureProtocol.h +++ b/headers/private/interface/PictureProtocol.h @@ -58,6 +58,7 @@ enum { B_PIC_SET_STIPLE_PATTERN = 0x0308, B_PIC_ENTER_FONT_STATE = 0x0309, B_PIC_SET_BLENDING_MODE = 0x030A, + B_PIC_SET_FILL_RULE = 0x030B, B_PIC_SET_FONT_FAMILY = 0x0380, B_PIC_SET_FONT_STYLE = 0x0381, B_PIC_SET_FONT_SPACING = 0x0382, @@ -76,7 +77,7 @@ enum { }; -const static uint32 kOpsTableSize = 70; +const static uint32 kOpsTableSize = 71; #endif diff --git a/src/kits/interface/PictureDataWriter.cpp b/src/kits/interface/PictureDataWriter.cpp index 7de6b56603..284092818d 100644 --- a/src/kits/interface/PictureDataWriter.cpp +++ b/src/kits/interface/PictureDataWriter.cpp @@ -156,6 +156,21 @@ PictureDataWriter::WriteSetLineMode(const cap_mode& cap, const join_mode& join, } +status_t +PictureDataWriter::WriteSetFillRule(int32 fillRule) +{ + try { + BeginOp(B_PIC_SET_FILL_RULE); + Write(fillRule); + EndOp(); + } catch (status_t& status) { + return status; + } + + return B_OK; +} + + status_t PictureDataWriter::WriteSetScale(const float& scale) { diff --git a/src/kits/interface/PicturePlayer.cpp b/src/kits/interface/PicturePlayer.cpp index ec2bdd94dd..be402543d8 100644 --- a/src/kits/interface/PicturePlayer.cpp +++ b/src/kits/interface/PicturePlayer.cpp @@ -605,6 +605,15 @@ draw_shape_gradient(void* _context, const BShape& shape, BGradient& gradient, bo } +static void +set_fill_rule(void* _context, int32 fillRule) +{ + adapter_context* context = reinterpret_cast(_context); + ((void (*)(void*, int32))context->function_table[70])( + context->user_data, fillRule); +} + + #if DEBUG > 1 static const char * @@ -747,7 +756,8 @@ PicturePlayer::Play(void** callBackTable, int32 tableEntries, void* userData) draw_arc_gradient, draw_ellipse_gradient, draw_polygon_gradient, - draw_shape_gradient + draw_shape_gradient, + set_fill_rule }; // We don't check if the functions in the table are NULL, but we @@ -1545,6 +1555,18 @@ PicturePlayer::_Play(const picture_player_callbacks& callbacks, void* userData, break; } + case B_PIC_SET_FILL_RULE: + { + const uint32* fillRule; + if (callbacks.set_fill_rule == NULL + || !reader.Get(fillRule)) { + break; + } + + callbacks.set_fill_rule(userData, *fillRule); + break; + } + case B_PIC_SET_TRANSFORM: { const BAffineTransform* transform; diff --git a/src/servers/app/ServerPicture.cpp b/src/servers/app/ServerPicture.cpp index 4159049d66..10d61edd4f 100644 --- a/src/servers/app/ServerPicture.cpp +++ b/src/servers/app/ServerPicture.cpp @@ -896,6 +896,15 @@ set_blending_mode(void* _canvas, source_alpha alphaSrcMode, } +static void +set_fill_rule(void* _canvas, int32 fillRule) +{ + Canvas* const canvas = reinterpret_cast(_canvas); + canvas->CurrentState()->SetFillRule(fillRule); + canvas->GetDrawingEngine()->SetFillRule(fillRule); +} + + static void set_transform(void* _canvas, const BAffineTransform& transform) { @@ -1062,7 +1071,8 @@ static const BPrivate::picture_player_callbacks kPicturePlayerCallbacks = { draw_arc_gradient, draw_ellipse_gradient, draw_polygon_gradient, - draw_shape_gradient + draw_shape_gradient, + set_fill_rule }; diff --git a/src/servers/app/ServerWindow.cpp b/src/servers/app/ServerWindow.cpp index bc9dbf8526..c23e3cfb42 100644 --- a/src/servers/app/ServerWindow.cpp +++ b/src/servers/app/ServerWindow.cpp @@ -3303,6 +3303,19 @@ ServerWindow::_DispatchPictureMessage(int32 code, BPrivate::LinkReceiver& link) info.lineJoin, info.miterLimit); break; } + case AS_VIEW_SET_FILL_RULE: + { + int32 fillRule; + if (link.Read(&fillRule) != B_OK) + break; + + picture->WriteSetFillRule(fillRule); + + fCurrentView->CurrentState()->SetFillRule(fillRule); + fWindow->GetDrawingEngine()->SetFillRule(fillRule); + + break; + } case AS_VIEW_SET_SCALE: { float scale;