Search in sources :

Example 1 with AttributedStringCharacterIterator

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

the class TextPaneSkin method getCaretRectangle.

private Rectangle getCaretRectangle(TextHitInfo textCaret) {
    TextPane textPane = getTextPane();
    AttributedStringCharacterIterator composedText = textPane.getComposedText();
    // Special case that tweaks the bounds at the end of line so that the entire
    // composed text width isn't added in here.... (yeah, I know it's ugly...)
    int selectionStart = textPane.getSelectionStart();
    this.doingCaretCalculations = true;
    Bounds selectionStartBounds = getCharacterBounds(selectionStart);
    this.doingCaretCalculations = false;
    // without the "doingCaretCalculations" flag to get back something non-null
    if (selectionStartBounds == null) {
        selectionStartBounds = getCharacterBounds(selectionStart);
        org.apache.pivot.util.Console.logMethod("****", "null selection bounds: selectionStart=%1$d, updated bounds=%2$s", selectionStart, selectionStartBounds);
    }
    return GraphicsUtilities.getCaretRectangle(textCaret, composedText, selectionStartBounds.x, selectionStartBounds.y);
}
Also used : TextPane(org.apache.pivot.wtk.TextPane) Bounds(org.apache.pivot.wtk.Bounds) AttributedStringCharacterIterator(org.apache.pivot.text.AttributedStringCharacterIterator)

Example 2 with AttributedStringCharacterIterator

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

the class TextPaneSkinTextNodeView method getPreferredSize.

@Override
public Dimensions getPreferredSize(int breakWidth) {
    TextNode textNode = (TextNode) getNode();
    Font effectiveFont = getEffectiveFont();
    // For now, just get the committed text
    if (textNode.getCharacterCount() == 0) /* && composedText == null || composedText doesn't impinge on this node */
    {
        Dimensions charSize = GraphicsUtilities.getAverageCharacterSize(effectiveFont);
        return new Dimensions(0, charSize.height);
    } else {
        FontRenderContext fontRenderContext = Platform.getFontRenderContext();
        // TODO: deal with composed text here
        AttributedCharacterIterator text = new AttributedStringCharacterIterator(textNode.getCharacters(), start, effectiveFont);
        // Note: we don't add the underline/strikethrough attributes here because
        // they shouldn't affect the sizing...
        TextLayout currentTextLayout;
        if (getTextPaneSkin().getWrapText()) {
            LineBreakMeasurer measurer = new LineBreakMeasurer(text, fontRenderContext);
            float wrappingWidth = (float) breakWidth;
            currentTextLayout = measurer.nextLayout(wrappingWidth);
        } else {
            // Not wrapping the text, then the width is of the whole thing
            currentTextLayout = new TextLayout(text, fontRenderContext);
        }
        return getTextSize(currentTextLayout);
    }
}
Also used : LineBreakMeasurer(java.awt.font.LineBreakMeasurer) Dimensions(org.apache.pivot.wtk.Dimensions) TextNode(org.apache.pivot.wtk.text.TextNode) FontRenderContext(java.awt.font.FontRenderContext) Font(java.awt.Font) AttributedCharacterIterator(java.text.AttributedCharacterIterator) AttributedStringCharacterIterator(org.apache.pivot.text.AttributedStringCharacterIterator) TextLayout(java.awt.font.TextLayout)

Example 3 with AttributedStringCharacterIterator

use of org.apache.pivot.text.AttributedStringCharacterIterator 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 4 with AttributedStringCharacterIterator

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

the class TerraTextInputSkin method paint.

