* fix weird Shape op/point allocation
* handle out of memory situations * don't try to copy (and assign op!) in SetData if opCount/ptCount is 0 -> FontDemo doesn't crash anymore eventually when cycling fonts in outline mode git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@22000 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
parent
a728651f04
commit
f591e3a0f2
@ -84,8 +84,8 @@ virtual void _ReservedShape4();
|
|||||||
void GetData(int32 *opCount, int32 *ptCount, uint32 **opList, BPoint **ptList);
|
void GetData(int32 *opCount, int32 *ptCount, uint32 **opList, BPoint **ptList);
|
||||||
void SetData(int32 opCount, int32 ptCount, const uint32 *opList, const BPoint *ptList);
|
void SetData(int32 opCount, int32 ptCount, const uint32 *opList, const BPoint *ptList);
|
||||||
void InitData();
|
void InitData();
|
||||||
void AllocatePts(int32 count);
|
bool AllocatePts(int32 count);
|
||||||
void AllocateOps(int32 count);
|
bool AllocateOps(int32 count);
|
||||||
|
|
||||||
uint32 fState;
|
uint32 fState;
|
||||||
uint32 fBuildingOp;
|
uint32 fBuildingOp;
|
||||||
|
@ -19,11 +19,9 @@ struct shape_data {
|
|||||||
uint32 *opList;
|
uint32 *opList;
|
||||||
int32 opCount;
|
int32 opCount;
|
||||||
int32 opSize;
|
int32 opSize;
|
||||||
int32 opBlockSize;
|
|
||||||
BPoint *ptList;
|
BPoint *ptList;
|
||||||
int32 ptCount;
|
int32 ptCount;
|
||||||
int32 ptSize;
|
int32 ptSize;
|
||||||
int32 ptBlockSize;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
@ -130,7 +130,8 @@ BShape::BShape(BMessage *archive)
|
|||||||
int32 count = 0;
|
int32 count = 0;
|
||||||
type_code type = 0;
|
type_code type = 0;
|
||||||
archive->GetInfo("ops", &type, &count);
|
archive->GetInfo("ops", &type, &count);
|
||||||
AllocateOps(count);
|
if (!AllocateOps(count))
|
||||||
|
return;
|
||||||
|
|
||||||
int32 i = 0;
|
int32 i = 0;
|
||||||
const uint32 *opPtr;
|
const uint32 *opPtr;
|
||||||
@ -138,7 +139,10 @@ BShape::BShape(BMessage *archive)
|
|||||||
data->opList[data->opCount++] = *opPtr;
|
data->opList[data->opCount++] = *opPtr;
|
||||||
|
|
||||||
archive->GetInfo("pts", &type, &count);
|
archive->GetInfo("pts", &type, &count);
|
||||||
AllocatePts(count);
|
if (!AllocatePts(count)) {
|
||||||
|
Clear();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
i = 0;
|
i = 0;
|
||||||
const BPoint *ptPtr;
|
const BPoint *ptPtr;
|
||||||
@ -263,12 +267,13 @@ BShape::AddShape(const BShape *otherShape)
|
|||||||
shape_data *data = (shape_data*)fPrivateData;
|
shape_data *data = (shape_data*)fPrivateData;
|
||||||
shape_data *otherData = (shape_data*)otherShape->fPrivateData;
|
shape_data *otherData = (shape_data*)otherShape->fPrivateData;
|
||||||
|
|
||||||
AllocateOps(otherData->opCount);
|
if (!AllocateOps(otherData->opCount) || !AllocatePts(otherData->ptCount))
|
||||||
|
return B_NO_MEMORY;
|
||||||
|
|
||||||
memcpy(data->opList + data->opCount * sizeof(uint32), otherData->opList,
|
memcpy(data->opList + data->opCount * sizeof(uint32), otherData->opList,
|
||||||
otherData->opCount * sizeof(uint32));
|
otherData->opCount * sizeof(uint32));
|
||||||
data->opCount += otherData->opCount;
|
data->opCount += otherData->opCount;
|
||||||
|
|
||||||
AllocatePts(otherData->ptCount);
|
|
||||||
memcpy(data->ptList + data->ptCount * sizeof(BPoint), otherData->ptList,
|
memcpy(data->ptList + data->ptCount * sizeof(BPoint), otherData->ptList,
|
||||||
otherData->ptCount * sizeof(BPoint));
|
otherData->ptCount * sizeof(BPoint));
|
||||||
data->ptCount += otherData->ptCount;
|
data->ptCount += otherData->ptCount;
|
||||||
@ -290,14 +295,15 @@ BShape::MoveTo(BPoint point)
|
|||||||
return B_OK;
|
return B_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!AllocateOps(1) || !AllocatePts(1))
|
||||||
|
return B_NO_MEMORY;
|
||||||
|
|
||||||
fBuildingOp = OP_MOVETO;
|
fBuildingOp = OP_MOVETO;
|
||||||
|
|
||||||
// Add op
|
// Add op
|
||||||
AllocateOps(1);
|
|
||||||
data->opList[data->opCount++] = fBuildingOp;
|
data->opList[data->opCount++] = fBuildingOp;
|
||||||
|
|
||||||
// Add point
|
// Add point
|
||||||
AllocatePts(1);
|
|
||||||
data->ptList[data->ptCount++] = point;
|
data->ptList[data->ptCount++] = point;
|
||||||
|
|
||||||
return B_OK;
|
return B_OK;
|
||||||
@ -307,6 +313,9 @@ BShape::MoveTo(BPoint point)
|
|||||||
status_t
|
status_t
|
||||||
BShape::LineTo(BPoint point)
|
BShape::LineTo(BPoint point)
|
||||||
{
|
{
|
||||||
|
if (!AllocatePts(1))
|
||||||
|
return B_NO_MEMORY;
|
||||||
|
|
||||||
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
|
||||||
@ -317,13 +326,13 @@ BShape::LineTo(BPoint point)
|
|||||||
fBuildingOp += 1;
|
fBuildingOp += 1;
|
||||||
data->opList[data->opCount - 1] = fBuildingOp;
|
data->opList[data->opCount - 1] = fBuildingOp;
|
||||||
} else {
|
} else {
|
||||||
|
if (!AllocateOps(1))
|
||||||
|
return B_NO_MEMORY;
|
||||||
fBuildingOp = OP_LINETO + 1;
|
fBuildingOp = OP_LINETO + 1;
|
||||||
AllocateOps(1);
|
|
||||||
data->opList[data->opCount++] = fBuildingOp;
|
data->opList[data->opCount++] = fBuildingOp;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Add point
|
// Add point
|
||||||
AllocatePts(1);
|
|
||||||
data->ptList[data->ptCount++] = point;
|
data->ptList[data->ptCount++] = point;
|
||||||
|
|
||||||
return B_OK;
|
return B_OK;
|
||||||
@ -333,6 +342,9 @@ BShape::LineTo(BPoint point)
|
|||||||
status_t
|
status_t
|
||||||
BShape::BezierTo(BPoint controlPoints[3])
|
BShape::BezierTo(BPoint controlPoints[3])
|
||||||
{
|
{
|
||||||
|
if (!AllocatePts(3))
|
||||||
|
return B_NO_MEMORY;
|
||||||
|
|
||||||
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
|
||||||
@ -343,13 +355,13 @@ BShape::BezierTo(BPoint controlPoints[3])
|
|||||||
fBuildingOp += 3;
|
fBuildingOp += 3;
|
||||||
data->opList[data->opCount - 1] = fBuildingOp;
|
data->opList[data->opCount - 1] = fBuildingOp;
|
||||||
} else {
|
} else {
|
||||||
|
if (!AllocateOps(1))
|
||||||
|
return B_NO_MEMORY;
|
||||||
fBuildingOp = OP_BEZIERTO + 3;
|
fBuildingOp = OP_BEZIERTO + 3;
|
||||||
AllocateOps(1);
|
|
||||||
data->opList[data->opCount++] = fBuildingOp;
|
data->opList[data->opCount++] = fBuildingOp;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Add points
|
// Add points
|
||||||
AllocatePts(3);
|
|
||||||
data->ptList[data->ptCount++] = controlPoints[0];
|
data->ptList[data->ptCount++] = controlPoints[0];
|
||||||
data->ptList[data->ptCount++] = controlPoints[1];
|
data->ptList[data->ptCount++] = controlPoints[1];
|
||||||
data->ptList[data->ptCount++] = controlPoints[2];
|
data->ptList[data->ptCount++] = controlPoints[2];
|
||||||
@ -361,12 +373,14 @@ BShape::BezierTo(BPoint controlPoints[3])
|
|||||||
status_t
|
status_t
|
||||||
BShape::Close()
|
BShape::Close()
|
||||||
{
|
{
|
||||||
shape_data *data = (shape_data*)fPrivateData;
|
|
||||||
|
|
||||||
// If the last op is Close or MoveTo, ignore this
|
// If the last op is Close or MoveTo, ignore this
|
||||||
if (fBuildingOp == OP_CLOSE || fBuildingOp == OP_MOVETO)
|
if (fBuildingOp == OP_CLOSE || fBuildingOp == OP_MOVETO)
|
||||||
return B_OK;
|
return B_OK;
|
||||||
|
|
||||||
|
if (!AllocateOps(1))
|
||||||
|
return B_NO_MEMORY;
|
||||||
|
|
||||||
|
shape_data *data = (shape_data*)fPrivateData;
|
||||||
|
|
||||||
// ToDo: Decide about that, it's not BeOS compatible
|
// ToDo: Decide about that, it's not BeOS compatible
|
||||||
// If there was any op before we can attach the close to it
|
// If there was any op before we can attach the close to it
|
||||||
@ -377,7 +391,6 @@ BShape::Close()
|
|||||||
}*/
|
}*/
|
||||||
|
|
||||||
fBuildingOp = OP_CLOSE;
|
fBuildingOp = OP_CLOSE;
|
||||||
AllocateOps(1);
|
|
||||||
data->opList[data->opCount++] = fBuildingOp;
|
data->opList[data->opCount++] = fBuildingOp;
|
||||||
|
|
||||||
return B_OK;
|
return B_OK;
|
||||||
@ -416,17 +429,25 @@ BShape::SetData(int32 opCount, int32 ptCount, const uint32 *opList,
|
|||||||
{
|
{
|
||||||
Clear();
|
Clear();
|
||||||
|
|
||||||
|
if (opCount == 0)
|
||||||
|
return;
|
||||||
|
|
||||||
shape_data *data = (shape_data*)fPrivateData;
|
shape_data *data = (shape_data*)fPrivateData;
|
||||||
|
|
||||||
AllocateOps(opCount);
|
if (!AllocateOps(opCount) || !AllocatePts(ptCount))
|
||||||
|
return;
|
||||||
|
|
||||||
memcpy(data->opList, opList, opCount * sizeof(uint32));
|
memcpy(data->opList, opList, opCount * sizeof(uint32));
|
||||||
data->opCount = opCount;
|
data->opCount = opCount;
|
||||||
fBuildingOp = data->opList[data->opCount - 1];
|
fBuildingOp = data->opList[data->opCount - 1];
|
||||||
|
|
||||||
AllocatePts(ptCount);
|
if (ptCount > 0) {
|
||||||
memcpy(data->ptList, ptList, ptCount * sizeof(BPoint));
|
memcpy(data->ptList, ptList, ptCount * sizeof(BPoint));
|
||||||
data->ptCount = ptCount;
|
data->ptCount = ptCount;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
void
|
void
|
||||||
@ -441,41 +462,47 @@ BShape::InitData()
|
|||||||
data->opList = NULL;
|
data->opList = NULL;
|
||||||
data->opCount = 0;
|
data->opCount = 0;
|
||||||
data->opSize = 0;
|
data->opSize = 0;
|
||||||
data->opBlockSize = 255;
|
|
||||||
data->ptList = NULL;
|
data->ptList = NULL;
|
||||||
data->ptCount = 0;
|
data->ptCount = 0;
|
||||||
data->ptSize = 0;
|
data->ptSize = 0;
|
||||||
data->ptBlockSize = 255;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
inline void
|
inline bool
|
||||||
BShape::AllocateOps(int32 count)
|
BShape::AllocateOps(int32 count)
|
||||||
{
|
{
|
||||||
shape_data *data = (shape_data*)fPrivateData;
|
shape_data *data = (shape_data*)fPrivateData;
|
||||||
|
|
||||||
while (data->opSize < data->opCount + count) {
|
int32 newSize = (data->opCount + count + 255) / 256 * 256;
|
||||||
int32 new_size = ((data->opCount + data->opBlockSize) /
|
if (data->opSize >= newSize)
|
||||||
data->opBlockSize) * data->opBlockSize;
|
return true;
|
||||||
data->opList = (uint32*)realloc(data->opList, new_size * sizeof(uint32));
|
|
||||||
data->opSize = new_size;
|
uint32* resizedArray = (uint32*)realloc(data->opList, newSize * sizeof(uint32));
|
||||||
count -= data->opBlockSize;
|
if (resizedArray) {
|
||||||
|
data->opList = resizedArray;
|
||||||
|
data->opSize = newSize;
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
inline void
|
inline bool
|
||||||
BShape::AllocatePts(int32 count)
|
BShape::AllocatePts(int32 count)
|
||||||
{
|
{
|
||||||
shape_data *data = (shape_data*)fPrivateData;
|
shape_data *data = (shape_data*)fPrivateData;
|
||||||
|
|
||||||
while (data->ptSize < data->ptCount + count) {
|
int32 newSize = (data->ptCount + count + 255) / 256 * 256;
|
||||||
int32 new_size = ((data->ptCount + data->ptBlockSize) /
|
if (data->ptSize >= newSize)
|
||||||
data->ptBlockSize) * data->ptBlockSize;
|
return true;
|
||||||
data->ptList = (BPoint*)realloc(data->ptList, new_size * sizeof(BPoint));
|
|
||||||
data->ptSize = new_size;
|
BPoint* resizedArray = (BPoint*)realloc(data->ptList, newSize * sizeof(BPoint));
|
||||||
count -= data->ptBlockSize;
|
if (resizedArray) {
|
||||||
|
data->ptList = resizedArray;
|
||||||
|
data->ptSize = newSize;
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user