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

📄 textlayout.java

📁 JAVA基本类源代码,大家可以学习学习!
💻 JAVA
📖 第 1 页 / 共 5 页
字号:
/* * @(#)TextLayout.java	1.88 03/01/23 * * Copyright 2003 Sun Microsystems, Inc. All rights reserved. * SUN PROPRIETARY/CONFIDENTIAL. Use is subject to license terms. *//* * (C) Copyright Taligent, Inc. 1996 - 1997, All Rights Reserved * (C) Copyright IBM Corp. 1996 - 1998, All Rights Reserved * * The original version of this source code and documentation is * copyrighted and owned by Taligent, Inc., a wholly-owned subsidiary * of IBM. These materials are provided under terms of a License * Agreement between Taligent and Sun. This technology is protected * by multiple US and International patents. * * This notice and attribution to Taligent may not be removed. * Taligent is a registered trademark of Taligent, Inc. * */package java.awt.font;import java.awt.Color;import java.awt.Font;import java.awt.Graphics2D;import java.awt.Shape;import java.awt.font.NumericShaper;import java.awt.geom.AffineTransform;import java.awt.geom.GeneralPath;import java.awt.geom.Point2D;import java.awt.geom.Rectangle2D;import java.text.AttributedString;import java.text.AttributedCharacterIterator;import java.util.Map;import java.util.HashMap;import java.util.Hashtable;import sun.awt.font.AdvanceCache;import sun.awt.font.Decoration;import sun.awt.font.FontResolver;import sun.awt.font.NativeFontWrapper;import sun.java2d.SunGraphicsEnvironment;/** *  * <code>TextLayout</code> is an immutable graphical representation of styled  * character data. * <p> * It provides the following capabilities: * <ul> * <li>implicit bidirectional analysis and reordering, * <li>cursor positioning and movement, including split cursors for * mixed directional text, * <li>highlighting, including both logical and visual highlighting * for mixed directional text, * <li>multiple baselines (roman, hanging, and centered), * <li>hit testing, * <li>justification, * <li>default font substitution, * <li>metric information such as ascent, descent, and advance, and * <li>rendering * </ul> * <p> * A <code>TextLayout</code> object can be rendered using  * its <code>draw</code> method. * <p> * <code>TextLayout</code> can be constructed either directly or through  * the use of a {@link LineBreakMeasurer}.  When constructed directly, the  * source text represents a single paragraph.  <code>LineBreakMeasurer</code> * allows styled text to be broken into lines that fit within a particular  * width.  See the <code>LineBreakMeasurer</code> documentation for more * information. * <p> * <code>TextLayout</code> construction logically proceeds as follows: * <ul> * <li>paragraph attributes are extracted and examined, * <li>text is analyzed for bidirectional reordering, and reordering * information is computed if needed, * <li>text is segmented into style runs * <li>fonts are chosen for style runs, first by using a font if the * attribute {@link TextAttribute#FONT} is present, otherwise by computing * a default font using the attributes that have been defined * <li>if text is on multiple baselines, the runs or subruns are further * broken into subruns sharing a common baseline, * <li>glyphvectors are generated for each run using the chosen font, * <li>final bidirectional reordering is performed on the glyphvectors * </ul> * <p> * All graphical information returned from a <code>TextLayout</code>  * object's methods is relative to the origin of the  * <code>TextLayout</code>, which is the intersection of the * <code>TextLayout</code> object's baseline with its left edge.  Also,  * coordinates passed into a <code>TextLayout</code> object's methods  * are assumed to be relative to the <code>TextLayout</code> object's * origin.  Clients usually need to translate between a  * <code>TextLayout</code> object's coordinate system and the coordinate * system in another object (such as a  * {@link java.awt.Graphics Graphics} object). * <p> * <code>TextLayout</code> objects are constructed from styled text,  * but they do not retain a reference to their source text.  Thus,  * changes in the text previously used to generate a <code>TextLayout</code> * do not affect the <code>TextLayout</code>. * <p> * Three methods on a <code>TextLayout</code> object  * (<code>getNextRightHit</code>, <code>getNextLeftHit</code>, and  * <code>hitTestChar</code>) return instances of {@link TextHitInfo}.   * The offsets contained in these <code>TextHitInfo</code> objects * are relative to the start of the <code>TextLayout</code>, <b>not</b>  * to the text used to create the <code>TextLayout</code>.  Similarly,  * <code>TextLayout</code> methods that accept <code>TextHitInfo</code> * instances as parameters expect the <code>TextHitInfo</code> object's  * offsets to be relative to the <code>TextLayout</code>, not to any  * underlying text storage model. * <p> * <strong>Examples</strong>:<p> * Constructing and drawing a <code>TextLayout</code> and its bounding  * rectangle: * <blockquote><pre> *   Graphics2D g = ...; *   Point2D loc = ...; *   Font font = Font.getFont("Helvetica-bold-italic"); *   FontRenderContext frc = g.getFontRenderContext(); *   TextLayout layout = new TextLayout("This is a string", font, frc); *   layout.draw(g, (float)loc.getX(), (float)loc.getY()); * *   Rectangle2D bounds = layout.getBounds(); *   bounds.setRect(bounds.getX()+loc.getX(), *                  bounds.getY()+loc.getY(), *                  bounds.getWidth(), *                  bounds.getHeight()); *   g.draw(bounds); * </pre> * </blockquote> * <p> * Hit-testing a <code>TextLayout</code> (determining which character is at * a particular graphical location): * <blockquote><pre> *   Point2D click = ...; *   TextHitInfo hit = layout.hitTestChar( *                         (float) (click.getX() - loc.getX()), *                         (float) (click.getY() - loc.getY())); * </pre> * </blockquote> * <p> * Responding to a right-arrow key press: * <blockquote><pre> *   int insertionIndex = ...; *   TextHitInfo next = layout.getNextRightHit(insertionIndex); *   if (next != null) { *       // translate graphics to origin of layout on screen *       g.translate(loc.getX(), loc.getY()); *       Shape[] carets = layout.getCaretShapes(next.getInsertionIndex()); *       g.draw(carets[0]); *       if (carets[1] != null) { *           g.draw(carets[1]); *       } *   } * </pre></blockquote> * <p> * Drawing a selection range corresponding to a substring in the source text. * The selected area may not be visually contiguous: * <blockquote><pre> *   // selStart, selLimit should be relative to the layout, *   // not to the source text * *   int selStart = ..., selLimit = ...; *   Color selectionColor = ...; *   Shape selection = layout.getLogicalHighlightShape(selStart, selLimit); *   // selection may consist of disjoint areas *   // graphics is assumed to be tranlated to origin of layout *   g.setColor(selectionColor); *   g.fill(selection); * </pre></blockquote> * <p> * Drawing a visually contiguous selection range.  The selection range may * correspond to more than one substring in the source text.  The ranges of * the corresponding source text substrings can be obtained with * <code>getLogicalRangesForVisualSelection()</code>: * <blockquote><pre> *   TextHitInfo selStart = ..., selLimit = ...; *   Shape selection = layout.getVisualHighlightShape(selStart, selLimit); *   g.setColor(selectionColor); *   g.fill(selection); *   int[] ranges = getLogicalRangesForVisualSelection(selStart, selLimit); *   // ranges[0], ranges[1] is the first selection range, *   // ranges[2], ranges[3] is the second selection range, etc. * </pre></blockquote> * <p> * @see LineBreakMeasurer * @see TextAttribute * @see TextHitInfo */public final class TextLayout implements Cloneable {    private int characterCount;    private boolean isVerticalLine = false;    private byte baseline;    private float[] baselineOffsets;  // why have these ?    private TextLine textLine;    // cached values computed from GlyphSets and set info:    // all are recomputed from scratch in buildCache()    private TextLine.TextLineMetrics lineMetrics = null;    private float visibleAdvance;    private int hashCodeCache;    /**     * temporary optimization     */    static class OptInfo implements Decoration.Label {        private static final float MAGIC_ADVANCE = -12345.67f;        // cache of required information for TextLine construction        private FontRenderContext frc;        private char[] chars;        private Font font;        private LineMetrics metrics;        private Map attrs;        // deferred initialization         private float advance;	private Rectangle2D vb;        private Decoration decoration;        private String str;        private OptInfo(FontRenderContext frc, char[] chars, Font font, LineMetrics metrics, Map attrs) {            this.frc = frc;            this.chars = chars;            this.font = font;            this.metrics = metrics;            this.attrs = attrs;	    if (attrs != null) {		this.attrs = new HashMap(attrs); // sigh, need to clone since might change...	    }            this.advance = MAGIC_ADVANCE;        }        TextLine createTextLine() {            return TextLine.fastCreateTextLine(frc, chars, font, metrics, attrs);        }        float getAdvance() {            if (advance == MAGIC_ADVANCE) {                AdvanceCache adv = AdvanceCache.get(font, frc);                advance = adv.getAdvance(chars, 0, chars.length); // we pretested the chars array so no exception here            }            return advance;        }        // Decoration.Label reqd.        public LineMetrics getLineMetrics() {            return metrics;        }        // Decoration.Label reqd.        public Rectangle2D getLogicalBounds() {            return new Rectangle2D.Float(0, -metrics.getAscent(), getAdvance(), metrics.getHeight());        }        // Decoration.Label reqd.        public void handleDraw(Graphics2D g2d, float x, float y) {            if (str == null) {                str = new String(chars, 0, chars.length);            }            g2d.drawString(str, x , y);        }        // Decoration.Label reqd.        public Rectangle2D handleGetCharVisualBounds(int index) {            // not used            throw new InternalError();        }        // Decoration.Label reqd.        public Rectangle2D handleGetVisualBounds() {	    AdvanceCache adv = AdvanceCache.get(font, frc);	    return adv.getVisualBounds(chars, 0, chars.length);        }        // Decoration.Label reqd.        public Shape handleGetOutline(float x, float y) {            // not used            throw new InternalError();        }        // if we could successfully draw, then return true        boolean draw(Graphics2D g2d, float x, float y) {            // If the frc differs from the graphics frc, we punt to TextLayout because the            // metrics might be different...            if (g2d.getFontRenderContext().equals(frc)) {                Font oldFont = g2d.getFont();                g2d.setFont(font);                                    getDecoration().drawTextAndDecorations(this, g2d, x, y);                g2d.setFont(oldFont);                return true;            }            return false;        }	Rectangle2D getVisualBounds() {	    if (vb == null) {		vb = getDecoration().getVisualBounds(this);	    }	    return (Rectangle2D)vb.clone();	}	Decoration getDecoration() {	    if (decoration == null) {		if (attrs == null) {		    decoration = Decoration.getDecoration(null);		} else {		    decoration = Decoration.getDecoration(StyledParagraph.addInputMethodAttrs(attrs));		}	    }	    return decoration;	}        static OptInfo create(FontRenderContext frc, char[] chars, Font font, LineMetrics metrics, Map attrs) {            // Preflight text to make sure advance cache supports it, otherwise it would throw an exception.            // We also need to preflight to make sure we don't require layout.  If we limit optimizations to            // latin-1 we handle both cases.  We could add an additional check for Japanese since currently            // it doesn't require layout and the advance cache would be simple, but right now we don't.            if (!font.isTransformed() && AdvanceCache.supportsText(chars)) {		if (attrs == null || attrs.get(TextAttribute.CHAR_REPLACEMENT) == null) {		    return new OptInfo(frc, chars, font, metrics, attrs);		}            }            return null;        }    }    private OptInfo optInfo;    /*     * TextLayouts are supposedly immutable.  If you mutate a TextLayout under     * the covers (like the justification code does) you'll need to set this     * back to false.  Could be replaced with textLine != null <--> cacheIsValid.     */    private boolean cacheIsValid = false;    // This value is obtained from an attribute, and constrained to the    // interval [0,1].  If 0, the layout cannot be justified.    private float justifyRatio;    // If a layout is produced by justification, then that layout    // cannot be justified.  To enforce this constraint the

⌨️ 快捷键说明

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