239 lines
7.9 KiB
Java
239 lines
7.9 KiB
Java
/*
|
|
* Licensed to the Apache Software Foundation (ASF) under one or more
|
|
* contributor license agreements. See the NOTICE file distributed with
|
|
* this work for additional information regarding copyright ownership.
|
|
* The ASF licenses this file to You under the Apache License, Version 2.0
|
|
* (the "License"); you may not use this file except in compliance with
|
|
* the License. You may obtain a copy of the License at
|
|
*
|
|
* http://www.apache.org/licenses/LICENSE-2.0
|
|
*
|
|
* Unless required by applicable law or agreed to in writing, software
|
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
* See the License for the specific language governing permissions and
|
|
* limitations under the License.
|
|
*/
|
|
/*
|
|
* @author Oleg V. Khaschansky
|
|
* @version $Revision$
|
|
*/
|
|
|
|
package java.awt.font;
|
|
|
|
import java.text.AttributedCharacterIterator; //???AWT: import java.text.BreakIterator;
|
|
|
|
import org.apache.harmony.awt.internal.nls.Messages;
|
|
|
|
/**
|
|
* The class LineBreakMeasurer provides methods to measure the graphical
|
|
* representation of a text in order to determine where to add line breaks so
|
|
* the resulting line of text fits its wrapping width. The wrapping width
|
|
* defines the visual width of the paragraph.
|
|
*
|
|
* @since Android 1.0
|
|
*/
|
|
public final class LineBreakMeasurer {
|
|
|
|
/**
|
|
* The tm.
|
|
*/
|
|
private TextMeasurer tm = null;
|
|
|
|
// ???AWT private BreakIterator bi = null;
|
|
/**
|
|
* The position.
|
|
*/
|
|
private int position = 0;
|
|
|
|
/**
|
|
* The maxpos.
|
|
*/
|
|
int maxpos = 0;
|
|
|
|
/**
|
|
* Instantiates a new LineBreakMeasurer object for the specified text.
|
|
*
|
|
* @param text
|
|
* the AttributedCharacterIterator object which contains text
|
|
* with at least one character.
|
|
* @param frc
|
|
* the FontRenderContext represented information about graphic
|
|
* device.
|
|
*/
|
|
public LineBreakMeasurer(AttributedCharacterIterator text, FontRenderContext frc) {
|
|
// ???AWT: this(text, BreakIterator.getLineInstance(), frc);
|
|
}
|
|
|
|
/*
|
|
* ???AWT public LineBreakMeasurer( AttributedCharacterIterator text,
|
|
* BreakIterator bi, FontRenderContext frc ) { tm = new TextMeasurer(text,
|
|
* frc); this.bi = bi; this.bi.setText(text); position =
|
|
* text.getBeginIndex(); maxpos = tm.aci.getEndIndex(); }
|
|
*/
|
|
|
|
/**
|
|
* Deletes a character from the specified position of the text, updates this
|
|
* LineBreakMeasurer object.
|
|
*
|
|
* @param newText
|
|
* the new text.
|
|
* @param pos
|
|
* the position of the character which is deleted.
|
|
*/
|
|
public void deleteChar(AttributedCharacterIterator newText, int pos) {
|
|
tm.deleteChar(newText, pos);
|
|
// ???AWT: bi.setText(newText);
|
|
|
|
position = newText.getBeginIndex();
|
|
|
|
maxpos--;
|
|
}
|
|
|
|
/**
|
|
* Gets current position of this LineBreakMeasurer.
|
|
*
|
|
* @return the current position of this LineBreakMeasurer
|
|
*/
|
|
public int getPosition() {
|
|
return position;
|
|
}
|
|
|
|
/**
|
|
* Inserts a character at the specified position in the text, updates this
|
|
* LineBreakMeasurer object.
|
|
*
|
|
* @param newText
|
|
* the new text.
|
|
* @param pos
|
|
* the position of the character which is inserted.
|
|
*/
|
|
public void insertChar(AttributedCharacterIterator newText, int pos) {
|
|
tm.insertChar(newText, pos);
|
|
// ???AWT: bi.setText(newText);
|
|
|
|
position = newText.getBeginIndex();
|
|
|
|
maxpos++;
|
|
}
|
|
|
|
/**
|
|
* Returns the next line of text, updates current position in this
|
|
* LineBreakMeasurer.
|
|
*
|
|
* @param wrappingWidth
|
|
* the maximum visible line width.
|
|
* @param offsetLimit
|
|
* the limit point within the text indicating that no further
|
|
* text should be included on the line; the paragraph break.
|
|
* @param requireNextWord
|
|
* if true, null is returned (the entire word at the current
|
|
* position does not fit within the wrapping width); if false, a
|
|
* valid layout is returned that includes at least the character
|
|
* at the current position.
|
|
* @return the next TextLayout which begins at the current position and
|
|
* represents the next line of text with width wrappingWidth, null
|
|
* is returned if the entire word at the current position does not
|
|
* fit within the wrapping width.
|
|
*/
|
|
public TextLayout nextLayout(float wrappingWidth, int offsetLimit, boolean requireNextWord) {
|
|
if (position == maxpos) {
|
|
return null;
|
|
}
|
|
|
|
int nextPosition = nextOffset(wrappingWidth, offsetLimit, requireNextWord);
|
|
|
|
if (nextPosition == position) {
|
|
return null;
|
|
}
|
|
TextLayout layout = tm.getLayout(position, nextPosition);
|
|
position = nextPosition;
|
|
return layout;
|
|
}
|
|
|
|
/**
|
|
* Returns the next line of text.
|
|
*
|
|
* @param wrappingWidth
|
|
* the maximum visible line width.
|
|
* @return the next line of text.
|
|
*/
|
|
public TextLayout nextLayout(float wrappingWidth) {
|
|
return nextLayout(wrappingWidth, maxpos, false);
|
|
}
|
|
|
|
/**
|
|
* Returns the end position of the next line of text.
|
|
*
|
|
* @param wrappingWidth
|
|
* the maximum visible line width.
|
|
* @return the end position of the next line of text.
|
|
*/
|
|
public int nextOffset(float wrappingWidth) {
|
|
return nextOffset(wrappingWidth, maxpos, false);
|
|
}
|
|
|
|
/**
|
|
* Returns the end position of the next line of text.
|
|
*
|
|
* @param wrappingWidth
|
|
* the maximum visible line width.
|
|
* @param offsetLimit
|
|
* the limit point withing the text indicating that no further
|
|
* text should be included on the line; the paragraph break.
|
|
* @param requireNextWord
|
|
* if true, the current position is returned if the entire next
|
|
* word does not fit within wrappingWidth; if false, the offset
|
|
* returned is at least one greater than the current position.
|
|
* @return the end position of the next line of text.
|
|
* @throws IllegalArgumentException
|
|
* if the offsetLimit is less than the current position.
|
|
*/
|
|
public int nextOffset(float wrappingWidth, int offsetLimit, boolean requireNextWord) {
|
|
if (offsetLimit <= position) {
|
|
// awt.203=Offset limit should be greater than current position.
|
|
throw new IllegalArgumentException(Messages.getString("awt.203")); //$NON-NLS-1$
|
|
}
|
|
|
|
if (position == maxpos) {
|
|
return position;
|
|
}
|
|
|
|
int breakPos = tm.getLineBreakIndex(position, wrappingWidth);
|
|
int correctedPos = breakPos;
|
|
|
|
// This check is required because bi.preceding(maxpos) throws an
|
|
// exception
|
|
/*
|
|
* ???AWT if (breakPos == maxpos) { correctedPos = maxpos; } else if
|
|
* (Character.isWhitespace(bi.getText().setIndex(breakPos))) {
|
|
* correctedPos = bi.following(breakPos); } else { correctedPos =
|
|
* bi.preceding(breakPos); }
|
|
*/
|
|
|
|
if (position >= correctedPos) {
|
|
if (requireNextWord) {
|
|
correctedPos = position;
|
|
} else {
|
|
correctedPos = Math.max(position + 1, breakPos);
|
|
}
|
|
}
|
|
|
|
return Math.min(correctedPos, offsetLimit);
|
|
}
|
|
|
|
/**
|
|
* Sets the new position of this LineBreakMeasurer.
|
|
*
|
|
* @param pos
|
|
* the new position of this LineBreakMeasurer.
|
|
*/
|
|
public void setPosition(int pos) {
|
|
if (tm.aci.getBeginIndex() > pos || maxpos < pos) {
|
|
// awt.33=index is out of range
|
|
throw new IllegalArgumentException(Messages.getString("awt.33")); //$NON-NLS-1$
|
|
}
|
|
position = pos;
|
|
}
|
|
}
|