Fixing #3040 (DeskCalcs textview showing wrong/multiple styles)
* fixed crash in StyleBuffer::SetStyleFromMode() if any of the given pointers is NULL (which is perfectly valid) * BTextView::SetFontAndColor() now syncs the null style before it sets the range, thus making sure that there is only one style if the view is not stylable git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@30516 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
@@ -1619,6 +1619,7 @@ BTextView::SetFontAndColor(int32 startOffset, int32 endOffset,
|
|||||||
endOffset = textLength;
|
endOffset = textLength;
|
||||||
|
|
||||||
// add the style to the style buffer
|
// add the style to the style buffer
|
||||||
|
fStyles->SyncNullStyle(startOffset);
|
||||||
fStyles->SetStyleRange(startOffset, endOffset, fText->Length(),
|
fStyles->SetStyleRange(startOffset, endOffset, fText->Length(),
|
||||||
fontMode, &newFont, color);
|
fontMode, &newFont, color);
|
||||||
|
|
||||||
|
|||||||
@@ -43,11 +43,11 @@ _BStyleRunDescBuffer_::OffsetToRun(int32 offset) const
|
|||||||
{
|
{
|
||||||
if (fItemCount <= 1)
|
if (fItemCount <= 1)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
int32 minIndex = 0;
|
int32 minIndex = 0;
|
||||||
int32 maxIndex = fItemCount;
|
int32 maxIndex = fItemCount;
|
||||||
int32 index = 0;
|
int32 index = 0;
|
||||||
|
|
||||||
while (minIndex < maxIndex) {
|
while (minIndex < maxIndex) {
|
||||||
index = (minIndex + maxIndex) >> 1;
|
index = (minIndex + maxIndex) >> 1;
|
||||||
if (offset >= fBuffer[index].offset) {
|
if (offset >= fBuffer[index].offset) {
|
||||||
@@ -62,7 +62,7 @@ _BStyleRunDescBuffer_::OffsetToRun(int32 offset) const
|
|||||||
} else
|
} else
|
||||||
maxIndex = index;
|
maxIndex = index;
|
||||||
}
|
}
|
||||||
|
|
||||||
return index;
|
return index;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -88,7 +88,7 @@ int32
|
|||||||
_BStyleRecordBuffer_::InsertRecord(const BFont *inFont, const rgb_color *inColor)
|
_BStyleRecordBuffer_::InsertRecord(const BFont *inFont, const rgb_color *inColor)
|
||||||
{
|
{
|
||||||
int32 index = 0;
|
int32 index = 0;
|
||||||
|
|
||||||
// look for style in buffer
|
// look for style in buffer
|
||||||
if (MatchRecord(inFont, inColor, &index))
|
if (MatchRecord(inFont, inColor, &index))
|
||||||
return index;
|
return index;
|
||||||
@@ -96,7 +96,7 @@ _BStyleRecordBuffer_::InsertRecord(const BFont *inFont, const rgb_color *inColor
|
|||||||
// style not found, add it
|
// style not found, add it
|
||||||
font_height fh;
|
font_height fh;
|
||||||
inFont->GetHeight(&fh);
|
inFont->GetHeight(&fh);
|
||||||
|
|
||||||
// check if there's any unused space
|
// check if there's any unused space
|
||||||
for (index = 0; index < fItemCount; index++) {
|
for (index = 0; index < fItemCount; index++) {
|
||||||
if (fBuffer[index].refs < 1) {
|
if (fBuffer[index].refs < 1) {
|
||||||
@@ -106,12 +106,12 @@ _BStyleRecordBuffer_::InsertRecord(const BFont *inFont, const rgb_color *inColor
|
|||||||
fBuffer[index].style.font = *inFont;
|
fBuffer[index].style.font = *inFont;
|
||||||
fBuffer[index].style.color = *inColor;
|
fBuffer[index].style.color = *inColor;
|
||||||
return index;
|
return index;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// no unused space, expand the buffer
|
// no unused space, expand the buffer
|
||||||
const STEStyle style = { *inFont, *inColor };
|
const STEStyle style = { *inFont, *inColor };
|
||||||
const STEStyleRecord newRecord = {
|
const STEStyleRecord newRecord = {
|
||||||
0,
|
0,
|
||||||
fh.ascent,
|
fh.ascent,
|
||||||
fh.descent + fh.leading,
|
fh.descent + fh.leading,
|
||||||
@@ -141,7 +141,7 @@ bool
|
|||||||
_BStyleRecordBuffer_::MatchRecord(const BFont *inFont, const rgb_color *inColor, int32 *outIndex)
|
_BStyleRecordBuffer_::MatchRecord(const BFont *inFont, const rgb_color *inColor, int32 *outIndex)
|
||||||
{
|
{
|
||||||
for (int32 i = 0; i < fItemCount; i++) {
|
for (int32 i = 0; i < fItemCount; i++) {
|
||||||
if (*inFont == fBuffer[i].style.font
|
if (*inFont == fBuffer[i].style.font
|
||||||
&& *inColor == fBuffer[i].style.color) {
|
&& *inColor == fBuffer[i].style.color) {
|
||||||
*outIndex = i;
|
*outIndex = i;
|
||||||
return true;
|
return true;
|
||||||
@@ -158,17 +158,20 @@ _BStyleRecordBuffer_::MatchRecord(const BFont *inFont, const rgb_color *inColor,
|
|||||||
static void
|
static void
|
||||||
SetStyleFromMode(uint32 mode, const BFont *fromFont, BFont *toFont,
|
SetStyleFromMode(uint32 mode, const BFont *fromFont, BFont *toFont,
|
||||||
const rgb_color *fromColor, rgb_color *toColor)
|
const rgb_color *fromColor, rgb_color *toColor)
|
||||||
{
|
{
|
||||||
if (mode & B_FONT_FAMILY_AND_STYLE)
|
if (fromFont != NULL && toFont != NULL) {
|
||||||
toFont->SetFamilyAndStyle(fromFont->FamilyAndStyle());
|
if (mode & B_FONT_FAMILY_AND_STYLE)
|
||||||
|
toFont->SetFamilyAndStyle(fromFont->FamilyAndStyle());
|
||||||
|
|
||||||
if (mode & B_FONT_SIZE)
|
if (mode & B_FONT_SIZE)
|
||||||
toFont->SetSize(fromFont->Size());
|
toFont->SetSize(fromFont->Size());
|
||||||
|
|
||||||
if (mode & B_FONT_SHEAR)
|
if (mode & B_FONT_SHEAR)
|
||||||
toFont->SetShear(fromFont->Shear());
|
toFont->SetShear(fromFont->Shear());
|
||||||
|
}
|
||||||
|
|
||||||
if (!mode || (mode == B_FONT_ALL))
|
if (fromColor != NULL && toColor != NULL
|
||||||
|
&& (mode == 0 || mode == B_FONT_ALL))
|
||||||
*toColor = *fromColor;
|
*toColor = *fromColor;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -206,7 +209,7 @@ BTextView::StyleBuffer::SyncNullStyle(int32 offset)
|
|||||||
fNullStyle = fStyleRecord[fStyleRunDesc[index]->index]->style;
|
fNullStyle = fStyleRecord[fStyleRunDesc[index]->index]->style;
|
||||||
|
|
||||||
fValidNullStyle = true;
|
fValidNullStyle = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void
|
void
|
||||||
@@ -218,7 +221,7 @@ BTextView::StyleBuffer::SetNullStyle(uint32 inMode, const BFont *inFont,
|
|||||||
else {
|
else {
|
||||||
int32 index = OffsetToRun(offset - 1);
|
int32 index = OffsetToRun(offset - 1);
|
||||||
fNullStyle = fStyleRecord[fStyleRunDesc[index]->index]->style;
|
fNullStyle = fStyleRecord[fStyleRunDesc[index]->index]->style;
|
||||||
SetStyleFromMode(inMode, inFont, &fNullStyle.font, inColor, &fNullStyle.color);
|
SetStyleFromMode(inMode, inFont, &fNullStyle.font, inColor, &fNullStyle.color);
|
||||||
}
|
}
|
||||||
|
|
||||||
fValidNullStyle = true;
|
fValidNullStyle = true;
|
||||||
@@ -244,7 +247,7 @@ BTextView::StyleBuffer::AllocateStyleRange(const int32 numStyles) const
|
|||||||
return range;
|
return range;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void
|
void
|
||||||
BTextView::StyleBuffer::SetStyleRange(int32 fromOffset, int32 toOffset,
|
BTextView::StyleBuffer::SetStyleRange(int32 fromOffset, int32 toOffset,
|
||||||
int32 textLen, uint32 inMode, const BFont *inFont,
|
int32 textLen, uint32 inMode, const BFont *inFont,
|
||||||
@@ -260,7 +263,7 @@ BTextView::StyleBuffer::SetStyleRange(int32 fromOffset, int32 toOffset,
|
|||||||
SetNullStyle(inMode, inFont, inColor, fromOffset);
|
SetNullStyle(inMode, inFont, inColor, fromOffset);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (fStyleRunDesc.ItemCount() < 1) {
|
if (fStyleRunDesc.ItemCount() < 1) {
|
||||||
STEStyleRunDesc newDesc;
|
STEStyleRunDesc newDesc;
|
||||||
newDesc.offset = fromOffset;
|
newDesc.offset = fromOffset;
|
||||||
@@ -278,7 +281,7 @@ BTextView::StyleBuffer::SetStyleRange(int32 fromOffset, int32 toOffset,
|
|||||||
int32 runEnd = textLen;
|
int32 runEnd = textLen;
|
||||||
if (runIndex < fStyleRunDesc.ItemCount() - 1)
|
if (runIndex < fStyleRunDesc.ItemCount() - 1)
|
||||||
runEnd = fStyleRunDesc[runIndex + 1]->offset;
|
runEnd = fStyleRunDesc[runIndex + 1]->offset;
|
||||||
|
|
||||||
STEStyle style = fStyleRecord[runDesc.index]->style;
|
STEStyle style = fStyleRecord[runDesc.index]->style;
|
||||||
SetStyleFromMode(inMode, inFont, &style.font, inColor, &style.color);
|
SetStyleFromMode(inMode, inFont, &style.font, inColor, &style.color);
|
||||||
|
|
||||||
@@ -287,7 +290,7 @@ BTextView::StyleBuffer::SetStyleRange(int32 fromOffset, int32 toOffset,
|
|||||||
if (runDesc.offset == offset && runIndex > 0
|
if (runDesc.offset == offset && runIndex > 0
|
||||||
&& fStyleRunDesc[runIndex - 1]->index == styleIndex) {
|
&& fStyleRunDesc[runIndex - 1]->index == styleIndex) {
|
||||||
RemoveStyles(runIndex);
|
RemoveStyles(runIndex);
|
||||||
runIndex--;
|
runIndex--;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (styleIndex != runDesc.index) {
|
if (styleIndex != runDesc.index) {
|
||||||
@@ -297,7 +300,7 @@ BTextView::StyleBuffer::SetStyleRange(int32 fromOffset, int32 toOffset,
|
|||||||
newDesc.index = styleIndex;
|
newDesc.index = styleIndex;
|
||||||
fStyleRunDesc.InsertDesc(&newDesc, runIndex + 1);
|
fStyleRunDesc.InsertDesc(&newDesc, runIndex + 1);
|
||||||
fStyleRecord.CommitRecord(newDesc.index);
|
fStyleRecord.CommitRecord(newDesc.index);
|
||||||
runIndex++;
|
runIndex++;
|
||||||
} else {
|
} else {
|
||||||
fStyleRunDesc[runIndex]->index = styleIndex;
|
fStyleRunDesc[runIndex]->index = styleIndex;
|
||||||
fStyleRecord.CommitRecord(styleIndex);
|
fStyleRecord.CommitRecord(styleIndex);
|
||||||
@@ -500,7 +503,7 @@ FixupMode(const STEStyle &firstStyle, const STEStyle &otherStyle, uint32 &mode,
|
|||||||
}
|
}
|
||||||
if (firstStyle.color != otherStyle.color)
|
if (firstStyle.color != otherStyle.color)
|
||||||
sameColor = false;
|
sameColor = false;
|
||||||
|
|
||||||
// TODO: Finish this: handle B_FONT_FACE, B_FONT_FLAGS, etc.
|
// TODO: Finish this: handle B_FONT_FACE, B_FONT_FLAGS, etc.
|
||||||
// if needed
|
// if needed
|
||||||
}
|
}
|
||||||
@@ -521,14 +524,14 @@ BTextView::StyleBuffer::ContinuousGetStyle(BFont *outFont, uint32 *ioMode,
|
|||||||
if (outColor)
|
if (outColor)
|
||||||
*outColor = fNullStyle.color;
|
*outColor = fNullStyle.color;
|
||||||
if (sameColor)
|
if (sameColor)
|
||||||
*sameColor = true;
|
*sameColor = true;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
int32 fromIndex = OffsetToRun(fromOffset);
|
int32 fromIndex = OffsetToRun(fromOffset);
|
||||||
int32 toIndex = OffsetToRun(toOffset - 1);
|
int32 toIndex = OffsetToRun(toOffset - 1);
|
||||||
|
|
||||||
if (fromIndex == toIndex) {
|
if (fromIndex == toIndex) {
|
||||||
int32 styleIndex = fStyleRunDesc[fromIndex]->index;
|
int32 styleIndex = fStyleRunDesc[fromIndex]->index;
|
||||||
const STEStyle* style = &fStyleRecord[styleIndex]->style;
|
const STEStyle* style = &fStyleRecord[styleIndex]->style;
|
||||||
|
|
||||||
@@ -539,12 +542,12 @@ BTextView::StyleBuffer::ContinuousGetStyle(BFont *outFont, uint32 *ioMode,
|
|||||||
if (outColor)
|
if (outColor)
|
||||||
*outColor = style->color;
|
*outColor = style->color;
|
||||||
if (sameColor)
|
if (sameColor)
|
||||||
*sameColor = true;
|
*sameColor = true;
|
||||||
} else {
|
} else {
|
||||||
bool oneColor = true;
|
bool oneColor = true;
|
||||||
int32 styleIndex = fStyleRunDesc[toIndex]->index;
|
int32 styleIndex = fStyleRunDesc[toIndex]->index;
|
||||||
STEStyle theStyle = fStyleRecord[styleIndex]->style;
|
STEStyle theStyle = fStyleRecord[styleIndex]->style;
|
||||||
|
|
||||||
for (int32 i = fromIndex; i < toIndex; i++) {
|
for (int32 i = fromIndex; i < toIndex; i++) {
|
||||||
styleIndex = fStyleRunDesc[i]->index;
|
styleIndex = fStyleRunDesc[i]->index;
|
||||||
FixupMode(fStyleRecord[styleIndex]->style, theStyle, mode, oneColor);
|
FixupMode(fStyleRecord[styleIndex]->style, theStyle, mode, oneColor);
|
||||||
@@ -557,6 +560,6 @@ BTextView::StyleBuffer::ContinuousGetStyle(BFont *outFont, uint32 *ioMode,
|
|||||||
if (outColor)
|
if (outColor)
|
||||||
*outColor = theStyle.color;
|
*outColor = theStyle.color;
|
||||||
if (sameColor)
|
if (sameColor)
|
||||||
*sameColor = oneColor;
|
*sameColor = oneColor;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user