Java Code Examples for com.intellij.util.DocumentUtil#alignToCodePointBoundary()

The following examples show how to use com.intellij.util.DocumentUtil#alignToCodePointBoundary() . You can vote up the ones you like or vote down the ones you don't like, and go to the original project or source file by following the links above each example. You may check out the related API usage on the sidebar.
Example 1
Source File: EditorCoordinateMapper.java    From consulo with Apache License 2.0 6 votes vote down vote up
private int visualLineStartOffset(int offset, boolean leanForward) {
  DesktopEditorImpl editor = myView.getEditor();
  offset = DocumentUtil.alignToCodePointBoundary(myDocument, offset);
  int result = EditorUtil.getNotFoldedLineStartOffset(editor, offset);

  SoftWrapModelImpl softWrapModel = editor.getSoftWrapModel();
  List<? extends SoftWrap> softWraps = softWrapModel.getRegisteredSoftWraps();
  int currentOrPrevWrapIndex = softWrapModel.getSoftWrapIndex(offset);
  SoftWrap currentOrPrevWrap;
  if (currentOrPrevWrapIndex < 0) {
    currentOrPrevWrapIndex = -currentOrPrevWrapIndex - 2;
    currentOrPrevWrap = currentOrPrevWrapIndex < 0 || currentOrPrevWrapIndex >= softWraps.size() ? null : softWraps.get(currentOrPrevWrapIndex);
  }
  else {
    currentOrPrevWrap = leanForward ? softWraps.get(currentOrPrevWrapIndex) : null;
  }
  if (currentOrPrevWrap != null && currentOrPrevWrap.getStart() > result) {
    result = currentOrPrevWrap.getStart();
  }
  return result;
}
 
Example 2
Source File: EditorCoordinateMapper.java    From consulo with Apache License 2.0 5 votes vote down vote up
@Nonnull
Point2D offsetToXY(int offset, boolean leanTowardsLargerOffsets, boolean beforeSoftWrap) {
  offset = Math.max(0, Math.min(myDocument.getTextLength(), offset));
  offset = DocumentUtil.alignToCodePointBoundary(myDocument, offset);
  int logicalLine = myDocument.getLineNumber(offset);
  int visualLine = offsetToVisualLine(offset, beforeSoftWrap);
  int visualLineStartOffset = visualLineToOffset(visualLine);
  int y = visualLineToY(visualLine);
  float x = getStartX(logicalLine);
  if (myDocument.getTextLength() > 0) {
    boolean firstFragment = true;
    for (VisualLineFragmentsIterator.Fragment fragment : VisualLineFragmentsIterator.create(myView, offset, beforeSoftWrap, true)) {
      if (firstFragment && offset == visualLineStartOffset && !leanTowardsLargerOffsets) {
        x = fragment.getStartX();
        break;
      }
      firstFragment = false;
      int minOffset = fragment.getMinOffset();
      int maxOffset = fragment.getMaxOffset();
      if (fragment.getCurrentInlay() == null && (offset > minOffset && offset < maxOffset || offset == minOffset && leanTowardsLargerOffsets || offset == maxOffset && !leanTowardsLargerOffsets)) {
        x = fragment.offsetToX(offset);
        break;
      }
      else {
        x = fragment.getEndX();
      }
    }
  }
  return new Point2D.Double(x, y);
}
 
Example 3
Source File: IterationState.java    From consulo with Apache License 2.0 4 votes vote down vote up
private int alignOffset(int offset) {
  return DocumentUtil.alignToCodePointBoundary(myDocument, offset);
}
 
