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

📄 textlayout.java

📁 JAVA基本类源代码,大家可以学习学习!
💻 JAVA
📖 第 1 页 / 共 5 页
字号:
        // set paragraph attributes        {            // If there's an embedded graphic at the start of the            // paragraph, look for the first non-graphic character            // and use it and its font to initialize the paragraph.            // If not, use the first graphic to initialize.            Map paragraphAttrs = text.getAttributes();            boolean haveFont = TextLine.advanceToFirstFont(text);            if (haveFont) {                Font defaultFont = TextLine.getFontAtCurrentPos(text);                int charsStart = text.getIndex() - text.getBeginIndex();                LineMetrics lm = defaultFont.getLineMetrics(chars, charsStart, charsStart+1, frc);                paragraphInit((byte)lm.getBaselineIndex(), lm, paragraphAttrs, chars);            }            else {                // hmmm what to do here?  Just try to supply reasonable                // values I guess.                GraphicAttribute graphic = (GraphicAttribute)                                paragraphAttrs.get(TextAttribute.CHAR_REPLACEMENT);                byte defaultBaseline = getBaselineFromGraphic(graphic);                Font dummyFont = new Font(new Hashtable(5, (float)0.9));                LineMetrics lm = dummyFont.getLineMetrics(" ", 0, 1, frc);                paragraphInit(defaultBaseline, lm, paragraphAttrs, chars);            }        }        textLine = TextLine.standardCreateTextLine(frc, text, chars, baselineOffsets);    }    /*     * A utility to rebuild the ascent/descent/leading/advance cache.     * You'll need to call this if you clone and mutate (like justification,     * editing methods do)     */    private void ensureCache() {        if (!cacheIsValid) {            buildCache();        }    }    private void buildCache() {        if (textLine == null) {            initTextLine();        }        lineMetrics = textLine.getMetrics();        // compute visibleAdvance        if (textLine.isDirectionLTR()) {            int lastNonSpace = characterCount-1;            while (lastNonSpace != -1) {                int logIndex = textLine.visualToLogical(lastNonSpace);                if (!textLine.isCharSpace(logIndex)) {                    break;                }                else {                    --lastNonSpace;                }            }            if (lastNonSpace == characterCount-1) {                visibleAdvance = lineMetrics.advance;            }            else if (lastNonSpace == -1) {                visibleAdvance = 0;            }            else {                int logIndex = textLine.visualToLogical(lastNonSpace);                visibleAdvance = textLine.getCharLinePosition(logIndex)                                        + textLine.getCharAdvance(logIndex);            }        }        else {            int leftmostNonSpace = 0;            while (leftmostNonSpace != characterCount) {                int logIndex = textLine.visualToLogical(leftmostNonSpace);                if (!textLine.isCharSpace(logIndex)) {                    break;                }                else {                    ++leftmostNonSpace;                }            }            if (leftmostNonSpace == characterCount) {                visibleAdvance = 0;            }            else if (leftmostNonSpace == 0) {                visibleAdvance = lineMetrics.advance;            }            else {                int logIndex = textLine.visualToLogical(leftmostNonSpace);                float pos = textLine.getCharLinePosition(logIndex);                visibleAdvance = lineMetrics.advance - pos;            }        }        // naturalBounds, boundsRect will be generated on demand        naturalBounds = null;        boundsRect = null;        // hashCode will be regenerated on demand        hashCodeCache = 0;        cacheIsValid = true;    }    private Rectangle2D getNaturalBounds() {        ensureCache();        if (naturalBounds == null) {            int leftmostCharIndex = textLine.visualToLogical(0);            float angle = textLine.getCharAngle(leftmostCharIndex);            float leftOrTop = isVerticalLine? -dy : -dx;            if (angle < 0) {                leftOrTop += angle*textLine.getCharAscent(leftmostCharIndex);            }            else if (angle > 0) {                leftOrTop -= angle*textLine.getCharDescent(leftmostCharIndex);            }            int rightmostCharIndex = textLine.visualToLogical(characterCount-1);            angle = textLine.getCharAngle(rightmostCharIndex);            float rightOrBottom = lineMetrics.advance;            if (angle < 0) {                rightOrBottom -=                            angle*textLine.getCharDescent(rightmostCharIndex);            }            else if (angle > 0) {                rightOrBottom +=                            angle*textLine.getCharAscent(rightmostCharIndex);            }            float lineDim = rightOrBottom - leftOrTop;            if (isVerticalLine) {                naturalBounds = new Rectangle2D.Float(                            -lineMetrics.descent, leftOrTop,                            lineMetrics.ascent + lineMetrics.descent, lineDim);            }            else {                naturalBounds = new Rectangle2D.Float(                            leftOrTop, -lineMetrics.ascent,                            lineDim, lineMetrics.ascent + lineMetrics.descent);            }        }        return naturalBounds;    }    /**     * Creates a copy of this <code>TextLayout</code>.     */    protected Object clone() {        /*         * !!! I think this is safe.  Once created, nothing mutates the         * glyphvectors or arrays.  But we need to make sure.         * {jbr} actually, that's not quite true.  The justification code         * mutates after cloning.  It doesn't actually change the glyphvectors         * (that's impossible) but it replaces them with justified sets.  This         * is a problem for GlyphIterator creation, since new GlyphIterators         * are created by cloning a prototype.  If the prototype has outdated         * glyphvectors, so will the new ones.  A partial solution is to set the         * prototypical GlyphIterator to null when the glyphvectors change.  If         * you forget this one time, you're hosed.         */        try {            return super.clone();        }        catch (CloneNotSupportedException e) {            throw new InternalError();        }    }    /*     * Utility to throw an expection if an invalid TextHitInfo is passed     * as a parameter.  Avoids code duplication.     */    private void checkTextHit(TextHitInfo hit) {        if (hit == null) {            throw new IllegalArgumentException("TextHitInfo is null.");        }        if (hit.getInsertionIndex() < 0 ||            hit.getInsertionIndex() > characterCount) {            throw new IllegalArgumentException("TextHitInfo is out of range");        }    }    /**     * Creates a copy of this <code>TextLayout</code> justified to the      * specified width.     * <p>     * If this <code>TextLayout</code> has already been justified, an     * exception is thrown.  If this <code>TextLayout</code> object's      * justification ratio is zero, a <code>TextLayout</code> identical      * to this <code>TextLayout</code> is returned.     * @param justificationWidth the width to use when justifying the line.     * For best results, it should not be too different from the current     * advance of the line.     * @return a <code>TextLayout</code> justified to the specified width.     * @exception Error if this layout has already been justified, an Error is     * thrown.     */    public TextLayout getJustifiedLayout(float justificationWidth) {        if (justificationWidth <= 0) {            throw new IllegalArgumentException("justificationWidth <= 0 passed to TextLayout.getJustifiedLayout()");        }        if (justifyRatio == ALREADY_JUSTIFIED) {            throw new Error("Can't justify again.");        }	ensureCache(); // make sure textLine is not null        // default justification range to exclude trailing logical whitespace        int limit = characterCount;        while (limit > 0 && textLine.isCharWhitespace(limit-1)) {            --limit;        }        TextLine newLine = textLine.getJustifiedLine(justificationWidth, justifyRatio, 0, limit);        if (newLine != null) {            return new TextLayout(newLine, baseline, baselineOffsets, ALREADY_JUSTIFIED);        }        return this;    }    /**     * Justify this layout.  Overridden by subclassers to control justification     * (if there were subclassers, that is...)     *     * The layout will only justify if the paragraph attributes (from the     * source text, possibly defaulted by the layout attributes) indicate a     * non-zero justification ratio.  The text will be justified to the     * indicated width.  The current implementation also adjusts hanging     * punctuation and trailing whitespace to overhang the justification width.     * Once justified, the layout may not be rejustified.     * <p>     * Some code may rely on immutablity of layouts.  Subclassers should not     * call this directly, but instead should call getJustifiedLayout, which     * will call this method on a clone of this layout, preserving     * the original.     *     * @param justificationWidth the width to use when justifying the line.     * For best results, it should not be too different from the current     * advance of the line.     * @see #getJustifiedLayout(float)     */    protected void handleJustify(float justificationWidth) {      // never called    }    /**     * Returns the baseline for this <code>TextLayout</code>.     * The baseline is one of the values defined in <code>Font</code>,     * which are roman, centered and hanging.  Ascent and descent are     * relative to this baseline.  The <code>baselineOffsets</code>     * are also relative to this baseline.     * @return the baseline of this <code>TextLayout</code>.     * @see #getBaselineOffsets()     * @see Font     */    public byte getBaseline() {        return baseline;    }    /**     * Returns the offsets array for the baselines used for this      * <code>TextLayout</code>.     * <p>     * The array is indexed by one of the values defined in      * <code>Font</code>, which are roman, centered and hanging.  The      * values are relative to this <code>TextLayout</code> object's      * baseline, so that <code>getBaselineOffsets[getBaseline()] == 0</code>.     * Offsets are added to the position of the <code>TextLayout</code>      * object's baseline to get the position for the new baseline.     * @return the offsets array containing the baselines used for this     *    <code>TextLayout</code>.     * @see #getBaseline()     * @see Font     */    public float[] getBaselineOffsets() {        float[] offsets = new float[baselineOffsets.length];        System.arraycopy(baselineOffsets, 0, offsets, 0, offsets.length);        return offsets;    }    /**     * Returns the advance of this <code>TextLayout</code>.     * The advance is the distance from the origin to the advance of the     * rightmost (bottommost) character measuring in the line direction.     * @return the advance of this <code>TextLayout</code>.     */    public float getAdvance() {        if (optInfo != null) {            try {                return optInfo.getAdvance();            }            catch (Error e) {                // cache was flushed under optInfo            }        }        ensureCache();        return lineMetrics.advance;    }    /**     * Returns the advance of this <code>TextLayout</code>, minus trailing      * whitespace.     * @return the advance of this <code>TextLayout</code> without the     *      trailing whitespace.     * @see #getAdvance()     */    public float getVisibleAdvance() {        ensureCache();        return visibleAdvance;    }    /**     * Returns the ascent of this <code>TextLayout</code>.     * The ascent is the distance from the top (right) of the      * <code>TextLayout</code> to the baseline.  It is always either      * positive or zero.  The ascent is sufficient to     * accomodate superscripted text and is the maximum of the sum of the     * ascent, offset, and baseline of each glyph.     * @return the ascent of this <code>TextLayout</code>.     */    public float getAscent() {        if (optInfo != null) {            return optInfo.getLineMetrics().getAscent();        }        ensureCache();        return lineMetrics.ascent;    }    /**     * Returns the descent of this <code>TextLayout</code>.     * The descent is the distance from the baseline to the bottom (left) of     * the <code>TextLayout</code>.  It is always either positive or zero.       * The descent is sufficient to accomodate subscripted text and is the      * maximum of the sum of the descent, offset, and baseline of each glyph.     * @return the descent of this <code>TextLayout</code>.     */

⌨️ 快捷键说明

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