use of com.mta.tehreer.unicode.BidiParagraph in project Tehreer-Android by mta452.
the class FrameResolver method createFrame.
/**
* Creates a frame representing specified string range in source text.
* <p>
* The resolver keeps on filling the frame until it either runs out of text or it finds that
* text no longer fits in frame bounds. The resulting frame consists of at least one line even
* if frame bounds are smaller.
*
* @param charStart The index to first character of the frame in source text.
* @param charEnd The index after the last character of the line in source text.
* @return A new composed frame.
*
* @throws IllegalArgumentException if <code>charStart</code> is negative, or
* <code>charEnd</code> is greater than the length of source text, or
* <code>charStart</code> is greater than or equal to <code>charEnd</code>.
*/
@NonNull
public ComposedFrame createFrame(int charStart, int charEnd) {
checkSubRange(charStart, charEnd);
FrameFiller frameFiller = new FrameFiller();
int paragraphIndex = mParagraphs.binarySearch(charStart);
int segmentStart = charStart;
int segmentEnd;
// Iterate over all paragraphs in provided range.
do {
BidiParagraph paragraph = mParagraphs.get(paragraphIndex);
segmentEnd = Math.min(charEnd, paragraph.getCharEnd());
// Setup the frame filler and add the lines.
frameFiller.charStart = segmentStart;
frameFiller.charEnd = segmentEnd;
frameFiller.baseLevel = paragraph.getBaseLevel();
frameFiller.addParagraphLines();
if (frameFiller.filled) {
break;
}
segmentStart = segmentEnd;
paragraphIndex++;
} while (segmentStart < charEnd);
frameFiller.handleTruncation(charEnd);
frameFiller.resolveAlignments();
ComposedFrame frame = new ComposedFrame(mSpanned, charStart, frameFiller.frameEnd(), frameFiller.frameLines);
frame.setContainerRect(mFrameBounds.left, mFrameBounds.top, frameFiller.layoutWidth, frameFiller.layoutHeight);
return frame;
}
use of com.mta.tehreer.unicode.BidiParagraph in project Tehreer-Android by mta452.
the class ShapeResolver method fillRuns.
public static void fillRuns(@NonNull String text, @NonNull Spanned spanned, @NonNull List<Object> defaultSpans, @NonNull byte[] breaks, @NonNull List<BidiParagraph> paragraphs, @NonNull List<TextRun> runs) {
BidiAlgorithm bidiAlgorithm = null;
ShapingEngine shapingEngine = null;
try {
bidiAlgorithm = new BidiAlgorithm(text);
shapingEngine = new ShapingEngine();
ScriptClassifier scriptClassifier = new ScriptClassifier(text);
ShapingRunLocator locator = new ShapingRunLocator(spanned, defaultSpans);
BaseDirection baseDirection = BaseDirection.DEFAULT_LEFT_TO_RIGHT;
byte forwardType = BreakResolver.typeMode(BreakResolver.PARAGRAPH, true);
byte backwardType = BreakResolver.typeMode(BreakResolver.PARAGRAPH, false);
int paragraphStart = 0;
int suggestedEnd = text.length();
while (paragraphStart != suggestedEnd) {
BidiParagraph paragraph = bidiAlgorithm.createParagraph(paragraphStart, suggestedEnd, baseDirection);
for (BidiRun bidiRun : paragraph.getLogicalRuns()) {
for (ScriptRun scriptRun : scriptClassifier.getScriptRuns(bidiRun.charStart, bidiRun.charEnd)) {
int scriptTag = Script.getOpenTypeTag(scriptRun.script);
WritingDirection writingDirection = ShapingEngine.getScriptDirection(scriptTag);
boolean isOddLevel = ((bidiRun.embeddingLevel & 1) == 1);
boolean isBackward = (isOddLevel && writingDirection == WritingDirection.LEFT_TO_RIGHT) | (!isOddLevel && writingDirection == WritingDirection.RIGHT_TO_LEFT);
ShapingOrder shapingOrder = (isBackward ? ShapingOrder.BACKWARD : ShapingOrder.FORWARD);
locator.reset(scriptRun.charStart, scriptRun.charEnd);
shapingEngine.setScriptTag(scriptTag);
shapingEngine.setWritingDirection(writingDirection);
shapingEngine.setShapingOrder(shapingOrder);
resolveTypefaces(text, spanned, runs, locator, shapingEngine, bidiRun.embeddingLevel);
}
}
paragraphs.add(paragraph);
breaks[paragraph.getCharStart()] |= backwardType;
breaks[paragraph.getCharEnd() - 1] |= forwardType;
paragraphStart = paragraph.getCharEnd();
}
} finally {
if (shapingEngine != null) {
shapingEngine.dispose();
}
if (bidiAlgorithm != null) {
bidiAlgorithm.dispose();
}
}
}
use of com.mta.tehreer.unicode.BidiParagraph in project Tehreer-Android by mta452.
the class ParagraphCollection method finalize.
@Override
protected void finalize() throws Throwable {
try {
int size = size();
for (int i = 0; i < size; i++) {
BidiParagraph paragraph = get(i);
paragraph.dispose();
}
} finally {
super.finalize();
}
}
use of com.mta.tehreer.unicode.BidiParagraph in project Tehreer-Android by mta452.
the class ParagraphCollection method forEachLineRun.
public void forEachLineRun(int lineStart, int lineEnd, @NonNull RunConsumer runConsumer) {
int paragraphIndex = binarySearch(lineStart);
BidiParagraph directionalParagraph = get(paragraphIndex);
boolean isRTL = (directionalParagraph.getBaseLevel() & 1) == 1;
if (isRTL) {
int paragraphEnd = directionalParagraph.getCharEnd();
if (paragraphEnd < lineEnd) {
paragraphIndex = binarySearch(lineEnd - 1);
}
}
int next = (isRTL ? -1 : 1);
int feasibleStart;
int feasibleEnd;
do {
BidiParagraph bidiParagraph = get(paragraphIndex);
feasibleStart = Math.max(bidiParagraph.getCharStart(), lineStart);
feasibleEnd = Math.min(bidiParagraph.getCharEnd(), lineEnd);
BidiLine bidiLine = bidiParagraph.createLine(feasibleStart, feasibleEnd);
List<BidiRun> bidiRuns = bidiLine.getVisualRuns();
int runCount = bidiRuns.size();
for (int i = 0; i < runCount; i++) {
runConsumer.accept(bidiRuns.get(i));
}
bidiLine.dispose();
paragraphIndex += next;
} while (isRTL ? feasibleStart != lineStart : feasibleEnd != lineEnd);
}
use of com.mta.tehreer.unicode.BidiParagraph in project Tehreer-Android by mta452.
the class Typesetter method addContinuousLineRuns.
private void addContinuousLineRuns(int charStart, int charEnd, BidiRunConsumer runConsumer) {
int paragraphIndex = indexOfBidiParagraph(charStart);
int feasibleStart;
int feasibleEnd;
do {
BidiParagraph bidiParagraph = mBidiParagraphs.get(paragraphIndex);
feasibleStart = Math.max(bidiParagraph.getCharStart(), charStart);
feasibleEnd = Math.min(bidiParagraph.getCharEnd(), charEnd);
BidiLine bidiLine = bidiParagraph.createLine(feasibleStart, feasibleEnd);
for (BidiRun bidiRun : bidiLine.getVisualRuns()) {
runConsumer.accept(bidiRun);
}
bidiLine.dispose();
paragraphIndex++;
} while (feasibleEnd != charEnd);
}
Aggregations