Example 4
Source File: EditorPainter.java    From consulo with Apache License 2.0 4 votes vote down vote up
private void paintBorderEffect(int startOffset, int endOffset, EffectDescriptor borderDescriptor) {
  startOffset = DocumentUtil.alignToCodePointBoundary(myDocument, startOffset);
  endOffset = DocumentUtil.alignToCodePointBoundary(myDocument, endOffset);
  if (!myClipDetector.rangeCanBeVisible(startOffset, endOffset)) return;
  int startLine = myDocument.getLineNumber(startOffset);
  int endLine = myDocument.getLineNumber(endOffset);
  if (startLine + 1 == endLine && startOffset == myDocument.getLineStartOffset(startLine) && endOffset == myDocument.getLineStartOffset(endLine)) {
    // special case of line highlighters
    endLine--;
    endOffset = myDocument.getLineEndOffset(endLine);
  }

  boolean rounded = borderDescriptor.effectType == EffectType.ROUNDED_BOX;
  myGraphics.setColor(borderDescriptor.effectColor);
  VisualPosition startPosition = myView.offsetToVisualPosition(startOffset, true, false);
  VisualPosition endPosition = myView.offsetToVisualPosition(endOffset, false, true);
  if (startPosition.line == endPosition.line) {
    int y = myView.visualLineToY(startPosition.line) + myYShift;
    TFloatArrayList ranges = adjustedLogicalRangeToVisualRanges(startOffset, endOffset);
    for (int i = 0; i < ranges.size() - 1; i += 2) {
      float startX = myCorrector.singleLineBorderStart(ranges.get(i));
      float endX = myCorrector.singleLineBorderEnd(ranges.get(i + 1));
      drawSimpleBorder(startX, endX, y, rounded);
    }
  }
  else {
    TFloatArrayList leadingRanges = adjustedLogicalRangeToVisualRanges(startOffset, myView.visualPositionToOffset(new VisualPosition(startPosition.line, Integer.MAX_VALUE, true)));
    TFloatArrayList trailingRanges = adjustedLogicalRangeToVisualRanges(myView.visualPositionToOffset(new VisualPosition(endPosition.line, 0)), endOffset);
    if (!leadingRanges.isEmpty() && !trailingRanges.isEmpty()) {
      int minX = Math.min(myCorrector.minX(startPosition.line, endPosition.line), (int)leadingRanges.get(0));
      int maxX = Math.max(myCorrector.maxX(startPosition.line, endPosition.line), (int)trailingRanges.get(trailingRanges.size() - 1));
      boolean containsInnerLines = endPosition.line > startPosition.line + 1;
      int lineHeight = myLineHeight - 1;
      int leadingTopY = myView.visualLineToY(startPosition.line) + myYShift;
      int leadingBottomY = leadingTopY + lineHeight;
      int trailingTopY = myView.visualLineToY(endPosition.line) + myYShift;
      int trailingBottomY = trailingTopY + lineHeight;
      float start = 0;
      float end = 0;
      float leftGap = leadingRanges.get(0) - (containsInnerLines ? minX : trailingRanges.get(0));
      int adjustY = leftGap == 0 ? 2 : leftGap > 0 ? 1 : 0; // avoiding 1-pixel gap between aligned lines
      for (int i = 0; i < leadingRanges.size() - 1; i += 2) {
        start = leadingRanges.get(i);
        end = leadingRanges.get(i + 1);
        if (i > 0) {
          drawLine(leadingRanges.get(i - 1), leadingBottomY, start, leadingBottomY, rounded);
        }
        drawLine(start, leadingBottomY + (i == 0 ? adjustY : 0), start, leadingTopY, rounded);
        if ((i + 2) < leadingRanges.size()) {
          drawLine(start, leadingTopY, end, leadingTopY, rounded);
          drawLine(end, leadingTopY, end, leadingBottomY, rounded);
        }
      }
      end = Math.max(end, maxX);
      drawLine(start, leadingTopY, end, leadingTopY, rounded);
      drawLine(end, leadingTopY, end, trailingTopY - 1, rounded);
      float targetX = trailingRanges.get(trailingRanges.size() - 1);
      drawLine(end, trailingTopY - 1, targetX, trailingTopY - 1, rounded);
      adjustY = end == targetX ? -2 : -1; // for lastX == targetX we need to avoid a gap when rounding is used
      for (int i = trailingRanges.size() - 2; i >= 0; i -= 2) {
        start = trailingRanges.get(i);
        end = trailingRanges.get(i + 1);

        drawLine(end, trailingTopY + (i == 0 ? adjustY : 0), end, trailingBottomY, rounded);
        drawLine(end, trailingBottomY, start, trailingBottomY, rounded);
        drawLine(start, trailingBottomY, start, trailingTopY, rounded);
        if (i > 0) {
          drawLine(start, trailingTopY, trailingRanges.get(i - 1), trailingTopY, rounded);
        }
      }
      float lastX = start;
      if (containsInnerLines) {
        if (start != minX) {
          drawLine(start, trailingTopY, start, trailingTopY - 1, rounded);
          drawLine(start, trailingTopY - 1, minX, trailingTopY - 1, rounded);
          drawLine(minX, trailingTopY - 1, minX, leadingBottomY + 1, rounded);
        }
        else {
          drawLine(minX, trailingTopY, minX, leadingBottomY + 1, rounded);
        }
        lastX = minX;
      }
      targetX = leadingRanges.get(0);
      if (lastX < targetX) {
        drawLine(lastX, leadingBottomY + 1, targetX, leadingBottomY + 1, rounded);
      }
      else {
        drawLine(lastX, leadingBottomY + 1, lastX, leadingBottomY, rounded);
        drawLine(lastX, leadingBottomY, targetX, leadingBottomY, rounded);
      }
    }
  }
}
 
