List<InlineChunk> (@NotNull final CharSequence text) { final List<InlineChunk> chunks = new ArrayList<>(); int len = text.length(); int offset = 0; int wordStart = -1; int wordHash = 0; while (offset < len) { int ch = Character.codePointAt(text, offset); int charCount = Character.charCount(ch); boolean isAlpha = isAlpha(ch); boolean isWordPart = isAlpha && !isContinuousScript(ch); if (isWordPart) { if (wordStart == -1) { wordStart = offset; wordHash = 0; } wordHash = wordHash * 31 + ch; } else { if (wordStart != -1) { chunks.add(new WordChunk(text, wordStart, offset, wordHash)); wordStart = -1; } if (isAlpha) { // continuous script chunks.add(new WordChunk(text, offset, offset + charCount, ch)); } else if (ch == '\n') { chunks.add(new NewlineChunk(offset)); } } offset += charCount; } if (wordStart != -1) { chunks.add(new WordChunk(text, wordStart, len, wordHash)); } return chunks; }