Fixed all wrapping issues that I know of (non-working wrapping at end of text, broken hard-wrapping of overlong words, visual leftovers after a word got wrapped):

* adjusted _FindLineBreak() to no longer expect that only whitespace can
  end a line, as that is simply not true
* CanEndLine() returns true for characters that are followed by end-of-text
  or a separator
* activated the commented lines in CanEndLine() that allow '...' to be treated
  as a word
As I have nothing more relating to BTextView on my todo-list, I will start doing something else now, but please *do* send any complaints my way ;-)

git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@30473 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
Oliver Tappe 2009-04-27 20:58:37 +00:00
parent dc4c7cc492
commit 6241755766
1 changed files with 56 additions and 37 deletions

View File

@ -1955,7 +1955,8 @@ BTextView::CanEndLine(int32 offset)
} }
uint32 nextClassification = _CharClassification(offset + 1); uint32 nextClassification = _CharClassification(offset + 1);
if (nextClassification == B_END_OF_TEXT) if (nextClassification == B_END_OF_TEXT
|| nextClassification == B_SEPARATOR_CHARACTER)
return true; return true;
if (classification == B_PUNCTUATION_CHARACTER if (classification == B_PUNCTUATION_CHARACTER
@ -1963,16 +1964,12 @@ BTextView::CanEndLine(int32 offset)
return true; return true;
} }
// TODO: This cannot be enabled, since the wrapping code things the char uint32 nextNextClassification = _CharClassification(offset + 2);
// is a trailing space or something. Otherwise it would allow to treat if (classification == B_OTHER_CHARACTER
// something like "..." as a word. && nextClassification == B_PUNCTUATION_CHARACTER
// uint32 nextNextClassification = _CharClassification(offset + 2); && nextClassification == nextNextClassification) {
// return true;
// if (classification == B_OTHER_CHARACTER }
// && nextClassification == B_PUNCTUATION_CHARACTER
// && nextClassification == nextNextClassification) {
// return true;
// }
return false; return false;
} }
@ -3801,39 +3798,44 @@ BTextView::_FindLineBreak(int32 fromOffset, float *outAscent, float *outDescent,
float deltaWidth = 0.0; float deltaWidth = 0.0;
float tabWidth = 0.0; float tabWidth = 0.0;
float strWidth = 0.0; float strWidth = 0.0;
uchar theChar;
// wrap the text // wrap the text
do { do {
bool foundTab = false; bool foundTab = false;
// find the next line break candidate // find the next line break candidate
for ( ; (offset + delta) < limit ; delta++) { for ( ; (offset + delta) < limit ; delta++) {
if (CanEndLine(offset + delta)) if (CanEndLine(offset + delta)) {
theChar = fText->RealCharAt(offset + delta);
if (theChar != B_SPACE && theChar != B_TAB
&& theChar != B_ENTER) {
// we are scanning for trailing whitespace below, so we
// have to skip non-whitespace characters, that can end
// the line, here
delta++;
}
break; break;
}
} }
// now skip over trailing whitespace, if any
for ( ; (offset + delta) < limit; delta++) { for ( ; (offset + delta) < limit; delta++) {
uchar theChar = fText->RealCharAt(offset + delta);
if (!CanEndLine(offset + delta)) if (!CanEndLine(offset + delta))
break; break;
theChar = fText->RealCharAt(offset + delta);
if (theChar == B_ENTER) { if (theChar == B_ENTER) {
// found a newline, we're done! // found a newline, we're done!
done = true; done = true;
delta++; delta++;
break; break;
} else if (theChar != B_SPACE && theChar != B_TAB) {
// stop at anything else than trailing whitespace
break;
} else { } else {
// include all trailing spaces and tabs, // include all trailing spaces and tabs,
// but not spaces after tabs // but not spaces after tabs
if (theChar != B_SPACE && theChar != B_TAB) if (theChar == B_TAB)
break; foundTab = true;
else {
if (theChar == B_SPACE && foundTab)
break;
else {
if (theChar == B_TAB)
foundTab = true;
}
}
} }
} }
delta = max_c(delta, 1); delta = max_c(delta, 1);
@ -3860,23 +3862,39 @@ BTextView::_FindLineBreak(int32 fromOffset, float *outAscent, float *outDescent,
// we've found where the line will wrap // we've found where the line will wrap
bool foundNewline = done; bool foundNewline = done;
done = true; done = true;
// we have included trailing whitespace in the width computation
// above, but that is not being shown anyway, so we try again
// without the trailing whitespace
int32 pos = delta - 1; int32 pos = delta - 1;
if (!CanEndLine(offset + pos)) theChar = fText->RealCharAt(offset + pos);
if (theChar != B_SPACE && theChar != B_TAB && theChar != B_ENTER) {
// there is no trailing whitespace, no point in trying
break; break;
strWidth -= (deltaWidth + tabWidth);
while (offset + pos > offset) {
if (!CanEndLine(offset + pos))
break;
pos--;
} }
// reset string width to start of current run ...
strWidth -= (deltaWidth + tabWidth);
// ... skip back all trailing whitespace ...
while (offset + pos > offset) {
theChar = fText->RealCharAt(offset + pos);
if (theChar != B_SPACE && theChar != B_TAB
&& theChar != B_ENTER)
break;
pos--;
}
// ... and compute the resulting width (of visible characters)
strWidth += _StyledWidth(offset, pos + 1, &ascent, &descent); strWidth += _StyledWidth(offset, pos + 1, &ascent, &descent);
if (strWidth >= *ioWidth) if (strWidth >= *ioWidth) {
// width of visible characters exceeds line, we need to wrap
// before the current "word"
break; break;
}
// we can include the current "word" on this line, but we need
// to eat the trailing whitespace, such that we do not encounter
// it again during the next run
// TODO: can this ever be entered?
if (!foundNewline) { if (!foundNewline) {
while (offset + delta < limit) { while (offset + delta < limit) {
const char realChar = fText->RealCharAt(offset + delta); const char realChar = fText->RealCharAt(offset + delta);
@ -3889,7 +3907,8 @@ BTextView::_FindLineBreak(int32 fromOffset, float *outAscent, float *outDescent,
&& fText->RealCharAt(offset + delta) == B_ENTER) && fText->RealCharAt(offset + delta) == B_ENTER)
delta++; delta++;
} }
// get the ascent and descent of the spaces/tabs // get the ascent and descent of the current word, including all
// trailing whitespace
_StyledWidth(offset, delta, &ascent, &descent); _StyledWidth(offset, delta, &ascent, &descent);
} }
@ -3909,8 +3928,8 @@ BTextView::_FindLineBreak(int32 fromOffset, float *outAscent, float *outDescent,
strWidth = 0.0; strWidth = 0.0;
int32 current = fromOffset; int32 current = fromOffset;
for (offset = fromOffset; offset < limit; current = offset, for (offset = _NextInitialByte(current); current < limit;
offset = _NextInitialByte(offset)) { current = offset, offset = _NextInitialByte(offset)) {
strWidth += _StyledWidth(current, offset - current, &ascent, strWidth += _StyledWidth(current, offset - current, &ascent,
&descent); &descent);
if (strWidth >= *ioWidth) { if (strWidth >= *ioWidth) {