/** * Draw the given line range. * * @param gc * @param startLine first line number * @param endLine last line number (inclusive) * @param x the X-coordinate of the drawing range * @param w the width of the drawing range */ private void drawLineRange(GC gc, int startLine, int endLine, int x, int w) { final int viewPortWidth = fTextWidget.getClientArea().width; for (int line = startLine; line <= endLine; line++) { int lineOffset = fTextWidget.getOffsetAtLine(line); // line end offset including line delimiter int lineEndOffset; if (line < fTextWidget.getLineCount() - 1) { lineEndOffset = fTextWidget.getOffsetAtLine(line + 1); } else { lineEndOffset = fTextWidget.getCharCount(); } // line length excluding line delimiter int lineLength = lineEndOffset - lineOffset; while (lineLength > 0) { char c = fTextWidget.getTextRange(lineOffset + lineLength - 1, 1).charAt(0); if (c != '\r' && c != '\n') { break; } --lineLength; } // compute coordinates of last character on line Point endOfLine = fTextWidget.getLocationAtOffset(lineOffset + lineLength); if (x - endOfLine.x > viewPortWidth) { // line is not visible continue; } // Y-coordinate of line int y = fTextWidget.getLinePixel(line); // compute first visible char offset int startOffset; try { startOffset = fTextWidget.getOffsetAtLocation(new Point(x, y)) - 1; if (startOffset - 2 <= lineOffset) { startOffset = lineOffset; } } catch (IllegalArgumentException iae) { startOffset = lineOffset; } // compute last visible char offset int endOffset; if (x + w >= endOfLine.x) { // line end is visible endOffset = lineEndOffset; } else { try { endOffset = fTextWidget.getOffsetAtLocation(new Point(x + w - 1, y)) + 1; if (endOffset + 2 >= lineEndOffset) { endOffset = lineEndOffset; } } catch (IllegalArgumentException iae) { endOffset = lineEndOffset; } } // draw character range if (endOffset > startOffset) { drawCharRange(gc, startOffset, endOffset); } } }
/** * Convert mouse screen coordinates to a <code>StyledText</code> offset. * * @param x screen X-coordinate * @param y screen Y-coordinate * @param absolute if <code>true</code>, coordinates are expected to be absolute screen * coordinates * @return text offset * @see StyledText#getOffsetAtLocation() */ private int getOffsetAtLocation(int x, int y, boolean absolute) { StyledText textWidget = fViewer.getTextWidget(); StyledTextContent content = textWidget.getContent(); Point location; if (absolute) { location = textWidget.toControl(x, y); } else { location = new Point(x, y); } int line = (textWidget.getTopPixel() + location.y) / textWidget.getLineHeight(); if (line >= content.getLineCount()) { return content.getCharCount(); } int lineOffset = content.getOffsetAtLine(line); String lineText = content.getLine(line); Point endOfLine = textWidget.getLocationAtOffset(lineOffset + lineText.length()); if (location.x >= endOfLine.x) { return lineOffset + lineText.length(); } try { return textWidget.getOffsetAtLocation(location); } catch (IllegalArgumentException iae) { // we are expecting this return -1; } }
/** * Get style range at x/y coordinates * * @param x * @param y * @return style range, will be null when no style range exists at given coordinates */ private StyleRange getStyleRange(final int x, final int y) { final StyledText t = getTextWidget(); final int offset; try { offset = t.getOffsetAtLocation(new Point(x, y)); } catch (IllegalArgumentException e) { return null; } if (offset < t.getCharCount()) return t.getStyleRangeAtOffset(offset); else return null; }
// modified version from TextViewer private int computeOffsetAtLocation(ITextViewer textViewer, int x, int y) { StyledText styledText = textViewer.getTextWidget(); IDocument document = textViewer.getDocument(); if (document == null) return -1; try { int widgetOffset = styledText.getOffsetAtLocation(new Point(x, y)); Point p = styledText.getLocationAtOffset(widgetOffset); if (p.x > x) widgetOffset--; if (textViewer instanceof ITextViewerExtension5) { ITextViewerExtension5 extension = (ITextViewerExtension5) textViewer; return extension.widgetOffset2ModelOffset(widgetOffset); } else { IRegion visibleRegion = textViewer.getVisibleRegion(); return widgetOffset + visibleRegion.getOffset(); } } catch (IllegalArgumentException e) { return -1; } }