Search in sources :

Example 1 with CompositeIterator

use of org.apache.pivot.text.CompositeIterator in project pivot by apache.

the class TextPaneSkinTextNodeView method childLayout.

@Override
protected void childLayout(int breakWidth) {
    TextNode textNode = (TextNode) getNode();
    textLayout = null;
    Font effectiveFont = getEffectiveFont();
    FontRenderContext fontRenderContext = Platform.getFontRenderContext();
    TextPane textPane = (TextPane) getTextPaneSkin().getComponent();
    AttributedStringCharacterIterator composedText = textPane.getComposedText();
    Element parent = textNode.getParent();
    // The calculations below really need to know if we're at the end of the paragraph
    // when composing text, so make sure we ignore intervening span or other nodes, but
    // also update the offset relative to the paragraph in the process.
    int relStart = start;
    if (parent != null && !(parent instanceof Paragraph)) {
        relStart += parent.getOffset();
        parent = parent.getParent();
    }
    int parentCount = parent == null ? 0 : parent.getCharacterCount();
    int selectionStart = textPane.getSelectionStart();
    int selectionLength = textPane.getSelectionLength();
    int documentOffset = textNode.getDocumentOffset();
    int charCount = textNode.getCharacterCount();
    boolean composedIntersects = false;
    if (composedText != null) {
        int composedTextBegin = composedText.getBeginIndex();
        int composedTextEnd = composedText.getEndIndex();
        int composedTextLength = composedTextEnd - composedTextBegin;
        /* exclusive - inclusive, so no +1 needed */
        // If this text node is at the end of a paragraph, increase the span by 1 for the newline
        Span ourSpan;
        if (parent instanceof Paragraph && charCount + relStart == parentCount - 1) {
            ourSpan = new Span(documentOffset + start, documentOffset + charCount);
        } else {
            ourSpan = new Span(documentOffset + start, documentOffset + charCount - 1);
        }
        // The "composed span" just encompasses the start position, because this is "phantom" text, so it exists between any two other "real" text positions.
        Span composedSpan = new Span(selectionStart + composedTextBegin);
        composedIntersects = composedSpan.intersects(ourSpan);
    }
    if (charCount == 0 && !composedIntersects) {
        Dimensions charSize = GraphicsUtilities.getAverageCharacterSize(effectiveFont);
        setSize(0, charSize.height);
        length = 0;
        next = null;
    } else {
        AttributedCharacterIterator text = null;
        boolean underlined = getEffectiveUnderline();
        boolean struckthrough = getEffectiveStrikethrough();
        if (composedText != null && composedIntersects) {
            int composedPos = selectionStart - documentOffset;
            if (composedPos == 0) {
                if (charCount - start == 0) {
                    text = composedText;
                } else {
                    AttributedStringCharacterIterator fullText = getCharIterator(textNode, start, charCount, effectiveFont);
                    // Note: only apply the underline and strikethrough to our text, not the composed text
                    fullText.addUnderlineAttribute(underlined);
                    fullText.addStrikethroughAttribute(struckthrough);
                    text = new CompositeIterator(composedText, fullText);
                }
            } else if (composedPos == charCount) {
                // Composed text is at the end
                AttributedStringCharacterIterator fullText = getCharIterator(textNode, start, charCount, effectiveFont);
                // Note: only apply the underline and strikethrough to our text, not the composed text
                fullText.addUnderlineAttribute(underlined);
                fullText.addStrikethroughAttribute(struckthrough);
                text = new CompositeIterator(fullText, composedText);
            } else {
                // Composed text is somewhere in the middle
                AttributedStringCharacterIterator leadingText = getCharIterator(textNode, start, composedPos, effectiveFont);
                leadingText.addUnderlineAttribute(underlined);
                leadingText.addStrikethroughAttribute(struckthrough);
                AttributedStringCharacterIterator trailingText = getCharIterator(textNode, composedPos, charCount, effectiveFont);
                trailingText.addUnderlineAttribute(underlined);
                trailingText.addStrikethroughAttribute(struckthrough);
                text = new CompositeIterator(leadingText, composedText, trailingText);
            }
        } else {
            AttributedStringCharacterIterator fullText = getCharIterator(textNode, start, charCount, effectiveFont);
            fullText.addUnderlineAttribute(underlined);
            fullText.addStrikethroughAttribute(struckthrough);
            text = fullText;
        }
        if (getTextPaneSkin().getWrapText()) {
            LineBreakMeasurer measurer = new LineBreakMeasurer(text, fontRenderContext);
            float wrappingWidth = (float) breakWidth;
            textLayout = measurer.nextLayout(wrappingWidth);
            length = textLayout.getCharacterCount();
            Dimensions size = getTextSize(textLayout);
            float advance = textLayout.getAdvance();
            setSize(size);
            if (start + measurer.getPosition() < textNode.getCharacterCount()) {
                next = new TextPaneSkinTextNodeView(getTextPaneSkin(), textNode, start + measurer.getPosition());
                next.setParent(getParent());
            } else {
                next = null;
            }
        } else {
            // Not wrapping the text, then the width is of the whole thing
            textLayout = new TextLayout(text, fontRenderContext);
            length = textLayout.getCharacterCount();
            Dimensions size = getTextSize(textLayout);
            float advance = textLayout.getAdvance();
            setSize(size);
            // set to null in case this node used to be broken across multiple,
            // but is no longer
            next = null;
        }
    }
}
Also used : CompositeIterator(org.apache.pivot.text.CompositeIterator) Element(org.apache.pivot.wtk.text.Element) LineBreakMeasurer(java.awt.font.LineBreakMeasurer) Dimensions(org.apache.pivot.wtk.Dimensions) TextNode(org.apache.pivot.wtk.text.TextNode) Span(org.apache.pivot.wtk.Span) TextSpan(org.apache.pivot.wtk.text.TextSpan) Font(java.awt.Font) AttributedStringCharacterIterator(org.apache.pivot.text.AttributedStringCharacterIterator) Paragraph(org.apache.pivot.wtk.text.Paragraph) AttributedCharacterIterator(java.text.AttributedCharacterIterator) TextLayout(java.awt.font.TextLayout) TextPane(org.apache.pivot.wtk.TextPane) FontRenderContext(java.awt.font.FontRenderContext)

