Implemented the following BPicture ops: fill region, stroke/fill arc,

stroke/fill polygon, stroke/fill bezier. some work towards drawing of 
nested pictures.


git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@21918 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
Stefano Ceccherini
2007-08-13 07:20:43 +00:00
parent 337171e417
commit ed5de868df
7 changed files with 234 additions and 16 deletions
@@ -36,6 +36,10 @@ public:
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 WriteDrawPolygon(const int32 &numPoints, BPoint *points,
const bool &isClosed, const bool &fill);
status_t WriteDrawBezier(const BPoint points[4], const bool &fill);
status_t WriteStrokeLine(const BPoint &start, const BPoint &end);
status_t WriteSetHighColor(const rgb_color &color);
@@ -48,7 +52,9 @@ public:
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 WriteDrawPicture(const BPoint &where, const int32 &token);
status_t WriteSetFontFamily(const font_family &family);
status_t WriteSetFontStyle(const font_style &style);
status_t WriteSetFontSpacing(const int32 &spacing);
+52 -1
View File
@@ -221,6 +221,40 @@ PictureDataWriter::WriteDrawArc(const BPoint &center, const BPoint &radius,
}
status_t
PictureDataWriter::WriteDrawPolygon(const int32 &numPoints, BPoint *points,
const bool &isClosed, const bool &fill)
{
try {
BeginOp(fill ? B_PIC_FILL_POLYGON : B_PIC_STROKE_POLYGON);
Write<int32>(numPoints);
for (int32 i = 0; i < numPoints; i++)
Write<BPoint>(points[i]);
if (!fill)
Write<uint8>((uint8)isClosed);
EndOp();
} catch (status_t &status) {
return status;
}
return B_OK;
}
status_t
PictureDataWriter::WriteDrawBezier(const BPoint points[4], const bool &fill)
{
try {
BeginOp(fill ? B_PIC_FILL_BEZIER : B_PIC_STROKE_BEZIER);
for (int32 i = 0; i < 4; i++)
Write<BPoint>(points[i]);
EndOp();
} catch (status_t &status) {
return status;
}
return B_OK;
}
status_t
PictureDataWriter::WriteStrokeLine(const BPoint &start, const BPoint &end)
{
@@ -304,6 +338,23 @@ PictureDataWriter::WriteDrawBitmap(const BRect &srcRect, const BRect &dstRect, c
}
status_t
PictureDataWriter::WriteDrawPicture(const BPoint &where, const int32 &token)
{
// TODO: I'm not sure about this function. I think we need to attach the picture
// data too. The token won't be sufficient in many cases.
try {
BeginOp(B_PIC_DRAW_PICTURE);
Write<BPoint>(where);
Write<int32>(token);
EndOp();
} catch (status_t &status) {
return status;
}
return B_OK;
}
status_t
PictureDataWriter::WriteSetFontFamily(const font_family &family)
{
@@ -493,6 +544,6 @@ PictureDataWriter::WriteData(const void *data, size_t size)
ssize_t result = fData->Write(data, size);
if (result < 0)
THROW_ERROR(result);
if (result != size)
if ((size_t)result != size)
THROW_ERROR(B_IO_ERROR);
}
+4
View File
@@ -38,6 +38,7 @@ typedef void (*fnc_ss)(void *, int16, int16);
typedef void (*fnc_PBRecti)(void*, const BRect*, int32);
typedef void (*fnc_DrawPixels)(void *, BRect, BRect, int32, int32, int32,
int32, int32, const void *);
typedef void (*fnc_DrawPicture)(void *, BPoint, int32);
typedef void (*fnc_BShape)(void*, BShape*);
@@ -230,6 +231,9 @@ PicturePlayer::Play(void **callBackTable, int32 tableEntries, void *userData)
case B_PIC_DRAW_PICTURE:
{
((fnc_DrawPicture)callBackTable[19])(userData,
*reinterpret_cast<const BPoint *>(data),
*reinterpret_cast<const int32 *>(data + sizeof(BPoint)));
break;
}
+2 -1
View File
@@ -3091,7 +3091,8 @@ BView::SetDiskMode(char* filename, long offset)
}
void BView::BeginPicture(BPicture *picture)
void
BView::BeginPicture(BPicture *picture)
{
if (do_owner_check() && picture && picture->usurped == NULL) {
picture->usurp(cpicture);
+58 -7
View File
@@ -10,6 +10,7 @@
#include "DrawingEngine.h"
#include "ServerApp.h"
#include "ServerBitmap.h"
#include "ServerPicture.h"
#include "ServerTokenSpace.h"
@@ -25,6 +26,7 @@
#include <ShapePrivate.h>
#include <Bitmap.h>
#include <List.h>
#include <Shape.h>
#include <stdio.h>
@@ -108,7 +110,7 @@ ShapePainter::IterateClose(void)
void
ShapePainter::Draw(ViewLayer *view, BRect frame, bool filled)
{
// We're going to draw the currently iterated picture.
// We're going to draw the currently iterated shape.
int32 opCount, ptCount;
opCount = fOpStack.size();
ptCount = fPtStack.size();
@@ -136,6 +138,8 @@ ShapePainter::Draw(ViewLayer *view, BRect frame, bool filled)
}
}
// drawing functions
static void
get_polygon_frame(const BPoint *points, int32 numPoints, BRect *_frame)
{
@@ -406,7 +410,6 @@ static void
draw_pixels(ViewLayer *view, BRect src, BRect dest, int32 width, int32 height,
int32 bytesPerRow, int32 pixelFormat, int32 flags, const void *data)
{
// TODO: Review this
UtilityBitmap bitmap(BRect(0, 0, width - 1, height - 1), (color_space)pixelFormat, flags, bytesPerRow);
if (!bitmap.IsValid())
@@ -420,6 +423,17 @@ draw_pixels(ViewLayer *view, BRect src, BRect dest, int32 width, int32 height,
}
static void
draw_picture(ViewLayer *view, BPoint where, int32 token)
{
ServerPicture *picture = view->Window()->ServerWindow()->App()->FindPicture(token);
if (picture != NULL) {
view->CurrentState()->SetOrigin(where);
picture->Play(view);
}
}
static void
set_clipping_rects(ViewLayer *view, const BRect *rects, uint32 numRects)
{
@@ -667,7 +681,7 @@ const void *tableEntries[] = {
(const void *)fill_shape,
(const void *)draw_string,
(const void *)draw_pixels,
(const void *)reserved, // TODO: This is probably "draw_picture". Investigate
(const void *)draw_picture,
(const void *)set_clipping_rects,
(const void *)clip_to_picture,
(const void *)push_state,
@@ -703,7 +717,9 @@ const void *tableEntries[] = {
ServerPicture::ServerPicture()
:
PictureDataWriter(),
fData(NULL)
fData(NULL),
fPictures(NULL),
fUsurped(NULL)
{
fToken = gTokenSpace.NewToken(kPictureToken, this);
fData = new (std::nothrow) BMallocIO();
@@ -715,7 +731,9 @@ ServerPicture::ServerPicture()
ServerPicture::ServerPicture(const ServerPicture &picture)
:
PictureDataWriter(),
fData(NULL)
fData(NULL),
fPictures(NULL),
fUsurped(NULL)
{
fToken = gTokenSpace.NewToken(kPictureToken, this);
@@ -738,7 +756,9 @@ ServerPicture::ServerPicture(const ServerPicture &picture)
ServerPicture::ServerPicture(const char *fileName, const int32 &offset)
:
PictureDataWriter(),
fData(NULL)
fData(NULL),
fPictures(NULL),
fUsurped(NULL)
{
BPrivate::Storage::OffsetFile *file =
new BPrivate::Storage::OffsetFile(new BFile(fileName, B_READ_WRITE), (off_t)offset);
@@ -757,6 +777,7 @@ ServerPicture::~ServerPicture()
{
delete fData;
gTokenSpace.RemoveToken(fToken);
delete fPictures;
}
@@ -800,11 +821,41 @@ ServerPicture::Play(ViewLayer *view)
if (mallocIO == NULL)
return;
PicturePlayer player(mallocIO->Buffer(), mallocIO->BufferLength(), NULL);
PicturePlayer player(mallocIO->Buffer(), mallocIO->BufferLength(), fPictures);
player.Play(const_cast<void **>(tableEntries), sizeof(tableEntries) / sizeof(void *), view);
}
void
ServerPicture::Usurp(ServerPicture *picture)
{
fUsurped = picture;
}
ServerPicture *
ServerPicture::StepDown()
{
ServerPicture *old = fUsurped;
fUsurped = NULL;
return old;
}
bool
ServerPicture::NestPicture(ServerPicture *picture)
{
if (fPictures == NULL)
fPictures = new (std::nothrow) BList;
if (fPictures == NULL
|| !fPictures->AddItem(picture))
return false;
return true;
}
off_t
ServerPicture::DataLength() const
{
+9 -2
View File
@@ -12,6 +12,7 @@
class ServerApp;
class ViewLayer;
class BPrivate::LinkReceiver;
class BList;
class ServerPicture : public PictureDataWriter {
public:
int32 Token() { return fToken; }
@@ -22,10 +23,14 @@ public:
void EnterFontChange();
void ExitFontChange();
void SyncState(ViewLayer *view);
void SyncState(ViewLayer *view);
void Play(ViewLayer *view);
void Usurp(ServerPicture *newPicture);
ServerPicture* StepDown();
bool NestPicture(ServerPicture *picture);
off_t DataLength() const;
status_t ImportData(BPrivate::LinkReceiver &link);
@@ -42,6 +47,8 @@ friend class ServerApp;
int32 fToken;
BPositionIO *fData;
// DrawState *fState;
BList *fPictures;
ServerPicture *fUsurped;
};
#endif // __SERVER_PICTURE_H
+102 -4
View File
@@ -2171,14 +2171,14 @@ ServerWindow::_DispatchViewDrawingMessage(int32 code, BPrivate::LinkReceiver &li
case AS_FILL_TRIANGLE:
{
DTRACE(("ServerWindow %s: Message AS_STROKE/FILL_TRIANGLE\n", Title()));
BPoint pts[3];
BPoint pts[3];
BRect rect;
for (int32 i = 0; i < 3; i++) {
for (int32 i = 0; i < 3; i++) {
link.Read<BPoint>(&(pts[i]));
fCurrentLayer->ConvertToScreenForDrawing(&pts[i]);
}
}
link.Read<BRect>(&rect);
@@ -2439,6 +2439,18 @@ ServerWindow::_DispatchPictureMessage(int32 code, BPrivate::LinkReceiver &link)
break;
}
case AS_FILL_REGION:
{
// There is no B_PIC_FILL_REGION op, we have to
// implement it using B_PIC_FILL_RECT
BRegion region;
if (link.ReadRegion(&region) < B_OK)
break;
for (int32 i = 0; i < region.CountRects(); i++)
picture->WriteDrawRect(region.RectAt(i), true);
break;
}
case AS_STROKE_ROUNDRECT:
case AS_FILL_ROUNDRECT:
{
@@ -2478,6 +2490,57 @@ ServerWindow::_DispatchPictureMessage(int32 code, BPrivate::LinkReceiver &link)
break;
}
case AS_STROKE_TRIANGLE:
case AS_FILL_TRIANGLE:
{
// There is no B_PIC_FILL/STROKE_TRIANGLE op,
// we implement it using B_PIC_FILL/STROKE_POLYGON
BPoint points[3];
for (int32 i = 0; i < 3; i++) {
link.Read<BPoint>(&(points[i]));
}
BRect rect;
link.Read<BRect>(&rect);
picture->WriteDrawPolygon(3, points,
true, code == AS_FILL_TRIANGLE);
break;
}
case AS_STROKE_POLYGON:
case AS_FILL_POLYGON:
{
BRect polyFrame;
bool isClosed = true;
int32 pointCount;
const bool fill = (code == AS_FILL_POLYGON);
link.Read<BRect>(&polyFrame);
if (code == AS_STROKE_POLYGON)
link.Read<bool>(&isClosed);
link.Read<int32>(&pointCount);
BPoint* pointList = new(nothrow) BPoint[pointCount];
if (link.Read(pointList, pointCount * sizeof(BPoint)) >= B_OK) {
picture->WriteDrawPolygon(pointCount, pointList,
isClosed && pointCount > 2, fill);
}
delete[] pointList;
break;
}
case AS_STROKE_BEZIER:
case AS_FILL_BEZIER:
{
BPoint points[4];
for (int32 i = 0; i < 4; i++) {
link.Read<BPoint>(&(points[i]));
}
picture->WriteDrawBezier(points, code == AS_FILL_BEZIER);
break;
}
case AS_STROKE_LINE:
{
float x1, y1, x2, y2;
@@ -2604,6 +2667,41 @@ ServerWindow::_DispatchPictureMessage(int32 code, BPrivate::LinkReceiver &link)
break;
}
case AS_LAYER_DRAW_PICTURE:
{
int32 token;
if (link.Read<int32>(&token) == B_OK) {
BPoint where;
link.Read<BPoint>(&where);
picture->WriteDrawPicture(where, token);
}
break;
}
case AS_LAYER_BEGIN_PICTURE:
{
ServerPicture *newPicture = App()->CreatePicture();
newPicture->Usurp(picture);
newPicture->SyncState(fCurrentLayer);
fCurrentLayer->SetPicture(newPicture);
break;
}
case AS_LAYER_END_PICTURE:
{
ServerPicture *steppedDown = picture->StepDown();
if (!steppedDown)
return false;
steppedDown->NestPicture(picture);
fCurrentLayer->SetPicture(steppedDown);
fLink.StartMessage(B_OK);
fLink.Attach<int32>(picture->Token());
fLink.Flush();
return true;
}
/*
case AS_LAYER_SET_BLENDING_MODE:
{