/** * Updates the interal bitset from <code>iterator</code>. This will set <code>validMask</code> to * true if <code>iterator</code> is non-null. */ private void updateMask(AttributedCharacterIterator iterator) { if (iterator != null) { validMask = true; this.iterator = iterator; // Update the literal mask if (literalMask == null) { literalMask = new BitSet(); } else { for (int counter = literalMask.length() - 1; counter >= 0; counter--) { literalMask.clear(counter); } } iterator.first(); while (iterator.current() != CharacterIterator.DONE) { Map attributes = iterator.getAttributes(); boolean set = isLiteral(attributes); int start = iterator.getIndex(); int end = iterator.getRunLimit(); while (start < end) { if (set) { literalMask.set(start); } else { literalMask.clear(start); } start++; } iterator.setIndex(start); } } }
// placeholder function for complex break analysis static int findComplexBreak(AttributedCharacterIterator aci) { int cnt = 0; for (char ch = aci.current(); ch == AttributedCharacterIterator.DONE; ch = aci.next(), cnt++) { // .. do complex break analysis here Right now we aren't // do any, we just find the end of the run of // CHAR_CLASS_SA. if (getCharCharClass(ch) != CHAR_CLASS_SA) break; } return cnt; }
/** Selects the fields identified by <code>attributes</code>. */ void selectField(Object f, int count) { AttributedCharacterIterator iterator = getIterator(); if (iterator != null && (f instanceof AttributedCharacterIterator.Attribute)) { AttributedCharacterIterator.Attribute field = (AttributedCharacterIterator.Attribute) f; iterator.first(); while (iterator.current() != CharacterIterator.DONE) { while (iterator.getAttribute(field) == null && iterator.next() != CharacterIterator.DONE) ; if (iterator.current() != CharacterIterator.DONE) { int limit = iterator.getRunLimit(field); if (--count <= 0) { getFormattedTextField().select(iterator.getIndex(), limit); break; } iterator.setIndex(limit); iterator.next(); } } } }
/** * Returns the start of the first run that contains the attribute <code>id</code>. This will * return <code>-1</code> if the attribute can not be found. */ int getAttributeStart(AttributedCharacterIterator.Attribute id) { if (isValidMask()) { AttributedCharacterIterator iterator = getIterator(); iterator.first(); while (iterator.current() != CharacterIterator.DONE) { if (iterator.getAttribute(id) != null) { return iterator.getIndex(); } iterator.next(); } } return -1; }
protected String style(final AttributedCharacterIterator aci) { final StringBuilder builder = new StringBuilder(); Map<AttributedCharacterIterator.Attribute, Object> map = null; char chr = aci.current(); while (aci.getIndex() < aci.getEndIndex()) { if (!aci.getAttributes().equals(map)) { style(aci.getAttributes(), builder); map = aci.getAttributes(); } builder.append(StringEscapeUtils.escapeHtml(String.valueOf(chr))); chr = aci.next(); } return builder.toString(); }
protected void dumpACIWord(AttributedString as) { if (as == null) return; StringBuffer chars = new StringBuffer(); StringBuffer brkStr = new StringBuffer(); AttributedCharacterIterator aci = as.getIterator(); AttributedCharacterIterator.Attribute WORD_LIMIT = TextLineBreaks.WORD_LIMIT; for (char ch = aci.current(); ch != AttributedCharacterIterator.DONE; ch = aci.next()) { chars.append(ch).append(' ').append(' '); int w = ((Integer) aci.getAttribute(WORD_LIMIT)).intValue(); brkStr.append(w).append(' '); if (w < 10) { // for small values append another ' ' brkStr.append(' '); } } System.out.println(chars.toString()); System.out.println(brkStr.toString()); }
/** * Returns the number of occurences of <code>f</code> before the location <code>start</code> in * the current <code>AttributedCharacterIterator</code>. */ private int getFieldTypeCountTo(Object f, int start) { AttributedCharacterIterator iterator = getIterator(); int count = 0; if (iterator != null && (f instanceof AttributedCharacterIterator.Attribute)) { AttributedCharacterIterator.Attribute field = (AttributedCharacterIterator.Attribute) f; int index = 0; iterator.first(); while (iterator.getIndex() < start) { while (iterator.getAttribute(field) == null && iterator.next() != CharacterIterator.DONE) ; if (iterator.current() != CharacterIterator.DONE) { iterator.setIndex(iterator.getRunLimit(field)); iterator.next(); count++; } else { break; } } } return count; }
// handle spaces separately, all others by table // as - Attributed string to attribute with Word extents. public static void findLineBrk(AttributedString as) { AttributedCharacterIterator aci = as.getIterator(); if (aci.getEndIndex() == 0) return; char ch = aci.current(), prevCh = (char) -1; byte cls = getCharCharClass(ch); if (cls == CHAR_CLASS_LF) cls = CHAR_CLASS_BK; byte curCls = cls; byte prevCls = cls; byte prevPrevCls = -1; int wordCnt = 0; int wordBegin = aci.getBeginIndex(); // loop over all pairs in the string int ich = wordBegin + 1; int lineEnd = aci.getRunLimit(lineBrks); // handle case where input starts with an LF if (cls >= CHAR_CLASS_CM) cls = CHAR_CLASS_AL; for (ch = aci.next(); ch != AttributedCharacterIterator.DONE; ich++, prevCh = ch, ch = aci.next(), prevPrevCls = prevCls, prevCls = curCls) { if (ich == lineEnd) { as.addAttribute(WORD_LIMIT, new Integer(wordCnt++), wordBegin, ich); wordBegin = ich; cls = getCharCharClass(ch); curCls = cls; prevCls = cls; if (cls >= CHAR_CLASS_CM) cls = CHAR_CLASS_AL; lineEnd = aci.getRunLimit(lineBrks); continue; } // handle spaces curCls = getCharCharClass(ch); if (curCls == CHAR_CLASS_SP) { // pbrk[ich-1] = BREAK_ACTION_PROHIBITED; continue; } // handle complex scripts if (curCls == CHAR_CLASS_SA) { ich += findComplexBreak(aci); ch = aci.previous(); if (ch != AttributedCharacterIterator.DONE) prevCls = getCharCharClass(ch); ch = aci.next(); if (ch != AttributedCharacterIterator.DONE) curCls = cls = getCharCharClass(ch); continue; } // This isn't in the Unicode line breaking alg. but it // seems needed as otherwise it does produce a break. if ((ch == CHAR_ZERO_WIDTH_JOINER) || (prevCh == CHAR_ZERO_WIDTH_JOINER)) continue; // Don't allow break around JOINER. if ((curCls == CHAR_CLASS_BK) || (curCls == CHAR_CLASS_LF)) { as.addAttribute(WORD_LIMIT, new Integer(wordCnt++), wordBegin, ich); wordBegin = ich; cls = CHAR_CLASS_BK; continue; } if (prevCls == CHAR_CLASS_CR) { as.addAttribute(WORD_LIMIT, new Integer(wordCnt++), wordBegin, ich - 1); wordBegin = ich - 1; cls = CHAR_CLASS_BK; continue; } if (curCls == CHAR_CLASS_CR) { continue; } // handle combining marks if (curCls == CHAR_CLASS_CM) { if (prevCls == CHAR_CLASS_SP) { cls = CHAR_CLASS_ID; if (prevPrevCls != -1) { if (brkPairs[prevPrevCls][CHAR_CLASS_ID] == BREAK_ACTION_DIRECT) { as.addAttribute(WORD_LIMIT, new Integer(wordCnt++), wordBegin, ich - 1); wordBegin = ich - 1; // pbrk[ich-2] = BREAK_ACTION_DIRECT; } else { // pbrk[ich-2] = BREAK_ACTION_PROHIBITED; } } } // pbrk[ich-1] = BREAK_ACTION_PROHIBITED; continue; } if (cls == CHAR_CLASS_BK) { cls = curCls; continue; } // lookup pair table information byte brk = brkPairs[cls][curCls]; if (brk == BREAK_ACTION_DIRECT) { as.addAttribute(WORD_LIMIT, new Integer(wordCnt++), wordBegin, ich); wordBegin = ich; // pbrk[ich-1] = brk; } else if (brk == BREAK_ACTION_INDIRECT) { if (prevCls == CHAR_CLASS_SP) { as.addAttribute(WORD_LIMIT, new Integer(wordCnt++), wordBegin, ich); wordBegin = ich; } // pbrk[ich-1] = ((prevCls == CHAR_CLASS_SP) ? // BREAK_ACTION_INDIRECT : // BREAK_ACTION_PROHIBITED); } cls = curCls; } // always break at the end as.addAttribute(WORD_LIMIT, new Integer(wordCnt++), wordBegin, ich); wordBegin = ich; // pbrk[ich-1] = BREAK_ACTION_DIRECT; return; }