Java Code Examples for java.text.AttributedCharacterIterator#first()
The following examples show how to use
java.text.AttributedCharacterIterator#first() .
You can vote up the ones you like or vote down the ones you don't like,
and go to the original project or source file by following the links above each example. You may check out the related API usage on the sidebar.
Example 1
Source File: PdfGraphics2D.java From pentaho-reporting with GNU Lesser General Public License v2.1 | 6 votes |
/** * @see Graphics2D#drawString(AttributedCharacterIterator, float, float) */ @Override public void drawString( final AttributedCharacterIterator iter, float x, final float y ) { /* * StringBuffer sb = new StringBuffer(); for(char c = iter.first(); c != AttributedCharacterIterator.DONE; c = * iter.next()) { sb.append(c); } drawString(sb.toString(),x,y); */ final StringBuilder stringbuffer = new StringBuilder( iter.getEndIndex() ); for ( char c = iter.first(); c != AttributedCharacterIterator.DONE; c = iter.next() ) { if ( iter.getIndex() == iter.getRunStart() ) { if ( stringbuffer.length() > 0 ) { drawString( stringbuffer.toString(), x, y ); final FontMetrics fontmetrics = getFontMetrics(); x = (float) ( x + fontmetrics.getStringBounds( stringbuffer.toString(), this ).getWidth() ); stringbuffer.delete( 0, stringbuffer.length() ); } doAttributes( iter ); } stringbuffer.append( c ); } drawString( stringbuffer.toString(), x, y ); underline = false; }
Example 2
Source File: FXGraphics2D.java From ccu-historian with GNU General Public License v3.0 | 6 votes |
/** * Draws a string of attributed characters at {@code (x, y)}. * * @param iterator an iterator over the characters ({@code null} not * permitted). * @param x the x-coordinate. * @param y the y-coordinate. */ @Override public void drawString(AttributedCharacterIterator iterator, float x, float y) { Set<AttributedCharacterIterator.Attribute> s = iterator.getAllAttributeKeys(); if (!s.isEmpty()) { TextLayout layout = new TextLayout(iterator, getFontRenderContext()); layout.draw(this, x, y); } else { StringBuilder strb = new StringBuilder(); iterator.first(); for (int i = iterator.getBeginIndex(); i < iterator.getEndIndex(); i++) { strb.append(iterator.current()); iterator.next(); } drawString(strb.toString(), x, y); } }
Example 3
Source File: EpsGraphics2D.java From osp with GNU General Public License v3.0 | 6 votes |
/** * Draws the characters of an AttributedCharacterIterator, starting from * (x,y). */ public void drawString(AttributedCharacterIterator iterator, float x, float y) { if(getAccurateTextMode()) { TextLayout layout = new TextLayout(iterator, getFontRenderContext()); Shape shape = layout.getOutline(AffineTransform.getTranslateInstance(x, y)); draw(shape, "fill"); //$NON-NLS-1$ } else { append("newpath"); //$NON-NLS-1$ Point2D location = transform(x, y); append(location.getX()+" "+location.getY()+" moveto"); //$NON-NLS-1$ //$NON-NLS-2$ StringBuffer buffer = new StringBuffer(); for(char ch = iterator.first(); ch!=CharacterIterator.DONE; ch = iterator.next()) { if((ch=='(')||(ch==')')) { buffer.append('\\'); } buffer.append(ch); } append("("+buffer.toString()+") show"); //$NON-NLS-1$ //$NON-NLS-2$ } }
Example 4
Source File: ScientificNumberFormatter.java From fitnotifications with Apache License 2.0 | 5 votes |
@Override String format( AttributedCharacterIterator iterator, String preExponent) { int copyFromOffset = 0; StringBuilder result = new StringBuilder(); for ( iterator.first(); iterator.current() != CharacterIterator.DONE; ) { Map<Attribute, Object> attributeSet = iterator.getAttributes(); if (attributeSet.containsKey(NumberFormat.Field.EXPONENT_SYMBOL)) { append( iterator, copyFromOffset, iterator.getRunStart(NumberFormat.Field.EXPONENT_SYMBOL), result); copyFromOffset = iterator.getRunLimit(NumberFormat.Field.EXPONENT_SYMBOL); iterator.setIndex(copyFromOffset); result.append(preExponent); result.append(beginMarkup); } else if (attributeSet.containsKey(NumberFormat.Field.EXPONENT)) { int limit = iterator.getRunLimit(NumberFormat.Field.EXPONENT); append( iterator, copyFromOffset, limit, result); copyFromOffset = limit; iterator.setIndex(copyFromOffset); result.append(endMarkup); } else { iterator.next(); } } append(iterator, copyFromOffset, iterator.getEndIndex(), result); return result.toString(); }
Example 5
Source File: AttributedStringTest.java From openjdk-jdk8u with GNU General Public License v2.0 | 5 votes |
private static final void checkIteratorSubranges(AttributedCharacterIterator iterator, Attribute key, int[] expectedLimits) throws Exception { int previous = 0; char c = iterator.first(); for (int i = 0; i < expectedLimits.length; i++) { if (iterator.getRunStart(key) != previous || iterator.getRunLimit(key) != expectedLimits[i]) { throwException(iterator, "run boundaries are not as expected: " + iterator.getRunStart(key) + ", " + iterator.getRunLimit(key) + " for key " + key); } previous = expectedLimits[i]; c = iterator.setIndex(previous); } if (c != CharacterIterator.DONE) { throwException(iterator, "iterator's run sequence doesn't end with DONE"); } }
Example 6
Source File: TextLayout.java From openjdk-8 with GNU General Public License v2.0 | 5 votes |
/** * Constructs a <code>TextLayout</code> from an iterator over styled text. * <p> * The iterator must specify a single paragraph of text because an * entire paragraph is required for the bidirectional * algorithm. * @param text the styled text to display * @param frc contains information about a graphics device which is needed * to measure the text correctly. * Text measurements can vary slightly depending on the * device resolution, and attributes such as antialiasing. This * parameter does not specify a translation between the * <code>TextLayout</code> and user space. */ public TextLayout(AttributedCharacterIterator text, FontRenderContext frc) { if (text == null) { throw new IllegalArgumentException("Null iterator passed to TextLayout constructor."); } int start = text.getBeginIndex(); int limit = text.getEndIndex(); if (start == limit) { throw new IllegalArgumentException("Zero length iterator passed to TextLayout constructor."); } int len = limit - start; text.first(); char[] chars = new char[len]; int n = 0; for (char c = text.first(); c != CharacterIterator.DONE; c = text.next()) { chars[n++] = c; } text.first(); if (text.getRunLimit() == limit) { Map<? extends Attribute, ?> attributes = text.getAttributes(); Font font = singleFont(chars, 0, len, attributes); if (font != null) { fastInit(chars, font, attributes, frc); return; } } standardInit(text, chars, frc); }
Example 7
Source File: AttributedStringTest.java From dragonwell8_jdk with GNU General Public License v2.0 | 5 votes |
private static final void checkIteratorSubranges(AttributedCharacterIterator iterator, int[] expectedLimits) throws Exception { int previous = 0; char c = iterator.first(); for (int i = 0; i < expectedLimits.length; i++) { if (iterator.getRunStart() != previous || iterator.getRunLimit() != expectedLimits[i]) { throwException(iterator, "run boundaries are not as expected: " + iterator.getRunStart() + ", " + iterator.getRunLimit()); } previous = expectedLimits[i]; c = iterator.setIndex(previous); } if (c != CharacterIterator.DONE) { throwException(iterator, "iterator's run sequence doesn't end with DONE"); } }
Example 8
Source File: AttributedStringUtilities.java From astor with GNU General Public License v2.0 | 5 votes |
/** * Tests two attributed strings for equality. * * @param s1 string 1 (<code>null</code> permitted). * @param s2 string 2 (<code>null</code> permitted). * * @return <code>true</code> if <code>s1</code> and <code>s2</code> are * equal or both <code>null</code>, and <code>false</code> * otherwise. */ public static boolean equal(AttributedString s1, AttributedString s2) { if (s1 == null) { return (s2 == null); } if (s2 == null) { return false; } AttributedCharacterIterator it1 = s1.getIterator(); AttributedCharacterIterator it2 = s2.getIterator(); char c1 = it1.first(); char c2 = it2.first(); int start = 0; while (c1 != CharacterIterator.DONE) { int limit1 = it1.getRunLimit(); int limit2 = it2.getRunLimit(); if (limit1 != limit2) { return false; } // if maps aren't equivalent, return false Map m1 = it1.getAttributes(); Map m2 = it2.getAttributes(); if (!m1.equals(m2)) { return false; } // now check characters in the run are the same for (int i = start; i < limit1; i++) { if (c1 != c2) { return false; } c1 = it1.next(); c2 = it2.next(); } start = limit1; } return c2 == CharacterIterator.DONE; }
Example 9
Source File: AttributedStringTest.java From TencentKona-8 with GNU General Public License v2.0 | 5 votes |
private static final void checkIteratorSubranges(AttributedCharacterIterator iterator, int[] expectedLimits) throws Exception { int previous = 0; char c = iterator.first(); for (int i = 0; i < expectedLimits.length; i++) { if (iterator.getRunStart() != previous || iterator.getRunLimit() != expectedLimits[i]) { throwException(iterator, "run boundaries are not as expected: " + iterator.getRunStart() + ", " + iterator.getRunLimit()); } previous = expectedLimits[i]; c = iterator.setIndex(previous); } if (c != CharacterIterator.DONE) { throwException(iterator, "iterator's run sequence doesn't end with DONE"); } }
Example 10
Source File: TextLayout.java From jdk8u60 with GNU General Public License v2.0 | 5 votes |
/** * Constructs a <code>TextLayout</code> from an iterator over styled text. * <p> * The iterator must specify a single paragraph of text because an * entire paragraph is required for the bidirectional * algorithm. * @param text the styled text to display * @param frc contains information about a graphics device which is needed * to measure the text correctly. * Text measurements can vary slightly depending on the * device resolution, and attributes such as antialiasing. This * parameter does not specify a translation between the * <code>TextLayout</code> and user space. */ public TextLayout(AttributedCharacterIterator text, FontRenderContext frc) { if (text == null) { throw new IllegalArgumentException("Null iterator passed to TextLayout constructor."); } int start = text.getBeginIndex(); int limit = text.getEndIndex(); if (start == limit) { throw new IllegalArgumentException("Zero length iterator passed to TextLayout constructor."); } int len = limit - start; text.first(); char[] chars = new char[len]; int n = 0; for (char c = text.first(); c != CharacterIterator.DONE; c = text.next()) { chars[n++] = c; } text.first(); if (text.getRunLimit() == limit) { Map<? extends Attribute, ?> attributes = text.getAttributes(); Font font = singleFont(chars, 0, len, attributes); if (font != null) { fastInit(chars, font, attributes, frc); return; } } standardInit(text, chars, frc); }
Example 11
Source File: SWTGraphics2D.java From buffer_bci with GNU General Public License v3.0 | 5 votes |
/** * Draws a string at the specified position. * * @param iterator the string. * @param x the x-coordinate. * @param y the y-coordinate. */ public void drawString(AttributedCharacterIterator iterator, int x, int y) { // for now we simply want to extract the chars from the iterator // and call an unstyled text renderer StringBuffer sb = new StringBuffer(); int numChars = iterator.getEndIndex() - iterator.getBeginIndex(); char c = iterator.first(); for (int i = 0; i < numChars; i++) { sb.append(c); c = iterator.next(); } drawString(new String(sb),x,y); }
Example 12
Source File: AttributedStringTest.java From openjdk-jdk9 with GNU General Public License v2.0 | 5 votes |
private static final void dumpIterator(AttributedCharacterIterator iterator) { Set attributeKeys = iterator.getAllAttributeKeys(); System.out.print("All attributes: "); Iterator keyIterator = attributeKeys.iterator(); while (keyIterator.hasNext()) { Attribute key = (Attribute) keyIterator.next(); System.out.print(key); } for(char c = iterator.first(); c != CharacterIterator.DONE; c = iterator.next()) { if (iterator.getIndex() == iterator.getBeginIndex() || iterator.getIndex() == iterator.getRunStart()) { System.out.println(); Map attributes = iterator.getAttributes(); Set entries = attributes.entrySet(); Iterator attributeIterator = entries.iterator(); while (attributeIterator.hasNext()) { Map.Entry entry = (Map.Entry) attributeIterator.next(); System.out.print("<" + entry.getKey() + ": " + entry.getValue() + ">"); } } System.out.print(" "); System.out.print(c); } System.out.println(); System.out.println("done"); System.out.println(); }
Example 13
Source File: TextLine.java From JDKSourceCode1.8 with MIT License | 5 votes |
/** * When this returns, the ACI's current position will be at the start of the * first run which does NOT contain a GraphicAttribute. If no such run exists * the ACI's position will be at the end, and this method will return false. */ static boolean advanceToFirstFont(AttributedCharacterIterator aci) { for (char ch = aci.first(); ch != CharacterIterator.DONE; ch = aci.setIndex(aci.getRunLimit())) { if (aci.getAttribute(TextAttribute.CHAR_REPLACEMENT) == null) { return true; } } return false; }
Example 14
Source File: BidiBase.java From dragonwell8_jdk with GNU General Public License v2.0 | 4 votes |
/** * Perform the Unicode Bidi algorithm on a given paragraph, as defined in the * <a href="http://www.unicode.org/unicode/reports/tr9/">Unicode Standard Annex #9</a>, * version 13, * also described in The Unicode Standard, Version 4.0 .<p> * * This method takes a paragraph of text and computes the * left-right-directionality of each character. The text should not * contain any Unicode block separators.<p> * * The RUN_DIRECTION attribute in the text, if present, determines the base * direction (left-to-right or right-to-left). If not present, the base * direction is computed using the Unicode Bidirectional Algorithm, * defaulting to left-to-right if there are no strong directional characters * in the text. This attribute, if present, must be applied to all the text * in the paragraph.<p> * * The BIDI_EMBEDDING attribute in the text, if present, represents * embedding level information. Negative values from -1 to -62 indicate * overrides at the absolute value of the level. Positive values from 1 to * 62 indicate embeddings. Where values are zero or not defined, the base * embedding level as determined by the base direction is assumed.<p> * * The NUMERIC_SHAPING attribute in the text, if present, converts European * digits to other decimal digits before running the bidi algorithm. This * attribute, if present, must be applied to all the text in the paragraph. * * If the entire text is all of the same directionality, then * the method may not perform all the steps described by the algorithm, * i.e., some levels may not be the same as if all steps were performed. * This is not relevant for unidirectional text.<br> * For example, in pure LTR text with numbers the numbers would get * a resolved level of 2 higher than the surrounding text according to * the algorithm. This implementation may set all resolved levels to * the same value in such a case.<p> * * @param paragraph a paragraph of text with optional character and * paragraph attribute information * @stable ICU 3.8 */ public void setPara(AttributedCharacterIterator paragraph) { byte paraLvl; char ch = paragraph.first(); Boolean runDirection = (Boolean) paragraph.getAttribute(TextAttributeConstants.RUN_DIRECTION); Object shaper = paragraph.getAttribute(TextAttributeConstants.NUMERIC_SHAPING); if (runDirection == null) { paraLvl = INTERNAL_LEVEL_DEFAULT_LTR; } else { paraLvl = (runDirection.equals(TextAttributeConstants.RUN_DIRECTION_LTR)) ? (byte)Bidi.DIRECTION_LEFT_TO_RIGHT : (byte)Bidi.DIRECTION_RIGHT_TO_LEFT; } byte[] lvls = null; int len = paragraph.getEndIndex() - paragraph.getBeginIndex(); byte[] embeddingLevels = new byte[len]; char[] txt = new char[len]; int i = 0; while (ch != AttributedCharacterIterator.DONE) { txt[i] = ch; Integer embedding = (Integer) paragraph.getAttribute(TextAttributeConstants.BIDI_EMBEDDING); if (embedding != null) { byte level = embedding.byteValue(); if (level == 0) { /* no-op */ } else if (level < 0) { lvls = embeddingLevels; embeddingLevels[i] = (byte)((0 - level) | INTERNAL_LEVEL_OVERRIDE); } else { lvls = embeddingLevels; embeddingLevels[i] = level; } } ch = paragraph.next(); ++i; } if (shaper != null) { NumericShapings.shape(shaper, txt, 0, len); } setPara(txt, paraLvl, lvls); }
Example 15
Source File: StyledParagraph.java From jdk8u-jdk with GNU General Public License v2.0 | 4 votes |
/** * Create a new StyledParagraph over the given styled text. * @param aci an iterator over the text * @param chars the characters extracted from aci */ public StyledParagraph(AttributedCharacterIterator aci, char[] chars) { int start = aci.getBeginIndex(); int end = aci.getEndIndex(); length = end - start; int index = start; aci.first(); do { final int nextRunStart = aci.getRunLimit(); final int localIndex = index-start; Map<? extends Attribute, ?> attributes = aci.getAttributes(); attributes = addInputMethodAttrs(attributes); Decoration d = Decoration.getDecoration(attributes); addDecoration(d, localIndex); Object f = getGraphicOrFont(attributes); if (f == null) { addFonts(chars, attributes, localIndex, nextRunStart-start); } else { addFont(f, localIndex); } aci.setIndex(nextRunStart); index = nextRunStart; } while (index < end); // Add extra entries to starts arrays with the length // of the paragraph. 'this' is used as a dummy value // in the Vector. if (decorations != null) { decorationStarts = addToVector(this, length, decorations, decorationStarts); } if (fonts != null) { fontStarts = addToVector(this, length, fonts, fontStarts); } }
Example 16
Source File: SerialUtilities.java From astor with GNU General Public License v2.0 | 4 votes |
/** * Serialises an <code>AttributedString</code> object. * * @param as the attributed string object (<code>null</code> permitted). * @param stream the output stream (<code>null</code> not permitted). * * @throws IOException if there is an I/O error. */ public static void writeAttributedString(AttributedString as, ObjectOutputStream stream) throws IOException { if (stream == null) { throw new IllegalArgumentException("Null 'stream' argument."); } if (as != null) { stream.writeBoolean(false); AttributedCharacterIterator aci = as.getIterator(); // build a plain string from aci // then write the string StringBuffer plainStr = new StringBuffer(); char current = aci.first(); while (current != CharacterIterator.DONE) { plainStr = plainStr.append(current); current = aci.next(); } stream.writeObject(plainStr.toString()); // then write the attributes and limits for each run current = aci.first(); int begin = aci.getBeginIndex(); while (current != CharacterIterator.DONE) { // write the current character - when the reader sees that this // is not CharacterIterator.DONE, it will know to read the // run limits and attributes stream.writeChar(current); // now write the limit, adjusted as if beginIndex is zero int limit = aci.getRunLimit(); stream.writeInt(limit - begin); // now write the attribute set Map atts = new HashMap(aci.getAttributes()); stream.writeObject(atts); current = aci.setIndex(limit); } // write a character that signals to the reader that all runs // are done... stream.writeChar(CharacterIterator.DONE); } else { // write a flag that indicates a null stream.writeBoolean(true); } }
Example 17
Source File: StyledParagraph.java From openjdk-jdk8u-backup with GNU General Public License v2.0 | 4 votes |
/** * Create a new StyledParagraph over the given styled text. * @param aci an iterator over the text * @param chars the characters extracted from aci */ public StyledParagraph(AttributedCharacterIterator aci, char[] chars) { int start = aci.getBeginIndex(); int end = aci.getEndIndex(); length = end - start; int index = start; aci.first(); do { final int nextRunStart = aci.getRunLimit(); final int localIndex = index-start; Map<? extends Attribute, ?> attributes = aci.getAttributes(); attributes = addInputMethodAttrs(attributes); Decoration d = Decoration.getDecoration(attributes); addDecoration(d, localIndex); Object f = getGraphicOrFont(attributes); if (f == null) { addFonts(chars, attributes, localIndex, nextRunStart-start); } else { addFont(f, localIndex); } aci.setIndex(nextRunStart); index = nextRunStart; } while (index < end); // Add extra entries to starts arrays with the length // of the paragraph. 'this' is used as a dummy value // in the Vector. if (decorations != null) { decorationStarts = addToVector(this, length, decorations, decorationStarts); } if (fonts != null) { fontStarts = addToVector(this, length, fonts, fontStarts); } }
Example 18
Source File: StyledParagraph.java From jdk8u60 with GNU General Public License v2.0 | 4 votes |
/** * Create a new StyledParagraph over the given styled text. * @param aci an iterator over the text * @param chars the characters extracted from aci */ public StyledParagraph(AttributedCharacterIterator aci, char[] chars) { int start = aci.getBeginIndex(); int end = aci.getEndIndex(); length = end - start; int index = start; aci.first(); do { final int nextRunStart = aci.getRunLimit(); final int localIndex = index-start; Map<? extends Attribute, ?> attributes = aci.getAttributes(); attributes = addInputMethodAttrs(attributes); Decoration d = Decoration.getDecoration(attributes); addDecoration(d, localIndex); Object f = getGraphicOrFont(attributes); if (f == null) { addFonts(chars, attributes, localIndex, nextRunStart-start); } else { addFont(f, localIndex); } aci.setIndex(nextRunStart); index = nextRunStart; } while (index < end); // Add extra entries to starts arrays with the length // of the paragraph. 'this' is used as a dummy value // in the Vector. if (decorations != null) { decorationStarts = addToVector(this, length, decorations, decorationStarts); } if (fonts != null) { fontStarts = addToVector(this, length, fonts, fontStarts); } }
Example 19
Source File: StyledParagraph.java From openjdk-8 with GNU General Public License v2.0 | 4 votes |
/** * Create a new StyledParagraph over the given styled text. * @param aci an iterator over the text * @param chars the characters extracted from aci */ public StyledParagraph(AttributedCharacterIterator aci, char[] chars) { int start = aci.getBeginIndex(); int end = aci.getEndIndex(); length = end - start; int index = start; aci.first(); do { final int nextRunStart = aci.getRunLimit(); final int localIndex = index-start; Map<? extends Attribute, ?> attributes = aci.getAttributes(); attributes = addInputMethodAttrs(attributes); Decoration d = Decoration.getDecoration(attributes); addDecoration(d, localIndex); Object f = getGraphicOrFont(attributes); if (f == null) { addFonts(chars, attributes, localIndex, nextRunStart-start); } else { addFont(f, localIndex); } aci.setIndex(nextRunStart); index = nextRunStart; } while (index < end); // Add extra entries to starts arrays with the length // of the paragraph. 'this' is used as a dummy value // in the Vector. if (decorations != null) { decorationStarts = addToVector(this, length, decorations, decorationStarts); } if (fonts != null) { fontStarts = addToVector(this, length, fonts, fontStarts); } }
Example 20
Source File: BidiBase.java From jdk8u-jdk with GNU General Public License v2.0 | 4 votes |
/** * Perform the Unicode Bidi algorithm on a given paragraph, as defined in the * <a href="http://www.unicode.org/unicode/reports/tr9/">Unicode Standard Annex #9</a>, * version 13, * also described in The Unicode Standard, Version 4.0 .<p> * * This method takes a paragraph of text and computes the * left-right-directionality of each character. The text should not * contain any Unicode block separators.<p> * * The RUN_DIRECTION attribute in the text, if present, determines the base * direction (left-to-right or right-to-left). If not present, the base * direction is computed using the Unicode Bidirectional Algorithm, * defaulting to left-to-right if there are no strong directional characters * in the text. This attribute, if present, must be applied to all the text * in the paragraph.<p> * * The BIDI_EMBEDDING attribute in the text, if present, represents * embedding level information. Negative values from -1 to -62 indicate * overrides at the absolute value of the level. Positive values from 1 to * 62 indicate embeddings. Where values are zero or not defined, the base * embedding level as determined by the base direction is assumed.<p> * * The NUMERIC_SHAPING attribute in the text, if present, converts European * digits to other decimal digits before running the bidi algorithm. This * attribute, if present, must be applied to all the text in the paragraph. * * If the entire text is all of the same directionality, then * the method may not perform all the steps described by the algorithm, * i.e., some levels may not be the same as if all steps were performed. * This is not relevant for unidirectional text.<br> * For example, in pure LTR text with numbers the numbers would get * a resolved level of 2 higher than the surrounding text according to * the algorithm. This implementation may set all resolved levels to * the same value in such a case.<p> * * @param paragraph a paragraph of text with optional character and * paragraph attribute information * @stable ICU 3.8 */ public void setPara(AttributedCharacterIterator paragraph) { byte paraLvl; char ch = paragraph.first(); Boolean runDirection = (Boolean) paragraph.getAttribute(TextAttributeConstants.RUN_DIRECTION); Object shaper = paragraph.getAttribute(TextAttributeConstants.NUMERIC_SHAPING); if (runDirection == null) { paraLvl = INTERNAL_LEVEL_DEFAULT_LTR; } else { paraLvl = (runDirection.equals(TextAttributeConstants.RUN_DIRECTION_LTR)) ? (byte)Bidi.DIRECTION_LEFT_TO_RIGHT : (byte)Bidi.DIRECTION_RIGHT_TO_LEFT; } byte[] lvls = null; int len = paragraph.getEndIndex() - paragraph.getBeginIndex(); byte[] embeddingLevels = new byte[len]; char[] txt = new char[len]; int i = 0; while (ch != AttributedCharacterIterator.DONE) { txt[i] = ch; Integer embedding = (Integer) paragraph.getAttribute(TextAttributeConstants.BIDI_EMBEDDING); if (embedding != null) { byte level = embedding.byteValue(); if (level == 0) { /* no-op */ } else if (level < 0) { lvls = embeddingLevels; embeddingLevels[i] = (byte)((0 - level) | INTERNAL_LEVEL_OVERRIDE); } else { lvls = embeddingLevels; embeddingLevels[i] = level; } } ch = paragraph.next(); ++i; } if (shaper != null) { NumericShapings.shape(shaper, txt, 0, len); } setPara(txt, paraLvl, lvls); }