private int getLogicalColumn(int startLogicalColumn, int offset) { assert offset >= startOffset; assert offset <= endOffset; int currentStartOffset = startOffset; for (LineFragment fragment : fragments) { int currentEndOffset = currentStartOffset + fragment.getLength(); startLogicalColumn = fragment.offsetToLogicalColumn( startLogicalColumn, Math.min(offset, currentEndOffset) - currentStartOffset); currentStartOffset = currentEndOffset; if (offset <= currentStartOffset) break; } return startLogicalColumn; }
// column is expected to be between startVisualColumn and endVisualColumn for this fragment int visualToLogicalColumn(int column) { int relativeLogicalColumn = delegate.visualToLogicalColumn(startX, getMinLogicalColumn(), column - startVisualColumn); return isRtl ? startLogicalColumn - relativeLogicalColumn : startLogicalColumn + relativeLogicalColumn; }
// column is expected to be between minLogicalColumn and maxLogicalColumn for this fragment int logicalToVisualColumn(int column) { return startVisualColumn + delegate.logicalToVisualColumn( startX, getMinLogicalColumn(), isRtl ? startLogicalColumn - column : column - startLogicalColumn); }
private BidiRun subRun(int targetStartOffset, int targetEndOffset) { assert targetStartOffset < endOffset; assert targetEndOffset > startOffset; if (targetStartOffset <= startOffset && targetEndOffset >= this.endOffset) { return this; } int start = Math.max(startOffset, targetStartOffset); int end = Math.min(endOffset, targetEndOffset); BidiRun run = new BidiRun(level, start, end); int offset = startOffset; for (LineFragment fragment : fragments) { if (end <= offset) break; int endOffset = offset + fragment.getLength(); if (start < endOffset) { run.fragments.add( fragment.subFragment( Math.max(start, offset) - offset, Math.min(end, endOffset) - offset)); } offset = endOffset; } return run; }
// columns are visual (relative to fragment's start) void draw(Graphics2D g, float x, float y, int startRelativeColumn, int endRelativeColumn) { delegate.draw(g, x, y, startRelativeColumn, endRelativeColumn); }
void draw(Graphics2D g, float x, float y) { delegate.draw(g, x, y, 0, getLength()); }
// column is expected to be between startVisualColumn and endVisualColumn for this fragment float visualColumnToX(int column) { return delegate.visualColumnToX(startX, column - startVisualColumn); }
// x is expected to be between startX and endX for this fragment // returns array of two elements // - first one is visual column, // - second one is 1 if target location is closer to larger columns and 0 otherwise int[] xToVisualColumn(float x) { int[] column = delegate.xToVisualColumn(startX, x); column[0] += startVisualColumn; return column; }
// both startOffset and offset are expected to be between minOffset and maxOffset for this // fragment float offsetToX(float startX, int startOffset, int offset) { return delegate.offsetToX(startX, getRelativeOffset(startOffset), getRelativeOffset(offset)); }
// offset is expected to be between minOffset and maxOffset for this fragment float offsetToX(int offset) { return delegate.offsetToX(startX, 0, getRelativeOffset(offset)); }
float getEndX() { return delegate.offsetToX(startX, 0, getLength()); }
int getVisualColumnCount() { return delegate.getVisualColumnCount(startX); }
int getLogicalColumnCount() { return isRtl ? getLength() : delegate.getLogicalColumnCount(getMinLogicalColumn()); }
int getLength() { return delegate.getLength(); }