jdk/src/share/classes/java/awt/font/TextMeasurer.java
author mchung
Tue, 08 Dec 2009 09:02:09 -0800
changeset 4374 f672d9cf521e
parent 2 90ce3da70b43
child 5506 202f599c92aa
permissions -rw-r--r--
6907568: java/awt/KeyboardFocusManager.java inproperly merged and lost a changeset Summary: Reapply fix for 6879044 in java.awt.KeyboardFocusManager Reviewed-by: dcherepanov, asaha
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
     1
/*
90ce3da70b43 Initial load
duke
parents:
diff changeset
     2
 * Copyright 1997-2005 Sun Microsystems, Inc.  All Rights Reserved.
90ce3da70b43 Initial load
duke
parents:
diff changeset
     3
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
90ce3da70b43 Initial load
duke
parents:
diff changeset
     4
 *
90ce3da70b43 Initial load
duke
parents:
diff changeset
     5
 * This code is free software; you can redistribute it and/or modify it
90ce3da70b43 Initial load
duke
parents:
diff changeset
     6
 * under the terms of the GNU General Public License version 2 only, as
90ce3da70b43 Initial load
duke
parents:
diff changeset
     7
 * published by the Free Software Foundation.  Sun designates this
90ce3da70b43 Initial load
duke
parents:
diff changeset
     8
 * particular file as subject to the "Classpath" exception as provided
90ce3da70b43 Initial load
duke
parents:
diff changeset
     9
 * by Sun in the LICENSE file that accompanied this code.
90ce3da70b43 Initial load
duke
parents:
diff changeset
    10
 *
90ce3da70b43 Initial load
duke
parents:
diff changeset
    11
 * This code is distributed in the hope that it will be useful, but WITHOUT
90ce3da70b43 Initial load
duke
parents:
diff changeset
    12
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
90ce3da70b43 Initial load
duke
parents:
diff changeset
    13
 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
90ce3da70b43 Initial load
duke
parents:
diff changeset
    14
 * version 2 for more details (a copy is included in the LICENSE file that
90ce3da70b43 Initial load
duke
parents:
diff changeset
    15
 * accompanied this code).
90ce3da70b43 Initial load
duke
parents:
diff changeset
    16
 *
90ce3da70b43 Initial load
duke
parents:
diff changeset
    17
 * You should have received a copy of the GNU General Public License version
90ce3da70b43 Initial load
duke
parents:
diff changeset
    18
 * 2 along with this work; if not, write to the Free Software Foundation,
90ce3da70b43 Initial load
duke
parents:
diff changeset
    19
 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
90ce3da70b43 Initial load
duke
parents:
diff changeset
    20
 *
90ce3da70b43 Initial load
duke
parents:
diff changeset
    21
 * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
90ce3da70b43 Initial load
duke
parents:
diff changeset
    22
 * CA 95054 USA or visit www.sun.com if you need additional information or
90ce3da70b43 Initial load
duke
parents:
diff changeset
    23
 * have any questions.
90ce3da70b43 Initial load
duke
parents:
diff changeset
    24
 */
90ce3da70b43 Initial load
duke
parents:
diff changeset
    25
90ce3da70b43 Initial load
duke
parents:
diff changeset
    26
/*
90ce3da70b43 Initial load
duke
parents:
diff changeset
    27
 * (C) Copyright Taligent, Inc. 1996 - 1997, All Rights Reserved
90ce3da70b43 Initial load
duke
parents:
diff changeset
    28
 * (C) Copyright IBM Corp. 1996 - 1998, All Rights Reserved
90ce3da70b43 Initial load
duke
parents:
diff changeset
    29
 *
90ce3da70b43 Initial load
duke
parents:
diff changeset
    30
 * The original version of this source code and documentation is
90ce3da70b43 Initial load
duke
parents:
diff changeset
    31
 * copyrighted and owned by Taligent, Inc., a wholly-owned subsidiary
90ce3da70b43 Initial load
duke
parents:
diff changeset
    32
 * of IBM. These materials are provided under terms of a License
90ce3da70b43 Initial load
duke
parents:
diff changeset
    33
 * Agreement between Taligent and Sun. This technology is protected
90ce3da70b43 Initial load
duke
parents:
diff changeset
    34
 * by multiple US and International patents.
90ce3da70b43 Initial load
duke
parents:
diff changeset
    35
 *
90ce3da70b43 Initial load
duke
parents:
diff changeset
    36
 * This notice and attribution to Taligent may not be removed.
90ce3da70b43 Initial load
duke
parents:
diff changeset
    37
 * Taligent is a registered trademark of Taligent, Inc.
90ce3da70b43 Initial load
duke
parents:
diff changeset
    38
 *
90ce3da70b43 Initial load
duke
parents:
diff changeset
    39
 */
90ce3da70b43 Initial load
duke
parents:
diff changeset
    40
90ce3da70b43 Initial load
duke
parents:
diff changeset
    41
package java.awt.font;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    42
90ce3da70b43 Initial load
duke
parents:
diff changeset
    43
import java.awt.Font;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    44
90ce3da70b43 Initial load
duke
parents:
diff changeset
    45
import java.text.AttributedCharacterIterator;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    46
import java.text.AttributedString;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    47
import java.text.Bidi;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    48
import java.text.BreakIterator;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    49
import java.text.CharacterIterator;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    50
90ce3da70b43 Initial load
duke
parents:
diff changeset
    51
import java.awt.font.FontRenderContext;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    52
90ce3da70b43 Initial load
duke
parents:
diff changeset
    53
import java.util.Hashtable;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    54
import java.util.Map;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    55
90ce3da70b43 Initial load
duke
parents:
diff changeset
    56
import sun.font.AttributeValues;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    57
import sun.font.BidiUtils;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    58
import sun.font.TextLineComponent;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    59
import sun.font.TextLabelFactory;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    60
import sun.font.FontResolver;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    61
90ce3da70b43 Initial load
duke
parents:
diff changeset
    62
