Moved picture data writing to its own class, thus simplifying code in

various places. Implemented SetLineMode op for BPicture, fixed shape 
drawing (I accidentally broke it in the previous commit).


git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@19264 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
Stefano Ceccherini
2006-11-12 20:00:36 +00:00
parent fd5c02b25c
commit 420fe80e5c
7 changed files with 380 additions and 155 deletions
@@ -0,0 +1,56 @@
#ifndef __PICTUREDATAWRITER_H
#define __PICTUREDATAWRITER_H
#include <InterfaceDefs.h>
#include <Font.h>
#include <OS.h>
#include <stack>
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 &center, 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<off_t> fStack;
status_t WriteData(const void *data, size_t size);
template <typename T> status_t Write(const T &data) { return WriteData(&data, sizeof(data)); }
status_t BeginOp(const int16 &op);
status_t EndOp();
};
#endif // __PICTUREDATAWRITER_H
+1
View File
@@ -81,6 +81,7 @@ MergeObject <libbe>interface_kit.o :
OutlineListView.cpp
Picture.cpp
PictureButton.cpp
PictureDataWriter.cpp
PicturePlayer.cpp
Point.cpp
Polygon.cpp
+269
View File
@@ -0,0 +1,269 @@
#include <DataIO.h>
#include <Point.h>
#include <Rect.h>
#include <PictureDataWriter.h>
#include <PictureProtocol.h>
PictureDataWriter::PictureDataWriter(BPositionIO *data)
:
fData(data)
{
}
status_t
PictureDataWriter::WriteSetOrigin(const BPoint &point)
{
BeginOp(B_PIC_SET_ORIGIN);
Write<BPoint>(point);
EndOp();
return B_OK;
}
status_t
PictureDataWriter::WriteInvertRect(const BRect &rect)
{
WriteSetDrawingMode(B_OP_INVERT);
BeginOp(B_PIC_FILL_RECT);
Write<BRect>(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>((int16)mode);
EndOp();
return B_OK;
}
status_t
PictureDataWriter::WriteSetPenSize(const float &penSize)
{
BeginOp(B_PIC_SET_PEN_SIZE);
Write<float>(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>((int16)cap);
Write<int16>((int16)join);
Write<float>(miterLimit);
EndOp();
return B_OK;
}
status_t
PictureDataWriter::WriteSetScale(const float &scale)
{
BeginOp(B_PIC_SET_SCALE);
Write<float>(scale);
EndOp();
return B_OK;
}
status_t
PictureDataWriter::WriteSetHighColor(const rgb_color &color)
{
BeginOp(B_PIC_SET_FORE_COLOR);
Write<rgb_color>(color);
EndOp();
return B_OK;
}
status_t
PictureDataWriter::WriteSetLowColor(const rgb_color &color)
{
BeginOp(B_PIC_SET_BACK_COLOR);
Write<rgb_color>(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<BRect>(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<BRect>(rect);
Write<BPoint>(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<BRect>(rect);
EndOp();
return B_OK;
}
status_t
PictureDataWriter::WriteDrawArc(const BPoint &center, const BPoint &radius,
const float &startTheta, const float &arcTheta, const bool &fill)
{
BeginOp(fill ? B_PIC_FILL_ARC : B_PIC_STROKE_ARC);
Write<BPoint>(center);
Write<BPoint>(radius);
Write<float>(startTheta);
Write<float>(arcTheta);
EndOp();
return B_OK;
}
status_t
PictureDataWriter::WriteStrokeLine(const BPoint &start, const BPoint &end)
{
BeginOp(B_PIC_STROKE_LINE);
Write<BPoint>(start);
Write<BPoint>(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<BPoint>(where);
EndOp();
BeginOp(B_PIC_DRAW_STRING);
Write<int32>(length);
WriteData(string, length);
Write<float>(escapement.space);
Write<float>(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<int32>(opCount);
WriteData(opList, opCount * sizeof(uint32));
Write<int32>(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<BRect>(srcRect);
Write<BRect>(dstRect);
Write<int32>(width);
Write<int32>(height);
Write<int32>(bytesPerRow);
Write<int32>(colorSpace);
Write<int32>(flags);
Write<int32>(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);
}
+2 -2
View File
@@ -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?
+8 -35
View File
@@ -26,6 +26,7 @@
#include <stdio.h>
#include <stack>
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();
*/
}
+2 -23
View File
@@ -1,42 +1,22 @@
#ifndef __SERVER_PICTURE_H
#define __SERVER_PICTURE_H
#include <Font.h>
#include <Rect.h>
#include <Region.h>
#include <DataIO.h>
#include <InterfaceDefs.h>
#include <stack>
using std::stack;
#include <PictureDataWriter.h>
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<off_t> fStack;
// DrawState *fState;
};
+42 -95
View File
@@ -42,7 +42,6 @@
#include <DirectWindowPrivate.h>
#include <MessagePrivate.h>
#include <PictureProtocol.h>
#include <PortLink.h>
#include <WindowInfo.h>
#include <WindowPrivate.h>
@@ -2307,42 +2306,28 @@ ServerWindow::_DispatchPictureMessage(int32 code, BPrivate::LinkReceiver &link)
link.Read<float>(&x);
link.Read<float>(&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<BRect>(&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<int8>(&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<float>(&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<int8>(&lineCap);
link.Read<int8>(&lineJoin);
link.Read<float>(&miterLimit);
picture->WriteSetLineMode((cap_mode)lineCap, (join_mode)lineJoin, miterLimit);
break;
}
case AS_LAYER_SET_SCALE:
{
float scale;
link.Read<float>(&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<BRect>(&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<float>(&radii.x);
link.Read<float>(&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<BRect>(&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<float>(&x2);
link.Read<float>(&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<rgb_color>(&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<escapement_delta>(&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;
}