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:
Oliver Tappe
2009-04-30 18:44:26 +00:00
parent d5ad762913
commit 819c98a383
2 changed files with 34 additions and 30 deletions
+1
View File
@@ -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;
} }
} }