/**
90ce3da70b43 Initial load
duke
parents:
diff changeset
    63
 * The <code>TextMeasurer</code> class provides the primitive operations
90ce3da70b43 Initial load
duke
parents:
diff changeset
    64
 * needed for line break: measuring up to a given advance, determining the
90ce3da70b43 Initial load
duke
parents:
diff changeset
    65
 * advance of a range of characters, and generating a
90ce3da70b43 Initial load
duke
parents:
diff changeset
    66
 * <code>TextLayout</code> for a range of characters. It also provides
90ce3da70b43 Initial load
duke
parents:
diff changeset
    67
 * methods for incremental editing of paragraphs.
90ce3da70b43 Initial load
duke
parents:
diff changeset
    68
 * <p>
90ce3da70b43 Initial load
duke
parents:
diff changeset
    69
 * A <code>TextMeasurer</code> object is constructed with an
90ce3da70b43 Initial load
duke
parents:
diff changeset
    70
 * {@link java.text.AttributedCharacterIterator AttributedCharacterIterator}
90ce3da70b43 Initial load
duke
parents:
diff changeset
    71
 * representing a single paragraph of text.  The value returned by the
90ce3da70b43 Initial load
duke
parents:
diff changeset
    72
 * {@link AttributedCharacterIterator#getBeginIndex() getBeginIndex}
90ce3da70b43 Initial load
duke
parents:
diff changeset
    73
 * method of <code>AttributedCharacterIterator</code>
90ce3da70b43 Initial load
duke
parents:
diff changeset
    74
 * defines the absolute index of the first character.  The value
90ce3da70b43 Initial load
duke
parents:
diff changeset
    75
 * returned by the
90ce3da70b43 Initial load
duke
parents:
diff changeset
    76
 * {@link AttributedCharacterIterator#getEndIndex() getEndIndex}
90ce3da70b43 Initial load
duke
parents:
diff changeset
    77
 * method of <code>AttributedCharacterIterator</code> defines the index
90ce3da70b43 Initial load
duke
parents:
diff changeset
    78
 * past the last character.  These values define the range of indexes to
90ce3da70b43 Initial load
duke
parents:
diff changeset
    79
 * use in calls to the <code>TextMeasurer</code>.  For example, calls to
90ce3da70b43 Initial load
duke
parents:
diff changeset
    80
 * get the advance of a range of text or the line break of a range of text
90ce3da70b43 Initial load
duke
parents:
diff changeset
    81
 * must use indexes between the beginning and end index values.  Calls to
90ce3da70b43 Initial load
duke
parents:
diff changeset
    82
 * {@link #insertChar(java.text.AttributedCharacterIterator, int) insertChar}
90ce3da70b43 Initial load
duke
parents:
diff changeset
    83
 * and
90ce3da70b43 Initial load
duke
parents:
diff changeset
    84
 * {@link #deleteChar(java.text.AttributedCharacterIterator, int) deleteChar}
90ce3da70b43 Initial load
duke
parents:
diff changeset
    85
 * reset the <code>TextMeasurer</code> to use the beginning index and end
90ce3da70b43 Initial load
duke
parents:
diff changeset
    86
 * index of the <code>AttributedCharacterIterator</code> passed in those calls.
90ce3da70b43 Initial load
duke
parents:
diff changeset
    87
 * <p>
90ce3da70b43 Initial load
duke
parents:
diff changeset
    88
 * Most clients will use the more convenient <code>LineBreakMeasurer</code>,
90ce3da70b43 Initial load
duke
parents:
diff changeset
    89
 * which implements the standard line break policy (placing as many words
90ce3da70b43 Initial load
duke
parents:
diff changeset
    90
 * as will fit on each line).
90ce3da70b43 Initial load
duke
parents:
diff changeset
    91
 *
90ce3da70b43 Initial load
duke
parents:
diff changeset
    92
 * @author John Raley
90ce3da70b43 Initial load
duke
parents:
diff changeset
    93
 * @see LineBreakMeasurer
90ce3da70b43 Initial load
duke
parents:
diff changeset
    94
 * @since 1.3
90ce3da70b43 Initial load
duke
parents:
diff changeset
    95
 */
90ce3da70b43 Initial load
duke
parents:
diff changeset
    96
90ce3da70b43 Initial load
duke
parents:
diff changeset
    97