Example 2 with CompositeIterator

use of org.apache.pivot.text.CompositeIterator in project pivot by apache.

the class TerraTextInputSkin method layout.

@Override
public void layout() {
    TextInput textInput = (TextInput) getComponent();
    textLayout = null;
    int n = textInput.getCharacterCount();
    AttributedStringCharacterIterator composedText = textInput.getComposedText();
    if (n > 0 || composedText != null) {
        AttributedCharacterIterator text = null;
        if (n > 0) {
            int insertPos = textInput.getSelectionStart();
            if (composedText == null) {
                text = getCharIterator(textInput, 0, n);
            } else if (insertPos == n) {
                // The composed text position is the end of the committed text
                text = new CompositeIterator(getCharIterator(textInput, 0, n), composedText);
            } else if (insertPos == 0) {
                text = new CompositeIterator(composedText, getCharIterator(textInput, 0, n));
            } else {
                // The composed text is somewhere in the middle of the text
                text = new CompositeIterator(getCharIterator(textInput, 0, insertPos), composedText, getCharIterator(textInput, insertPos, n));
            }
        } else {
            text = composedText;
        }
        FontRenderContext fontRenderContext = Platform.getFontRenderContext();
        textLayout = new TextLayout(text, fontRenderContext);
        int textWidth = getTextWidth(textLayout);
        int width = getWidth();
        if (textWidth - scrollLeft + padding.left + 1 < width - padding.right - 1) {
            // The right edge of the text is less than the right inset;
            // align the text's right edge with the inset
            scrollLeft = Math.max(textWidth + padding.getWidth() + 2 - width, 0);
        } else {
            // Scroll selection start to visible
            int selectionStart = textInput.getSelectionStart();
            if (textInput.isFocused()) {
                if (composedVisiblePosition != null) {
                    scrollCharacterToVisible(selectionStart + composedVisiblePosition.getInsertionIndex());
                } else {
                    if (selectionStart <= n) {
                        scrollCharacterToVisible(selectionStart);
                    }
                }
            }
        }
    } else {
        scrollLeft = 0;
    }
    updateSelection();
    showCaret(textInput.isFocused() && textInput.getSelectionLength() == 0);
}
Also used : CompositeIterator(org.apache.pivot.text.CompositeIterator) FontRenderContext(java.awt.font.FontRenderContext) TextInput(org.apache.pivot.wtk.TextInput) AttributedStringCharacterIterator(org.apache.pivot.text.AttributedStringCharacterIterator) AttributedCharacterIterator(java.text.AttributedCharacterIterator) TextLayout(java.awt.font.TextLayout)

Aggregations

FontRenderContext (java.awt.font.FontRenderContext)2 TextLayout (java.awt.font.TextLayout)2 AttributedCharacterIterator (java.text.AttributedCharacterIterator)2 AttributedStringCharacterIterator (org.apache.pivot.text.AttributedStringCharacterIterator)2 CompositeIterator (org.apache.pivot.text.CompositeIterator)2 Font (java.awt.Font)1 LineBreakMeasurer (java.awt.font.LineBreakMeasurer)1 Dimensions (org.apache.pivot.wtk.Dimensions)1 Span (org.apache.pivot.wtk.Span)1 TextInput (org.apache.pivot.wtk.TextInput)1 TextPane (org.apache.pivot.wtk.TextPane)1 Element (org.apache.pivot.wtk.text.Element)1 Paragraph (org.apache.pivot.wtk.text.Paragraph)1 TextNode (org.apache.pivot.wtk.text.TextNode)1 TextSpan (org.apache.pivot.wtk.text.TextSpan)1