1
0
Fork 0
mirror of https://github.com/geometer/FBReaderJ.git synced 2025-10-03 17:59:33 +02:00

fast hyphenation processing

This commit is contained in:
Nikolay Pultsin 2014-09-24 13:40:31 +01:00
parent 7105b6dc7d
commit e1d476e92c
2 changed files with 47 additions and 17 deletions

View file

@ -9,6 +9,7 @@
* Updated Czech localisation (by Marek Pavelka) * Updated Czech localisation (by Marek Pavelka)
* Updated German localisation (by Matthias Dill) * Updated German localisation (by Matthias Dill)
* Fixed TTF loader (for Roman fonts) * Fixed TTF loader (for Roman fonts)
* Fast hyphenation for very long words (200+ characters)
* (planned) Fixed authors list/tags list editing * (planned) Fixed authors list/tags list editing
===== 2.1.4 (Sep 21, 2014) ===== ===== 2.1.4 (Sep 21, 2014) =====

View file

@ -965,6 +965,7 @@ public abstract class ZLTextView extends ZLTextViewBase {
} }
private void buildInfos(ZLTextPage page, ZLTextWordCursor start, ZLTextWordCursor result) { private void buildInfos(ZLTextPage page, ZLTextWordCursor start, ZLTextWordCursor result) {
final long startTime = System.currentTimeMillis();
result.setCursor(start); result.setCursor(start);
int textAreaHeight = page.getTextHeight(); int textAreaHeight = page.getTextHeight();
page.LineInfos.clear(); page.LineInfos.clear();
@ -1022,6 +1023,16 @@ public abstract class ZLTextView extends ZLTextViewBase {
&& getTextStyle().allowHyphenations(); && getTextStyle().allowHyphenations();
} }
private volatile ZLTextWord myCachedWord;
private volatile ZLTextHyphenationInfo myCachedInfo;
private final synchronized ZLTextHyphenationInfo getHyphenationInfo(ZLTextWord word) {
if (myCachedWord != word) {
myCachedWord = word;
myCachedInfo = ZLTextHyphenator.Instance().getInfo(word);
}
return myCachedInfo;
}
private ZLTextLineInfo processTextLine( private ZLTextLineInfo processTextLine(
ZLTextPage page, ZLTextPage page,
ZLTextParagraphCursor paragraphCursor, ZLTextParagraphCursor paragraphCursor,
@ -1030,6 +1041,7 @@ public abstract class ZLTextView extends ZLTextViewBase {
final int endIndex, final int endIndex,
ZLTextLineInfo previousInfo ZLTextLineInfo previousInfo
) { ) {
final long startTime = System.currentTimeMillis();
final ZLPaintContext context = getContext(); final ZLPaintContext context = getContext();
final ZLTextLineInfo info = new ZLTextLineInfo(paragraphCursor, startIndex, startCharIndex, getTextStyle()); final ZLTextLineInfo info = new ZLTextLineInfo(paragraphCursor, startIndex, startCharIndex, getTextStyle());
final ZLTextLineInfo cachedInfo = myLineInfoCache.get(info); final ZLTextLineInfo cachedInfo = myLineInfoCache.get(info);
@ -1149,36 +1161,53 @@ public abstract class ZLTextView extends ZLTextViewBase {
int spaceLeft = maxWidth - newWidth; int spaceLeft = maxWidth - newWidth;
if ((word.Length > 3 && spaceLeft > 2 * context.getSpaceWidth()) if ((word.Length > 3 && spaceLeft > 2 * context.getSpaceWidth())
|| info.EndElementIndex == startIndex) { || info.EndElementIndex == startIndex) {
ZLTextHyphenationInfo hyphenationInfo = ZLTextHyphenator.Instance().getInfo(word); ZLTextHyphenationInfo hyphenationInfo = getHyphenationInfo(word);
int hyphenationPosition = word.Length - 1; int hyphenationPosition = currentCharIndex;
int subwordWidth = 0; int subwordWidth = 0;
for (; hyphenationPosition > currentCharIndex; hyphenationPosition--) { for (int right = word.Length - 1, left = currentCharIndex; right > left; ) {
if (hyphenationInfo.isHyphenationPossible(hyphenationPosition)) { final int mid = (right + left + 1) / 2;
subwordWidth = getWordWidth( int m1 = mid;
while (m1 > left && !hyphenationInfo.isHyphenationPossible(m1)) {
--m1;
}
if (m1 > left) {
final int w = getWordWidth(
word, word,
currentCharIndex, currentCharIndex,
hyphenationPosition - currentCharIndex, m1 - currentCharIndex,
word.Data[word.Offset + hyphenationPosition - 1] != '-' word.Data[word.Offset + m1 - 1] != '-'
); );
if (subwordWidth <= spaceLeft) { if (w < spaceLeft) {
break; left = mid;
hyphenationPosition = m1;
subwordWidth = w;
} else {
right = mid - 1;
} }
} else {
left = mid;
} }
} }
if (hyphenationPosition == currentCharIndex && info.EndElementIndex == startIndex) { if (hyphenationPosition == currentCharIndex && info.EndElementIndex == startIndex) {
hyphenationPosition = word.Length == currentCharIndex + 1 ? word.Length : word.Length - 1; subwordWidth = getWordWidth(word, currentCharIndex, 1, false);
subwordWidth = getWordWidth(word, currentCharIndex, word.Length - currentCharIndex, false); int right = word.Length == currentCharIndex + 1 ? word.Length : word.Length - 1;
for (; hyphenationPosition > currentCharIndex + 1; hyphenationPosition--) { int left = currentCharIndex + 1;
subwordWidth = getWordWidth( while (right > left) {
final int mid = (right + left + 1) / 2;
final int w = getWordWidth(
word, word,
currentCharIndex, currentCharIndex,
hyphenationPosition - currentCharIndex, mid - currentCharIndex,
word.Data[word.Offset + hyphenationPosition - 1] != '-' word.Data[word.Offset + mid - 1] != '-'
); );
if (subwordWidth <= spaceLeft) { if (w <= spaceLeft) {
break; left = mid;
subwordWidth = w;
} else {
right = mid - 1;
} }
} }
hyphenationPosition = right;
} }
if (hyphenationPosition > currentCharIndex) { if (hyphenationPosition > currentCharIndex) {
info.IsVisible = true; info.IsVisible = true;