Iterable<VisualFragment> getFragmentsInVisualOrder( final float startX, final int startVisualColumn, final int startOffset, int endOffset) { assert startOffset <= endOffset; final BidiRun[] runs; int startLogicalColumn = 0; if (startOffset == endOffset) { runs = new BidiRun[0]; } else { List<BidiRun> runList = new ArrayList<BidiRun>(); for (BidiRun run : myBidiRunsInLogicalOrder) { if (run.startOffset < startOffset) { startLogicalColumn = run.getLogicalColumn(startLogicalColumn, Math.min(startOffset, run.endOffset)); } if (run.endOffset <= startOffset) continue; if (run.startOffset >= endOffset) break; runList.add(run.subRun(startOffset, endOffset)); } runs = runList.toArray(new BidiRun[runList.size()]); reorderRunsVisually(runs); } final int finalStartLogicalColumn = startLogicalColumn; return new Iterable<VisualFragment>() { @Override public Iterator<VisualFragment> iterator() { return new VisualOrderIterator( startX, startVisualColumn, finalStartLogicalColumn, startOffset, runs); } }; }