/** * Converts an offset in a line into an x co-ordinate. This is a fast version that should only be * used if no changes were made to the text since the last repaint. * * @param line The line * @param offset The offset, from the start of the line */ public int _offsetToX(int line, int offset) { TokenMarker tokenMarker = getTokenMarker(); /* Use painter's cached info for speed */ FontMetrics fm = painter.getFontMetrics(); getLineText(line, lineSegment); int segmentOffset = lineSegment.offset; int x = horizontalOffset; /* If syntax coloring is disabled, do simple translation */ if (tokenMarker == null) { lineSegment.count = offset; return x + Utilities.getTabbedTextWidth(lineSegment, fm, x, painter, 0); } /* If syntax coloring is enabled, we have to do this because * tokens can vary in width */ else { Token tokens; if (painter.currentLineIndex == line && painter.currentLineTokens != null) tokens = painter.currentLineTokens; else { painter.currentLineIndex = line; tokens = painter.currentLineTokens = tokenMarker.markTokens(lineSegment, line); } Toolkit toolkit = painter.getToolkit(); Font defaultFont = painter.getFont(); SyntaxStyle[] styles = painter.getStyles(); for (; ; ) { byte id = tokens.id; if (id == Token.END) { return x; } if (id == Token.NULL) fm = painter.getFontMetrics(); else fm = styles[id].getFontMetrics(defaultFont); int length = tokens.length; if (offset + segmentOffset < lineSegment.offset + length) { lineSegment.count = offset - (lineSegment.offset - segmentOffset); return x + Utilities.getTabbedTextWidth(lineSegment, fm, x, painter, 0); } else { lineSegment.count = length; x += Utilities.getTabbedTextWidth(lineSegment, fm, x, painter, 0); lineSegment.offset += length; } tokens = tokens.next; } } }
/** * Determines the preferred span for this view along an axis. * * @param axis may be either View.X_AXIS or View.Y_AXIS * @return the span the view would like to be rendered into >= 0. Typically the view is told to * render into the span that is returned, although there is no guarantee. The parent may * choose to resize or break the view. */ public float getPreferredSpan(int axis) { switch (axis) { case View.X_AXIS: Segment buff = SegmentCache.getSharedSegment(); Document doc = getDocument(); int width; try { FontMetrics fm = getFontMetrics(); doc.getText(0, doc.getLength(), buff); width = Utilities.getTabbedTextWidth(buff, fm, 0, this, 0); if (buff.count > 0) { Component c = getContainer(); firstLineOffset = sun.swing.SwingUtilities2.getLeftSideBearing( (c instanceof JComponent) ? (JComponent) c : null, fm, buff.array[buff.offset]); firstLineOffset = Math.max(0, -firstLineOffset); } else { firstLineOffset = 0; } } catch (BadLocationException bl) { width = 0; } SegmentCache.releaseSharedSegment(buff); return width + firstLineOffset; default: return super.getPreferredSpan(axis); } }