| /* |
| * 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; |
| |
| import org.apache.harmony.awt.gl.font.TextMetricsCalculator; |
| import org.apache.harmony.awt.gl.font.TextRunBreaker; |
| |
| /** |
| * The TextMeasurer class provides utilities for line break operations. |
| */ |
| public final class TextMeasurer implements Cloneable { |
| |
| /** The aci. */ |
| AttributedCharacterIterator aci; |
| |
| /** The frc. */ |
| FontRenderContext frc; |
| |
| /** The breaker. */ |
| TextRunBreaker breaker = null; |
| |
| /** The tmc. */ |
| TextMetricsCalculator tmc = null; |
| |
| /** |
| * Instantiates a new text measurer from the specified text. |
| * |
| * @param text the source text. |
| * @param frc the FontRenderContext. |
| */ |
| public TextMeasurer(AttributedCharacterIterator text, FontRenderContext frc) { |
| this.aci = text; |
| this.frc = frc; |
| breaker = new TextRunBreaker(aci, this.frc); |
| tmc = new TextMetricsCalculator(breaker); |
| } |
| |
| /** |
| * Replaces the current text with the new text, inserting a break |
| * character at the specified insert position. |
| * |
| * @param newParagraph the new paragraph text. |
| * @param insertPos the position in the text where the character is inserted. |
| */ |
| public void insertChar(AttributedCharacterIterator newParagraph, int insertPos) { |
| AttributedCharacterIterator oldAci = aci; |
| aci = newParagraph; |
| if ((oldAci.getEndIndex() - oldAci.getBeginIndex()) - |
| (aci.getEndIndex() - aci.getBeginIndex()) != -1) { |
| breaker = new TextRunBreaker(aci, this.frc); |
| tmc = new TextMetricsCalculator(breaker); |
| } else { |
| breaker.insertChar(newParagraph, insertPos); |
| } |
| } |
| |
| /** |
| * Replaces the current text with the new text and deletes a |
| * character at the specified position. |
| * |
| * @param newParagraph the paragraph text after deletion. |
| * @param deletePos the position in the text where the character is removed. |
| */ |
| public void deleteChar(AttributedCharacterIterator newParagraph, int deletePos) { |
| AttributedCharacterIterator oldAci = aci; |
| aci = newParagraph; |
| if ((oldAci.getEndIndex() - oldAci.getBeginIndex()) - |
| (aci.getEndIndex() - aci.getBeginIndex()) != 1) { |
| breaker = new TextRunBreaker(aci, this.frc); |
| tmc = new TextMetricsCalculator(breaker); |
| } else { |
| breaker.deleteChar(newParagraph, deletePos); |
| } |
| } |
| |
| /** |
| * Returns a copy of this object. |
| * |
| * @return a copy of this object. |
| */ |
| @Override |
| protected Object clone() { |
| return new TextMeasurer((AttributedCharacterIterator) aci.clone(), frc); |
| } |
| |
| /** |
| * Returns a TextLayout of the specified character range. |
| * |
| * @param start the index of the first character. |
| * @param limit the index after the last character. |
| * |
| * @return a TextLayout for the characters beginning at "start" up |
| * to "end". |
| */ |
| public TextLayout getLayout(int start, int limit) { |
| breaker.pushSegments(start - aci.getBeginIndex(), limit - aci.getBeginIndex()); |
| |
| breaker.createAllSegments(); |
| TextLayout layout = new TextLayout((TextRunBreaker) breaker.clone()); |
| |
| breaker.popSegments(); |
| return layout; |
| } |
| |
| /** |
| * Returns the graphical width of a line beginning at "start" |
| * parameter and including characters up to "end" parameter. |
| * "start" and "end" are absolute indices, not relative to the |
| * "start" of the paragraph. |
| * |
| * @param start the character index at which to start measuring. |
| * @param end the character index at which to stop measuring. |
| * |
| * @return the graphical width of a line beginning at "start" |
| * and including characters up to "end". |
| */ |
| public float getAdvanceBetween(int start, int end) { |
| breaker.pushSegments(start - aci.getBeginIndex(), end - aci.getBeginIndex()); |
| |
| breaker.createAllSegments(); |
| float retval = tmc.createMetrics().getAdvance(); |
| |
| breaker.popSegments(); |
| return retval; |
| } |
| |
| /** |
| * Returns the index of the first character which is not fit on |
| * a line beginning at start and possible measuring up to maxAdvance |
| * in graphical width. |
| * |
| * @param start he character index at which to start measuring. |
| * @param maxAdvance the graphical width in which the line must fit. |
| * |
| * @return the index after the last character that is fit on a line |
| * beginning at start, which is not longer than maxAdvance in graphical |
| * width. |
| */ |
| public int getLineBreakIndex(int start, float maxAdvance) { |
| breaker.createAllSegments(); |
| return breaker.getLineBreakIndex( |
| start - aci.getBeginIndex(), maxAdvance) + aci.getBeginIndex(); |
| } |
| } |
| |