public final class TextMeasurer implements Cloneable {
90ce3da70b43 Initial load
duke
parents:
diff changeset
    98
90ce3da70b43 Initial load
duke
parents:
diff changeset
    99
    // Number of lines to format to.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   100
    private static float EST_LINES = (float) 2.1;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   101
90ce3da70b43 Initial load
duke
parents:
diff changeset
   102
    /*
90ce3da70b43 Initial load
duke
parents:
diff changeset
   103
    static {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   104
        String s = System.getProperty("estLines");
90ce3da70b43 Initial load
duke
parents:
diff changeset
   105
        if (s != null) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   106
            try {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   107
                Float f = new Float(s);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   108
                EST_LINES = f.floatValue();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   109
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   110
            catch(NumberFormatException e) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   111
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   112
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   113
        //System.out.println("EST_LINES="+EST_LINES);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   114
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   115
    */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   116
90ce3da70b43 Initial load
duke
parents:
diff changeset
   117
    private FontRenderContext fFrc;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   118
90ce3da70b43 Initial load
duke
parents:
diff changeset
   119
    private int fStart;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   120
90ce3da70b43 Initial load
duke
parents:
diff changeset
   121
    // characters in source text
90ce3da70b43 Initial load
duke
parents:
diff changeset
   122
    private char[] fChars;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   123
90ce3da70b43 Initial load
duke
parents:
diff changeset
   124
    // Bidi for this paragraph
90ce3da70b43 Initial load
duke
parents:
diff changeset
   125
    private Bidi fBidi;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   126
90ce3da70b43 Initial load
duke
parents:
diff changeset
   127
    // Levels array for chars in this paragraph - needed to reorder
90ce3da70b43 Initial load
duke
parents:
diff changeset
   128
    // trailing counterdirectional whitespace
90ce3da70b43 Initial load
duke
parents:
diff changeset
   129
    private byte[] fLevels;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   130
90ce3da70b43 Initial load
duke
parents:
diff changeset
   131
    // line components in logical order
90ce3da70b43 Initial load
duke
parents:
diff changeset
   132
    private TextLineComponent[] fComponents;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   133
90ce3da70b43 Initial load
duke
parents:
diff changeset
   134
    // index where components begin
90ce3da70b43 Initial load
duke
parents:
diff changeset
   135
    private int fComponentStart;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   136
90ce3da70b43 Initial load
duke
parents:
diff changeset
   137
    // index where components end
90ce3da70b43 Initial load
duke
parents:
diff changeset
   138
    private int fComponentLimit;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   139
90ce3da70b43 Initial load
duke
parents:
diff changeset
   140
    private boolean haveLayoutWindow;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   141
90ce3da70b43 Initial load
duke
parents:
diff changeset
   142
    // used to find valid starting points for line components
90ce3da70b43 Initial load
duke
parents:
diff changeset
   143
    private BreakIterator fLineBreak = null;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   144
    private CharArrayIterator charIter = null;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   145
    int layoutCount = 0;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   146
    int layoutCharCount = 0;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   147
90ce3da70b43 Initial load
duke
parents:
diff changeset
   148
    // paragraph, with resolved fonts and styles
90ce3da70b43 Initial load
duke
parents:
diff changeset
   149
    private StyledParagraph fParagraph;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   150
90ce3da70b43 Initial load
duke
parents:
diff changeset
   151
    // paragraph data - same across all layouts
90ce3da70b43 Initial load
duke
parents:
diff changeset
   152
    private boolean fIsDirectionLTR;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   153
    private byte fBaseline;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   154
    private float[] fBaselineOffsets;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   155
    private float fJustifyRatio = 1;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   156
90ce3da70b43 Initial load
duke
parents:
diff changeset
   157
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   158
     * Constructs a <code>TextMeasurer</code> from the source text.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   159
     * The source text should be a single entire paragraph.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   160
     * @param text the source paragraph.  Cannot be null.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   161
     * @param frc the information about a graphics device which is needed
90ce3da70b43 Initial load
duke
parents:
diff changeset
   162
     *       to measure the text correctly.  Cannot be null.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   163
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   164
    public TextMeasurer(AttributedCharacterIterator text, FontRenderContext frc) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   165
90ce3da70b43 Initial load
duke
parents:
diff changeset
   166
        fFrc = frc;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   167
        initAll(text);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   168
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   169
90ce3da70b43 Initial load
duke
parents:
diff changeset
   170
    protected Object clone() {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   171
        TextMeasurer other;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   172
        try {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   173
            other = (TextMeasurer) super.clone();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   174
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   175
        catch(CloneNotSupportedException e) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   176
            throw new Error();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   177
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   178
        if (fComponents != null) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   179
            other.fComponents = (TextLineComponent[]) fComponents.clone();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   180
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   181
        return other;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   182
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   183
90ce3da70b43 Initial load
duke
parents:
diff changeset
   184
    private void invalidateComponents() {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   185
        fComponentStart = fComponentLimit = fChars.length;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   186
        fComponents = null;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   187
        haveLayoutWindow = false;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   188
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   189
90ce3da70b43 Initial load
duke
parents:
diff changeset
   190
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   191
     * Initialize state, including fChars array, direction, and
90ce3da70b43 Initial load
duke
parents:
diff changeset
   192
     * fBidi.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   193
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   194
    private void initAll(AttributedCharacterIterator text) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   195
90ce3da70b43 Initial load
duke
parents:
diff changeset
   196
        fStart = text.getBeginIndex();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   197
90ce3da70b43 Initial load
duke
parents:
diff changeset
   198
        // extract chars
90ce3da70b43 Initial load
duke
parents:
diff changeset
   199
        fChars = new char[text.getEndIndex() - fStart];
90ce3da70b43 Initial load
duke
parents:
diff changeset
   200
90ce3da70b43 Initial load
duke
parents:
diff changeset
   201
        int n = 0;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   202
        for (char c = text.first(); c != text.DONE; c = text.next()) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   203
            fChars[n++] = c;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   204
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   205
90ce3da70b43 Initial load
duke
parents:
diff changeset
   206
        text.first();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   207
90ce3da70b43 Initial load
duke
parents:
diff changeset
   208
        fBidi = new Bidi(text);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   209
        if (fBidi.isLeftToRight()) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   210
            fBidi = null;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   211
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   212
90ce3da70b43 Initial load
duke
parents:
diff changeset
   213
        text.first();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   214
        Map paragraphAttrs = text.getAttributes();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   215
        NumericShaper shaper = AttributeValues.getNumericShaping(paragraphAttrs);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   216
        if (shaper != null) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   217
            shaper.shape(fChars, 0, fChars.length);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   218
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   219
90ce3da70b43 Initial load
duke
parents:
diff changeset
   220
        fParagraph = new StyledParagraph(text, fChars);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   221
90ce3da70b43 Initial load
duke
parents:
diff changeset
   222
        // set paragraph attributes
90ce3da70b43 Initial load
duke
parents:
diff changeset
   223
        {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   224
            // If there's an embedded graphic at the start of the
90ce3da70b43 Initial load
duke
parents:
diff changeset
   225
            // paragraph, look for the first non-graphic character
90ce3da70b43 Initial load
duke
parents:
diff changeset
   226
            // and use it and its font to initialize the paragraph.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   227
            // If not, use the first graphic to initialize.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   228
            fJustifyRatio = AttributeValues.getJustification(paragraphAttrs);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   229
90ce3da70b43 Initial load
duke
parents:
diff changeset
   230
            boolean haveFont = TextLine.advanceToFirstFont(text);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   231
90ce3da70b43 Initial load
duke
parents:
diff changeset
   232
            if (haveFont) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   233
                Font defaultFont = TextLine.getFontAtCurrentPos(text);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   234
                int charsStart = text.getIndex() - text.getBeginIndex();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   235
                LineMetrics lm = defaultFont.getLineMetrics(fChars, charsStart, charsStart+1, fFrc);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   236
                fBaseline = (byte) lm.getBaselineIndex();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   237
                fBaselineOffsets = lm.getBaselineOffsets();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   238
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   239
            else {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   240
                // hmmm what to do here?  Just try to supply reasonable
90ce3da70b43 Initial load
duke
parents:
diff changeset
   241
                // values I guess.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   242
90ce3da70b43 Initial load
duke
parents:
diff changeset
   243
                GraphicAttribute graphic = (GraphicAttribute)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   244
                                paragraphAttrs.get(TextAttribute.CHAR_REPLACEMENT);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   245
                fBaseline = TextLayout.getBaselineFromGraphic(graphic);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   246
                Font dummyFont = new Font(new Hashtable(5, (float)0.9));
90ce3da70b43 Initial load
duke
parents:
diff changeset
   247
                LineMetrics lm = dummyFont.getLineMetrics(" ", 0, 1, fFrc);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   248
                fBaselineOffsets = lm.getBaselineOffsets();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   249
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   250
            fBaselineOffsets = TextLine.getNormalizedOffsets(fBaselineOffsets, fBaseline);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   251
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   252
90ce3da70b43 Initial load
duke
parents:
diff changeset
   253
        invalidateComponents();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   254
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   255
90ce3da70b43 Initial load
duke
parents:
diff changeset
   256
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   257
     * Generate components for the paragraph.  fChars, fBidi should have been
90ce3da70b43 Initial load
duke
parents:
diff changeset
   258
     * initialized already.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   259
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   260
    private void generateComponents(int startingAt, int endingAt) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   261
90ce3da70b43 Initial load
duke
parents:
diff changeset
   262
        if (collectStats) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   263
            formattedChars += (endingAt-startingAt);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   264
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   265
        int layoutFlags = 0; // no extra info yet, bidi determines run and line direction
90ce3da70b43 Initial load
duke
parents:
diff changeset
   266
        TextLabelFactory factory = new TextLabelFactory(fFrc, fChars, fBidi, layoutFlags);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   267
90ce3da70b43 Initial load
duke
parents:
diff changeset
   268
        int[] charsLtoV = null;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   269
90ce3da70b43 Initial load
duke
parents:
diff changeset
   270
        if (fBidi != null) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   271
            fLevels = BidiUtils.getLevels(fBidi);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   272
            int[] charsVtoL = BidiUtils.createVisualToLogicalMap(fLevels);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   273
            charsLtoV = BidiUtils.createInverseMap(charsVtoL);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   274
            fIsDirectionLTR = fBidi.baseIsLeftToRight();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   275
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   276
        else {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   277
            fLevels = null;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   278
            fIsDirectionLTR = true;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   279
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   280
90ce3da70b43 Initial load
duke
parents:
diff changeset
   281
        try {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   282
            fComponents = TextLine.getComponents(
90ce3da70b43 Initial load
duke
parents:
diff changeset
   283
                fParagraph, fChars, startingAt, endingAt, charsLtoV, fLevels, factory);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   284
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   285
        catch(IllegalArgumentException e) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   286
            System.out.println("startingAt="+startingAt+"; endingAt="+endingAt);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   287
            System.out.println("fComponentLimit="+fComponentLimit);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   288
            throw e;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   289
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   290
90ce3da70b43 Initial load
duke
parents:
diff changeset
   291
        fComponentStart = startingAt;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   292
        fComponentLimit = endingAt;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   293
        //debugFormatCount += (endingAt-startingAt);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   294
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   295
90ce3da70b43 Initial load
duke
parents:
diff changeset
   296
    private int calcLineBreak(final int pos, final float maxAdvance) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   297
90ce3da70b43 Initial load
duke
parents:
diff changeset
   298
        // either of these statements removes the bug:
90ce3da70b43 Initial load
duke
parents:
diff changeset
   299
        //generateComponents(0, fChars.length);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   300
        //generateComponents(pos, fChars.length);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   301
90ce3da70b43 Initial load
duke
parents:
diff changeset
   302
        int startPos = pos;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   303
        float width = maxAdvance;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   304
90ce3da70b43 Initial load
duke
parents:
diff changeset
   305
        int tlcIndex;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   306
        int tlcStart = fComponentStart;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   307
90ce3da70b43 Initial load
duke
parents:
diff changeset
   308
        for (tlcIndex = 0; tlcIndex < fComponents.length; tlcIndex++) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   309
            int gaLimit = tlcStart + fComponents[tlcIndex].getNumCharacters();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   310
            if (gaLimit > startPos) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   311
                break;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   312
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   313
            else {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   314
                tlcStart = gaLimit;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   315
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   316
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   317
90ce3da70b43 Initial load
duke
parents:
diff changeset
   318
        // tlcStart is now the start of the tlc at tlcIndex
90ce3da70b43 Initial load
duke
parents:
diff changeset
   319
90ce3da70b43 Initial load
duke
parents:
diff changeset
   320
        for (; tlcIndex < fComponents.length; tlcIndex++) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   321
90ce3da70b43 Initial load
duke
parents:
diff changeset
   322
            TextLineComponent tlc = fComponents[tlcIndex];
90ce3da70b43 Initial load
duke
parents:
diff changeset
   323
            int numCharsInGa = tlc.getNumCharacters();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   324
90ce3da70b43 Initial load
duke
parents:
diff changeset
   325
            int lineBreak = tlc.getLineBreakIndex(startPos - tlcStart, width);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   326
            if (lineBreak == numCharsInGa && tlcIndex < fComponents.length) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   327
                width -= tlc.getAdvanceBetween(startPos - tlcStart, lineBreak);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   328
                tlcStart += numCharsInGa;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   329
                startPos = tlcStart;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   330
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   331
            else {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   332
                return tlcStart + lineBreak;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   333
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   334
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   335
90ce3da70b43 Initial load
duke
parents:
diff changeset
   336
        if (fComponentLimit < fChars.length) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   337
            // format more text and try again
90ce3da70b43 Initial load
duke
parents:
diff changeset
   338
            //if (haveLayoutWindow) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   339
            //    outOfWindow++;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   340
            //}
90ce3da70b43 Initial load
duke
parents:
diff changeset
   341
90ce3da70b43 Initial load
duke
parents:
diff changeset
   342
            generateComponents(pos, fChars.length);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   343
            return calcLineBreak(pos, maxAdvance);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   344
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   345
90ce3da70b43 Initial load
duke
parents:
diff changeset
   346
        return fChars.length;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   347
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   348
90ce3da70b43 Initial load
duke
parents:
diff changeset
   349
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   350
     * According to the Unicode Bidirectional Behavior specification
90ce3da70b43 Initial load
duke
parents:
diff changeset
   351
     * (Unicode Standard 2.0, section 3.11), whitespace at the ends
90ce3da70b43 Initial load
duke
parents:
diff changeset
   352
     * of lines which would naturally flow against the base direction
90ce3da70b43 Initial load
duke
parents:
diff changeset
   353
     * must be made to flow with the line direction, and moved to the
90ce3da70b43 Initial load
duke
parents:
diff changeset
   354
     * end of the line.  This method returns the start of the sequence
90ce3da70b43 Initial load
duke
parents:
diff changeset
   355
     * of trailing whitespace characters to move to the end of a
90ce3da70b43 Initial load
duke
parents:
diff changeset
   356
     * line taken from the given range.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   357
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   358
    private int trailingCdWhitespaceStart(int startPos, int limitPos) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   359
90ce3da70b43 Initial load
duke
parents:
diff changeset
   360
        if (fLevels != null) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   361
            // Back up over counterdirectional whitespace
90ce3da70b43 Initial load
duke
parents:
diff changeset
   362
            final byte baseLevel = (byte) (fIsDirectionLTR? 0 : 1);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   363
            for (int cdWsStart = limitPos; --cdWsStart >= startPos;) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   364
                if ((fLevels[cdWsStart] % 2) == baseLevel ||
90ce3da70b43 Initial load
duke
parents:
diff changeset
   365
                        Character.getDirectionality(fChars[cdWsStart]) != Character.DIRECTIONALITY_WHITESPACE) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   366
                    return ++cdWsStart;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   367
                }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   368
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   369
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   370
90ce3da70b43 Initial load
duke
parents:
diff changeset
   371
        return startPos;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   372
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   373
90ce3da70b43 Initial load
duke
parents:
diff changeset
   374
    private TextLineComponent[] makeComponentsOnRange(int startPos,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   375
                                                      int limitPos) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   376
90ce3da70b43 Initial load
duke
parents:
diff changeset
   377
        // sigh I really hate to do this here since it's part of the
90ce3da70b43 Initial load
duke
parents:
diff changeset
   378
        // bidi algorithm.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   379
        // cdWsStart is the start of the trailing counterdirectional
90ce3da70b43 Initial load
duke
parents:
diff changeset
   380
        // whitespace
90ce3da70b43 Initial load
duke
parents:
diff changeset
   381
        final int cdWsStart = trailingCdWhitespaceStart(startPos, limitPos);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   382
90ce3da70b43 Initial load
duke
parents:
diff changeset
   383
        int tlcIndex;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   384
        int tlcStart = fComponentStart;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   385
90ce3da70b43 Initial load
duke
parents:
diff changeset
   386
        for (tlcIndex = 0; tlcIndex < fComponents.length; tlcIndex++) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   387
            int gaLimit = tlcStart + fComponents[tlcIndex].getNumCharacters();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   388
            if (gaLimit > startPos) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   389
                break;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   390
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   391
            else {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   392
                tlcStart = gaLimit;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   393
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   394
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   395
90ce3da70b43 Initial load
duke
parents:
diff changeset
   396
        // tlcStart is now the start of the tlc at tlcIndex
90ce3da70b43 Initial load
duke
parents:
diff changeset
   397
90ce3da70b43 Initial load
duke
parents:
diff changeset
   398
        int componentCount;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   399
        {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   400
            boolean split = false;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   401
            int compStart = tlcStart;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   402
            int lim=tlcIndex;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   403
            for (boolean cont=true; cont; lim++) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   404
                int gaLimit = compStart + fComponents[lim].getNumCharacters();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   405
                if (cdWsStart > Math.max(compStart, startPos)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   406
                            && cdWsStart < Math.min(gaLimit, limitPos)) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   407
                    split = true;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   408
                }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   409
                if (gaLimit >= limitPos) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   410
                    cont=false;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   411
                }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   412
                else {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   413
                    compStart = gaLimit;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   414
                }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   415
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   416
            componentCount = lim-tlcIndex;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   417
            if (split) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   418
                componentCount++;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   419
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   420
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   421
90ce3da70b43 Initial load
duke
parents:
diff changeset
   422
        TextLineComponent[] components = new TextLineComponent[componentCount];
90ce3da70b43 Initial load
duke
parents:
diff changeset
   423
        int newCompIndex = 0;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   424
        int linePos = startPos;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   425
90ce3da70b43 Initial load
duke
parents:
diff changeset
   426
        int breakPt = cdWsStart;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   427
90ce3da70b43 Initial load
duke
parents:
diff changeset
   428
        int subsetFlag;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   429
        if (breakPt == startPos) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   430
            subsetFlag = fIsDirectionLTR? TextLineComponent.LEFT_TO_RIGHT :
90ce3da70b43 Initial load
duke
parents:
diff changeset
   431
                                          TextLineComponent.RIGHT_TO_LEFT;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   432
            breakPt = limitPos;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   433
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   434
        else {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   435
            subsetFlag = TextLineComponent.UNCHANGED;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   436
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   437
90ce3da70b43 Initial load
duke
parents:
diff changeset
   438
        while (linePos < limitPos) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   439
90ce3da70b43 Initial load
duke
parents:
diff changeset
   440
            int compLength = fComponents[tlcIndex].getNumCharacters();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   441
            int tlcLimit = tlcStart + compLength;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   442
90ce3da70b43 Initial load
duke
parents:
diff changeset
   443
            int start = Math.max(linePos, tlcStart);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   444
            int limit = Math.min(breakPt, tlcLimit);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   445
90ce3da70b43 Initial load
duke
parents:
diff changeset
   446
            components[newCompIndex++] = fComponents[tlcIndex].getSubset(
90ce3da70b43 Initial load
duke
parents:
diff changeset
   447
                                                                start-tlcStart,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   448
                                                                limit-tlcStart,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   449
                                                                subsetFlag);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   450
            linePos += (limit-start);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   451
            if (linePos == breakPt) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   452
                breakPt = limitPos;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   453
                subsetFlag = fIsDirectionLTR? TextLineComponent.LEFT_TO_RIGHT :
90ce3da70b43 Initial load
duke
parents:
diff changeset
   454
                                              TextLineComponent.RIGHT_TO_LEFT;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   455
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   456
            if (linePos == tlcLimit) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   457
                tlcIndex++;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   458
                tlcStart = tlcLimit;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   459
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   460
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   461
90ce3da70b43 Initial load
duke
parents:
diff changeset
   462
        return components;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   463
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   464
90ce3da70b43 Initial load
duke
parents:
diff changeset
   465
    private TextLine makeTextLineOnRange(int startPos, int limitPos) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   466
90ce3da70b43 Initial load
duke
parents:
diff changeset
   467
        int[] charsLtoV = null;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   468
        byte[] charLevels = null;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   469
90ce3da70b43 Initial load
duke
parents:
diff changeset
   470
        if (fBidi != null) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   471
            Bidi lineBidi = fBidi.createLineBidi(startPos, limitPos);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   472
            charLevels = BidiUtils.getLevels(lineBidi);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   473
            int[] charsVtoL = BidiUtils.createVisualToLogicalMap(charLevels);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   474
            charsLtoV = BidiUtils.createInverseMap(charsVtoL);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   475
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   476
90ce3da70b43 Initial load
duke
parents:
diff changeset
   477
        TextLineComponent[] components = makeComponentsOnRange(startPos, limitPos);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   478
90ce3da70b43 Initial load
duke
parents:
diff changeset
   479
        return new TextLine(fFrc,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   480
                            components,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   481
                            fBaselineOffsets,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   482
                            fChars,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   483
                            startPos,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   484
                            limitPos,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   485
                            charsLtoV,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   486
                            charLevels,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   487
                            fIsDirectionLTR);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   488
90ce3da70b43 Initial load
duke
parents:
diff changeset
   489
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   490
90ce3da70b43 Initial load
duke
parents:
diff changeset
   491
    private void ensureComponents(int start, int limit) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   492
90ce3da70b43 Initial load
duke
parents:
diff changeset
   493
        if (start < fComponentStart || limit > fComponentLimit) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   494
            generateComponents(start, limit);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   495
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   496
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   497
90ce3da70b43 Initial load
duke
parents:
diff changeset
   498
    private void makeLayoutWindow(int localStart) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   499
90ce3da70b43 Initial load
duke
parents:
diff changeset
   500
        int compStart = localStart;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   501
        int compLimit = fChars.length;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   502
90ce3da70b43 Initial load
duke
parents:
diff changeset
   503
        // If we've already gone past the layout window, format to end of paragraph
90ce3da70b43 Initial load
duke
parents:
diff changeset
   504
        if (layoutCount > 0 && !haveLayoutWindow) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   505
            float avgLineLength = Math.max(layoutCharCount / layoutCount, 1);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   506
            compLimit = Math.min(localStart + (int)(avgLineLength*EST_LINES), fChars.length);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   507
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   508
90ce3da70b43 Initial load
duke
parents:
diff changeset
   509
        if (localStart > 0 || compLimit < fChars.length) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   510
            if (charIter == null) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   511
                charIter = new CharArrayIterator(fChars);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   512
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   513
            else {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   514
                charIter.reset(fChars);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   515
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   516
            if (fLineBreak == null) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   517
                fLineBreak = BreakIterator.getLineInstance();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   518
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   519
            fLineBreak.setText(charIter);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   520
            if (localStart > 0) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   521
                if (!fLineBreak.isBoundary(localStart)) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   522
                    compStart = fLineBreak.preceding(localStart);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   523
                }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   524
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   525
            if (compLimit < fChars.length) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   526
                if (!fLineBreak.isBoundary(compLimit)) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   527
                    compLimit = fLineBreak.following(compLimit);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   528
                }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   529
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   530
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   531
90ce3da70b43 Initial load
duke
parents:
diff changeset
   532
        ensureComponents(compStart, compLimit);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   533
        haveLayoutWindow = true;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   534
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   535
90ce3da70b43 Initial load
duke
parents:
diff changeset
   536
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   537
     * Returns the index of the first character which will not fit on
90ce3da70b43 Initial load
duke
parents:
diff changeset
   538
     * on a line beginning at <code>start</code> and possible
90ce3da70b43 Initial load
duke
parents:
diff changeset
   539
     * measuring up to <code>maxAdvance</code> in graphical width.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   540
     *
90ce3da70b43 Initial load
duke
parents:
diff changeset
   541
     * @param start the character index at which to start measuring.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   542
     *  <code>start</code> is an absolute index, not relative to the
90ce3da70b43 Initial load
duke
parents:
diff changeset
   543
     *  start of the paragraph
90ce3da70b43 Initial load
duke
parents:
diff changeset
   544
     * @param maxAdvance the graphical width in which the line must fit
90ce3da70b43 Initial load
duke
parents:
diff changeset
   545
     * @return the index after the last character that will fit
90ce3da70b43 Initial load
duke
parents:
diff changeset
   546
     *  on a line beginning at <code>start</code>, which is not longer
90ce3da70b43 Initial load
duke
parents:
diff changeset
   547
     *  than <code>maxAdvance</code> in graphical width
90ce3da70b43 Initial load
duke
parents:
diff changeset
   548
     * @throws IllegalArgumentException if <code>start</code> is
90ce3da70b43 Initial load
duke
parents:
diff changeset
   549
     *          less than the beginning of the paragraph.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   550
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   551
    public int getLineBreakIndex(int start, float maxAdvance) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   552
90ce3da70b43 Initial load
duke
parents:
diff changeset
   553
        int localStart = start - fStart;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   554
90ce3da70b43 Initial load
duke
parents:
diff changeset
   555
        if (!haveLayoutWindow ||
90ce3da70b43 Initial load
duke
parents:
diff changeset
   556
                localStart < fComponentStart ||
90ce3da70b43 Initial load
duke
parents:
diff changeset
   557
                localStart >= fComponentLimit) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   558
            makeLayoutWindow(localStart);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   559
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   560
90ce3da70b43 Initial load
duke
parents:
diff changeset
   561
        return calcLineBreak(localStart, maxAdvance) + fStart;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   562
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   563
90ce3da70b43 Initial load
duke
parents:
diff changeset
   564
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   565
     * Returns the graphical width of a line beginning at <code>start</code>
90ce3da70b43 Initial load
duke
parents:
diff changeset
   566
     * and including characters up to <code>limit</code>.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   567
     * <code>start</code> and <code>limit</code> are absolute indices,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   568
     * not relative to the start of the paragraph.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   569
     *
90ce3da70b43 Initial load
duke
parents:
diff changeset
   570
     * @param start the character index at which to start measuring
90ce3da70b43 Initial load
duke
parents:
diff changeset
   571
     * @param limit the character index at which to stop measuring
90ce3da70b43 Initial load
duke
parents:
diff changeset
   572
     * @return the graphical width of a line beginning at <code>start</code>
90ce3da70b43 Initial load
duke
parents:
diff changeset
   573
     *   and including characters up to <code>limit</code>
90ce3da70b43 Initial load
duke
parents:
diff changeset
   574
     * @throws IndexOutOfBoundsException if <code>limit</code> is less
90ce3da70b43 Initial load
duke
parents:
diff changeset
   575
     *         than <code>start</code>
90ce3da70b43 Initial load
duke
parents:
diff changeset
   576
     * @throws IllegalArgumentException if <code>start</code> or
90ce3da70b43 Initial load
duke
parents:
diff changeset
   577
     *          <code>limit</code> is not between the beginning of
90ce3da70b43 Initial load
duke
parents:
diff changeset
   578
     *          the paragraph and the end of the paragraph.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   579
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   580
    public float getAdvanceBetween(int start, int limit) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   581
90ce3da70b43 Initial load
duke
parents:
diff changeset
   582
        int localStart = start - fStart;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   583
        int localLimit = limit - fStart;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   584
90ce3da70b43 Initial load
duke
parents:
diff changeset
   585
        ensureComponents(localStart, localLimit);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   586
        TextLine line = makeTextLineOnRange(localStart, localLimit);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   587
        return line.getMetrics().advance;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   588
        // could cache line in case getLayout is called with same start, limit
90ce3da70b43 Initial load
duke
parents:
diff changeset
   589
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   590
90ce3da70b43 Initial load
duke
parents:
diff changeset
   591
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   592
     * Returns a <code>TextLayout</code> on the given character range.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   593
     *
90ce3da70b43 Initial load
duke
parents:
diff changeset
   594
     * @param start the index of the first character
90ce3da70b43 Initial load
duke
parents:
diff changeset
   595
     * @param limit the index after the last character.  Must be greater
90ce3da70b43 Initial load
duke
parents:
diff changeset
   596
     *   than <code>start</code>
90ce3da70b43 Initial load
duke
parents:
diff changeset
   597
     * @return a <code>TextLayout</code> for the characters beginning at
90ce3da70b43 Initial load
duke
parents:
diff changeset
   598
     *  <code>start</code> up to (but not including) <code>limit</code>
90ce3da70b43 Initial load
duke
parents:
diff changeset
   599
     * @throws IndexOutOfBoundsException if <code>limit</code> is less
90ce3da70b43 Initial load
duke
parents:
diff changeset
   600
     *         than <code>start</code>
90ce3da70b43 Initial load
duke
parents:
diff changeset
   601
     * @throws IllegalArgumentException if <code>start</code> or
90ce3da70b43 Initial load
duke
parents:
diff changeset
   602
     *          <code>limit</code> is not between the beginning of
90ce3da70b43 Initial load
duke
parents:
diff changeset
   603
     *          the paragraph and the end of the paragraph.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   604
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   605
    public TextLayout getLayout(int start, int limit) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   606
90ce3da70b43 Initial load
duke
parents:
diff changeset
   607
        int localStart = start - fStart;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   608
        int localLimit = limit - fStart;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   609
90ce3da70b43 Initial load
duke
parents:
diff changeset
   610
        ensureComponents(localStart, localLimit);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   611
        TextLine textLine = makeTextLineOnRange(localStart, localLimit);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   612
90ce3da70b43 Initial load
duke
parents:
diff changeset
   613
        if (localLimit < fChars.length) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   614
            layoutCharCount += limit-start;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   615
            layoutCount++;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   616
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   617
90ce3da70b43 Initial load
duke
parents:
diff changeset
   618
        return new TextLayout(textLine,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   619
                              fBaseline,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   620
                              fBaselineOffsets,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   621
                              fJustifyRatio);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   622
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   623
90ce3da70b43 Initial load
duke
parents:
diff changeset
   624
    private int formattedChars = 0;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   625
    private static boolean wantStats = false;/*"true".equals(System.getProperty("collectStats"));*/
90ce3da70b43 Initial load
duke
parents:
diff changeset
   626
    private boolean collectStats = false;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   627
90ce3da70b43 Initial load
duke
parents:
diff changeset
   628
    private void printStats() {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   629
        System.out.println("formattedChars: " + formattedChars);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   630
        //formattedChars = 0;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   631
        collectStats = false;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   632
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   633
90ce3da70b43 Initial load
duke
parents:
diff changeset
   634
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   635
     * Updates the <code>TextMeasurer</code> after a single character has
90ce3da70b43 Initial load
duke
parents:
diff changeset
   636
     * been inserted
90ce3da70b43 Initial load
duke
parents:
diff changeset
   637
     * into the paragraph currently represented by this
90ce3da70b43 Initial load
duke
parents:
diff changeset
   638
     * <code>TextMeasurer</code>.  After this call, this
90ce3da70b43 Initial load
duke
parents:
diff changeset
   639
     * <code>TextMeasurer</code> is equivalent to a new
90ce3da70b43 Initial load
duke
parents:
diff changeset
   640
     * <code>TextMeasurer</code> created from the text;  however, it will
90ce3da70b43 Initial load
duke
parents:
diff changeset
   641
     * usually be more efficient to update an existing
90ce3da70b43 Initial load
duke
parents:
diff changeset
   642
     * <code>TextMeasurer</code> than to create a new one from scratch.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   643
     *
90ce3da70b43 Initial load
duke
parents:
diff changeset
   644
     * @param newParagraph the text of the paragraph after performing
90ce3da70b43 Initial load
duke
parents:
diff changeset
   645
     * the insertion.  Cannot be null.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   646
     * @param insertPos the position in the text where the character was
90ce3da70b43 Initial load
duke
parents:
diff changeset
   647
     * inserted.  Must not be less than the start of
90ce3da70b43 Initial load
duke
parents:
diff changeset
   648
     * <code>newParagraph</code>, and must be less than the end of
90ce3da70b43 Initial load
duke
parents:
diff changeset
   649
     * <code>newParagraph</code>.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   650
     * @throws IndexOutOfBoundsException if <code>insertPos</code> is less
90ce3da70b43 Initial load
duke
parents:
diff changeset
   651
     *         than the start of <code>newParagraph</code> or greater than
90ce3da70b43 Initial load
duke
parents:
diff changeset
   652
     *         or equal to the end of <code>newParagraph</code>
90ce3da70b43 Initial load
duke
parents:
diff changeset
   653
     * @throws NullPointerException if <code>newParagraph</code> is
90ce3da70b43 Initial load
duke
parents:
diff changeset
   654
     *         <code>null</code>
90ce3da70b43 Initial load
duke
parents:
diff changeset
   655
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   656
    public void insertChar(AttributedCharacterIterator newParagraph, int insertPos) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   657
90ce3da70b43 Initial load
duke
parents:
diff changeset
   658
        if (collectStats) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   659
            printStats();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   660
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   661
        if (wantStats) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   662
            collectStats = true;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   663
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   664
90ce3da70b43 Initial load
duke
parents:
diff changeset
   665
        fStart = newParagraph.getBeginIndex();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   666
        int end = newParagraph.getEndIndex();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   667
        if (end - fStart != fChars.length+1) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   668
            initAll(newParagraph);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   669
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   670
90ce3da70b43 Initial load
duke
parents:
diff changeset
   671
        char[] newChars = new char[end-fStart];
90ce3da70b43 Initial load
duke
parents:
diff changeset
   672
        int newCharIndex = insertPos - fStart;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   673
        System.arraycopy(fChars, 0, newChars, 0, newCharIndex);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   674
90ce3da70b43 Initial load
duke
parents:
diff changeset
   675
        char newChar = newParagraph.setIndex(insertPos);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   676
        newChars[newCharIndex] = newChar;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   677
        System.arraycopy(fChars,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   678
                         newCharIndex,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   679
                         newChars,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   680
                         newCharIndex+1,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   681
                         end-insertPos-1);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   682
        fChars = newChars;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   683
90ce3da70b43 Initial load
duke
parents:
diff changeset
   684
        if (fBidi != null || Bidi.requiresBidi(newChars, newCharIndex, newCharIndex + 1) ||
90ce3da70b43 Initial load
duke
parents:
diff changeset
   685
                newParagraph.getAttribute(TextAttribute.BIDI_EMBEDDING) != null) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   686
90ce3da70b43 Initial load
duke
parents:
diff changeset
   687
            fBidi = new Bidi(newParagraph);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   688
            if (fBidi.isLeftToRight()) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   689
                fBidi = null;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   690
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   691
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   692
90ce3da70b43 Initial load
duke
parents:
diff changeset
   693
        fParagraph = StyledParagraph.insertChar(newParagraph,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   694
                                                fChars,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   695
                                                insertPos,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   696
                                                fParagraph);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   697
        invalidateComponents();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   698
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   699
90ce3da70b43 Initial load
duke
parents:
diff changeset
   700
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   701
     * Updates the <code>TextMeasurer</code> after a single character has
90ce3da70b43 Initial load
duke
parents:
diff changeset
   702
     * been deleted
90ce3da70b43 Initial load
duke
parents:
diff changeset
   703
     * from the paragraph currently represented by this
90ce3da70b43 Initial load
duke
parents:
diff changeset
   704
     * <code>TextMeasurer</code>.  After this call, this
90ce3da70b43 Initial load
duke
parents:
diff changeset
   705
     * <code>TextMeasurer</code> is equivalent to a new <code>TextMeasurer</code>
90ce3da70b43 Initial load
duke
parents:
diff changeset
   706
     * created from the text;  however, it will usually be more efficient
90ce3da70b43 Initial load
duke
parents:
diff changeset
   707
     * to update an existing <code>TextMeasurer</code> than to create a new one
90ce3da70b43 Initial load
duke
parents:
diff changeset
   708
     * from scratch.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   709
     *
90ce3da70b43 Initial load
duke
parents:
diff changeset
   710
     * @param newParagraph the text of the paragraph after performing
90ce3da70b43 Initial load
duke
parents:
diff changeset
   711
     * the deletion.  Cannot be null.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   712
     * @param deletePos the position in the text where the character was removed.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   713
     * Must not be less than
90ce3da70b43 Initial load
duke
parents:
diff changeset
   714
     * the start of <code>newParagraph</code>, and must not be greater than the
90ce3da70b43 Initial load
duke
parents:
diff changeset
   715
     * end of <code>newParagraph</code>.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   716
     * @throws IndexOutOfBoundsException if <code>deletePos</code> is
90ce3da70b43 Initial load
duke
parents:
diff changeset
   717
     *         less than the start of <code>newParagraph</code> or greater
90ce3da70b43 Initial load
duke
parents:
diff changeset
   718
     *         than the end of <code>newParagraph</code>
90ce3da70b43 Initial load
duke
parents:
diff changeset
   719
     * @throws NullPointerException if <code>newParagraph</code> is
90ce3da70b43 Initial load
duke
parents:
diff changeset
   720
     *         <code>null</code>
90ce3da70b43 Initial load
duke
parents:
diff changeset
   721
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   722
    public void deleteChar(AttributedCharacterIterator newParagraph, int deletePos) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   723
90ce3da70b43 Initial load
duke
parents:
diff changeset
   724
        fStart = newParagraph.getBeginIndex();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   725
        int end = newParagraph.getEndIndex();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   726
        if (end - fStart != fChars.length-1) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   727
            initAll(newParagraph);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   728
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   729
90ce3da70b43 Initial load
duke
parents:
diff changeset
   730
        char[] newChars = new char[end-fStart];
90ce3da70b43 Initial load
duke
parents:
diff changeset
   731
        int changedIndex = deletePos-fStart;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   732
90ce3da70b43 Initial load
duke
parents:
diff changeset
   733
        System.arraycopy(fChars, 0, newChars, 0, deletePos-fStart);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   734
        System.arraycopy(fChars, changedIndex+1, newChars, changedIndex, end-deletePos);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   735
        fChars = newChars;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   736
90ce3da70b43 Initial load
duke
parents:
diff changeset
   737
        if (fBidi != null) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   738
            fBidi = new Bidi(newParagraph);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   739
            if (fBidi.isLeftToRight()) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   740
                fBidi = null;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   741
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   742
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   743
90ce3da70b43 Initial load
duke
parents:
diff changeset
   744
        fParagraph = StyledParagraph.deleteChar(newParagraph,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   745
                                                fChars,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   746
                                                deletePos,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   747
                                                fParagraph);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   748
        invalidateComponents();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   749
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   750
90ce3da70b43 Initial load
duke
parents:
diff changeset
   751
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   752
     * NOTE:  This method is only for LineBreakMeasurer's use.  It is package-
90ce3da70b43 Initial load
duke
parents:
diff changeset
   753
     * private because it returns internal data.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   754
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   755
    char[] getChars() {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   756
90ce3da70b43 Initial load
duke
parents:
diff changeset
   757
        return fChars;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   758
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   759
}