Search in sources :

Example 1 with BidiParagraph

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;
}
Also used : BidiParagraph(com.mta.tehreer.unicode.BidiParagraph) Paint(android.graphics.Paint) NonNull(androidx.annotation.NonNull)

Example 2 with BidiParagraph

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();
        }
    }
}
Also used : ShapingEngine(com.mta.tehreer.sfnt.ShapingEngine) BidiRun(com.mta.tehreer.unicode.BidiRun) ScriptClassifier(com.mta.tehreer.unicode.ScriptClassifier) Paint(android.graphics.Paint) ShapingOrder(com.mta.tehreer.sfnt.ShapingOrder) BaseDirection(com.mta.tehreer.unicode.BaseDirection) ScriptRun(com.mta.tehreer.unicode.ScriptRun) BidiParagraph(com.mta.tehreer.unicode.BidiParagraph) WritingDirection(com.mta.tehreer.sfnt.WritingDirection) BidiAlgorithm(com.mta.tehreer.unicode.BidiAlgorithm)

Example 3 with BidiParagraph

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();
    }
}
Also used : BidiParagraph(com.mta.tehreer.unicode.BidiParagraph)

Example 4 with BidiParagraph

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);
}
Also used : BidiRun(com.mta.tehreer.unicode.BidiRun) BidiParagraph(com.mta.tehreer.unicode.BidiParagraph) BidiLine(com.mta.tehreer.unicode.BidiLine)

Example 5 with BidiParagraph

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);
}
Also used : BidiRun(com.mta.tehreer.unicode.BidiRun) BidiParagraph(com.mta.tehreer.unicode.BidiParagraph) BidiLine(com.mta.tehreer.unicode.BidiLine)

Aggregations

BidiParagraph (com.mta.tehreer.unicode.BidiParagraph)10 BidiRun (com.mta.tehreer.unicode.BidiRun)4 Paint (android.graphics.Paint)2 ShapingEngine (com.mta.tehreer.sfnt.ShapingEngine)2 WritingDirection (com.mta.tehreer.sfnt.WritingDirection)2 BaseDirection (com.mta.tehreer.unicode.BaseDirection)2 BidiAlgorithm (com.mta.tehreer.unicode.BidiAlgorithm)2 BidiLine (com.mta.tehreer.unicode.BidiLine)2 NonNull (androidx.annotation.NonNull)1 ShapingOrder (com.mta.tehreer.sfnt.ShapingOrder)1 ScriptClassifier (com.mta.tehreer.unicode.ScriptClassifier)1 ScriptRun (com.mta.tehreer.unicode.ScriptRun)1