3261N/A * Copyright (c) 1999, 2010, Oracle and/or its affiliates. All rights reserved. 0N/A * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 0N/A * This code is free software; you can redistribute it and/or modify it 0N/A * under the terms of the GNU General Public License version 2 only, as 2362N/A * published by the Free Software Foundation. Oracle designates this 0N/A * particular file as subject to the "Classpath" exception as provided 2362N/A * by Oracle in the LICENSE file that accompanied this code. 0N/A * This code is distributed in the hope that it will be useful, but WITHOUT 0N/A * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 0N/A * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 0N/A * version 2 for more details (a copy is included in the LICENSE file that 0N/A * accompanied this code). 0N/A * You should have received a copy of the GNU General Public License version 0N/A * 2 along with this work; if not, write to the Free Software Foundation, 0N/A * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 2362N/A * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 2362N/A * or visit www.oracle.com if you need additional information or have any 0N/A * A GlyphView is a styled chunk of text that represents a view 0N/A * mapped over an element in the text model. This view is generally 0N/A * responsible for displaying text glyphs using character level 0N/A * attributes in some way. 0N/A * An implementation of the GlyphPainter class is used to do the 0N/A * actual rendering and model/view translations. This separates 0N/A * rendering from layout and management of the association with 0N/A * The view supports breaking for the purpose of formatting. 0N/A * The fragments produced by breaking share the view that has 0N/A * primary responsibility for the element (i.e. they are nested 0N/A * classes and carry only a small amount of state of their own) 0N/A * so they can share its resources. 0N/A * represents text that may have tabs embedded in it, it implements the 0N/A * <code>TabableView</code> interface. Tabs will only be 0N/A * expanded if this view is embedded in a container that does 0N/A * tab expansion. ParagraphView is an example of a container 0N/A * that does tab expansion. 0N/A * @author Timothy Prinzing 0N/A * Constructs a new view wrapped on an element. 0N/A * @param elem the element 0N/A // if there was an implied CR 0N/A // if this is non-empty paragraph 0N/A * Creates a shallow copy. This is used by the 0N/A * createFragment and breakView methods. 0N/A * Fetch the currently installed glyph painter. 0N/A * If a painter has not yet been installed, and 0N/A * a default was not yet needed, null is returned. 0N/A * Sets the painter to use for rendering glyphs. 0N/A * Fetch a reference to the text that occupies 0N/A * the given range. This is normally used by 0N/A * the GlyphPainter to determine what characters 0N/A * it should render glyphs for. 0N/A * @param p0 the starting document offset >= 0 0N/A * @param p1 the ending document offset >= p0 0N/A * @return the <code>Segment</code> containing the text 0N/A // When done with the returned Segment it should be released by 0N/A // SegmentCache.releaseSharedSegment(segment); 0N/A * Fetch the background color to use to render the 0N/A * glyphs. If there is no background color, null should 0N/A * be returned. This is implemented to call 0N/A * <code>StyledDocument.getBackground</code> if the associated 0N/A * document is a styled document, otherwise it returns null. 0N/A * Fetch the foreground color to use to render the 0N/A * glyphs. If there is no foreground color, null should 0N/A * be returned. This is implemented to call 0N/A * <code>StyledDocument.getBackground</code> if the associated 0N/A * document is a StyledDocument. If the associated document 0N/A * is not a StyledDocument, the associated components foreground 0N/A * color is used. If there is no associated component, null 0N/A * Fetch the font that the glyphs should be based 0N/A * upon. This is implemented to call 0N/A * <code>StyledDocument.getFont</code> if the associated 0N/A * document is a StyledDocument. If the associated document 0N/A * is not a StyledDocument, the associated components font 0N/A * is used. If there is no associated component, null 0N/A * Determine if the glyphs should be underlined. If true, 0N/A * an underline should be drawn through the baseline. 0N/A * Determine if the glyphs should have a strikethrough 0N/A * line. If true, a line should be drawn through the center 0N/A * Determine if the glyphs should be rendered as superscript. 0N/A * Determine if the glyphs should be rendered as subscript. 0N/A * Fetch the TabExpander to use if tabs are present in this view. 0N/A * Check to see that a glyph painter exists. If a painter 0N/A * doesn't exist, a default glyph painter will be installed. 0N/A // the classname should probably come from a property file. 0N/A // --- TabableView methods -------------------------------------- 0N/A * Determines the desired span when using the given 0N/A * tab expansion implementation. 0N/A * @param x the position the view would be located 0N/A * at for the purpose of tab expansion >= 0. 0N/A * @param e how to expand the tabs when encountered. 0N/A * @return the desired span >= 0 0N/A * @see TabableView#getTabbedSpan 0N/A // setting expander can change horizontal span of the view, 0N/A // so we have to call preferenceChanged() 0N/A * Determines the span along the same axis as tab 0N/A * expansion for a portion of the view. This is 0N/A * intended for use by the TabExpander for cases 0N/A * where the tab expansion involves aligning the 0N/A * portion of text that doesn't have whitespace 0N/A * relative to the tab stop. There is therefore 0N/A * an assumption that the range given does not 0N/A * This method can be called while servicing the 0N/A * getTabbedSpan or getPreferredSize. It has to 0N/A * arrange for its own text buffer to make the 0N/A * @param p0 the starting document offset >= 0 0N/A * @param p1 the ending document offset >= p0 0N/A * @return the span >= 0 0N/A // --- View methods --------------------------------------------- 0N/A * Fetches the portion of the model that this view is responsible for. 0N/A * @return the starting offset into the model 0N/A * @see View#getStartOffset 0N/A * Fetches the portion of the model that this view is responsible for. 0N/A * @return the ending offset into the model 0N/A * @see View#getEndOffset 0N/A * Lazily initializes the selections field 0N/A * Renders a portion of a text style run. 0N/A * @param g the rendering surface to use 0N/A * @param a the allocated region to render into 0N/A if (
// there's a highlighter (bug 4532590), and 0N/A // selected text color is different from regular foreground 0N/A // the selection is out of this view 0N/A // the whole view is selected 0N/A // the array is lazily created only when the view 0N/A // is partially selected 0N/A // the array represents view positions [0, p1-p0+1] 0N/A // later will iterate this array and sum its 0N/A // elements. Positions with sum == 0 are not selected. 0N/A // the view is partially selected 0N/A // searching for the next selection start 0N/A // paint unselected text 0N/A // searching for next start position of unselected text 0N/A * Paints the specified region of text in the specified color. 0N/A // render the glyphs 0N/A // render underline or strikethrough if set. 0N/A // calculate x coordinates 0N/A // strip whitespace on end 0N/A // calculate y coordinate 0N/A // move y coordinate above baseline 0N/A * Determines the minimum span for this view along an axis. 0N/A * <p>This implementation returns the longest non-breakable area within 0N/A * the view as a minimum span for {@code View.X_AXIS}.</p> 0N/A * @param axis may be either {@code View.X_AXIS} or {@code View.Y_AXIS} 0N/A * @return the minimum span the view can be rendered into 0N/A * @throws IllegalArgumentException if the {@code axis} parameter is invalid 0N/A * @see javax.swing.text.View#getMinimumSpan 3954N/A // the rest of the view is non-breakable 3954N/A // Note: getBreakSpot returns the *last* breakspot 0N/A * Determines the preferred span for this view along an 0N/A * @param axis may be either View.X_AXIS or View.Y_AXIS 0N/A * @return the span the view would like to be rendered into >= 0. 0N/A * Typically the view is told to render into the span 0N/A * that is returned, although there is no guarantee. 0N/A * The parent may choose to resize or break the view. 0N/A * Determines the desired alignment for this view along an 0N/A * axis. For the label, the alignment is along the font 0N/A * baseline for the y axis, and the superclasses alignment 0N/A * @param axis may be either View.X_AXIS or View.Y_AXIS 0N/A * @return the desired alignment. This should be a value 0N/A * between 0.0 and 1.0 inclusive, where 0 indicates alignment at the 0N/A * origin and 1.0 indicates alignment to the full span 0N/A * away from the origin. An alignment of 0.5 would be the 0N/A * center of the view. 0N/A align = (h >
0) ? (h - (d + (a /
2))) / h :
0;
0N/A * Provides a mapping from the document model coordinate space 0N/A * to the coordinate space of the view mapped to it. 0N/A * @param pos the position to convert >= 0 0N/A * @param a the allocated region to render into 0N/A * @param b either <code>Position.Bias.Forward</code> 0N/A * or <code>Position.Bias.Backward</code> 0N/A * @return the bounding box of the given position 0N/A * @exception BadLocationException if the given position does not represent a 0N/A * valid location in the associated document 0N/A * @see View#modelToView 0N/A * Provides a mapping from the view coordinate space to the logical 0N/A * coordinate space of the model. 0N/A * @param x the X coordinate >= 0 0N/A * @param y the Y coordinate >= 0 0N/A * @param a the allocated region to render into 0N/A * @param biasReturn either <code>Position.Bias.Forward</code> 0N/A * or <code>Position.Bias.Backward</code> is returned as the 0N/A * zero-th element of this array 0N/A * @return the location within the model that best represents the 0N/A * given point of view >= 0 0N/A * @see View#viewToModel 0N/A * Determines how attractive a break opportunity in 0N/A * this view is. This can be used for determining which 0N/A * view is the most attractive to call <code>breakView</code> 0N/A * on in the process of formatting. The 0N/A * higher the weight, the more attractive the break. A 0N/A * value equal to or lower than <code>View.BadBreakWeight</code> 0N/A * should not be considered for a break. A value greater 0N/A * than or equal to <code>View.ForcedBreakWeight</code> should 0N/A * This is implemented to forward to the superclass for 0N/A * the Y_AXIS. Along the X_AXIS the following values 0N/A * <dt><b>View.ExcellentBreakWeight</b> 0N/A * <dd>if there is whitespace proceeding the desired break 0N/A * <dt><b>View.BadBreakWeight</b> 0N/A * <dd>if the desired break location results in a break 0N/A * location of the starting offset. 0N/A * <dt><b>View.GoodBreakWeight</b> 0N/A * <dd>if the other conditions don't occur. 0N/A * This will normally result in the behavior of breaking 0N/A * on a whitespace location if one can be found, otherwise 0N/A * breaking between characters. 0N/A * @param axis may be either View.X_AXIS or View.Y_AXIS 0N/A * @param pos the potential location of the start of the 0N/A * broken view >= 0. This may be useful for calculating tab 0N/A * @param len specifies the relative length from <em>pos</em> 0N/A * where a potential break is desired >= 0. 0N/A * @return the weight, which should be a value between 0N/A * View.ForcedBreakWeight and View.BadBreakWeight. 0N/A * @see ParagraphView 0N/A * @see View#BadBreakWeight 0N/A * @see View#GoodBreakWeight 0N/A * @see View#ExcellentBreakWeight 0N/A * @see View#ForcedBreakWeight 0N/A * Breaks this view on the given axis at the given length. 0N/A * This is implemented to attempt to break on a whitespace 0N/A * location, and returns a fragment with the whitespace at 0N/A * the end. If a whitespace location can't be found, the 0N/A * nearest character is used. 0N/A * @param axis may be either View.X_AXIS or View.Y_AXIS 0N/A * @param p0 the location in the model where the 0N/A * fragment should start it's representation >= 0. 0N/A * @param pos the position along the axis that the 0N/A * broken view would occupy >= 0. This may be useful for 0N/A * things like tab calculations. 0N/A * @param len specifies the distance along the axis 0N/A * where a potential break is desired >= 0. 0N/A * @return the fragment of the view that represents the 0N/A * given span, if the view can be broken. If the view 0N/A * doesn't support breaking behavior, the view itself is 0N/A * @see View#breakView 0N/A // else, no break in the region, return a fragment of the 0N/A * Returns a location to break at in the passed in region, or 0N/A * BreakIterator.DONE if there isn't a good location to break at 0N/A * in the specified region. 0N/A // Re-calculate breakpoints for the whole view 0N/A // Breaker should work on the parent element because there may be 0N/A // a valid breakpoint at the end edge of the view (space, etc.) 0N/A // Backward search should start from end+1 unless there's NO end+1 0N/A // The break spot is within the view 0N/A * Return break iterator appropriate for the current document. 0N/A * For non-i18n documents a fast whitespace-based break iterator is used. 0N/A * Creates a view that represents a portion of the element. 0N/A * This is potentially useful during formatting operations 0N/A * for taking measurements of fragments of the view. If 0N/A * the view doesn't support fragmenting (the default), it 0N/A * should return itself. 0N/A * This view does support fragmenting. It is implemented 0N/A * to return a nested class that shares state in this view 0N/A * representing only a portion of the view. 0N/A * @param p0 the starting offset >= 0. This should be a value 0N/A * greater or equal to the element starting offset and 0N/A * less than the element ending offset. 0N/A * @param p1 the ending offset > p0. This should be a value 0N/A * less than or equal to the elements end offset and 0N/A * greater than the elements starting offset. 0N/A * @return the view fragment, or itself if the view doesn't 0N/A * support breaking into fragments 0N/A * Provides a way to determine the next visually represented model 0N/A * location that one might place a caret. Some views may not be 0N/A * visible, they might not be in the same order found in the model, or 0N/A * they just might not allow access to some of the locations in the 0N/A * @param pos the position to convert >= 0 0N/A * @param a the allocated region to render into 0N/A * @param direction the direction from the current position that can 0N/A * be thought of as the arrow keys typically found on a keyboard. 0N/A * This may be SwingConstants.WEST, SwingConstants.EAST, 0N/A * SwingConstants.NORTH, or SwingConstants.SOUTH. 0N/A * @return the location within the model that best represents the next 0N/A * location visual position. 0N/A * @exception BadLocationException 0N/A * @exception IllegalArgumentException for an invalid direction 0N/A * Gives notification that something was inserted into 0N/A * the document in a location that this view is responsible for. 0N/A * This is implemented to call preferenceChanged along the 0N/A * axis the glyphs are rendered. 0N/A * @param e the change information from the associated document 0N/A * @param a the current allocation of the view 0N/A * @param f the factory to use to rebuild if the view has children 0N/A * @see View#insertUpdate 0N/A * Gives notification that something was removed from the document 0N/A * in a location that this view is responsible for. 0N/A * This is implemented to call preferenceChanged along the 0N/A * axis the glyphs are rendered. 0N/A * @param e the change information from the associated document 0N/A * @param a the current allocation of the view 0N/A * @param f the factory to use to rebuild if the view has children 0N/A * @see View#removeUpdate 0N/A * Gives notification from the document that attributes were changed 0N/A * in a location that this view is responsible for. 0N/A * This is implemented to call preferenceChanged along both the 0N/A * horizontal and vertical axis. 0N/A * @param e the change information from the associated document 0N/A * @param a the current allocation of the view 0N/A * @param f the factory to use to rebuild if the view has children 0N/A * @see View#changedUpdate 0N/A // checks if the paragraph is empty and updates impliedCR flag 0N/A * Class to hold data needed to justify this GlyphView in a PargraphView.Row 0N/A //justifiable content start 0N/A //justifiable content end 0N/A //states for the parsing 0N/A //we parse conent to the right of the rightmost TAB only. 0N/A //we are looking for the trailing and leading spaces. 0N/A //position after the leading spaces (startContentPosition) 0N/A //position before the trailing spaces (endContentPosition) 0N/A // --- variables ------------------------------------------------ 0N/A * Used by paint() to store highlighted view positions 0N/A // if it is an implied newline character 0N/A * how to expand tabs 0N/A /** Cached minimum x-span value */ 0N/A /** Cached breakpoints within the view */ 0N/A * location for determining tab expansion against. 0N/A * Glyph rendering functionality. 0N/A * The prototype painter used by default. 0N/A * A class to perform rendering of the glyphs. 0N/A * This can be implemented to be stateless, or 0N/A * to hold some information as a cache to 0N/A * translation. At a minimum, the GlyphPainter 0N/A * allows a View implementation to perform its 0N/A * duties independant of a particular version 0N/A * of JVM and selection of capabilities (i.e. 0N/A * shaping for i18n, etc). 0N/A * Determine the span the glyphs given a start location 0N/A * (for tab expansion). 0N/A * Paint the glyphs representing the given range. 0N/A * Provides a mapping from the document model coordinate space 0N/A * to the coordinate space of the view mapped to it. 0N/A * This is shared by the broken views. 0N/A * @param v the <code>GlyphView</code> containing the 0N/A * destination coordinate space 0N/A * @param pos the position to convert 0N/A * @param bias either <code>Position.Bias.Forward</code> 0N/A * or <code>Position.Bias.Backward</code> 0N/A * @param a Bounds of the View 0N/A * @return the bounding box of the given position 0N/A * @exception BadLocationException if the given position does not represent a 0N/A * valid location in the associated document 0N/A * @see View#modelToView 0N/A * Provides a mapping from the view coordinate space to the logical 0N/A * coordinate space of the model. 0N/A * @param v the <code>GlyphView</code> to provide a mapping for 0N/A * @param x the X coordinate 0N/A * @param y the Y coordinate 0N/A * @param a the allocated region to render into 0N/A * @param biasReturn either <code>Position.Bias.Forward</code> 0N/A * or <code>Position.Bias.Backward</code> 0N/A * is returned as the zero-th element of this array 0N/A * @return the location within the model that best represents the 0N/A * given point of view 0N/A * @see View#viewToModel 0N/A * Determines the model location that represents the 0N/A * maximum advance that fits within the given span. 0N/A * This could be used to break the given view. The result 0N/A * should be a location just shy of the given advance. This 0N/A * differs from viewToModel which returns the closest 0N/A * position which might be proud of the maximum advance. 0N/A * @param v the view to find the model location to break at. 0N/A * @param p0 the location in the model where the 0N/A * fragment should start it's representation >= 0. 0N/A * @param x the graphic location along the axis that the 0N/A * broken view would occupy >= 0. This may be useful for 0N/A * things like tab calculations. 0N/A * @param len specifies the distance into the view 0N/A * where a potential break is desired >= 0. 0N/A * @return the maximum model location possible for a break. 0N/A * @see View#breakView 0N/A * Create a painter to use for the given GlyphView. If 0N/A * the painter carries state it can create another painter 0N/A * to represent a new GlyphView that is being created. If 0N/A * the painter doesn't hold any significant state, it can 0N/A * return itself. The default behavior is to return itself. 0N/A * @param v the <code>GlyphView</code> to provide a painter for 0N/A * @param p0 the starting document offset >= 0 0N/A * @param p1 the ending document offset >= p0 0N/A * Provides a way to determine the next visually represented model 0N/A * location that one might place a caret. Some views may not be 0N/A * visible, they might not be in the same order found in the model, or 0N/A * they just might not allow access to some of the locations in the 0N/A * @param v the view to use 0N/A * @param pos the position to convert >= 0 0N/A * @param b either <code>Position.Bias.Forward</code> 0N/A * or <code>Position.Bias.Backward</code> 0N/A * @param a the allocated region to render into 0N/A * @param direction the direction from the current position that can 0N/A * be thought of as the arrow keys typically found on a keyboard. 0N/A * This may be SwingConstants.WEST, SwingConstants.EAST, 0N/A * SwingConstants.NORTH, or SwingConstants.SOUTH. 0N/A * @param biasRet either <code>Position.Bias.Forward</code> 0N/A * or <code>Position.Bias.Backward</code> 0N/A * is returned as the zero-th element of this array 0N/A * @return the location within the model that best represents the next 0N/A * location visual position. 0N/A * @exception BadLocationException 0N/A * @exception IllegalArgumentException for an invalid direction 0N/A // Presumably pos is between startOffset and endOffset, 0N/A // since GlyphView is only one line, we won't contain 0N/A // End case for bidi text where newline is at beginning 0N/A // Assumed not used in bidi text, GlyphPainter2 will 0N/A // override as necessary, therefore return -1. 0N/A // End case for bidi text where newline is at beginning 0N/A // Assumed not used in bidi text, GlyphPainter2 will 0N/A // override as necessary, therefore return -1.