* Improve clarity of some code.

* Preserve transparency of default color when color
   changes via tag.


git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@38826 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
Stephan Aßmus 2010-09-27 09:43:55 +00:00
parent f6d6a61645
commit 4ad39ed76d

View File

@ -117,9 +117,9 @@ SubtitleBitmap::_GenerateBitmap()
struct ParseState { struct ParseState {
ParseState() ParseState(rgb_color color)
: :
color(rgb_color().set_to(255, 255, 255, 255)), color(color),
bold(false), bold(false),
italic(false), italic(false),
underlined(false), underlined(false),
@ -138,6 +138,7 @@ struct ParseState {
previous(previous) previous(previous)
{ {
} }
rgb_color color; rgb_color color;
bool bold; bool bold;
bool italic; bool italic;
@ -159,7 +160,7 @@ find_next_tag(const BString& string, int32& tagPos, int32& tagLength,
}; };
static const int32 kTagCount = sizeof(kTags) / sizeof(const char*); static const int32 kTagCount = sizeof(kTags) / sizeof(const char*);
int32 current = tagPos; int32 startPos = tagPos;
tagPos = string.Length(); tagPos = string.Length();
tagLength = 0; tagLength = 0;
@ -167,49 +168,50 @@ find_next_tag(const BString& string, int32& tagPos, int32& tagLength,
// This way of doing it allows broken input with overlapping tags even. // This way of doing it allows broken input with overlapping tags even.
BString tag; BString tag;
for (int32 i = 0; i < kTagCount; i++) { for (int32 i = 0; i < kTagCount; i++) {
int32 nextTag = string.IFindFirst(kTags[i], current); int32 nextTag = string.IFindFirst(kTags[i], startPos);
if (nextTag >= current && nextTag < tagPos) { if (nextTag >= startPos && nextTag < tagPos) {
tagPos = nextTag; tagPos = nextTag;
tag = kTags[i]; tag = kTags[i];
} }
} }
if (tag != "") { if (tag.Length() == 0)
// Tag found, ParseState will change. return false;
tagLength = tag.Length();
if (tag == "<b>") { // Tag found, ParseState will change.
state = new ParseState(state); tagLength = tag.Length();
state->bold = true; if (tag == "<b>") {
} else if (tag == "<i>") { state = new ParseState(state);
state = new ParseState(state); state->bold = true;
state->italic = true; } else if (tag == "<i>") {
} else if (tag == "<u>") { state = new ParseState(state);
state = new ParseState(state); state->italic = true;
state->underlined = true; } else if (tag == "<u>") {
} else if (tag == "<font color=\"#") { state = new ParseState(state);
state = new ParseState(state); state->underlined = true;
char number[16]; } else if (tag == "<font color=\"#") {
snprintf(number, sizeof(number), "0x%.6s", state = new ParseState(state);
string.String() + tagPos + tag.Length()); char number[16];
int colorInt; snprintf(number, sizeof(number), "0x%.6s",
if (sscanf(number, "%x", &colorInt) == 1) { string.String() + tagPos + tag.Length());
state->color.red = (colorInt & 0xff0000) >> 16; int colorInt;
state->color.green = (colorInt & 0x00ff00) >> 8; if (sscanf(number, "%x", &colorInt) == 1) {
state->color.blue = (colorInt & 0x0000ff); state->color.red = (colorInt & 0xff0000) >> 16;
tagLength += 8; state->color.green = (colorInt & 0x00ff00) >> 8;
} state->color.blue = (colorInt & 0x0000ff);
} else if (tag == "</b>" || tag == "</i>" || tag == "</u>" // skip 'RRGGBB">' part, too
|| tag == "</font>") { tagLength += 8;
// Closing tag, pop state }
if (state->previous != NULL) { } else if (tag == "</b>" || tag == "</i>" || tag == "</u>"
ParseState* oldState = state; || tag == "</font>") {
state = state->previous; // Closing tag, pop state
delete oldState; if (state->previous != NULL) {
} ParseState* oldState = state;
state = state->previous;
delete oldState;
} }
return true;
} }
return false; return true;
} }
@ -223,6 +225,8 @@ apply_state(BTextView* textView, const ParseState* state, BFont font,
face |= B_BOLD_FACE; face |= B_BOLD_FACE;
if (state->italic) if (state->italic)
face |= B_ITALIC_FACE; face |= B_ITALIC_FACE;
// NOTE: This is probably not supported by the app_server (perhaps
// it is if the font contains a specific underline face).
if (state->underlined) if (state->underlined)
face |= B_UNDERSCORE_FACE; face |= B_UNDERSCORE_FACE;
} else } else
@ -237,9 +241,11 @@ apply_state(BTextView* textView, const ParseState* state, BFont font,
static void static void
parse_text(const BString& string, BTextView* textView, const BFont& font, parse_text(const BString& string, BTextView* textView, const BFont& font,
bool changeColor) const rgb_color& color, bool changeColor)
{ {
ParseState rootState; ParseState rootState(color);
// Colors may change, but alpha channel will be preserved
ParseState* state = &rootState; ParseState* state = &rootState;
int32 pos = 0; int32 pos = 0;
@ -294,14 +300,14 @@ SubtitleBitmap::_InsertText()
fTextView->SetFontAndColor(&font, B_FONT_ALL, &color); fTextView->SetFontAndColor(&font, B_FONT_ALL, &color);
fTextView->Insert(" "); fTextView->Insert(" ");
parse_text(fText, fTextView, font, true); parse_text(fText, fTextView, font, color, true);
font.SetFalseBoldWidth(falseBoldWidth); font.SetFalseBoldWidth(falseBoldWidth);
fShadowTextView->SetText(NULL); fShadowTextView->SetText(NULL);
fShadowTextView->SetFontAndColor(&font, B_FONT_ALL, &shadow); fShadowTextView->SetFontAndColor(&font, B_FONT_ALL, &shadow);
fShadowTextView->Insert(" "); fShadowTextView->Insert(" ");
parse_text(fText, fShadowTextView, font, false); parse_text(fText, fShadowTextView, font, shadow, false);
// This causes the BTextView to calculate the layout of the text // This causes the BTextView to calculate the layout of the text
fTextView->SetTextRect(BRect(0, 0, 0, 0)); fTextView->SetTextRect(BRect(0, 0, 0, 0));