seems like the BShape implementation was never tested, this update brings it into working condition, but the code could use more refactoring... duplication all over the place

git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@14734 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
Stephan Aßmus
2005-11-07 01:19:36 +00:00
parent b574c74121
commit b5f439b668
+144 -166
View File
@@ -1,49 +1,33 @@
//------------------------------------------------------------------------------ /*
// Copyright (c) 2001-2002, OpenBeOS * Copyright (c) 2001-2005, Haiku, Inc.
// * Distributed under the terms of the MIT license.
// Permission is hereby granted, free of charge, to any person obtaining a *
// copy of this software and associated documentation files (the "Software"), * Authors:
// to deal in the Software without restriction, including without limitation * Marc Flerackers ([email protected])
// the rights to use, copy, modify, merge, publish, distribute, sublicense, * Stephan Aßmus <[email protected]>
// and/or sell copies of the Software, and to permit persons to whom the *
// Software is furnished to do so, subject to the following conditions: * Description:
// * BShape encapsulates a Postscript-style "path"
// The above copyright notice and this permission notice shall be included in */
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
// DEALINGS IN THE SOFTWARE.
//
// File Name: Shape.cpp
// Author: Marc Flerackers ([email protected])
// Description: BShape encapsulates a Postscript-style "path"
//------------------------------------------------------------------------------
// Standard Includes -----------------------------------------------------------
#include <stdlib.h> #include <stdlib.h>
// System Includes -------------------------------------------------------------
#include <Shape.h> #include <Shape.h>
#include <Point.h> #include <Point.h>
#include <Rect.h> #include <Rect.h>
#include <Errors.h> #include <Errors.h>
#include <Message.h> #include <Message.h>
// Project Includes ------------------------------------------------------------
// Local Includes -------------------------------------------------------------- // NOTE: changing these defines will break Painter,
// currently located in src/servers/app/drawing/Painter/Painter.cpp
// Local Defines ---------------------------------------------------------------
#define OP_LINETO 0x10000000 #define OP_LINETO 0x10000000
#define OP_BEZIERTO 0x20000000 #define OP_BEZIERTO 0x20000000
#define OP_CLOSE 0x40000000 #define OP_CLOSE 0x40000000
#define OP_MOVETO 0x80000000 #define OP_MOVETO 0x80000000
struct shape_data { struct shape_data {
uint32 *opList; uint32 *opList;
int32 opCount; int32 opCount;
@@ -55,35 +39,32 @@ struct shape_data {
int32 ptBlockSize; int32 ptBlockSize;
}; };
// Globals ---------------------------------------------------------------------
//------------------------------------------------------------------------------
BShapeIterator::BShapeIterator() BShapeIterator::BShapeIterator()
{ {
} }
//------------------------------------------------------------------------------
BShapeIterator::~BShapeIterator() BShapeIterator::~BShapeIterator()
{ {
} }
//------------------------------------------------------------------------------
status_t BShapeIterator::Iterate(BShape *shape)
status_t
BShapeIterator::Iterate(BShape *shape)
{ {
shape_data *data = (shape_data*)shape->fPrivateData; shape_data *data = (shape_data*)shape->fPrivateData;
BPoint *points = data->ptList; BPoint *points = data->ptList;
for (int32 i = 0; i < data->opCount; i++) for (int32 i = 0; i < data->opCount; i++) {
{ switch (data->opList[i] & 0xFF000000) {
switch (data->opList[i] & 0xFF000000) case OP_LINETO: {
{
case OP_LINETO:
{
int32 count = data->opList[i] & 0x00FFFFFF; int32 count = data->opList[i] & 0x00FFFFFF;
IterateLineTo(count, points); IterateLineTo(count, points);
points += count; points += count;
break; break;
} }
case (OP_MOVETO | OP_LINETO): case (OP_MOVETO | OP_LINETO): {
{
int32 count = data->opList[i] & 0x00FFFFFF; int32 count = data->opList[i] & 0x00FFFFFF;
IterateMoveTo(points); IterateMoveTo(points);
points++; points++;
@@ -91,15 +72,13 @@ status_t BShapeIterator::Iterate(BShape *shape)
points += count; points += count;
break; break;
} }
case OP_BEZIERTO: case OP_BEZIERTO: {
{
int32 count = data->opList[i] & 0x00FFFFFF; int32 count = data->opList[i] & 0x00FFFFFF;
IterateBezierTo(count, points); IterateBezierTo(count, points);
points += count; points += count;
break; break;
} }
case (OP_MOVETO | OP_BEZIERTO): case (OP_MOVETO | OP_BEZIERTO): {
{
int32 count = data->opList[i] & 0x00FFFFFF; int32 count = data->opList[i] & 0x00FFFFFF;
IterateMoveTo(points); IterateMoveTo(points);
points++; points++;
@@ -108,8 +87,7 @@ status_t BShapeIterator::Iterate(BShape *shape)
break; break;
} }
case OP_CLOSE: case OP_CLOSE:
case OP_CLOSE | OP_LINETO | OP_BEZIERTO: case OP_CLOSE | OP_LINETO | OP_BEZIERTO: {
{
IterateClose(); IterateClose();
break; break;
} }
@@ -118,46 +96,56 @@ status_t BShapeIterator::Iterate(BShape *shape)
return B_OK; return B_OK;
} }
//------------------------------------------------------------------------------
status_t BShapeIterator::IterateBezierTo(int32 bezierCount,
status_t
BShapeIterator::IterateBezierTo(int32 bezierCount,
BPoint *bezierPoints) BPoint *bezierPoints)
{ {
return B_OK; return B_OK;
} }
//------------------------------------------------------------------------------
status_t BShapeIterator::IterateClose()
status_t
BShapeIterator::IterateClose()
{ {
return B_OK; return B_OK;
} }
//------------------------------------------------------------------------------
status_t BShapeIterator::IterateLineTo(int32 lineCount, BPoint *linePoints)
status_t
BShapeIterator::IterateLineTo(int32 lineCount, BPoint *linePoints)
{ {
return B_OK; return B_OK;
} }
//------------------------------------------------------------------------------
status_t BShapeIterator::IterateMoveTo ( BPoint *point )
status_t
BShapeIterator::IterateMoveTo ( BPoint *point )
{ {
return B_OK; return B_OK;
} }
//------------------------------------------------------------------------------
void BShapeIterator::_ReservedShapeIterator1() {} void BShapeIterator::_ReservedShapeIterator1() {}
void BShapeIterator::_ReservedShapeIterator2() {} void BShapeIterator::_ReservedShapeIterator2() {}
void BShapeIterator::_ReservedShapeIterator3() {} void BShapeIterator::_ReservedShapeIterator3() {}
void BShapeIterator::_ReservedShapeIterator4() {} void BShapeIterator::_ReservedShapeIterator4() {}
//------------------------------------------------------------------------------
//------------------------------------------------------------------------------
BShape::BShape() BShape::BShape()
{ {
InitData(); InitData();
} }
//------------------------------------------------------------------------------
BShape::BShape(const BShape &copyFrom) BShape::BShape(const BShape &copyFrom)
{ {
InitData(); InitData();
AddShape(&copyFrom); AddShape(&copyFrom);
} }
//------------------------------------------------------------------------------
BShape::BShape(BMessage *archive) BShape::BShape(BMessage *archive)
: BArchivable(archive) : BArchivable(archive)
{ {
@@ -169,10 +157,8 @@ BShape::BShape(BMessage *archive)
const uint32 *opPtr; const uint32 *opPtr;
while (archive->FindData("ops", B_INT32_TYPE, i++, (const void**)&opPtr, &size) == B_OK) while (archive->FindData("ops", B_INT32_TYPE, i++, (const void**)&opPtr, &size) == B_OK) {
{ if (data->opSize < data->opCount + 1) {
if (data->opSize < data->opCount + 1)
{
int32 new_size = ((data->opCount + data->opBlockSize) / int32 new_size = ((data->opCount + data->opBlockSize) /
data->opBlockSize) * data->opBlockSize; data->opBlockSize) * data->opBlockSize;
data->opList = (uint32*)realloc(data->opList, new_size * sizeof(uint32)); data->opList = (uint32*)realloc(data->opList, new_size * sizeof(uint32));
@@ -184,10 +170,8 @@ BShape::BShape(BMessage *archive)
const BPoint *ptPtr; const BPoint *ptPtr;
while (archive->FindData("pts", B_POINT_TYPE, i++, (const void**)&ptPtr, &size) == B_OK) while (archive->FindData("pts", B_POINT_TYPE, i++, (const void**)&ptPtr, &size) == B_OK) {
{ if (data->ptSize < data->ptCount + 1) {
if (data->ptSize < data->ptCount + 1)
{
int32 new_size = ((data->ptCount + data->ptBlockSize) / int32 new_size = ((data->ptCount + data->ptBlockSize) /
data->ptBlockSize) * data->ptBlockSize; data->ptBlockSize) * data->ptBlockSize;
data->ptList = (BPoint*)realloc(data->ptList, data->ptList = (BPoint*)realloc(data->ptList,
@@ -198,7 +182,8 @@ BShape::BShape(BMessage *archive)
data->ptList[data->ptCount++] = *ptPtr; data->ptList[data->ptCount++] = *ptPtr;
} }
} }
//------------------------------------------------------------------------------
BShape::~BShape() BShape::~BShape()
{ {
shape_data *data = (shape_data*)fPrivateData; shape_data *data = (shape_data*)fPrivateData;
@@ -208,8 +193,10 @@ BShape::~BShape()
delete (shape_data*)fPrivateData; delete (shape_data*)fPrivateData;
} }
//------------------------------------------------------------------------------
status_t BShape::Archive(BMessage *archive, bool deep) const
status_t
BShape::Archive(BMessage *archive, bool deep) const
{ {
status_t err = BArchivable::Archive(archive, deep); status_t err = BArchivable::Archive(archive, deep);
int32 i; int32 i;
@@ -241,31 +228,35 @@ status_t BShape::Archive(BMessage *archive, bool deep) const
return err; return err;
} }
//------------------------------------------------------------------------------
BArchivable *BShape::Instantiate(BMessage *archive)
BArchivable*
BShape::Instantiate(BMessage *archive)
{ {
if (validate_instantiation(archive, "BShape")) if (validate_instantiation(archive, "BShape"))
return new BShape(archive); return new BShape(archive);
else else
return NULL; return NULL;
} }
//------------------------------------------------------------------------------
void BShape::Clear()
void
BShape::Clear()
{ {
shape_data *data = (shape_data*)fPrivateData; shape_data *data = (shape_data*)fPrivateData;
if (data->opList) if (data->opList) {
{
free(data->opList); free(data->opList);
data->opList = NULL; data->opList = NULL;
data->opCount = 0; data->opCount = 0;
data->opSize = 0;
} }
if (data->ptList) if (data->ptList) {
{
free(data->ptList); free(data->ptList);
data->ptList = NULL; data->ptList = NULL;
data->ptCount = 0; data->ptCount = 0;
data->ptSize = 0;
} }
fState = 0; fState = 0;
@@ -346,31 +337,17 @@ BShape::MoveTo(BPoint point)
// If the last op is MoveTo, replace the point // If the last op is MoveTo, replace the point
// If there was a previous op, add the op // If there was a previous op, add the op
if (fBuildingOp == OP_MOVETO) if (fBuildingOp == OP_MOVETO) {
{
data->ptList[data->ptCount - 1] = point; data->ptList[data->ptCount - 1] = point;
return B_OK; return B_OK;
} }
else if (fBuildingOp != 0)
{
if (data->opSize < data->opCount + 1)
{
int32 new_size = ((data->opCount + data->opBlockSize) /
data->opBlockSize) * data->opBlockSize;
data->opList = (uint32*)realloc(data->opList, new_size * sizeof(uint32));
data->opSize = new_size;
}
data->opList[data->opCount++] = fBuildingOp;
}
// BuildingOp is MoveTo // BuildingOp is MoveTo
fBuildingOp = OP_MOVETO; fBuildingOp = OP_MOVETO;
// Add point // Add point
if (data->ptSize < data->ptCount + 1) if (data->ptSize < data->ptCount + 1) {
{
int32 new_size = ((data->ptCount + data->ptBlockSize) / int32 new_size = ((data->ptCount + data->ptBlockSize) /
data->ptBlockSize) * data->ptBlockSize; data->ptBlockSize) * data->ptBlockSize;
data->ptList = (BPoint*)realloc(data->ptList, new_size * sizeof(BPoint)); data->ptList = (BPoint*)realloc(data->ptList, new_size * sizeof(BPoint));
@@ -381,43 +358,39 @@ BShape::MoveTo(BPoint point)
return B_OK; return B_OK;
} }
//------------------------------------------------------------------------------
status_t BShape::LineTo(BPoint point)
status_t
BShape::LineTo(BPoint point)
{ {
shape_data *data = (shape_data*)fPrivateData; shape_data *data = (shape_data*)fPrivateData;
// If the last op is MoveTo, replace the op and set the count // If the last op is MoveTo, replace the op and set the count
// If the last op is LineTo increase the count // If the last op is LineTo increase the count
// If there was a previous op, add the op // If there was a previous op, add the op
if (fBuildingOp == OP_MOVETO) bool newOp = true;
{ if (fBuildingOp == OP_MOVETO) {
fBuildingOp = OP_LINETO | OP_MOVETO | 0x01; fBuildingOp = OP_LINETO | OP_MOVETO;
} else if (fBuildingOp & OP_LINETO) {
newOp = false;
} else {
fBuildingOp = OP_LINETO;
} }
else if (fBuildingOp & OP_LINETO) fBuildingOp++;
{
fBuildingOp++;
}
else
{
if (fBuildingOp != 0)
{
if (data->opSize < data->opCount + 1)
{
int32 new_size = ((data->opCount + data->opBlockSize) /
data->opBlockSize) * data->opBlockSize;
data->opList = (uint32*)realloc(data->opList, new_size * sizeof(uint32));
data->opSize = new_size;
}
data->opList[data->opCount++] = fBuildingOp; if (newOp) {
if (data->opSize < data->opCount + 1) {
int32 new_size = ((data->opCount + data->opBlockSize) /
data->opBlockSize) * data->opBlockSize;
data->opList = (uint32*)realloc(data->opList, new_size * sizeof(uint32));
data->opSize = new_size;
} }
data->opCount++;
fBuildingOp = OP_LINETO | 0x01;
} }
data->opList[data->opCount - 1] = fBuildingOp;
// Add point // Add point
if (data->ptSize < data->ptCount + 1) if (data->ptSize < data->ptCount + 1) {
{
int32 new_size = ((data->ptCount + data->ptBlockSize) / int32 new_size = ((data->ptCount + data->ptBlockSize) /
data->ptBlockSize) * data->ptBlockSize; data->ptBlockSize) * data->ptBlockSize;
data->ptList = (BPoint*)realloc(data->ptList, new_size * sizeof(BPoint)); data->ptList = (BPoint*)realloc(data->ptList, new_size * sizeof(BPoint));
@@ -428,39 +401,37 @@ status_t BShape::LineTo(BPoint point)
return B_OK; return B_OK;
} }
//------------------------------------------------------------------------------
status_t BShape::BezierTo(BPoint controlPoints[3])
status_t
BShape::BezierTo(BPoint controlPoints[3])
{ {
shape_data *data = (shape_data*)fPrivateData; shape_data *data = (shape_data*)fPrivateData;
// If the last op is MoveTo, replace the op and set the count // If the last op is MoveTo, replace the op and set the count
// If the last op is BezierTo increase the count // If the last op is BezierTo increase the count
// If there was a previous op, add the op // If there was a previous op, add the op
if (fBuildingOp == OP_MOVETO) bool newOp = true;
{ if (fBuildingOp == OP_MOVETO) {
fBuildingOp = OP_BEZIERTO | OP_MOVETO | 0x03; fBuildingOp = OP_BEZIERTO | OP_MOVETO;
} else if (fBuildingOp & OP_BEZIERTO) {
newOp = false;
} else {
fBuildingOp = OP_BEZIERTO;
} }
else if (fBuildingOp & OP_BEZIERTO) fBuildingOp += 3;
{
fBuildingOp += 3;
}
else
{
if (fBuildingOp != 0)
{
if (data->opSize < data->opCount + 1)
{
int32 new_size = ((data->opCount + data->opBlockSize) /
data->opBlockSize) * data->opBlockSize;
data->opList = (uint32*)realloc(data->opList, new_size * sizeof(uint32));
data->opSize = new_size;
}
data->opList[data->opCount++] = fBuildingOp; if (newOp) {
if (data->opSize < data->opCount + 1) {
int32 new_size = ((data->opCount + data->opBlockSize) /
data->opBlockSize) * data->opBlockSize;
data->opList = (uint32*)realloc(data->opList, new_size * sizeof(uint32));
data->opSize = new_size;
} }
data->opCount++;
fBuildingOp = OP_BEZIERTO | 0x03;
} }
data->opList[data->opCount - 1] = fBuildingOp;
// Add points // Add points
if (data->ptSize < data->ptCount + 3) if (data->ptSize < data->ptCount + 3)
@@ -477,16 +448,16 @@ status_t BShape::BezierTo(BPoint controlPoints[3])
return B_OK; return B_OK;
} }
//------------------------------------------------------------------------------
status_t BShape::Close()
status_t
BShape::Close()
{ {
shape_data *data = (shape_data*)fPrivateData; shape_data *data = (shape_data*)fPrivateData;
// If there was a previous line/bezier op, add the op // If there was a previous line/bezier op, add the op
if (fBuildingOp & (OP_LINETO | OP_BEZIERTO)) if (fBuildingOp & (OP_LINETO | OP_BEZIERTO)) {
{ if (data->opSize < data->opCount + 1) {
if (data->opSize < data->opCount + 1)
{
int32 new_size = ((data->opCount + data->opBlockSize) / int32 new_size = ((data->opCount + data->opBlockSize) /
data->opBlockSize) * data->opBlockSize; data->opBlockSize) * data->opBlockSize;
data->opList = (uint32*)realloc(data->opList, new_size * sizeof(uint32)); data->opList = (uint32*)realloc(data->opList, new_size * sizeof(uint32));
@@ -499,18 +470,23 @@ status_t BShape::Close()
return B_OK; return B_OK;
} }
//------------------------------------------------------------------------------
status_t BShape::Perform(perform_code d, void *arg)
status_t
BShape::Perform(perform_code d, void *arg)
{ {
return BArchivable::Perform(d, arg); return BArchivable::Perform(d, arg);
} }
//------------------------------------------------------------------------------
void BShape::_ReservedShape1() {} void BShape::_ReservedShape1() {}
void BShape::_ReservedShape2() {} void BShape::_ReservedShape2() {}
void BShape::_ReservedShape3() {} void BShape::_ReservedShape3() {}
void BShape::_ReservedShape4() {} void BShape::_ReservedShape4() {}
//------------------------------------------------------------------------------
void BShape::GetData(int32 *opCount, int32 *ptCount, uint32 **opList,
void
BShape::GetData(int32 *opCount, int32 *ptCount, uint32 **opList,
BPoint **ptList) BPoint **ptList)
{ {
shape_data *data = (shape_data*)fPrivateData; shape_data *data = (shape_data*)fPrivateData;
@@ -520,14 +496,15 @@ void BShape::GetData(int32 *opCount, int32 *ptCount, uint32 **opList,
*opList = data->opList; *opList = data->opList;
*ptList = data->ptList; *ptList = data->ptList;
} }
//------------------------------------------------------------------------------
void BShape::SetData(int32 opCount, int32 ptCount, uint32 *opList,
BPoint *ptList) void
BShape::SetData(int32 opCount, int32 ptCount, uint32 *opList,
BPoint *ptList)
{ {
shape_data *data = (shape_data*)fPrivateData; shape_data *data = (shape_data*)fPrivateData;
if (data->opSize < opCount) if (data->opSize < opCount) {
{
int32 new_size = ((opCount + data->opBlockSize) / int32 new_size = ((opCount + data->opBlockSize) /
data->opBlockSize) * data->opBlockSize; data->opBlockSize) * data->opBlockSize;
@@ -538,8 +515,7 @@ void BShape::SetData(int32 opCount, int32 ptCount, uint32 *opList,
memcpy(data->opList, opList, opCount * sizeof(uint32)); memcpy(data->opList, opList, opCount * sizeof(uint32));
data->opCount = opCount; data->opCount = opCount;
if (data->ptSize < ptCount) if (data->ptSize < ptCount) {
{
int32 new_size = ((ptCount + data->ptBlockSize) / int32 new_size = ((ptCount + data->ptBlockSize) /
data->ptBlockSize) * data->ptBlockSize; data->ptBlockSize) * data->ptBlockSize;
@@ -550,8 +526,10 @@ void BShape::SetData(int32 opCount, int32 ptCount, uint32 *opList,
memcpy(data->ptList, ptList, ptCount * sizeof(BPoint)); memcpy(data->ptList, ptList, ptCount * sizeof(BPoint));
data->ptCount = ptCount; data->ptCount = ptCount;
} }
//------------------------------------------------------------------------------
void BShape::InitData()
void
BShape::InitData()
{ {
fPrivateData = new shape_data; fPrivateData = new shape_data;
shape_data *data = (shape_data*)fPrivateData; shape_data *data = (shape_data*)fPrivateData;