// ------------------------------------------------------------------ // Desc: // ------------------------------------------------------------------ private static float BuildLine(string _text, exISpriteFont _sprite, ref int _parsedVbIndex, float _top) { // cache property var letterSpacing = _sprite.letterSpacing; var wordSpacing = _sprite.wordSpacing; bool useKerning = _sprite.useKerning; exFont font = _sprite.font; // Vector2 pos = new Vector2(0.0f, _top); float lastAdvance = 0.0f; float lastWidth = 0.0f; for (int _charIndex = 0; _charIndex < _text.Length; ++_charIndex, _parsedVbIndex += 4, pos.x += letterSpacing) { char c = _text[_charIndex]; // if new line if (c == '\n' || c == '\r') { vertices.buffer[_parsedVbIndex + 0] = new Vector3(); vertices.buffer[_parsedVbIndex + 1] = new Vector3(); vertices.buffer[_parsedVbIndex + 2] = new Vector3(); vertices.buffer[_parsedVbIndex + 3] = new Vector3(); ++_charIndex; _parsedVbIndex += 4; break; } bool hasPreviousChar = _charIndex > 0; if (hasPreviousChar) { pos.x += lastAdvance; // kerning if (useKerning) { pos.x += font.GetKerning(_text[_charIndex - 1], c); } // wordSpacing if (c == ' ') { pos.x += wordSpacing; } } float width, advance; if (BuildChar(font, c, pos, _parsedVbIndex, out width, out advance)) { // advance x lastWidth = width; lastAdvance = advance; } } return(pos.x + lastWidth); }
// ------------------------------------------------------------------ // Desc: This only calculate result in one line // ------------------------------------------------------------------ public static bool CalcTextLine( out int _end_x, out int _end_index, StringBuilder _builder, string _text, int _index, int _maxWidth, exFont _font, int _wordSpacing, int _letterSpacing, bool _wrapWord, bool _collapseSpace, bool _collapseLinebreak ) { int cur_index = _index; int next_index = _index; int word_start_index = _index; int cur_x = 0; int word_start_x = 0; bool linebreak = false; bool trimWhitespace = true; bool beginningOfLine = true; char last_ch = '\0'; while ( cur_index < _text.Length ) { bool skipcpy = false; char ch = _text[cur_index]; next_index = cur_index+1; // if this is line-break if ( ch == '\n' || ch == '\r' ) { if ( _collapseLinebreak ) { ch = ' '; // turn it to space } else { linebreak = true; } } // if this is space if ( ch == ' ' || ch == '\t' || ch == '\f' ) { if ( _collapseSpace ) { while ( next_index < _text.Length ) { char next_ch = _text[next_index]; next_index = next_index + 1; // if next_ch is white-space, then collapse this char if ( next_ch == ' ' || next_ch == '\t' || next_ch == '\f' ) { cur_index = next_index-1; continue; } // if next_ch is line-break and collapseLinebreak is true, then collapse this char if ( next_ch == '\n' || next_ch == '\r' ) { if ( _collapseLinebreak ) { cur_index = next_index-1; continue; } } // break; } // skip first-time collapse if ( trimWhitespace ) { trimWhitespace = false; cur_index = next_index; continue; } // yes, must turn it to space to make sure only one space ch = ' '; } } // trimWhitespace = false; // process word-break, word-wrap if ( _wrapWord ) { word_start_index = cur_index; word_start_x = cur_x; // if this character can break if ( next_index >= _text.Length || CanWordBreak (ch) ) { // advanced character if ( last_ch != '\0' ) { cur_x += _font.GetKerning(last_ch, ch); } cur_x += _font.GetAdvance(ch); last_ch = ch; // check if the word exceed content width if ( cur_x > _maxWidth ) { if ( !beginningOfLine ) { linebreak = true; // skip copy the white-space if it is at the end of the wrap if ( ch == ' ' || ch == '\t' || ch == '\f' ) { skipcpy = true; } else { next_index = word_start_index; cur_x = word_start_x; } } } beginningOfLine = false; } else { // advanced current character if ( last_ch != '\0' ) { cur_x += _font.GetKerning(last_ch, ch); } cur_x += _font.GetAdvance(ch); last_ch = ch; while ( next_index < _text.Length ) { char next_ch = _text[next_index]; next_index = next_index + 1; // if this character can break if ( CanWordBreak (next_ch) ) { next_index -= 1; break; } // advanced character if ( last_ch != '\0' ) { cur_x += _font.GetKerning(last_ch, next_ch); } cur_x += _font.GetAdvance(next_ch); last_ch = next_ch; // TODO: process word-break // check if the word exceed content width if ( cur_x > _maxWidth ) { if ( !beginningOfLine ) { linebreak = true; next_index = word_start_index; cur_x = word_start_x; skipcpy = true; break; } } } } } else { // advanced character if ( last_ch != '\0' ) { cur_x += _font.GetKerning(last_ch, ch); } cur_x += _font.GetAdvance(ch); last_ch = ch; } // copy character to newtext_p if ( !skipcpy ) { int cpylen = next_index-cur_index; if ( cpylen > 0 ) { _builder.Append(_text, cur_index, cpylen ); } } // step cur_index = next_index; if ( linebreak ) { break; } } _end_x = cur_x; _end_index = cur_index; return linebreak; }
// ------------------------------------------------------------------ // Desc: This only calculate result in one line // ------------------------------------------------------------------ public static bool CalcTextLine(out int _end_x, out int _end_index, StringBuilder _builder, string _text, int _index, int _maxWidth, exFont _font, int _wordSpacing, int _letterSpacing, bool _wrapWord, bool _collapseSpace, bool _collapseLinebreak) { int cur_index = _index; int next_index = _index; int word_start_index = _index; int cur_x = 0; int word_start_x = 0; bool linebreak = false; bool trimWhitespace = true; bool beginningOfLine = true; char last_ch = '\0'; while (cur_index < _text.Length) { bool skipcpy = false; char ch = _text[cur_index]; next_index = cur_index + 1; // if this is line-break if (ch == '\n' || ch == '\r') { if (_collapseLinebreak) { ch = ' '; // turn it to space } else { linebreak = true; } } // if this is space if (ch == ' ' || ch == '\t' || ch == '\f') { if (_collapseSpace) { while (next_index < _text.Length) { char next_ch = _text[next_index]; next_index = next_index + 1; // if next_ch is white-space, then collapse this char if (next_ch == ' ' || next_ch == '\t' || next_ch == '\f') { cur_index = next_index - 1; continue; } // if next_ch is line-break and collapseLinebreak is true, then collapse this char if (next_ch == '\n' || next_ch == '\r') { if (_collapseLinebreak) { cur_index = next_index - 1; continue; } } // break; } // skip first-time collapse if (trimWhitespace) { trimWhitespace = false; cur_index = next_index; continue; } // yes, must turn it to space to make sure only one space ch = ' '; } } // trimWhitespace = false; // process word-break, word-wrap if (_wrapWord) { word_start_index = cur_index; word_start_x = cur_x; // if this character can break if (next_index >= _text.Length || CanWordBreak(ch)) { // advanced character if (last_ch != '\0') { cur_x += _font.GetKerning(last_ch, ch); } cur_x += _font.GetAdvance(ch); last_ch = ch; // check if the word exceed content width if (cur_x > _maxWidth) { if (!beginningOfLine) { linebreak = true; // skip copy the white-space if it is at the end of the wrap if (ch == ' ' || ch == '\t' || ch == '\f') { skipcpy = true; } else { next_index = word_start_index; cur_x = word_start_x; } } } beginningOfLine = false; } else { // advanced current character if (last_ch != '\0') { cur_x += _font.GetKerning(last_ch, ch); } cur_x += _font.GetAdvance(ch); last_ch = ch; while (next_index < _text.Length) { char next_ch = _text[next_index]; next_index = next_index + 1; // if this character can break if (CanWordBreak(next_ch)) { next_index -= 1; break; } // advanced character if (last_ch != '\0') { cur_x += _font.GetKerning(last_ch, next_ch); } cur_x += _font.GetAdvance(next_ch); last_ch = next_ch; // TODO: process word-break // check if the word exceed content width if (cur_x > _maxWidth) { if (!beginningOfLine) { linebreak = true; next_index = word_start_index; cur_x = word_start_x; skipcpy = true; break; } } } } } else { // advanced character if (last_ch != '\0') { cur_x += _font.GetKerning(last_ch, ch); } cur_x += _font.GetAdvance(ch); last_ch = ch; } // copy character to newtext_p if (!skipcpy) { int cpylen = next_index - cur_index; if (cpylen > 0) { _builder.Append(_text, cur_index, cpylen); } } // step cur_index = next_index; if (linebreak) { break; } } _end_x = cur_x; _end_index = cur_index; return(linebreak); }