⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 textmeasurer.java

📁 JAVA基本类源代码,大家可以学习学习!
💻 JAVA
📖 第 1 页 / 共 2 页
字号:
/* * @(#)TextMeasurer.java	1.37 03/01/23 * * Copyright 2003 Sun Microsystems, Inc. All rights reserved. * SUN PROPRIETARY/CONFIDENTIAL. Use is subject to license terms. *//* * (C) Copyright Taligent, Inc. 1996 - 1997, All Rights Reserved * (C) Copyright IBM Corp. 1996 - 1998, All Rights Reserved * * The original version of this source code and documentation is * copyrighted and owned by Taligent, Inc., a wholly-owned subsidiary * of IBM. These materials are provided under terms of a License * Agreement between Taligent and Sun. This technology is protected * by multiple US and International patents. * * This notice and attribution to Taligent may not be removed. * Taligent is a registered trademark of Taligent, Inc. * */package java.awt.font;import java.awt.Font;import java.text.AttributedCharacterIterator;import java.text.AttributedString;import java.text.Bidi;import java.text.BreakIterator;import java.text.CharacterIterator;import java.awt.font.FontRenderContext;import java.util.Hashtable;import java.util.Map;import sun.awt.font.BidiUtils;import sun.awt.font.TextLineComponent;import sun.awt.font.TextLabelFactory;import sun.awt.font.FontResolver;/** * The <code>TextMeasurer</code> class provides the primitive operations  * needed for line break: measuring up to a given advance, determining the  * advance of a range of characters, and generating a * <code>TextLayout</code> for a range of characters. It also provides  * methods for incremental editing of paragraphs. * <p> * A <code>TextMeasurer</code> object is constructed with an  * {@link java.text.AttributedCharacterIterator AttributedCharacterIterator}  * representing a single paragraph of text.  The value returned by the * {@link AttributedCharacterIterator#getBeginIndex() getBeginIndex}  * method of <code>AttributedCharacterIterator</code> * defines the absolute index of the first character.  The value * returned by the  * {@link AttributedCharacterIterator#getEndIndex() getEndIndex} * method of <code>AttributedCharacterIterator</code> defines the index * past the last character.  These values define the range of indexes to  * use in calls to the <code>TextMeasurer</code>.  For example, calls to * get the advance of a range of text or the line break of a range of text * must use indexes between the beginning and end index values.  Calls to * {@link #insertChar(java.text.AttributedCharacterIterator, int) insertChar}  * and  * {@link #deleteChar(java.text.AttributedCharacterIterator, int) deleteChar}  * reset the <code>TextMeasurer</code> to use the beginning index and end * index of the <code>AttributedCharacterIterator</code> passed in those calls. * <p> * Most clients will use the more convenient <code>LineBreakMeasurer</code>,  * which implements the standard line break policy (placing as many words * as will fit on each line).  * * @author John Raley * @version 1.31, 04/20/01 * @see LineBreakMeasurer * @since 1.3 */public final class TextMeasurer implements Cloneable {    // Number of lines to format to.    private static float EST_LINES = (float) 2.1;    /*    static {        String s = System.getProperty("estLines");        if (s != null) {            try {                Float f = new Float(s);                EST_LINES = f.floatValue();            }            catch(NumberFormatException e) {            }        }        //System.out.println("EST_LINES="+EST_LINES);    }    */    private FontRenderContext fFrc;    private int fStart;    // characters in source text    private char[] fChars;    // Bidi for this paragraph    private Bidi fBidi;    // Levels array for chars in this paragraph - needed to reorder    // trailing counterdirectional whitespace    private byte[] fLevels;    // line components in logical order    private TextLineComponent[] fComponents;        // index where components begin    private int fComponentStart;        // index where components end    private int fComponentLimit;        private boolean haveLayoutWindow;        // used to find valid starting points for line components    private BreakIterator fLineBreak = null;    private CharArrayIterator charIter = null;    int layoutCount = 0;    int layoutCharCount = 0;        // paragraph, with resolved fonts and styles    private StyledParagraph fParagraph;    // paragraph data - same across all layouts    private boolean fIsDirectionLTR;    private byte fBaseline;    private float[] fBaselineOffsets;    private float fJustifyRatio = 1;    /**     * Constructs a <code>TextMeasurer</code> from the source text.       * The source text should be a single entire paragraph.     * @param text the source paragraph.  Cannot be null.     * @param frc the information about a graphics device which is needed      *       to measure the text correctly.  Cannot be null.     */    public TextMeasurer(AttributedCharacterIterator text, FontRenderContext frc) {        fFrc = frc;        initAll(text);    }        protected Object clone() {        TextMeasurer other;        try {            other = (TextMeasurer) super.clone();        }        catch(CloneNotSupportedException e) {            throw new Error();        }        if (fComponents != null) {            other.fComponents = (TextLineComponent[]) fComponents.clone();        }        return other;    }        private void invalidateComponents() {        fComponentStart = fComponentLimit = fChars.length;        fComponents = null;        haveLayoutWindow = false;    }            /**     * Initialize state, including fChars array, direction, and     * fBidi.     */    private void initAll(AttributedCharacterIterator text) {        fStart = text.getBeginIndex();        // extract chars        fChars = new char[text.getEndIndex() - fStart];        int n = 0;        for (char c = text.first(); c != text.DONE; c = text.next()) {            fChars[n++] = c;        }                text.first();                        fBidi = new Bidi(text);	if (fBidi.isLeftToRight()) {	    fBidi = null;	}        text.first();        Map paragraphAttrs = text.getAttributes();        if (paragraphAttrs != null) {            try {                NumericShaper shaper = (NumericShaper)paragraphAttrs.get(TextAttribute.NUMERIC_SHAPING);                if (shaper != null) {                    shaper.shape(fChars, 0, fChars.length);                }            }            catch (ClassCastException e) {            }        }        fParagraph = new StyledParagraph(text, fChars);                // set paragraph attributes        {            // If there's an embedded graphic at the start of the            // paragraph, look for the first non-graphic character            // and use it and its font to initialize the paragraph.            // If not, use the first graphic to initialize.            fJustifyRatio = TextLine.getJustifyRatio(paragraphAttrs);                        boolean haveFont = TextLine.advanceToFirstFont(text);            if (haveFont) {                Font defaultFont = TextLine.getFontAtCurrentPos(text);                int charsStart = text.getIndex() - text.getBeginIndex();                LineMetrics lm = defaultFont.getLineMetrics(fChars, charsStart, charsStart+1, fFrc);                fBaseline = (byte) lm.getBaselineIndex();                fBaselineOffsets = lm.getBaselineOffsets();            }            else {                // hmmm what to do here?  Just try to supply reasonable                // values I guess.                GraphicAttribute graphic = (GraphicAttribute)                                paragraphAttrs.get(TextAttribute.CHAR_REPLACEMENT);                fBaseline = TextLayout.getBaselineFromGraphic(graphic);                Font dummyFont = new Font(new Hashtable(5, (float)0.9));                LineMetrics lm = dummyFont.getLineMetrics(" ", 0, 1, fFrc);                fBaselineOffsets = lm.getBaselineOffsets();            }            fBaselineOffsets = TextLine.getNormalizedOffsets(fBaselineOffsets, fBaseline);        }                invalidateComponents();    }        /**     * Generate components for the paragraph.  fChars, fBidi should have been      * initialized already.     */    private void generateComponents(int startingAt, int endingAt) {                if (collectStats) {            formattedChars += (endingAt-startingAt);        }	int layoutFlags = 0; // no extra info yet, bidi determines run and line direction        TextLabelFactory factory = new TextLabelFactory(fFrc, fChars, fBidi, layoutFlags);        int[] charsLtoV = null;                if (fBidi != null) {            fLevels = BidiUtils.getLevels(fBidi);	    int[] charsVtoL = BidiUtils.createVisualToLogicalMap(fLevels);            charsLtoV = BidiUtils.createInverseMap(charsVtoL);            fIsDirectionLTR = fBidi.baseIsLeftToRight();        }        else {            fLevels = null;            fIsDirectionLTR = true;        }                try {            fComponents = TextLine.getComponents(                fParagraph, fChars, startingAt, endingAt, charsLtoV, fLevels, factory);        }        catch(IllegalArgumentException e) {            System.out.println("startingAt="+startingAt+"; endingAt="+endingAt);            System.out.println("fComponentLimit="+fComponentLimit);            throw e;        }                fComponentStart = startingAt;        fComponentLimit = endingAt;        //debugFormatCount += (endingAt-startingAt);    }        private int calcLineBreak(final int pos, final float maxAdvance) {        // either of these statements removes the bug:        //generateComponents(0, fChars.length);        //generateComponents(pos, fChars.length);                int startPos = pos;        float width = maxAdvance;                int tlcIndex;        int tlcStart = fComponentStart;        for (tlcIndex = 0; tlcIndex < fComponents.length; tlcIndex++) {            int gaLimit = tlcStart + fComponents[tlcIndex].getNumCharacters();            if (gaLimit > startPos) {                break;            }            else {                tlcStart = gaLimit;            }        }                // tlcStart is now the start of the tlc at tlcIndex        for (; tlcIndex < fComponents.length; tlcIndex++) {                        TextLineComponent tlc = fComponents[tlcIndex];            int numCharsInGa = tlc.getNumCharacters();            int lineBreak = tlc.getLineBreakIndex(startPos - tlcStart, width);            if (lineBreak == numCharsInGa && tlcIndex < fComponents.length) {                width -= tlc.getAdvanceBetween(startPos - tlcStart, lineBreak);                tlcStart += numCharsInGa;                startPos = tlcStart;            }            else {                return tlcStart + lineBreak;            }        }        if (fComponentLimit < fChars.length) {            // format more text and try again            //if (haveLayoutWindow) {            //    outOfWindow++;            //}                        generateComponents(pos, fChars.length);            return calcLineBreak(pos, maxAdvance);        }                return fChars.length;    }    /**     * According to the Unicode Bidirectional Behavior specification     * (Unicode Standard 2.0, section 3.11), whitespace at the ends     * of lines which would naturally flow against the base direction     * must be made to flow with the line direction, and moved to the     * end of the line.  This method returns the start of the sequence     * of trailing whitespace characters to move to the end of a     * line taken from the given range.     */    private int trailingCdWhitespaceStart(int startPos, int limitPos) {        if (fLevels != null) {            // Back up over counterdirectional whitespace            final byte baseLevel = (byte) (fIsDirectionLTR? 0 : 1);             for (int cdWsStart = limitPos; --cdWsStart >= startPos;) {                if ((fLevels[cdWsStart] % 2) == baseLevel ||                         Character.getDirectionality(fChars[cdWsStart]) != Character.DIRECTIONALITY_WHITESPACE) {                    return ++cdWsStart;                }            }        }        return startPos;    }    private TextLineComponent[] makeComponentsOnRange(int startPos,                                                       int limitPos) {        // sigh I really hate to do this here since it's part of the        // bidi algorithm.        // cdWsStart is the start of the trailing counterdirectional        // whitespace        final int cdWsStart = trailingCdWhitespaceStart(startPos, limitPos);        int tlcIndex;        int tlcStart = fComponentStart;        for (tlcIndex = 0; tlcIndex < fComponents.length; tlcIndex++) {

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -