int (@NotNull Editor editor, @NotNull CharSequence text, int start, int end, int x) { int startToUse = start; int lastTabSymbolIndex = -1; // Skip all lines except the last. loop: for (int i = end - 1; i >= start; i--) { switch (text.charAt(i)) { case '\n': startToUse = i + 1; break loop; case '\t': if (lastTabSymbolIndex < 0) lastTabSymbolIndex = i; } } // Tabulation is assumed to be the only symbol which representation may take various number of visual columns, hence, // we return eagerly if no such symbol is found. if (lastTabSymbolIndex < 0) { return end - startToUse; } int result = 0; int spaceSize = getSpaceWidth(Font.PLAIN, editor); // Calculate number of columns up to the latest tabulation symbol. for (int i = startToUse; i <= lastTabSymbolIndex; i++) { SoftWrap softWrap = editor.getSoftWrapModel().getSoftWrap(i); if (softWrap != null) { x = softWrap.getIndentInPixels(); } char c = text.charAt(i); int prevX = x; switch (c) { case '\t' -> { x = nextTabStop(x, editor); result += columnsNumber(x - prevX, spaceSize); } case '\n' -> x = result = 0; default -> { x += charWidth(c, Font.PLAIN, editor); result++; } } } // Add remaining tabulation-free columns. result += end - lastTabSymbolIndex - 1; return result; }