Example 5
Source File: DesktopCaretImpl.java    From consulo with Apache License 2.0 4 votes vote down vote up
@Override
protected void changedUpdateImpl(@Nonnull DocumentEvent e) {
  int oldOffset = intervalStart();
  super.changedUpdateImpl(e);
  if (isValid()) {
    // Under certain conditions, when text is inserted at caret position, we position caret at the end of inserted text.
    // Ideally, client code should be responsible for positioning caret after document modification, but in case of
    // postponed formatting (after PSI modifications), this is hard to implement, so a heuristic below is used.
    if (e.getOldLength() == 0 &&
        oldOffset == e.getOffset() &&
        !Boolean.TRUE.equals(myEditor.getUserData(DesktopEditorImpl.DISABLE_CARET_SHIFT_ON_WHITESPACE_INSERTION)) &&
        needToShiftWhiteSpaces(e)) {
      int afterInserted = e.getOffset() + e.getNewLength();
      setIntervalStart(afterInserted);
      setIntervalEnd(afterInserted);
    }
    int offset = intervalStart();
    if (DocumentUtil.isInsideSurrogatePair(getDocument(), offset)) {
      setIntervalStart(offset - 1);
      setIntervalEnd(offset - 1);
    }
  }
  else {
    setValid(true);
    int newOffset = Math.min(intervalStart(), e.getOffset() + e.getNewLength());
    if (!e.getDocument().isInBulkUpdate() && e.isWholeTextReplaced()) {
      try {
        final int line = ((DocumentEventImpl)e).translateLineViaDiff(myLogicalCaret.line);
        newOffset = myEditor.logicalPositionToOffset(new LogicalPosition(line, myLogicalCaret.column));
      }
      catch (FilesTooBigForDiffException ex) {
        LOG.info(ex);
      }
    }
    newOffset = DocumentUtil.alignToCodePointBoundary(getDocument(), newOffset);
    setIntervalStart(newOffset);
    setIntervalEnd(newOffset);
  }
  myLogicalColumnAdjustment = 0;
  myVisualColumnAdjustment = 0;
  if (oldOffset >= e.getOffset() && oldOffset <= e.getOffset() + e.getOldLength() && e.getNewLength() == 0 && e.getOldLength() > 0) {
    int inlaysToTheLeft = myEditor.getInlayModel().getInlineElementsInRange(e.getOffset(), e.getOffset()).size();
    boolean hasInlaysToTheRight = myEditor.getInlayModel().hasInlineElementAt(e.getOffset() + e.getOldLength());
    if (inlaysToTheLeft > 0 || hasInlaysToTheRight) {
      myLeansTowardsLargerOffsets = !hasInlaysToTheRight;
      myVisualColumnAdjustment = hasInlaysToTheRight ? inlaysToTheLeft : 0;
    }
    else if (oldOffset == e.getOffset()) {
      myLeansTowardsLargerOffsets = false;
    }
  }
}