diff --git a/headers/private/interface/PictureDataWriter.h b/headers/private/interface/PictureDataWriter.h new file mode 100644 index 0000000000..872875fb2c --- /dev/null +++ b/headers/private/interface/PictureDataWriter.h @@ -0,0 +1,56 @@ +#ifndef __PICTUREDATAWRITER_H +#define __PICTUREDATAWRITER_H + +#include +#include +#include + +#include + +class BPositionIO; +class PictureDataWriter { +public: + PictureDataWriter(BPositionIO *data); + + status_t WriteSetOrigin(const BPoint &point); + status_t WriteInvertRect(const BRect &rect); + + status_t WriteSetDrawingMode(const drawing_mode &mode); + status_t WriteSetPenSize(const float &penSize); + status_t WriteSetLineMode(const cap_mode &cap, const join_mode &join, const float &miterLimit); + status_t WriteSetScale(const float &scale); + + status_t WriteDrawRect(const BRect &rect, const bool &fill); + status_t WriteDrawRoundRect(const BRect &rect, const BPoint &radius, const bool &fill); + status_t WriteDrawEllipse(const BRect &rect, const bool &fill); + status_t WriteDrawArc(const BPoint ¢er, const BPoint &radius, + const float &startTheta, const float &arcTheta, const bool &fill); + status_t WriteStrokeLine(const BPoint &start, const BPoint &end); + + status_t WriteSetHighColor(const rgb_color &color); + status_t WriteSetLowColor(const rgb_color &color); + + status_t WriteDrawString(const BPoint &where, const char *string, + const int32 &length, const escapement_delta &delta); + status_t WriteDrawShape(const int32 &opCount, const void *opList, + const int32 &ptCount, const void *ptList, const bool &fill); + status_t WriteDrawBitmap(const BRect &srcRect, const BRect &dstRect, const int32 &width, const int32 &height, + const int32 &bytesPerRow, const int32 &colorSpace, const int32 &flags, + const void *data, const int32 &length); + + status_t WritePushState(); + status_t WritePopState(); + +private: + BPositionIO *fData; + std::stack fStack; + + status_t WriteData(const void *data, size_t size); + template status_t Write(const T &data) { return WriteData(&data, sizeof(data)); } + + status_t BeginOp(const int16 &op); + status_t EndOp(); + +}; + +#endif // __PICTUREDATAWRITER_H diff --git a/src/kits/interface/Jamfile b/src/kits/interface/Jamfile index 79a726fcc9..ea95f7d09c 100644 --- a/src/kits/interface/Jamfile +++ b/src/kits/interface/Jamfile @@ -81,6 +81,7 @@ MergeObject interface_kit.o : OutlineListView.cpp Picture.cpp PictureButton.cpp + PictureDataWriter.cpp PicturePlayer.cpp Point.cpp Polygon.cpp diff --git a/src/kits/interface/PictureDataWriter.cpp b/src/kits/interface/PictureDataWriter.cpp new file mode 100644 index 0000000000..4413ac2063 --- /dev/null +++ b/src/kits/interface/PictureDataWriter.cpp @@ -0,0 +1,269 @@ +#include +#include +#include + +#include +#include + +PictureDataWriter::PictureDataWriter(BPositionIO *data) + : + fData(data) +{ +} + + +status_t +PictureDataWriter::WriteSetOrigin(const BPoint &point) +{ + BeginOp(B_PIC_SET_ORIGIN); + Write(point); + EndOp(); + return B_OK; +} + + +status_t +PictureDataWriter::WriteInvertRect(const BRect &rect) +{ + WriteSetDrawingMode(B_OP_INVERT); + + BeginOp(B_PIC_FILL_RECT); + Write(rect); + EndOp(); + + WriteSetDrawingMode(B_OP_COPY); + return B_OK; +} + + +status_t +PictureDataWriter::WriteSetDrawingMode(const drawing_mode &mode) +{ + BeginOp(B_PIC_SET_DRAWING_MODE); + Write((int16)mode); + EndOp(); + return B_OK; +} + + +status_t +PictureDataWriter::WriteSetPenSize(const float &penSize) +{ + BeginOp(B_PIC_SET_PEN_SIZE); + Write(penSize); + EndOp(); + return B_OK; +} + + +status_t +PictureDataWriter::WriteSetLineMode(const cap_mode &cap, const join_mode &join, const float &miterLimit) +{ + BeginOp(B_PIC_SET_LINE_MODE); + Write((int16)cap); + Write((int16)join); + Write(miterLimit); + EndOp(); + return B_OK; +} + + +status_t +PictureDataWriter::WriteSetScale(const float &scale) +{ + BeginOp(B_PIC_SET_SCALE); + Write(scale); + EndOp(); + return B_OK; +} + + +status_t +PictureDataWriter::WriteSetHighColor(const rgb_color &color) +{ + BeginOp(B_PIC_SET_FORE_COLOR); + Write(color); + EndOp(); + return B_OK; +} + + +status_t +PictureDataWriter::WriteSetLowColor(const rgb_color &color) +{ + BeginOp(B_PIC_SET_BACK_COLOR); + Write(color); + EndOp(); + return B_OK; +} + + +status_t +PictureDataWriter::WriteDrawRect(const BRect &rect, const bool &fill) +{ + BeginOp(fill ? B_PIC_FILL_RECT : B_PIC_STROKE_RECT); + Write(rect); + EndOp(); + return B_OK; +} + + +status_t +PictureDataWriter::WriteDrawRoundRect(const BRect &rect, const BPoint &radius, const bool &fill) +{ + BeginOp(fill ? B_PIC_FILL_ROUND_RECT : B_PIC_STROKE_ROUND_RECT); + Write(rect); + Write(radius); + EndOp(); + return B_OK; +} + + +status_t +PictureDataWriter::WriteDrawEllipse(const BRect &rect, const bool &fill) +{ + BeginOp(fill ? B_PIC_FILL_ELLIPSE : B_PIC_STROKE_ELLIPSE); + Write(rect); + EndOp(); + return B_OK; +} + + +status_t +PictureDataWriter::WriteDrawArc(const BPoint ¢er, const BPoint &radius, + const float &startTheta, const float &arcTheta, const bool &fill) +{ + BeginOp(fill ? B_PIC_FILL_ARC : B_PIC_STROKE_ARC); + Write(center); + Write(radius); + Write(startTheta); + Write(arcTheta); + EndOp(); + return B_OK; +} + + +status_t +PictureDataWriter::WriteStrokeLine(const BPoint &start, const BPoint &end) +{ + BeginOp(B_PIC_STROKE_LINE); + Write(start); + Write(end); + EndOp(); + return B_OK; +} + + +status_t +PictureDataWriter::WriteDrawString(const BPoint &where, const char *string, + const int32 &length, const escapement_delta &escapement) +{ + BeginOp(B_PIC_SET_PEN_LOCATION); + Write(where); + EndOp(); + + BeginOp(B_PIC_DRAW_STRING); + Write(length); + WriteData(string, length); + Write(escapement.space); + Write(escapement.nonspace); + EndOp(); + + return B_OK; +} + + +status_t +PictureDataWriter::WriteDrawShape(const int32 &opCount, const void *opList, + const int32 &ptCount, const void *ptList, const bool &fill) +{ + BeginOp(fill ? B_PIC_FILL_SHAPE : B_PIC_STROKE_SHAPE); + Write(opCount); + WriteData(opList, opCount * sizeof(uint32)); + Write(ptCount); + WriteData(ptList, ptCount * sizeof(BPoint)); + EndOp(); + + return B_OK; +} + + +status_t +PictureDataWriter::WriteDrawBitmap(const BRect &srcRect, const BRect &dstRect, const int32 &width, const int32 &height, + const int32 &bytesPerRow, const int32 &colorSpace, const int32 &flags, + const void *data, const int32 &length) +{ + BeginOp(B_PIC_DRAW_PIXELS); + Write(srcRect); + Write(dstRect); + Write(width); + Write(height); + Write(bytesPerRow); + Write(colorSpace); + Write(flags); + Write(length); + WriteData(data, length); + EndOp(); + return B_OK; +} + + +status_t +PictureDataWriter::WritePushState() +{ + BeginOp(B_PIC_PUSH_STATE); + EndOp(); + return B_OK; +} + + + +status_t +PictureDataWriter::WritePopState() +{ + BeginOp(B_PIC_POP_STATE); + EndOp(); + return B_OK; +} + + +// private +status_t +PictureDataWriter::BeginOp(const int16 &op) +{ + fStack.push(fData->Position()); + fData->Write(&op, sizeof(op)); + + // Init the size of the opcode block to 0 + size_t size = 0; + fData->Write(&size, sizeof(size)); + return B_OK; +} + + +status_t +PictureDataWriter::EndOp() +{ + off_t curPos = fData->Position(); + off_t stackPos = fStack.top(); + fStack.pop(); + + // The size of the op is calculated like this: + // current position on the stream minus the position on the stack, + // minus the space occupied by the op code itself (int16) + // and the space occupied by the size field (size_t) + size_t size = curPos - stackPos - sizeof(size_t) - sizeof(int16); + + // Size was set to 0 in BeginOp(). Now we overwrite it with the correct value + fData->Seek(stackPos + sizeof(int16), SEEK_SET); + fData->Write(&size, sizeof(size)); + fData->Seek(curPos, SEEK_SET); + return B_OK; +} + + +status_t +PictureDataWriter::WriteData(const void *data, size_t size) +{ + return fData->Write(data, size); +} diff --git a/src/kits/interface/PicturePlayer.cpp b/src/kits/interface/PicturePlayer.cpp index 6eef79ef10..934e407640 100644 --- a/src/kits/interface/PicturePlayer.cpp +++ b/src/kits/interface/PicturePlayer.cpp @@ -40,7 +40,7 @@ typedef void (*fnc_DrawPixels)(void *, BRect, BRect, int32, int32, int32, typedef void (*fnc_BShape)(void*, BShape*); -PicturePlayer::PicturePlayer(void *data, int32 size, BList *pictures) +PicturePlayer::PicturePlayer(const void *data, int32 size, BList *pictures) : fData(data, size), fPictures(pictures) { @@ -537,7 +537,7 @@ PicturePlayer::Play(void **callBackTable, int32 tableEntries, void *userData) // If we didn't read enough bytes, skip them. This is not a error // since the instructions can change over time. - if (op != B_PIC_ENTER_STATE_CHANGE && op != B_PIC_ENTER_FONT_STATE && fData.Position() - pos < size) + if (/*op != B_PIC_ENTER_STATE_CHANGE && op != B_PIC_ENTER_FONT_STATE && */fData.Position() - pos < size) fData.Seek(size - (fData.Position() - pos), SEEK_CUR); // TODO: what if too much was read, should we return B_ERROR? diff --git a/src/servers/app/ServerPicture.cpp b/src/servers/app/ServerPicture.cpp index 5f015d7ac3..0f639e134d 100644 --- a/src/servers/app/ServerPicture.cpp +++ b/src/servers/app/ServerPicture.cpp @@ -26,6 +26,7 @@ #include #include +using std::stack; class ShapePainter : public BShapeIterator { public: @@ -602,16 +603,18 @@ const void *tableEntries[] = { // ServerPicture ServerPicture::ServerPicture() + :PictureDataWriter(&fData) { fToken = gTokenSpace.NewToken(kPictureToken, this); } ServerPicture::ServerPicture(const ServerPicture &picture) + :PictureDataWriter(&fData) { fToken = gTokenSpace.NewToken(kPictureToken, this); - AddData(picture.Data(), picture.DataLength()); + fData.Write(picture.Data(), picture.DataLength()); } @@ -619,38 +622,7 @@ ServerPicture::~ServerPicture() { } - -void -ServerPicture::BeginOp(int16 op) -{ - fStack.push(fData.Position()); - fData.Write(&op, sizeof(op)); - - // Init the size of the opcode block to 0 - size_t size = 0; - fData.Write(&size, sizeof(size)); -} - - -void -ServerPicture::EndOp() -{ - off_t curPos = fData.Position(); - off_t stackPos = fStack.top(); - fStack.pop(); - - // The size of the op is calculated like this: - // current position on the stream minus the position on the stack, - // minus the space occupied by the op code itself (int16) - // and the space occupied by the size field (size_t) - size_t size = curPos - stackPos - sizeof(size_t) - sizeof(int16); - - // Size was set to 0 in BeginOp(). Now we overwrite it with the correct value - fData.Seek(stackPos + sizeof(int16), SEEK_SET); - fData.Write(&size, sizeof(size)); - fData.Seek(curPos, SEEK_SET); -} - +/* void ServerPicture::EnterStateChange() @@ -751,11 +723,11 @@ ServerPicture::AddData(const void *data, int32 size) fData.Write(data, size); } - +*/ void ServerPicture::SyncState(ViewLayer *view) { - BeginOp(B_PIC_ENTER_STATE_CHANGE); +/* BeginOp(B_PIC_ENTER_STATE_CHANGE); BeginOp(B_PIC_SET_PEN_LOCATION); AddCoord(view->CurrentState()->PenLocation()); @@ -797,6 +769,7 @@ ServerPicture::SyncState(ViewLayer *view) EndOp(); EndOp(); +*/ } diff --git a/src/servers/app/ServerPicture.h b/src/servers/app/ServerPicture.h index da407a7b94..c114cbb478 100644 --- a/src/servers/app/ServerPicture.h +++ b/src/servers/app/ServerPicture.h @@ -1,42 +1,22 @@ #ifndef __SERVER_PICTURE_H #define __SERVER_PICTURE_H -#include -#include -#include #include -#include -#include - -using std::stack; +#include class ServerApp; class ViewLayer; -class ServerPicture { +class ServerPicture : public PictureDataWriter { public: int32 Token() { return fToken; } - void BeginOp(int16 op); - void EndOp(); - void EnterStateChange(); void ExitStateChange(); void EnterFontChange(); void ExitFontChange(); - void AddInt8(int8 data); - void AddInt16(int16 data); - void AddInt32(int32 data); - void AddInt64(int64 data); - void AddFloat(float data); - void AddCoord(BPoint data); - void AddRect(BRect data); - void AddColor(rgb_color data); - void AddString(const char *data); - void AddData(const void *data, int32 size); - void SyncState(ViewLayer *view); void Play(ViewLayer *view); @@ -53,7 +33,6 @@ friend class ServerApp; int32 fToken; BMallocIO fData; - stack fStack; // DrawState *fState; }; diff --git a/src/servers/app/ServerWindow.cpp b/src/servers/app/ServerWindow.cpp index 60d3db1d36..71a1decc3e 100644 --- a/src/servers/app/ServerWindow.cpp +++ b/src/servers/app/ServerWindow.cpp @@ -42,7 +42,6 @@ #include #include -#include #include #include #include @@ -2307,42 +2306,28 @@ ServerWindow::_DispatchPictureMessage(int32 code, BPrivate::LinkReceiver &link) link.Read(&x); link.Read(&y); - picture->BeginOp(B_PIC_SET_ORIGIN); - picture->AddCoord(BPoint(x, y)); - picture->EndOp(); + picture->WriteSetOrigin(BPoint(x, y)); break; } case AS_LAYER_INVERT_RECT: { - picture->BeginOp(B_PIC_SET_DRAWING_MODE); - picture->AddInt16((int16)B_OP_INVERT); - picture->EndOp(); - BRect rect; link.Read(&rect); - picture->BeginOp(B_PIC_FILL_RECT); - picture->AddRect(rect); - picture->EndOp(); - - picture->BeginOp(B_PIC_SET_DRAWING_MODE); - picture->AddInt16((int16)B_OP_COPY); - picture->EndOp(); + picture->WriteInvertRect(rect); break; } case AS_LAYER_PUSH_STATE: { - picture->BeginOp(B_PIC_PUSH_STATE); - picture->EndOp(); + picture->WritePushState(); break; } case AS_LAYER_POP_STATE: { - picture->BeginOp(B_PIC_POP_STATE); - picture->EndOp(); + picture->WritePopState(); break; } @@ -2351,29 +2336,36 @@ ServerWindow::_DispatchPictureMessage(int32 code, BPrivate::LinkReceiver &link) int8 drawingMode; link.Read(&drawingMode); - picture->BeginOp(B_PIC_SET_DRAWING_MODE); - picture->AddInt16((int16)drawingMode); - picture->EndOp(); + picture->WriteSetDrawingMode((drawing_mode)drawingMode); break; } - + case AS_LAYER_SET_PEN_SIZE: { float penSize; link.Read(&penSize); - picture->BeginOp(B_PIC_SET_PEN_SIZE); - picture->AddFloat(penSize); - picture->EndOp(); + picture->WriteSetPenSize(penSize); break; } + case AS_LAYER_SET_LINE_MODE: + { + int8 lineCap, lineJoin; + float miterLimit; + + link.Read(&lineCap); + link.Read(&lineJoin); + link.Read(&miterLimit); + + picture->WriteSetLineMode((cap_mode)lineCap, (join_mode)lineJoin, miterLimit); + + break; + } case AS_LAYER_SET_SCALE: { float scale; link.Read(&scale); - picture->BeginOp(B_PIC_SET_SCALE); - picture->AddFloat(scale); - picture->EndOp(); + picture->WriteSetScale(scale); break; } @@ -2383,9 +2375,7 @@ ServerWindow::_DispatchPictureMessage(int32 code, BPrivate::LinkReceiver &link) BRect rect; link.Read(&rect); - picture->BeginOp(code == AS_FILL_RECT ? B_PIC_FILL_RECT : B_PIC_STROKE_RECT); - picture->AddRect(rect); - picture->EndOp(); + picture->WriteDrawRect(rect, code == AS_FILL_RECT); break; } @@ -2399,10 +2389,7 @@ ServerWindow::_DispatchPictureMessage(int32 code, BPrivate::LinkReceiver &link) link.Read(&radii.x); link.Read(&radii.y); - picture->BeginOp(code == AS_FILL_ROUNDRECT ? B_PIC_FILL_ROUND_RECT : B_PIC_STROKE_ROUND_RECT); - picture->AddRect(rect); - picture->AddCoord(radii); - picture->EndOp(); + picture->WriteDrawRoundRect(rect, radii, code == AS_FILL_ROUNDRECT); break; } @@ -2411,11 +2398,7 @@ ServerWindow::_DispatchPictureMessage(int32 code, BPrivate::LinkReceiver &link) { BRect rect; link.Read(&rect); - picture->BeginOp(code == AS_FILL_ELLIPSE ? B_PIC_FILL_ELLIPSE : - B_PIC_STROKE_ELLIPSE); - picture->AddRect(rect); - picture->EndOp(); - + picture->WriteDrawEllipse(rect, code == AS_FILL_ELLIPSE); break; } @@ -2431,12 +2414,7 @@ ServerWindow::_DispatchPictureMessage(int32 code, BPrivate::LinkReceiver &link) BPoint radii((rect.Width() + 1) / 2, (rect.Height() + 1) / 2); BPoint center = rect.LeftTop() + radii; - picture->BeginOp(code == AS_FILL_ARC ? B_PIC_FILL_ARC : B_PIC_STROKE_ARC); - picture->AddCoord(center); - picture->AddCoord(radii); - picture->AddFloat(startTheta); - picture->AddFloat(arcTheta); - picture->EndOp(); + picture->WriteDrawArc(center, radii, startTheta, arcTheta, code == AS_FILL_ARC); break; } @@ -2449,10 +2427,7 @@ ServerWindow::_DispatchPictureMessage(int32 code, BPrivate::LinkReceiver &link) link.Read(&x2); link.Read(&y2); - picture->BeginOp(B_PIC_STROKE_LINE); - picture->AddCoord(BPoint(x1, y1)); - picture->AddCoord(BPoint(x2, y2)); - picture->EndOp(); + picture->WriteStrokeLine(BPoint(x1, y1), BPoint(x2, y2)); break; } @@ -2463,8 +2438,7 @@ ServerWindow::_DispatchPictureMessage(int32 code, BPrivate::LinkReceiver &link) if (lineCount <= 0) break; - picture->BeginOp(B_PIC_PUSH_STATE); - picture->EndOp(); + picture->WritePushState(); for (int32 i = 0; i < lineCount; i++) { float x1, y1, x2, y2; @@ -2476,18 +2450,11 @@ ServerWindow::_DispatchPictureMessage(int32 code, BPrivate::LinkReceiver &link) rgb_color color; link.Read(&color); - picture->BeginOp(B_PIC_SET_FORE_COLOR); - picture->AddColor(color); - picture->EndOp(); - - picture->BeginOp(B_PIC_STROKE_LINE); - picture->AddCoord(BPoint(x1, y1)); - picture->AddCoord(BPoint(x2, y2)); - picture->EndOp(); + picture->WriteSetHighColor(color); + picture->WriteStrokeLine(BPoint(x1, y1), BPoint(x2, y2)); } - picture->BeginOp(B_PIC_POP_STATE); - picture->EndOp(); + picture->WritePopState(); break; } @@ -2497,9 +2464,10 @@ ServerWindow::_DispatchPictureMessage(int32 code, BPrivate::LinkReceiver &link) rgb_color color; link.Read(&color, sizeof(rgb_color)); - picture->BeginOp(code == AS_LAYER_SET_HIGH_COLOR ? B_PIC_SET_FORE_COLOR : B_PIC_SET_BACK_COLOR); - picture->AddColor(color); - picture->EndOp(); + if (code == AS_LAYER_SET_HIGH_COLOR) + picture->WriteSetHighColor(color); + else + picture->WriteSetLowColor(color); break; } @@ -2515,16 +2483,7 @@ ServerWindow::_DispatchPictureMessage(int32 code, BPrivate::LinkReceiver &link) link.Read(&delta); link.ReadString(&string); - picture->BeginOp(B_PIC_SET_PEN_LOCATION); - picture->AddCoord(location); - picture->EndOp(); - - picture->BeginOp(B_PIC_DRAW_STRING); - picture->AddInt32(length); - picture->AddData(string, length); - picture->AddFloat(delta.space); - picture->AddFloat(delta.nonspace); - picture->EndOp(); + picture->WriteDrawString(location, string, length, delta); free(string); break; @@ -2547,12 +2506,8 @@ ServerWindow::_DispatchPictureMessage(int32 code, BPrivate::LinkReceiver &link) && 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->AddInt32(opCount); - picture->AddData(opList, opCount * sizeof(uint32)); - picture->AddInt32(ptCount); - picture->AddData(ptList, ptCount * sizeof(BPoint)); - picture->EndOp(); + const bool fill = (code == AS_FILL_SHAPE); + picture->WriteDrawShape(opCount, opList, ptCount, ptList, fill); } delete[] opList; delete[] ptList; @@ -2575,21 +2530,13 @@ ServerWindow::_DispatchPictureMessage(int32 code, BPrivate::LinkReceiver &link) if (bitmap == NULL) break; - picture->BeginOp(B_PIC_DRAW_PIXELS); - picture->AddRect(sourceRect); - picture->AddRect(destRect); - picture->AddInt32(bitmap->Width()); - picture->AddInt32(bitmap->Height()); - picture->AddInt32(bitmap->BytesPerRow()); - picture->AddInt32(bitmap->ColorSpace()); - picture->AddInt32(/*bitmap->Flags()*/0); - picture->AddInt32(bitmap->BitsLength()); - picture->AddData((void *)bitmap->Bits(), bitmap->BitsLength()); - picture->EndOp(); + picture->WriteDrawBitmap(sourceRect, destRect, bitmap->Width(), bitmap->Height(), + bitmap->BytesPerRow(), bitmap->ColorSpace(), /*bitmap->Flags()*/0, + bitmap->Bits(), bitmap->BitsLength()); break; } - +/* case AS_LAYER_SET_BLENDING_MODE: { int8 srcAlpha, alphaFunc; @@ -2603,7 +2550,7 @@ ServerWindow::_DispatchPictureMessage(int32 code, BPrivate::LinkReceiver &link) picture->EndOp(); break; - } + }*/ default: return false; }