@Override
public void paint(Graphics2D graphics) {
    TextInput textInput = (TextInput) getComponent();
    int width = getWidth();
    int height = getHeight();
    Color backgroundColorLocal;
    Color borderColorLocal;
    Color bevelColorLocal;
    if (textInput.isEnabled()) {
        if (textInput.isTextValid()) {
            backgroundColorLocal = this.backgroundColor;
            bevelColorLocal = this.bevelColor;
        } else {
            backgroundColorLocal = invalidBackgroundColor;
            bevelColorLocal = invalidBevelColor;
        }
        borderColorLocal = this.borderColor;
    } else {
        backgroundColorLocal = disabledBackgroundColor;
        borderColorLocal = disabledBorderColor;
        bevelColorLocal = disabledBevelColor;
    }
    graphics.setStroke(new BasicStroke());
    // Paint the background
    graphics.setColor(backgroundColorLocal);
    graphics.fillRect(0, 0, width, height);
    if (!themeIsFlat()) {
        // Paint the bevel
        graphics.setColor(bevelColorLocal);
        GraphicsUtilities.drawLine(graphics, 0, 0, width, Orientation.HORIZONTAL);
    }
    // Paint the content
    FontRenderContext fontRenderContext = Platform.getFontRenderContext();
    LineMetrics lm = font.getLineMetrics("", fontRenderContext);
    float ascent = lm.getAscent();
    float textHeight = lm.getHeight();
    String prompt = textInput.getPrompt();
    Color caretColor;
    TextLayout drawingTextLayout = textLayout;
    if (textLayout == null && prompt != null && !prompt.isEmpty()) {
        AttributedStringCharacterIterator promptText = new AttributedStringCharacterIterator(prompt);
        drawingTextLayout = new TextLayout(promptText, fontRenderContext);
    }
    int alignmentDeltaX = getAlignmentDeltaX(drawingTextLayout);
    int xpos = padding.left - scrollLeft + 1 + alignmentDeltaX;
    if (textLayout == null && prompt != null && !prompt.isEmpty()) {
        GraphicsUtilities.prepareForText(graphics, fontRenderContext, font, promptColor);
        graphics.drawString(prompt, xpos, (height - textHeight) / 2 + ascent);
        caretColor = color;
    } else {
        boolean textValid = textInput.isTextValid();
        Color colorLocal;
        if (textInput.isEnabled()) {
            if (!textValid) {
                colorLocal = invalidColor;
            } else {
                colorLocal = this.color;
            }
        } else {
            colorLocal = disabledColor;
        }
        caretColor = colorLocal;
        if (textLayout != null) {
            graphics.setFont(font);
            float ypos = (height - textHeight) / 2 + ascent;
            if (selection == null) {
                // Paint the text
                graphics.setColor(colorLocal);
                textLayout.draw(graphics, xpos, ypos);
            } else {
                // Paint the unselected text
                Area unselectedArea = new Area();
                unselectedArea.add(new Area(new Rectangle(0, 0, width, height)));
                unselectedArea.subtract(new Area(selection));
                Graphics2D textGraphics = (Graphics2D) graphics.create();
                textGraphics.setColor(colorLocal);
                textGraphics.clip(unselectedArea);
                textLayout.draw(textGraphics, xpos, ypos);
                textGraphics.dispose();
                // Paint the selection
                Color selectionColorLocal;
                Color selectionBackgroundColorLocal;
                if (textInput.isFocused() && textInput.isEditable()) {
                    selectionColorLocal = this.selectionColor;
                    selectionBackgroundColorLocal = this.selectionBackgroundColor;
                } else {
                    selectionColorLocal = inactiveSelectionColor;
                    selectionBackgroundColorLocal = inactiveSelectionBackgroundColor;
                }
                graphics.setColor(selectionBackgroundColorLocal);
                graphics.fill(selection);
                Graphics2D selectedTextGraphics = (Graphics2D) graphics.create();
                selectedTextGraphics.setColor(selectionColorLocal);
                selectedTextGraphics.clip(selection.getBounds());
                textLayout.draw(selectedTextGraphics, xpos, ypos);
                selectedTextGraphics.dispose();
            }
        }
    }
    // Paint the caret
    if (selection == null && caretOn && textInput.isFocused()) {
        graphics.setColor(caretColor);
        graphics.fill(caret);
    }
    if (!themeIsFlat()) {
        // Paint the border
        graphics.setColor(borderColorLocal);
        GraphicsUtilities.drawRect(graphics, 0, 0, width, height);
    }
}
Also used : BasicStroke(java.awt.BasicStroke) Color(java.awt.Color) Rectangle(java.awt.Rectangle) TextLayout(java.awt.font.TextLayout) AttributedStringCharacterIterator(org.apache.pivot.text.AttributedStringCharacterIterator) Graphics2D(java.awt.Graphics2D) Area(java.awt.geom.Area) FontRenderContext(java.awt.font.FontRenderContext) LineMetrics(java.awt.font.LineMetrics) TextInput(org.apache.pivot.wtk.TextInput)

Example 5 with AttributedStringCharacterIterator

use of org.apache.pivot.text.AttributedStringCharacterIterator 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

AttributedStringCharacterIterator (org.apache.pivot.text.AttributedStringCharacterIterator)6 FontRenderContext (java.awt.font.FontRenderContext)4 TextLayout (java.awt.font.TextLayout)4 AttributedCharacterIterator (java.text.AttributedCharacterIterator)3 TextInput (org.apache.pivot.wtk.TextInput)3 Font (java.awt.Font)2 LineBreakMeasurer (java.awt.font.LineBreakMeasurer)2 CompositeIterator (org.apache.pivot.text.CompositeIterator)2 Bounds (org.apache.pivot.wtk.Bounds)2 Dimensions (org.apache.pivot.wtk.Dimensions)2 TextPane (org.apache.pivot.wtk.TextPane)2 TextNode (org.apache.pivot.wtk.text.TextNode)2 BasicStroke (java.awt.BasicStroke)1 Color (java.awt.Color)1 Graphics2D (java.awt.Graphics2D)1 Rectangle (java.awt.Rectangle)1 LineMetrics (java.awt.font.LineMetrics)1 Area (java.awt.geom.Area)1 Span (org.apache.pivot.wtk.Span)1 Element (org.apache.pivot.wtk.text.Element)1