// Default word BreakIterator. /* Copyright (C) 1999 Cygnus Solutions This file is part of libgcj. This software is copyrighted work licensed under the terms of the Libgcj License. Please consult the file "LIBGCJ_LICENSE" for details. */ package gnu.gcj.text; import java.text.BreakIterator; import java.text.CharacterIterator; /** * @author Tom Tromey * @date March 22, 1999 * Written using The Unicode Standard, Version 2.0. */ public class LineBreakIterator extends BaseBreakIterator { public Object clone () { return new LineBreakIterator (this); } public LineBreakIterator () { iter = null; } private LineBreakIterator (LineBreakIterator other) { iter = (CharacterIterator) other.iter.clone(); } // Some methods to tell us different properties of characters. private final boolean isNb (char c) { return (c == 0x00a0 // NO-BREAK SPACE || c == 0x2011 // NON-BREAKING HYPHEN || c == 0xfeff); // ZERO WITH NO-BREAK SPACE } private final boolean isClose (int type) { return (type == Character.END_PUNCTUATION // Unicode book says "comma, period, ...", which I take to // mean "Po" class. || type == Character.OTHER_PUNCTUATION); } private final boolean isIdeo (char c) { return (c >= 0x3040 && c <= 0x309f // Hiragana || c >= 0x30a0 && c <= 0x30ff // Katakana || c >= 0x4e00 && c <= 0x9fff // Han || c >= 0x3100 && c <= 0x312f); // Bopomofo } public int next () { int end = iter.getEndIndex(); if (iter.getIndex() == end) return DONE; while (iter.getIndex() < end) { char c = iter.current(); int type = Character.getType(c); char n = iter.next(); if (n == CharacterIterator.DONE || type == Character.PARAGRAPH_SEPARATOR || type == Character.LINE_SEPARATOR) break; // Handle two cases where we must scan for non-spacing marks. int start = iter.getIndex(); if (type == Character.SPACE_SEPARATOR || type == Character.START_PUNCTUATION || isIdeo (c)) { while (n != CharacterIterator.DONE && Character.getType(n) == Character.NON_SPACING_MARK) n = iter.next(); if (n == CharacterIterator.DONE) break; if (type == Character.SPACE_SEPARATOR) { int nt = Character.getType(n); if (nt != Character.NON_SPACING_MARK && nt != Character.SPACE_SEPARATOR && ! isNb (n)) break; } else if (type == Character.START_PUNCTUATION) { if (isIdeo (n)) { // Open punctuation followed by non spacing marks // and then ideograph does not have a break in // it. So skip all this. start = iter.getIndex(); } } else { // Ideograph preceded this character. if (isClose (Character.getType(n))) break; } } iter.setIndex(start); } return iter.getIndex(); } public int previous () { int start = iter.getBeginIndex(); if (iter.getIndex() == start) return DONE; while (iter.getIndex() >= start) { char c = iter.previous(); if (c == CharacterIterator.DONE) break; int type = Character.getType(c); char n = iter.previous(); if (n == CharacterIterator.DONE) break; iter.next(); int nt = Character.getType(n); // Break after paragraph separators. if (nt == Character.PARAGRAPH_SEPARATOR || nt == Character.LINE_SEPARATOR) break; // Skip non-spacing marks. int init = iter.getIndex(); while (n != CharacterIterator.DONE && nt == Character.NON_SPACING_MARK) { n = iter.previous(); nt = Character.getType(n); } if (nt == Character.SPACE_SEPARATOR && type != Character.SPACE_SEPARATOR && type != Character.NON_SPACING_MARK && ! isNb (c)) break; if (! isClose (type) && isIdeo (n)) break; if (isIdeo (c) && nt != Character.START_PUNCTUATION) break; iter.setIndex(init); } return iter.getIndex(); } }