TextBreakIteratorGtk.cpp [plain text]
#include "config.h"
#include "GOwnPtr.h"
#include "TextBreakIterator.h"
#include <pango/pango.h>
namespace WebCore {
enum UBreakIteratorType {
UBRK_CHARACTER,
UBRK_WORD,
UBRK_LINE,
UBRK_SENTENCE
};
class TextBreakIterator {
public:
UBreakIteratorType m_type;
int m_length;
PangoLogAttr* m_logAttrs;
int m_index;
};
static TextBreakIterator* setUpIterator(bool& createdIterator, TextBreakIterator*& iterator,
UBreakIteratorType type, const UChar* string, int length)
{
if (!string)
return 0;
if (!createdIterator) {
iterator = new TextBreakIterator();
createdIterator = true;
}
if (!iterator)
return 0;
long utf8len;
GOwnPtr<char> utf8;
utf8.set(g_utf16_to_utf8(string, length, 0, &utf8len, 0));
iterator->m_type = type;
iterator->m_length = length;
if (createdIterator)
g_free(iterator->m_logAttrs);
iterator->m_logAttrs = g_new0(PangoLogAttr, length + 1);
iterator->m_index = -1;
pango_get_log_attrs(utf8.get(), utf8len, -1, 0, iterator->m_logAttrs, length + 1);
return iterator;
}
TextBreakIterator* characterBreakIterator(const UChar* string, int length)
{
static bool createdCharacterBreakIterator = false;
static TextBreakIterator* staticCharacterBreakIterator;
return setUpIterator(createdCharacterBreakIterator, staticCharacterBreakIterator, UBRK_CHARACTER, string, length);
}
TextBreakIterator* cursorMovementIterator(const UChar* string, int length)
{
return characterBreakIterator(string, length);
}
TextBreakIterator* wordBreakIterator(const UChar* string, int length)
{
static bool createdWordBreakIterator = false;
static TextBreakIterator* staticWordBreakIterator;
return setUpIterator(createdWordBreakIterator, staticWordBreakIterator, UBRK_WORD, string, length);
}
TextBreakIterator* lineBreakIterator(const UChar* string, int length)
{
static bool createdLineBreakIterator = false;
static TextBreakIterator* staticLineBreakIterator;
return setUpIterator(createdLineBreakIterator, staticLineBreakIterator, UBRK_LINE, string, length);
}
TextBreakIterator* sentenceBreakIterator(const UChar* string, int length)
{
static bool createdSentenceBreakIterator = false;
static TextBreakIterator* staticSentenceBreakIterator;
return setUpIterator(createdSentenceBreakIterator, staticSentenceBreakIterator, UBRK_SENTENCE, string, length);
}
int textBreakFirst(TextBreakIterator* bi)
{
int firstCursorPosition = -1;
int pos = 0;
while (pos <= bi->m_length && (firstCursorPosition < 0)) {
if (bi->m_logAttrs[pos].is_cursor_position)
firstCursorPosition = pos;
}
bi->m_index = firstCursorPosition;
return firstCursorPosition;
}
int textBreakLast(TextBreakIterator* bi)
{
bool whiteSpaceAtTheEnd = true;
int nextWhiteSpacePos = bi->m_length;
int pos = bi->m_length;
while (pos >= 0 && whiteSpaceAtTheEnd) {
if (bi->m_logAttrs[pos].is_cursor_position) {
if (whiteSpaceAtTheEnd = bi->m_logAttrs[pos].is_white)
nextWhiteSpacePos = pos;
}
pos--;
}
bi->m_index = nextWhiteSpacePos;
return nextWhiteSpacePos;
}
int textBreakNext(TextBreakIterator* bi)
{
for (int i = bi->m_index + 1; i <= bi->m_length; i++) {
if ((bi->m_type == UBRK_LINE && bi->m_logAttrs[i].is_line_break)
|| (bi->m_type == UBRK_WORD && (bi->m_logAttrs[i].is_word_start || bi->m_logAttrs[i].is_word_end))
|| (bi->m_type == UBRK_CHARACTER && bi->m_logAttrs[i].is_cursor_position)
|| (bi->m_type == UBRK_SENTENCE && (bi->m_logAttrs[i].is_sentence_start || bi->m_logAttrs[i].is_sentence_end)) ) {
bi->m_index = i;
return i;
}
}
return TextBreakDone;
}
int textBreakPrevious(TextBreakIterator* bi)
{
for (int i = bi->m_index - 1; i >= 0; i--) {
if ((bi->m_type == UBRK_LINE && bi->m_logAttrs[i].is_line_break)
|| (bi->m_type == UBRK_WORD && (bi->m_logAttrs[i].is_word_start || bi->m_logAttrs[i].is_word_end))
|| (bi->m_type == UBRK_CHARACTER && bi->m_logAttrs[i].is_cursor_position)
|| (bi->m_type == UBRK_SENTENCE && (bi->m_logAttrs[i].is_sentence_start || bi->m_logAttrs[i].is_sentence_end)) ) {
bi->m_index = i;
return i;
}
}
return textBreakFirst(bi);
}
int textBreakPreceding(TextBreakIterator* bi, int pos)
{
bi->m_index = pos;
return textBreakPrevious(bi);
}
int textBreakFollowing(TextBreakIterator* bi, int pos)
{
if (pos < 0)
pos = -1;
bi->m_index = pos;
return textBreakNext(bi);
}
int textBreakCurrent(TextBreakIterator* bi)
{
return bi->m_index;
}
bool isTextBreak(TextBreakIterator* bi, int pos)
{
if (bi->m_index < 0)
return false;
return ((bi->m_type == UBRK_LINE && bi->m_logAttrs[bi->m_index].is_line_break)
|| (bi->m_type == UBRK_WORD && bi->m_logAttrs[bi->m_index].is_word_end)
|| (bi->m_type == UBRK_CHARACTER && bi->m_logAttrs[bi->m_index].is_char_break)
|| (bi->m_type == UBRK_SENTENCE && bi->m_logAttrs[bi->m_index].is_sentence_end) );
}
}