Basically, this changeset implements BShape::ArcTo(). In more detail:
* Added BShape::ArcTo() and BShapeIterator::IterateArcTo(), using a previously unused virtual slot. (Added the symbols for binary compatibility for GCC2 and GCC4.) * Added operator=(), operator==() and operator!=() to BShape. * Added BShape::BezierTo() version taking three points, which is sometimes more convenient. * Added the four new shape data ops OP_LARGE_ARC_TO_CW, OP_LARGE_ARC_TO_CCW, OP_SMALL_ARC_TO_CW and OP_SMALL_ARC_TO_CCW. For a single arc, provided the radius is large enough, there are four possibilities to draw the arc, these are controlled by the two boolean flags to ArcTo() and mapped to the new commands accordingly. * Some style cleanup in Shape.cpp (sorry for mixing it up, but it gets worse below...) * Added ShapeTest to src/tests/servers/app. * Changed the way BShapes are transformed from view to screen space in the app_server. For arcs, it would be nontrivial to apply a proper transformation, it's much easier to let AGG take care of it. This affects ServerPicture as well. * Wrapped iterating the BShape into try/catch blocks in ShapeIterator. But I really don't understand the purpose of the class in the first place. Maybe it can now be dropped, since coordinates don't have to be transformed in place anymore. * Refactored copy&paste shape iteration code in Painter. The transformation to screen space happens there. * Since RemoteDrawingEngine needed to be adopted anyway, I also updated it for the new DrawString() with offsets version. But the client still needs to be adapted. * Style cleanup in Painter.h git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@35905 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
parent
fe0963a835
commit
76ab3f88df
@ -30,10 +30,13 @@ public:
|
|||||||
BPoint* bezierPts);
|
BPoint* bezierPts);
|
||||||
virtual status_t IterateClose();
|
virtual status_t IterateClose();
|
||||||
|
|
||||||
|
virtual status_t IterateArcTo(float& rx, float& ry,
|
||||||
|
float& angle, bool largeArc,
|
||||||
|
bool counterClockWise, BPoint& point);
|
||||||
|
|
||||||
status_t Iterate(BShape* shape);
|
status_t Iterate(BShape* shape);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
virtual void _ReservedShapeIterator1();
|
|
||||||
virtual void _ReservedShapeIterator2();
|
virtual void _ReservedShapeIterator2();
|
||||||
virtual void _ReservedShapeIterator3();
|
virtual void _ReservedShapeIterator3();
|
||||||
virtual void _ReservedShapeIterator4();
|
virtual void _ReservedShapeIterator4();
|
||||||
@ -53,6 +56,11 @@ public:
|
|||||||
virtual status_t Archive(BMessage* archive,
|
virtual status_t Archive(BMessage* archive,
|
||||||
bool deep = true) const;
|
bool deep = true) const;
|
||||||
|
|
||||||
|
BShape& operator=(const BShape& other);
|
||||||
|
|
||||||
|
bool operator==(const BShape& other) const;
|
||||||
|
bool operator!=(const BShape& other) const;
|
||||||
|
|
||||||
void Clear();
|
void Clear();
|
||||||
BRect Bounds() const;
|
BRect Bounds() const;
|
||||||
|
|
||||||
@ -61,6 +69,13 @@ public:
|
|||||||
status_t MoveTo(BPoint point);
|
status_t MoveTo(BPoint point);
|
||||||
status_t LineTo(BPoint linePoint);
|
status_t LineTo(BPoint linePoint);
|
||||||
status_t BezierTo(BPoint controlPoints[3]);
|
status_t BezierTo(BPoint controlPoints[3]);
|
||||||
|
status_t BezierTo(const BPoint& control1,
|
||||||
|
const BPoint& control2,
|
||||||
|
const BPoint& endPoint);
|
||||||
|
status_t ArcTo(float rx, float ry,
|
||||||
|
float angle, bool largeArc,
|
||||||
|
bool counterClockWise,
|
||||||
|
const BPoint& point);
|
||||||
status_t Close();
|
status_t Close();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright 2003-2006, Haiku.
|
* Copyright 2003-2010, Haiku.
|
||||||
* Distributed under the terms of the MIT License.
|
* Distributed under the terms of the MIT License.
|
||||||
*
|
*
|
||||||
* Authors:
|
* Authors:
|
||||||
@ -13,6 +13,10 @@
|
|||||||
#define OP_BEZIERTO 0x20000000
|
#define OP_BEZIERTO 0x20000000
|
||||||
#define OP_CLOSE 0x40000000
|
#define OP_CLOSE 0x40000000
|
||||||
#define OP_MOVETO 0x80000000
|
#define OP_MOVETO 0x80000000
|
||||||
|
#define OP_LARGE_ARC_TO_CW 0x01000000
|
||||||
|
#define OP_LARGE_ARC_TO_CCW 0x02000000
|
||||||
|
#define OP_SMALL_ARC_TO_CW 0x04000000
|
||||||
|
#define OP_SMALL_ARC_TO_CCW 0x08000000
|
||||||
|
|
||||||
|
|
||||||
struct shape_data {
|
struct shape_data {
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (c) 2001-2007, Haiku, Inc.
|
* Copyright (c) 2001-2010, Haiku, Inc.
|
||||||
* Distributed under the terms of the MIT license.
|
* Distributed under the terms of the MIT license.
|
||||||
*
|
*
|
||||||
* Authors:
|
* Authors:
|
||||||
@ -62,6 +62,18 @@ BShapeIterator::Iterate(BShape *shape)
|
|||||||
points += count;
|
points += count;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if ((op & OP_LARGE_ARC_TO_CW) || (op & OP_LARGE_ARC_TO_CCW)
|
||||||
|
|| (op & OP_SMALL_ARC_TO_CW) || (op & OP_SMALL_ARC_TO_CCW)) {
|
||||||
|
int32 count = data->opList[i] & 0x00FFFFFF;
|
||||||
|
for (int32 i = 0; i < count / 3; i++) {
|
||||||
|
IterateArcTo(points[0].x, points[0].y, points[1].x,
|
||||||
|
op & (OP_LARGE_ARC_TO_CW | OP_LARGE_ARC_TO_CCW),
|
||||||
|
op & (OP_SMALL_ARC_TO_CCW | OP_LARGE_ARC_TO_CCW),
|
||||||
|
points[2]);
|
||||||
|
points += 3;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (op & OP_CLOSE) {
|
if (op & OP_CLOSE) {
|
||||||
IterateClose();
|
IterateClose();
|
||||||
}
|
}
|
||||||
@ -72,15 +84,7 @@ BShapeIterator::Iterate(BShape *shape)
|
|||||||
|
|
||||||
|
|
||||||
status_t
|
status_t
|
||||||
BShapeIterator::IterateBezierTo(int32 bezierCount,
|
BShapeIterator::IterateMoveTo(BPoint* point)
|
||||||
BPoint *bezierPoints)
|
|
||||||
{
|
|
||||||
return B_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
status_t
|
|
||||||
BShapeIterator::IterateClose()
|
|
||||||
{
|
{
|
||||||
return B_OK;
|
return B_OK;
|
||||||
}
|
}
|
||||||
@ -94,18 +98,35 @@ BShapeIterator::IterateLineTo(int32 lineCount, BPoint *linePoints)
|
|||||||
|
|
||||||
|
|
||||||
status_t
|
status_t
|
||||||
BShapeIterator::IterateMoveTo ( BPoint *point )
|
BShapeIterator::IterateBezierTo(int32 bezierCount, BPoint* bezierPoints)
|
||||||
|
{
|
||||||
|
return B_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
status_t
|
||||||
|
BShapeIterator::IterateClose()
|
||||||
|
{
|
||||||
|
return B_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
status_t
|
||||||
|
BShapeIterator::IterateArcTo(float& rx, float& ry, float& angle, bool largeArc,
|
||||||
|
bool counterClockWise, BPoint& point)
|
||||||
{
|
{
|
||||||
return B_OK;
|
return B_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void BShapeIterator::_ReservedShapeIterator1() {}
|
|
||||||
void BShapeIterator::_ReservedShapeIterator2() {}
|
void BShapeIterator::_ReservedShapeIterator2() {}
|
||||||
void BShapeIterator::_ReservedShapeIterator3() {}
|
void BShapeIterator::_ReservedShapeIterator3() {}
|
||||||
void BShapeIterator::_ReservedShapeIterator4() {}
|
void BShapeIterator::_ReservedShapeIterator4() {}
|
||||||
|
|
||||||
|
|
||||||
|
// #pragma mark -
|
||||||
|
|
||||||
|
|
||||||
BShape::BShape()
|
BShape::BShape()
|
||||||
{
|
{
|
||||||
InitData();
|
InitData();
|
||||||
@ -207,6 +228,46 @@ BShape::Instantiate(BMessage *archive)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
BShape&
|
||||||
|
BShape::operator=(const BShape& other)
|
||||||
|
{
|
||||||
|
if (this != &other) {
|
||||||
|
Clear();
|
||||||
|
AddShape(&other);
|
||||||
|
}
|
||||||
|
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool
|
||||||
|
BShape::operator==(const BShape& other) const
|
||||||
|
{
|
||||||
|
if (this == &other)
|
||||||
|
return true;
|
||||||
|
|
||||||
|
shape_data* data = (shape_data*)fPrivateData;
|
||||||
|
shape_data* otherData = (shape_data*)other.fPrivateData;
|
||||||
|
|
||||||
|
if (data->opCount != otherData->opCount)
|
||||||
|
return false;
|
||||||
|
if (data->ptCount != otherData->ptCount)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
return memcmp(data->opList, otherData->opList,
|
||||||
|
data->opCount * sizeof(uint32)) == 0
|
||||||
|
&& memcmp(data->ptList, otherData->ptList,
|
||||||
|
data->ptCount * sizeof(BPoint)) == 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool
|
||||||
|
BShape::operator!=(const BShape& other) const
|
||||||
|
{
|
||||||
|
return !(*this == other);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
void
|
void
|
||||||
BShape::Clear()
|
BShape::Clear()
|
||||||
{
|
{
|
||||||
@ -341,6 +402,14 @@ BShape::LineTo(BPoint point)
|
|||||||
|
|
||||||
status_t
|
status_t
|
||||||
BShape::BezierTo(BPoint controlPoints[3])
|
BShape::BezierTo(BPoint controlPoints[3])
|
||||||
|
{
|
||||||
|
return BezierTo(controlPoints[0], controlPoints[1], controlPoints[2]);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
status_t
|
||||||
|
BShape::BezierTo(const BPoint& control1, const BPoint& control2,
|
||||||
|
const BPoint& endPoint)
|
||||||
{
|
{
|
||||||
if (!AllocatePts(3))
|
if (!AllocatePts(3))
|
||||||
return B_NO_MEMORY;
|
return B_NO_MEMORY;
|
||||||
@ -362,9 +431,54 @@ BShape::BezierTo(BPoint controlPoints[3])
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Add points
|
// Add points
|
||||||
data->ptList[data->ptCount++] = controlPoints[0];
|
data->ptList[data->ptCount++] = control1;
|
||||||
data->ptList[data->ptCount++] = controlPoints[1];
|
data->ptList[data->ptCount++] = control2;
|
||||||
data->ptList[data->ptCount++] = controlPoints[2];
|
data->ptList[data->ptCount++] = endPoint;
|
||||||
|
|
||||||
|
return B_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
status_t
|
||||||
|
BShape::ArcTo(float rx, float ry, float angle, bool largeArc,
|
||||||
|
bool counterClockWise, const BPoint& point)
|
||||||
|
{
|
||||||
|
if (!AllocatePts(3))
|
||||||
|
return B_NO_MEMORY;
|
||||||
|
|
||||||
|
shape_data* data = (shape_data*)fPrivateData;
|
||||||
|
|
||||||
|
uint32 op;
|
||||||
|
if (largeArc) {
|
||||||
|
if (counterClockWise)
|
||||||
|
op = OP_LARGE_ARC_TO_CCW;
|
||||||
|
else
|
||||||
|
op = OP_LARGE_ARC_TO_CW;
|
||||||
|
} else {
|
||||||
|
if (counterClockWise)
|
||||||
|
op = OP_SMALL_ARC_TO_CCW;
|
||||||
|
else
|
||||||
|
op = OP_SMALL_ARC_TO_CW;
|
||||||
|
}
|
||||||
|
|
||||||
|
// If the last op is MoveTo, replace the op and set the count
|
||||||
|
// If the last op is ArcTo increase the count
|
||||||
|
// Otherwise add the op
|
||||||
|
if (fBuildingOp == op || fBuildingOp == (op | OP_MOVETO)) {
|
||||||
|
fBuildingOp |= op;
|
||||||
|
fBuildingOp += 3;
|
||||||
|
data->opList[data->opCount - 1] = fBuildingOp;
|
||||||
|
} else {
|
||||||
|
if (!AllocateOps(1))
|
||||||
|
return B_NO_MEMORY;
|
||||||
|
fBuildingOp = op + 3;
|
||||||
|
data->opList[data->opCount++] = fBuildingOp;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Add points
|
||||||
|
data->ptList[data->ptCount++] = BPoint(rx, ry);
|
||||||
|
data->ptList[data->ptCount++] = BPoint(angle, 0);
|
||||||
|
data->ptList[data->ptCount++] = point;
|
||||||
|
|
||||||
return B_OK;
|
return B_OK;
|
||||||
}
|
}
|
||||||
@ -506,11 +620,12 @@ BShape::AllocatePts(int32 count)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// #pragma mark - R4.5 compatibility
|
// #pragma mark - binary compatibility
|
||||||
|
|
||||||
|
|
||||||
#if __GNUC__ < 3
|
#if __GNUC__ < 3
|
||||||
|
|
||||||
|
|
||||||
extern "C" BShape*
|
extern "C" BShape*
|
||||||
__6BShapeR6BShape(void* self, BShape& copyFrom)
|
__6BShapeR6BShape(void* self, BShape& copyFrom)
|
||||||
{
|
{
|
||||||
@ -525,4 +640,20 @@ Bounds__6BShape(BShape *self)
|
|||||||
return self->Bounds();
|
return self->Bounds();
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif // __GNUC__ < 3
|
|
||||||
|
extern "C" void
|
||||||
|
_ReservedShapeIterator1__14BShapeIterator(BShapeIterator* self)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
#else // __GNUC__ < 3
|
||||||
|
|
||||||
|
|
||||||
|
extern "C" void
|
||||||
|
_ZN14BShapeIterator23_ReservedShapeIterator1Ev(BShapeIterator* self)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
#endif // __GNUC__ >= 3
|
||||||
|
@ -42,7 +42,7 @@ using std::stack;
|
|||||||
|
|
||||||
class ShapePainter : public BShapeIterator {
|
class ShapePainter : public BShapeIterator {
|
||||||
public:
|
public:
|
||||||
ShapePainter();
|
ShapePainter(View* view);
|
||||||
virtual ~ShapePainter();
|
virtual ~ShapePainter();
|
||||||
|
|
||||||
status_t Iterate(const BShape* shape);
|
status_t Iterate(const BShape* shape);
|
||||||
@ -51,16 +51,21 @@ public:
|
|||||||
virtual status_t IterateLineTo(int32 lineCount, BPoint* linePts);
|
virtual status_t IterateLineTo(int32 lineCount, BPoint* linePts);
|
||||||
virtual status_t IterateBezierTo(int32 bezierCount, BPoint* bezierPts);
|
virtual status_t IterateBezierTo(int32 bezierCount, BPoint* bezierPts);
|
||||||
virtual status_t IterateClose();
|
virtual status_t IterateClose();
|
||||||
|
virtual status_t IterateArcTo(float& rx, float& ry,
|
||||||
|
float& angle, bool largeArc, bool counterClockWise, BPoint& point);
|
||||||
|
|
||||||
void Draw(View* view, BRect frame, bool filled);
|
void Draw(BRect frame, bool filled);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
View* fView;
|
||||||
stack<uint32> fOpStack;
|
stack<uint32> fOpStack;
|
||||||
stack<BPoint> fPtStack;
|
stack<BPoint> fPtStack;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
ShapePainter::ShapePainter()
|
ShapePainter::ShapePainter(View* view)
|
||||||
|
:
|
||||||
|
fView(view)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -81,8 +86,14 @@ ShapePainter::Iterate(const BShape* shape)
|
|||||||
status_t
|
status_t
|
||||||
ShapePainter::IterateMoveTo(BPoint* point)
|
ShapePainter::IterateMoveTo(BPoint* point)
|
||||||
{
|
{
|
||||||
|
try {
|
||||||
fOpStack.push(OP_MOVETO);
|
fOpStack.push(OP_MOVETO);
|
||||||
fPtStack.push(*point);
|
BPoint transformed(*point);
|
||||||
|
fView->ConvertToScreenForDrawing(&transformed);
|
||||||
|
fPtStack.push(transformed);
|
||||||
|
} catch (std::bad_alloc) {
|
||||||
|
return B_NO_MEMORY;
|
||||||
|
}
|
||||||
|
|
||||||
return B_OK;
|
return B_OK;
|
||||||
}
|
}
|
||||||
@ -91,9 +102,16 @@ ShapePainter::IterateMoveTo(BPoint* point)
|
|||||||
status_t
|
status_t
|
||||||
ShapePainter::IterateLineTo(int32 lineCount, BPoint* linePts)
|
ShapePainter::IterateLineTo(int32 lineCount, BPoint* linePts)
|
||||||
{
|
{
|
||||||
|
try {
|
||||||
fOpStack.push(OP_LINETO | lineCount);
|
fOpStack.push(OP_LINETO | lineCount);
|
||||||
for (int32 i = 0; i < lineCount; i++)
|
for (int32 i = 0; i < lineCount; i++) {
|
||||||
fPtStack.push(linePts[i]);
|
BPoint transformed(linePts[i]);
|
||||||
|
fView->ConvertToScreenForDrawing(&transformed);
|
||||||
|
fPtStack.push(transformed);
|
||||||
|
}
|
||||||
|
} catch (std::bad_alloc) {
|
||||||
|
return B_NO_MEMORY;
|
||||||
|
}
|
||||||
|
|
||||||
return B_OK;
|
return B_OK;
|
||||||
}
|
}
|
||||||
@ -103,27 +121,71 @@ status_t
|
|||||||
ShapePainter::IterateBezierTo(int32 bezierCount, BPoint* bezierPts)
|
ShapePainter::IterateBezierTo(int32 bezierCount, BPoint* bezierPts)
|
||||||
{
|
{
|
||||||
bezierCount *= 3;
|
bezierCount *= 3;
|
||||||
|
try {
|
||||||
fOpStack.push(OP_BEZIERTO | bezierCount);
|
fOpStack.push(OP_BEZIERTO | bezierCount);
|
||||||
for (int32 i = 0; i < bezierCount; i++)
|
for (int32 i = 0; i < bezierCount; i++) {
|
||||||
fPtStack.push(bezierPts[i]);
|
BPoint transformed(bezierPts[i]);
|
||||||
|
fView->ConvertToScreenForDrawing(&transformed);
|
||||||
|
fPtStack.push(transformed);
|
||||||
|
}
|
||||||
|
} catch (std::bad_alloc) {
|
||||||
|
return B_NO_MEMORY;
|
||||||
|
}
|
||||||
|
|
||||||
return B_OK;
|
return B_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
status_t
|
status_t
|
||||||
ShapePainter::IterateClose(void)
|
ShapePainter::IterateArcTo(float& rx, float& ry,
|
||||||
|
float& angle, bool largeArc, bool counterClockWise, BPoint& point)
|
||||||
{
|
{
|
||||||
|
uint32 op;
|
||||||
|
if (largeArc) {
|
||||||
|
if (counterClockWise)
|
||||||
|
op = OP_LARGE_ARC_TO_CCW;
|
||||||
|
else
|
||||||
|
op = OP_LARGE_ARC_TO_CW;
|
||||||
|
} else {
|
||||||
|
if (counterClockWise)
|
||||||
|
op = OP_SMALL_ARC_TO_CCW;
|
||||||
|
else
|
||||||
|
op = OP_SMALL_ARC_TO_CW;
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
fOpStack.push(op | 3);
|
||||||
|
fPtStack.push(BPoint(rx * fView->Scale(), ry * fView->Scale()));
|
||||||
|
fPtStack.push(BPoint(angle, 0));
|
||||||
|
BPoint transformed(point);
|
||||||
|
fView->ConvertToScreenForDrawing(&transformed);
|
||||||
|
fPtStack.push(transformed);
|
||||||
|
} catch (std::bad_alloc) {
|
||||||
|
return B_NO_MEMORY;
|
||||||
|
}
|
||||||
|
|
||||||
|
return B_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
status_t
|
||||||
|
ShapePainter::IterateClose()
|
||||||
|
{
|
||||||
|
try {
|
||||||
fOpStack.push(OP_CLOSE);
|
fOpStack.push(OP_CLOSE);
|
||||||
|
} catch (std::bad_alloc) {
|
||||||
|
return B_NO_MEMORY;
|
||||||
|
}
|
||||||
|
|
||||||
return B_OK;
|
return B_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void
|
void
|
||||||
ShapePainter::Draw(View* view, BRect frame, bool filled)
|
ShapePainter::Draw(BRect frame, bool filled)
|
||||||
{
|
{
|
||||||
// We're going to draw the currently iterated shape.
|
// We're going to draw the currently iterated shape.
|
||||||
|
// TODO: This can be more efficient by skipping the conversion.
|
||||||
int32 opCount = fOpStack.size();
|
int32 opCount = fOpStack.size();
|
||||||
int32 ptCount = fPtStack.size();
|
int32 ptCount = fPtStack.size();
|
||||||
|
|
||||||
@ -144,14 +206,15 @@ ShapePainter::Draw(View* view, BRect frame, bool filled)
|
|||||||
fOpStack.pop();
|
fOpStack.pop();
|
||||||
}
|
}
|
||||||
|
|
||||||
for (i = (ptCount - 1); i >= 0; i--) {
|
for (i = ptCount - 1; i >= 0; i--) {
|
||||||
ptList[i] = fPtStack.top();
|
ptList[i] = fPtStack.top();
|
||||||
fPtStack.pop();
|
fPtStack.pop();
|
||||||
view->ConvertToScreenForDrawing(&ptList[i]);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
view->Window()->GetDrawingEngine()->DrawShape(frame, opCount,
|
BPoint offset;
|
||||||
opList, ptCount, ptList, filled);
|
fView->ConvertToScreenForDrawing(&offset);
|
||||||
|
fView->Window()->GetDrawingEngine()->DrawShape(frame, opCount,
|
||||||
|
opList, ptCount, ptList, filled, offset, fView->Scale());
|
||||||
|
|
||||||
delete[] opList;
|
delete[] opList;
|
||||||
delete[] ptList;
|
delete[] ptList;
|
||||||
@ -399,20 +462,20 @@ fill_polygon(View* view, int32 numPoints, const BPoint* viewPoints)
|
|||||||
static void
|
static void
|
||||||
stroke_shape(View* view, const BShape* shape)
|
stroke_shape(View* view, const BShape* shape)
|
||||||
{
|
{
|
||||||
ShapePainter drawShape;
|
ShapePainter drawShape(view);
|
||||||
|
|
||||||
drawShape.Iterate(shape);
|
drawShape.Iterate(shape);
|
||||||
drawShape.Draw(view, shape->Bounds(), false);
|
drawShape.Draw(shape->Bounds(), false);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static void
|
static void
|
||||||
fill_shape(View* view, const BShape* shape)
|
fill_shape(View* view, const BShape* shape)
|
||||||
{
|
{
|
||||||
ShapePainter drawShape;
|
ShapePainter drawShape(view);
|
||||||
|
|
||||||
drawShape.Iterate(shape);
|
drawShape.Iterate(shape);
|
||||||
drawShape.Draw(view, shape->Bounds(), true);
|
drawShape.Draw(shape->Bounds(), true);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -2541,18 +2541,16 @@ ServerWindow::_DispatchViewDrawingMessage(int32 code,
|
|||||||
|
|
||||||
// this might seem a bit weird, but under R5, the shapes
|
// this might seem a bit weird, but under R5, the shapes
|
||||||
// are always offset by the current pen location
|
// are always offset by the current pen location
|
||||||
BPoint penLocation
|
BPoint screenOffset
|
||||||
= fCurrentView->CurrentState()->PenLocation();
|
= fCurrentView->CurrentState()->PenLocation();
|
||||||
for (int32 i = 0; i < ptCount; i++) {
|
shapeFrame.OffsetBy(screenOffset);
|
||||||
ptList[i] += penLocation;
|
|
||||||
fCurrentView->ConvertToScreenForDrawing(&ptList[i]);
|
|
||||||
}
|
|
||||||
|
|
||||||
shapeFrame.OffsetBy(penLocation);
|
fCurrentView->ConvertToScreenForDrawing(&screenOffset);
|
||||||
fCurrentView->ConvertToScreenForDrawing(&shapeFrame);
|
fCurrentView->ConvertToScreenForDrawing(&shapeFrame);
|
||||||
|
|
||||||
drawingEngine->DrawShape(shapeFrame, opCount, opList, ptCount,
|
drawingEngine->DrawShape(shapeFrame, opCount, opList, ptCount,
|
||||||
ptList, code == AS_FILL_SHAPE);
|
ptList, code == AS_FILL_SHAPE, screenOffset,
|
||||||
|
fCurrentView->Scale());
|
||||||
}
|
}
|
||||||
|
|
||||||
delete[] opList;
|
delete[] opList;
|
||||||
@ -2581,15 +2579,16 @@ ServerWindow::_DispatchViewDrawingMessage(int32 code,
|
|||||||
|
|
||||||
// this might seem a bit weird, but under R5, the shapes
|
// this might seem a bit weird, but under R5, the shapes
|
||||||
// are always offset by the current pen location
|
// are always offset by the current pen location
|
||||||
BPoint penLocation
|
BPoint screenOffset
|
||||||
= fCurrentView->CurrentState()->PenLocation();
|
= fCurrentView->CurrentState()->PenLocation();
|
||||||
for (int32 i = 0; i < ptCount; i++) {
|
shapeFrame.OffsetBy(screenOffset);
|
||||||
ptList[i] += penLocation;
|
|
||||||
fCurrentView->ConvertToScreenForDrawing(&ptList[i]);
|
fCurrentView->ConvertToScreenForDrawing(&screenOffset);
|
||||||
}
|
fCurrentView->ConvertToScreenForDrawing(&shapeFrame);
|
||||||
fCurrentView->ConvertToScreenForDrawing(gradient);
|
fCurrentView->ConvertToScreenForDrawing(gradient);
|
||||||
drawingEngine->FillShape(shapeFrame, opCount, opList,
|
drawingEngine->FillShape(shapeFrame, opCount, opList,
|
||||||
ptCount, ptList, *gradient);
|
ptCount, ptList, *gradient, screenOffset,
|
||||||
|
fCurrentView->Scale());
|
||||||
}
|
}
|
||||||
|
|
||||||
delete[] opList;
|
delete[] opList;
|
||||||
|
@ -150,7 +150,7 @@ DrawingEngine::LockExclusiveAccess()
|
|||||||
|
|
||||||
|
|
||||||
bool
|
bool
|
||||||
DrawingEngine::IsExclusiveAccessLocked()
|
DrawingEngine::IsExclusiveAccessLocked() const
|
||||||
{
|
{
|
||||||
return fGraphicsCard->IsExclusiveAccessLocked();
|
return fGraphicsCard->IsExclusiveAccessLocked();
|
||||||
}
|
}
|
||||||
@ -1141,16 +1141,30 @@ DrawingEngine::FillRoundRect(BRect r, float xrad, float yrad,
|
|||||||
|
|
||||||
void
|
void
|
||||||
DrawingEngine::DrawShape(const BRect& bounds, int32 opCount,
|
DrawingEngine::DrawShape(const BRect& bounds, int32 opCount,
|
||||||
const uint32* opList, int32 ptCount, const BPoint* ptList, bool filled)
|
const uint32* opList, int32 ptCount, const BPoint* ptList, bool filled,
|
||||||
|
const BPoint& viewToScreenOffset, float viewScale)
|
||||||
{
|
{
|
||||||
ASSERT_PARALLEL_LOCKED();
|
ASSERT_PARALLEL_LOCKED();
|
||||||
|
|
||||||
// NOTE: hides cursor regardless of if and where
|
// TODO: bounds probably does not take curves and arcs into account...
|
||||||
// shape is drawn on screen, TODO: optimize
|
// BRect clipped(bounds);
|
||||||
|
// if (!filled)
|
||||||
|
// extend_by_stroke_width(clipped, fPainter->PenSize());
|
||||||
|
// clipped = fPainter->ClipRect(bounds);
|
||||||
|
//
|
||||||
|
// clipped.left = floorf(clipped.left);
|
||||||
|
// clipped.top = floorf(clipped.top);
|
||||||
|
// clipped.right = ceilf(clipped.right);
|
||||||
|
// clipped.bottom = ceilf(clipped.bottom);
|
||||||
|
//
|
||||||
|
// if (!clipped.IsValid())
|
||||||
|
// return;
|
||||||
|
//
|
||||||
|
// AutoFloatingOverlaysHider _(fGraphicsCard, clipped);
|
||||||
AutoFloatingOverlaysHider _(fGraphicsCard);
|
AutoFloatingOverlaysHider _(fGraphicsCard);
|
||||||
|
|
||||||
BRect touched = fPainter->DrawShape(opCount, opList, ptCount, ptList,
|
BRect touched = fPainter->DrawShape(opCount, opList, ptCount, ptList,
|
||||||
filled);
|
filled, viewToScreenOffset, viewScale);
|
||||||
|
|
||||||
_CopyToFront(touched);
|
_CopyToFront(touched);
|
||||||
}
|
}
|
||||||
@ -1159,16 +1173,27 @@ DrawingEngine::DrawShape(const BRect& bounds, int32 opCount,
|
|||||||
void
|
void
|
||||||
DrawingEngine::FillShape(const BRect& bounds, int32 opCount,
|
DrawingEngine::FillShape(const BRect& bounds, int32 opCount,
|
||||||
const uint32* opList, int32 ptCount, const BPoint* ptList,
|
const uint32* opList, int32 ptCount, const BPoint* ptList,
|
||||||
const BGradient& gradient)
|
const BGradient& gradient, const BPoint& viewToScreenOffset,
|
||||||
|
float viewScale)
|
||||||
{
|
{
|
||||||
ASSERT_PARALLEL_LOCKED();
|
ASSERT_PARALLEL_LOCKED();
|
||||||
|
|
||||||
// NOTE: hides cursor regardless of if and where
|
// TODO: bounds probably does not take curves and arcs into account...
|
||||||
// shape is drawn on screen, TODO: optimize
|
// BRect clipped = fPainter->ClipRect(bounds);
|
||||||
|
//
|
||||||
|
// clipped.left = floorf(clipped.left);
|
||||||
|
// clipped.top = floorf(clipped.top);
|
||||||
|
// clipped.right = ceilf(clipped.right);
|
||||||
|
// clipped.bottom = ceilf(clipped.bottom);
|
||||||
|
//
|
||||||
|
// if (!clipped.IsValid())
|
||||||
|
// return;
|
||||||
|
//
|
||||||
|
// AutoFloatingOverlaysHider _(fGraphicsCard, clipped);
|
||||||
AutoFloatingOverlaysHider _(fGraphicsCard);
|
AutoFloatingOverlaysHider _(fGraphicsCard);
|
||||||
|
|
||||||
BRect touched = fPainter->FillShape(opCount, opList, ptCount, ptList,
|
BRect touched = fPainter->FillShape(opCount, opList, ptCount, ptList,
|
||||||
gradient);
|
gradient, viewToScreenOffset, viewScale);
|
||||||
|
|
||||||
_CopyToFront(touched);
|
_CopyToFront(touched);
|
||||||
}
|
}
|
||||||
|
@ -56,7 +56,7 @@ public:
|
|||||||
void UnlockParallelAccess();
|
void UnlockParallelAccess();
|
||||||
|
|
||||||
bool LockExclusiveAccess();
|
bool LockExclusiveAccess();
|
||||||
virtual bool IsExclusiveAccessLocked();
|
virtual bool IsExclusiveAccessLocked() const;
|
||||||
void UnlockExclusiveAccess();
|
void UnlockExclusiveAccess();
|
||||||
|
|
||||||
// for screen shots
|
// for screen shots
|
||||||
@ -138,11 +138,14 @@ public:
|
|||||||
virtual void DrawShape(const BRect& bounds,
|
virtual void DrawShape(const BRect& bounds,
|
||||||
int32 opcount, const uint32* oplist,
|
int32 opcount, const uint32* oplist,
|
||||||
int32 ptcount, const BPoint* ptlist,
|
int32 ptcount, const BPoint* ptlist,
|
||||||
bool filled);
|
bool filled, const BPoint& viewToScreenOffset,
|
||||||
|
float viewScale);
|
||||||
virtual void FillShape(const BRect& bounds,
|
virtual void FillShape(const BRect& bounds,
|
||||||
int32 opcount, const uint32* oplist,
|
int32 opcount, const uint32* oplist,
|
||||||
int32 ptcount, const BPoint* ptlist,
|
int32 ptcount, const BPoint* ptlist,
|
||||||
const BGradient& gradient);
|
const BGradient& gradient,
|
||||||
|
const BPoint& viewToScreenOffset,
|
||||||
|
float viewScale);
|
||||||
|
|
||||||
virtual void DrawTriangle(BPoint* points, const BRect& bounds,
|
virtual void DrawTriangle(BPoint* points, const BRect& bounds,
|
||||||
bool filled);
|
bool filled);
|
||||||
|
@ -668,28 +668,31 @@ Painter::FillBezier(BPoint* p, const BGradient& gradient) const
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// DrawShape
|
static void
|
||||||
BRect
|
iterate_shape_data(agg::path_storage& path,
|
||||||
Painter::DrawShape(const int32& opCount, const uint32* opList,
|
const int32& opCount, const uint32* opList,
|
||||||
const int32& ptCount, const BPoint* points, bool filled) const
|
const int32& ptCount, const BPoint* points,
|
||||||
|
const BPoint& viewToScreenOffset, float viewScale)
|
||||||
{
|
{
|
||||||
CHECK_CLIPPING
|
|
||||||
|
|
||||||
// TODO: if shapes are ever used more heavily in Haiku,
|
// TODO: if shapes are ever used more heavily in Haiku,
|
||||||
// it would be nice to use BShape data directly (write
|
// it would be nice to use BShape data directly (write
|
||||||
// an AGG "VertexSource" adaptor)
|
// an AGG "VertexSource" adaptor)
|
||||||
fPath.remove_all();
|
path.remove_all();
|
||||||
for (int32 i = 0; i < opCount; i++) {
|
for (int32 i = 0; i < opCount; i++) {
|
||||||
uint32 op = opList[i] & 0xFF000000;
|
uint32 op = opList[i] & 0xFF000000;
|
||||||
if (op & OP_MOVETO) {
|
if (op & OP_MOVETO) {
|
||||||
fPath.move_to(points->x, points->y);
|
path.move_to(
|
||||||
|
points->x * viewScale + viewToScreenOffset.x,
|
||||||
|
points->y * viewScale + viewToScreenOffset.y);
|
||||||
points++;
|
points++;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (op & OP_LINETO) {
|
if (op & OP_LINETO) {
|
||||||
int32 count = opList[i] & 0x00FFFFFF;
|
int32 count = opList[i] & 0x00FFFFFF;
|
||||||
while (count--) {
|
while (count--) {
|
||||||
fPath.line_to(points->x, points->y);
|
path.line_to(
|
||||||
|
points->x * viewScale + viewToScreenOffset.x,
|
||||||
|
points->y * viewScale + viewToScreenOffset.y);
|
||||||
points++;
|
points++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -697,16 +700,51 @@ Painter::DrawShape(const int32& opCount, const uint32* opList,
|
|||||||
if (op & OP_BEZIERTO) {
|
if (op & OP_BEZIERTO) {
|
||||||
int32 count = opList[i] & 0x00FFFFFF;
|
int32 count = opList[i] & 0x00FFFFFF;
|
||||||
while (count) {
|
while (count) {
|
||||||
fPath.curve4(points[0].x, points[0].y, points[1].x, points[1].y,
|
path.curve4(
|
||||||
points[2].x, points[2].y);
|
points[0].x * viewScale + viewToScreenOffset.x,
|
||||||
|
points[0].y * viewScale + viewToScreenOffset.y,
|
||||||
|
points[1].x * viewScale + viewToScreenOffset.x,
|
||||||
|
points[1].y * viewScale + viewToScreenOffset.y,
|
||||||
|
points[2].x * viewScale + viewToScreenOffset.x,
|
||||||
|
points[2].y * viewScale + viewToScreenOffset.y);
|
||||||
|
points += 3;
|
||||||
|
count -= 3;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if ((op & OP_LARGE_ARC_TO_CW) || (op & OP_LARGE_ARC_TO_CCW)
|
||||||
|
|| (op & OP_SMALL_ARC_TO_CW) || (op & OP_SMALL_ARC_TO_CCW)) {
|
||||||
|
int32 count = opList[i] & 0x00FFFFFF;
|
||||||
|
while (count) {
|
||||||
|
path.arc_to(
|
||||||
|
points[0].x * viewScale,
|
||||||
|
points[0].y * viewScale,
|
||||||
|
points[1].x,
|
||||||
|
op & (OP_LARGE_ARC_TO_CW | OP_LARGE_ARC_TO_CCW),
|
||||||
|
op & (OP_SMALL_ARC_TO_CW | OP_LARGE_ARC_TO_CW),
|
||||||
|
points[2].x * viewScale + viewToScreenOffset.x,
|
||||||
|
points[2].y * viewScale + viewToScreenOffset.y);
|
||||||
points += 3;
|
points += 3;
|
||||||
count -= 3;
|
count -= 3;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (op & OP_CLOSE)
|
if (op & OP_CLOSE)
|
||||||
fPath.close_polygon();
|
path.close_polygon();
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// DrawShape
|
||||||
|
BRect
|
||||||
|
Painter::DrawShape(const int32& opCount, const uint32* opList,
|
||||||
|
const int32& ptCount, const BPoint* points, bool filled,
|
||||||
|
const BPoint& viewToScreenOffset, float viewScale) const
|
||||||
|
{
|
||||||
|
CHECK_CLIPPING
|
||||||
|
|
||||||
|
iterate_shape_data(fPath, opCount, opList, ptCount, points,
|
||||||
|
viewToScreenOffset, viewScale);
|
||||||
|
|
||||||
if (filled)
|
if (filled)
|
||||||
return _FillPath(fCurve);
|
return _FillPath(fCurve);
|
||||||
@ -718,42 +756,13 @@ Painter::DrawShape(const int32& opCount, const uint32* opList,
|
|||||||
// FillShape
|
// FillShape
|
||||||
BRect
|
BRect
|
||||||
Painter::FillShape(const int32& opCount, const uint32* opList,
|
Painter::FillShape(const int32& opCount, const uint32* opList,
|
||||||
const int32& ptCount, const BPoint* points, const BGradient& gradient) const
|
const int32& ptCount, const BPoint* points, const BGradient& gradient,
|
||||||
|
const BPoint& viewToScreenOffset, float viewScale) const
|
||||||
{
|
{
|
||||||
CHECK_CLIPPING
|
CHECK_CLIPPING
|
||||||
|
|
||||||
// TODO: if shapes are ever used more heavily in Haiku,
|
iterate_shape_data(fPath, opCount, opList, ptCount, points,
|
||||||
// it would be nice to use BShape data directly (write
|
viewToScreenOffset, viewScale);
|
||||||
// an AGG "VertexSource" adaptor)
|
|
||||||
fPath.remove_all();
|
|
||||||
for (int32 i = 0; i < opCount; i++) {
|
|
||||||
uint32 op = opList[i] & 0xFF000000;
|
|
||||||
if (op & OP_MOVETO) {
|
|
||||||
fPath.move_to(points->x, points->y);
|
|
||||||
points++;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (op & OP_LINETO) {
|
|
||||||
int32 count = opList[i] & 0x00FFFFFF;
|
|
||||||
while (count--) {
|
|
||||||
fPath.line_to(points->x, points->y);
|
|
||||||
points++;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (op & OP_BEZIERTO) {
|
|
||||||
int32 count = opList[i] & 0x00FFFFFF;
|
|
||||||
while (count) {
|
|
||||||
fPath.curve4(points[0].x, points[0].y, points[1].x, points[1].y,
|
|
||||||
points[2].x, points[2].y);
|
|
||||||
points += 3;
|
|
||||||
count -= 3;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (op & OP_CLOSE)
|
|
||||||
fPath.close_polygon();
|
|
||||||
}
|
|
||||||
|
|
||||||
return _FillPath(fCurve, gradient);
|
return _FillPath(fCurve, gradient);
|
||||||
}
|
}
|
||||||
|
@ -132,12 +132,15 @@ class Painter {
|
|||||||
// shapes
|
// shapes
|
||||||
BRect DrawShape(const int32& opCount,
|
BRect DrawShape(const int32& opCount,
|
||||||
const uint32* opList, const int32& ptCount,
|
const uint32* opList, const int32& ptCount,
|
||||||
const BPoint* ptList, bool filled) const;
|
const BPoint* ptList, bool filled,
|
||||||
|
const BPoint& viewToScreenOffset,
|
||||||
|
float viewScale) const;
|
||||||
BRect FillShape(const int32& opCount,
|
BRect FillShape(const int32& opCount,
|
||||||
const uint32* opList,
|
const uint32* opList, const int32& ptCount,
|
||||||
const int32& ptCount,
|
|
||||||
const BPoint* ptList,
|
const BPoint* ptList,
|
||||||
const BGradient& gradient) const;
|
const BGradient& gradient,
|
||||||
|
const BPoint& viewToScreenOffset,
|
||||||
|
float viewScale) const;
|
||||||
|
|
||||||
// rects
|
// rects
|
||||||
BRect StrokeRect(const BRect& r) const;
|
BRect StrokeRect(const BRect& r) const;
|
||||||
@ -383,6 +386,7 @@ Painter::ClipRect(BRect rect) const
|
|||||||
return _Clipped(rect);
|
return _Clipped(rect);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
inline BRect
|
inline BRect
|
||||||
Painter::AlignAndClipRect(BRect rect) const
|
Painter::AlignAndClipRect(BRect rect) const
|
||||||
{
|
{
|
||||||
|
@ -12,6 +12,7 @@
|
|||||||
#include "DrawState.h"
|
#include "DrawState.h"
|
||||||
|
|
||||||
#include <Bitmap.h>
|
#include <Bitmap.h>
|
||||||
|
#include <utf8_functions.h>
|
||||||
|
|
||||||
#include <new>
|
#include <new>
|
||||||
|
|
||||||
@ -682,7 +683,7 @@ RemoteDrawingEngine::FillRoundRect(BRect rect, float xRadius, float yRadius,
|
|||||||
void
|
void
|
||||||
RemoteDrawingEngine::DrawShape(const BRect& bounds, int32 opCount,
|
RemoteDrawingEngine::DrawShape(const BRect& bounds, int32 opCount,
|
||||||
const uint32* opList, int32 pointCount, const BPoint* pointList,
|
const uint32* opList, int32 pointCount, const BPoint* pointList,
|
||||||
bool filled)
|
bool filled, const BPoint& viewToScreenOffset, float viewScale)
|
||||||
{
|
{
|
||||||
BRect clipBounds = bounds;
|
BRect clipBounds = bounds;
|
||||||
if (!filled)
|
if (!filled)
|
||||||
@ -699,13 +700,15 @@ RemoteDrawingEngine::DrawShape(const BRect& bounds, int32 opCount,
|
|||||||
message.AddList(opList, opCount);
|
message.AddList(opList, opCount);
|
||||||
message.Add(pointCount);
|
message.Add(pointCount);
|
||||||
message.AddList(pointList, pointCount);
|
message.AddList(pointList, pointCount);
|
||||||
|
// TODO: viewToScreenOffset and viewScale
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void
|
void
|
||||||
RemoteDrawingEngine::FillShape(const BRect& bounds, int32 opCount,
|
RemoteDrawingEngine::FillShape(const BRect& bounds, int32 opCount,
|
||||||
const uint32* opList, int32 pointCount, const BPoint* pointList,
|
const uint32* opList, int32 pointCount, const BPoint* pointList,
|
||||||
const BGradient& gradient)
|
const BGradient& gradient, const BPoint& viewToScreenOffset,
|
||||||
|
float viewScale)
|
||||||
{
|
{
|
||||||
if (!fClippingRegion.Intersects(bounds))
|
if (!fClippingRegion.Intersects(bounds))
|
||||||
return;
|
return;
|
||||||
@ -719,6 +722,7 @@ RemoteDrawingEngine::FillShape(const BRect& bounds, int32 opCount,
|
|||||||
message.Add(pointCount);
|
message.Add(pointCount);
|
||||||
message.AddList(pointList, pointCount);
|
message.AddList(pointList, pointCount);
|
||||||
message.AddGradient(gradient);
|
message.AddGradient(gradient);
|
||||||
|
// TODO: viewToScreenOffset and viewScale
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -824,6 +828,37 @@ RemoteDrawingEngine::DrawString(const char* string, int32 length,
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
BPoint
|
||||||
|
RemoteDrawingEngine::DrawString(const char* string, int32 length,
|
||||||
|
const BPoint* offsets)
|
||||||
|
{
|
||||||
|
// Guaranteed to have at least one point.
|
||||||
|
RemoteMessage message(NULL, fHWInterface->SendBuffer());
|
||||||
|
|
||||||
|
message.Start(RP_DRAW_STRING_WITH_OFFSETS);
|
||||||
|
message.Add(fToken);
|
||||||
|
message.AddString(string, length);
|
||||||
|
message.AddList(offsets, UTF8CountChars(string, length));
|
||||||
|
|
||||||
|
status_t result = _AddCallback();
|
||||||
|
if (message.Flush() != B_OK)
|
||||||
|
return offsets[0];
|
||||||
|
|
||||||
|
if (result != B_OK)
|
||||||
|
return offsets[0];
|
||||||
|
|
||||||
|
do {
|
||||||
|
result = acquire_sem_etc(fResultNotify, 1, B_RELATIVE_TIMEOUT,
|
||||||
|
1 * 1000 * 1000);
|
||||||
|
} while (result == B_INTERRUPTED);
|
||||||
|
|
||||||
|
if (result != B_OK)
|
||||||
|
return offsets[0];
|
||||||
|
|
||||||
|
return fDrawStringResult;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
float
|
float
|
||||||
RemoteDrawingEngine::StringWidth(const char* string, int32 length,
|
RemoteDrawingEngine::StringWidth(const char* string, int32 length,
|
||||||
escapement_delta* delta)
|
escapement_delta* delta)
|
||||||
|
@ -107,11 +107,15 @@ virtual void FillRoundRect(BRect rect, float xRadius,
|
|||||||
virtual void DrawShape(const BRect& bounds,
|
virtual void DrawShape(const BRect& bounds,
|
||||||
int32 opCount, const uint32* opList,
|
int32 opCount, const uint32* opList,
|
||||||
int32 pointCount, const BPoint* pointList,
|
int32 pointCount, const BPoint* pointList,
|
||||||
bool filled);
|
bool filled,
|
||||||
|
const BPoint& viewToScreenOffset,
|
||||||
|
float viewScale);
|
||||||
virtual void FillShape(const BRect& bounds,
|
virtual void FillShape(const BRect& bounds,
|
||||||
int32 opCount, const uint32* opList,
|
int32 opCount, const uint32* opList,
|
||||||
int32 pointCount, const BPoint* pointList,
|
int32 pointCount, const BPoint* pointList,
|
||||||
const BGradient& gradient);
|
const BGradient& gradient,
|
||||||
|
const BPoint& viewToScreenOffset,
|
||||||
|
float viewScale);
|
||||||
|
|
||||||
virtual void DrawTriangle(BPoint* points,
|
virtual void DrawTriangle(BPoint* points,
|
||||||
const BRect& bounds, bool filled);
|
const BRect& bounds, bool filled);
|
||||||
@ -131,6 +135,8 @@ virtual void StrokeLineArray(int32 numlines,
|
|||||||
virtual BPoint DrawString(const char* string, int32 length,
|
virtual BPoint DrawString(const char* string, int32 length,
|
||||||
const BPoint& point,
|
const BPoint& point,
|
||||||
escapement_delta* delta = NULL);
|
escapement_delta* delta = NULL);
|
||||||
|
virtual BPoint DrawString(const char* string, int32 length,
|
||||||
|
const BPoint* offsets);
|
||||||
|
|
||||||
virtual float StringWidth(const char* string, int32 length,
|
virtual float StringWidth(const char* string, int32 length,
|
||||||
escapement_delta* delta = NULL);
|
escapement_delta* delta = NULL);
|
||||||
|
@ -100,6 +100,7 @@ enum {
|
|||||||
RP_FILL_REGION_COLOR_NO_CLIPPING,
|
RP_FILL_REGION_COLOR_NO_CLIPPING,
|
||||||
|
|
||||||
RP_DRAW_STRING = 180,
|
RP_DRAW_STRING = 180,
|
||||||
|
RP_DRAW_STRING_WITH_OFFSETS,
|
||||||
RP_DRAW_STRING_RESULT,
|
RP_DRAW_STRING_RESULT,
|
||||||
RP_STRING_WIDTH,
|
RP_STRING_WIDTH,
|
||||||
RP_STRING_WIDTH_RESULT,
|
RP_STRING_WIDTH_RESULT,
|
||||||
|
@ -192,6 +192,7 @@ SubInclude HAIKU_TOP src tests servers app regularapps ;
|
|||||||
SubInclude HAIKU_TOP src tests servers app resize_limits ;
|
SubInclude HAIKU_TOP src tests servers app resize_limits ;
|
||||||
SubInclude HAIKU_TOP src tests servers app scrollbar ;
|
SubInclude HAIKU_TOP src tests servers app scrollbar ;
|
||||||
SubInclude HAIKU_TOP src tests servers app scrolling ;
|
SubInclude HAIKU_TOP src tests servers app scrolling ;
|
||||||
|
SubInclude HAIKU_TOP src tests servers app shape_test ;
|
||||||
SubInclude HAIKU_TOP src tests servers app statusbar ;
|
SubInclude HAIKU_TOP src tests servers app statusbar ;
|
||||||
SubInclude HAIKU_TOP src tests servers app stress_test ;
|
SubInclude HAIKU_TOP src tests servers app stress_test ;
|
||||||
SubInclude HAIKU_TOP src tests servers app textview ;
|
SubInclude HAIKU_TOP src tests servers app textview ;
|
||||||
|
17
src/tests/servers/app/shape_test/Jamfile
Normal file
17
src/tests/servers/app/shape_test/Jamfile
Normal file
@ -0,0 +1,17 @@
|
|||||||
|
SubDir HAIKU_TOP src tests servers app shape_test ;
|
||||||
|
|
||||||
|
SetSubDirSupportedPlatformsBeOSCompatible ;
|
||||||
|
AddSubDirSupportedPlatforms libbe_test ;
|
||||||
|
|
||||||
|
UseHeaders [ FDirName os app ] ;
|
||||||
|
UseHeaders [ FDirName os interface ] ;
|
||||||
|
|
||||||
|
SimpleTest ShapeTest :
|
||||||
|
main.cpp
|
||||||
|
: be $(TARGET_LIBSUPC++)
|
||||||
|
;
|
||||||
|
|
||||||
|
if ( $(TARGET_PLATFORM) = libbe_test ) {
|
||||||
|
HaikuInstall install-test-apps : $(HAIKU_APP_TEST_DIR) : ShapeTest
|
||||||
|
: tests!apps ;
|
||||||
|
}
|
181
src/tests/servers/app/shape_test/main.cpp
Normal file
181
src/tests/servers/app/shape_test/main.cpp
Normal file
@ -0,0 +1,181 @@
|
|||||||
|
#include <stdio.h>
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
|
#include <Application.h>
|
||||||
|
#include <Message.h>
|
||||||
|
#include <Shape.h>
|
||||||
|
#include <View.h>
|
||||||
|
#include <Window.h>
|
||||||
|
|
||||||
|
|
||||||
|
static const char* kAppSignature = "application/x.vnd-Haiku.ShapeTest";
|
||||||
|
|
||||||
|
|
||||||
|
class TestView : public BView {
|
||||||
|
public:
|
||||||
|
TestView(BRect frame, const char* name,
|
||||||
|
uint32 resizeFlags, uint32 flags);
|
||||||
|
|
||||||
|
virtual void Draw(BRect updateRect);
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
TestView::TestView(BRect frame, const char* name, uint32 resizeFlags,
|
||||||
|
uint32 flags)
|
||||||
|
:
|
||||||
|
BView(frame, name, resizeFlags, flags)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void
|
||||||
|
TestView::Draw(BRect updateRect)
|
||||||
|
{
|
||||||
|
BRect r(Bounds());
|
||||||
|
|
||||||
|
SetDrawingMode(B_OP_ALPHA);
|
||||||
|
SetBlendingMode(B_PIXEL_ALPHA, B_ALPHA_OVERLAY);
|
||||||
|
SetHighColor(0, 0, 0, 240);
|
||||||
|
|
||||||
|
class TranslateIterator : public BShapeIterator {
|
||||||
|
public:
|
||||||
|
TranslateIterator()
|
||||||
|
:
|
||||||
|
fOffsetX(0),
|
||||||
|
fOffsetY(0)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
TranslateIterator(float offsetX, float offsetY)
|
||||||
|
:
|
||||||
|
fOffsetX(offsetX),
|
||||||
|
fOffsetY(offsetY)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
void SetOffset(float offsetX, float offsetY)
|
||||||
|
{
|
||||||
|
fOffsetX = offsetX;
|
||||||
|
fOffsetY = offsetY;
|
||||||
|
}
|
||||||
|
|
||||||
|
virtual status_t IterateMoveTo(BPoint* point)
|
||||||
|
{
|
||||||
|
point->x += fOffsetX;
|
||||||
|
point->y += fOffsetY;
|
||||||
|
return B_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
virtual status_t IterateLineTo(int32 lineCount, BPoint* linePts)
|
||||||
|
{
|
||||||
|
while (lineCount--) {
|
||||||
|
linePts->x += fOffsetX;
|
||||||
|
linePts->y += fOffsetY;
|
||||||
|
linePts++;
|
||||||
|
}
|
||||||
|
return B_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
virtual status_t IterateBezierTo(int32 bezierCount, BPoint* bezierPts)
|
||||||
|
{
|
||||||
|
while (bezierCount--) {
|
||||||
|
bezierPts[0].x += fOffsetX;
|
||||||
|
bezierPts[0].y += fOffsetY;
|
||||||
|
bezierPts[1].x += fOffsetX;
|
||||||
|
bezierPts[1].y += fOffsetY;
|
||||||
|
bezierPts[2].x += fOffsetX;
|
||||||
|
bezierPts[2].y += fOffsetY;
|
||||||
|
bezierPts += 3;
|
||||||
|
}
|
||||||
|
return B_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
virtual status_t IterateArcTo(float& rx, float& ry, float& angle,
|
||||||
|
bool largeArc, bool counterClockWise, BPoint& point)
|
||||||
|
{
|
||||||
|
point.x += fOffsetX;
|
||||||
|
point.y += fOffsetY;
|
||||||
|
return B_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
float fOffsetX;
|
||||||
|
float fOffsetY;
|
||||||
|
} translator;
|
||||||
|
|
||||||
|
MovePenTo(B_ORIGIN);
|
||||||
|
|
||||||
|
const float arcRX = 50;
|
||||||
|
const float arcRY = 80;
|
||||||
|
|
||||||
|
BShape shape;
|
||||||
|
shape.MoveTo(BPoint(20, 10));
|
||||||
|
shape.LineTo(BPoint(10, 90));
|
||||||
|
shape.LineTo(BPoint(90, 100));
|
||||||
|
shape.ArcTo(arcRX, arcRY, 45, true, true, BPoint(100, 20));
|
||||||
|
shape.Close();
|
||||||
|
|
||||||
|
StrokeShape(&shape);
|
||||||
|
|
||||||
|
shape.Clear();
|
||||||
|
shape.MoveTo(BPoint(20, 10));
|
||||||
|
shape.LineTo(BPoint(10, 90));
|
||||||
|
shape.LineTo(BPoint(90, 100));
|
||||||
|
shape.ArcTo(arcRX, arcRY, 45, false, true, BPoint(100, 20));
|
||||||
|
shape.Close();
|
||||||
|
|
||||||
|
translator.SetOffset(10, 10);
|
||||||
|
translator.Iterate(&shape);
|
||||||
|
|
||||||
|
SetHighColor(140, 30, 50, 255);
|
||||||
|
StrokeShape(&shape);
|
||||||
|
|
||||||
|
shape.Clear();
|
||||||
|
shape.MoveTo(BPoint(20, 10));
|
||||||
|
shape.LineTo(BPoint(10, 90));
|
||||||
|
shape.LineTo(BPoint(90, 100));
|
||||||
|
shape.ArcTo(arcRX, arcRY, 45, true, false, BPoint(100, 20));
|
||||||
|
shape.Close();
|
||||||
|
|
||||||
|
translator.SetOffset(20, 20);
|
||||||
|
translator.Iterate(&shape);
|
||||||
|
|
||||||
|
SetHighColor(140, 130, 50, 255);
|
||||||
|
StrokeShape(&shape);
|
||||||
|
|
||||||
|
shape.Clear();
|
||||||
|
shape.MoveTo(BPoint(20, 10));
|
||||||
|
shape.LineTo(BPoint(10, 90));
|
||||||
|
shape.LineTo(BPoint(90, 100));
|
||||||
|
shape.ArcTo(arcRX, arcRY, 45, false, false, BPoint(100, 20));
|
||||||
|
shape.Close();
|
||||||
|
|
||||||
|
translator.SetOffset(30, 30);
|
||||||
|
translator.Iterate(&shape);
|
||||||
|
|
||||||
|
SetHighColor(40, 130, 150, 255);
|
||||||
|
StrokeShape(&shape);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// #pragma mark -
|
||||||
|
|
||||||
|
|
||||||
|
int
|
||||||
|
main(int argc, char** argv)
|
||||||
|
{
|
||||||
|
BApplication app(kAppSignature);
|
||||||
|
|
||||||
|
BWindow* window = new BWindow(BRect(50.0, 50.0, 300.0, 250.0),
|
||||||
|
"BShape Test", B_TITLED_WINDOW,
|
||||||
|
B_ASYNCHRONOUS_CONTROLS | B_QUIT_ON_WINDOW_CLOSE);
|
||||||
|
|
||||||
|
BView* view = new TestView(window->Bounds(), "test", B_FOLLOW_ALL,
|
||||||
|
B_WILL_DRAW);
|
||||||
|
window->AddChild(view);
|
||||||
|
|
||||||
|
window->Show();
|
||||||
|
|
||||||
|
app.Run();
|
||||||
|
return 0;
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user