/** * Wraps lines at and below the caret that exceed the number of characters per line. * * <p>Lines are wrapped at spaces between words when possible. Lines that don't exceed the number * of characters per line are not changed. * * <p>Currently this cannot be undone. */ public void rewrapFromCaret() { StringBuilder stringBuilder = new StringBuilder(charsPerLine * 3); for (int i = content.getLineAtOffset(currentText.getCaretOffset()); i < content.getLineCount(); i++) { String line = content.getLine(i); if (line.length() == 0) continue; // line too long if (line.length() > charsPerLine) { int wordWrap, wordEnd; // find beginning of word being wrapped if (line.charAt(charsPerLine) != ' ') { for (wordWrap = charsPerLine; wordWrap > charsPerLine / 2; wordWrap--) if (line.charAt(wordWrap) == ' ') break; if (wordWrap == charsPerLine / 2) continue; wordWrap++; } else { for (wordWrap = charsPerLine; wordWrap < line.length(); wordWrap++) if (line.charAt(wordWrap) != ' ') break; if (wordWrap == line.length()) continue; } // find end of word before word being wrapped for (wordEnd = wordWrap - 1; wordEnd > charsPerLine / 4; wordEnd--) if (line.charAt(wordEnd) != ' ') break; if (wordEnd == charsPerLine / 4) continue; wordEnd++; // build replacement text int length = line.length(); stringBuilder.setLength(0); stringBuilder .append(line.substring(0, wordEnd)) .append(eol) .append(line.substring(wordWrap, length)); if (length > 0 && line.charAt(length - 1) != PARAGRAPH_END) if (i < content.getLineCount() - 1) { String next = content.getLine(i + 1); stringBuilder.append(' ').append(next); length += eol.length() + next.length(); } content.replaceTextRange(content.getOffsetAtLine(i), length, stringBuilder.toString()); } else if (line.length() > 0 && line.charAt(line.length() - 1) == PARAGRAPH_END) break; } clearChanges(); }
/* * @see org.eclipse.jface.text.source.AnnotationPainter.IDrawingStrategy#draw(org.eclipse.swt.graphics.GC, org.eclipse.swt.custom.StyledText, int, int, org.eclipse.swt.graphics.Color) */ public void draw( Annotation annotation, GC gc, StyledText textWidget, int offset, int length, Color color) { if (annotation instanceof ProjectionAnnotation) { ProjectionAnnotation projectionAnnotation = (ProjectionAnnotation) annotation; if (projectionAnnotation.isCollapsed()) { if (gc != null) { StyledTextContent content = textWidget.getContent(); int line = content.getLineAtOffset(offset); int lineStart = content.getOffsetAtLine(line); String text = content.getLine(line); int lineLength = text == null ? 0 : text.length(); int lineEnd = lineStart + lineLength; Point p = textWidget.getLocationAtOffset(lineEnd); Color c = gc.getForeground(); gc.setForeground(color); FontMetrics metrics = gc.getFontMetrics(); // baseline: where the dots are drawn int baseline = textWidget.getBaseline(offset); // descent: number of pixels that the box extends over baseline int descent = Math.min(2, textWidget.getLineHeight(offset) - baseline); // ascent: so much does the box stand up from baseline int ascent = metrics.getAscent(); // leading: free space from line top to box upper line int leading = baseline - ascent; // height: height of the box int height = ascent + descent; int width = metrics.getAverageCharWidth(); gc.drawRectangle(p.x, p.y + leading, width, height); int third = width / 3; int dotsVertical = p.y + baseline - 1; gc.drawPoint(p.x + third, dotsVertical); gc.drawPoint(p.x + width - third, dotsVertical); gc.setForeground(c); } else { textWidget.redrawRange(offset, length, true); } } } }
/** * Draw characters of content range. * * @param gc the GC * @param startOffset inclusive start index * @param endOffset exclusive end index */ private void drawCharRange(GC gc, int startOffset, int endOffset) { StyledTextContent content = fTextWidget.getContent(); int length = endOffset - startOffset; String text = content.getTextRange(startOffset, length); StyleRange styleRange = null; Color fg = null; Point selection = fTextWidget.getSelection(); StringBuffer visibleChar = new StringBuffer(10); for (int textOffset = 0; textOffset <= length; ++textOffset) { int delta = 0; boolean eol = false; if (textOffset < length) { delta = 1; char c = text.charAt(textOffset); switch (c) { case ' ': visibleChar.append(SPACE_SIGN); // 'continue' would improve performance but may produce // drawing errors // for long runs of space if width of space and dot differ break; case '\u3000': // ideographic whitespace visibleChar.append(IDEOGRAPHIC_SPACE_SIGN); // 'continue' would improve performance but may produce // drawing errors // for long runs of space if width of space and dot differ break; case '\t': visibleChar.append(TAB_SIGN); break; case '\r': visibleChar.append(CARRIAGE_RETURN_SIGN); if (textOffset >= length - 1 || text.charAt(textOffset + 1) != '\n') { eol = true; break; } continue; case '\n': visibleChar.append(LINE_FEED_SIGN); eol = true; break; default: delta = 0; break; } } if (visibleChar.length() > 0) { int widgetOffset = startOffset + textOffset - visibleChar.length() + delta; if (!eol || !isFoldedLine(content.getLineAtOffset(widgetOffset))) { if (widgetOffset >= selection.x && widgetOffset < selection.y) { fg = fTextWidget.getSelectionForeground(); } else if (styleRange == null || styleRange.start + styleRange.length <= widgetOffset) { styleRange = fTextWidget.getStyleRangeAtOffset(widgetOffset); if (styleRange == null || styleRange.foreground == null) { fg = fTextWidget.getForeground(); } else { fg = styleRange.foreground; } } draw(gc, widgetOffset, visibleChar.toString(), fg); } visibleChar.delete(0, visibleChar.length()); } } }