diff --git a/headers/os/interface/Shape.h b/headers/os/interface/Shape.h index 795fee8348..5c4232f318 100644 --- a/headers/os/interface/Shape.h +++ b/headers/os/interface/Shape.h @@ -75,7 +75,7 @@ virtual void _ReservedShape3(); virtual void _ReservedShape4(); friend class BShapeIterator; - friend class TPicture; + friend class PicturePlayer; friend class BView; friend class BFont; friend class BPrivate::ServerLink; diff --git a/src/kits/interface/PicturePlayer.cpp b/src/kits/interface/PicturePlayer.cpp index a7503d4a9c..a53dbbc90e 100644 --- a/src/kits/interface/PicturePlayer.cpp +++ b/src/kits/interface/PicturePlayer.cpp @@ -14,6 +14,7 @@ #include #include +#include typedef void (*fnc)(void*); typedef void (*fnc_BPoint)(void*, BPoint); @@ -36,6 +37,7 @@ typedef void (*fnc_ss)(void *, int16, int16); typedef void (*fnc_PBRecti)(void*, BRect*, int32); typedef void (*fnc_DrawPixels)(void *, BRect, BRect, int32, int32, int32, int32, int32, void*); +typedef void (*fnc_BShape)(void*, BShape*); PicturePlayer::PicturePlayer(void *data, int32 size, BList *pictures) @@ -270,8 +272,49 @@ PicturePlayer::Play(void **callBackTable, int32 tableEntries, void *userData) break; } case B_PIC_STROKE_SHAPE: - case B_PIC_FILL_SHAPE: + { + BRect shapeFrame = GetRect(); + (void)shapeFrame; + + int32 opCount, ptCount; + opCount = GetInt32(); + ptCount = GetInt32(); + + uint32 *opList = new uint32[opCount]; + BPoint *ptList = new BPoint[ptCount]; + GetData(opList, opCount * sizeof(uint32)); + GetData(ptList, ptCount * sizeof(BPoint)); + + BShape shape; + shape.SetData(opCount, ptCount, opList, ptList); + + ((fnc_BShape)callBackTable[15])(userData, &shape); + delete[] opList; + delete[] ptList; break; + } + case B_PIC_FILL_SHAPE: + { + BRect shapeFrame = GetRect(); + (void)shapeFrame; + + int32 opCount, ptCount; + opCount = GetInt32(); + ptCount = GetInt32(); + + uint32 *opList = new uint32[opCount]; + BPoint *ptList = new BPoint[ptCount]; + GetData(opList, opCount * sizeof(uint32)); + GetData(ptList, ptCount * sizeof(BPoint)); + + BShape shape; + shape.SetData(opCount, ptCount, opList, ptList); + + ((fnc_BShape)callBackTable[16])(userData, &shape); + delete[] opList; + delete[] ptList; + break; + } case B_PIC_DRAW_STRING: { int32 len = GetInt32(); diff --git a/src/servers/app/ServerPicture.cpp b/src/servers/app/ServerPicture.cpp index 983710f19f..1562cb6933 100644 --- a/src/servers/app/ServerPicture.cpp +++ b/src/servers/app/ServerPicture.cpp @@ -20,9 +20,111 @@ #include #include +#include #include +#include +// NOTE: Initially defined in Shape.cpp. +#define OP_LINETO 0x10000000 +#define OP_BEZIERTO 0x20000000 +#define OP_CLOSE 0x40000000 +#define OP_MOVETO 0x80000000 + + +class ShapePainter : public BShapeIterator { + public: + ShapePainter(); + virtual ~ShapePainter(); + + virtual status_t IterateMoveTo(BPoint *point); + virtual status_t IterateLineTo(int32 lineCount, BPoint *linePts); + virtual status_t IterateBezierTo(int32 bezierCount, BPoint *bezierPts); + virtual status_t IterateClose(); + + void Draw(ViewLayer *view, BRect frame, bool filled); + + private: + stack fOpStack; + stack fPtStack; +}; + +ShapePainter::ShapePainter() + : BShapeIterator() +{ +} + +ShapePainter::~ShapePainter() +{ +} + +status_t +ShapePainter::IterateMoveTo(BPoint *point) +{ + fOpStack.push(OP_MOVETO); + fPtStack.push(*point); + + return B_OK; +} + +status_t +ShapePainter::IterateLineTo(int32 lineCount, BPoint *linePts) +{ + fOpStack.push(OP_LINETO | lineCount); + for(int32 i = 0;i < lineCount;i++) + fPtStack.push(linePts[i]); + + return B_OK; +} + +status_t +ShapePainter::IterateBezierTo(int32 bezierCount, BPoint *bezierPts) +{ + bezierCount *= 3; + fOpStack.push(OP_BEZIERTO | bezierCount); + for(int32 i = 0;i < bezierCount;i++) + fPtStack.push(bezierPts[i]); + + return B_OK; +} + +status_t +ShapePainter::IterateClose(void) +{ + fOpStack.push(OP_CLOSE); + + return B_OK; +} + +void +ShapePainter::Draw(ViewLayer *view, BRect frame, bool filled) +{ + // We're going to draw the currently iterated picture. + int32 opCount, ptCount; + opCount = fOpStack.size(); + ptCount = fPtStack.size(); + + uint32 *opList; + BPoint *ptList; + if(opCount > 0 && ptCount > 0) { + int32 i; + opList = new uint32[opCount]; + ptList = new BPoint[ptCount]; + + for(i = (opCount - 1);i >= 0;i--) { + opList[i] = fOpStack.top(); + fOpStack.pop(); + } + + for(i = (ptCount - 1);i >= 0;i--) { + ptList[i] = fPtStack.top(); + fPtStack.pop(); + } + + view->Window()->GetDrawingEngine()->DrawShape(frame, opCount, opList, ptCount, ptList, + view->CurrentState(), filled); + } +} static void nop() @@ -191,21 +293,20 @@ fill_polygon(ViewLayer *view, int32 numPoints, BPoint *points) static void stroke_shape(ViewLayer *view, BShape *shape) { - //TODO: Oh-ho... how do I access BShape private members ? - /*for (int32 i = 0; i < ptCount; i++) - fCurrentLayer->ConvertToScreenForDrawing(&ptList[i]); + ShapePainter drawShape; - view->Window()->GetDrawingEngine()->DrawShape(shapeFrame, opCount, opList, ptCount, ptList, - fCurrentLayer->CurrentState(), code == AS_FILL_SHAPE);*/ + drawShape.Iterate(shape); + drawShape.Draw(view, shape->Bounds(), false); } static void fill_shape(ViewLayer *view, BShape *shape) { - //view->FillShape(shape); + ShapePainter drawShape; - printf("FillShape\n"); + drawShape.Iterate(shape); + drawShape.Draw(view, shape->Bounds(), true); } diff --git a/src/servers/app/ServerWindow.cpp b/src/servers/app/ServerWindow.cpp index 1b43f04073..d52c4d7147 100644 --- a/src/servers/app/ServerWindow.cpp +++ b/src/servers/app/ServerWindow.cpp @@ -2525,6 +2525,33 @@ ServerWindow::_DispatchPictureMessage(int32 code, BPrivate::LinkReceiver &link) break; } + case AS_STROKE_SHAPE: + case AS_FILL_SHAPE: + { + BRect shapeFrame; + int32 opCount; + int32 ptCount; + + link.Read(&shapeFrame); + link.Read(&opCount); + link.Read(&ptCount); + + uint32 *opList = new(nothrow) uint32[opCount]; + BPoint *ptList = new(nothrow) BPoint[ptCount]; + if (link.Read(opList, opCount * sizeof(uint32)) >= B_OK && + link.Read(ptList, ptCount * sizeof(BPoint)) >= B_OK) { + + picture->BeginOp(code == AS_FILL_SHAPE ? B_PIC_FILL_SHAPE : B_PIC_STROKE_SHAPE); + picture->AddRect(shapeFrame); + picture->AddInt32(opCount); + picture->AddInt32(ptCount); + picture->AddData(opList, opCount * sizeof(uint32)); + picture->AddData(ptList, ptCount * sizeof(BPoint)); + picture->EndOp(); + } + break; + } + case AS_LAYER_DRAW_BITMAP: { int32 token;