/*
Реализация спецификаций CLDC версии 1.1 (JSR-139), MIDP версии 2.1 (JSR-118)
и других спецификаций для функционирования компактных приложений на языке
Java (мидлетов) в среде программного обеспечения Малик Эмулятор.
Copyright © 2016, 2019 Малик Разработчик
Это свободная программа: вы можете перераспространять ее и/или изменять
ее на условиях Меньшей Стандартной общественной лицензии GNU в том виде,
в каком она была опубликована Фондом свободного программного обеспечения;
либо версии 3 лицензии, либо (по вашему выбору) любой более поздней версии.
Эта программа распространяется в надежде, что она будет полезной,
но БЕЗО ВСЯКИХ ГАРАНТИЙ; даже без неявной гарантии ТОВАРНОГО ВИДА
или ПРИГОДНОСТИ ДЛЯ ОПРЕДЕЛЕННЫХ ЦЕЛЕЙ. Подробнее см. в Меньшей Стандартной
общественной лицензии GNU.
Вы должны были получить копию Меньшей Стандартной общественной лицензии GNU
вместе с этой программой. Если это не так, см.
<https://www.gnu.org/licenses/>.
*/
package javax.microedition.lcdui;
public class TextOutputMultilined extends TextOutput
{
public static final char LINE_SEPARATOR = '\n';
public static final char WHITE_SPACE = '\u0020';
protected int linesCount;
protected int[] linesBounds;
public TextOutputMultilined()
{
}
public TextOutputMultilined(int capacity)
{
super(capacity);
}
public void split(Font font, int width)
{
boolean ending;
char ch;
int i;
int j;
int s;
int e;
int n;
int w;
int line = 0;
int len = length;
char[] c = chars;
int[] l = new int[17];
for(i = s = 0; i <= len; i = s = n)
{
w = 0;
do
{
if((ending = i >= len) || (ending = (ch = c[i]) == LINE_SEPARATOR) ||
(j = w + font.charWidth(ch)) > width)
{
break;
}
w = j;
i++;
} while(true);
if(ending)
{
n = (e = i) + 1;
}
else if(i == s)
{
n = e = s + 1;
}
else
{
n = e = i;
for(j = i - 1; j > s; j--)
{
if((ch = c[j]) == WHITE_SPACE)
{
n = (e = j) + 1;
break;
}
if(isWordSeparator(ch))
{
n = e = j + 1;
break;
}
}
}
if(l.length == line + 1)
{
Array.copy(l, 0, l = new int[(line << 1) - 1], 0, line);
}
l[line++] = s;
l[line++] = e - s;
}
l[line] = len;
linesCount = line >> 1;
linesBounds = l;
}
public boolean isWordSeparator(char c)
{
return (c >= 0 && c <= 32) || c == '!' || c == '%' || c == '&' ||
(c >= ')' && c <= '/') || (c >= ':' && c <= '@') || (c >= '\\' && c <= '`') ||
(c >= '|' && c <= '~');
}
public final int getLinesCount()
{
return linesCount;
}
public final int getLineStart(int lineIndex)
{
int linesCount;
return (linesCount = this.linesCount) > 0 &&
lineIndex >= 0 && lineIndex <= linesCount ? linesBounds[lineIndex << 1] : -1;
}
public final int getLineLength(int lineIndex)
{
return lineIndex >= 0 && lineIndex < linesCount ? linesBounds[(lineIndex << 1) + 1] : 0;
}
public final int getLineAt(int position)
{
int a;
int b;
int c;
int a1;
int a2;
int a3;
int count;
int[] bounds = linesBounds;
a = 0;
b = (count = linesCount) >> 1;
c = count;
do
{
a1 = bounds[a << 1];
a2 = bounds[b << 1];
a3 = bounds[c << 1];
if(b - a <= 1 && c - b <= 1)
{
break;
}
if(position >= a1 && position < a2)
{
c = b;
b = (a + c) >> 1;
continue;
}
if(position >= a2 && position <= a3)
{
a = b;
b = (a + c) >> 1;
continue;
}
return -1;
} while(true);
if(position >= a2)
{
if(b >= 0 && b <= count)
{
return b;
}
}
if(position >= a1)
{
if(a >= 0 && a <= count)
{
return a;
}
}
return -1;
}
}